Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Send LP_ConnectReq event to the lower layer protocol. Create new connection | * Send LP_ConnectReq event to the lower layer protocol. Create new connection | ||||
* descriptor and initialize it. Create LP_ConnectReq event and send it to the | * descriptor and initialize it. Create LP_ConnectReq event and send it to the | ||||
* lower layer, then adjust connection state and start timer. The function WILL | * lower layer, then adjust connection state and start timer. The function WILL | ||||
* FAIL if connection to the remote unit already exists. | * FAIL if connection to the remote unit already exists. | ||||
*/ | */ | ||||
int | int | ||||
ng_l2cap_lp_con_req(ng_l2cap_p l2cap, bdaddr_p bdaddr) | ng_l2cap_lp_con_req(ng_l2cap_p l2cap, bdaddr_p bdaddr, int type) | ||||
{ | { | ||||
struct ng_mesg *msg = NULL; | struct ng_mesg *msg = NULL; | ||||
ng_hci_lp_con_req_ep *ep = NULL; | ng_hci_lp_con_req_ep *ep = NULL; | ||||
ng_l2cap_con_p con = NULL; | ng_l2cap_con_p con = NULL; | ||||
int error = 0; | int error = 0; | ||||
/* Verify that we DO NOT have connection to the remote unit */ | /* Verify that we DO NOT have connection to the remote unit */ | ||||
con = ng_l2cap_con_by_addr(l2cap, bdaddr); | con = ng_l2cap_con_by_addr(l2cap, bdaddr, type); | ||||
if (con != NULL) { | if (con != NULL) { | ||||
NG_L2CAP_ALERT( | NG_L2CAP_ALERT( | ||||
"%s: %s - unexpected LP_ConnectReq event. " \ | "%s: %s - unexpected LP_ConnectReq event. " \ | ||||
"Connection already exists, state=%d, con_handle=%d\n", | "Connection already exists, state=%d, con_handle=%d\n", | ||||
__func__, NG_NODE_NAME(l2cap->node), con->state, | __func__, NG_NODE_NAME(l2cap->node), con->state, | ||||
con->con_handle); | con->con_handle); | ||||
return (EEXIST); | return (EEXIST); | ||||
} | } | ||||
/* Check if lower layer protocol is still connected */ | /* Check if lower layer protocol is still connected */ | ||||
if (l2cap->hci == NULL || NG_HOOK_NOT_VALID(l2cap->hci)) { | if (l2cap->hci == NULL || NG_HOOK_NOT_VALID(l2cap->hci)) { | ||||
NG_L2CAP_ERR( | NG_L2CAP_ERR( | ||||
"%s: %s - hook \"%s\" is not connected or valid\n", | "%s: %s - hook \"%s\" is not connected or valid\n", | ||||
__func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI); | __func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI); | ||||
return (ENOTCONN); | return (ENOTCONN); | ||||
} | } | ||||
/* Create and intialize new connection descriptor */ | /* Create and intialize new connection descriptor */ | ||||
con = ng_l2cap_new_con(l2cap, bdaddr); | con = ng_l2cap_new_con(l2cap, bdaddr, type); | ||||
if (con == NULL) | if (con == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
/* Create and send LP_ConnectReq event */ | /* Create and send LP_ConnectReq event */ | ||||
NG_MKMESSAGE(msg, NGM_HCI_COOKIE, NGM_HCI_LP_CON_REQ, | NG_MKMESSAGE(msg, NGM_HCI_COOKIE, NGM_HCI_LP_CON_REQ, | ||||
sizeof(*ep), M_NOWAIT); | sizeof(*ep), M_NOWAIT); | ||||
if (msg == NULL) { | if (msg == NULL) { | ||||
ng_l2cap_free_con(con); | ng_l2cap_free_con(con); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
ep = (ng_hci_lp_con_req_ep *) (msg->data); | ep = (ng_hci_lp_con_req_ep *) (msg->data); | ||||
bcopy(bdaddr, &ep->bdaddr, sizeof(ep->bdaddr)); | bcopy(bdaddr, &ep->bdaddr, sizeof(ep->bdaddr)); | ||||
ep->link_type = NG_HCI_LINK_ACL; | ep->link_type = type; | ||||
con->flags |= NG_L2CAP_CON_OUTGOING; | con->flags |= NG_L2CAP_CON_OUTGOING; | ||||
con->state = NG_L2CAP_W4_LP_CON_CFM; | con->state = NG_L2CAP_W4_LP_CON_CFM; | ||||
ng_l2cap_lp_timeout(con); | ng_l2cap_lp_timeout(con); | ||||
NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->hci, 0); | NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->hci, 0); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (ng_l2cap_lp_untimeout(con) == 0) | if (ng_l2cap_lp_untimeout(con) == 0) | ||||
Show All 27 Lines | if (msg->header.arglen != sizeof(*ep)) { | ||||
NG_L2CAP_ALERT( | NG_L2CAP_ALERT( | ||||
"%s: %s - invalid LP_ConnectCfm[Neg] message size\n", | "%s: %s - invalid LP_ConnectCfm[Neg] message size\n", | ||||
__func__, NG_NODE_NAME(l2cap->node)); | __func__, NG_NODE_NAME(l2cap->node)); | ||||
error = EMSGSIZE; | error = EMSGSIZE; | ||||
goto out; | goto out; | ||||
} | } | ||||
ep = (ng_hci_lp_con_cfm_ep *) (msg->data); | ep = (ng_hci_lp_con_cfm_ep *) (msg->data); | ||||
/* Check if we have requested/accepted this connection */ | /* Check if we have requested/accepted this connection */ | ||||
con = ng_l2cap_con_by_addr(l2cap, &ep->bdaddr); | con = ng_l2cap_con_by_addr(l2cap, &ep->bdaddr, ep->link_type); | ||||
if (con == NULL) { | if (con == NULL) { | ||||
NG_L2CAP_ERR( | NG_L2CAP_ERR( | ||||
"%s: %s - unexpected LP_ConnectCfm event. Connection does not exist\n", | "%s: %s - unexpected LP_ConnectCfm event. Connection does not exist\n", | ||||
__func__, NG_NODE_NAME(l2cap->node)); | __func__, NG_NODE_NAME(l2cap->node)); | ||||
error = ENOENT; | error = ENOENT; | ||||
goto out; | goto out; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | "%s: %s - invalid LP_ConnectInd message size\n", | ||||
__func__, NG_NODE_NAME(l2cap->node)); | __func__, NG_NODE_NAME(l2cap->node)); | ||||
return (EMSGSIZE); | return (EMSGSIZE); | ||||
} | } | ||||
ep = (ng_hci_lp_con_ind_ep *) (msg->data); | ep = (ng_hci_lp_con_ind_ep *) (msg->data); | ||||
/* Make sure we have only one connection to the remote unit */ | /* Make sure we have only one connection to the remote unit */ | ||||
con = ng_l2cap_con_by_addr(l2cap, &ep->bdaddr); | con = ng_l2cap_con_by_addr(l2cap, &ep->bdaddr, ep->link_type); | ||||
if (con != NULL) { | if (con != NULL) { | ||||
NG_L2CAP_ALERT( | NG_L2CAP_ALERT( | ||||
"%s: %s - unexpected LP_ConnectInd event. " \ | "%s: %s - unexpected LP_ConnectInd event. " \ | ||||
"Connection already exists, state=%d, con_handle=%d\n", | "Connection already exists, state=%d, con_handle=%d\n", | ||||
__func__, NG_NODE_NAME(l2cap->node), con->state, | __func__, NG_NODE_NAME(l2cap->node), con->state, | ||||
con->con_handle); | con->con_handle); | ||||
return (EEXIST); | return (EEXIST); | ||||
} | } | ||||
/* Check if lower layer protocol is still connected */ | /* Check if lower layer protocol is still connected */ | ||||
if (l2cap->hci == NULL || NG_HOOK_NOT_VALID(l2cap->hci)) { | if (l2cap->hci == NULL || NG_HOOK_NOT_VALID(l2cap->hci)) { | ||||
NG_L2CAP_ERR( | NG_L2CAP_ERR( | ||||
"%s: %s - hook \"%s\" is not connected or valid", | "%s: %s - hook \"%s\" is not connected or valid", | ||||
__func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI); | __func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI); | ||||
return (ENOTCONN); | return (ENOTCONN); | ||||
} | } | ||||
/* Create and intialize new connection descriptor */ | /* Create and intialize new connection descriptor */ | ||||
con = ng_l2cap_new_con(l2cap, &ep->bdaddr); | con = ng_l2cap_new_con(l2cap, &ep->bdaddr, ep->link_type); | ||||
if (con == NULL) | if (con == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
/* Create and send LP_ConnectRsp event */ | /* Create and send LP_ConnectRsp event */ | ||||
NG_MKMESSAGE(rsp, NGM_HCI_COOKIE, NGM_HCI_LP_CON_RSP, | NG_MKMESSAGE(rsp, NGM_HCI_COOKIE, NGM_HCI_LP_CON_RSP, | ||||
sizeof(*rp), M_NOWAIT); | sizeof(*rp), M_NOWAIT); | ||||
if (rsp == NULL) { | if (rsp == NULL) { | ||||
ng_l2cap_free_con(con); | ng_l2cap_free_con(con); | ||||
▲ Show 20 Lines • Show All 511 Lines • ▼ Show 20 Lines | "%s: %s - hook \"%s\" is not connected or valid", | ||||
} | } | ||||
/* Send ACL data packets */ | /* Send ACL data packets */ | ||||
while (con->pending < con->l2cap->num_pkts && con->tx_pkt != NULL) { | while (con->pending < con->l2cap->num_pkts && con->tx_pkt != NULL) { | ||||
m = con->tx_pkt; | m = con->tx_pkt; | ||||
con->tx_pkt = con->tx_pkt->m_nextpkt; | con->tx_pkt = con->tx_pkt->m_nextpkt; | ||||
m->m_nextpkt = NULL; | m->m_nextpkt = NULL; | ||||
if(m->m_flags &M_PROTO2){ | |||||
ng_l2cap_lp_receive(con->l2cap, m); | |||||
continue; | |||||
} | |||||
NG_L2CAP_INFO( | NG_L2CAP_INFO( | ||||
"%s: %s - sending ACL packet, con_handle=%d, len=%d\n", | "%s: %s - sending ACL packet, con_handle=%d, len=%d\n", | ||||
__func__, NG_NODE_NAME(l2cap->node), con->con_handle, | __func__, NG_NODE_NAME(l2cap->node), con->con_handle, | ||||
m->m_pkthdr.len); | m->m_pkthdr.len); | ||||
NG_SEND_DATA_ONLY(error, l2cap->hci, m); | NG_SEND_DATA_ONLY(error, l2cap->hci, m); | ||||
if (error != 0) { | if (error != 0) { | ||||
NG_L2CAP_ERR( | NG_L2CAP_ERR( | ||||
▲ Show 20 Lines • Show All 129 Lines • Show Last 20 Lines |