rework SDP Service Record management. Service Records can be stored in ROM, daemon creates records on the heap

This commit is contained in:
Matthias Ringwald 2015-11-15 20:56:59 +01:00
parent 60416aa529
commit 9293bfa465
18 changed files with 157 additions and 229 deletions

View File

@ -261,20 +261,9 @@ int btstack_main(void)
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
/* LISTING_PAUSE */
#ifdef EMBEDDED
/* LISTING_RESUME */
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, RFCOMM_SERVER_CHANNEL, "SPP Counter");
printf("SDP service buffer size: %u\n", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
/* LISTING_PAUSE */
#else
sdp_create_spp_service( (uint8_t*)spp_service_buffer, RFCOMM_SERVER_CHANNEL, "SPP Counter");
printf("SDP service record size: %u\n", de_get_len((uint8_t*)spp_service_buffer));
sdp_register_service_internal((uint8_t*)spp_service_buffer);
#endif
/* LISTING_RESUME */
sdp_register_service((uint8_t*)spp_service_buffer);
hci_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);

View File

@ -100,20 +100,9 @@ static void spp_service_setup(void){
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
/* LISTING_PAUSE */
#ifdef EMBEDDED
/* LISTING_RESUME */
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, RFCOMM_SERVER_CHANNEL, "SPP Counter");
printf("SDP service buffer size: %u\n", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
/* LISTING_PAUSE */
#else
sdp_create_spp_service( (uint8_t*) spp_service_buffer, RFCOMM_SERVER_CHANNEL, "SPP Counter");
printf("SDP service record size: %u\n", de_get_len((uint8_t*) spp_service_buffer));
sdp_register_service_internal((uint8_t*)spp_service_buffer);
#endif
/* LISTING_RESUME */
sdp_register_service((uint8_t*)spp_service_buffer);
}
/* LISTING_END */

View File

@ -88,15 +88,14 @@ static void spp_service_setup(void){
rfcomm_init();
rfcomm_register_packet_handler(packet_handler);
// reserved channel, mtu limited by l2cap, 1 credit
rfcomm_register_service_with_initial_credits_internal(NULL, rfcomm_channel_nr, 0xffff, 1);
rfcomm_register_service_with_initial_credits(rfcomm_channel_nr, 0xffff, 1);
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
sdp_create_spp_service( (uint8_t*) &spp_service_buffer, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) sdp_create_spp_service));
sdp_register_service(spp_service_buffer);
}
/* LISTING_END */

View File

