mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 13:20:39 +00:00
AttributeList is sequence of alternative AttributeID,AttributeValue item not sequence of sequences that contain tuples
This commit is contained in:
parent
e608d2e056
commit
af8a029a59
73
src/sdp.c
73
src/sdp.c
@ -76,7 +76,7 @@ void sdp_init(){
|
||||
}
|
||||
|
||||
uint32_t sdp_get_service_record_handle(uint8_t * record){
|
||||
uint8_t * serviceRecordHandleAttribute = sdp_get_attribute_value_for_attribute_id(record, 0x0000);
|
||||
uint8_t * serviceRecordHandleAttribute = sdp_get_attribute_value_for_attribute_id(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;
|
||||
@ -132,8 +132,8 @@ uint32_t sdp_register_service_internal(connection_t *connection, uint8_t * recor
|
||||
}
|
||||
|
||||
// calculate size of new service record: DES (2 byte len)
|
||||
// + ServiceRecordHandle attribute (DES UINT16 UINT32) + size of existing attributes
|
||||
uint16_t recordSize = 3 + (3 + 3 + 5) + de_get_data_size(record);
|
||||
// + 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));
|
||||
@ -152,16 +152,14 @@ uint32_t sdp_register_service_internal(connection_t *connection, uint8_t * recor
|
||||
de_create_sequence(newRecord);
|
||||
|
||||
// set service record handle
|
||||
uint8_t * serviceRecordHandleAttribute = de_push_sequence(newRecord);
|
||||
de_add_number(serviceRecordHandleAttribute, DE_UINT, DE_SIZE_16, 0);
|
||||
de_add_number(serviceRecordHandleAttribute, DE_UINT, DE_SIZE_32, record_handle);
|
||||
de_pop_sequence(newRecord, serviceRecordHandleAttribute);
|
||||
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);
|
||||
de_dump_data_element(newRecord);
|
||||
// printf("reserved size %u, actual size %u\n", recordSize, de_get_len(newRecord));
|
||||
|
||||
// add to linked list
|
||||
@ -369,6 +367,7 @@ int sdp_handle_service_search_attribute_request(uint8_t * packet){
|
||||
uint16_t attributeListsSize = de_get_len(attributeLists);
|
||||
if (attributeListsSize + 3 > maximumAttributeByteCount) {
|
||||
continuation = 1;
|
||||
continuation_service_index = current_service_index;
|
||||
continuation_attribute_index = 0;
|
||||
break;
|
||||
}
|
||||
@ -382,12 +381,13 @@ int sdp_handle_service_search_attribute_request(uint8_t * packet){
|
||||
// no space left?
|
||||
if (result >= 0){
|
||||
continuation = 1;
|
||||
continuation_service_index = current_service_index;
|
||||
continuation_attribute_index = (uint16_t) result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_service_index++;
|
||||
}
|
||||
pos += de_get_len(attributeLists);
|
||||
|
||||
@ -486,49 +486,22 @@ static void dump_service_search_response(){
|
||||
void sdp_test(){
|
||||
|
||||
// create two records with 2 attributes each
|
||||
uint8_t *attribute;
|
||||
|
||||
de_create_sequence(record);
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_32, 0x10001);
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
|
||||
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList);
|
||||
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_32, 0x10001);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
|
||||
de_add_number(record, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList);
|
||||
de_add_number(record, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
uint32_t handle_1 = sdp_register_service_internal(NULL, record);
|
||||
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_32, 0x10002);
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
|
||||
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x0002);
|
||||
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
attribute = de_push_sequence(record);
|
||||
{
|
||||
de_add_number(attribute, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList);
|
||||
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
}
|
||||
de_pop_sequence(record, attribute);
|
||||
de_create_sequence(record);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_32, 0x10002);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
|
||||
de_add_number(record, DE_UUID, DE_SIZE_16, 0x0002);
|
||||
de_add_number(record, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList);
|
||||
de_add_number(record, DE_UUID, DE_SIZE_16, 0x0001);
|
||||
uint32_t handle_2 = sdp_register_service_internal(NULL, record);
|
||||
|
||||
// sdp_handle_service_search_request
|
||||
@ -555,7 +528,7 @@ void sdp_test(){
|
||||
request[0] = SDP_ServiceAttributeRequest;
|
||||
net_store_16(request, 1, transactionID++); // transaction ID
|
||||
net_store_32(request, 5, handle_1); // record handle
|
||||
net_store_16(request, 9, 15); // max bytes
|
||||
net_store_16(request, 9, 200); // max bytes
|
||||
uint8_t * attributeIDList = request + 11;
|
||||
de_create_sequence(attributeIDList);
|
||||
de_add_number(attributeIDList, DE_UINT, DE_SIZE_32, 0x0000ffff);
|
||||
|
@ -202,6 +202,9 @@ void de_add_uuid128(uint8_t * seq, uint8_t * uuid){
|
||||
net_store_16(seq, 1, data_size+1+16);
|
||||
}
|
||||
|
||||
void sdp_add_attribute(uint8_t *seq, uint16_t attributeID, uint8_t attributeValue){
|
||||
}
|
||||
|
||||
#pragma mark DataElementSequence traversal
|
||||
typedef int (*de_traversal_callback_t)(uint8_t * element, de_type_t type, de_size_t size, void *context);
|
||||
static void de_traverse_sequence(uint8_t * element, de_traversal_callback_t handler, void *context){
|
||||
@ -259,31 +262,40 @@ int sdp_attribute_list_constains_id(uint8_t *attributeIDList, uint16_t attribute
|
||||
// pre: buffer contains DES with 2 byte length field
|
||||
struct sdp_context_append_attributes {
|
||||
uint8_t * buffer;
|
||||
uint16_t dataSize;
|
||||
uint16_t startIndex; // index of first to examine
|
||||
uint16_t attributeIndex; // index over list
|
||||
uint16_t maxBytes;
|
||||
uint8_t *attributeIDList;
|
||||
uint8_t currentAttributeID;
|
||||
uint8_t copyAttributeValue;
|
||||
uint8_t moreData; // extra data: attributeIndex has to be examined next
|
||||
};
|
||||
static int sdp_traversal_append_attributes(uint8_t * element, de_type_t type, de_size_t size, void *my_context){
|
||||
struct sdp_context_append_attributes * context = (struct sdp_context_append_attributes *) my_context;
|
||||
// check each Attribute in root DES
|
||||
int attributeLen = de_get_len(element);
|
||||
// Attribute must be DES with more than sizeof(UINT16 element) and index at least continuation index
|
||||
if (type == DE_DES && context->attributeIndex >= context->startIndex){
|
||||
int attributeIDPos = de_get_header_size(element);
|
||||
de_size_t attributeIDSize = de_get_size_type(element+attributeIDPos);
|
||||
if (attributeIDSize == DE_SIZE_16) {
|
||||
uint16_t attributeID = READ_NET_16(element, attributeIDPos+1);
|
||||
if ( sdp_attribute_list_constains_id(context->attributeIDList, attributeID)){
|
||||
if (3 + context->dataSize + attributeLen <= context->maxBytes) {
|
||||
if (context->attributeIndex >= context->startIndex) {
|
||||
// handle odd/even attribute index: even is AttributeID, odd is AttributeValue
|
||||
if ( (context->attributeIndex & 1) == 0){
|
||||
if (type == DE_UINT && size == DE_SIZE_16){
|
||||
context->currentAttributeID = READ_NET_16(element, 1);
|
||||
context->copyAttributeValue = sdp_attribute_list_constains_id(context->attributeIDList, context->currentAttributeID);
|
||||
} else {
|
||||
context->copyAttributeValue = 0;
|
||||
}
|
||||
} else {
|
||||
// DES_HEADER(3) + DES_DATA + (UINT16(3) + attribute)
|
||||
if (context->copyAttributeValue) {
|
||||
uint16_t data_size = READ_NET_16(context->buffer, 1);
|
||||
int attribute_len = de_get_len(element);
|
||||
if (3 + data_size + (3 + attribute_len) <= context->maxBytes) {
|
||||
// copy Attribute
|
||||
memcpy( context->buffer + 3 + context->dataSize, element, attributeLen);
|
||||
context->dataSize += attributeLen;
|
||||
de_add_number(context->buffer, DE_UINT, DE_SIZE_16, context->currentAttributeID);
|
||||
data_size += 3; // 3 bytes
|
||||
memcpy(context->buffer + 3 + data_size, element, attribute_len);
|
||||
net_store_16(context->buffer,1,data_size+attribute_len);
|
||||
} else {
|
||||
// not enought space left -> continuation
|
||||
// not enought space left -> continue with previous element
|
||||
context->moreData = 1;
|
||||
context->attributeIndex--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -297,14 +309,12 @@ static int sdp_traversal_append_attributes(uint8_t * element, de_type_t type, de
|
||||
int sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attributeIDList, uint16_t startIndex, uint16_t maxBytes, uint8_t *buffer){
|
||||
struct sdp_context_append_attributes context;
|
||||
context.buffer = buffer;
|
||||
context.dataSize = READ_NET_16(buffer, 1);
|
||||
context.maxBytes = maxBytes;
|
||||
context.attributeIndex = 0;
|
||||
context.startIndex = startIndex;
|
||||
context.moreData = 0;
|
||||
context.attributeIDList = attributeIDList;
|
||||
de_traverse_sequence(record, sdp_traversal_append_attributes, &context);
|
||||
net_store_16(buffer, 1, context.dataSize);
|
||||
if (context.moreData) {
|
||||
return context.attributeIndex;
|
||||
}
|
||||
@ -317,25 +327,24 @@ int sdp_append_attributes_in_attributeIDList(uint8_t *record, uint8_t *attribute
|
||||
struct sdp_context_attribute_by_id {
|
||||
uint16_t attributeID;
|
||||
uint8_t * attributeValue;
|
||||
uint8_t attributeFound;
|
||||
uint16_t index;
|
||||
};
|
||||
static int sdp_traversal_attribute_by_id(uint8_t * element, de_type_t attributeType, de_size_t size, void *my_context){
|
||||
struct sdp_context_attribute_by_id * context = (struct sdp_context_attribute_by_id *) my_context;
|
||||
|
||||
// check each Attribute in root DES
|
||||
int attributeDataSize = de_get_data_size(element);
|
||||
int attributeLen = de_get_len(element);
|
||||
// Attribute must be DES with more than sizeof(UINT16 element)
|
||||
if (attributeType == DE_DES && attributeDataSize >= 3){
|
||||
int attributeIDPos = de_get_header_size(element);
|
||||
de_size_t attributeIDSize = de_get_size_type(element+attributeIDPos);
|
||||
if (attributeIDSize == DE_SIZE_16) {
|
||||
uint16_t attributeID = READ_NET_16(element,attributeIDPos+1);
|
||||
if (context->attributeID == attributeID && attributeIDPos < attributeLen){
|
||||
context->attributeValue = element + attributeIDPos+3;
|
||||
return 1;
|
||||
if ((context->index & 1) == 0) {
|
||||
if (attributeType == DE_UINT && size == DE_SIZE_16){
|
||||
if (READ_NET_16(element, 1) == context->attributeID){
|
||||
context->attributeFound = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (context->attributeFound) {
|
||||
context->attributeValue = element;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
context->index++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -343,6 +352,8 @@ uint8_t * sdp_get_attribute_value_for_attribute_id(uint8_t * record, uint16_t at
|
||||
struct sdp_context_attribute_by_id context;
|
||||
context.attributeValue = NULL;
|
||||
context.attributeID = attributeID;
|
||||
context.attributeFound = 0;
|
||||
context.index = 0;
|
||||
de_traverse_sequence(record, sdp_traversal_attribute_by_id, &context);
|
||||
return context.attributeValue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user