Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F99540464
D3981.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D3981.diff
View Options
Index: head/sys/netgraph/bluetooth/hci/ng_hci_evnt.c
===================================================================
--- head/sys/netgraph/bluetooth/hci/ng_hci_evnt.c
+++ head/sys/netgraph/bluetooth/hci/ng_hci_evnt.c
@@ -929,7 +929,7 @@
"%s: %s - invalid connection handle=%d\n",
__func__, NG_NODE_NAME(unit->node), h);
error = ENOENT;
- } else if (con->link_type != NG_HCI_LINK_ACL) {
+ } else if (con->link_type == NG_HCI_LINK_SCO) {
NG_HCI_ALERT(
"%s: %s - invalid link type=%d\n",
__func__, NG_NODE_NAME(unit->node),
@@ -940,6 +940,7 @@
con->encryption_mode = NG_HCI_ENCRYPTION_MODE_P2P;
else
con->encryption_mode = NG_HCI_ENCRYPTION_MODE_NONE;
+ ng_hci_lp_enc_change(con, ep->encryption_enable);
} else
NG_HCI_ERR(
"%s: %s - failed to change encryption mode, status=%d\n",
Index: head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.h
===================================================================
--- head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.h
+++ head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.h
@@ -47,6 +47,7 @@
int ng_hci_lp_qos_req (ng_hci_unit_p, item_p, hook_p);
int ng_hci_lp_qos_cfm (ng_hci_unit_con_p, int);
int ng_hci_lp_qos_ind (ng_hci_unit_con_p);
+int ng_hci_lp_enc_change (ng_hci_unit_con_p, int);
void ng_hci_process_con_timeout (node_p, hook_p, void *, int);
Index: head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.c
===================================================================
--- head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.c
+++ head/sys/netgraph/bluetooth/hci/ng_hci_ulpi.c
@@ -814,6 +814,37 @@
return (0);
} /* ng_hci_lp_con_cfm */
+int
+ng_hci_lp_enc_change(ng_hci_unit_con_p con, int status)
+{
+ ng_hci_unit_p unit = con->unit;
+ struct ng_mesg *msg = NULL;
+ ng_hci_lp_enc_change_ep *ep = NULL;
+ int error;
+
+
+ if (con->link_type != NG_HCI_LINK_SCO) {
+ if (unit->acl != NULL && NG_HOOK_IS_VALID(unit->acl)) {
+ NG_MKMESSAGE(msg, NGM_HCI_COOKIE, NGM_HCI_LP_ENC_CHG,
+ sizeof(*ep), M_NOWAIT);
+ if (msg != NULL) {
+ ep = (ng_hci_lp_enc_change_ep *) msg->data;
+ ep->status = status;
+ ep->link_type = con->link_type;
+ ep->con_handle = con->con_handle;
+
+ NG_SEND_MSG_HOOK(error, unit->node, msg,
+ unit->acl, 0);
+ }
+ } else
+ NG_HCI_INFO(
+"%s: %s - ACL hook not valid, hook=%p\n",
+ __func__, NG_NODE_NAME(unit->node), unit->acl);
+
+ }
+ return (0);
+} /* ng_hci_lp_con_cfm */
+
/*
* Send LP_ConnectInd event to the upper layer protocol
*/
Index: head/sys/netgraph/bluetooth/include/ng_btsocket.h
===================================================================
--- head/sys/netgraph/bluetooth/include/ng_btsocket.h
+++ head/sys/netgraph/bluetooth/include/ng_btsocket.h
@@ -255,7 +255,7 @@
#define SO_L2CAP_IFLOW 3 /* get incoming flow spec. */
#define SO_L2CAP_OFLOW 4 /* get/set outgoing flow spec. */
#define SO_L2CAP_FLUSH 5 /* get/set flush timeout */
-
+#define SO_L2CAP_ENCRYPTED 6 /* get/set whether wait for encryptin on connect */
/*
* Raw L2CAP sockets ioctl's
*/
Index: head/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
===================================================================
--- head/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
+++ head/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
@@ -136,7 +136,7 @@
u_int16_t psm; /* PSM */
u_int16_t cid; /* Local channel ID */
-
+ uint8_t idtype;
u_int16_t flags; /* socket flags */
#define NG_BTSOCKET_L2CAP_CLIENT (1 << 0) /* socket is client */
#define NG_BTSOCKET_L2CAP_TIMO (1 << 1) /* timeout pending */
@@ -147,6 +147,7 @@
#define NG_BTSOCKET_L2CAP_CONFIGURING 2 /* wait for config */
#define NG_BTSOCKET_L2CAP_OPEN 3 /* socket open */
#define NG_BTSOCKET_L2CAP_DISCONNECTING 4 /* wait for disconnect */
+#define NG_BTSOCKET_L2CAP_W4_ENC_CHANGE 5
u_int8_t cfg_state; /* config state */
#define NG_BTSOCKET_L2CAP_CFG_IN (1 << 0) /* incoming path done */
@@ -156,7 +157,7 @@
#define NG_BTSOCKET_L2CAP_CFG_IN_SENT (1 << 2) /* L2CAP ConfigReq sent */
#define NG_BTSOCKET_L2CAP_CFG_OUT_SENT (1 << 3) /* ---/--- */
-
+ uint8_t encryption;
u_int16_t imtu; /* Incoming MTU */
ng_l2cap_flow_t iflow; /* Input flow spec */
@@ -172,7 +173,8 @@
ng_btsocket_l2cap_rtentry_p rt; /* routing info */
struct mtx pcb_mtx; /* pcb mutex */
-
+ uint16_t need_encrypt; /*encryption needed*/
+
LIST_ENTRY(ng_btsocket_l2cap_pcb) next; /* link to next PCB */
};
typedef struct ng_btsocket_l2cap_pcb ng_btsocket_l2cap_pcb_t;
Index: head/sys/netgraph/bluetooth/include/ng_hci.h
===================================================================
--- head/sys/netgraph/bluetooth/include/ng_hci.h
+++ head/sys/netgraph/bluetooth/include/ng_hci.h
@@ -469,7 +469,13 @@
typedef struct {
u_int16_t con_handle; /* connection handle */
} ng_hci_lp_qos_ind_ep;
-
+/*Encryption Change event*/
+#define NGM_HCI_LP_ENC_CHG 10 /* HCI->Upper*/
+typedef struct {
+ uint16_t con_handle;
+ uint8_t status;
+ uint8_t link_type;
+}ng_hci_lp_enc_change_ep;
/**************************************************************************
**************************************************************************
** HCI node command/event parameters
Index: head/sys/netgraph/bluetooth/include/ng_l2cap.h
===================================================================
--- head/sys/netgraph/bluetooth/include/ng_l2cap.h
+++ head/sys/netgraph/bluetooth/include/ng_l2cap.h
@@ -256,6 +256,7 @@
u_int16_t mtu; /* NG_L2CAP_OPT_MTU */
u_int16_t flush_timo; /* NG_L2CAP_OPT_FLUSH_TIMO */
ng_l2cap_flow_t flow; /* NG_L2CAP_OPT_QOS */
+ uint16_t encryption;
} ng_l2cap_cfg_opt_val_t;
typedef ng_l2cap_cfg_opt_val_t * ng_l2cap_cfg_opt_val_p;
@@ -357,6 +358,7 @@
#define NG_L2CAP_L2CA_IDTYPE_BREDR 0
#define NG_L2CAP_L2CA_IDTYPE_ATT 1
#define NG_L2CAP_L2CA_IDTYPE_LE 2
+#define NG_L2CAP_L2CA_IDTYPE_SMP 3
/* L2CA_Connect */
#define NGM_L2CAP_L2CA_CON 0x80
/* Upper -> L2CAP */
@@ -373,6 +375,7 @@
uint16_t idtype; /*ID type*/
u_int16_t result; /* 0x00 - success */
u_int16_t status; /* if result != 0x00 */
+ uint8_t encryption;
} ng_l2cap_l2ca_con_op;
/* L2CA_ConnectInd */
@@ -598,6 +601,12 @@
* u_int16_t result; /* 0x00 - success */
* } ng_l2cap_l2ca_enable_clt_op;
#endif
+#define NGM_L2CAP_L2CA_ENC_CHANGE 0x92
+typedef struct {
+ uint16_t lcid;
+ uint16_t result;
+ uint8_t idtype;
+} ng_l2cap_l2ca_enc_chg_op;
/**************************************************************************
**************************************************************************
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_evnt.c
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_evnt.c
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_evnt.c
@@ -475,6 +475,8 @@
con->rx_pkt = NULL;
if(dcid == NG_L2CAP_ATT_CID)
idtype = NG_L2CAP_L2CA_IDTYPE_ATT;
+ else if(dcid == NG_L2CAP_SMP_CID)
+ idtype = NG_L2CAP_L2CA_IDTYPE_SMP;
else if( con->linktype != NG_HCI_LINK_ACL)
idtype = NG_L2CAP_L2CA_IDTYPE_LE;
else
@@ -602,7 +604,9 @@
*/
cmd->ch->dcid = dcid;
- cmd->ch->state = (cmd->ch->scid == NG_L2CAP_ATT_CID)?
+ cmd->ch->state = ((cmd->ch->scid == NG_L2CAP_ATT_CID)||
+ (cmd->ch->scid == NG_L2CAP_SMP_CID))
+ ?
NG_L2CAP_OPEN : NG_L2CAP_CONFIG;
} else
/* There was an error, so close the channel */
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.h
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.h
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.h
@@ -41,6 +41,7 @@
int ng_l2cap_lp_qos_req (ng_l2cap_p, u_int16_t, ng_l2cap_flow_p);
int ng_l2cap_lp_qos_cfm (ng_l2cap_p, struct ng_mesg *);
int ng_l2cap_lp_qos_ind (ng_l2cap_p, struct ng_mesg *);
+int ng_l2cap_lp_enc_change (ng_l2cap_p, struct ng_mesg *);
int ng_l2cap_lp_send (ng_l2cap_con_p, u_int16_t,struct mbuf *);
int ng_l2cap_lp_receive (ng_l2cap_p, struct mbuf *);
void ng_l2cap_lp_deliver (ng_l2cap_con_p);
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
@@ -481,6 +481,58 @@
return (error);
} /* ng_l2cap_qos_ind */
+int
+ng_l2cap_lp_enc_change(ng_l2cap_p l2cap, struct ng_mesg *msg)
+{
+ ng_hci_lp_enc_change_ep *ep = NULL;
+ ng_l2cap_con_p con = NULL;
+ int error = 0;
+ ng_l2cap_chan_p ch = NULL;
+ /* Check message */
+ if (msg->header.arglen != sizeof(*ep)) {
+ NG_L2CAP_ALERT(
+"%s: %s - invalid LP_ENCChange message size\n",
+ __func__, NG_NODE_NAME(l2cap->node));
+ error = EMSGSIZE;
+ goto out;
+ }
+
+ ep = (ng_hci_lp_enc_change_ep *) (msg->data);
+
+ /* Check if we have this connection */
+ con = ng_l2cap_con_by_handle(l2cap, ep->con_handle);
+ if (con == NULL) {
+ NG_L2CAP_ERR(
+"%s: %s - unexpected LP_Enc Change Event. " \
+"Connection does not exist, con_handle=%d\n",
+ __func__, NG_NODE_NAME(l2cap->node), ep->con_handle);
+ error = ENOENT;
+ goto out;
+ }
+
+ /* Verify connection state */
+ if (con->state != NG_L2CAP_CON_OPEN) {
+ NG_L2CAP_ERR(
+"%s: %s - unexpected ENC_CHANGE event. " \
+"Invalid connection state, state=%d, con_handle=%d\n",
+ __func__, NG_NODE_NAME(l2cap->node), con->state,
+ con->con_handle);
+ error = EINVAL;
+ goto out;
+ }
+
+ con->encryption = ep->status;
+
+ LIST_FOREACH(ch, &l2cap->chan_list, next){
+ if((ch->con->con_handle == ep->con_handle) &&
+ (ch->con->linktype == ep->link_type))
+ ng_l2cap_l2ca_encryption_change(ch, ep->status);
+ }
+
+out:
+ return (error);
+} /* ng_l2cap_enc_change */
+
/*
* Prepare L2CAP packet. Prepend packet with L2CAP packet header and then
* segment it according to HCI MTU.
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_main.c
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_main.c
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_main.c
@@ -350,7 +350,9 @@
case NGM_HCI_LP_QOS_IND:
error = ng_l2cap_lp_qos_ind(l2cap, msg);
break;
-
+ case NGM_HCI_LP_ENC_CHG:
+ error = ng_l2cap_lp_enc_change(l2cap, msg);
+ break;
default:
error = EINVAL;
break;
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
@@ -114,7 +114,7 @@
con->l2cap = l2cap;
con->state = NG_L2CAP_CON_CLOSED;
-
+ con->encryption = 0;
/*
* XXX
*
@@ -340,6 +340,8 @@
return (NULL);
if(idtype == NG_L2CAP_L2CA_IDTYPE_ATT){
ch->scid = ch->dcid = NG_L2CAP_ATT_CID;
+ }else if(idtype == NG_L2CAP_L2CA_IDTYPE_SMP){
+ ch->scid = ch->dcid = NG_L2CAP_SMP_CID;
}else{
ch->scid = ng_l2cap_get_cid(l2cap,
(con->linktype!= NG_HCI_LINK_ACL));
@@ -379,7 +381,8 @@
{
ng_l2cap_chan_p ch = NULL;
- if(idtype == NG_L2CAP_L2CA_IDTYPE_ATT){
+ if((idtype == NG_L2CAP_L2CA_IDTYPE_ATT)||
+ (idtype == NG_L2CAP_L2CA_IDTYPE_SMP)){
return NULL;
}
@@ -390,7 +393,6 @@
if((idtype != NG_L2CAP_L2CA_IDTYPE_LE)&&
(ch->con->linktype != NG_HCI_LINK_ACL ))
continue;
-
if (ch->scid == scid)
break;
}
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.h
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.h
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.h
@@ -74,6 +74,6 @@
struct mbuf *);
int ng_l2cap_l2ca_enable_clt (ng_l2cap_p, struct ng_mesg *);
-
+int ng_l2cap_l2ca_encryption_change(ng_l2cap_chan_p , uint16_t );
#endif /* ndef _NETGRAPH_L2CAP_ULPI_H_ */
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c
@@ -130,6 +130,10 @@
_ng_l2cap_con_rsp(cmd->aux, cmd->ident, NG_L2CAP_ATT_CID,
NG_L2CAP_ATT_CID, 0, 0);
cmd->aux->m_flags |= M_PROTO2;
+ }else if(ip->idtype == NG_L2CAP_L2CA_IDTYPE_SMP){
+ _ng_l2cap_con_rsp(cmd->aux, cmd->ident, NG_L2CAP_SMP_CID,
+ NG_L2CAP_SMP_CID, 0, 0);
+ cmd->aux->m_flags |= M_PROTO2;
}else{
_ng_l2cap_con_req(cmd->aux, cmd->ident, ch->psm, ch->scid);
}
@@ -191,13 +195,16 @@
if(ch->scid == NG_L2CAP_ATT_CID){
op->idtype = NG_L2CAP_L2CA_IDTYPE_ATT;
op->lcid = ch->con->con_handle;
+ }else if(ch->scid == NG_L2CAP_SMP_CID){
+ op->idtype = NG_L2CAP_L2CA_IDTYPE_SMP;
+ op->lcid = ch->con->con_handle;
}else{
op->idtype = (ch->con->linktype == NG_HCI_LINK_ACL)?
NG_L2CAP_L2CA_IDTYPE_BREDR :
NG_L2CAP_L2CA_IDTYPE_LE;
op->lcid = ch->scid;
}
-
+ op->encryption = ch->con->encryption;
op->result = result;
op->status = status;
@@ -234,7 +241,8 @@
ip = (ng_l2cap_l2ca_con_rsp_ip *)(msg->data);
/* Check if we have this channel */
- if(ip->lcid != NG_L2CAP_ATT_CID){
+ if((ip->lcid != NG_L2CAP_ATT_CID)&&
+ (ip->lcid != NG_L2CAP_SMP_CID)){
ch = ng_l2cap_chan_by_scid(l2cap, ip->lcid
,(ip->linktype == NG_HCI_LINK_ACL)?
NG_L2CAP_L2CA_IDTYPE_BREDR:
@@ -281,7 +289,8 @@
/* Check result */
switch (ip->result) {
case NG_L2CAP_SUCCESS:
- ch->state = (ch->scid == NG_L2CAP_ATT_CID)?
+ ch->state = ((ch->scid == NG_L2CAP_ATT_CID)||
+ (ch->scid == NG_L2CAP_SMP_CID))?
NG_L2CAP_OPEN : NG_L2CAP_CONFIG;
ch->cfg_state = 0;
break;
@@ -324,6 +333,53 @@
return (error);
} /* ng_l2cap_l2ca_con_rsp_req */
+int ng_l2cap_l2ca_encryption_change(ng_l2cap_chan_p ch, uint16_t result)
+{
+ ng_l2cap_p l2cap = ch->con->l2cap;
+ struct ng_mesg *msg = NULL;
+ ng_l2cap_l2ca_enc_chg_op *op = NULL;
+ int error = 0;
+
+ /* Check if upstream hook is connected and valid */
+ if (l2cap->l2c == NULL || NG_HOOK_NOT_VALID(l2cap->l2c)) {
+ NG_L2CAP_ERR(
+"%s: %s - unable to send L2CA_ConnectRsp response message. " \
+"Hook is not connected or valid, psm=%d\n",
+ __func__, NG_NODE_NAME(l2cap->node), ch->psm);
+
+ return (ENOTCONN);
+ }
+
+ /* Create and send L2CA_ConnectRsp response message */
+ NG_MKMESSAGE(msg, NGM_L2CAP_COOKIE, NGM_L2CAP_L2CA_ENC_CHANGE,
+ sizeof(*op), M_NOWAIT);
+ if (msg == NULL)
+ error = ENOMEM;
+ else {
+ msg->header.token = 0;
+ msg->header.flags |= NGF_RESP;
+
+ op = (ng_l2cap_l2ca_enc_chg_op *)(msg->data);
+ op->result = result;
+ if(ch->scid ==NG_L2CAP_ATT_CID||
+ ch->scid ==NG_L2CAP_SMP_CID){
+ op->lcid = ch->con->con_handle;
+ op->idtype = (ch->scid==NG_L2CAP_ATT_CID)?
+ NG_L2CAP_L2CA_IDTYPE_ATT:
+ NG_L2CAP_L2CA_IDTYPE_SMP;
+ }else{
+ op->idtype =(ch->con->linktype ==NG_HCI_LINK_ACL)?
+ NG_L2CAP_L2CA_IDTYPE_BREDR:
+ NG_L2CAP_L2CA_IDTYPE_LE;
+ }
+
+
+ NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->l2c, 0);
+ }
+
+ return (error);
+
+}
/*
* Send L2CAP_ConnectRsp response to the upper layer
*/
@@ -399,6 +455,7 @@
ip->psm = ch->psm;
ip->ident = ch->ident;
ip->linktype = ch->con->linktype;
+
NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->l2c, 0);
}
@@ -501,7 +558,8 @@
/* Adjust channel state for re-configuration */
if (ch->state == NG_L2CAP_OPEN) {
- ch->state = (ch->scid == NG_L2CAP_ATT_CID)?
+ ch->state = ((ch->scid == NG_L2CAP_ATT_CID)||
+ (ch->scid == NG_L2CAP_SMP_CID))?
NG_L2CAP_OPEN : NG_L2CAP_CONFIG;
ch->cfg_state = 0;
}
@@ -812,7 +870,10 @@
if (l2ca_hdr->idtype == NG_L2CAP_L2CA_IDTYPE_ATT){
ch = ng_l2cap_chan_by_conhandle(l2cap, NG_L2CAP_ATT_CID,
l2ca_hdr->lcid);
- } else{
+ } else if (l2ca_hdr->idtype == NG_L2CAP_L2CA_IDTYPE_SMP){
+ ch = ng_l2cap_chan_by_conhandle(l2cap, NG_L2CAP_SMP_CID,
+ l2ca_hdr->lcid);
+ }else{
if (l2ca_hdr->lcid < NG_L2CAP_FIRST_CID) {
NG_L2CAP_ERR(
"%s: %s - invalid L2CA Data packet. Inavlid channel ID, cid=%d\n",
@@ -901,6 +962,9 @@
if(ch->scid == NG_L2CAP_ATT_CID){
op->idtype = NG_L2CAP_L2CA_IDTYPE_ATT;
op->lcid = ch->con->con_handle;
+ }else if(ch->scid == NG_L2CAP_SMP_CID){
+ op->idtype = NG_L2CAP_L2CA_IDTYPE_SMP;
+ op->lcid = ch->con->con_handle;
}else{
op->idtype = (ch->con->linktype == NG_HCI_LINK_ACL)?
NG_L2CAP_L2CA_IDTYPE_BREDR :
@@ -928,7 +992,8 @@
int error = 0;
int idtype;
uint16_t *idp;
-
+ int silent = 0;
+
NG_L2CAP_M_PULLUP(con->rx_pkt, sizeof(*hdr));
if (con->rx_pkt == NULL)
return (ENOBUFS);
@@ -945,6 +1010,17 @@
* Here,ATT channel is distinguished by
* connection handle
*/
+ hdr->dcid = con->con_handle;
+ silent = 1;
+ }else if(hdr->dcid == NG_L2CAP_SMP_CID){
+ idtype = NG_L2CAP_L2CA_IDTYPE_SMP;
+ ch = ng_l2cap_chan_by_conhandle(l2cap, NG_L2CAP_SMP_CID,
+ con->con_handle);
+ /*
+ * Here,SMP channel is distinguished by
+ * connection handle
+ */
+ silent = 1;
hdr->dcid = con->con_handle;
}else{
idtype = (con->linktype==NG_HCI_LINK_ACL)?
@@ -953,7 +1029,8 @@
ch = ng_l2cap_chan_by_scid(l2cap, hdr->dcid, idtype);
}
if (ch == NULL) {
- NG_L2CAP_ERR(
+ if(!silent)
+ NG_L2CAP_ERR(
"%s: %s - unexpected L2CAP data packet. Channel does not exist, cid=%d, idtype=%d\n",
__func__, NG_NODE_NAME(l2cap->node), hdr->dcid, idtype);
error = ENOENT;
@@ -1170,6 +1247,21 @@
error = EINVAL;
}
goto out;
+ }else if(ip->idtype == NG_L2CAP_L2CA_IDTYPE_SMP){
+ /* Don't send Disconnect request on L2CAP Layer*/
+ ch = ng_l2cap_chan_by_conhandle(l2cap, NG_L2CAP_SMP_CID,
+ ip->lcid);
+
+ if(ch != NULL){
+ ng_l2cap_free_chan(ch);
+ }else{
+ NG_L2CAP_ERR(
+"%s: %s - unexpected L2CA_Disconnect request message. " \
+"Channel does not exist, conhandle=%d\n",
+ __func__, NG_NODE_NAME(l2cap->node), ip->lcid);
+ error = EINVAL;
+ }
+ goto out;
}else{
/* Check if we have this channel */
ch = ng_l2cap_chan_by_scid(l2cap, ip->lcid, ip->idtype);
Index: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_var.h
===================================================================
--- head/sys/netgraph/bluetooth/l2cap/ng_l2cap_var.h
+++ head/sys/netgraph/bluetooth/l2cap/ng_l2cap_var.h
@@ -119,7 +119,8 @@
u_int8_t ident; /* last allocated ident */
uint8_t linktype;
-
+ uint8_t encryption;
+
TAILQ_HEAD(, ng_l2cap_cmd) cmd_list; /* pending L2CAP cmds */
struct mbuf *tx_pkt; /* xmitted L2CAP packet */
Index: head/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
===================================================================
--- head/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
+++ head/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
@@ -213,7 +213,7 @@
static int ng_btsocket_l2cap_result2errno(int);
static int ng_btsock_l2cap_addrtype_to_linktype(int addrtype);
-static int ng_btsock_l2cap_pcb_to_idtype(struct ng_btsocket_l2cap_pcb *);
+
#define ng_btsocket_l2cap_wakeup_input_task() \
taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_l2cap_queue_task)
@@ -221,16 +221,6 @@
taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_l2cap_rt_task)
-int ng_btsock_l2cap_pcb_to_idtype(struct ng_btsocket_l2cap_pcb *pcb)
-{
- if(pcb->dsttype == BDADDR_BREDR){
- return NG_L2CAP_L2CA_IDTYPE_BREDR;
- }else if(pcb->psm == 0){
- return NG_L2CAP_L2CA_IDTYPE_ATT;
- }else{
- return NG_L2CAP_L2CA_IDTYPE_LE;
- }
-}
int ng_btsock_l2cap_addrtype_to_linktype(int addrtype)
{
@@ -473,11 +463,15 @@
}
if (op->result == NG_L2CAP_SUCCESS){
- if(ng_btsock_l2cap_pcb_to_idtype(pcb) ==
- NG_L2CAP_L2CA_IDTYPE_ATT){
- pcb->state = NG_BTSOCKET_L2CAP_OPEN;
- soisconnected(pcb->so);
- pcb->cid = op->lcid;
+ if((pcb->idtype == NG_L2CAP_L2CA_IDTYPE_ATT)||
+ (pcb->idtype == NG_L2CAP_L2CA_IDTYPE_SMP)){
+ pcb->encryption = op->encryption; pcb->cid = op->lcid;
+ if(pcb->need_encrypt && !(pcb->encryption)){
+ pcb->state = NG_BTSOCKET_L2CAP_W4_ENC_CHANGE;
+ }else{
+ pcb->state = NG_BTSOCKET_L2CAP_OPEN;
+ soisconnected(pcb->so);
+ }
}else{
/*
* Channel is now open, so update local channel ID and
@@ -486,7 +480,7 @@
*/
pcb->cid = op->lcid;
-
+ pcb->encryption = op->encryption;
error = ng_btsocket_l2cap_send_l2ca_cfg_req(pcb);
if (error != 0) {
/* Send disconnect request with "zero" token */
@@ -513,7 +507,6 @@
pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
soisdisconnected(pcb->so);
}
-
mtx_unlock(&pcb->pcb_mtx);
mtx_unlock(&ng_btsocket_l2cap_sockets_mtx);
@@ -702,7 +695,40 @@
return (error);
} /* ng_btsocket_l2cap_process_l2ca_con_ind */
+/*Encryption Change*/
+static int ng_btsocket_l2cap_process_l2ca_enc_change(struct ng_mesg *msg, ng_btsocket_l2cap_rtentry_p rt)
+{
+ ng_l2cap_l2ca_enc_chg_op *op = NULL;
+ ng_btsocket_l2cap_pcb_t *pcb = NULL;
+
+
+ if (msg->header.arglen != sizeof(*op))
+ return (EMSGSIZE);
+
+ op = (ng_l2cap_l2ca_enc_chg_op *)(msg->data);
+
+ pcb = ng_btsocket_l2cap_pcb_by_cid(&rt->src, op->lcid,
+ op->idtype);
+ mtx_lock(&pcb->pcb_mtx);
+ pcb->encryption = op->result;
+
+ if(pcb->need_encrypt){
+ if(pcb->state != NG_BTSOCKET_L2CAP_W4_ENC_CHANGE){
+ NG_BTSOCKET_L2CAP_WARN("%s: Invalid pcb status %d",
+ __func__, pcb->state);
+ }else if(pcb->encryption){
+ pcb->state = NG_BTSOCKET_L2CAP_OPEN;
+ soisconnected(pcb->so);
+ }else{
+ pcb->so->so_error = EPERM;
+ pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
+ soisdisconnected(pcb->so);
+ }
+ }
+ mtx_unlock(&pcb->pcb_mtx);
+ return 0;
+}
/*
* Process L2CA_Config response
*/
@@ -1215,7 +1241,7 @@
bcopy(&pcb->dst, &ip->bdaddr, sizeof(ip->bdaddr));
ip->psm = pcb->psm;
ip->linktype = ng_btsock_l2cap_addrtype_to_linktype(pcb->dsttype);
- ip->idtype = ng_btsock_l2cap_pcb_to_idtype(pcb);
+ ip->idtype = pcb->idtype;
NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg,pcb->rt->hook, 0);
return (error);
@@ -1354,7 +1380,7 @@
ip = (ng_l2cap_l2ca_discon_ip *)(msg->data);
ip->lcid = pcb->cid;
- ip->idtype = ng_btsock_l2cap_pcb_to_idtype(pcb);
+ ip->idtype = pcb->idtype;
NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg,pcb->rt->hook, 0);
@@ -1441,7 +1467,9 @@
hdr->dcid, hdr->length);
if ((hdr->dcid >= NG_L2CAP_FIRST_CID) ||
- (idtype == NG_L2CAP_L2CA_IDTYPE_ATT)){
+ (idtype == NG_L2CAP_L2CA_IDTYPE_ATT)||
+ (idtype == NG_L2CAP_L2CA_IDTYPE_SMP)
+ ){
mtx_lock(&ng_btsocket_l2cap_sockets_mtx);
@@ -1707,7 +1735,10 @@
case NGM_L2CAP_L2CA_WRITE: /* L2CA_Write response */
ng_btsocket_l2cap_process_l2ca_write_rsp(msg, rt);
break;
+ case NGM_L2CAP_L2CA_ENC_CHANGE:
+ ng_btsocket_l2cap_process_l2ca_enc_change(msg, rt);
+ break;
/* XXX FIXME add other L2CA messages */
default:
@@ -1764,6 +1795,7 @@
case NGM_L2CAP_L2CA_DISCON:
case NGM_L2CAP_L2CA_DISCON_IND:
case NGM_L2CAP_L2CA_WRITE:
+ case NGM_L2CAP_L2CA_ENC_CHANGE:
/* XXX FIXME add other L2CA messages */
ng_btsocket_l2cap_l2ca_msg_input(msg, hook);
break;
@@ -2135,7 +2167,7 @@
struct sockaddr_l2cap ba;
ng_btsocket_l2cap_rtentry_t *rt = NULL;
int have_src, error = 0;
-
+ int idtype = NG_L2CAP_L2CA_IDTYPE_BREDR;
/* Check socket */
if (pcb == NULL)
return (EINVAL);
@@ -2164,9 +2196,16 @@
if((sa->l2cap_bdaddr_type == BDADDR_BREDR)&&
(sa->l2cap_psm == 0))
return EDESTADDRREQ;
- if((sa->l2cap_bdaddr_type != BDADDR_BREDR)&&
- (sa->l2cap_cid != NG_L2CAP_ATT_CID)){
- return EINVAL;
+ if(sa->l2cap_bdaddr_type != BDADDR_BREDR){
+ if(sa->l2cap_cid == NG_L2CAP_ATT_CID){
+ idtype = NG_L2CAP_L2CA_IDTYPE_ATT;
+ }else if (sa->l2cap_cid == NG_L2CAP_SMP_CID){
+ idtype =NG_L2CAP_L2CA_IDTYPE_SMP;
+ }else{
+ //if cid == 0 idtype = NG_L2CAP_L2CA_IDTYPE_LE;
+ // Not supported yet
+ return EINVAL;
+ }
}
if (pcb->psm != 0 && pcb->psm != le16toh(sa->l2cap_psm))
return (EINVAL);
@@ -2185,8 +2224,8 @@
bcopy(&sa->l2cap_bdaddr, &pcb->dst, sizeof(pcb->dst));
pcb->psm = le16toh(sa->l2cap_psm);
pcb->dsttype = sa->l2cap_bdaddr_type;
- pcb->cid = sa->l2cap_cid;
-
+ pcb->cid = 0;
+ pcb->idtype = idtype;
pcb->rt = NULL;
have_src = bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(pcb->src));
@@ -2211,7 +2250,7 @@
bcopy(&rt->src, &pcb->src, sizeof(pcb->src));
pcb->srctype =
(sa->l2cap_bdaddr_type == BDADDR_BREDR)?
- BDADDR_BREDR : BDADDR_LE_RANDOM;
+ BDADDR_BREDR : BDADDR_LE_PUBLIC;
}
} else
error = EHOSTUNREACH;
@@ -2297,6 +2336,11 @@
error = sooptcopyout(sopt, &pcb->flush_timo,
sizeof(pcb->flush_timo));
break;
+ case SO_L2CAP_ENCRYPTED: /* get encrypt required */
+ error = sooptcopyout(sopt, &pcb->need_encrypt,
+ sizeof(pcb->need_encrypt));
+ break;
+
default:
error = ENOPROTOOPT;
@@ -2337,7 +2381,17 @@
if (error == 0)
pcb->flush_timo = v.flush_timo;
break;
-
+ case SO_L2CAP_ENCRYPTED: /*set connect encryption opt*/
+ if((pcb->state != NG_BTSOCKET_L2CAP_OPEN) &&
+ (pcb->state != NG_BTSOCKET_L2CAP_W4_ENC_CHANGE)){
+ error = sooptcopyin(sopt, &v, sizeof(v),
+ sizeof(v.encryption));
+ if(error == 0)
+ pcb->need_encrypt = (v.encryption)?1:0;
+ }else{
+ error = EINVAL;
+ }
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -2489,7 +2543,17 @@
sa.l2cap_psm = htole16(pcb->psm);
sa.l2cap_len = sizeof(sa);
sa.l2cap_family = AF_BLUETOOTH;
- sa.l2cap_cid = 0;
+ switch(pcb->idtype){
+ case NG_L2CAP_L2CA_IDTYPE_ATT:
+ sa.l2cap_cid = NG_L2CAP_ATT_CID;
+ break;
+ case NG_L2CAP_L2CA_IDTYPE_SMP:
+ sa.l2cap_cid = NG_L2CAP_SMP_CID;
+ break;
+ default:
+ sa.l2cap_cid = 0;
+ break;
+ }
sa.l2cap_bdaddr_type = pcb->dsttype;
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
@@ -2608,7 +2672,7 @@
hdr->token = pcb->token;
hdr->length = m->m_pkthdr.len - sizeof(*hdr);
hdr->lcid = pcb->cid;
- hdr->idtype = ng_btsock_l2cap_pcb_to_idtype(pcb);
+ hdr->idtype = pcb->idtype;
NG_BTSOCKET_L2CAP_INFO(
"%s: Sending packet: len=%d, length=%d, lcid=%d, token=%d, state=%d\n",
__func__, m->m_pkthdr.len, hdr->length, hdr->lcid,
@@ -2721,7 +2785,7 @@
LIST_FOREACH(p, &ng_btsocket_l2cap_sockets, next){
if (p->cid == cid &&
bcmp(src, &p->src, sizeof(p->src)) == 0&&
- ng_btsock_l2cap_pcb_to_idtype(p) == idtype)
+ p->idtype == idtype)
break;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 11, 2:21 PM (1 m, 11 s ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13926483
Default Alt Text
D3981.diff (26 KB)
Attached To
Mode
D3981: Bluetooth LE Security Manager Protocol Support
Attached
Detach File
Event Timeline
Log In to Comment