From 12fb62f7a8f98bb400119930053af072b4719371 Mon Sep 17 00:00:00 2001 From: "matthias.ringwald@gmail.com" Date: Thu, 17 Oct 2013 14:28:55 +0000 Subject: [PATCH] started adding client-server functionality (SDP query) --- src/daemon.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++- src/hci.h | 3 +++ src/hci_cmds.c | 6 ++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/daemon.c b/src/daemon.c index 5ed137099..829dd57f1 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -65,7 +65,9 @@ #include "l2cap.h" #include "rfcomm.h" #include "sdp.h" +#include "sdp_parser.h" #include "sdp_client.h" +#include "sdp_query_util.h" #include "sdp_query_rfcomm.h" #include "socket_connection.h" @@ -103,6 +105,7 @@ typedef struct { // MARK: prototypes static void handle_sdp_rfcomm_service_result(sdp_query_event_t * event, void * context); +static void handle_sdp_client_query_result(sdp_parser_event_t * event); static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state); static client_state_t * client_for_connection(connection_t *connection); static int clients_require_power_on(void); @@ -125,6 +128,9 @@ static int global_enable = 0; static remote_device_db_t const * remote_device_db = NULL; static int rfcomm_channel_generator = 1; +static uint8_t attribute_value[1000]; +static const int attribute_value_buffer_size = sizeof(attribute_value); + static int loggingEnabled; static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){ @@ -325,7 +331,12 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui sdp_query_rfcomm_register_callback(handle_sdp_rfcomm_service_result, connection); sdp_query_rfcomm_channel_and_name_for_search_pattern(addr, &packet[9]); break; - + case SDP_CLIENT_QUERY_SERVICES: + bt_flip_addr(addr, &packet[3]); + sdp_parser_init(); + sdp_parser_register_callback(handle_sdp_client_query_result); + sdp_general_query_for_uuid(addr, 0x1002); + break; default: log_error("Error: command %u not implemented\n:", READ_CMD_OCF(packet)); break; @@ -549,6 +560,50 @@ static void handle_sdp_rfcomm_service_result(sdp_query_event_t * rfcomm_event, v } } +static void sdp_client_assert_buffer(int size){ + if (size > attribute_value_buffer_size){ + log_error("SDP attribute value buffer size exceeded: available %d, required %d", attribute_value_buffer_size, size); + } +} + +// define new packet type SDP_CLIENT_PACKET +static void handle_sdp_client_query_result(sdp_parser_event_t * event){ + sdp_parser_attribute_value_event_t * ve; + sdp_parser_complete_event_t * complete_event; + + switch (event->type){ + case SDP_PARSER_ATTRIBUTE_VALUE: + ve = (sdp_parser_attribute_value_event_t*) event; + + sdp_client_assert_buffer(ve->attribute_length); + + attribute_value[ve->data_offset] = ve->data; + + if ((uint16_t)(ve->data_offset+1) == ve->attribute_length){ + hexdump(attribute_value, ve->attribute_length); + + int event_len = 1 + 3 * 2 + ve->attribute_length; + uint8_t event[event_len]; + event[0] = SDP_QUERY_ATTRIBUTE_VALUE; + event[1] = ve->record_id; + event[3] = ve->attribute_id; + event[5] = ve->attribute_length; + + memcpy(&event[7], attribute_value, ve->attribute_length); + hci_dump_packet(SDP_CLIENT_PACKET, 0, event, event_len); + socket_connection_send_packet(NULL, SDP_CLIENT_PACKET, 0, event, event_len); + } + + break; + case SDP_PARSER_COMPLETE: + complete_event = (sdp_parser_complete_event_t*) event; + uint8_t event[] = { SDP_QUERY_COMPLETE, 1, complete_event->status}; + hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event)); + socket_connection_send_packet(NULL, HCI_EVENT_PACKET, 0, event, sizeof(event)); + break; + } +} + static void power_notification_callback(POWER_NOTIFICATION_t notification){ switch (notification) { case POWER_WILL_SLEEP: diff --git a/src/hci.h b/src/hci.h index 231872716..dd0d174e6 100644 --- a/src/hci.h +++ b/src/hci.h @@ -162,6 +162,9 @@ extern "C" { // Get remote RFCOMM services #define SDP_CLIENT_QUERY_RFCOMM_SERVICES 0x32 +// Get remote SDP services +#define SDP_CLIENT_QUERY_SERVICES 0x33 + // RFCOMM "HCI" Commands #define RFCOMM_CREATE_CHANNEL 0x40 #define RFCOMM_DISCONNECT 0x41 diff --git a/src/hci_cmds.c b/src/hci_cmds.c index fd2539246..79b13c3db 100644 --- a/src/hci_cmds.c +++ b/src/hci_cmds.c @@ -670,11 +670,17 @@ const hci_cmd_t sdp_unregister_service_record = { OPCODE(OGF_BTSTACK, SDP_UNREGISTER_SERVICE_RECORD), "4" // @param service record handle (32) }; + const hci_cmd_t sdp_client_query_rfcomm_services = { OPCODE(OGF_BTSTACK, SDP_CLIENT_QUERY_RFCOMM_SERVICES), "BS" // @param service record handle (32) }; +const hci_cmd_t sdp_client_query_services = { +OPCODE(OGF_BTSTACK, SDP_CLIENT_QUERY_SERVICES), "BS" +// @param service record handle (32) +}; + // create rfcomm channel: @param bd_addr(48), channel (8) const hci_cmd_t rfcomm_create_channel = { OPCODE(OGF_BTSTACK, RFCOMM_CREATE_CHANNEL), "B1"