mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 04:20:20 +00:00
sdp: added service search and service attribute search queries
This commit is contained in:
parent
46a10724a8
commit
bace66242a
@ -51,6 +51,9 @@ sdp_general_query: ${CORE_OBJ} ${COMMON_OBJ} sdp_general_query.c
|
||||
spp_counter: ${CORE_OBJ} ${COMMON_OBJ} spp_counter.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
spp_counter_ssp: ${CORE_OBJ} ${COMMON_OBJ} spp_counter_ssp.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
# compile .ble description
|
||||
profile.h: profile.gatt
|
||||
python ${BTSTACK_ROOT}/ble/compile-gatt.py $< $@
|
||||
|
@ -58,7 +58,7 @@ static void btstack_setup(){
|
||||
btstack_memory_init();
|
||||
run_loop_init(RUN_LOOP_POSIX);
|
||||
|
||||
// hci_dump_open("/tmp/hci_dump_sdp_client.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
hci_dump_open("/tmp/hci_dump_sdp_general_query.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
|
||||
hci_transport_t * transport = hci_transport_usb_instance();
|
||||
hci_uart_config_t * config = NULL;
|
||||
|
@ -52,7 +52,7 @@ static void btstack_setup(){
|
||||
btstack_memory_init();
|
||||
run_loop_init(RUN_LOOP_POSIX);
|
||||
|
||||
// hci_dump_open("/tmp/hci_dump_sdp_client.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
hci_dump_open("/tmp/hci_dump_sdp_rfcomm_query.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
|
||||
hci_transport_t * transport = hci_transport_usb_instance();
|
||||
hci_uart_config_t * config = NULL;
|
||||
|
@ -209,6 +209,9 @@ extern "C" {
|
||||
|
||||
// data: event(8), len(8), record nr(16), attribute id(16), attribute value(var)
|
||||
#define SDP_QUERY_ATTRIBUTE_VALUE 0x93
|
||||
|
||||
// data: event(8), total nr(16), current nr(16), service record handle(32)
|
||||
#define SDP_QUERY_SERVICE_RECORD_HANDLE 0x94
|
||||
//#define SDP_PARSER_ATTRIBUTE_VALUE 0x94
|
||||
//#define SDP_PARSER_COMPLETE 0x95
|
||||
|
||||
|
@ -45,6 +45,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SDP_Invalid = 0,
|
||||
SDP_ErrorResponse = 1,
|
||||
SDP_ServiceSearchRequest,
|
||||
SDP_ServiceSearchResponse,
|
||||
|
263
src/sdp_client.c
263
src/sdp_client.c
@ -55,11 +55,15 @@ typedef enum {
|
||||
|
||||
void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
static uint16_t setup_sdp_request(uint8_t * data);
|
||||
static uint16_t setup_ServiceSearchRequest(uint8_t * data);
|
||||
static uint16_t setup_ServiceAttributeRequest(uint8_t * data);
|
||||
static uint16_t setup_ServiceSearchAttributeRequest(uint8_t * data);
|
||||
|
||||
|
||||
// SDP Client Query
|
||||
static uint16_t mtu;
|
||||
static uint16_t sdp_cid = 0x40;
|
||||
static uint32_t serviceRecordHandle;
|
||||
static uint8_t * serviceSearchPattern;
|
||||
static uint8_t * attributeIDList;
|
||||
static uint16_t transactionID = 0;
|
||||
@ -67,6 +71,7 @@ static uint8_t continuationState[16];
|
||||
static uint8_t continuationStateLen;
|
||||
|
||||
static sdp_client_state_t sdp_client_state;
|
||||
static SDP_PDU_ID_t PDU_ID = SDP_Invalid;
|
||||
|
||||
void sdp_client_handle_done(uint8_t status){
|
||||
if (status == 0){
|
||||
@ -75,7 +80,11 @@ void sdp_client_handle_done(uint8_t status){
|
||||
sdp_parser_handle_done(status);
|
||||
}
|
||||
|
||||
// TODO: inline if not needed
|
||||
void parse_ServiceRecordHandleList(uint8_t* packet, uint16_t total_count, uint16_t current_count){
|
||||
sdp_parser_handle_service_search(packet, total_count, current_count);
|
||||
}
|
||||
|
||||
// TODO: inline if not needed (des(des))
|
||||
void parse_AttributeLists(uint8_t* packet, uint16_t length){
|
||||
sdp_parser_handle_chunk(packet, length);
|
||||
}
|
||||
@ -94,25 +103,58 @@ 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. */
|
||||
|
||||
void sdp_client_query(bd_addr_t remote, uint8_t * des_serviceSearchPattern, uint8_t * des_attributeIDList){
|
||||
|
||||
serviceSearchPattern = des_serviceSearchPattern;
|
||||
attributeIDList = des_attributeIDList;
|
||||
continuationStateLen = 0;
|
||||
|
||||
PDU_ID = SDP_ServiceSearchAttributeResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
l2cap_create_channel_internal(NULL, sdp_packet_handler, remote, PSM_SDP, l2cap_max_mtu());
|
||||
}
|
||||
|
||||
void sdp_client_service_attribute_search(bd_addr_t remote, uint32_t search_serviceRecordHandle, uint8_t * des_attributeIDList){
|
||||
serviceRecordHandle = search_serviceRecordHandle;
|
||||
attributeIDList = des_attributeIDList;
|
||||
continuationStateLen = 0;
|
||||
PDU_ID = SDP_ServiceAttributeResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
l2cap_create_channel_internal(NULL, sdp_packet_handler, remote, PSM_SDP, l2cap_max_mtu());
|
||||
}
|
||||
|
||||
void sdp_client_service_search(bd_addr_t remote, uint8_t * des_serviceSearchPattern){
|
||||
serviceSearchPattern = des_serviceSearchPattern;
|
||||
continuationStateLen = 0;
|
||||
PDU_ID = SDP_ServiceSearchResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
l2cap_create_channel_internal(NULL, sdp_packet_handler, remote, PSM_SDP, l2cap_max_mtu());
|
||||
}
|
||||
|
||||
|
||||
void tryToSend(uint16_t channel){
|
||||
|
||||
static void tryToSend(uint16_t channel){
|
||||
|
||||
if (sdp_client_state != W2_SEND) return;
|
||||
|
||||
if (!l2cap_can_send_packet_now(channel)) return;
|
||||
|
||||
uint8_t * data = l2cap_get_outgoing_buffer();
|
||||
uint16_t request_len = setup_sdp_request(data);
|
||||
uint16_t request_len = 0;
|
||||
|
||||
switch (PDU_ID){
|
||||
case SDP_ServiceSearchResponse:
|
||||
request_len = setup_ServiceSearchRequest(data);
|
||||
break;
|
||||
case SDP_ServiceAttributeResponse:
|
||||
request_len = setup_ServiceAttributeRequest(data);
|
||||
break;
|
||||
case SDP_ServiceSearchAttributeResponse:
|
||||
request_len = setup_ServiceSearchAttributeRequest(data);
|
||||
break;
|
||||
default:
|
||||
log_info("SDP Client tryToSend :: PDU ID invalid. %u", PDU_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("tryToSend channel %x, size %u\n", channel, request_len);
|
||||
|
||||
@ -121,6 +163,7 @@ void tryToSend(uint16_t channel){
|
||||
case 0:
|
||||
// packet is sent prepare next one
|
||||
printf("l2cap_send_internal() -> OK\n\r");
|
||||
PDU_ID = SDP_Invalid;
|
||||
sdp_client_state = W4_RESPONSE;
|
||||
break;
|
||||
case BTSTACK_ACL_BUFFERS_FULL:
|
||||
@ -132,7 +175,76 @@ void tryToSend(uint16_t channel){
|
||||
}
|
||||
}
|
||||
|
||||
void parse_ServiceSearchAttributeResponse(uint8_t* packet){
|
||||
static void parse_ServiceSearchResponse(uint8_t* packet){
|
||||
uint16_t offset = 3;
|
||||
uint16_t parameterLength = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
|
||||
uint16_t totalServiceRecordCount = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
|
||||
uint16_t currentServiceRecordCount = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
|
||||
if (currentServiceRecordCount > totalServiceRecordCount){
|
||||
log_error("CurrentServiceRecordCount is larger then TotalServiceRecordCount.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
parse_ServiceRecordHandleList(packet+offset, totalServiceRecordCount, currentServiceRecordCount);
|
||||
offset+=(currentServiceRecordCount * 4);
|
||||
|
||||
|
||||
continuationStateLen = packet[offset];
|
||||
offset++;
|
||||
|
||||
if (continuationStateLen > 16){
|
||||
log_error("Error parsing ServiceSearchResponse: Number of bytes in continuation state exceedes 16.\n");
|
||||
return;
|
||||
}
|
||||
memcpy(continuationState, packet+offset, continuationStateLen);
|
||||
offset+=continuationStateLen;
|
||||
|
||||
if (parameterLength != offset - 5){
|
||||
log_error("Error parsing ServiceSearchResponse: wrong size of parameters, number of expected bytes%u, actual number %u.\n", parameterLength, offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_ServiceAttributeResponse(uint8_t* packet){
|
||||
uint16_t offset = 3;
|
||||
uint16_t parameterLength = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
|
||||
// AttributeListByteCount <= mtu
|
||||
uint16_t attributeListByteCount = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
|
||||
if (attributeListByteCount > mtu){
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// AttributeLists
|
||||
parse_AttributeLists(packet+offset, attributeListByteCount);
|
||||
offset+=attributeListByteCount;
|
||||
|
||||
continuationStateLen = packet[offset];
|
||||
offset++;
|
||||
|
||||
if (continuationStateLen > 16){
|
||||
log_error("Error parsing ServiceAttributeResponse: Number of bytes in continuation state exceedes 16.\n");
|
||||
return;
|
||||
}
|
||||
memcpy(continuationState, packet+offset, continuationStateLen);
|
||||
offset+=continuationStateLen;
|
||||
|
||||
if (parameterLength != offset - 5){
|
||||
log_error("Error parsing ServiceAttributeResponse: wrong size of parameters, number of expected bytes%u, actual number %u.\n", parameterLength, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void parse_ServiceSearchAttributeResponse(uint8_t* packet){
|
||||
uint16_t offset = 3;
|
||||
uint16_t parameterLength = READ_NET_16(packet,offset);
|
||||
offset+=2;
|
||||
@ -141,7 +253,7 @@ void parse_ServiceSearchAttributeResponse(uint8_t* packet){
|
||||
offset+=2;
|
||||
|
||||
if (attributeListByteCount > mtu){
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then MTU.\n");
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -164,34 +276,57 @@ void parse_ServiceSearchAttributeResponse(uint8_t* packet){
|
||||
}
|
||||
}
|
||||
|
||||
void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
||||
uint16_t handle;
|
||||
|
||||
printf("l2cap_packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
|
||||
printf("SDP Client :: l2cap_packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
|
||||
|
||||
if (packet_type == L2CAP_DATA_PACKET){
|
||||
printf("SDP Client :: L2CAP_DATA_PACKET received\n");
|
||||
|
||||
uint16_t responseTransactionID = READ_NET_16(packet,1);
|
||||
if ( responseTransactionID != transactionID){
|
||||
printf("Missmatching transaction ID, expected %u, found %u.\n", transactionID, responseTransactionID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet[0] == SDP_ServiceSearchAttributeResponse){
|
||||
parse_ServiceSearchAttributeResponse(packet);
|
||||
|
||||
// continuation set or DONE?
|
||||
if (continuationStateLen == 0){
|
||||
printf("DONE! All clients already notified.\n");
|
||||
sdp_client_handle_done(0);
|
||||
sdp_client_state = INIT;
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare next request and send
|
||||
sdp_client_state = W2_SEND;
|
||||
tryToSend(sdp_cid);
|
||||
if (packet[0] != SDP_ServiceSearchAttributeResponse
|
||||
&& packet[0] != SDP_ServiceSearchResponse
|
||||
&& packet[0] != SDP_ServiceAttributeResponse){
|
||||
printf("Not a valid PDU ID, expected %u, %u or %u, found %u.\n", SDP_ServiceSearchResponse,
|
||||
SDP_ServiceAttributeResponse, SDP_ServiceSearchAttributeResponse, packet[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
PDU_ID = packet[0];
|
||||
log_info("SDP Client :: PDU ID. %u ,%u", PDU_ID, packet[0]);
|
||||
switch (PDU_ID){
|
||||
case SDP_ServiceSearchResponse:
|
||||
parse_ServiceSearchResponse(packet);
|
||||
break;
|
||||
case SDP_ServiceAttributeResponse:
|
||||
parse_ServiceAttributeResponse(packet);
|
||||
break;
|
||||
case SDP_ServiceSearchAttributeResponse:
|
||||
parse_ServiceSearchAttributeResponse(packet);
|
||||
break;
|
||||
default:
|
||||
log_error("SDP Client :: PDU ID invalid. %u ,%u", PDU_ID, packet[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// continuation set or DONE?
|
||||
if (continuationStateLen == 0){
|
||||
printf("DONE! All clients already notified.\n");
|
||||
sdp_client_handle_done(0);
|
||||
sdp_client_state = INIT;
|
||||
return;
|
||||
}
|
||||
// prepare next request and send
|
||||
sdp_client_state = W2_SEND;
|
||||
tryToSend(sdp_cid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -230,7 +365,82 @@ void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet,
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t setup_sdp_request(uint8_t * data){
|
||||
static uint16_t setup_ServiceSearchRequest(uint8_t * data){
|
||||
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
// uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
|
||||
data[offset++] = SDP_ServiceSearchRequest;
|
||||
// uint16_t transactionID
|
||||
net_store_16(data, offset, transactionID);
|
||||
offset += 2;
|
||||
|
||||
// param legnth
|
||||
offset += 2;
|
||||
|
||||
// parameters:
|
||||
// ServiceSearchPattern - DES (min 1 UUID, max 12)
|
||||
uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern);
|
||||
memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen);
|
||||
offset += serviceSearchPatternLen;
|
||||
|
||||
// MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
|
||||
net_store_16(data, offset, mtu);
|
||||
offset += 2;
|
||||
|
||||
// ContinuationState - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = continuationStateLen;
|
||||
// - N-bytes previous response from server
|
||||
memcpy(data + offset, continuationState, continuationStateLen);
|
||||
offset += continuationStateLen;
|
||||
|
||||
// uint16_t paramLength
|
||||
net_store_16(data, 3, offset - 5);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t setup_ServiceAttributeRequest(uint8_t * data){
|
||||
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
// uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
|
||||
data[offset++] = SDP_ServiceAttributeRequest;
|
||||
// uint16_t transactionID
|
||||
net_store_16(data, offset, transactionID);
|
||||
offset += 2;
|
||||
|
||||
// param legnth
|
||||
offset += 2;
|
||||
|
||||
// parameters:
|
||||
// ServiceRecordHandle
|
||||
net_store_32(data, offset, serviceRecordHandle);
|
||||
offset += 4;
|
||||
|
||||
// MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
|
||||
net_store_16(data, offset, mtu);
|
||||
offset += 2;
|
||||
|
||||
// AttibuteIDList
|
||||
uint16_t attributeIDListLen = de_get_len(attributeIDList);
|
||||
memcpy(data + offset, attributeIDList, attributeIDListLen);
|
||||
offset += attributeIDListLen;
|
||||
|
||||
// ContinuationState - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = continuationStateLen;
|
||||
// - N-bytes previous response from server
|
||||
memcpy(data + offset, continuationState, continuationStateLen);
|
||||
offset += continuationStateLen;
|
||||
|
||||
// uint16_t paramLength
|
||||
net_store_16(data, 3, offset - 5);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static uint16_t setup_ServiceSearchAttributeRequest(uint8_t * data){
|
||||
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
@ -271,4 +481,3 @@ static uint16_t setup_sdp_request(uint8_t * data){
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -53,6 +53,8 @@ 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. */
|
||||
|
||||
void sdp_client_query(bd_addr_t remote, uint8_t * des_serviceSearchPattern, uint8_t * des_attributeIDList);
|
||||
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);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
|
@ -52,14 +52,14 @@ typedef enum {
|
||||
|
||||
static state_t state = GET_LIST_LENGTH;
|
||||
static uint16_t attribute_id = 0;
|
||||
static uint32_t attribute_bytes_received = 0;
|
||||
static uint32_t attribute_bytes_delivered = 0;
|
||||
static int list_offset = 0;
|
||||
static int list_size;
|
||||
static int record_offset = 0;
|
||||
static int record_size;
|
||||
static int attribute_value_size;
|
||||
|
||||
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 uint32_t record_handle;
|
||||
static int record_counter = 0;
|
||||
|
||||
static void (*sdp_query_rfcomm_callback)(sdp_query_event_t * event);
|
||||
@ -117,7 +117,11 @@ void parse(uint8_t eventByte){
|
||||
list_offset++;
|
||||
record_offset++;
|
||||
|
||||
// printf("BYTE_RECEIVED %02x\n", eventByte);
|
||||
static int b = 0;
|
||||
printf("0x%02x, ", eventByte);
|
||||
if (++b==16) { printf("\n"); b = 0; }
|
||||
|
||||
// printf(" parse BYTE_RECEIVED %02x\n", eventByte);
|
||||
switch(state){
|
||||
case GET_LIST_LENGTH:
|
||||
if (!de_state_size(eventByte, &de_header_state)) break;
|
||||
@ -127,6 +131,8 @@ void parse(uint8_t eventByte){
|
||||
|
||||
record_counter = 0;
|
||||
state = GET_RECORD_LENGTH;
|
||||
|
||||
printf("\n -- new record starts --\n"); b = 0;
|
||||
break;
|
||||
|
||||
case GET_RECORD_LENGTH:
|
||||
@ -203,17 +209,19 @@ void parse(uint8_t eventByte){
|
||||
}
|
||||
record_offset = 0;
|
||||
// printf("parser: List offset %u, list size %u\n", list_offset, list_size);
|
||||
if (list_offset != list_size){
|
||||
|
||||
if (list_size > 0 && list_offset != list_size){
|
||||
record_counter++;
|
||||
state = GET_RECORD_LENGTH;
|
||||
// printf("parser: END_OF_RECORD\n\n");
|
||||
printf("\n -- new record starts --\n %u %u %u", list_offset, list_size, record_offset); b = 0;
|
||||
break;
|
||||
}
|
||||
list_offset = 0;
|
||||
de_state_init(&de_header_state);
|
||||
state = GET_LIST_LENGTH;
|
||||
record_counter = 0;
|
||||
// printf("parser: END_OF_RECORD & DONE\n\n\n");
|
||||
printf("parser: END_OF_RECORD & DONE\n\n\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -229,6 +237,15 @@ void sdp_parser_init(void){
|
||||
record_counter = 0;
|
||||
}
|
||||
|
||||
void sdp_parser_init_service_attribute_search(void){
|
||||
// init
|
||||
de_state_init(&de_header_state);
|
||||
state = GET_RECORD_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<size;i++){
|
||||
@ -236,6 +253,27 @@ void sdp_parser_handle_chunk(uint8_t * data, uint16_t size){
|
||||
}
|
||||
}
|
||||
|
||||
void sdp_parser_init_service_search(void){
|
||||
record_offset = 0;
|
||||
}
|
||||
|
||||
void sdp_parser_handle_service_search(uint8_t * data, uint16_t total_count, uint16_t record_handle_count){
|
||||
int i;
|
||||
for (i=0;i<record_handle_count;i++){
|
||||
record_handle = READ_NET_32(data, i*4);
|
||||
record_counter++;
|
||||
printf("handle[%d/%d] = %d\n", i, record_handle_count, record_handle);
|
||||
sdp_query_service_record_handle_event_t service_record_handle_event = {
|
||||
SDP_QUERY_SERVICE_RECORD_HANDLE,
|
||||
total_count,
|
||||
record_counter,
|
||||
record_handle
|
||||
};
|
||||
(*sdp_query_rfcomm_callback)((sdp_query_event_t*)&service_record_handle_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sdp_parser_handle_done(uint8_t status){
|
||||
sdp_query_complete_event_t complete_event = {
|
||||
SDP_QUERY_COMPLETE,
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <btstack/sdp_util.h>
|
||||
#include <btstack/utils.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
@ -86,8 +87,21 @@ typedef struct sdp_query_attribute_value_event {
|
||||
} sdp_query_attribute_value_event_t;
|
||||
|
||||
|
||||
typedef struct sdp_query_service_record_handle_event {
|
||||
uint8_t type;
|
||||
uint16_t total_count;
|
||||
uint16_t current_count;
|
||||
uint32_t record_handle;
|
||||
} sdp_query_service_record_handle_event_t;
|
||||
|
||||
|
||||
void sdp_parser_init(void);
|
||||
void sdp_parser_init_service_attribute_search(void);
|
||||
void sdp_parser_handle_chunk(uint8_t * data, uint16_t size);
|
||||
|
||||
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);
|
||||
|
||||
void sdp_parser_handle_done(uint8_t status);
|
||||
|
||||
// Registers a callback to receive attribute value data and parse complete event.
|
||||
|
@ -142,7 +142,7 @@ static void test_attribute_value_event(sdp_query_attribute_value_event_t* event)
|
||||
}
|
||||
|
||||
|
||||
static void handle_general_sdp_parser_event(sdp_query_event_t * event){
|
||||
static void handle_sdp_parser_event(sdp_query_event_t * event){
|
||||
|
||||
sdp_query_attribute_value_event_t * ve;
|
||||
sdp_query_complete_event_t * ce;
|
||||
@ -176,12 +176,12 @@ TEST_GROUP(SDPClient){
|
||||
attribute_value = (uint8_t*) malloc(attribute_value_buffer_size);
|
||||
record_id = -1;
|
||||
sdp_parser_init();
|
||||
sdp_parser_register_callback(handle_general_sdp_parser_event);
|
||||
sdp_parser_register_callback(handle_sdp_parser_event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(SDPClient, QueryRFCOMMWithMacOSXData){
|
||||
TEST(SDPClient, QueryWithMacOSXData){
|
||||
uint16_t expected_last_attribute_id = 0xffff;
|
||||
uint16_t expected_last_record_id = 8;
|
||||
uint8_t expected_attribute_value[3] = {0x09, 0x00, 0x05};
|
||||
|
Loading…
x
Reference in New Issue
Block a user