status_t send_l2cap_reject(HciConnection* conn, uint8 ident, uint16 reason, uint16 mtu, uint16 scid, uint16 dcid) { L2capFrame* cmd = NULL; cmd = btCoreData->SpawnSignal(conn, NULL, l2cap_cmd_rej(ident, reason, mtu, scid, dcid), ident, L2CAP_CMD_REJ); if (cmd == NULL) return ENOMEM; /* Link command to the queue */ SchedConnectionPurgeThread(conn); return B_OK; }
static void l2cap_le_sig(struct bthost *bthost, struct btconn *conn, const void *data, uint16_t len) { const struct bt_l2cap_hdr_sig *hdr = data; struct bt_l2cap_pdu_cmd_reject rej; uint16_t hdr_len; bool ret; if (len < sizeof(*hdr)) goto reject; hdr_len = le16_to_cpu(hdr->len); if (sizeof(*hdr) + hdr_len != len) goto reject; switch (hdr->code) { case BT_L2CAP_PDU_CMD_REJECT: ret = l2cap_cmd_rej(bthost, conn, hdr->ident, data + sizeof(*hdr), hdr_len); break; case BT_L2CAP_PDU_CONN_PARAM_REQ: ret = l2cap_conn_param_req(bthost, conn, hdr->ident, data + sizeof(*hdr), hdr_len); break; case BT_L2CAP_PDU_CONN_PARAM_RSP: ret = l2cap_conn_param_rsp(bthost, conn, hdr->ident, data + sizeof(*hdr), hdr_len); break; default: printf("Unknown L2CAP code 0x%02x\n", hdr->code); ret = false; } handle_pending_l2reqs(bthost, conn, hdr->ident, hdr->code, data + sizeof(*hdr), hdr_len); if (ret) return; reject: memset(&rej, 0, sizeof(rej)); l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_CMD_REJECT, 0, &rej, sizeof(rej)); }