started adding client-server functionality (SDP query)

This commit is contained in:
matthias.ringwald@gmail.com 2013-10-17 14:28:55 +00:00
parent b11fb29405
commit 12fb62f7a8
3 changed files with 65 additions and 1 deletions

View File

@ -65,7 +65,9 @@
#include "l2cap.h" #include "l2cap.h"
#include "rfcomm.h" #include "rfcomm.h"
#include "sdp.h" #include "sdp.h"
#include "sdp_parser.h"
#include "sdp_client.h" #include "sdp_client.h"
#include "sdp_query_util.h"
#include "sdp_query_rfcomm.h" #include "sdp_query_rfcomm.h"
#include "socket_connection.h" #include "socket_connection.h"
@ -103,6 +105,7 @@ typedef struct {
// MARK: prototypes // MARK: prototypes
static void handle_sdp_rfcomm_service_result(sdp_query_event_t * event, void * context); 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 void dummy_bluetooth_status_handler(BLUETOOTH_STATE state);
static client_state_t * client_for_connection(connection_t *connection); static client_state_t * client_for_connection(connection_t *connection);
static int clients_require_power_on(void); 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 remote_device_db_t const * remote_device_db = NULL;
static int rfcomm_channel_generator = 1; 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 int loggingEnabled;
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){ 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_register_callback(handle_sdp_rfcomm_service_result, connection);
sdp_query_rfcomm_channel_and_name_for_search_pattern(addr, &packet[9]); sdp_query_rfcomm_channel_and_name_for_search_pattern(addr, &packet[9]);
break; 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: default:
log_error("Error: command %u not implemented\n:", READ_CMD_OCF(packet)); log_error("Error: command %u not implemented\n:", READ_CMD_OCF(packet));
break; 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){ static void power_notification_callback(POWER_NOTIFICATION_t notification){
switch (notification) { switch (notification) {
case POWER_WILL_SLEEP: case POWER_WILL_SLEEP:

View File

@ -162,6 +162,9 @@ extern "C" {
// Get remote RFCOMM services // Get remote RFCOMM services
#define SDP_CLIENT_QUERY_RFCOMM_SERVICES 0x32 #define SDP_CLIENT_QUERY_RFCOMM_SERVICES 0x32
// Get remote SDP services
#define SDP_CLIENT_QUERY_SERVICES 0x33
// RFCOMM "HCI" Commands // RFCOMM "HCI" Commands
#define RFCOMM_CREATE_CHANNEL 0x40 #define RFCOMM_CREATE_CHANNEL 0x40
#define RFCOMM_DISCONNECT 0x41 #define RFCOMM_DISCONNECT 0x41

View File

@ -670,11 +670,17 @@ const hci_cmd_t sdp_unregister_service_record = {
OPCODE(OGF_BTSTACK, SDP_UNREGISTER_SERVICE_RECORD), "4" OPCODE(OGF_BTSTACK, SDP_UNREGISTER_SERVICE_RECORD), "4"
// @param service record handle (32) // @param service record handle (32)
}; };
const hci_cmd_t sdp_client_query_rfcomm_services = { const hci_cmd_t sdp_client_query_rfcomm_services = {
OPCODE(OGF_BTSTACK, SDP_CLIENT_QUERY_RFCOMM_SERVICES), "BS" OPCODE(OGF_BTSTACK, SDP_CLIENT_QUERY_RFCOMM_SERVICES), "BS"
// @param service record handle (32) // @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) // create rfcomm channel: @param bd_addr(48), channel (8)
const hci_cmd_t rfcomm_create_channel = { const hci_cmd_t rfcomm_create_channel = {
OPCODE(OGF_BTSTACK, RFCOMM_CREATE_CHANNEL), "B1" OPCODE(OGF_BTSTACK, RFCOMM_CREATE_CHANNEL), "B1"