sdp_util.c (7907f06931c075b55e3402fa469abbe35eebee25) | sdp_util.c (f8fbdce0c5067e7e7edd3a29934b1f9b79c8ff2d) |
---|---|
1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 72 unchanged lines hidden (view full) --- 81 uint32_t result = 0; 82 de_type_t de_type = de_get_element_type(header); 83 de_size_t de_size = de_get_size_type(header); 84 switch (de_size){ 85 case DE_SIZE_VAR_8: 86 result = header[1]; 87 break; 88 case DE_SIZE_VAR_16: | 1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 72 unchanged lines hidden (view full) --- 81 uint32_t result = 0; 82 de_type_t de_type = de_get_element_type(header); 83 de_size_t de_size = de_get_size_type(header); 84 switch (de_size){ 85 case DE_SIZE_VAR_8: 86 result = header[1]; 87 break; 88 case DE_SIZE_VAR_16: |
89 result = READ_NET_16(header,1); | 89 result = big_endian_read_16(header,1); |
90 break; 91 case DE_SIZE_VAR_32: | 90 break; 91 case DE_SIZE_VAR_32: |
92 result = READ_NET_32(header,1); | 92 result = bit_endian_read_32(header,1); |
93 break; 94 default: 95 // case DE_SIZE_8: 96 // case DE_SIZE_16: 97 // case DE_SIZE_32: 98 // case DE_SIZE_64: 99 // case DE_SIZE_128: 100 if (de_type == DE_NIL) return 0; --- 4 unchanged lines hidden (view full) --- 105 106int de_get_len(uint8_t *header){ 107 return de_get_header_size(header) + de_get_data_size(header); 108} 109 110// @returns OK, if UINT16 value was read 111int de_element_get_uint16(uint8_t * element, uint16_t * value){ 112 if (de_get_size_type(element) != DE_SIZE_16) return 0; | 93 break; 94 default: 95 // case DE_SIZE_8: 96 // case DE_SIZE_16: 97 // case DE_SIZE_32: 98 // case DE_SIZE_64: 99 // case DE_SIZE_128: 100 if (de_type == DE_NIL) return 0; --- 4 unchanged lines hidden (view full) --- 105 106int de_get_len(uint8_t *header){ 107 return de_get_header_size(header) + de_get_data_size(header); 108} 109 110// @returns OK, if UINT16 value was read 111int de_element_get_uint16(uint8_t * element, uint16_t * value){ 112 if (de_get_size_type(element) != DE_SIZE_16) return 0; |
113 *value = READ_NET_16(element, de_get_header_size(element)); | 113 *value = big_endian_read_16(element, de_get_header_size(element)); |
114 return 1; 115} 116 117// @returns: element is valid UUID 118int de_get_normalized_uuid(uint8_t *uuid128, uint8_t *element){ 119 de_type_t uuidType = de_get_element_type(element); 120 de_size_t uuidSize = de_get_size_type(element); 121 if (uuidType != DE_UUID) return 0; 122 uint32_t shortUUID; 123 switch (uuidSize){ 124 case DE_SIZE_16: | 114 return 1; 115} 116 117// @returns: element is valid UUID 118int de_get_normalized_uuid(uint8_t *uuid128, uint8_t *element){ 119 de_type_t uuidType = de_get_element_type(element); 120 de_size_t uuidSize = de_get_size_type(element); 121 if (uuidType != DE_UUID) return 0; 122 uint32_t shortUUID; 123 switch (uuidSize){ 124 case DE_SIZE_16: |
125 shortUUID = READ_NET_16(element, 1); | 125 shortUUID = big_endian_read_16(element, 1); |
126 break; 127 case DE_SIZE_32: | 126 break; 127 case DE_SIZE_32: |
128 shortUUID = READ_NET_32(element, 1); | 128 shortUUID = bit_endian_read_32(element, 1); |
129 break; 130 case DE_SIZE_128: 131 memcpy(uuid128, element+1, 16); 132 return 1; 133 default: 134 return 0; 135 } 136 sdp_normalize_uuid(uuid128, shortUUID); 137 return 1; 138} 139 140// @returns 0 if no UUID16 or UUID32 is present, and UUID32 otherwise 141uint32_t de_get_uuid32(uint8_t * element){ 142 uint8_t uuid128[16]; 143 int validUuid128 = de_get_normalized_uuid(uuid128, element); 144 if (!validUuid128) return 0; 145 int hasBlueoothBaseUuid = sdp_has_blueooth_base_uuid(uuid128); 146 if (!hasBlueoothBaseUuid) return 0; | 129 break; 130 case DE_SIZE_128: 131 memcpy(uuid128, element+1, 16); 132 return 1; 133 default: 134 return 0; 135 } 136 sdp_normalize_uuid(uuid128, shortUUID); 137 return 1; 138} 139 140// @returns 0 if no UUID16 or UUID32 is present, and UUID32 otherwise 141uint32_t de_get_uuid32(uint8_t * element){ 142 uint8_t uuid128[16]; 143 int validUuid128 = de_get_normalized_uuid(uuid128, element); 144 if (!validUuid128) return 0; 145 int hasBlueoothBaseUuid = sdp_has_blueooth_base_uuid(uuid128); 146 if (!hasBlueoothBaseUuid) return 0; |
147 return READ_NET_32(uuid128, 0); | 147 return bit_endian_read_32(uuid128, 0); |
148} 149 150// functions to create record 151static void de_store_descriptor(uint8_t * header, de_type_t type, de_size_t size){ 152 header[0] = (type << 3) | size; 153} 154 155void de_store_descriptor_with_len(uint8_t * header, de_type_t type, de_size_t size, uint32_t len){ 156 header[0] = (type << 3) | size; 157 switch (size){ 158 case DE_SIZE_VAR_8: 159 header[1] = len; 160 break; 161 case DE_SIZE_VAR_16: | 148} 149 150// functions to create record 151static void de_store_descriptor(uint8_t * header, de_type_t type, de_size_t size){ 152 header[0] = (type << 3) | size; 153} 154 155void de_store_descriptor_with_len(uint8_t * header, de_type_t type, de_size_t size, uint32_t len){ 156 header[0] = (type << 3) | size; 157 switch (size){ 158 case DE_SIZE_VAR_8: 159 header[1] = len; 160 break; 161 case DE_SIZE_VAR_16: |
162 net_store_16(header, 1, len); | 162 big_endian_store_16(header, 1, len); |
163 break; 164 case DE_SIZE_VAR_32: | 163 break; 164 case DE_SIZE_VAR_32: |
165 net_store_32(header, 1, len); | 165 big_endian_store_32(header, 1, len); |
166 break; 167 default: 168 break; 169 } 170} 171 172// MARK: DataElement creation 173 --- 7 unchanged lines hidden (view full) --- 181 int element_len = de_get_len(header); 182 de_store_descriptor_with_len(header+element_len, DE_DES, DE_SIZE_VAR_16, 0); // DES, 2 Byte Length 183 return header + element_len; 184} 185 186/* closes the current sequence and updates the parent sequence */ 187void de_pop_sequence(uint8_t * parent, uint8_t * child){ 188 int child_len = de_get_len(child); | 166 break; 167 default: 168 break; 169 } 170} 171 172// MARK: DataElement creation 173 --- 7 unchanged lines hidden (view full) --- 181 int element_len = de_get_len(header); 182 de_store_descriptor_with_len(header+element_len, DE_DES, DE_SIZE_VAR_16, 0); // DES, 2 Byte Length 183 return header + element_len; 184} 185 186/* closes the current sequence and updates the parent sequence */ 187void de_pop_sequence(uint8_t * parent, uint8_t * child){ 188 int child_len = de_get_len(child); |
189 int data_size_parent = READ_NET_16(parent,1); 190 net_store_16(parent, 1, data_size_parent + child_len); | 189 int data_size_parent = big_endian_read_16(parent,1); 190 big_endian_store_16(parent, 1, data_size_parent + child_len); |
191} 192 193/* adds a single number value and 16+32 bit UUID to the sequence */ 194void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value){ | 191} 192 193/* adds a single number value and 16+32 bit UUID to the sequence */ 194void de_add_number(uint8_t *seq, de_type_t type, de_size_t size, uint32_t value){ |
195 int data_size = READ_NET_16(seq,1); | 195 int data_size = big_endian_read_16(seq,1); |
196 int element_size = 1; // e.g. for DE_TYPE_NIL 197 de_store_descriptor(seq+3+data_size, type, size); 198 switch (size){ 199 case DE_SIZE_8: 200 if (type != DE_NIL){ 201 seq[4+data_size] = value; 202 element_size = 2; 203 } 204 break; 205 case DE_SIZE_16: | 196 int element_size = 1; // e.g. for DE_TYPE_NIL 197 de_store_descriptor(seq+3+data_size, type, size); 198 switch (size){ 199 case DE_SIZE_8: 200 if (type != DE_NIL){ 201 seq[4+data_size] = value; 202 element_size = 2; 203 } 204 break; 205 case DE_SIZE_16: |
206 net_store_16(seq, 4+data_size, value); | 206 big_endian_store_16(seq, 4+data_size, value); |
207 element_size = 3; 208 break; 209 case DE_SIZE_32: | 207 element_size = 3; 208 break; 209 case DE_SIZE_32: |
210 net_store_32(seq, 4+data_size, value); | 210 big_endian_store_32(seq, 4+data_size, value); |
211 element_size = 5; 212 break; 213 default: 214 break; 215 } | 211 element_size = 5; 212 break; 213 default: 214 break; 215 } |
216 net_store_16(seq, 1, data_size+element_size); | 216 big_endian_store_16(seq, 1, data_size+element_size); |
217} 218 219/* add a single block of data, e.g. as DE_STRING, DE_URL */ 220void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data){ | 217} 218 219/* add a single block of data, e.g. as DE_STRING, DE_URL */ 220void de_add_data( uint8_t *seq, de_type_t type, uint16_t size, uint8_t *data){ |
221 int data_size = READ_NET_16(seq,1); | 221 int data_size = big_endian_read_16(seq,1); |
222 if (size > 0xff) { 223 // use 16-bit lengh information (3 byte header) 224 de_store_descriptor_with_len(seq+3+data_size, type, DE_SIZE_VAR_16, size); 225 data_size += 3; 226 } else { 227 // use 8-bit lengh information (2 byte header) 228 de_store_descriptor_with_len(seq+3+data_size, type, DE_SIZE_VAR_8, size); 229 data_size += 2; 230 } 231 memcpy( seq + 3 + data_size, data, size); 232 data_size += size; | 222 if (size > 0xff) { 223 // use 16-bit lengh information (3 byte header) 224 de_store_descriptor_with_len(seq+3+data_size, type, DE_SIZE_VAR_16, size); 225 data_size += 3; 226 } else { 227 // use 8-bit lengh information (2 byte header) 228 de_store_descriptor_with_len(seq+3+data_size, type, DE_SIZE_VAR_8, size); 229 data_size += 2; 230 } 231 memcpy( seq + 3 + data_size, data, size); 232 data_size += size; |
233 net_store_16(seq, 1, data_size); | 233 big_endian_store_16(seq, 1, data_size); |
234} 235 236void de_add_uuid128(uint8_t * seq, uint8_t * uuid){ | 234} 235 236void de_add_uuid128(uint8_t * seq, uint8_t * uuid){ |
237 int data_size = READ_NET_16(seq,1); | 237 int data_size = big_endian_read_16(seq,1); |
238 de_store_descriptor(seq+3+data_size, DE_UUID, DE_SIZE_128); 239 memcpy( seq + 4 + data_size, uuid, 16); | 238 de_store_descriptor(seq+3+data_size, DE_UUID, DE_SIZE_128); 239 memcpy( seq + 4 + data_size, uuid, 16); |
240 net_store_16(seq, 1, data_size+1+16); | 240 big_endian_store_16(seq, 1, data_size+1+16); |
241} 242 243// MARK: DES iterator 244int des_iterator_init(des_iterator_t * it, uint8_t * element){ 245 de_type_t type = de_get_element_type(element); 246 if (type != DE_DES) return 0; 247 248 it->element = element; --- 50 unchanged lines hidden (view full) --- 299 de_type_t type = de_get_element_type(element); 300 if (type != DE_DES) return; 301 int pos = de_get_header_size(element); 302 int end_pos = de_get_len(element); 303 while (pos < end_pos){ 304 de_type_t idType = de_get_element_type(element + pos); 305 de_size_t idSize = de_get_size_type(element + pos); 306 if (idType != DE_UINT || idSize != DE_SIZE_16) break; // wrong type | 241} 242 243// MARK: DES iterator 244int des_iterator_init(des_iterator_t * it, uint8_t * element){ 245 de_type_t type = de_get_element_type(element); 246 if (type != DE_DES) return 0; 247 248 it->element = element; --- 50 unchanged lines hidden (view full) --- 299 de_type_t type = de_get_element_type(element); 300 if (type != DE_DES) return; 301 int pos = de_get_header_size(element); 302 int end_pos = de_get_len(element); 303 while (pos < end_pos){ 304 de_type_t idType = de_get_element_type(element + pos); 305 de_size_t idSize = de_get_size_type(element + pos); 306 if (idType != DE_UINT || idSize != DE_SIZE_16) break; // wrong type |
307 uint16_t attribute_id = READ_NET_16(element, pos + 1); | 307 uint16_t attribute_id = big_endian_read_16(element, pos + 1); |
308 pos += 3; 309 if (pos >= end_pos) break; // array out of bounds 310 de_type_t valueType = de_get_element_type(element + pos); 311 de_size_t valueSize = de_get_size_type(element + pos); 312 uint8_t done = (*handler)(attribute_id, element + pos, valueType, valueSize, context); 313 if (done) break; 314 pos += de_get_len(element + pos); 315 } --- 6 unchanged lines hidden (view full) --- 322 int result; 323 uint16_t attributeID; 324}; 325static int sdp_traversal_attributeID_search(uint8_t * element, de_type_t type, de_size_t size, void *my_context){ 326 struct sdp_context_attributeID_search * context = (struct sdp_context_attributeID_search *) my_context; 327 if (type != DE_UINT) return 0; 328 switch (size) { 329 case DE_SIZE_16: | 308 pos += 3; 309 if (pos >= end_pos) break; // array out of bounds 310 de_type_t valueType = de_get_element_type(element + pos); 311 de_size_t valueSize = de_get_size_type(element + pos); 312 uint8_t done = (*handler)(attribute_id, element + pos, valueType, valueSize, context); 313 if (done) break; 314 pos += de_get_len(element + pos); 315 } --- 6 unchanged lines hidden (view full) --- 322 int result; 323 uint16_t attributeID; 324}; 325static int sdp_traversal_attributeID_search(uint8_t * element, de_type_t type, de_size_t size, void *my_context){ 326 struct sdp_context_attributeID_search * context = (struct sdp_context_attributeID_search *) my_context; 327 if (type != DE_UINT) return 0; 328 switch (size) { 329 case DE_SIZE_16: |
330 if (READ_NET_16(element, 1) == context->attributeID) { | 330 if (big_endian_read_16(element, 1) == context->attributeID) { |
331 context->result = 1; 332 return 1; 333 } 334 break; 335 case DE_SIZE_32: | 331 context->result = 1; 332 return 1; 333 } 334 break; 335 case DE_SIZE_32: |
336 if (READ_NET_16(element, 1) <= context->attributeID 337 && context->attributeID <= READ_NET_16(element, 3)) { | 336 if (big_endian_read_16(element, 1) <= context->attributeID 337 && context->attributeID <= big_endian_read_16(element, 3)) { |
338 context->result = 1; 339 return 1; 340 } 341 break; 342 default: 343 break; 344 } 345 return 0; --- 16 unchanged lines hidden (view full) --- 362 uint16_t usedBytes; 363 uint8_t *attributeIDList; 364}; 365 366static int sdp_traversal_append_attributes(uint16_t attributeID, uint8_t * attributeValue, de_type_t type, de_size_t size, void *my_context){ 367 struct sdp_context_append_attributes * context = (struct sdp_context_append_attributes *) my_context; 368 if (sdp_attribute_list_constains_id(context->attributeIDList, attributeID)) { 369 // DES_HEADER(3) + DES_DATA + (UINT16(3) + attribute) | 338 context->result = 1; 339 return 1; 340 } 341 break; 342 default: 343 break; 344 } 345 return 0; --- 16 unchanged lines hidden (view full) --- 362 uint16_t usedBytes; 363 uint8_t *attributeIDList; 364}; 365 366static int sdp_traversal_append_attributes(uint16_t attributeID, uint8_t * attributeValue, de_type_t type, de_size_t size, void *my_context){ 367 struct sdp_context_append_attributes * context = (struct sdp_context_append_attributes *) my_context; 368 if (sdp_attribute_list_constains_id(context->attributeIDList, attributeID)) { 369 // DES_HEADER(3) + DES_DATA + (UINT16(3) + attribute) |
370 uint16_t data_size = READ_NET_16(context->buffer, 1); | 370 uint16_t data_size = big_endian_read_16(context->buffer, 1); |
371 int attribute_len = de_get_len(attributeValue); 372 if (3 + data_size + (3 + attribute_len) <= context->maxBytes) { 373 // copy Attribute 374 de_add_number(context->buffer, DE_UINT, DE_SIZE_16, attributeID); 375 data_size += 3; // 3 bytes 376 memcpy(context->buffer + 3 + data_size, attributeValue, attribute_len); | 371 int attribute_len = de_get_len(attributeValue); 372 if (3 + data_size + (3 + attribute_len) <= context->maxBytes) { 373 // copy Attribute 374 de_add_number(context->buffer, DE_UINT, DE_SIZE_16, attributeID); 375 data_size += 3; // 3 bytes 376 memcpy(context->buffer + 3 + data_size, attributeValue, attribute_len); |
377 net_store_16(context->buffer,1,data_size+attribute_len); | 377 big_endian_store_16(context->buffer,1,data_size+attribute_len); |
378 } else { 379 // not enought space left -> continue with previous element 380 return 1; 381 } 382 } 383 return 0; 384} 385 --- 43 unchanged lines hidden (view full) --- 429 // { Attribute ID (Descriptor, big endian 16-bit ID), AttributeValue (data)} 430 431 // handle Attribute ID 432 if (context->startOffset >= 3){ 433 context->startOffset -= 3; 434 } else { 435 uint8_t idBuffer[3]; 436 de_store_descriptor(idBuffer, DE_UINT, DE_SIZE_16); | 378 } else { 379 // not enought space left -> continue with previous element 380 return 1; 381 } 382 } 383 return 0; 384} 385 --- 43 unchanged lines hidden (view full) --- 429 // { Attribute ID (Descriptor, big endian 16-bit ID), AttributeValue (data)} 430 431 // handle Attribute ID 432 if (context->startOffset >= 3){ 433 context->startOffset -= 3; 434 } else { 435 uint8_t idBuffer[3]; 436 de_store_descriptor(idBuffer, DE_UINT, DE_SIZE_16); |
437 net_store_16(idBuffer,1,attributeID); | 437 big_endian_store_16(idBuffer,1,attributeID); |
438 439 int ok = spd_append_range(context, 3, idBuffer); 440 if (!ok) { 441 context->complete = 0; 442 return 1; 443 } 444 } 445 --- 85 unchanged lines hidden (view full) --- 531 context->attributeFound = 1; 532 switch (size){ 533 case DE_SIZE_8: 534 if (attributeType != DE_NIL){ 535 attributeValue[1] = context->attributeValue; 536 } 537 break; 538 case DE_SIZE_16: | 438 439 int ok = spd_append_range(context, 3, idBuffer); 440 if (!ok) { 441 context->complete = 0; 442 return 1; 443 } 444 } 445 --- 85 unchanged lines hidden (view full) --- 531 context->attributeFound = 1; 532 switch (size){ 533 case DE_SIZE_8: 534 if (attributeType != DE_NIL){ 535 attributeValue[1] = context->attributeValue; 536 } 537 break; 538 case DE_SIZE_16: |
539 net_store_16(attributeValue, 1, context->attributeValue); | 539 big_endian_store_16(attributeValue, 1, context->attributeValue); |
540 break; 541 case DE_SIZE_32: | 540 break; 541 case DE_SIZE_32: |
542 net_store_32(attributeValue, 1, context->attributeValue); | 542 big_endian_store_32(attributeValue, 1, context->attributeValue); |
543 break; 544 // Might want to support STRINGS to, copy upto original length 545 default: 546 break; 547 } 548 return 1; 549 } 550 return 0; --- 81 unchanged lines hidden (view full) --- 632 printf("\n"); 633 } else if (de_type == DE_STRING) { 634 int len = 0; 635 switch (de_size){ 636 case DE_SIZE_VAR_8: 637 len = element[1]; 638 break; 639 case DE_SIZE_VAR_16: | 543 break; 544 // Might want to support STRINGS to, copy upto original length 545 default: 546 break; 547 } 548 return 1; 549 } 550 return 0; --- 81 unchanged lines hidden (view full) --- 632 printf("\n"); 633 } else if (de_type == DE_STRING) { 634 int len = 0; 635 switch (de_size){ 636 case DE_SIZE_VAR_8: 637 len = element[1]; 638 break; 639 case DE_SIZE_VAR_16: |
640 len = READ_NET_16(element, 1); | 640 len = big_endian_read_16(element, 1); |
641 break; 642 default: 643 break; 644 } 645 printf("len %u (0x%02x)\n", len, len); 646 printf_hexdump(&element[pos], len); 647 } else { 648 uint32_t value = 0; 649 switch (de_size) { 650 case DE_SIZE_8: 651 if (de_type != DE_NIL){ 652 value = element[pos]; 653 } 654 break; 655 case DE_SIZE_16: | 641 break; 642 default: 643 break; 644 } 645 printf("len %u (0x%02x)\n", len, len); 646 printf_hexdump(&element[pos], len); 647 } else { 648 uint32_t value = 0; 649 switch (de_size) { 650 case DE_SIZE_8: 651 if (de_type != DE_NIL){ 652 value = element[pos]; 653 } 654 break; 655 case DE_SIZE_16: |
656 value = READ_NET_16(element,pos); | 656 value = big_endian_read_16(element,pos); |
657 break; 658 case DE_SIZE_32: | 657 break; 658 case DE_SIZE_32: |
659 value = READ_NET_32(element,pos); | 659 value = bit_endian_read_32(element,pos); |
660 break; 661 default: 662 break; 663 } 664 printf(", value: 0x%08" PRIx32 "\n", value); 665 } 666 return 0; 667} --- 83 unchanged lines hidden --- | 660 break; 661 default: 662 break; 663 } 664 printf(", value: 0x%08" PRIx32 "\n", value); 665 } 666 return 0; 667} --- 83 unchanged lines hidden --- |