@ -498,7 +498,7 @@ static void daemon_sdp_close_connection(client_state_t * daemon_client){
linked_list_iterator_init(&it, list);
while (linked_list_iterator_has_next(&it)){
linked_list_uint32_t * item = (linked_list_uint32_t*) linked_list_iterator_next(&it);
sdp_unregister_service_internal(&daemon_client->connection, item->value);
sdp_unregister_service(item->value);
linked_list_remove(list, (linked_item_t *) item);
free(item);
}
@ -521,6 +521,45 @@ static connection_t * connection_for_l2cap_cid(uint16_t cid){
return NULL;
}
static const uint8_t removeServiceRecordHandleAttributeIDList[] = { 0x36, 0x00, 0x05, 0x0A, 0x00, 0x01, 0xFF, 0xFF };
// register a service record
// pre: AttributeIDs are in ascending order
// pre: ServiceRecordHandle is first attribute and is not already registered in database
// @returns status
static uint32_t daemon_sdp_create_and_register_service(uint8_t * record){
// create new handle
uint32_t record_handle = sdp_create_service_record_handle();
// calculate size of new service record: DES (2 byte len)
// + ServiceRecordHandle attribute (UINT16 UINT32) + size of existing attributes
uint16_t recordSize = 3 + (3 + 5) + de_get_data_size(record);
// alloc memory for new service record
uint8_t * newRecord = malloc(recordSize);
if (!newRecord) return 0;
// create DES for new record
de_create_sequence(newRecord);
// set service record handle
de_add_number(newRecord, DE_UINT, DE_SIZE_16, 0);
de_add_number(newRecord, DE_UINT, DE_SIZE_32, record_handle);
// add other attributes
sdp_append_attributes_in_attributeIDList(record, (uint8_t *) removeServiceRecordHandleAttributeIDList, 0, recordSize, newRecord);
uint8_t status = sdp_register_service(newRecord);
if (status) {
free(newRecord);
return 0;
}
return record_handle;
}
static connection_t * connection_for_rfcomm_cid(uint16_t cid){
linked_list_iterator_t cl;
linked_list_iterator_init(&cl, &clients);
@ -637,7 +676,6 @@ static void send_l2cap_connection_open_failed(connection_t * connection, bd_addr
}
static void l2cap_emit_service_registered(void *connection, uint8_t status, uint16_t psm){
log_info("L2CAP_EVENT_SERVICE_REGISTERED status 0x%x psm 0x%x", status, psm);
uint8_t event[5];
event[0] = L2CAP_EVENT_SERVICE_REGISTERED;
event[1] = sizeof(event) - 2;
@ -648,7 +686,6 @@ static void l2cap_emit_service_registered(void *connection, uint8_t status, uint
}
static void rfcomm_emit_service_registered(void *connection, uint8_t status, uint8_t channel){
log_info("RFCOMM_EVENT_SERVICE_REGISTERED status 0x%x channel #%u", status, channel);
uint8_t event[4];
event[0] = RFCOMM_EVENT_SERVICE_REGISTERED;
event[1] = sizeof(event) - 2;
@ -675,10 +712,8 @@ static void send_rfcomm_create_channel_failed(void * connection, bd_addr_t addr,
socket_connection_send_packet(connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
}
// data: event(8), len(8), status(8), service_record_handle(32)
static void sdp_emit_service_registered(void *connection, uint32_t handle, uint8_t status) {
if (!app_packet_handler) return;
uint8_t event[7];
event[0] = SDP_SERVICE_REGISTERED;
event[1] = sizeof(event) - 2;
@ -781,14 +816,13 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
uint32_t service_record_handle;
client_state_t *client;
uint8_t status;
uint8_t * data;
#if defined(HAVE_MALLOC) && defined(HAVE_BLE)
uint8_t uuid128[16];
le_service_t service;
le_characteristic_t characteristic;
le_characteristic_descriptor_t descriptor;
uint16_t data_length;
uint8_t * data;
linked_list_gatt_client_helper_t * gatt_helper;
#endif
@ -985,10 +1019,9 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
socket_connection_send_packet(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
break;
}
case SDP_REGISTER_SERVICE_RECORD:
log_info("SDP_REGISTER_SERVICE_RECORD size %u\n", size);
service_record_handle = sdp_register_service_internal(&packet[3]);
service_record_handle = daemon_sdp_create_and_register_service(&packet[3]);
if (service_record_handle){
daemon_add_client_sdp_service_record_handle(connection, service_record_handle);
sdp_emit_service_registered(connection, service_record_handle, 0);
@ -999,8 +1032,12 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
case SDP_UNREGISTER_SERVICE_RECORD:
service_record_handle = READ_BT_32(packet, 3);
log_info("SDP_UNREGISTER_SERVICE_RECORD handle 0x%x ", service_record_handle);
sdp_unregister_service_internal(service_record_handle);
data = sdp_get_record_for_handle(service_record_handle);
sdp_unregister_service(service_record_handle);
daemon_remove_client_sdp_service_record_handle(connection, service_record_handle);
if (data){
free(data);
}
break;
case SDP_CLIENT_QUERY_RFCOMM_SERVICES:
bt_flip_addr(addr, &packet[3]);

View File

@ -227,10 +227,9 @@ int btstack_main(int argc, const char * argv[]){
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
sdp_create_spp_service( (uint8_t*) spp_service_buffer, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) (de_get_len((uint8_t*) spp_service_buffer)));
sdp_register_service(service_record_item);
// set one-shot timer
timer_source_t heartbeat;

View File

@ -217,10 +217,9 @@ int btstack_main(int argc, const char * argv[]){
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Accel");
printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
sdp_create_spp_service((uint8_t*) spp_service_buffer, 1, "SPP Accel");
printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) spp_service_buffer));
sdp_register_service((uint8_t*) spp_service_buffer);
// ready - enable irq used in h4 task
__enable_interrupt();

View File

@ -227,10 +227,9 @@ int btstack_main(int argc, const char * argv[]){
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
sdp_create_spp_service( (uint8_t*) spp_service_buffer, 1, "SPP Counter");
printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) spp_service_buffer));
sdp_register_service(spp_service_buffer);
// set one-shot timer
timer_source_t heartbeat;

View File

@ -217,10 +217,9 @@ int btstack_main(int argc, const char * argv[]){
// init SDP, create record for SPP and register with SDP
sdp_init();
memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Accel");
printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
sdp_create_spp_service( (uint8_t*) spp_service_buffer, 1, "SPP Accel");
printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) spp_service_buffer));
sdp_register_service(spp_service_buffer);
// ready - enable irq used in h4 task
__enable_interrupt();

View File

@ -39,17 +39,16 @@
* Implementation of the Service Discovery Protocol Server
*/
#include "classic/sdp.h"
#include <stdio.h>
#include <string.h>
#include "classic/sdp_util.h"
#include "btstack_memory.h"
#include "debug.h"
#include "hci_dump.h"
#include "l2cap.h"
#include "debug.h"
#include "classic/sdp.h"
#include "classic/sdp_util.h"
// max reserved ServiceRecordHandle
#define maxReservedServiceRecordHandle 0xffff
@ -58,7 +57,6 @@
#define SDP_RESPONSE_BUFFER_SIZE (HCI_ACL_BUFFER_SIZE-HCI_ACL_HEADER_SIZE)
static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
uint32_t sdp_get_service_record_handle(uint8_t * record);
// registered service records
static linked_list_t sdp_service_records = NULL;
@ -76,15 +74,16 @@ void sdp_init(void){
l2cap_register_service(sdp_packet_handler, PSM_SDP, 0xffff, LEVEL_0);
}
uint32_t sdp_get_service_record_handle(uint8_t * record){
uint8_t * serviceRecordHandleAttribute = sdp_get_attribute_value_for_attribute_id(record, SDP_ServiceRecordHandle);
uint32_t sdp_get_service_record_handle(const uint8_t * record){
// TODO: make sdp_get_attribute_value_for_attribute_id accept const data to remove cast
uint8_t * serviceRecordHandleAttribute = sdp_get_attribute_value_for_attribute_id((uint8_t *)record, SDP_ServiceRecordHandle);
if (!serviceRecordHandleAttribute) return 0;
if (de_get_element_type(serviceRecordHandleAttribute) != DE_UINT) return 0;
if (de_get_size_type(serviceRecordHandleAttribute) != DE_SIZE_32) return 0;
return READ_NET_32(serviceRecordHandleAttribute, 1);
}
static service_record_item_t * sdp_get_record_for_handle(uint32_t handle){
static service_record_item_t * sdp_get_record_item_for_handle(uint32_t handle){
linked_item_t *it;
for (it = (linked_item_t *) sdp_service_records; it ; it = it->next){
service_record_item_t * item = (service_record_item_t *) it;
@ -95,140 +94,58 @@ static service_record_item_t * sdp_get_record_for_handle(uint32_t handle){
return NULL;
}
uint8_t * sdp_get_record_for_handle(uint32_t handle){
service_record_item_t * record_item = sdp_get_record_item_for_handle(handle);
if (!record_item) return 0;
return record_item->service_record;
}
// get next free, unregistered service record handle
static uint32_t sdp_create_service_record_handle(void){
uint32_t sdp_create_service_record_handle(void){
uint32_t handle = 0;
do {
handle = sdp_next_service_record_handle++;
if (sdp_get_record_for_handle(handle)) handle = 0;
if (sdp_get_record_item_for_handle(handle)) handle = 0;
} while (handle == 0);
return handle;
}
#ifdef EMBEDDED
/**
* @brief Register Service Record with database using ServiceRecordHandle stored in record
* @pre AttributeIDs are in ascending order
* @pre ServiceRecordHandle is first attribute and valid
* @param record is not copied!
* @result status
*/
uint8_t sdp_register_service(const uint8_t * record){
// register service record internally - this special version doesn't copy the record, it should not be freeed
// pre: AttributeIDs are in ascending order
// pre: ServiceRecordHandle is first attribute and valid
// pre: record
// @returns ServiceRecordHandle or 0 if registration failed
uint32_t sdp_register_service_internal(service_record_item_t * record_item){
// get user record handle
uint32_t record_handle = record_item->service_record_handle;
// get actual record
uint8_t *record = record_item->service_record;
// check for ServiceRecordHandle attribute, returns pointer or null
uint8_t * req_record_handle = sdp_get_attribute_value_for_attribute_id(record, SDP_ServiceRecordHandle);
if (!req_record_handle) {
log_error("SDP Error - record does not contain ServiceRecordHandle attribute");
return 0;
}
// validate service record handle is not in reserved range
if (record_handle <= maxReservedServiceRecordHandle) record_handle = 0;
// check if already in use
if (record_handle) {
if (sdp_get_record_for_handle(record_handle)) {
record_handle = 0;
}
}
// create new handle if needed
if (!record_handle){
record_handle = sdp_create_service_record_handle();
// Write the handle back into the record too
record_item->service_record_handle = record_handle;
sdp_set_attribute_value_for_attribute_id(record, SDP_ServiceRecordHandle, record_handle);
}
// add to linked list
linked_list_add(&sdp_service_records, (linked_item_t *) record_item);
return record_handle;
}
#else
// AttributeIDList used to remove ServiceRecordHandle
static const uint8_t removeServiceRecordHandleAttributeIDList[] = { 0x36, 0x00, 0x05, 0x0A, 0x00, 0x01, 0xFF, 0xFF };
// register service record internally - the normal version creates a copy of the record
// pre: AttributeIDs are in ascending order => ServiceRecordHandle is first attribute if present
// @returns ServiceRecordHandle or 0 if registration failed
uint32_t sdp_register_service_internal(uint8_t * record){
// dump for now
// log_info("Register service record");
// de_dump_data_element(record);
// get user record handle
// validate service record handle. it must: exist, be in valid range, not have been already used
uint32_t record_handle = sdp_get_service_record_handle(record);
if (!record_handle) return SDP_HANDLE_INVALID;
if (record_handle <= maxReservedServiceRecordHandle) return SDP_HANDLE_INVALID;
if (sdp_get_record_item_for_handle(record_handle)) return SDP_HANDLE_ALREADY_REGISTERED;
// validate service record handle is not in reserved range
if (record_handle <= maxReservedServiceRecordHandle) record_handle = 0;
// check if already in use
if (record_handle) {
if (sdp_get_record_for_handle(record_handle)) {
record_handle = 0;
}
}
// create new handle if needed
if (!record_handle){
record_handle = sdp_create_service_record_handle();
}
// calculate size of new service record: DES (2 byte len)
// + ServiceRecordHandle attribute (UINT16 UINT32) + size of existing attributes
uint16_t recordSize = 3 + (3 + 5) + de_get_data_size(record);
// alloc memory for new service_record_item
service_record_item_t * newRecordItem = (service_record_item_t *) malloc(recordSize + sizeof(service_record_item_t));
if (!newRecordItem) {
return 0;
}
// set new handle
newRecordItem->service_record_handle = record_handle;
service_record_item_t * newRecordItem = btstack_memory_service_record_item_get();
if (!newRecordItem) return BTSTACK_MEMORY_ALLOC_FAILED;
// create updated service record
uint8_t * newRecord = (uint8_t *) &(newRecordItem->service_record);
// create DES for new record
de_create_sequence(newRecord);
// set service record handle
de_add_number(newRecord, DE_UINT, DE_SIZE_16, 0);
de_add_number(newRecord, DE_UINT, DE_SIZE_32, record_handle);
// add other attributes
sdp_append_attributes_in_attributeIDList(record, (uint8_t *) removeServiceRecordHandleAttributeIDList, 0, recordSize, newRecord);
// dump for now
// de_dump_data_element(newRecord);
// log_info("reserved size %u, actual size %u", recordSize, de_get_len(newRecord));
// set handle and record
newRecordItem->service_record_handle = record_handle;
newRecordItem->service_record = (uint8_t*) record;
// add to linked list
linked_list_add(&sdp_service_records, (linked_item_t *) newRecordItem);
return record_handle;
return 0;
}
#endif
// unregister service record internally
//
// makes sure one client cannot remove service records of other clients
//
void sdp_unregister_service_internal(uint32_t service_record_handle){
service_record_item_t * record_item = sdp_get_record_for_handle(service_record_handle);
// unregister service record
//
void sdp_unregister_service(uint32_t service_record_handle){
service_record_item_t * record_item = sdp_get_record_item_for_handle(service_record_handle);
if (!record_item) return;
linked_list_remove(&sdp_service_records, (linked_item_t *) record_item);
#ifndef EMBEDDED
free(record_item);
#endif
}
// PDU
@ -343,7 +260,7 @@ int sdp_handle_service_attribute_request(uint8_t * packet, uint16_t remote_mtu){
}
// get service record
service_record_item_t * item = sdp_get_record_for_handle(serviceRecordHandle);
service_record_item_t * item = sdp_get_record_item_for_handle(serviceRecordHandle);
if (!item){
// service record handle doesn't exist
return sdp_create_error_response(transaction_id, 0x0002); /// invalid Service Record Handle

View File

@ -57,22 +57,18 @@ typedef enum {
SDP_ServiceSearchAttributeResponse
} SDP_PDU_ID_t;
// service record
// -- uses user_data field for actual
typedef struct {
// linked list - assert: first field
linked_item_t item;
// data is contained in same memory
uint32_t service_record_handle;
uint8_t service_record[1]; // waste 1 byte to allow compilation with older compilers
uint8_t * service_record;
} service_record_item_t;
int sdp_handle_service_search_request(uint8_t * packet, uint16_t remote_mtu);
int sdp_handle_service_attribute_request(uint8_t * packet, uint16_t remote_mtu);
int sdp_handle_service_search_attribute_request(uint8_t * packet, uint16_t remote_mtu);
/* API_START */
/**
@ -80,30 +76,43 @@ int sdp_handle_service_search_attribute_request(uint8_t * packet, uint16_t remot
*/
void sdp_init(void);
#ifdef EMBEDDED
/**
* @brief Register service record internally - this version doesn't copy the record therefore it must be forever accessible. Preconditions:
- AttributeIDs are in ascending order;
- ServiceRecordHandle is first attribute and valid.
* @return ServiceRecordHandle or 0 if registration failed.
/**
* @brief Register Service Record with database using ServiceRecordHandle stored in record
* @pre AttributeIDs are in ascending order
* @pre ServiceRecordHandle is first attribute and valid
* @param record is not copied!
* @result status
*/
uint32_t sdp_register_service_internal(service_record_item_t * record_item);
#endif
#ifndef EMBEDDED
/**
* @brief Register service record internally - this version creates a copy of the record precondition: AttributeIDs are in ascending order => ServiceRecordHandle is first attribute if present.
* @return ServiceRecordHandle or 0 if registration failed
*/
uint32_t sdp_register_service_internal(uint8_t * service_record);
#endif
uint8_t sdp_register_service(const uint8_t * record);
/**
* @brief Unregister service record internally.
*/
void sdp_unregister_service_internal(uint32_t service_record_handle);
void sdp_unregister_service(uint32_t service_record_handle);
/* API_END */
// used by daemon
/**
* @brief Finds an unused valid service record handle
* @result handle
*/
uint32_t sdp_create_service_record_handle(void);
/**
* @brief gets record for handle
* @result record
*/
uint8_t * sdp_get_record_for_handle(uint32_t handle);
/**
* @brief gets service record handle from record
* @resutl service record handle or 0
*/
uint32_t sdp_get_service_record_handle(const uint8_t * record);
#if defined __cplusplus
}
#endif

View File

@ -853,6 +853,7 @@ extern "C" {
#define SDP_HANDLE_ALREADY_REGISTERED 0x80
#define SDP_QUERY_INCOMPLETE 0x81
#define SDP_SERVICE_NOT_FOUND 0x82
#define SDP_HANDLE_INVALID 0x83
#define ATT_HANDLE_VALUE_INDICATION_IN_PORGRESS 0x90
#define ATT_HANDLE_VALUE_INDICATION_TIMEOUT 0x91

View File

@ -12,7 +12,7 @@
#include "ble/sm.h"
static btstack_packet_handler_t att_packet_handler;
static void (*registered_l2cap_packet_handler) (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL;
static void (*registered_l2cap_packet_handler) (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL;
static linked_list_t connections;
static const uint16_t max_mtu = 23;
@ -25,22 +25,22 @@ uint16_t get_gatt_client_handle(void){
void mock_simulate_command_complete(const hci_cmd_t *cmd){
uint8_t packet[] = {HCI_EVENT_COMMAND_COMPLETE, 4, 1, cmd->opcode & 0xff, cmd->opcode >> 8, 0};
registered_l2cap_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
registered_l2cap_packet_handler(HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
}
void mock_simulate_hci_state_working(void){
uint8_t packet[3] = {BTSTACK_EVENT_STATE, 0, HCI_STATE_WORKING};
registered_l2cap_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, 3);
registered_l2cap_packet_handler(HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, 3);
}
void mock_simulate_connected(void){
uint8_t packet[] = {0x3E, 0x13, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x9B, 0x77, 0xD1, 0xF7, 0xB1, 0x34, 0x50, 0x00, 0x00, 0x00, 0xD0, 0x07, 0x05};
registered_l2cap_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
registered_l2cap_packet_handler(HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
}
void mock_simulate_scan_response(void){
uint8_t packet[] = {0xE2, 0x13, 0xE2, 0x01, 0x34, 0xB1, 0xF7, 0xD1, 0x77, 0x9B, 0xCC, 0x09, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
registered_l2cap_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
registered_l2cap_packet_handler(HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet));
}
le_command_status_t le_central_start_scan(void){
@ -89,7 +89,7 @@ void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint1
att_packet_handler = packet_handler;
}
void l2cap_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){
void l2cap_register_packet_handler(void (*handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){
registered_l2cap_packet_handler = handler;
}

View File

@ -799,16 +799,9 @@ int btstack_main(int argc, const char * argv[]){
sdp_init();
uint16_t network_packet_types[] = { NETWORK_TYPE_IPv4, NETWORK_TYPE_ARP, 0}; // 0 as end of list
#ifdef EMBEDDED
service_record_item_t * service_record_item = (service_record_item_t *) panu_sdp_record;
pan_create_panu_service((uint8_t*) &service_record_item->service_record, network_packet_types, NULL, NULL, BNEP_SECURITY_NONE);
printf("SDP service buffer size: %u\n", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
sdp_register_service_internal(service_record_item);
#else
pan_create_panu_service(panu_sdp_record, network_packet_types, NULL, NULL, BNEP_SECURITY_NONE);
printf("SDP service record size: %u\n", de_get_len((uint8_t*) panu_sdp_record));
sdp_register_service_internal((uint8_t*)panu_sdp_record);
#endif
sdp_register_service((uint8_t*)panu_sdp_record);
/* Turn on the device */
hci_power_control(HCI_POWER_ON);

View File

@ -781,12 +781,12 @@ int btstack_main(int argc, const char * argv[]){
sdp_create_spp_service((uint8_t*) spp_service_buffer, RFCOMM_SERVER_CHANNEL, "SPP Counter");
de_dump_data_element((uint8_t*) spp_service_buffer);
printf("SDP service record size: %u\n\r", de_get_len((uint8_t*)spp_service_buffer));
sdp_register_service_internal((uint8_t*)spp_service_buffer);
sdp_register_service((uint8_t*)spp_service_buffer);
memset(dummy_service_buffer, 0, sizeof(dummy_service_buffer));
sdp_create_dummy_service((uint8_t*)dummy_service_buffer, "UUID128 Test");
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_internal((uint8_t*)dummy_service_buffer);
sdp_register_service((uint8_t*)dummy_service_buffer);
sdp_query_rfcomm_register_callback(handle_query_rfcomm_event, NULL);

View File

@ -202,12 +202,11 @@ int btstack_main(int argc, const char * argv[]){
hfp_ag_register_packet_handler(packet_handler);
sdp_init();
// init SDP, create record for SPP and register with SDP
sdp_init();
memset((uint8_t *)hfp_service_buffer, 0, sizeof(hfp_service_buffer));
hfp_ag_create_sdp_record((uint8_t *)hfp_service_buffer, rfcomm_channel_nr, hfp_ag_service_name, 0, 0);
sdp_register_service_internal((uint8_t *)hfp_service_buffer);
sdp_register_service((uint8_t *)hfp_service_buffer);
// turn on!
hci_power_control(HCI_POWER_ON);

View File

@ -236,11 +236,11 @@ int btstack_main(int argc, const char * argv[]){
hfp_hf_register_packet_handler(packet_handler);
sdp_init();
// init SDP, create record for SPP and register with SDP
sdp_init();
memset((uint8_t *)hfp_service_buffer, 0, sizeof(hfp_service_buffer));
hfp_hf_create_sdp_record((uint8_t *)hfp_service_buffer, rfcomm_channel_nr, hfp_hf_service_name, 0);
sdp_register_service_internal((uint8_t *)hfp_service_buffer);
sdp_register_service((uint8_t *)hfp_service_buffer);
// turn on!
hci_power_control(HCI_POWER_ON);

View File

@ -184,15 +184,15 @@ static void packet_handler(uint8_t * event, uint16_t event_size){
int btstack_main(int argc, const char * argv[]);
int btstack_main(int argc, const char * argv[]){
// init SDP, create record for SPP and register with SDP
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
hsp_ag_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_ag_service_name);
hsp_ag_init(rfcomm_channel_nr);
hsp_ag_register_packet_handler(packet_handler);
// init SDP, create record for SPP and register with SDP
sdp_init();
sdp_register_service_internal((uint8_t *)hsp_service_buffer);
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
hsp_ag_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_ag_service_name);
sdp_register_service((uint8_t *)hsp_service_buffer);
// turn on!
hci_power_control(HCI_POWER_ON);

View File

@ -305,14 +305,13 @@ int btstack_main(int argc, const char * argv[]){
setup_audio();
hci_register_sco_packet_handler(&sco_packet_handler);
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0);
hsp_hs_init(rfcomm_channel_nr);
hsp_hs_register_packet_handler(packet_handler);
sdp_init();
sdp_register_service_internal((uint8_t *)hsp_service_buffer);
memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0);
sdp_register_service((uint8_t *)hsp_service_buffer);
hci_discoverable_control(1);
hci_set_class_of_device(0x200418);