void l2cap_task_handler(u8 event_id) { u8 *output; u16 osize; u8 edr; u16 cid; gap_get_buffer(&output, &osize); output += 4; osize -= 4; switch (event_id) { case L2CAP_SEND_SIG_EVENT_ID: edr = 1; cid = L2CAP_SIG_CID; l2sig_output(output, &osize); break; case L2CAP_SEND_RFCOMM_EVENT_ID: edr = 1; cid = l2cap.rfcomm_cid; rfcomm_output(output, &osize); break; case L2CAP_SEND_GATT_EVENT_ID: edr = 0; cid = L2CAP_ATT_CID; gatt_output(output, &osize); break; case L2CAP_SEND_SDP_EVENT_ID: edr = 1; cid = l2cap.sdp_cid; sdp_output(output, &osize); break; } output -= 4; bt_write_u16(output, osize); bt_write_u16(output + 2, cid); osize += 4; gap_send(output, osize, edr); }
static void hci_send_acl(u8* output, u16 osize) { u16 payload_size; u8 edr; payload_size = osize - 4; l2cap_output(output + 4, &payload_size, &edr); if (payload_size) { #if !DISABLE_BT_CLASSICAL if (edr) { bt_write_u16(output, hci.edr.hconn | 0x2000); } else #endif { bt_write_u16(output, hci.le.hconn | 0x2000); } bt_write_u16(output + 2, payload_size); hci_dumphex("ACLO", output, payload_size + 4); hci_write(BT_ACL_OUT_CHANNEL, payload_size + 4); } }
static void led_attr_read(u16 handle, u8* buffer, u16* size, u16 offset) { switch (handle & 0xff) { case LED_SERVICE_DECL: bt_write_u16(buffer, LED_SERVICE_UUID); *size = 2; break; case LED_STATE_DECL: GATT_WRITE_CHAR_DECL(buffer, handle, LED_STATE_UUID, BT_GATT_CHAR_READ | BT_GATT_CHAR_WRITE, size); break; case LED_STATE_VALUE: buffer[0] = led.state; *size = 1; break; } }
static void l2sig_output(u8* output, u16* osize) { u16 result; switch (l2cap.request.code) { case L2CAP_CONNECTION_REQUEST: switch (l2cap.request.u.connection.psm) { case L2CAP_SDP_PSM: l2cap.sdp_cid = l2cap.request.u.connection.scid; result = L2CAP_CONNECTION_SUCCESSFUL; break; case L2CAP_RFCOMM_PSM: l2cap.rfcomm_cid = l2cap.request.u.connection.scid; result = L2CAP_CONNECTION_SUCCESSFUL; break; default: result = L2CAP_PSM_NOT_SUPPORTED; } output[0] = L2CAP_CONNECTION_RESPONSE; output[1] = l2cap.request.id; bt_write_u16(output + 2, 8); bt_write_u16(output + 4, l2cap.request.u.connection.scid); bt_write_u16(output + 6, l2cap.request.u.connection.scid); bt_write_u16(output + 8, result); bt_write_u16(output + 10, 0); *osize = 12; break; case L2CAP_CONFIGURE_REQUEST: output[0] = L2CAP_CONFIGURE_RESPONSE; output[1] = l2cap.request.id; bt_write_u16(output + 2, 8); bt_write_u16(output + 4, l2cap.request.u.configure.dcid); bt_write_u16(output + 6, 0); bt_write_u16(output + 8, 0); output[10] = 1; output[11] = 2; bt_write_u16(output + 12, CFG_L2CAP_MTU_EDR); *osize = 14; l2cap.request.code = INTERNAL_SENDCFG_REQUEST; sys_set_event(L2CAP_TASK_ID, L2CAP_SEND_SIG_EVENT_ID); break; case L2CAP_DISCONNECTION_REQUEST: output[0] = L2CAP_DISCONNECTION_RESPONSE; output[1] = l2cap.request.id; bt_write_u16(output + 2, 4); bt_write_u16(output + 4, l2cap.request.u.disconnection.dcid); bt_write_u16(output + 6, l2cap.request.u.disconnection.scid); *osize = 8; break; case L2CAP_INFORMATION_REQUEST: output[0] = L2CAP_INFORMATION_RESPONSE; output[1] = l2cap.request.id; bt_write_u16(output + 2, 4); bt_write_u16(output + 4, l2cap.request.u.info.type); bt_write_u16(output + 6, 1); *osize = 8; break; case INTERNAL_SENDCFG_REQUEST: output[0] = L2CAP_CONFIGURE_REQUEST; output[1] = l2cap.request.id; bt_write_u16(output + 2, 8); bt_write_u16(output + 4, l2cap.request.u.configure.dcid); bt_write_u16(output + 6, 0); output[8] = 1; output[9] = 2; bt_write_u16(output + 10, CFG_L2CAP_MTU_EDR); *osize = 12; } }