static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig_id, uint16_t psm, uint16_t source_cid){ log_info("l2cap_handle_connection_request for handle %u, psm %u cid %u\n", handle, psm, source_cid); l2cap_service_t *service = l2cap_get_service(psm); if (!service) { // 0x0002 PSM not supported l2cap_register_signaling_response(handle, CONNECTION_REQUEST, sig_id, 0x0002); return; } hci_connection_t * hci_connection = connection_for_handle( handle ); if (!hci_connection) { // log_error("no hci_connection for handle %u\n", handle); return; } // alloc structure // log_info("l2cap_handle_connection_request register channel\n"); l2cap_channel_t * channel = (l2cap_channel_t*) btstack_memory_l2cap_channel_get(); if (!channel){ // 0x0004 No resources available l2cap_register_signaling_response(handle, CONNECTION_REQUEST, sig_id, 0x0004); return; } // fill in BD_ADDR_COPY(channel->address, hci_connection->address); channel->psm = psm; channel->handle = handle; channel->connection = service->connection; channel->packet_handler = service->packet_handler; channel->local_cid = l2cap_next_local_cid(); channel->remote_cid = source_cid; channel->local_mtu = service->mtu; channel->remote_mtu = L2CAP_DEFAULT_MTU; channel->packets_granted = 0; channel->remote_sig_id = sig_id; // limit local mtu to max acl packet length if (channel->local_mtu > l2cap_max_mtu()) { channel->local_mtu = l2cap_max_mtu(); } // set initial state channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT; channel->state_var = L2CAP_CHANNEL_STATE_VAR_NONE; // add to connections list linked_list_add(&l2cap_channels, (linked_item_t *) channel); // emit incoming connection request l2cap_emit_connection_request(channel); }
void sdp_client_service_search(bd_addr_t remote, uint8_t * des_serviceSearchPattern){ serviceSearchPattern = des_serviceSearchPattern; continuationStateLen = 0; PDU_ID = SDP_ServiceSearchResponse; sdp_client_state = W4_CONNECT; l2cap_create_channel_internal(NULL, sdp_packet_handler, remote, PSM_SDP, l2cap_max_mtu()); }
void sdp_client_service_attribute_search(bd_addr_t remote, uint32_t search_serviceRecordHandle, uint8_t * des_attributeIDList){ serviceRecordHandle = search_serviceRecordHandle; attributeIDList = des_attributeIDList; continuationStateLen = 0; PDU_ID = SDP_ServiceAttributeResponse; sdp_client_state = W4_CONNECT; l2cap_create_channel_internal(NULL, sdp_packet_handler, remote, PSM_SDP, l2cap_max_mtu()); }
// open outgoing L2CAP channel void l2cap_create_channel_internal(void * connection, btstack_packet_handler_t packet_handler, bd_addr_t address, uint16_t psm, uint16_t mtu){ // alloc structure l2cap_channel_t * chan = (l2cap_channel_t*) btstack_memory_l2cap_channel_get(); if (!chan) { // emit error event l2cap_channel_t dummy_channel; BD_ADDR_COPY(dummy_channel.address, address); dummy_channel.psm = psm; l2cap_emit_channel_opened(&dummy_channel, BTSTACK_MEMORY_ALLOC_FAILED); return; } // limit local mtu to max acl packet length if (mtu > l2cap_max_mtu()) { mtu = l2cap_max_mtu(); } // fill in BD_ADDR_COPY(chan->address, address); chan->psm = psm; chan->handle = 0; chan->connection = connection; chan->packet_handler = packet_handler; chan->remote_mtu = L2CAP_MINIMAL_MTU; chan->local_mtu = mtu; chan->packets_granted = 0; // set initial state chan->state = L2CAP_STATE_WILL_SEND_CREATE_CONNECTION; chan->state_var = L2CAP_CHANNEL_STATE_VAR_NONE; chan->remote_sig_id = L2CAP_SIG_ID_INVALID; chan->local_sig_id = L2CAP_SIG_ID_INVALID; // add to connections list linked_list_add(&l2cap_channels, (linked_item_t *) chan); l2cap_run(); }
uint8_t sdp_client_service_search(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern){ if (!sdp_client_ready()) return SDP_QUERY_BUSY; sdp_parser_init(callback); service_search_pattern = des_service_search_pattern; continuationStateLen = 0; PDU_ID = SDP_ServiceSearchResponse; sdp_client_state = W4_CONNECT; l2cap_create_channel(sdp_client_packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, l2cap_max_mtu(), NULL); return 0; }
uint8_t sdp_client_service_attribute_search(btstack_packet_handler_t callback, bd_addr_t remote, uint32_t search_service_record_handle, const uint8_t * des_attribute_id_list){ if (!sdp_client_ready()) return SDP_QUERY_BUSY; sdp_parser_init(callback); serviceRecordHandle = search_service_record_handle; attribute_id_list = des_attribute_id_list; continuationStateLen = 0; PDU_ID = SDP_ServiceAttributeResponse; sdp_client_state = W4_CONNECT; l2cap_create_channel(sdp_client_packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, l2cap_max_mtu(), NULL); return 0; }