status_t l2cap_cfg_req_ind(L2capChannel* channel) { // if our configuration has not been yet sent ... if (!(channel->cfgState & L2CAP_CFG_OUT_SENT)) { // TODO: check if we can handle this conf // send config_rsp net_buffer* buf = l2cap_cfg_rsp(channel->ident, channel->dcid, 0, L2CAP_SUCCESS, NULL); L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, channel->ident, L2CAP_CFG_RSP); if (cmd == NULL) { gBufferModule->free(buf); channel->state = L2CAP_CHAN_CLOSED; return ENOMEM; } // Link command to the queue SchedConnectionPurgeThread(channel->conn); // set status channel->cfgState |= L2CAP_CFG_OUT_SENT; } if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) { // Channel can be declared open channel->endpoint->MarkEstablished(); } else if ((channel->cfgState & L2CAP_CFG_IN_SENT) == 0) { // send configuration Request by our side if (channel->endpoint->RequiresConfiguration()) { // TODO: define complete configuration packet } else { // nothing special requested channel->ident = btCoreData->ChannelAllocateIdent(channel->conn); net_buffer* buf = l2cap_cfg_req(channel->ident, channel->dcid, 0, NULL); L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, channel->ident, L2CAP_CFG_REQ); if (cmd == NULL) { gBufferModule->free(buf); channel->state = L2CAP_CHAN_CLOSED; return ENOMEM; } // Link command to the queue SchedConnectionPurgeThread(channel->conn); } channel->cfgState |= L2CAP_CFG_IN_SENT; } return B_OK; }
status_t send_l2cap_cfg_rsp(HciConnection* conn, uint8 ident, uint16 scid, uint16 result, net_buffer* opt) { L2capFrame* cmd = NULL; cmd = btCoreData->SpawnSignal(conn, NULL, l2cap_cfg_rsp(ident, scid, 0, result, opt), ident, L2CAP_CFG_RSP); if (cmd == NULL) { gBufferModule->free(opt); return ENOMEM; } /* Link command to the queue */ SchedConnectionPurgeThread(conn); return B_OK; }