void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ // uint16_t handle; if (packet_type == L2CAP_DATA_PACKET){ uint16_t responseTransactionID = READ_NET_16(packet,1); if ( responseTransactionID != transactionID){ log_error("Missmatching transaction ID, expected %u, found %u.", transactionID, responseTransactionID); return; } if (packet[0] != SDP_ServiceSearchAttributeResponse && packet[0] != SDP_ServiceSearchResponse && packet[0] != SDP_ServiceAttributeResponse){ log_error("Not a valid PDU ID, expected %u, %u or %u, found %u.", SDP_ServiceSearchResponse, SDP_ServiceAttributeResponse, SDP_ServiceSearchAttributeResponse, packet[0]); return; } PDU_ID = packet[0]; log_info("SDP Client :: PDU ID. %u ,%u", PDU_ID, packet[0]); switch (PDU_ID){ #ifdef HAVE_SDP_EXTRA_QUERIES case SDP_ServiceSearchResponse: parse_service_search_response(packet); break; case SDP_ServiceAttributeResponse: parse_service_attribute_response(packet); break; #endif case SDP_ServiceSearchAttributeResponse: parse_service_search_attribute_response(packet); break; default: log_error("SDP Client :: PDU ID invalid. %u ,%u", PDU_ID, packet[0]); return; } // continuation set or DONE? if (continuationStateLen == 0){ log_info("SDP Client Query DONE! "); sdp_client_state = QUERY_COMPLETE; l2cap_disconnect_internal(sdp_cid, 0); // sdp_parser_handle_done(0); return; } // prepare next request and send sdp_client_state = W2_SEND; if (can_send_now(sdp_cid)) send_request(sdp_cid); return; } if (packet_type != HCI_EVENT_PACKET) return; switch(packet[0]){ case L2CAP_EVENT_TIMEOUT_CHECK: log_info("sdp client: L2CAP_EVENT_TIMEOUT_CHECK"); break; case L2CAP_EVENT_CHANNEL_OPENED: if (sdp_client_state != W4_CONNECT) break; // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16) if (packet[2]) { log_error("SDP Client Connection failed."); sdp_parser_handle_done(packet[2]); break; } sdp_cid = channel; mtu = READ_BT_16(packet, 17); // handle = READ_BT_16(packet, 9); log_info("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu); sdp_client_state = W2_SEND; if (can_send_now(sdp_cid)) send_request(sdp_cid); break; case L2CAP_EVENT_CREDITS: case DAEMON_EVENT_HCI_PACKET_SENT: if (can_send_now(sdp_cid)) send_request(sdp_cid); break; case L2CAP_EVENT_CHANNEL_CLOSED: { if (sdp_cid != READ_BT_16(packet, 2)) { // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", READ_BT_16(packet, 2),sdp_cid); break; } log_info("SDP Client disconnected."); uint8_t status = sdp_client_state == QUERY_COMPLETE ? 0 : SDP_QUERY_INCOMPLETE; sdp_client_state = INIT; sdp_parser_handle_done(status); break; } default: break; } }
void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(size); // uint16_t handle; if (packet_type == L2CAP_DATA_PACKET){ uint16_t responseTransactionID = big_endian_read_16(packet,1); if (responseTransactionID != transactionID){ log_error("Mismatching transaction ID, expected %u, found %u.", transactionID, responseTransactionID); return; } if (packet[0] == SDP_ErrorResponse){ log_error("Received error response with code %u, disconnecting", packet[2]); l2cap_disconnect(sdp_cid, 0); return; } if (packet[0] != SDP_ServiceSearchAttributeResponse && packet[0] != SDP_ServiceSearchResponse && packet[0] != SDP_ServiceAttributeResponse){ log_error("Not a valid PDU ID, expected %u, %u or %u, found %u.", SDP_ServiceSearchResponse, SDP_ServiceAttributeResponse, SDP_ServiceSearchAttributeResponse, packet[0]); return; } PDU_ID = (SDP_PDU_ID_t)packet[0]; log_debug("SDP Client :: PDU ID. %u ,%u", PDU_ID, packet[0]); switch (PDU_ID){ #ifdef ENABLE_SDP_EXTRA_QUERIES case SDP_ServiceSearchResponse: sdp_client_parse_service_search_response(packet); break; case SDP_ServiceAttributeResponse: sdp_client_parse_service_attribute_response(packet); break; #endif case SDP_ServiceSearchAttributeResponse: sdp_client_parse_service_search_attribute_response(packet); break; default: log_error("SDP Client :: PDU ID invalid. %u ,%u", PDU_ID, packet[0]); return; } // continuation set or DONE? if (continuationStateLen == 0){ log_debug("SDP Client Query DONE! "); sdp_client_state = QUERY_COMPLETE; l2cap_disconnect(sdp_cid, 0); return; } // prepare next request and send sdp_client_state = W2_SEND; l2cap_request_can_send_now_event(sdp_cid); return; } if (packet_type != HCI_EVENT_PACKET) return; switch(hci_event_packet_get_type(packet)){ case L2CAP_EVENT_CHANNEL_OPENED: if (sdp_client_state != W4_CONNECT) break; // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16) if (packet[2]) { log_info("SDP Client Connection failed, status 0x%02x.", packet[2]); sdp_client_state = INIT; sdp_parser_handle_done(packet[2]); break; } sdp_cid = channel; mtu = little_endian_read_16(packet, 17); // handle = little_endian_read_16(packet, 9); log_debug("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu); sdp_client_state = W2_SEND; l2cap_request_can_send_now_event(sdp_cid); break; case L2CAP_EVENT_CAN_SEND_NOW: if(l2cap_event_can_send_now_get_local_cid(packet) == sdp_cid){ sdp_client_send_request(sdp_cid); } break; case L2CAP_EVENT_CHANNEL_CLOSED: { if (sdp_cid != little_endian_read_16(packet, 2)) { // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", little_endian_read_16(packet, 2),sdp_cid); break; } log_info("SDP Client disconnected."); uint8_t status = sdp_client_state == QUERY_COMPLETE ? 0 : SDP_QUERY_INCOMPLETE; sdp_client_state = INIT; sdp_parser_handle_done(status); break; } default: break; } }