mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-31 00:32:52 +00:00
sdp: prefix globals, update deinit function
This commit is contained in:
parent
41fcd84f30
commit
f20b4214ea
@ -68,6 +68,7 @@ typedef enum {
|
||||
INIT, W4_CONNECT, W2_SEND, W4_RESPONSE, QUERY_COMPLETE
|
||||
} sdp_client_state_t;
|
||||
|
||||
static uint8_t sdp_client_des_attribute_id_list[] = {0x35, 0x05, 0x0A, 0x00, 0x00, 0xff, 0xff}; // Attribute: 0x0000 - 0xffff
|
||||
|
||||
// Prototypes SDP Parser
|
||||
void sdp_parser_init(btstack_packet_handler_t callback);
|
||||
@ -88,41 +89,39 @@ static void sdp_client_parse_service_search_response(uint8_t* packet, uint16
|
||||
static void sdp_client_parse_service_attribute_response(uint8_t* packet, uint16_t size);
|
||||
#endif
|
||||
|
||||
static uint8_t des_attributeIDList[] = { 0x35, 0x05, 0x0A, 0x00, 0x00, 0xff, 0xff}; // Attribute: 0x0000 - 0xffff
|
||||
|
||||
// State DES Parser
|
||||
static de_state_t de_header_state;
|
||||
static de_state_t des_parser_de_header_state;
|
||||
|
||||
// State SDP Parser
|
||||
static sdp_parser_state_t state;
|
||||
static uint16_t attribute_id = 0;
|
||||
static uint16_t attribute_bytes_received;
|
||||
static uint16_t attribute_bytes_delivered;
|
||||
static uint16_t list_offset;
|
||||
static uint16_t list_size;
|
||||
static uint16_t record_offset;
|
||||
static uint16_t record_size;
|
||||
static uint16_t attribute_value_size;
|
||||
static int record_counter;
|
||||
static sdp_parser_state_t sdp_parser_state;
|
||||
static uint16_t sdp_parser_attribute_id = 0;
|
||||
static uint16_t sdp_parser_attribute_bytes_received;
|
||||
static uint16_t sdp_parser_attribute_bytes_delivered;
|
||||
static uint16_t sdp_parser_list_offset;
|
||||
static uint16_t sdp_parser_list_size;
|
||||
static uint16_t sdp_parser_record_offset;
|
||||
static uint16_t sdp_parser_record_size;
|
||||
static uint16_t sdp_parser_attribute_value_size;
|
||||
static int sdp_parser_record_counter;
|
||||
static btstack_packet_handler_t sdp_parser_callback;
|
||||
|
||||
// State SDP Client
|
||||
static uint16_t mtu;
|
||||
static uint16_t sdp_cid = 0x40;
|
||||
static const uint8_t * service_search_pattern;
|
||||
static const uint8_t * attribute_id_list;
|
||||
static uint16_t transactionID;
|
||||
static uint8_t continuationState[16];
|
||||
static uint8_t continuationStateLen;
|
||||
static uint16_t sdp_client_mtu;
|
||||
static uint16_t sdp_client_sdp_cid = 0x40;
|
||||
static const uint8_t * sdp_client_service_search_pattern;
|
||||
static const uint8_t * sdp_client_attribute_id_list;
|
||||
static uint16_t sdp_client_transaction_id;
|
||||
static uint8_t sdp_client_continuation_state[16];
|
||||
static uint8_t sdp_client_continuation_state_len;
|
||||
static sdp_client_state_t sdp_client_state = INIT;
|
||||
static SDP_PDU_ID_t PDU_ID = SDP_Invalid;
|
||||
static sdp_pdu_id_t sdp_client_pdu_id = SDP_Invalid;
|
||||
|
||||
// Query registration
|
||||
static btstack_linked_list_t sdp_client_query_requests;
|
||||
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
static uint32_t serviceRecordHandle;
|
||||
static uint32_t record_handle;
|
||||
static uint32_t sdp_client_service_record_handle;
|
||||
static uint32_t sdp_client_record_handle;
|
||||
#endif
|
||||
|
||||
// DES Parser
|
||||
@ -166,97 +165,97 @@ 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);
|
||||
little_endian_store_16(event, 2, sdp_parser_record_counter);
|
||||
little_endian_store_16(event, 4, sdp_parser_attribute_id);
|
||||
little_endian_store_16(event, 6, sdp_parser_attribute_value_size);
|
||||
little_endian_store_16(event, 8, sdp_parser_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++;
|
||||
sdp_parser_list_offset++;
|
||||
sdp_parser_record_offset++;
|
||||
|
||||
// log_info(" parse BYTE_RECEIVED %02x", eventByte);
|
||||
switch(state){
|
||||
switch(sdp_parser_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;
|
||||
if (!de_state_size(eventByte, &des_parser_de_header_state)) break;
|
||||
sdp_parser_list_offset = des_parser_de_header_state.de_offset;
|
||||
sdp_parser_list_size = des_parser_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;
|
||||
sdp_parser_record_counter = 0;
|
||||
sdp_parser_state = GET_RECORD_LENGTH;
|
||||
break;
|
||||
|
||||
case GET_RECORD_LENGTH:
|
||||
// check size
|
||||
if (!de_state_size(eventByte, &de_header_state)) break;
|
||||
if (!de_state_size(eventByte, &des_parser_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;
|
||||
sdp_parser_record_offset = des_parser_de_header_state.de_offset;
|
||||
sdp_parser_record_size = des_parser_de_header_state.de_size;
|
||||
sdp_parser_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_debug("ID data is stored in %d bytes.", (int) de_header_state.de_size);
|
||||
state = GET_ATTRIBUTE_ID;
|
||||
if (!de_state_size(eventByte, &des_parser_de_header_state)) break;
|
||||
sdp_parser_attribute_id = 0;
|
||||
log_debug("ID data is stored in %d bytes.", (int) des_parser_de_header_state.de_size);
|
||||
sdp_parser_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_debug("parser: Attribute ID: %04x.", attribute_id);
|
||||
sdp_parser_attribute_id = (sdp_parser_attribute_id << 8) | eventByte;
|
||||
des_parser_de_header_state.de_size--;
|
||||
if (des_parser_de_header_state.de_size > 0) break;
|
||||
log_debug("parser: Attribute ID: %04x.", sdp_parser_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);
|
||||
sdp_parser_state = GET_ATTRIBUTE_VALUE_LENGTH;
|
||||
sdp_parser_attribute_bytes_received = 0;
|
||||
sdp_parser_attribute_bytes_delivered = 0;
|
||||
sdp_parser_attribute_value_size = 0;
|
||||
de_state_init(&des_parser_de_header_state);
|
||||
break;
|
||||
|
||||
case GET_ATTRIBUTE_VALUE_LENGTH:
|
||||
attribute_bytes_received++;
|
||||
sdp_parser_attribute_bytes_received++;
|
||||
sdp_parser_emit_value_byte(eventByte);
|
||||
attribute_bytes_delivered++;
|
||||
if (!de_state_size(eventByte, &de_header_state)) break;
|
||||
sdp_parser_attribute_bytes_delivered++;
|
||||
if (!de_state_size(eventByte, &des_parser_de_header_state)) break;
|
||||
|
||||
attribute_value_size = de_header_state.de_size + attribute_bytes_received;
|
||||
sdp_parser_attribute_value_size = des_parser_de_header_state.de_size + sdp_parser_attribute_bytes_received;
|
||||
|
||||
state = GET_ATTRIBUTE_VALUE;
|
||||
sdp_parser_state = GET_ATTRIBUTE_VALUE;
|
||||
break;
|
||||
|
||||
case GET_ATTRIBUTE_VALUE:
|
||||
attribute_bytes_received++;
|
||||
sdp_parser_attribute_bytes_received++;
|
||||
sdp_parser_emit_value_byte(eventByte);
|
||||
attribute_bytes_delivered++;
|
||||
sdp_parser_attribute_bytes_delivered++;
|
||||
// log_debug("paser: attribute_bytes_received %u, attribute_value_size %u", attribute_bytes_received, attribute_value_size);
|
||||
|
||||
if (attribute_bytes_received < attribute_value_size) break;
|
||||
if (sdp_parser_attribute_bytes_received < sdp_parser_attribute_value_size) break;
|
||||
// log_debug("parser: Record offset %u, record size %u", record_offset, record_size);
|
||||
if (record_offset != record_size){
|
||||
state = GET_ATTRIBUTE_ID_HEADER_LENGTH;
|
||||
if (sdp_parser_record_offset != sdp_parser_record_size){
|
||||
sdp_parser_state = GET_ATTRIBUTE_ID_HEADER_LENGTH;
|
||||
// log_debug("Get next attribute");
|
||||
break;
|
||||
}
|
||||
record_offset = 0;
|
||||
}
|
||||
sdp_parser_record_offset = 0;
|
||||
// log_debug("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;
|
||||
if ((sdp_parser_list_size > 0) && (sdp_parser_list_offset != sdp_parser_list_size)){
|
||||
sdp_parser_record_counter++;
|
||||
sdp_parser_state = GET_RECORD_LENGTH;
|
||||
log_debug("parser: END_OF_RECORD");
|
||||
break;
|
||||
}
|
||||
list_offset = 0;
|
||||
de_state_init(&de_header_state);
|
||||
state = GET_LIST_LENGTH;
|
||||
record_counter = 0;
|
||||
sdp_parser_list_offset = 0;
|
||||
de_state_init(&des_parser_de_header_state);
|
||||
sdp_parser_state = GET_LIST_LENGTH;
|
||||
sdp_parser_record_counter = 0;
|
||||
log_debug("parser: END_OF_RECORD & DONE");
|
||||
break;
|
||||
default:
|
||||
@ -267,22 +266,22 @@ static void sdp_parser_process_byte(uint8_t eventByte){
|
||||
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;
|
||||
list_size = 0;
|
||||
record_offset = 0;
|
||||
record_counter = 0;
|
||||
record_size = 0;
|
||||
attribute_id = 0;
|
||||
attribute_bytes_received = 0;
|
||||
attribute_bytes_delivered = 0;
|
||||
de_state_init(&des_parser_de_header_state);
|
||||
sdp_parser_state = GET_LIST_LENGTH;
|
||||
sdp_parser_list_offset = 0;
|
||||
sdp_parser_list_size = 0;
|
||||
sdp_parser_record_offset = 0;
|
||||
sdp_parser_record_counter = 0;
|
||||
sdp_parser_record_size = 0;
|
||||
sdp_parser_attribute_id = 0;
|
||||
sdp_parser_attribute_bytes_received = 0;
|
||||
sdp_parser_attribute_bytes_delivered = 0;
|
||||
}
|
||||
|
||||
static void sdp_parser_deinit(void) {
|
||||
sdp_parser_callback = NULL;
|
||||
attribute_value_size = 0;
|
||||
record_counter = 0;
|
||||
sdp_parser_attribute_value_size = 0;
|
||||
sdp_parser_record_counter = 0;
|
||||
}
|
||||
|
||||
void sdp_client_init(void){
|
||||
@ -291,16 +290,16 @@ void sdp_client_init(void){
|
||||
void sdp_client_deinit(void){
|
||||
sdp_parser_deinit();
|
||||
sdp_client_state = INIT;
|
||||
sdp_cid = 0x40;
|
||||
service_search_pattern = NULL;
|
||||
attribute_id_list = NULL;
|
||||
transactionID = 0;
|
||||
continuationStateLen = 0;
|
||||
sdp_client_sdp_cid = 0x40;
|
||||
sdp_client_service_search_pattern = NULL;
|
||||
sdp_client_attribute_id_list = NULL;
|
||||
sdp_client_transaction_id = 0;
|
||||
sdp_client_continuation_state_len = 0;
|
||||
sdp_client_state = INIT;
|
||||
PDU_ID = SDP_Invalid;
|
||||
sdp_client_pdu_id = SDP_Invalid;
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
serviceRecordHandle = 0;
|
||||
record_handle = 0;
|
||||
sdp_client_service_record_handle = 0;
|
||||
sdp_client_record_handle = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -319,28 +318,28 @@ void sdp_parser_handle_chunk(uint8_t * data, uint16_t size){
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
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;
|
||||
de_state_init(&des_parser_de_header_state);
|
||||
sdp_parser_state = GET_RECORD_LENGTH;
|
||||
sdp_parser_list_offset = 0;
|
||||
sdp_parser_record_offset = 0;
|
||||
sdp_parser_record_counter = 0;
|
||||
}
|
||||
|
||||
void sdp_parser_init_service_search(void){
|
||||
record_offset = 0;
|
||||
sdp_parser_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 = big_endian_read_32(data, i*4);
|
||||
record_counter++;
|
||||
sdp_client_record_handle = big_endian_read_32(data, i * 4);
|
||||
sdp_parser_record_counter++;
|
||||
uint8_t event[10];
|
||||
event[0] = SDP_EVENT_QUERY_SERVICE_RECORD_HANDLE;
|
||||
event[1] = 8;
|
||||
little_endian_store_16(event, 2, total_count);
|
||||
little_endian_store_16(event, 4, record_counter);
|
||||
little_endian_store_32(event, 6, record_handle);
|
||||
little_endian_store_16(event, 4, sdp_parser_record_counter);
|
||||
little_endian_store_32(event, 6, sdp_client_record_handle);
|
||||
(*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
}
|
||||
@ -389,7 +388,7 @@ static void sdp_client_send_request(uint16_t channel){
|
||||
uint8_t * data = l2cap_get_outgoing_buffer();
|
||||
uint16_t request_len = 0;
|
||||
|
||||
switch (PDU_ID){
|
||||
switch (sdp_client_pdu_id){
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
case SDP_ServiceSearchResponse:
|
||||
request_len = sdp_client_setup_service_search_request(data);
|
||||
@ -402,13 +401,13 @@ static void sdp_client_send_request(uint16_t channel){
|
||||
request_len = sdp_client_setup_service_search_attribute_request(data);
|
||||
break;
|
||||
default:
|
||||
log_error("SDP Client sdp_client_send_request :: PDU ID invalid. %u", PDU_ID);
|
||||
log_error("SDP Client sdp_client_send_request :: PDU ID invalid. %u", sdp_client_pdu_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent re-entrance
|
||||
sdp_client_state = W4_RESPONSE;
|
||||
PDU_ID = SDP_Invalid;
|
||||
sdp_client_pdu_id = SDP_Invalid;
|
||||
l2cap_send_prepared(channel, request_len);
|
||||
}
|
||||
|
||||
@ -424,7 +423,7 @@ static void sdp_client_parse_service_search_attribute_response(uint8_t* packet,
|
||||
// AttributeListByteCount <= mtu
|
||||
uint16_t attributeListByteCount = big_endian_read_16(packet,offset);
|
||||
offset+=2;
|
||||
if (attributeListByteCount > mtu){
|
||||
if (attributeListByteCount > sdp_client_mtu){
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
|
||||
return;
|
||||
}
|
||||
@ -436,17 +435,17 @@ static void sdp_client_parse_service_search_attribute_response(uint8_t* packet,
|
||||
|
||||
// continuation state len
|
||||
if ((offset + 1) > size) return;
|
||||
continuationStateLen = packet[offset];
|
||||
sdp_client_continuation_state_len = packet[offset];
|
||||
offset++;
|
||||
if (continuationStateLen > 16){
|
||||
continuationStateLen = 0;
|
||||
if (sdp_client_continuation_state_len > 16){
|
||||
sdp_client_continuation_state_len = 0;
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in continuation state exceedes 16.");
|
||||
return;
|
||||
}
|
||||
|
||||
// continuation state
|
||||
if ((offset + continuationStateLen) > size) return;
|
||||
(void)memcpy(continuationState, packet + offset, continuationStateLen);
|
||||
if ((offset + sdp_client_continuation_state_len) > size) return;
|
||||
(void)memcpy(sdp_client_continuation_state, packet + offset, sdp_client_continuation_state_len);
|
||||
// offset+=continuationStateLen;
|
||||
}
|
||||
|
||||
@ -456,16 +455,16 @@ void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
if (packet_type == L2CAP_DATA_PACKET){
|
||||
if (size < 3) return;
|
||||
uint16_t responseTransactionID = big_endian_read_16(packet,1);
|
||||
if (responseTransactionID != transactionID){
|
||||
log_error("Mismatching transaction ID, expected %u, found %u.", transactionID, responseTransactionID);
|
||||
if (responseTransactionID != sdp_client_transaction_id){
|
||||
log_error("Mismatching transaction ID, expected %u, found %u.", sdp_client_transaction_id, responseTransactionID);
|
||||
return;
|
||||
}
|
||||
|
||||
PDU_ID = (SDP_PDU_ID_t)packet[0];
|
||||
switch (PDU_ID){
|
||||
}
|
||||
|
||||
sdp_client_pdu_id = (sdp_pdu_id_t)packet[0];
|
||||
switch (sdp_client_pdu_id){
|
||||
case SDP_ErrorResponse:
|
||||
log_error("Received error response with code %u, disconnecting", packet[2]);
|
||||
l2cap_disconnect(sdp_cid, 0);
|
||||
l2cap_disconnect(sdp_client_sdp_cid, 0);
|
||||
return;
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
case SDP_ServiceSearchResponse:
|
||||
@ -479,20 +478,20 @@ void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
sdp_client_parse_service_search_attribute_response(packet, size);
|
||||
break;
|
||||
default:
|
||||
log_error("PDU ID %u unexpected/invalid", PDU_ID);
|
||||
log_error("PDU ID %u unexpected/invalid", sdp_client_pdu_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// continuation set or DONE?
|
||||
if (continuationStateLen == 0){
|
||||
if (sdp_client_continuation_state_len == 0){
|
||||
log_debug("SDP Client Query DONE! ");
|
||||
sdp_client_state = QUERY_COMPLETE;
|
||||
l2cap_disconnect(sdp_cid, 0);
|
||||
l2cap_disconnect(sdp_client_sdp_cid, 0);
|
||||
return;
|
||||
}
|
||||
// prepare next request and send
|
||||
sdp_client_state = W2_SEND;
|
||||
l2cap_request_can_send_now_event(sdp_cid);
|
||||
l2cap_request_can_send_now_event(sdp_client_sdp_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -507,22 +506,22 @@ void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
sdp_parser_handle_done(packet[2]);
|
||||
break;
|
||||
}
|
||||
sdp_cid = channel;
|
||||
mtu = little_endian_read_16(packet, 17);
|
||||
sdp_client_sdp_cid = channel;
|
||||
sdp_client_mtu = little_endian_read_16(packet, 17);
|
||||
// handle = little_endian_read_16(packet, 9);
|
||||
log_debug("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu);
|
||||
log_debug("SDP Client Connected, cid %x, mtu %u.", sdp_client_sdp_cid, sdp_client_mtu);
|
||||
|
||||
sdp_client_state = W2_SEND;
|
||||
l2cap_request_can_send_now_event(sdp_cid);
|
||||
l2cap_request_can_send_now_event(sdp_client_sdp_cid);
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CAN_SEND_NOW:
|
||||
if(l2cap_event_can_send_now_get_local_cid(packet) == sdp_cid){
|
||||
sdp_client_send_request(sdp_cid);
|
||||
if(l2cap_event_can_send_now_get_local_cid(packet) == sdp_client_sdp_cid){
|
||||
sdp_client_send_request(sdp_client_sdp_cid);
|
||||
}
|
||||
break;
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED: {
|
||||
if (sdp_cid != little_endian_read_16(packet, 2)) {
|
||||
if (sdp_client_sdp_cid != little_endian_read_16(packet, 2)) {
|
||||
// log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", little_endian_read_16(packet, 2),sdp_cid);
|
||||
break;
|
||||
}
|
||||
@ -540,11 +539,11 @@ void sdp_client_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
static uint16_t sdp_client_setup_service_search_attribute_request(uint8_t * data){
|
||||
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
sdp_client_transaction_id++;
|
||||
// uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
|
||||
data[offset++] = SDP_ServiceSearchAttributeRequest;
|
||||
// uint16_t transactionID
|
||||
big_endian_store_16(data, offset, transactionID);
|
||||
big_endian_store_16(data, offset, sdp_client_transaction_id);
|
||||
offset += 2;
|
||||
|
||||
// param legnth
|
||||
@ -552,25 +551,25 @@ static uint16_t sdp_client_setup_service_search_attribute_request(uint8_t * data
|
||||
|
||||
// parameters:
|
||||
// Service_search_pattern - DES (min 1 UUID, max 12)
|
||||
uint16_t service_search_pattern_len = de_get_len(service_search_pattern);
|
||||
(void)memcpy(data + offset, service_search_pattern,
|
||||
uint16_t service_search_pattern_len = de_get_len(sdp_client_service_search_pattern);
|
||||
(void)memcpy(data + offset, sdp_client_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);
|
||||
big_endian_store_16(data, offset, sdp_client_mtu);
|
||||
offset += 2;
|
||||
|
||||
// AttibuteIDList
|
||||
uint16_t attribute_id_list_len = de_get_len(attribute_id_list);
|
||||
(void)memcpy(data + offset, attribute_id_list, attribute_id_list_len);
|
||||
uint16_t attribute_id_list_len = de_get_len(sdp_client_attribute_id_list);
|
||||
(void)memcpy(data + offset, sdp_client_attribute_id_list, attribute_id_list_len);
|
||||
offset += attribute_id_list_len;
|
||||
|
||||
// ContinuationState - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = continuationStateLen;
|
||||
data[offset++] = sdp_client_continuation_state_len;
|
||||
// - N-bytes previous response from server
|
||||
(void)memcpy(data + offset, continuationState, continuationStateLen);
|
||||
offset += continuationStateLen;
|
||||
(void)memcpy(data + offset, sdp_client_continuation_state, sdp_client_continuation_state_len);
|
||||
offset += sdp_client_continuation_state_len;
|
||||
|
||||
// uint16_t paramLength
|
||||
big_endian_store_16(data, 3, offset - 5);
|
||||
@ -585,11 +584,11 @@ void sdp_client_parse_service_record_handle_list(uint8_t* packet, uint16_t total
|
||||
|
||||
static uint16_t sdp_client_setup_service_search_request(uint8_t * data){
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
sdp_client_transaction_id++;
|
||||
// uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
|
||||
data[offset++] = SDP_ServiceSearchRequest;
|
||||
// uint16_t transactionID
|
||||
big_endian_store_16(data, offset, transactionID);
|
||||
big_endian_store_16(data, offset, sdp_client_transaction_id);
|
||||
offset += 2;
|
||||
|
||||
// param legnth
|
||||
@ -597,20 +596,20 @@ static uint16_t sdp_client_setup_service_search_request(uint8_t * data){
|
||||
|
||||
// parameters:
|
||||
// Service_search_pattern - DES (min 1 UUID, max 12)
|
||||
uint16_t service_search_pattern_len = de_get_len(service_search_pattern);
|
||||
(void)memcpy(data + offset, service_search_pattern,
|
||||
uint16_t service_search_pattern_len = de_get_len(sdp_client_service_search_pattern);
|
||||
(void)memcpy(data + offset, sdp_client_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);
|
||||
big_endian_store_16(data, offset, sdp_client_mtu);
|
||||
offset += 2;
|
||||
|
||||
// ContinuationState - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = continuationStateLen;
|
||||
data[offset++] = sdp_client_continuation_state_len;
|
||||
// - N-bytes previous response from server
|
||||
(void)memcpy(data + offset, continuationState, continuationStateLen);
|
||||
offset += continuationStateLen;
|
||||
(void)memcpy(data + offset, sdp_client_continuation_state, sdp_client_continuation_state_len);
|
||||
offset += sdp_client_continuation_state_len;
|
||||
|
||||
// uint16_t paramLength
|
||||
big_endian_store_16(data, 3, offset - 5);
|
||||
@ -622,11 +621,11 @@ static uint16_t sdp_client_setup_service_search_request(uint8_t * data){
|
||||
static uint16_t sdp_client_setup_service_attribute_request(uint8_t * data){
|
||||
|
||||
uint16_t offset = 0;
|
||||
transactionID++;
|
||||
sdp_client_transaction_id++;
|
||||
// uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
|
||||
data[offset++] = SDP_ServiceAttributeRequest;
|
||||
// uint16_t transactionID
|
||||
big_endian_store_16(data, offset, transactionID);
|
||||
big_endian_store_16(data, offset, sdp_client_transaction_id);
|
||||
offset += 2;
|
||||
|
||||
// param legnth
|
||||
@ -634,23 +633,23 @@ static uint16_t sdp_client_setup_service_attribute_request(uint8_t * data){
|
||||
|
||||
// parameters:
|
||||
// ServiceRecordHandle
|
||||
big_endian_store_32(data, offset, serviceRecordHandle);
|
||||
big_endian_store_32(data, offset, sdp_client_service_record_handle);
|
||||
offset += 4;
|
||||
|
||||
// MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
|
||||
big_endian_store_16(data, offset, mtu);
|
||||
big_endian_store_16(data, offset, sdp_client_mtu);
|
||||
offset += 2;
|
||||
|
||||
// AttibuteIDList
|
||||
uint16_t attribute_id_list_len = de_get_len(attribute_id_list);
|
||||
(void)memcpy(data + offset, attribute_id_list, attribute_id_list_len);
|
||||
uint16_t attribute_id_list_len = de_get_len(sdp_client_attribute_id_list);
|
||||
(void)memcpy(data + offset, sdp_client_attribute_id_list, attribute_id_list_len);
|
||||
offset += attribute_id_list_len;
|
||||
|
||||
// ContinuationState - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = continuationStateLen;
|
||||
// sdp_client_continuation_state - uint8_t number of cont. bytes N<=16
|
||||
data[offset++] = sdp_client_continuation_state_len;
|
||||
// - N-bytes previous response from server
|
||||
(void)memcpy(data + offset, continuationState, continuationStateLen);
|
||||
offset += continuationStateLen;
|
||||
(void)memcpy(data + offset, sdp_client_continuation_state, sdp_client_continuation_state_len);
|
||||
offset += sdp_client_continuation_state_len;
|
||||
|
||||
// uint16_t paramLength
|
||||
big_endian_store_16(data, 3, offset - 5);
|
||||
@ -682,16 +681,16 @@ static void sdp_client_parse_service_search_response(uint8_t* packet, uint16_t s
|
||||
offset+= currentServiceRecordCount * 4;
|
||||
|
||||
if (offset + 1 > size) return;
|
||||
continuationStateLen = packet[offset];
|
||||
sdp_client_continuation_state_len = packet[offset];
|
||||
offset++;
|
||||
if (continuationStateLen > 16){
|
||||
continuationStateLen = 0;
|
||||
if (sdp_client_continuation_state_len > 16){
|
||||
sdp_client_continuation_state_len = 0;
|
||||
log_error("Error parsing ServiceSearchResponse: Number of bytes in continuation state exceedes 16.");
|
||||
return;
|
||||
}
|
||||
if (offset + continuationStateLen > size) return;
|
||||
(void)memcpy(continuationState, packet + offset, continuationStateLen);
|
||||
// offset+=continuationStateLen;
|
||||
if (offset + sdp_client_continuation_state_len > size) return;
|
||||
(void)memcpy(sdp_client_continuation_state, packet + offset, sdp_client_continuation_state_len);
|
||||
// offset+=sdp_client_continuation_state_len;
|
||||
}
|
||||
|
||||
static void sdp_client_parse_service_attribute_response(uint8_t* packet, uint16_t size){
|
||||
@ -705,7 +704,7 @@ static void sdp_client_parse_service_attribute_response(uint8_t* packet, uint16_
|
||||
// AttributeListByteCount <= mtu
|
||||
uint16_t attributeListByteCount = big_endian_read_16(packet,offset);
|
||||
offset+=2;
|
||||
if (attributeListByteCount > mtu){
|
||||
if (attributeListByteCount > sdp_client_mtu){
|
||||
log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
|
||||
return;
|
||||
}
|
||||
@ -715,18 +714,18 @@ static void sdp_client_parse_service_attribute_response(uint8_t* packet, uint16_
|
||||
sdp_client_parse_attribute_lists(packet+offset, attributeListByteCount);
|
||||
offset+=attributeListByteCount;
|
||||
|
||||
// continuationStateLen
|
||||
// sdp_client_continuation_state_len
|
||||
if (offset + 1 > size) return;
|
||||
continuationStateLen = packet[offset];
|
||||
sdp_client_continuation_state_len = packet[offset];
|
||||
offset++;
|
||||
if (continuationStateLen > 16){
|
||||
continuationStateLen = 0;
|
||||
if (sdp_client_continuation_state_len > 16){
|
||||
sdp_client_continuation_state_len = 0;
|
||||
log_error("Error parsing ServiceAttributeResponse: Number of bytes in continuation state exceedes 16.");
|
||||
return;
|
||||
}
|
||||
if (offset + continuationStateLen > size) return;
|
||||
(void)memcpy(continuationState, packet + offset, continuationStateLen);
|
||||
// offset+=continuationStateLen;
|
||||
if (offset + sdp_client_continuation_state_len > size) return;
|
||||
(void)memcpy(sdp_client_continuation_state, packet + offset, sdp_client_continuation_state_len);
|
||||
// offset+=sdp_client_continuation_state_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -747,10 +746,10 @@ uint8_t sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, co
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
|
||||
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_service_search_pattern = des_service_search_pattern;
|
||||
sdp_client_attribute_id_list = des_attribute_id_list;
|
||||
sdp_client_continuation_state_len = 0;
|
||||
sdp_client_pdu_id = SDP_ServiceSearchAttributeResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
return l2cap_create_channel(sdp_client_packet_handler, remote, BLUETOOTH_PSM_SDP, l2cap_max_mtu(), NULL);
|
||||
@ -758,12 +757,12 @@ uint8_t sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, co
|
||||
|
||||
uint8_t sdp_client_query_uuid16(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
return sdp_client_query(callback, remote, sdp_service_search_pattern_for_uuid16(uuid), des_attributeIDList);
|
||||
return sdp_client_query(callback, remote, sdp_service_search_pattern_for_uuid16(uuid), sdp_client_des_attribute_id_list);
|
||||
}
|
||||
|
||||
uint8_t sdp_client_query_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t* uuid){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
return sdp_client_query(callback, remote, sdp_service_search_pattern_for_uuid128(uuid), des_attributeIDList);
|
||||
return sdp_client_query(callback, remote, sdp_service_search_pattern_for_uuid128(uuid), sdp_client_des_attribute_id_list);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SDP_EXTRA_QUERIES
|
||||
@ -771,10 +770,10 @@ uint8_t sdp_client_service_attribute_search(btstack_packet_handler_t callback, b
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
|
||||
sdp_parser_init(callback);
|
||||
serviceRecordHandle = search_service_record_handle;
|
||||
attribute_id_list = des_attribute_id_list;
|
||||
continuationStateLen = 0;
|
||||
PDU_ID = SDP_ServiceAttributeResponse;
|
||||
sdp_client_service_record_handle = search_service_record_handle;
|
||||
sdp_client_attribute_id_list = des_attribute_id_list;
|
||||
sdp_client_continuation_state_len = 0;
|
||||
sdp_client_pdu_id = SDP_ServiceAttributeResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
l2cap_create_channel(sdp_client_packet_handler, remote, BLUETOOTH_PSM_SDP, l2cap_max_mtu(), NULL);
|
||||
@ -786,9 +785,9 @@ uint8_t sdp_client_service_search(btstack_packet_handler_t callback, bd_addr_t r
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
|
||||
sdp_parser_init(callback);
|
||||
service_search_pattern = des_service_search_pattern;
|
||||
continuationStateLen = 0;
|
||||
PDU_ID = SDP_ServiceSearchResponse;
|
||||
sdp_client_service_search_pattern = des_service_search_pattern;
|
||||
sdp_client_continuation_state_len = 0;
|
||||
sdp_client_pdu_id = SDP_ServiceSearchResponse;
|
||||
|
||||
sdp_client_state = W4_CONNECT;
|
||||
l2cap_create_channel(sdp_client_packet_handler, remote, BLUETOOTH_PSM_SDP, l2cap_max_mtu(), NULL);
|
||||
|
@ -67,7 +67,7 @@ static enum {
|
||||
GET_PROTOCOL_ID,
|
||||
GET_PROTOCOL_VALUE_LENGTH,
|
||||
GET_PROTOCOL_VALUE
|
||||
} protokoll_descriptor_list_state;
|
||||
} protocol_descriptor_list_state;
|
||||
|
||||
static enum {
|
||||
GET_SERVICE_LIST_LENGTH = 1,
|
||||
@ -81,48 +81,48 @@ static enum {
|
||||
// higher layer query - get rfcomm channel and name
|
||||
|
||||
// All attributes: 0x0001 - 0x0100
|
||||
static const uint8_t des_attributeIDList[] = { 0x35, 0x05, 0x0A, 0x00, 0x01, 0x01, 0x00};
|
||||
static const uint8_t des_attribute_id_list[] = {0x35, 0x05, 0x0A, 0x00, 0x01, 0x01, 0x00};
|
||||
|
||||
static uint8_t sdp_service_name[SDP_SERVICE_NAME_LEN+1];
|
||||
static uint8_t sdp_service_name_len = 0;
|
||||
static uint8_t sdp_rfcomm_channel_nr = 0;
|
||||
static uint8_t sdp_client_rfcomm_service_name[SDP_SERVICE_NAME_LEN + 1];
|
||||
static uint8_t sdp_client_rfcomm_service_name_len = 0;
|
||||
static uint8_t sdp_client_rfcomm_channel_nr = 0;
|
||||
|
||||
static uint8_t sdp_service_name_header_size;
|
||||
static uint8_t sdp_client_rfcomm_service_name_header_size;
|
||||
|
||||
static bool sdp_client_rfcomm_serviceclass_matched;
|
||||
static bool sdp_client_rfcomm_match_serviceclass;
|
||||
static bool sdp_client_rfcomm_servicec_lass_matched;
|
||||
static bool sdp_client_rfcomm_match_service_class;
|
||||
static uint16_t sdp_client_rfcomm_uuid16;
|
||||
|
||||
static int protocol_value_bytes_received = 0;
|
||||
static int protocol_value_size;
|
||||
static int protocol_offset;
|
||||
static int protocol_size;
|
||||
static int protocol_id_bytes_to_read;
|
||||
static uint32_t protocol_id = 0;
|
||||
static int sdp_client_rfcomm_protocol_value_bytes_received = 0;
|
||||
static int sdp_client_rfcomm_protocol_value_size;
|
||||
static int sdp_client_rfcomm_protocol_offset;
|
||||
static int sdp_client_rfcomm_protocol_size;
|
||||
static int sdp_client_rfcomm_protocol_id_bytes_to_read;
|
||||
static uint32_t sdp_client_rfcomm_protocol_id = 0;
|
||||
|
||||
static de_state_t de_header_state;
|
||||
static btstack_packet_handler_t sdp_app_callback;
|
||||
static de_state_t sdp_client_rfcomm_de_header_state;
|
||||
static btstack_packet_handler_t sdp_client_rfcomm_app_callback;
|
||||
//
|
||||
|
||||
static void sdp_rfcomm_query_prepare(void){
|
||||
sdp_rfcomm_channel_nr = 0;
|
||||
sdp_service_name[0] = 0;
|
||||
sdp_client_rfcomm_serviceclass_matched = false;
|
||||
sdp_client_rfcomm_channel_nr = 0;
|
||||
sdp_client_rfcomm_service_name[0] = 0;
|
||||
sdp_client_rfcomm_servicec_lass_matched = false;
|
||||
}
|
||||
|
||||
static void sdp_rfcomm_query_emit_service(void){
|
||||
uint8_t event[3+SDP_SERVICE_NAME_LEN+1];
|
||||
event[0] = SDP_EVENT_QUERY_RFCOMM_SERVICE;
|
||||
event[1] = sdp_service_name_len + 1;
|
||||
event[2] = sdp_rfcomm_channel_nr;
|
||||
(void)memcpy(&event[3], sdp_service_name, sdp_service_name_len);
|
||||
event[3+sdp_service_name_len] = 0;
|
||||
(*sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
event[1] = sdp_client_rfcomm_service_name_len + 1;
|
||||
event[2] = sdp_client_rfcomm_channel_nr;
|
||||
(void)memcpy(&event[3], sdp_client_rfcomm_service_name, sdp_client_rfcomm_service_name_len);
|
||||
event[3 + sdp_client_rfcomm_service_name_len] = 0;
|
||||
(*sdp_client_rfcomm_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void sdp_client_query_rfcomm_handle_record_parsed(void){
|
||||
if (sdp_rfcomm_channel_nr == 0) return;
|
||||
if (sdp_client_rfcomm_match_serviceclass && (sdp_client_rfcomm_serviceclass_matched == false)) return;
|
||||
if (sdp_client_rfcomm_channel_nr == 0) return;
|
||||
if (sdp_client_rfcomm_match_service_class && (sdp_client_rfcomm_servicec_lass_matched == false)) return;
|
||||
sdp_rfcomm_query_emit_service();
|
||||
sdp_rfcomm_query_prepare();
|
||||
}
|
||||
@ -134,7 +134,7 @@ static void sdp_client_query_rfcomm_handle_service_class_list_data(uint32_t attr
|
||||
// init state on first byte
|
||||
if (data_offset == 0){
|
||||
service_class_id_list_state = GET_SERVICE_LIST_LENGTH;
|
||||
de_state_init(&de_header_state);
|
||||
de_state_init(&sdp_client_rfcomm_de_header_state);
|
||||
}
|
||||
|
||||
// process data
|
||||
@ -142,21 +142,21 @@ static void sdp_client_query_rfcomm_handle_service_class_list_data(uint32_t attr
|
||||
|
||||
case GET_SERVICE_LIST_LENGTH:
|
||||
// read DES sequence header
|
||||
if (!de_state_size(data, &de_header_state)) break;
|
||||
if (!de_state_size(data, &sdp_client_rfcomm_de_header_state)) break;
|
||||
service_class_id_list_state = GET_SERVICE_LIST_ITEM_GET_UUID_TYPE;
|
||||
break;
|
||||
|
||||
case GET_SERVICE_LIST_ITEM_GET_UUID_TYPE:
|
||||
protocol_id = 0;
|
||||
protocol_offset = 0;
|
||||
sdp_client_rfcomm_protocol_id = 0;
|
||||
sdp_client_rfcomm_protocol_offset = 0;
|
||||
// validate UUID type
|
||||
if (de_get_element_type(&data) != DE_UUID) {
|
||||
service_class_id_list_state = GET_SERVICE_INVALID;
|
||||
break;
|
||||
}
|
||||
// get UUID length
|
||||
protocol_id_bytes_to_read = de_get_data_size(&data);
|
||||
if (protocol_id_bytes_to_read > 16) {
|
||||
sdp_client_rfcomm_protocol_id_bytes_to_read = de_get_data_size(&data);
|
||||
if (sdp_client_rfcomm_protocol_id_bytes_to_read > 16) {
|
||||
service_class_id_list_state = GET_SERVICE_INVALID;
|
||||
break;
|
||||
}
|
||||
@ -164,27 +164,27 @@ static void sdp_client_query_rfcomm_handle_service_class_list_data(uint32_t attr
|
||||
break;
|
||||
|
||||
case GET_SERVICE_LIST_ITEM:
|
||||
sdp_service_name[protocol_offset++] = data;
|
||||
protocol_id_bytes_to_read--;
|
||||
if (protocol_id_bytes_to_read > 0) break;
|
||||
sdp_client_rfcomm_service_name[sdp_client_rfcomm_protocol_offset++] = data;
|
||||
sdp_client_rfcomm_protocol_id_bytes_to_read--;
|
||||
if (sdp_client_rfcomm_protocol_id_bytes_to_read > 0) break;
|
||||
// parse 2/4/16 bytes UUID
|
||||
switch (protocol_offset){
|
||||
switch (sdp_client_rfcomm_protocol_offset){
|
||||
case 2:
|
||||
protocol_id = big_endian_read_16(sdp_service_name, 0);
|
||||
sdp_client_rfcomm_protocol_id = big_endian_read_16(sdp_client_rfcomm_service_name, 0);
|
||||
break;
|
||||
case 4:
|
||||
protocol_id = big_endian_read_32(sdp_service_name, 0);
|
||||
sdp_client_rfcomm_protocol_id = big_endian_read_32(sdp_client_rfcomm_service_name, 0);
|
||||
break;
|
||||
case 16:
|
||||
if (uuid_has_bluetooth_prefix(sdp_service_name)){
|
||||
protocol_id = big_endian_read_32(sdp_service_name, 0);
|
||||
if (uuid_has_bluetooth_prefix(sdp_client_rfcomm_service_name)){
|
||||
sdp_client_rfcomm_protocol_id = big_endian_read_32(sdp_client_rfcomm_service_name, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (protocol_id == sdp_client_rfcomm_uuid16){
|
||||
sdp_client_rfcomm_serviceclass_matched = true;
|
||||
if (sdp_client_rfcomm_protocol_id == sdp_client_rfcomm_uuid16){
|
||||
sdp_client_rfcomm_servicec_lass_matched = true;
|
||||
}
|
||||
service_class_id_list_state = GET_SERVICE_LIST_ITEM_GET_UUID_TYPE;
|
||||
break;
|
||||
@ -199,83 +199,83 @@ static void sdp_client_query_rfcomm_handle_protocol_descriptor_list_data(uint32_
|
||||
|
||||
// init state on first byte
|
||||
if (data_offset == 0){
|
||||
de_state_init(&de_header_state);
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH;
|
||||
de_state_init(&sdp_client_rfcomm_de_header_state);
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH;
|
||||
}
|
||||
|
||||
switch(protokoll_descriptor_list_state){
|
||||
switch(protocol_descriptor_list_state){
|
||||
|
||||
case GET_PROTOCOL_LIST_LENGTH:
|
||||
if (!de_state_size(data, &de_header_state)) break;
|
||||
if (!de_state_size(data, &sdp_client_rfcomm_de_header_state)) break;
|
||||
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
break;
|
||||
|
||||
case GET_PROTOCOL_LENGTH:
|
||||
// check size
|
||||
if (!de_state_size(data, &de_header_state)) break;
|
||||
if (!de_state_size(data, &sdp_client_rfcomm_de_header_state)) break;
|
||||
|
||||
// cache protocol info
|
||||
protocol_offset = de_header_state.de_offset;
|
||||
protocol_size = de_header_state.de_size;
|
||||
sdp_client_rfcomm_protocol_offset = sdp_client_rfcomm_de_header_state.de_offset;
|
||||
sdp_client_rfcomm_protocol_size = sdp_client_rfcomm_de_header_state.de_size;
|
||||
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH;
|
||||
break;
|
||||
|
||||
case GET_PROTOCOL_ID_HEADER_LENGTH:
|
||||
protocol_offset++;
|
||||
if (!de_state_size(data, &de_header_state)) break;
|
||||
|
||||
protocol_id = 0;
|
||||
protocol_id_bytes_to_read = de_header_state.de_size;
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_ID;
|
||||
sdp_client_rfcomm_protocol_offset++;
|
||||
if (!de_state_size(data, &sdp_client_rfcomm_de_header_state)) break;
|
||||
|
||||
sdp_client_rfcomm_protocol_id = 0;
|
||||
sdp_client_rfcomm_protocol_id_bytes_to_read = sdp_client_rfcomm_de_header_state.de_size;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_ID;
|
||||
|
||||
break;
|
||||
|
||||
case GET_PROTOCOL_ID:
|
||||
protocol_offset++;
|
||||
sdp_client_rfcomm_protocol_offset++;
|
||||
|
||||
protocol_id = (protocol_id << 8) | data;
|
||||
protocol_id_bytes_to_read--;
|
||||
if (protocol_id_bytes_to_read > 0) break;
|
||||
sdp_client_rfcomm_protocol_id = (sdp_client_rfcomm_protocol_id << 8) | data;
|
||||
sdp_client_rfcomm_protocol_id_bytes_to_read--;
|
||||
if (sdp_client_rfcomm_protocol_id_bytes_to_read > 0) break;
|
||||
|
||||
|
||||
if (protocol_offset >= protocol_size){
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
if (sdp_client_rfcomm_protocol_offset >= sdp_client_rfcomm_protocol_size){
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
break;
|
||||
}
|
||||
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_VALUE_LENGTH;
|
||||
protocol_value_bytes_received = 0;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_VALUE_LENGTH;
|
||||
sdp_client_rfcomm_protocol_value_bytes_received = 0;
|
||||
break;
|
||||
|
||||
case GET_PROTOCOL_VALUE_LENGTH:
|
||||
protocol_offset++;
|
||||
sdp_client_rfcomm_protocol_offset++;
|
||||
|
||||
if (!de_state_size(data, &de_header_state)) break;
|
||||
if (!de_state_size(data, &sdp_client_rfcomm_de_header_state)) break;
|
||||
|
||||
protocol_value_size = de_header_state.de_size;
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_VALUE;
|
||||
sdp_rfcomm_channel_nr = 0;
|
||||
sdp_client_rfcomm_protocol_value_size = sdp_client_rfcomm_de_header_state.de_size;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_VALUE;
|
||||
sdp_client_rfcomm_channel_nr = 0;
|
||||
break;
|
||||
|
||||
case GET_PROTOCOL_VALUE:
|
||||
protocol_offset++;
|
||||
protocol_value_bytes_received++;
|
||||
sdp_client_rfcomm_protocol_offset++;
|
||||
sdp_client_rfcomm_protocol_value_bytes_received++;
|
||||
|
||||
if (protocol_value_bytes_received < protocol_value_size) break;
|
||||
if (sdp_client_rfcomm_protocol_value_bytes_received < sdp_client_rfcomm_protocol_value_size) break;
|
||||
|
||||
if (protocol_id == BLUETOOTH_PROTOCOL_RFCOMM){
|
||||
if (sdp_client_rfcomm_protocol_id == BLUETOOTH_PROTOCOL_RFCOMM){
|
||||
// log_info("\n\n ******* Data ***** %02x\n\n", data);
|
||||
sdp_rfcomm_channel_nr = data;
|
||||
sdp_client_rfcomm_channel_nr = data;
|
||||
}
|
||||
|
||||
if (protocol_offset >= protocol_size) {
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
if (sdp_client_rfcomm_protocol_offset >= sdp_client_rfcomm_protocol_size) {
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_LENGTH;
|
||||
break;
|
||||
|
||||
}
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -286,41 +286,41 @@ static void sdp_client_query_rfcomm_handle_service_name_data(uint32_t attribute_
|
||||
|
||||
// Get Header Len
|
||||
if (data_offset == 0){
|
||||
de_state_init(&de_header_state);
|
||||
de_state_size(data, &de_header_state);
|
||||
sdp_service_name_header_size = de_header_state.addon_header_bytes + 1;
|
||||
de_state_init(&sdp_client_rfcomm_de_header_state);
|
||||
de_state_size(data, &sdp_client_rfcomm_de_header_state);
|
||||
sdp_client_rfcomm_service_name_header_size = sdp_client_rfcomm_de_header_state.addon_header_bytes + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Header
|
||||
if (data_offset < sdp_service_name_header_size){
|
||||
de_state_size(data, &de_header_state);
|
||||
if (data_offset < sdp_client_rfcomm_service_name_header_size){
|
||||
de_state_size(data, &sdp_client_rfcomm_de_header_state);
|
||||
return;
|
||||
}
|
||||
|
||||
// Process payload
|
||||
int name_len = attribute_value_length - sdp_service_name_header_size;
|
||||
int name_pos = data_offset - sdp_service_name_header_size;
|
||||
int name_len = attribute_value_length - sdp_client_rfcomm_service_name_header_size;
|
||||
int name_pos = data_offset - sdp_client_rfcomm_service_name_header_size;
|
||||
|
||||
if (name_pos < SDP_SERVICE_NAME_LEN){
|
||||
sdp_service_name[name_pos] = data;
|
||||
sdp_client_rfcomm_service_name[name_pos] = data;
|
||||
name_pos++;
|
||||
|
||||
// terminate if name complete
|
||||
if (name_pos >= name_len){
|
||||
sdp_service_name[name_pos] = 0;
|
||||
sdp_service_name_len = name_pos;
|
||||
sdp_client_rfcomm_service_name[name_pos] = 0;
|
||||
sdp_client_rfcomm_service_name_len = name_pos;
|
||||
}
|
||||
|
||||
// terminate if buffer full
|
||||
if (name_pos == SDP_SERVICE_NAME_LEN){
|
||||
sdp_service_name[name_pos] = 0;
|
||||
sdp_service_name_len = name_pos;
|
||||
sdp_client_rfcomm_service_name[name_pos] = 0;
|
||||
sdp_client_rfcomm_service_name_len = name_pos;
|
||||
}
|
||||
}
|
||||
|
||||
// notify on last char
|
||||
if ((data_offset == (attribute_value_length - 1)) && (sdp_rfcomm_channel_nr!=0)){
|
||||
if ((data_offset == (attribute_value_length - 1)) && (sdp_client_rfcomm_channel_nr != 0)){
|
||||
sdp_client_query_rfcomm_handle_record_parsed();
|
||||
}
|
||||
}
|
||||
@ -339,7 +339,7 @@ static void sdp_client_query_rfcomm_handle_sdp_parser_event(uint8_t packet_type,
|
||||
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
|
||||
switch (sdp_event_query_attribute_byte_get_attribute_id(packet)){
|
||||
case BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST:
|
||||
if (sdp_client_rfcomm_match_serviceclass){
|
||||
if (sdp_client_rfcomm_match_service_class){
|
||||
sdp_client_query_rfcomm_handle_service_class_list_data(sdp_event_query_attribute_byte_get_attribute_length(packet),
|
||||
sdp_event_query_attribute_byte_get_data_offset(packet),
|
||||
sdp_event_query_attribute_byte_get_data(packet));
|
||||
@ -364,7 +364,7 @@ static void sdp_client_query_rfcomm_handle_sdp_parser_event(uint8_t packet_type,
|
||||
break;
|
||||
case SDP_EVENT_QUERY_COMPLETE:
|
||||
sdp_client_query_rfcomm_handle_record_parsed();
|
||||
(*sdp_app_callback)(HCI_EVENT_PACKET, 0, packet, size);
|
||||
(*sdp_client_rfcomm_app_callback)(HCI_EVENT_PACKET, 0, packet, size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -373,41 +373,41 @@ static void sdp_client_query_rfcomm_handle_sdp_parser_event(uint8_t packet_type,
|
||||
|
||||
void sdp_client_query_rfcomm_init(void){
|
||||
// init
|
||||
protokoll_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH;
|
||||
protocol_offset = 0;
|
||||
sdp_rfcomm_channel_nr = 0;
|
||||
sdp_service_name[0] = 0;
|
||||
protocol_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH;
|
||||
sdp_client_rfcomm_protocol_offset = 0;
|
||||
sdp_client_rfcomm_channel_nr = 0;
|
||||
sdp_client_rfcomm_service_name[0] = 0;
|
||||
}
|
||||
|
||||
static uint8_t sdp_client_query_rfcomm(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * service_search_pattern){
|
||||
sdp_app_callback = callback;
|
||||
sdp_client_rfcomm_app_callback = callback;
|
||||
sdp_client_query_rfcomm_init();
|
||||
return sdp_client_query(&sdp_client_query_rfcomm_handle_sdp_parser_event, remote, service_search_pattern, (uint8_t*)&des_attributeIDList[0]);
|
||||
return sdp_client_query(&sdp_client_query_rfcomm_handle_sdp_parser_event, remote, service_search_pattern, (uint8_t*)&des_attribute_id_list[0]);
|
||||
}
|
||||
|
||||
// Public API
|
||||
|
||||
uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
sdp_client_rfcomm_match_serviceclass = false;
|
||||
sdp_client_rfcomm_match_service_class = false;
|
||||
return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid16(uuid16));
|
||||
}
|
||||
|
||||
uint8_t sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
sdp_client_rfcomm_match_serviceclass = true;
|
||||
sdp_client_rfcomm_match_service_class = true;
|
||||
sdp_client_rfcomm_uuid16 = uuid16;
|
||||
return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid16(uuid16));
|
||||
}
|
||||
|
||||
uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * uuid128){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
sdp_client_rfcomm_match_serviceclass = false;
|
||||
sdp_client_rfcomm_match_service_class = false;
|
||||
return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid128(uuid128));
|
||||
}
|
||||
|
||||
uint8_t sdp_client_query_rfcomm_channel_and_name_for_search_pattern(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * service_search_pattern){
|
||||
if (!sdp_client_ready()) return SDP_QUERY_BUSY;
|
||||
sdp_client_rfcomm_match_serviceclass = false;
|
||||
sdp_client_rfcomm_match_service_class = false;
|
||||
return sdp_client_query_rfcomm(callback, remote, service_search_pattern);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@
|
||||
#endif
|
||||
|
||||
// max reserved ServiceRecordHandle
|
||||
#define maxReservedServiceRecordHandle 0xffff
|
||||
#define MAX_RESERVED_SERVICE_RECORD_HANDLE 0xffff
|
||||
|
||||
// max SDP response matches L2CAP PDU -- allow to use smaller buffer
|
||||
#ifndef SDP_RESPONSE_BUFFER_SIZE
|
||||
@ -72,29 +72,29 @@
|
||||
static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
// registered service records
|
||||
static btstack_linked_list_t sdp_service_records;
|
||||
static btstack_linked_list_t sdp_server_service_records;
|
||||
|
||||
// our handles start after the reserved range
|
||||
static uint32_t sdp_next_service_record_handle;
|
||||
static uint32_t sdp_server_next_service_record_handle;
|
||||
|
||||
static uint8_t sdp_response_buffer[SDP_RESPONSE_BUFFER_SIZE];
|
||||
|
||||
static uint16_t l2cap_cid;
|
||||
static uint16_t sdp_response_size;
|
||||
static uint16_t l2cap_waiting_list_cids[SDP_WAITING_LIST_MAX_COUNT];
|
||||
static int l2cap_waiting_list_count;
|
||||
static uint16_t sdp_server_l2cap_cid;
|
||||
static uint16_t sdp_server_response_size;
|
||||
static uint16_t sdp_server_l2cap_waiting_list_cids[SDP_WAITING_LIST_MAX_COUNT];
|
||||
static int sdp_server_l2cap_waiting_list_count;
|
||||
|
||||
void sdp_init(void){
|
||||
l2cap_cid = 0;
|
||||
l2cap_waiting_list_count = 0;
|
||||
sdp_service_records = NULL;
|
||||
sdp_next_service_record_handle = ((uint32_t) maxReservedServiceRecordHandle) + 2;
|
||||
sdp_response_size = 0;
|
||||
sdp_server_next_service_record_handle = ((uint32_t) MAX_RESERVED_SERVICE_RECORD_HANDLE) + 2;
|
||||
// register with l2cap psm sevices - max MTU
|
||||
l2cap_register_service(sdp_packet_handler, BLUETOOTH_PSM_SDP, 0xffff, LEVEL_0);
|
||||
}
|
||||
|
||||
void sdp_deinit(void){
|
||||
sdp_server_service_records = NULL;
|
||||
sdp_server_l2cap_cid = 0;
|
||||
sdp_server_response_size = 0;
|
||||
sdp_server_l2cap_waiting_list_count = 0;
|
||||
}
|
||||
|
||||
uint32_t sdp_get_service_record_handle(const uint8_t * record){
|
||||
@ -108,7 +108,7 @@ uint32_t sdp_get_service_record_handle(const uint8_t * record){
|
||||
|
||||
static service_record_item_t * sdp_get_record_item_for_handle(uint32_t handle){
|
||||
btstack_linked_item_t *it;
|
||||
for (it = (btstack_linked_item_t *) sdp_service_records; it ; it = it->next){
|
||||
for (it = (btstack_linked_item_t *) sdp_server_service_records; it ; it = it->next){
|
||||
service_record_item_t * item = (service_record_item_t *) it;
|
||||
if (item->service_record_handle == handle){
|
||||
return item;
|
||||
@ -127,7 +127,7 @@ uint8_t * sdp_get_record_for_handle(uint32_t handle){
|
||||
uint32_t sdp_create_service_record_handle(void){
|
||||
uint32_t handle = 0;
|
||||
do {
|
||||
handle = sdp_next_service_record_handle++;
|
||||
handle = sdp_server_next_service_record_handle++;
|
||||
if (sdp_get_record_item_for_handle(handle)) handle = 0;
|
||||
} while (handle == 0);
|
||||
return handle;
|
||||
@ -145,7 +145,7 @@ uint8_t sdp_register_service(const uint8_t * record){
|
||||
// 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 (record_handle <= MAX_RESERVED_SERVICE_RECORD_HANDLE) return SDP_HANDLE_INVALID;
|
||||
if (sdp_get_record_item_for_handle(record_handle)) return SDP_HANDLE_ALREADY_REGISTERED;
|
||||
|
||||
// alloc memory for new service_record_item
|
||||
@ -157,7 +157,7 @@ uint8_t sdp_register_service(const uint8_t * record){
|
||||
newRecordItem->service_record = (uint8_t*) record;
|
||||
|
||||
// add to linked list
|
||||
btstack_linked_list_add(&sdp_service_records, (btstack_linked_item_t *) newRecordItem);
|
||||
btstack_linked_list_add(&sdp_server_service_records, (btstack_linked_item_t *) newRecordItem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -168,7 +168,7 @@ uint8_t sdp_register_service(const uint8_t * 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;
|
||||
btstack_linked_list_remove(&sdp_service_records, (btstack_linked_item_t *) record_item);
|
||||
btstack_linked_list_remove(&sdp_server_service_records, (btstack_linked_item_t *) record_item);
|
||||
btstack_memory_service_record_item_free(record_item);
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ int sdp_handle_service_search_request(uint8_t * packet, uint16_t remote_mtu){
|
||||
// get and limit total count
|
||||
btstack_linked_item_t *it;
|
||||
uint16_t total_service_count = 0;
|
||||
for (it = (btstack_linked_item_t *) sdp_service_records; it ; it = it->next){
|
||||
for (it = (btstack_linked_item_t *) sdp_server_service_records; it ; it = it->next){
|
||||
service_record_item_t * item = (service_record_item_t *) it;
|
||||
if (!sdp_record_matches_service_search_pattern(item->service_record, serviceSearchPattern)) continue;
|
||||
total_service_count++;
|
||||
@ -230,7 +230,7 @@ int sdp_handle_service_search_request(uint8_t * packet, uint16_t remote_mtu){
|
||||
uint16_t current_service_count = 0;
|
||||
uint16_t current_service_index = 0;
|
||||
uint16_t matching_service_count = 0;
|
||||
for (it = (btstack_linked_item_t *) sdp_service_records; it ; it = it->next, ++current_service_index){
|
||||
for (it = (btstack_linked_item_t *) sdp_server_service_records; it ; it = it->next, ++current_service_index){
|
||||
service_record_item_t * item = (service_record_item_t *) it;
|
||||
|
||||
if (!sdp_record_matches_service_search_pattern(item->service_record, serviceSearchPattern)) continue;
|
||||
@ -353,7 +353,7 @@ int sdp_handle_service_attribute_request(uint8_t * packet, uint16_t remote_mtu){
|
||||
static uint16_t sdp_get_size_for_service_search_attribute_response(uint8_t * serviceSearchPattern, uint8_t * attributeIDList){
|
||||
uint16_t total_response_size = 0;
|
||||
btstack_linked_item_t *it;
|
||||
for (it = (btstack_linked_item_t *) sdp_service_records; it ; it = it->next){
|
||||
for (it = (btstack_linked_item_t *) sdp_server_service_records; it ; it = it->next){
|
||||
service_record_item_t * item = (service_record_item_t *) it;
|
||||
|
||||
if (!sdp_record_matches_service_search_pattern(item->service_record, serviceSearchPattern)) continue;
|
||||
@ -424,7 +424,7 @@ int sdp_handle_service_search_attribute_request(uint8_t * packet, uint16_t remot
|
||||
int first_answer = 1;
|
||||
int continuation = 0;
|
||||
uint16_t current_service_index = 0;
|
||||
btstack_linked_item_t *it = (btstack_linked_item_t *) sdp_service_records;
|
||||
btstack_linked_item_t *it = (btstack_linked_item_t *) sdp_server_service_records;
|
||||
for ( ; it ; it = it->next, ++current_service_index){
|
||||
service_record_item_t * item = (service_record_item_t *) it;
|
||||
|
||||
@ -490,26 +490,26 @@ int sdp_handle_service_search_attribute_request(uint8_t * packet, uint16_t remot
|
||||
}
|
||||
|
||||
static void sdp_respond(void){
|
||||
if (!sdp_response_size ) return;
|
||||
if (!l2cap_cid) return;
|
||||
if (!sdp_server_response_size ) return;
|
||||
if (!sdp_server_l2cap_cid) return;
|
||||
|
||||
// update state before sending packet (avoid getting called when new l2cap credit gets emitted)
|
||||
uint16_t size = sdp_response_size;
|
||||
sdp_response_size = 0;
|
||||
l2cap_send(l2cap_cid, sdp_response_buffer, size);
|
||||
uint16_t size = sdp_server_response_size;
|
||||
sdp_server_response_size = 0;
|
||||
l2cap_send(sdp_server_l2cap_cid, sdp_response_buffer, size);
|
||||
}
|
||||
|
||||
// @pre space in list
|
||||
static void sdp_waiting_list_add(uint16_t cid){
|
||||
l2cap_waiting_list_cids[l2cap_waiting_list_count++] = cid;
|
||||
sdp_server_l2cap_waiting_list_cids[sdp_server_l2cap_waiting_list_count++] = cid;
|
||||
}
|
||||
|
||||
// @pre at least one item in list
|
||||
static uint16_t sdp_waiting_list_get(void){
|
||||
uint16_t cid = l2cap_waiting_list_cids[0];
|
||||
l2cap_waiting_list_count--;
|
||||
if (l2cap_waiting_list_count){
|
||||
memmove(&l2cap_waiting_list_cids[0], &l2cap_waiting_list_cids[1], l2cap_waiting_list_count * sizeof(uint16_t));
|
||||
uint16_t cid = sdp_server_l2cap_waiting_list_cids[0];
|
||||
sdp_server_l2cap_waiting_list_count--;
|
||||
if (sdp_server_l2cap_waiting_list_count){
|
||||
memmove(&sdp_server_l2cap_waiting_list_cids[0], &sdp_server_l2cap_waiting_list_cids[1], sdp_server_l2cap_waiting_list_count * sizeof(uint16_t));
|
||||
}
|
||||
return cid;
|
||||
}
|
||||
@ -517,14 +517,14 @@ static uint16_t sdp_waiting_list_get(void){
|
||||
// we assume that we don't get two requests in a row
|
||||
static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
uint16_t transaction_id;
|
||||
SDP_PDU_ID_t pdu_id;
|
||||
sdp_pdu_id_t pdu_id;
|
||||
uint16_t remote_mtu;
|
||||
uint16_t param_len;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
case L2CAP_DATA_PACKET:
|
||||
pdu_id = (SDP_PDU_ID_t) packet[0];
|
||||
pdu_id = (sdp_pdu_id_t) packet[0];
|
||||
transaction_id = big_endian_read_16(packet, 1);
|
||||
param_len = big_endian_read_16(packet, 3);
|
||||
remote_mtu = l2cap_get_remote_mtu_for_local_cid(channel);
|
||||
@ -542,23 +542,23 @@ static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
switch (pdu_id){
|
||||
|
||||
case SDP_ServiceSearchRequest:
|
||||
sdp_response_size = sdp_handle_service_search_request(packet, remote_mtu);
|
||||
sdp_server_response_size = sdp_handle_service_search_request(packet, remote_mtu);
|
||||
break;
|
||||
|
||||
case SDP_ServiceAttributeRequest:
|
||||
sdp_response_size = sdp_handle_service_attribute_request(packet, remote_mtu);
|
||||
sdp_server_response_size = sdp_handle_service_attribute_request(packet, remote_mtu);
|
||||
break;
|
||||
|
||||
case SDP_ServiceSearchAttributeRequest:
|
||||
sdp_response_size = sdp_handle_service_search_attribute_request(packet, remote_mtu);
|
||||
sdp_server_response_size = sdp_handle_service_search_attribute_request(packet, remote_mtu);
|
||||
break;
|
||||
|
||||
default:
|
||||
sdp_response_size = sdp_create_error_response(transaction_id, 0x0003); // invalid syntax
|
||||
sdp_server_response_size = sdp_create_error_response(transaction_id, 0x0003); // invalid syntax
|
||||
break;
|
||||
}
|
||||
if (!sdp_response_size) break;
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
if (!sdp_server_response_size) break;
|
||||
l2cap_request_can_send_now_event(sdp_server_l2cap_cid);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
@ -566,11 +566,11 @@ static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
|
||||
case L2CAP_EVENT_INCOMING_CONNECTION:
|
||||
if (l2cap_cid) {
|
||||
if (sdp_server_l2cap_cid) {
|
||||
// try to queue up
|
||||
if (l2cap_waiting_list_count < SDP_WAITING_LIST_MAX_COUNT){
|
||||
if (sdp_server_l2cap_waiting_list_count < SDP_WAITING_LIST_MAX_COUNT){
|
||||
sdp_waiting_list_add(channel);
|
||||
log_info("busy, queing incoming cid 0x%04x, now %u waiting", channel, l2cap_waiting_list_count);
|
||||
log_info("busy, queing incoming cid 0x%04x, now %u waiting", channel, sdp_server_l2cap_waiting_list_count);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -579,15 +579,15 @@ static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
break;
|
||||
}
|
||||
// accept
|
||||
l2cap_cid = channel;
|
||||
sdp_response_size = 0;
|
||||
l2cap_accept_connection(l2cap_cid);
|
||||
sdp_server_l2cap_cid = channel;
|
||||
sdp_server_response_size = 0;
|
||||
l2cap_accept_connection(sdp_server_l2cap_cid);
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
if (packet[2]) {
|
||||
// open failed -> reset
|
||||
l2cap_cid = 0;
|
||||
sdp_server_l2cap_cid = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -596,21 +596,21 @@ static void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||
if (channel == l2cap_cid){
|
||||
if (channel == sdp_server_l2cap_cid){
|
||||
// reset
|
||||
l2cap_cid = 0;
|
||||
sdp_server_l2cap_cid = 0;
|
||||
|
||||
// other request queued?
|
||||
if (!l2cap_waiting_list_count) break;
|
||||
if (!sdp_server_l2cap_waiting_list_count) break;
|
||||
|
||||
// get first item
|
||||
l2cap_cid = sdp_waiting_list_get();
|
||||
sdp_server_l2cap_cid = sdp_waiting_list_get();
|
||||
|
||||
log_info("disconnect, accept queued cid 0x%04x, now %u waiting", l2cap_cid, l2cap_waiting_list_count);
|
||||
log_info("disconnect, accept queued cid 0x%04x, now %u waiting", sdp_server_l2cap_cid, sdp_server_l2cap_waiting_list_count);
|
||||
|
||||
// accept connection
|
||||
sdp_response_size = 0;
|
||||
l2cap_accept_connection(l2cap_cid);
|
||||
sdp_server_response_size = 0;
|
||||
l2cap_accept_connection(sdp_server_l2cap_cid);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -67,8 +67,8 @@
|
||||
const char * const type_names[] = { "NIL", "UINT", "INT", "UUID", "STRING", "BOOL", "DES", "DEA", "URL"};
|
||||
#endif
|
||||
|
||||
static uint8_t des_serviceSearchPatternUUID16[] = {0x35, 0x03, 0x19, 0x00, 0x00};
|
||||
static uint8_t des_serviceSearchPatternUUID128[] = {
|
||||
static uint8_t des_service_search_pattern_uuid16[] = {0x35, 0x03, 0x19, 0x00, 0x00};
|
||||
static uint8_t des_service_search_pattern_uuid128[] = {
|
||||
0x35, 0x11, 0x1c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
@ -725,12 +725,12 @@ UNUSED(record);
|
||||
}
|
||||
|
||||
uint8_t* sdp_service_search_pattern_for_uuid16(uint16_t uuid16){
|
||||
big_endian_store_16(des_serviceSearchPatternUUID16, 3, uuid16);
|
||||
return (uint8_t*)des_serviceSearchPatternUUID16;
|
||||
big_endian_store_16(des_service_search_pattern_uuid16, 3, uuid16);
|
||||
return (uint8_t*)des_service_search_pattern_uuid16;
|
||||
}
|
||||
|
||||
uint8_t* sdp_service_search_pattern_for_uuid128(const uint8_t * uuid128){
|
||||
(void)memcpy(&des_serviceSearchPatternUUID128[3], uuid128, 16);
|
||||
return (uint8_t*)des_serviceSearchPatternUUID128;
|
||||
(void)memcpy(&des_service_search_pattern_uuid128[3], uuid128, 16);
|
||||
return (uint8_t*)des_service_search_pattern_uuid128;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ typedef enum {
|
||||
SDP_ServiceAttributeResponse,
|
||||
SDP_ServiceSearchAttributeRequest,
|
||||
SDP_ServiceSearchAttributeResponse
|
||||
} SDP_PDU_ID_t;
|
||||
} sdp_pdu_id_t;
|
||||
|
||||
|
||||
/* API_START */
|
||||
|
Loading…
x
Reference in New Issue
Block a user