diff --git a/doc/manual/update_apis.py b/doc/manual/update_apis.py index a9e1568c8..90f19a206 100755 --- a/doc/manual/update_apis.py +++ b/doc/manual/update_apis.py @@ -21,7 +21,6 @@ apis = [ ["src/classic/pan.h", "PAN", "pan"], ["src/classic/rfcomm.h", "RFCOMM", "rfcomm"], ["src/classic/sdp_client.h", "SDP Client", "sdpClient"], - ["src/classic/sdp_parser.h","SDP Parser","sdpParser"], ["src/classic/sdp_query_rfcomm.h", "SDP RFCOMM Query", "sdpQueries"], ["src/classic/sdp_query_util.h","SDP Query Utils","sdpQueryUtil"], ["src/classic/sdp_server.h", "SDP Server", "sdpSrv"], diff --git a/example/embedded/panu_demo.c b/example/embedded/panu_demo.c index e24ecbbc3..b18c0741c 100644 --- a/example/embedded/panu_demo.c +++ b/example/embedded/panu_demo.c @@ -85,7 +85,6 @@ #include "btstack_event.h" #include "btstack_run_loop.h" #include "classic/sdp_client.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_util.h" #include "classic/sdp_util.h" #include "hci.h" @@ -151,10 +150,6 @@ static void panu_setup(void){ bnep_register_packet_handler(packet_handler); // Minimum L2CAP MTU for bnep is 1691 bytes bnep_register_service(SDP_PANU, 1691); - - // Initialise SDP - sdp_parser_init(); - sdp_parser_register_callback(handle_sdp_client_query_result); } /* LISTING_END */ diff --git a/example/embedded/sdp_bnep_query.c b/example/embedded/sdp_bnep_query.c index ebd64697f..b5d0ce923 100644 --- a/example/embedded/sdp_bnep_query.c +++ b/example/embedded/sdp_bnep_query.c @@ -55,7 +55,6 @@ #include "btstack_memory.h" #include "btstack_run_loop.h" #include "classic/sdp_client.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_util.h" #include "classic/sdp_util.h" #include "hci.h" @@ -90,7 +89,7 @@ static void assertBuffer(int size){ /* LISTING_START(SDPClientInit): SDP client setup */ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -static void handle_sdp_client_query_result(uint8_t packet_type, uint8_t *packet, uint16_t size); +static void handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void sdp_client_init(void){ @@ -100,9 +99,6 @@ static void sdp_client_init(void){ // init L2CAP l2cap_init(); - - sdp_parser_init(); - sdp_parser_register_callback(handle_sdp_client_query_result); } /* LISTING_END */ @@ -125,7 +121,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack // BTstack activated, get started if (packet[2] == HCI_STATE_WORKING){ printf("Start SDP BNEP query.\n"); - sdp_general_query_for_uuid(remote, SDP_BNEPProtocol); + sdp_general_query_for_uuid(&handle_sdp_client_query_result, remote, SDP_BNEPProtocol); } break; default: @@ -165,7 +161,7 @@ static char * get_string_from_data_element(uint8_t * element){ */ /* LISTING_START(HandleSDPQUeryResult): Extracting BNEP Protcol UUID and L2CAP PSM */ -static void handle_sdp_client_query_result(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ /* LISTING_PAUSE */ des_iterator_t des_list_it; des_iterator_t prot_it; diff --git a/example/embedded/sdp_general_query.c b/example/embedded/sdp_general_query.c index 44330ff92..93bae4456 100644 --- a/example/embedded/sdp_general_query.c +++ b/example/embedded/sdp_general_query.c @@ -54,8 +54,6 @@ #include "btstack_memory.h" #include "btstack_run_loop.h" #include "classic/sdp_client.h" -#include "classic/sdp_parser.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_util.h" #include "hci.h" #include "hci_cmd.h" @@ -80,7 +78,7 @@ static btstack_packet_callback_registration_t hci_event_callback_registration; /* LISTING_START(SDPClientInit): SDP client setup */ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -static void handle_sdp_client_query_result(uint8_t packet_type, uint8_t *packet, uint16_t size); +static void handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void sdp_client_init(void){ @@ -90,9 +88,6 @@ static void sdp_client_init(void){ // init L2CAP l2cap_init(); - - sdp_parser_init(); - sdp_parser_register_callback(handle_sdp_client_query_result); } /* LISTING_END */ @@ -120,7 +115,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack switch (event) { case BTSTACK_EVENT_STATE: if (packet[2] == HCI_STATE_WORKING){ - sdp_general_query_for_uuid(remote, SDP_PublicBrowseGroup); + sdp_general_query_for_uuid(&handle_sdp_client_query_result, remote, SDP_PublicBrowseGroup); } break; default: @@ -149,7 +144,7 @@ static void assertBuffer(int size){ */ /* LISTING_START(HandleSDPQUeryResult): Handling query result chunks. */ -static void handle_sdp_client_query_result(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: // handle new record diff --git a/example/embedded/sdp_rfcomm_query.c b/example/embedded/sdp_rfcomm_query.c index 62cccbd68..a7a43fd27 100644 --- a/example/embedded/sdp_rfcomm_query.c +++ b/example/embedded/sdp_rfcomm_query.c @@ -59,6 +59,8 @@ #include "classic/sdp_query_rfcomm.h" #include "btstack_event.h" +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); + // static bd_addr_t remote = {0x04,0x0C,0xCE,0xE4,0x85,0xD3}; static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xD1, 0x15}; @@ -78,7 +80,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case BTSTACK_EVENT_STATE: // bt stack activated, get started if (packet[2] == HCI_STATE_WORKING){ - sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_PublicBrowseGroup); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_PublicBrowseGroup); } break; default: @@ -109,7 +111,7 @@ static void report_found_services(void){ printf(" ***\n\n"); } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: store_found_service(sdp_event_query_rfcomm_service_get_name(packet), @@ -133,8 +135,6 @@ int btstack_main(int argc, const char * argv[]){ // init L2CAP l2cap_init(); - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - // turn on! hci_power_control(HCI_POWER_ON); diff --git a/example/embedded/spp_streamer.c b/example/embedded/spp_streamer.c index cc0f136e0..350879c6b 100644 --- a/example/embedded/spp_streamer.c +++ b/example/embedded/spp_streamer.c @@ -70,6 +70,8 @@ typedef enum { DONE } state_t; +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); + #define DATA_VOLUME (1000 * 1000) // configuration area { @@ -124,7 +126,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack case BTSTACK_EVENT_STATE: // bt stack activated, get started if (packet[2] == HCI_STATE_WORKING){ - sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_PublicBrowseGroup); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_PublicBrowseGroup); } break; case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: @@ -161,7 +163,7 @@ static void handle_found_service(const char * name, uint8_t port){ state = W4_SDP_COMPLETE; } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: handle_found_service(sdp_event_query_rfcomm_service_get_name(packet), @@ -196,8 +198,6 @@ int btstack_main(int argc, const char * argv[]){ // init L2CAP l2cap_init(); - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - // turn on! hci_power_control(HCI_POWER_ON); diff --git a/platform/daemon/daemon.c b/platform/daemon/daemon.c index 5c533886b..19368b575 100644 --- a/platform/daemon/daemon.c +++ b/platform/daemon/daemon.c @@ -68,7 +68,6 @@ #include "classic/rfcomm.h" #include "classic/sdp_server.h" #include "classic/sdp_client.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_rfcomm.h" #include "classic/sdp_query_util.h" #include "hci.h" @@ -1134,13 +1133,11 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui memcpy(serviceSearchPattern, &packet[9], serviceSearchPatternLen); sdp_client_query_connection = connection; - sdp_query_rfcomm_register_callback(handle_sdp_rfcomm_service_result); sdp_query_rfcomm_channel_and_name_for_search_pattern(addr, serviceSearchPattern); break; case SDP_CLIENT_QUERY_SERVICES: bt_flip_addr(addr, &packet[3]); - sdp_parser_init(); sdp_client_query_connection = connection; sdp_parser_register_callback(handle_sdp_client_query_result); diff --git a/port/pic32-harmony/app.X/nbproject/configurations.xml b/port/pic32-harmony/app.X/nbproject/configurations.xml index c39023b85..a7f9e4e23 100644 --- a/port/pic32-harmony/app.X/nbproject/configurations.xml +++ b/port/pic32-harmony/app.X/nbproject/configurations.xml @@ -57,7 +57,6 @@ ../../../src/rfcomm.h ../../../src/sdp_server.h ../../../src/sdp_client.h - ../../../src/sdp_parser.h ../../../src/sdp_query_rfcomm.h ../../../src/sdp_query_util.h diff --git a/src/btstack.h b/src/btstack.h index c2db603ee..4b2bc31e5 100644 --- a/src/btstack.h +++ b/src/btstack.h @@ -88,7 +88,6 @@ #include "classic/rfcomm.h" #include "classic/sdp_server.h" #include "classic/sdp_client.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_rfcomm.h" #include "classic/sdp_query_util.h" #include "classic/sdp_util.h" diff --git a/src/classic/hfp.c b/src/classic/hfp.c index e19c5fe2d..67a273a59 100644 --- a/src/classic/hfp.c +++ b/src/classic/hfp.c @@ -424,7 +424,7 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac hfp_handle_hci_event(packet_type, packet, size); } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ hfp_connection_t * connection = connection_doing_sdp_query; if ( connection->state != HFP_W4_SDP_EVENT_QUERY_COMPLETE) return; @@ -1268,10 +1268,6 @@ static void parse_sequence(hfp_connection_t * context){ } } -void hfp_init(void){ - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); -} - void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr); log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context); @@ -1293,7 +1289,7 @@ void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_ context->state = HFP_W4_SDP_EVENT_QUERY_COMPLETE; connection_doing_sdp_query = context; context->service_uuid = service_uuid; - sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, context->remote_addr, service_uuid); break; default: break; diff --git a/src/classic/hfp.h b/src/classic/hfp.h index 85507378a..9c8712bc9 100644 --- a/src/classic/hfp.h +++ b/src/classic/hfp.h @@ -634,7 +634,6 @@ void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicato btstack_linked_list_t * hfp_get_connections(void); void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree); -void hfp_init(void); void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid); void hfp_release_service_level_connection(hfp_connection_t * connection); void hfp_reset_context_flags(hfp_connection_t * context); diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index dc2ec2e61..da529bace 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -1998,7 +1998,6 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, l2cap_init(); rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); - hfp_init(); hfp_supported_features = supported_features; hfp_codecs_nr = codecs_nr; diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index 403dd198c..b45251961 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -1058,8 +1058,7 @@ void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint16 l2cap_init(); rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); - hfp_init(); - + hfp_supported_features = supported_features; hfp_indicators_nr = indicators_nr; diff --git a/src/classic/hsp_ag.c b/src/classic/hsp_ag.c index b934f8c71..7fe08aab2 100644 --- a/src/classic/hsp_ag.c +++ b/src/classic/hsp_ag.c @@ -116,7 +116,7 @@ static hsp_ag_callback_t hsp_ag_callback; static void hsp_run(); static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size); +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void dummy_notify(uint8_t * event, uint16_t size){} @@ -263,8 +263,6 @@ void hsp_ag_init(uint8_t rfcomm_channel_nr){ rfcomm_init(); rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); // reserved channel, mtu limited by l2cap - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - hsp_ag_reset_state(); } @@ -367,7 +365,7 @@ static void hsp_run(void){ case HSP_SDP_QUERY_RFCOMM_CHANNEL: hsp_state = HSP_W4_SDP_EVENT_QUERY_COMPLETE; log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), SDP_HSP); - sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_HSP); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_HSP); break; case HSP_W4_RING_ANSWER: @@ -441,7 +439,7 @@ static void hsp_run(void){ } -static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ +static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ // log_info("packet_handler type %u, packet[0] %x", packet_type, packet[0]); if (packet_type == RFCOMM_DATA_PACKET){ while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){ @@ -601,7 +599,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha hsp_run(); } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet); diff --git a/src/classic/hsp_ag.h b/src/classic/hsp_ag.h index 8e065c003..e06ae0792 100644 --- a/src/classic/hsp_ag.h +++ b/src/classic/hsp_ag.h @@ -55,7 +55,7 @@ extern "C" { typedef void (*hsp_ag_callback_t)(uint8_t * event, uint16_t event_size); -void hsp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name); +void hsp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name); void hsp_ag_init(uint8_t rfcomm_channel_nr); diff --git a/src/classic/hsp_hs.c b/src/classic/hsp_hs.c index 55a315720..9cdf471a7 100644 --- a/src/classic/hsp_hs.c +++ b/src/classic/hsp_hs.c @@ -111,7 +111,7 @@ static hsp_state_t hsp_state = HSP_IDLE; static void hsp_run(void); static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size); +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static hsp_hs_callback_t hsp_hs_callback; static void dummy_notify(uint8_t * event, uint16_t size){} @@ -263,8 +263,6 @@ void hsp_hs_init(uint8_t rfcomm_channel_nr){ rfcomm_init(); rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); // reserved channel, mtu limited by l2cap - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - hsp_hs_reset_state(); } @@ -330,7 +328,7 @@ static void hsp_run(void){ switch (hsp_state){ case HSP_SDP_QUERY_RFCOMM_CHANNEL: hsp_state = HSP_W4_SDP_EVENT_QUERY_COMPLETE; - sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_Headset_AG); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_Headset_AG); break; case HSP_W2_CONNECT_SCO: @@ -565,7 +563,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack hsp_run(); } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet); diff --git a/src/classic/sdp_client.c b/src/classic/sdp_client.c index 1f98ccc98..3070d3bd7 100644 --- a/src/classic/sdp_client.c +++ b/src/classic/sdp_client.c @@ -45,64 +45,284 @@ #include "hci_cmd.h" #include "l2cap.h" -#include "classic/sdp_parser.h" #include "classic/sdp_server.h" #include "btstack_debug.h" +// Types SDP Parser - Data Element stream helper +typedef enum { + GET_LIST_LENGTH = 1, + GET_RECORD_LENGTH, + GET_ATTRIBUTE_ID_HEADER_LENGTH, + GET_ATTRIBUTE_ID, + GET_ATTRIBUTE_VALUE_LENGTH, + GET_ATTRIBUTE_VALUE +} sdp_parser_state_t; + +// Types SDP Client typedef enum { INIT, W4_CONNECT, W2_SEND, W4_RESPONSE, QUERY_COMPLETE } sdp_client_state_t; -void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); - -static uint16_t setup_service_search_attribute_request(uint8_t * data); +// Prototypes SDP Parser +void sdp_parser_init(btstack_packet_handler_t callback); +void sdp_parser_handle_chunk(uint8_t * data, uint16_t size); +void sdp_parser_handle_done(uint8_t status); +void sdp_parser_init_service_attribute_search(void); +void sdp_parser_init_service_search(void); +void sdp_parser_handle_service_search(uint8_t * data, uint16_t total_count, uint16_t record_handle_count); +// Prototypes SDP Client +void sdp_client_reset(void); +void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static uint16_t sdp_client_setup_service_search_attribute_request(uint8_t * data); #ifdef ENABLE_SDP_EXTRA_QUERIES -static uint16_t setup_service_search_request(uint8_t * data); -static uint16_t setup_service_attribute_request(uint8_t * data); -static void parse_service_search_response(uint8_t* packet); -static void parse_service_attribute_response(uint8_t* packet); +static uint16_t sdp_client_setup_service_search_request(uint8_t * data); +static uint16_t sdp_client_setup_service_attribute_request(uint8_t * data); +static void sdp_client_parse_service_search_response(uint8_t* packet); +static void sdp_client_parse_service_attribute_response(uint8_t* packet); static uint32_t serviceRecordHandle; +static uint32_t record_handle; #endif -// SDP Client Query +// State DES Parser +static de_state_t de_header_state; + +// State SDP Parser +static sdp_parser_state_t state = GET_LIST_LENGTH; +static uint16_t attribute_id = 0; +static uint16_t attribute_bytes_received = 0; +static uint16_t attribute_bytes_delivered = 0; +static uint16_t list_offset = 0; +static uint16_t list_size; +static uint16_t record_offset = 0; +static uint16_t record_size; +static uint16_t attribute_value_size; +static int record_counter = 0; +static btstack_packet_handler_t sdp_parser_callback; + +// State SDP Client static uint16_t mtu; static uint16_t sdp_cid = 0x40; -static uint8_t * serviceSearchPattern; -static uint8_t * attributeIDList; +static const uint8_t * service_search_pattern; +static const uint8_t * attribute_id_list; static uint16_t transactionID = 0; static uint8_t continuationState[16]; static uint8_t continuationStateLen; static sdp_client_state_t sdp_client_state = INIT; static SDP_PDU_ID_t PDU_ID = SDP_Invalid; +// DES Parser +void de_state_init(de_state_t * de_state){ + de_state->in_state_GET_DE_HEADER_LENGTH = 1; + de_state->addon_header_bytes = 0; + de_state->de_size = 0; + de_state->de_offset = 0; +} + +int de_state_size(uint8_t eventByte, de_state_t *de_state){ + if (de_state->in_state_GET_DE_HEADER_LENGTH){ + de_state->addon_header_bytes = de_get_header_size(&eventByte) - 1; + de_state->de_size = 0; + de_state->de_offset = 0; + + if (de_state->addon_header_bytes == 0){ + de_state->de_size = de_get_data_size(&eventByte); + if (de_state->de_size == 0) { + log_error(" ERROR: ID size is zero"); + } + // log_info("Data element payload is %d bytes.", de_state->de_size); + return 1; + } + de_state->in_state_GET_DE_HEADER_LENGTH = 0; + return 0; + } + + if (de_state->addon_header_bytes > 0){ + de_state->de_size = (de_state->de_size << 8) | eventByte; + de_state->addon_header_bytes--; + } + if (de_state->addon_header_bytes > 0) return 0; + // log_info("Data element payload is %d bytes.", de_state->de_size); + de_state->in_state_GET_DE_HEADER_LENGTH = 1; + return 1; +} + +// SDP Parser +static void sdp_parser_emit_value_byte(uint8_t event_byte){ + uint8_t event[11]; + event[0] = SDP_EVENT_QUERY_ATTRIBUTE_VALUE; + event[1] = 9; + little_endian_store_16(event, 2, record_counter); + little_endian_store_16(event, 4, attribute_id); + little_endian_store_16(event, 6, attribute_value_size); + little_endian_store_16(event, 8, attribute_bytes_delivered); + event[10] = event_byte; + (*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + +static void sdp_parser_process_byte(uint8_t eventByte){ + // count all bytes + list_offset++; + record_offset++; + + // log_info(" parse BYTE_RECEIVED %02x", eventByte); + switch(state){ + case GET_LIST_LENGTH: + if (!de_state_size(eventByte, &de_header_state)) break; + list_offset = de_header_state.de_offset; + list_size = de_header_state.de_size; + // log_info("parser: List offset %u, list size %u", list_offset, list_size); + + record_counter = 0; + state = GET_RECORD_LENGTH; + break; + + case GET_RECORD_LENGTH: + // check size + if (!de_state_size(eventByte, &de_header_state)) break; + // log_info("parser: Record payload is %d bytes.", de_header_state.de_size); + record_offset = de_header_state.de_offset; + record_size = de_header_state.de_size; + state = GET_ATTRIBUTE_ID_HEADER_LENGTH; + break; + + case GET_ATTRIBUTE_ID_HEADER_LENGTH: + if (!de_state_size(eventByte, &de_header_state)) break; + attribute_id = 0; + log_info("ID data is stored in %d bytes.", (int) de_header_state.de_size); + state = GET_ATTRIBUTE_ID; + break; + + case GET_ATTRIBUTE_ID: + attribute_id = (attribute_id << 8) | eventByte; + de_header_state.de_size--; + if (de_header_state.de_size > 0) break; + log_info("parser: Attribute ID: %04x.", attribute_id); + + state = GET_ATTRIBUTE_VALUE_LENGTH; + attribute_bytes_received = 0; + attribute_bytes_delivered = 0; + attribute_value_size = 0; + de_state_init(&de_header_state); + break; + + case GET_ATTRIBUTE_VALUE_LENGTH: + attribute_bytes_received++; + sdp_parser_emit_value_byte(eventByte); + attribute_bytes_delivered++; + if (!de_state_size(eventByte, &de_header_state)) break; + + attribute_value_size = de_header_state.de_size + attribute_bytes_received; + + state = GET_ATTRIBUTE_VALUE; + break; + + case GET_ATTRIBUTE_VALUE: + attribute_bytes_received++; + sdp_parser_emit_value_byte(eventByte); + attribute_bytes_delivered++; + // log_info("paser: attribute_bytes_received %u, attribute_value_size %u", attribute_bytes_received, attribute_value_size); + + if (attribute_bytes_received < attribute_value_size) break; + // log_info("parser: Record offset %u, record size %u", record_offset, record_size); + if (record_offset != record_size){ + state = GET_ATTRIBUTE_ID_HEADER_LENGTH; + // log_info("Get next attribute"); + break; + } + record_offset = 0; + // log_info("parser: List offset %u, list size %u", list_offset, list_size); + + if (list_size > 0 && list_offset != list_size){ + record_counter++; + state = GET_RECORD_LENGTH; + log_info("parser: END_OF_RECORD"); + break; + } + list_offset = 0; + de_state_init(&de_header_state); + state = GET_LIST_LENGTH; + record_counter = 0; + log_info("parser: END_OF_RECORD & DONE"); + break; + default: + break; + } +} + +void sdp_parser_init(btstack_packet_handler_t callback){ + // init + sdp_parser_callback = callback; + de_state_init(&de_header_state); + state = GET_LIST_LENGTH; + list_offset = 0; + record_offset = 0; + record_counter = 0; +} + +void sdp_parser_handle_chunk(uint8_t * data, uint16_t size){ + int i; + for (i=0;i mtu big_endian_store_16(data, offset, mtu); offset += 2; // AttibuteIDList - uint16_t attributeIDListLen = de_get_len(attributeIDList); - memcpy(data + offset, attributeIDList, attributeIDListLen); - offset += attributeIDListLen; + uint16_t attribute_id_list_len = de_get_len(attribute_id_list); + memcpy(data + offset, attribute_id_list, attribute_id_list_len); + offset += attribute_id_list_len; // ContinuationState - uint8_t number of cont. bytes N<=16 data[offset++] = continuationStateLen; @@ -311,11 +531,11 @@ static uint16_t setup_service_search_attribute_request(uint8_t * data){ } #ifdef ENABLE_SDP_EXTRA_QUERIES -void parse_service_record_handle_list(uint8_t* packet, uint16_t total_count, uint16_t current_count){ +void sdp_client_parse_service_record_handle_list(uint8_t* packet, uint16_t total_count, uint16_t current_count){ sdp_parser_handle_service_search(packet, total_count, current_count); } -static uint16_t setup_service_search_request(uint8_t * data){ +static uint16_t sdp_client_setup_service_search_request(uint8_t * data){ uint16_t offset = 0; transactionID++; // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest; @@ -328,10 +548,10 @@ static uint16_t setup_service_search_request(uint8_t * data){ offset += 2; // parameters: - // ServiceSearchPattern - DES (min 1 UUID, max 12) - uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern); - memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen); - offset += serviceSearchPatternLen; + // Service_search_pattern - DES (min 1 UUID, max 12) + uint16_t service_search_pattern_len = de_get_len(service_search_pattern); + memcpy(data + offset, service_search_pattern, service_search_pattern_len); + offset += service_search_pattern_len; // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu big_endian_store_16(data, offset, mtu); @@ -350,7 +570,7 @@ static uint16_t setup_service_search_request(uint8_t * data){ } -static uint16_t setup_service_attribute_request(uint8_t * data){ +static uint16_t sdp_client_setup_service_attribute_request(uint8_t * data){ uint16_t offset = 0; transactionID++; @@ -373,9 +593,9 @@ static uint16_t setup_service_attribute_request(uint8_t * data){ offset += 2; // AttibuteIDList - uint16_t attributeIDListLen = de_get_len(attributeIDList); - memcpy(data + offset, attributeIDList, attributeIDListLen); - offset += attributeIDListLen; + uint16_t attribute_id_list_len = de_get_len(attribute_id_list); + memcpy(data + offset, attribute_id_list, attribute_id_list_len); + offset += attribute_id_list_len; // ContinuationState - uint8_t number of cont. bytes N<=16 data[offset++] = continuationStateLen; @@ -389,7 +609,7 @@ static uint16_t setup_service_attribute_request(uint8_t * data){ return offset; } -static void parse_service_search_response(uint8_t* packet){ +static void sdp_client_parse_service_search_response(uint8_t* packet){ uint16_t offset = 3; uint16_t parameterLength = big_endian_read_16(packet,offset); offset+=2; @@ -404,7 +624,7 @@ static void parse_service_search_response(uint8_t* packet){ return; } - parse_service_record_handle_list(packet+offset, totalServiceRecordCount, currentServiceRecordCount); + sdp_client_parse_service_record_handle_list(packet+offset, totalServiceRecordCount, currentServiceRecordCount); offset+=(currentServiceRecordCount * 4); continuationStateLen = packet[offset]; @@ -421,7 +641,7 @@ static void parse_service_search_response(uint8_t* packet){ } } -static void parse_service_attribute_response(uint8_t* packet){ +static void sdp_client_parse_service_attribute_response(uint8_t* packet){ uint16_t offset = 3; uint16_t parameterLength = big_endian_read_16(packet,offset); offset+=2; @@ -436,7 +656,7 @@ static void parse_service_attribute_response(uint8_t* packet){ } // AttributeLists - parse_attribute_lists(packet+offset, attributeListByteCount); + sdp_client_parse_attribute_lists(packet+offset, attributeListByteCount); offset+=attributeListByteCount; continuationStateLen = packet[offset]; @@ -453,24 +673,62 @@ static void parse_service_attribute_response(uint8_t* packet){ log_error("Error parsing ServiceAttributeResponse: wrong size of parameters, number of expected bytes%u, actual number %u.", parameterLength, offset); } } +#endif -void sdp_client_service_attribute_search(bd_addr_t remote, uint32_t search_serviceRecordHandle, uint8_t * des_attributeIDList){ - serviceRecordHandle = search_serviceRecordHandle; - attributeIDList = des_attributeIDList; +// for testing only +void sdp_client_reset(void){ + sdp_client_state = INIT; +} + +// Public API + +int sdp_client_ready(void){ + return sdp_client_state == INIT; +} + +void sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern, const uint8_t * des_attribute_id_list){ + if (!sdp_client_ready()) { + log_error("sdp_client_query called when not ready"); + return; + } + sdp_parser_init(callback); + service_search_pattern = des_service_search_pattern; + attribute_id_list = des_attribute_id_list; + continuationStateLen = 0; + PDU_ID = SDP_ServiceSearchAttributeResponse; + + sdp_client_state = W4_CONNECT; + l2cap_create_channel(sdp_client_packet_handler, remote, PSM_SDP, l2cap_max_mtu(), NULL); +} + +#ifdef ENABLE_SDP_EXTRA_QUERIES +void sdp_client_service_attribute_search(btstack_packet_handler_t callback, bd_addr_t remote, uint32_t search_service_record_handle, uint8_t * des_attribute_id_list){ + if (!sdp_client_ready()) { + log_error("sdp_client_query called when not ready"); + return; + } + 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_packet_handler, remote, PSM_SDP, l2cap_max_mtu(), NULL); + l2cap_create_channel(sdp_client_packet_handler, remote, PSM_SDP, l2cap_max_mtu(), NULL); } -void sdp_client_service_search(bd_addr_t remote, uint8_t * des_serviceSearchPattern){ - serviceSearchPattern = des_serviceSearchPattern; +void sdp_client_service_search(btstack_packet_handler_t callback, bd_addr_t remote, uint8_t * des_service_search_pattern){ + if (!sdp_client_ready()) { + log_error("sdp_client_query called when not ready"); + return; + } + 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_packet_handler, remote, PSM_SDP, l2cap_max_mtu(), NULL); + l2cap_create_channel(sdp_client_packet_handler, remote, PSM_SDP, l2cap_max_mtu(), NULL); } #endif diff --git a/src/classic/sdp_client.h b/src/classic/sdp_client.h index ba6fec4a9..e75cdb18c 100644 --- a/src/classic/sdp_client.h +++ b/src/classic/sdp_client.h @@ -51,17 +51,55 @@ extern "C" { #endif /* API_START */ - + +typedef struct de_state { + uint8_t in_state_GET_DE_HEADER_LENGTH ; + uint32_t addon_header_bytes; + uint32_t de_size; + uint32_t de_offset; +} de_state_t; + +void de_state_init(de_state_t * state); +int de_state_size(uint8_t eventByte, de_state_t *de_state); + +/** + * @brief Checks if the SDP Client is ready + * @return 1 when no query is active + */ +int sdp_client_ready(void); + /** * @brief Queries the SDP service of the remote device given a service search pattern and a list of attribute IDs. - * The remote data is handled by the SDP parser. The SDP parser delivers attribute values and done event via a registered callback. + * The remote data is handled by the SDP parser. The SDP parser delivers attribute values and done event via the callback. + * @param callback for attributes values and done event + * @param remote address + * @param des_service_search_pattern + * @param des_attribute_id_list */ -void sdp_client_query(bd_addr_t remote, uint8_t * des_serviceSearchPattern, uint8_t * des_attributeIDList); +void sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern, const uint8_t * des_attribute_id_list); + +/** + * @brief Retrieves all attribute IDs of a SDP record specified by its service record handle and a list of attribute IDs. + * The remote data is handled by the SDP parser. The SDP parser delivers attribute values and done event via the callback. + * @note only provided if ENABLE_SDP_EXTRA_QUERIES is defined + * @param callback for attributes values and done event + * @param remote address + * @param search_service_record_handle + * @param des_attributeIDList + */ +void sdp_client_service_attribute_search(btstack_packet_handler_t callback, bd_addr_t remote, uint32_t search_service_record_handle, const uint8_t * des_attributeIDList); + +/** + * @brief Query the list of SDP records that match a given service search pattern. + * The remote data is handled by the SDP parser. The SDP parser delivers attribute values and done event via the callback. + * @note only provided if ENABLE_SDP_EXTRA_QUERIES is defined + * @param callback for attributes values and done event + * @param remote address + * @param des_service_search_pattern + */ +void sdp_client_service_search(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern); + -#ifdef ENABLE_SDP_EXTRA_QUERIES -void sdp_client_service_attribute_search(bd_addr_t remote, uint32_t search_serviceRecordHandle, uint8_t * des_attributeIDList); -void sdp_client_service_search(bd_addr_t remote, uint8_t * des_serviceSearchPattern); -#endif /* API_END */ #if defined __cplusplus diff --git a/src/classic/sdp_parser.c b/src/classic/sdp_parser.c deleted file mode 100644 index 3646f3783..000000000 --- a/src/classic/sdp_parser.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2014 BlueKitchen GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * 4. Any redistribution, use, or modification is done solely for - * personal benefit and not for any commercial purpose or for - * monetary gain. - * - * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Please inquire about commercial licensing options at - * contact@bluekitchen-gmbh.com - * - */ - -/* - * sdp_parser.c - */ -#include "hci_cmd.h" -#include "classic/sdp_parser.h" -#include "btstack_debug.h" - -typedef enum { - GET_LIST_LENGTH = 1, - GET_RECORD_LENGTH, - GET_ATTRIBUTE_ID_HEADER_LENGTH, - GET_ATTRIBUTE_ID, - GET_ATTRIBUTE_VALUE_LENGTH, - GET_ATTRIBUTE_VALUE -} state_t; - -static state_t state = GET_LIST_LENGTH; -static uint16_t attribute_id = 0; -static uint16_t attribute_bytes_received = 0; -static uint16_t attribute_bytes_delivered = 0; -static uint16_t list_offset = 0; -static uint16_t list_size; -static uint16_t record_offset = 0; -static uint16_t record_size; -static uint16_t attribute_value_size; -static int record_counter = 0; - -#ifdef ENABLE_SDP_EXTRA_QUERIES -static uint32_t record_handle; -#endif - -static void (*sdp_query_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size); - -// Low level parser -static de_state_t de_header_state; - - -void de_state_init(de_state_t * de_state){ - de_state->in_state_GET_DE_HEADER_LENGTH = 1; - de_state->addon_header_bytes = 0; - de_state->de_size = 0; - de_state->de_offset = 0; -} - -int de_state_size(uint8_t eventByte, de_state_t *de_state){ - if (de_state->in_state_GET_DE_HEADER_LENGTH){ - de_state->addon_header_bytes = de_get_header_size(&eventByte) - 1; - de_state->de_size = 0; - de_state->de_offset = 0; - - if (de_state->addon_header_bytes == 0){ - de_state->de_size = de_get_data_size(&eventByte); - if (de_state->de_size == 0) { - log_error(" ERROR: ID size is zero"); - } - // log_info("Data element payload is %d bytes.", de_state->de_size); - return 1; - } - de_state->in_state_GET_DE_HEADER_LENGTH = 0; - return 0; - } - - if (de_state->addon_header_bytes > 0){ - de_state->de_size = (de_state->de_size << 8) | eventByte; - de_state->addon_header_bytes--; - } - if (de_state->addon_header_bytes > 0) return 0; - // log_info("Data element payload is %d bytes.", de_state->de_size); - de_state->in_state_GET_DE_HEADER_LENGTH = 1; - return 1; -} - -static void dummy_notify(uint8_t packet_type, uint8_t *packet, uint16_t size){} - -void sdp_parser_register_callback(void (*sdp_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ - sdp_query_callback = dummy_notify; - if (sdp_callback != NULL){ - sdp_query_callback = sdp_callback; - } -} - -static void emit_value_byte(uint8_t event_byte){ - uint8_t event[11]; - event[0] = SDP_EVENT_QUERY_ATTRIBUTE_VALUE; - event[1] = 9; - little_endian_store_16(event, 2, record_counter); - little_endian_store_16(event, 4, attribute_id); - little_endian_store_16(event, 6, attribute_value_size); - little_endian_store_16(event, 8, attribute_bytes_delivered); - event[10] = event_byte; - (*sdp_query_callback)(HCI_EVENT_PACKET, event, sizeof(event)); -} - -static void parse(uint8_t eventByte){ - // count all bytes - list_offset++; - record_offset++; - - // log_info(" parse BYTE_RECEIVED %02x", eventByte); - switch(state){ - case GET_LIST_LENGTH: - if (!de_state_size(eventByte, &de_header_state)) break; - list_offset = de_header_state.de_offset; - list_size = de_header_state.de_size; - // log_info("parser: List offset %u, list size %u", list_offset, list_size); - - record_counter = 0; - state = GET_RECORD_LENGTH; - break; - - case GET_RECORD_LENGTH: - // check size - if (!de_state_size(eventByte, &de_header_state)) break; - // log_info("parser: Record payload is %d bytes.", de_header_state.de_size); - record_offset = de_header_state.de_offset; - record_size = de_header_state.de_size; - state = GET_ATTRIBUTE_ID_HEADER_LENGTH; - break; - - case GET_ATTRIBUTE_ID_HEADER_LENGTH: - if (!de_state_size(eventByte, &de_header_state)) break; - attribute_id = 0; - log_info("ID data is stored in %d bytes.", (int) de_header_state.de_size); - state = GET_ATTRIBUTE_ID; - break; - - case GET_ATTRIBUTE_ID: - attribute_id = (attribute_id << 8) | eventByte; - de_header_state.de_size--; - if (de_header_state.de_size > 0) break; - log_info("parser: Attribute ID: %04x.", attribute_id); - - state = GET_ATTRIBUTE_VALUE_LENGTH; - attribute_bytes_received = 0; - attribute_bytes_delivered = 0; - attribute_value_size = 0; - de_state_init(&de_header_state); - break; - - case GET_ATTRIBUTE_VALUE_LENGTH: - attribute_bytes_received++; - emit_value_byte(eventByte); - attribute_bytes_delivered++; - if (!de_state_size(eventByte, &de_header_state)) break; - - attribute_value_size = de_header_state.de_size + attribute_bytes_received; - - state = GET_ATTRIBUTE_VALUE; - break; - - case GET_ATTRIBUTE_VALUE: - attribute_bytes_received++; - emit_value_byte(eventByte); - attribute_bytes_delivered++; - // log_info("paser: attribute_bytes_received %u, attribute_value_size %u", attribute_bytes_received, attribute_value_size); - - if (attribute_bytes_received < attribute_value_size) break; - // log_info("parser: Record offset %u, record size %u", record_offset, record_size); - if (record_offset != record_size){ - state = GET_ATTRIBUTE_ID_HEADER_LENGTH; - // log_info("Get next attribute"); - break; - } - record_offset = 0; - // log_info("parser: List offset %u, list size %u", list_offset, list_size); - - if (list_size > 0 && list_offset != list_size){ - record_counter++; - state = GET_RECORD_LENGTH; - log_info("parser: END_OF_RECORD"); - break; - } - list_offset = 0; - de_state_init(&de_header_state); - state = GET_LIST_LENGTH; - record_counter = 0; - log_info("parser: END_OF_RECORD & DONE"); - break; - default: - break; - } -} - -void sdp_parser_init(void){ - // init - de_state_init(&de_header_state); - state = GET_LIST_LENGTH; - list_offset = 0; - record_offset = 0; - record_counter = 0; -} - -void sdp_parser_handle_chunk(uint8_t * data, uint16_t size){ - int i; - for (i=0;i -#include -#include -#include - -#include "classic/sdp_util.h" -#include "btstack_util.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* SDP Parser */ - -// Data Element stream parser helper -typedef struct de_state { - uint8_t in_state_GET_DE_HEADER_LENGTH ; - uint32_t addon_header_bytes; - uint32_t de_size; - uint32_t de_offset; -} de_state_t; -void de_state_init(de_state_t * state); -int de_state_size(uint8_t eventByte, de_state_t *de_state); - -/* API_START */ - -/* - * @brief - */ -void sdp_parser_init(void); - -/* - * @brief Registers a callback to receive attribute value data and parse complete event. - */ -void sdp_parser_register_callback(void (*sdp_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size)); - -/* - * @brief - */ -void sdp_parser_handle_chunk(uint8_t * data, uint16_t size); - -/* - * @brief - */ -void sdp_parser_handle_done(uint8_t status); - - -#ifdef ENABLE_SDP_EXTRA_QUERIES -/* - * @brief - */ -void sdp_parser_init_service_attribute_search(void); - -/* - * @brief - */ -void sdp_parser_init_service_search(void); - -/* - * @brief - */ -void sdp_parser_handle_service_search(uint8_t * data, uint16_t total_count, uint16_t record_handle_count); -#endif - - -/* API_END */ - -#if defined __cplusplus -} -#endif - -#endif // __SDP_PARSER_H diff --git a/src/classic/sdp_query_rfcomm.c b/src/classic/sdp_query_rfcomm.c index 19589c058..c3ed1984f 100644 --- a/src/classic/sdp_query_rfcomm.c +++ b/src/classic/sdp_query_rfcomm.c @@ -44,6 +44,7 @@ #include #include +#include "btstack_debug.h" #include "btstack_event.h" #include "classic/sdp_client.h" #include "classic/sdp_query_rfcomm.h" @@ -53,11 +54,6 @@ // called by test/sdp_client void sdp_query_rfcomm_init(void); -// called by test/sdp_client -void sdp_query_rfcomm_init(void); - -static void dummy_notify_app(uint8_t packet_type, uint8_t *packet, uint16_t size); - typedef enum { GET_PROTOCOL_LIST_LENGTH = 1, GET_PROTOCOL_LENGTH, @@ -88,12 +84,9 @@ static int protocol_id_bytes_to_read; static int protocol_value_size; static de_state_t de_header_state; static de_state_t sn_de_header_state; -static void (*sdp_app_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_notify_app; - +static btstack_packet_handler_t sdp_app_callback; // -static void dummy_notify_app(uint8_t packet_type, uint8_t *packet, uint16_t size){} - static void emit_service(void){ uint8_t event[3+SDP_SERVICE_NAME_LEN+1]; event[0] = SDP_EVENT_QUERY_RFCOMM_SERVICE; @@ -101,17 +94,10 @@ static void emit_service(void){ event[2] = sdp_rfcomm_channel_nr; memcpy(&event[3], sdp_service_name, sdp_service_name_len); event[3+sdp_service_name_len] = 0; - (*sdp_app_callback)(HCI_EVENT_PACKET, event, sizeof(event)); + (*sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); sdp_rfcomm_channel_nr = 0; } -void sdp_query_rfcomm_register_callback(void (*sdp_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ - sdp_app_callback = dummy_notify_app; - if (sdp_callback != NULL){ - sdp_app_callback = sdp_callback; - } -} - static void handleProtocolDescriptorListData(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ // init state on first byte if (data_offset == 0){ @@ -253,7 +239,7 @@ static void handleServiceNameData(uint32_t attribute_value_length, uint32_t data } } -static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_SERVICE_RECORD_HANDLE: // handle service without a name @@ -292,7 +278,7 @@ static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16 if (sdp_rfcomm_channel_nr){ emit_service(); } - (*sdp_app_callback)(HCI_EVENT_PACKET, packet, size); + (*sdp_app_callback)(HCI_EVENT_PACKET, 0, packet, size); break; } // insert higher level code HERE @@ -304,19 +290,31 @@ void sdp_query_rfcomm_init(void){ de_state_init(&sn_de_header_state); pdl_state = GET_PROTOCOL_LIST_LENGTH; protocol_offset = 0; - sdp_parser_register_callback(handle_sdp_parser_event); sdp_rfcomm_channel_nr = 0; sdp_service_name[0] = 0; } +// Public API -void sdp_query_rfcomm_channel_and_name_for_search_pattern(bd_addr_t remote, uint8_t * serviceSearchPattern){ - sdp_parser_init(); +int sdp_query_rfcomm_ready(void){ + return sdp_client_ready(); +} + +void sdp_query_rfcomm_channel_and_name_for_search_pattern(btstack_packet_handler_t callback, bd_addr_t remote, uint8_t * serviceSearchPattern){ + if (!sdp_query_rfcomm_ready()){ + log_error("sdp_query_rfcomm_channel_and_name_for_search_pattern called when not readdy"); + return; + } + sdp_app_callback = callback; sdp_query_rfcomm_init(); - sdp_client_query(remote, serviceSearchPattern, (uint8_t*)&des_attributeIDList[0]); + sdp_client_query(&handle_sdp_parser_event, remote, serviceSearchPattern, (uint8_t*)&des_attributeIDList[0]); } -void sdp_query_rfcomm_channel_and_name_for_uuid(bd_addr_t remote, uint16_t uuid){ +void sdp_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid){ + if (!sdp_query_rfcomm_ready()){ + log_error("sdp_query_rfcomm_channel_and_name_for_uuid called when not readdy"); + return; + } big_endian_store_16(des_serviceSearchPattern, 3, uuid); - sdp_query_rfcomm_channel_and_name_for_search_pattern(remote, (uint8_t*)des_serviceSearchPattern); + sdp_query_rfcomm_channel_and_name_for_search_pattern(callback, remote, (uint8_t*)des_serviceSearchPattern); } diff --git a/src/classic/sdp_query_rfcomm.h b/src/classic/sdp_query_rfcomm.h index e55d92a7e..3b9bd0b40 100644 --- a/src/classic/sdp_query_rfcomm.h +++ b/src/classic/sdp_query_rfcomm.h @@ -43,7 +43,6 @@ #define __SDP_QUERY_RFCOMM_H #include "btstack_util.h" -#include "classic/sdp_parser.h" #include "classic/sdp_query_util.h" #define SDP_SERVICE_NAME_LEN 20 @@ -55,19 +54,20 @@ extern "C" { /* API_START */ /** - * @brief Registers a callback to receive RFCOMM service and query complete event. + * @brief Checks if the SDP Client is ready + * @return 1 when no query is active */ -void sdp_query_rfcomm_register_callback(void(*sdp_app_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size)); +int sdp_query_rfcomm_ready(void); /** * @brief Searches SDP records on a remote device for RFCOMM services with a given UUID. */ -void sdp_query_rfcomm_channel_and_name_for_uuid(bd_addr_t remote, uint16_t uuid); +void sdp_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid); /** * @brief Searches SDP records on a remote device for RFCOMM services with a given service search pattern. */ -void sdp_query_rfcomm_channel_and_name_for_search_pattern(bd_addr_t remote, uint8_t * des_serviceSearchPattern); +void sdp_query_rfcomm_channel_and_name_for_search_pattern(btstack_packet_handler_t callback, bd_addr_t remote, uint8_t * des_serviceSearchPattern); /* API_END */ #if defined __cplusplus diff --git a/src/classic/sdp_query_util.c b/src/classic/sdp_query_util.c index 3fba75de0..b100472bd 100644 --- a/src/classic/sdp_query_util.c +++ b/src/classic/sdp_query_util.c @@ -38,7 +38,7 @@ /* * sdp_query_util.c */ -#include "classic/sdp_parser.h" +#include "btstack_debug.h" #include "classic/sdp_client.h" #include "classic/sdp_query_util.h" @@ -54,21 +54,35 @@ static uint8_t* create_service_search_pattern_for_uuid128(uint8_t* uuid){ return (uint8_t*)des_serviceSearchPatternUUID128; } +/** + * @brief Checks if the SDP Client is ready + * @return 1 when no query is active + */ +int sdp_general_query_ready(void){ + return sdp_client_ready(); +} + uint8_t* create_service_search_pattern_for_uuid(uint16_t uuid){ big_endian_store_16(des_serviceSearchPattern, 3, uuid); return (uint8_t*)des_serviceSearchPattern; } -void sdp_general_query_for_uuid(bd_addr_t remote, uint16_t uuid){ +void sdp_general_query_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid){ + if (!sdp_client_ready()){ + log_error("sdp_general_query_for_uuid called when not readdy"); + return; + } create_service_search_pattern_for_uuid(uuid); - sdp_parser_init(); - sdp_client_query(remote, (uint8_t*)&des_serviceSearchPattern[0], (uint8_t*)&des_attributeIDList[0]); + sdp_client_query(callback, remote, (uint8_t*)&des_serviceSearchPattern[0], (uint8_t*)&des_attributeIDList[0]); } -void sdp_general_query_for_uuid128(bd_addr_t remote, uint8_t* uuid){ +void sdp_general_query_for_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, uint8_t* uuid){ + if (!sdp_client_ready()){ + log_error("sdp_general_query_for_uuid called when not readdy"); + return; + } create_service_search_pattern_for_uuid128(uuid); - sdp_parser_init(); - sdp_client_query(remote, (uint8_t*)&des_serviceSearchPatternUUID128[0], (uint8_t*)&des_attributeIDList[0]); + sdp_client_query(callback, remote, (uint8_t*)&des_serviceSearchPatternUUID128[0], (uint8_t*)&des_attributeIDList[0]); } diff --git a/src/classic/sdp_query_util.h b/src/classic/sdp_query_util.h index 2f5ca3a36..5667b2640 100644 --- a/src/classic/sdp_query_util.h +++ b/src/classic/sdp_query_util.h @@ -54,15 +54,21 @@ extern "C" { */ uint8_t* create_service_search_pattern_for_uuid(uint16_t uuid); +/** + * @brief Checks if the SDP Client is ready + * @return 1 when no query is active + */ +int sdp_general_query_ready(void); + /* * @brief Searches SDP records on a remote device for all services with a given UUID. */ -void sdp_general_query_for_uuid(bd_addr_t remote, uint16_t uuid16); +void sdp_general_query_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16); /* * @brief */ -void sdp_general_query_for_uuid128(bd_addr_t remote, uint8_t* uuid128); +void sdp_general_query_for_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, uint8_t* uuid128); /* API_END */ diff --git a/src/classic/sdp_util.c b/src/classic/sdp_util.c index 50a94f6ed..2ae0380e8 100644 --- a/src/classic/sdp_util.c +++ b/src/classic/sdp_util.c @@ -61,15 +61,15 @@ const char * const type_names[] = { "NIL", "UINT", "INT", "UUID", "STRING", "BOO #endif // MARK: DataElement getter -de_size_t de_get_size_type(uint8_t *header){ +de_size_t de_get_size_type(const uint8_t *header){ return (de_size_t) (header[0] & 7); } -de_type_t de_get_element_type(uint8_t *header){ +de_type_t de_get_element_type(const uint8_t *header){ return (de_type_t) (header[0] >> 3); } -int de_get_header_size(uint8_t * header){ +int de_get_header_size(const uint8_t * header){ de_size_t de_size = de_get_size_type(header); if (de_size <= DE_SIZE_128) { return 1; @@ -77,7 +77,7 @@ int de_get_header_size(uint8_t * header){ return 1 + (1 << (de_size-DE_SIZE_VAR_8)); } -int de_get_data_size(uint8_t * header){ +int de_get_data_size(const uint8_t * header){ uint32_t result = 0; de_type_t de_type = de_get_element_type(header); de_size_t de_size = de_get_size_type(header); @@ -103,19 +103,19 @@ int de_get_data_size(uint8_t * header){ return result; } -int de_get_len(uint8_t *header){ +int de_get_len(const uint8_t *header){ return de_get_header_size(header) + de_get_data_size(header); } // @returns OK, if UINT16 value was read -int de_element_get_uint16(uint8_t * element, uint16_t * value){ +int de_element_get_uint16(const uint8_t * element, uint16_t * value){ if (de_get_size_type(element) != DE_SIZE_16) return 0; *value = big_endian_read_16(element, de_get_header_size(element)); return 1; } // @returns: element is valid UUID -int de_get_normalized_uuid(uint8_t *uuid128, uint8_t *element){ +int de_get_normalized_uuid(uint8_t *uuid128, const uint8_t *element){ de_type_t uuidType = de_get_element_type(element); de_size_t uuidSize = de_get_size_type(element); if (uuidType != DE_UUID) return 0; @@ -138,7 +138,7 @@ int de_get_normalized_uuid(uint8_t *uuid128, uint8_t *element){ } // @returns 0 if no UUID16 or UUID32 is present, and UUID32 otherwise -uint32_t de_get_uuid32(uint8_t * element){ +uint32_t de_get_uuid32(const uint8_t * element){ uint8_t uuid128[16]; int validUuid128 = de_get_normalized_uuid(uuid128, element); if (!validUuid128) return 0; @@ -665,13 +665,13 @@ static int de_traversal_dump_data(uint8_t * element, de_type_t de_type, de_size_ } #endif -void de_dump_data_element(uint8_t * record){ +void de_dump_data_element(const uint8_t * record){ #ifdef ENABLE_SDP_DES_DUMP int indent = 0; // hack to get root DES, too. de_type_t type = de_get_element_type(record); de_size_t size = de_get_size_type(record); - de_traversal_dump_data(record, type, size, (void*) &indent); + de_traversal_dump_data((uint8_t *) record, type, size, (void*) &indent); #endif } diff --git a/src/classic/sdp_util.h b/src/classic/sdp_util.h index 8c8b5e5a8..59302c595 100644 --- a/src/classic/sdp_util.h +++ b/src/classic/sdp_util.h @@ -74,23 +74,24 @@ typedef enum { } de_size_t; // MARK: DateElement -void de_dump_data_element(uint8_t * record); -int de_get_len(uint8_t *header); -de_size_t de_get_size_type(uint8_t *header); -de_type_t de_get_element_type(uint8_t *header); -int de_get_header_size(uint8_t * header); -void de_create_sequence(uint8_t *header); +void de_dump_data_element(const uint8_t * record); +int de_get_len(const uint8_t * header); +de_size_t de_get_size_type(const uint8_t * header); +de_type_t de_get_element_type(const uint8_t * header); +int de_get_header_size(const uint8_t * header); +int de_element_get_uint16(const uint8_t * element, uint16_t * value); +int de_get_data_size(const uint8_t * header); +uint32_t de_get_uuid32(const uint8_t * element); +int de_get_normalized_uuid(uint8_t *uuid128, const uint8_t *element); + +void de_create_sequence(uint8_t * header); void de_store_descriptor_with_len(uint8_t * header, de_type_t type, de_size_t size, uint32_t len); uint8_t * de_push_sequence(uint8_t *header); void de_pop_sequence(uint8_t * parent, uint8_t * child); void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value); void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data); -int de_element_get_uint16(uint8_t * element, uint16_t * value); -int de_get_data_size(uint8_t * header); void de_add_uuid128(uint8_t * seq, uint8_t * uuid); -uint32_t de_get_uuid32(uint8_t * element); -int de_get_normalized_uuid(uint8_t *uuid128, uint8_t *element); // MARK: DES iterator typedef struct { diff --git a/test/hfp/hfp_ag_client_test.c b/test/hfp/hfp_ag_client_test.c index 55b50ae3c..4749ce5c6 100644 --- a/test/hfp/hfp_ag_client_test.c +++ b/test/hfp/hfp_ag_client_test.c @@ -59,7 +59,6 @@ #include "l2cap.h" #include "classic/rfcomm.h" #include "classic/sdp_server.h" -#include "classic/sdp_parser.h" #include "btstack_debug.h" #include "classic/hfp_ag.h" diff --git a/test/hfp/hfp_hf_client_test.c b/test/hfp/hfp_hf_client_test.c index 19d41e9c0..ff445e55e 100644 --- a/test/hfp/hfp_hf_client_test.c +++ b/test/hfp/hfp_hf_client_test.c @@ -59,7 +59,6 @@ #include "l2cap.h" #include "classic/rfcomm.h" #include "classic/sdp_server.h" -#include "classic/sdp_parser.h" #include "btstack_debug.h" #include "classic/hfp_hf.h" diff --git a/test/hfp/mock.c b/test/hfp/mock.c index 872b36d9c..64a445bc7 100644 --- a/test/hfp/mock.c +++ b/test/hfp/mock.c @@ -70,7 +70,7 @@ static uint8_t rfcomm_reserved_buffer[1000]; hfp_connection_t * hfp_context; void (*registered_rfcomm_packet_handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -void (*registered_sdp_app_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size); +void (*registered_sdp_app_callback)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); uint8_t * get_rfcomm_payload(){ return &rfcomm_payload[0]; @@ -198,17 +198,12 @@ int hci_send_cmd(const hci_cmd_t *cmd, ...){ return 0; } - -void sdp_query_rfcomm_register_callback(void(*sdp_app_callback)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ - registered_sdp_app_callback = sdp_app_callback; -} - static void sdp_query_complete_response(uint8_t status){ uint8_t event[3]; event[0] = SDP_EVENT_QUERY_COMPLETE; event[1] = 1; event[2] = status; - (*registered_sdp_app_callback)(HCI_EVENT_PACKET, event, sizeof(event)); + (*registered_sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); } static void sdp_query_rfcomm_service_response(uint8_t status){ @@ -219,11 +214,12 @@ static void sdp_query_rfcomm_service_response(uint8_t status){ event[2] = sdp_rfcomm_channel_nr; memcpy(&event[3], sdp_rfcomm_service_name, sdp_service_name_len); event[3+sdp_service_name_len] = 0; - (*registered_sdp_app_callback)(HCI_EVENT_PACKET, event, sizeof(event)); + (*registered_sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); } -void sdp_query_rfcomm_channel_and_name_for_uuid(bd_addr_t remote, uint16_t uuid){ +void sdp_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid){ // printf("sdp_query_rfcomm_channel_and_name_for_uuid %p\n", registered_sdp_app_callback); + registered_sdp_app_callback = callback; sdp_query_rfcomm_service_response(0); sdp_query_complete_response(0); } diff --git a/test/pts/classic_test.c b/test/pts/classic_test.c index f40aeb51c..56d920d88 100644 --- a/test/pts/classic_test.c +++ b/test/pts/classic_test.c @@ -398,7 +398,7 @@ static void handle_found_service(const char * name, uint8_t port){ rfcomm_channel_nr = port; } -static void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: handle_found_service(sdp_event_query_rfcomm_service_get_name(packet), @@ -596,7 +596,7 @@ static int stdin_process(struct btstack_data_source *ds){ case 'k': printf("Start SDP query for SPP service\n"); - sdp_query_rfcomm_channel_and_name_for_uuid(remote_rfcomm, 0x1101); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote_rfcomm, 0x1101); break; case 't': @@ -790,8 +790,6 @@ int btstack_main(int argc, const char * argv[]){ de_dump_data_element((uint8_t*)dummy_service_buffer); printf("Dummy service record size: %u\n\r", de_get_len((uint8_t*)dummy_service_buffer)); sdp_register_service((uint8_t*)dummy_service_buffer); - - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); hci_discoverable_control(0); hci_connectable_control(0); diff --git a/test/pts/hfp_test.c b/test/pts/hfp_test.c index eb1f6ab68..e923ec8a3 100644 --- a/test/pts/hfp_test.c +++ b/test/pts/hfp_test.c @@ -107,7 +107,7 @@ static void packet_handler(void * connection, uint8_t packet_type, uint16_t chan // bt stack activated, get started if (packet[2] == HCI_STATE_WORKING){ printf("Start SDP RFCOMM Query for UUID 0x%02x\n", SDP_Handsfree); - // sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_Handsfree); + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_Handsfree); } break; @@ -146,7 +146,7 @@ static void hci_event_handler(uint8_t packet_type, uint8_t * packet, uint16_t si } -void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (event->type){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: channel_nr = sdp_event_query_rfcomm_service_get_name(packet); @@ -177,8 +177,6 @@ int btstack_main(int argc, const char * argv[]){ l2cap_init(); rfcomm_init(); - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - // turn on! hci_power_control(HCI_POWER_ON); diff --git a/test/pts/iopt.c b/test/pts/iopt.c index 8c8a260e3..ed509a678 100644 --- a/test/pts/iopt.c +++ b/test/pts/iopt.c @@ -103,10 +103,10 @@ int btstack_main(int argc, const char * argv[]){ pan_create_panu_service(pan_service_buffer, 0x10002, network_packet_types, NULL, NULL, BNEP_SECURITY_NONE); sdp_register_service((uint8_t*)pan_service_buffer); - hsp_ag_create_service((uint8_t *)hsp_ag_service_buffer, 0x10003, 2, "HSP AG"); + hsp_ag_create_sdp_record((uint8_t *)hsp_ag_service_buffer, 0x10003, 2, "HSP AG"); sdp_register_service((uint8_t *)hsp_ag_service_buffer); - hsp_hs_create_service((uint8_t *)hsp_hs_service_buffer, 0x10004, 3, "HSP HS", 0); + hsp_hs_create_sdp_record((uint8_t *)hsp_hs_service_buffer, 0x10004, 3, "HSP HS", 0); sdp_register_service((uint8_t *)hsp_hs_service_buffer); hfp_ag_create_sdp_record((uint8_t *)hfp_ag_service_buffer, 0x10005, 4, "HFP AG", 0, 0); diff --git a/test/sdp_client/Makefile b/test/sdp_client/Makefile index 27a086fd3..de64423e0 100644 --- a/test/sdp_client/Makefile +++ b/test/sdp_client/Makefile @@ -15,7 +15,8 @@ VPATH += ${BTSTACK_ROOT}/platform/posix COMMON = \ sdp_util.c \ - sdp_parser.c \ + sdp_client.c \ + mock.c \ hci_dump.c \ btstack_util.c \ diff --git a/test/sdp_client/general_sdp_query.c b/test/sdp_client/general_sdp_query.c index 2bea9c2b3..bf5c22946 100644 --- a/test/sdp_client/general_sdp_query.c +++ b/test/sdp_client/general_sdp_query.c @@ -15,11 +15,11 @@ #include "btstack_event.h" #include "btstack_memory.h" #include "btstack_run_loop.h" -#include "classic/sdp_parser.h" #include "hci.h" #include "hci_cmd.h" #include "hci_dump.h" #include "l2cap.h" +#include "mock.h" #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" @@ -95,7 +95,6 @@ static uint8_t sdp_test_record_list[] = { 0x09, 0x03, 0x0A, 0x09, 0x00, 0x01, 0x09, 0x03, 0x0B, 0x09, 0x00, 0x05 }; - uint16_t attribute_id = -1; uint16_t record_id = -1; @@ -142,7 +141,7 @@ static void test_attribute_value_event(const uint8_t * event){ } -static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: test_attribute_value_event(packet); @@ -168,8 +167,7 @@ TEST_GROUP(SDPClient){ attribute_value_buffer_size = 1000; attribute_value = (uint8_t*) malloc(attribute_value_buffer_size); record_id = -1; - sdp_parser_init(); - sdp_parser_register_callback(handle_sdp_parser_event); + sdp_parser_init(&handle_sdp_parser_event); } }; diff --git a/test/sdp_client/sdp_rfcomm_query.c b/test/sdp_client/sdp_rfcomm_query.c index cfa79beea..28d21dd98 100644 --- a/test/sdp_client/sdp_rfcomm_query.c +++ b/test/sdp_client/sdp_rfcomm_query.c @@ -21,6 +21,7 @@ #include "hci_dump.h" #include "l2cap.h" #include "btstack_event.h" +#include "mock.h" #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" @@ -82,15 +83,8 @@ static uint8_t sdp_test_record_list[] = { 0x36, 0x02, 0xE7, 0x35, 0x48, 0x6B, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65 }; -// dummy function to allow compile without the stack -extern "C" void sdp_client_query(bd_addr_t remote, uint8_t * des_serviceSearchPattern, uint8_t * des_attributeIDList){ -} -// for test purposes -void sdp_query_rfcomm_init(); - - -void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_RFCOMM_SERVICE: channel_nr[service_index] = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet); @@ -109,12 +103,13 @@ void handle_query_rfcomm_event(uint8_t packet_type, uint8_t *packet, uint16_t si TEST_GROUP(SDPClient){ uint8_t spp_buffer[sizeof(sdp_test_record_list)]; + bd_addr_t address; void setup(void){ service_index = 0; - sdp_query_rfcomm_register_callback(handle_query_rfcomm_event); - sdp_parser_init(); - sdp_query_rfcomm_init(); + sdp_client_reset(); // avoid "not ready" warning + // start query using public API although data will be injected + sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, address, 0x1234); } }; @@ -148,7 +143,6 @@ TEST(SDPClient, QueryRFCOMMWithMacOSXData){ "Bluetooth-PDA-Sync", "Headset Audio Gatewa"}; uint8_t expected_channel[] = {10, 2, 15, 3, 4}; // de_dump_data_element(sdp_test_record_list); - sdp_parser_handle_chunk(sdp_test_record_list, de_get_len(sdp_test_record_list)); CHECK_EQUAL(service_index, 5); diff --git a/test/sdp_client/service_attribute_search_query.c b/test/sdp_client/service_attribute_search_query.c index 62cf0b904..d2ba75ea7 100644 --- a/test/sdp_client/service_attribute_search_query.c +++ b/test/sdp_client/service_attribute_search_query.c @@ -15,11 +15,11 @@ #include "btstack_event.h" #include "btstack_memory.h" #include "btstack_run_loop.h" -#include "classic/sdp_parser.h" #include "hci.h" #include "hci_cmd.h" #include "hci_dump.h" #include "l2cap.h" +#include "mock.h" #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" @@ -87,7 +87,7 @@ static void test_attribute_value_event(const uint8_t * event){ } -static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet[0]){ case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: test_attribute_value_event(packet); @@ -113,8 +113,8 @@ TEST_GROUP(SDPClient){ attribute_value_buffer_size = 1000; attribute_value = (uint8_t*) malloc(attribute_value_buffer_size); record_id = -1; + sdp_parser_init(&handle_sdp_parser_event); sdp_parser_init_service_attribute_search(); - sdp_parser_register_callback(handle_sdp_parser_event); } }; diff --git a/test/sdp_client/service_search_query.c b/test/sdp_client/service_search_query.c index 3a8b17d20..d61c0dd0c 100644 --- a/test/sdp_client/service_search_query.c +++ b/test/sdp_client/service_search_query.c @@ -15,11 +15,11 @@ #include "btstack_event.h" #include "btstack_memory.h" #include "btstack_run_loop.h" -#include "classic/sdp_parser.h" #include "hci.h" #include "hci_cmd.h" #include "hci_dump.h" #include "l2cap.h" +#include "mock.h" #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" @@ -39,8 +39,7 @@ static uint8_t sdp_test_record_list[] = { 0x00, 0x00, 0x00, 0x0A }; - -static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16_t size){ +static void handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ static uint32_t record_handle = sdp_test_record_list[0]; switch (packet[0]){ case SDP_EVENT_QUERY_SERVICE_RECORD_HANDLE: @@ -56,8 +55,8 @@ static void handle_sdp_parser_event(uint8_t packet_type, uint8_t *packet, uint16 TEST_GROUP(SDPClient){ void setup(void){ + sdp_parser_init(&handle_sdp_parser_event); sdp_parser_init_service_search(); - sdp_parser_register_callback(handle_sdp_parser_event); } };