int ng_hci_lp_con_req(ng_hci_unit_p unit, item_p item, hook_p hook) { int link_type; if ((unit->state & NG_HCI_UNIT_READY) != NG_HCI_UNIT_READY) { NG_HCI_WARN( "%s: %s - unit is not ready, state=%#x\n", __func__, NG_NODE_NAME(unit->node), unit->state); NG_FREE_ITEM(item); return (ENXIO); } if (NGI_MSG(item)->header.arglen != sizeof(ng_hci_lp_con_req_ep)) { NG_HCI_ALERT( "%s: %s - invalid LP_ConnectReq message size=%d\n", __func__, NG_NODE_NAME(unit->node), NGI_MSG(item)->header.arglen); NG_FREE_ITEM(item); return (EMSGSIZE); } link_type = ((ng_hci_lp_con_req_ep *)(NGI_MSG(item)->data))->link_type; switch(link_type){ case NG_HCI_LINK_ACL: return (ng_hci_lp_acl_con_req(unit, item, hook)); case NG_HCI_LINK_SCO: if (hook != unit->sco ) { NG_HCI_WARN( "%s: %s - LP_ConnectReq for SCO connection came from wrong hook=%p\n", __func__, NG_NODE_NAME(unit->node), hook); NG_FREE_ITEM(item); return (EINVAL); } return (ng_hci_lp_sco_con_req(unit, item, hook)); case NG_HCI_LINK_LE_PUBLIC: case NG_HCI_LINK_LE_RANDOM: return (ng_hci_lp_le_con_req(unit, item, hook, link_type)); default: panic("%s: link_type invalid.", __func__); } return (EINVAL); } /* ng_hci_lp_con_req */
int ng_hci_lp_con_req(ng_hci_unit_p unit, item_p item, hook_p hook) { if ((unit->state & NG_HCI_UNIT_READY) != NG_HCI_UNIT_READY) { NG_HCI_WARN( "%s: %s - unit is not ready, state=%#x\n", __func__, NG_NODE_NAME(unit->node), unit->state); NG_FREE_ITEM(item); return (ENXIO); } if (NGI_MSG(item)->header.arglen != sizeof(ng_hci_lp_con_req_ep)) { NG_HCI_ALERT( "%s: %s - invalid LP_ConnectReq message size=%d\n", __func__, NG_NODE_NAME(unit->node), NGI_MSG(item)->header.arglen); NG_FREE_ITEM(item); return (EMSGSIZE); } if (((ng_hci_lp_con_req_ep *)(NGI_MSG(item)->data))->link_type == NG_HCI_LINK_ACL) return (ng_hci_lp_acl_con_req(unit, item, hook)); if (hook != unit->sco) { NG_HCI_WARN( "%s: %s - LP_ConnectReq for SCO connection came from wrong hook=%p\n", __func__, NG_NODE_NAME(unit->node), hook); NG_FREE_ITEM(item); return (EINVAL); } return (ng_hci_lp_sco_con_req(unit, item, hook)); } /* ng_hci_lp_con_req */
int ng_hci_lp_discon_req(ng_hci_unit_p unit, item_p item, hook_p hook) { struct discon_req { ng_hci_cmd_pkt_t hdr; ng_hci_discon_cp cp; } __attribute__ ((packed)) *req = NULL; ng_hci_lp_discon_req_ep *ep = NULL; ng_hci_unit_con_p con = NULL; struct mbuf *m = NULL; int error = 0; /* Check if unit is ready */ if ((unit->state & NG_HCI_UNIT_READY) != NG_HCI_UNIT_READY) { NG_HCI_WARN( "%s: %s - unit is not ready, state=%#x\n", __func__, NG_NODE_NAME(unit->node), unit->state); error = ENXIO; goto out; } if (NGI_MSG(item)->header.arglen != sizeof(*ep)) { NG_HCI_ALERT( "%s: %s - invalid LP_DisconnectReq message size=%d\n", __func__, NG_NODE_NAME(unit->node), NGI_MSG(item)->header.arglen); error = EMSGSIZE; goto out; } ep = (ng_hci_lp_discon_req_ep *)(NGI_MSG(item)->data); con = ng_hci_con_by_handle(unit, ep->con_handle); if (con == NULL) { NG_HCI_ERR( "%s: %s - invalid connection handle=%d\n", __func__, NG_NODE_NAME(unit->node), ep->con_handle); error = ENOENT; goto out; } if (con->state != NG_HCI_CON_OPEN) { NG_HCI_ERR( "%s: %s - invalid connection state=%d, handle=%d\n", __func__, NG_NODE_NAME(unit->node), con->state, ep->con_handle); error = EINVAL; goto out; } /* * Create HCI command */ MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { error = ENOBUFS; goto out; } m->m_pkthdr.len = m->m_len = sizeof(*req); req = mtod(m, struct discon_req *); req->hdr.type = NG_HCI_CMD_PKT; req->hdr.length = sizeof(req->cp); req->hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL, NG_HCI_OCF_DISCON)); req->cp.con_handle = htole16(ep->con_handle); req->cp.reason = ep->reason; /* * Queue and send HCI command */ NG_BT_MBUFQ_ENQUEUE(&unit->cmdq, m); if (!(unit->state & NG_HCI_UNIT_COMMAND_PENDING)) error = ng_hci_send_command(unit); out: NG_FREE_ITEM(item); return (error); } /* ng_hci_lp_discon_req */