xref: /btstack/test/sdp/sdp_record_builder.cpp (revision a64cbea79fa5fb9daa58e135a19c6cce10f3e642)
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
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 // *****************************************************************************
39 //
40 // test calculation of sdp records created by various profiles
41 //
42 // *****************************************************************************
43 
44 
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include "CppUTest/TestHarness.h"
51 #include "CppUTest/CommandLineTestRunner.h"
52 
53 #include "classic/avrcp_controller.h"
54 
55 #include "btstack_util.h"
56 #include "bluetooth.h"
57 
58 #include "classic/device_id_server.h"
59 #include "classic/avrcp_target.h"
60 #include "classic/a2dp_source.h"
61 #include "classic/a2dp_sink.h"
62 #include "classic/hsp_hs.h"
63 #include "classic/hsp_ag.h"
64 #include "classic/hfp_hf.h"
65 #include "classic/hfp_ag.h"
66 #include "classic/hid_device.h"
67 #include "classic/pan.h"
68 #include "classic/spp_server.h"
69 #include "classic/sdp_util.h"
70 
71 static uint8_t service_buffer[300];
72 static const char * test_string = "test";
73 static const uint16_t uint16_list_empty[] = { 0 };
74 static const uint16_t uint16_list_single_element[] = { 0x1234, 0 };
75 
76 TEST_GROUP(SDPRecordBuilder){
77     void setup(void){
78         memset(service_buffer, 0, sizeof(service_buffer));
79     }
80 };
81 
82 // a2dp sink
83 
84 static const char * default_a2dp_sink_service_name = "BTstack A2DP Sink Service";
85 static const char * default_a2dp_sink_service_provider_name = "BTstack A2DP Sink Service Provider";
86 
87 #define A2DP_SINK_RECORD_SIZE_MIN 84
88 
89 static uint16_t a2dp_sink_record_size(const char * service_name, const char * service_provider_name){
90     int service_name_len           = service_name           ? strlen(service_name)          : strlen(default_a2dp_sink_service_name);
91     int service_provider_name_len  = service_provider_name  ? strlen(service_provider_name) : strlen(default_a2dp_sink_service_provider_name);
92     return A2DP_SINK_RECORD_SIZE_MIN + service_name_len + service_provider_name_len;
93 }
94 
95 TEST(SDPRecordBuilder, A2DP_SINK){
96     const char * service_name;
97     const char * service_provider_name;
98     int expected_len;
99 
100     service_name = "";
101     service_provider_name = "";
102     expected_len = a2dp_sink_record_size(service_name, service_provider_name);
103     a2dp_sink_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
104     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
105 }
106 
107 // a2dp source
108 
109 static const char * default_a2dp_source_service_name = "BTstack A2DP Source Service";
110 static const char * default_a2dp_source_service_provider_name = "BTstack A2DP Source Service Provider";
111 
112 #define A2DP_SOURCE_RECORD_SIZE_MIN 84
113 
114 static uint16_t a2dp_source_record_size(const char * service_name, const char * service_provider_name){
115     int service_name_len           = service_name           ? strlen(service_name)          : strlen(default_a2dp_source_service_name);
116     int service_provider_name_len  = service_provider_name  ? strlen(service_provider_name) : strlen(default_a2dp_source_service_provider_name);
117     return A2DP_SOURCE_RECORD_SIZE_MIN + service_name_len + service_provider_name_len;
118 }
119 
120 TEST(SDPRecordBuilder, A2DP_SOURCE){
121     const char * service_name;
122     const char * service_provider_name;
123     int expected_len;
124 
125     service_name = "";
126     service_provider_name = "";
127     expected_len = a2dp_source_record_size(service_name, service_provider_name);
128     a2dp_source_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
129     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
130 
131     service_name = NULL;
132     service_provider_name = "";
133     expected_len = a2dp_source_record_size(service_name, service_provider_name);
134     a2dp_source_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
135     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
136 
137     service_name = NULL;
138     service_provider_name = NULL;
139     expected_len = a2dp_source_record_size(service_name, service_provider_name);
140     a2dp_source_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
141     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
142 }
143 
144 //
145 // avcrp target
146 //
147 
148 static const char * default_avrcp_target_service_name = "BTstack AVRCP Target Service";
149 static const char * default_avrcp_target_service_provider_name = "BTstack AVRCP Target Service Provider";
150 
151 #define AVRCP_TARGET_RECORD_SIZE_MIN 84
152 
153 static uint16_t avrcp_target_record_size(const char * service_name, const char * service_provider_name){
154     int service_name_len           = service_name           ? strlen(service_name)          : strlen(default_avrcp_target_service_name);
155     int service_provider_name_len  = service_provider_name  ? strlen(service_provider_name) : strlen(default_avrcp_target_service_provider_name);
156     return AVRCP_TARGET_RECORD_SIZE_MIN + service_name_len + service_provider_name_len;
157 }
158 
159 TEST(SDPRecordBuilder, AVRCP_TARGET){
160     const char * service_name;
161     const char * service_provider_name;
162     int expected_len;
163     int descriptor_size;
164 
165     service_name = "";
166     service_provider_name = "";
167     descriptor_size = 0;
168     expected_len = avrcp_target_record_size(service_name, service_provider_name);
169     avrcp_target_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
170     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
171 }
172 
173 //
174 // avrcp controller
175 //
176 
177 static const char * default_avrcp_controller_service_name = "BTstack AVRCP Controller Service";
178 static const char * default_avrcp_controller_service_provider_name = "BTstack AVRCP Controller Service Provider";
179 
180 #define AVRCP_CONTROLLER_RECORD_SIZE_MIN 87
181 
182 static uint16_t avrcp_controller_record_size(const char * service_name, const char * service_provider_name){
183     int service_name_len           = service_name           ? strlen(service_name)          : strlen(default_avrcp_controller_service_name);
184     int service_provider_name_len  = service_provider_name  ? strlen(service_provider_name) : strlen(default_avrcp_controller_service_provider_name);
185     return AVRCP_CONTROLLER_RECORD_SIZE_MIN + service_name_len + service_provider_name_len;
186 }
187 
188 TEST(SDPRecordBuilder, AVRCP_CONTROLLER){
189     const char * service_name;
190     const char * service_provider_name;
191     int expected_len;
192     int descriptor_size;
193 
194     service_name = "";
195     service_provider_name = "";
196     descriptor_size = 0;
197     expected_len = avrcp_controller_record_size(service_name, service_provider_name);
198     avrcp_controller_create_sdp_record(service_buffer, 0, 0, service_name, service_provider_name);
199     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
200 }
201 
202 //
203 // hid_device.h
204 //
205 
206 #define HID_DEVICE_RECORD_SIZE_MIN 187
207 
208 static uint16_t hid_device_record_size(uint16_t descriptor_size, const char * name){
209     return HID_DEVICE_RECORD_SIZE_MIN + descriptor_size + strlen(name);
210 }
211 
212 TEST(SDPRecordBuilder, HID_DEVICE){
213     const char * name;
214     int expected_len;
215     int descriptor_size;
216 
217     name = "";
218     descriptor_size = 0;
219     expected_len = hid_device_record_size(descriptor_size, name);
220 
221     hid_sdp_record_t hid_params = {0, 0, 0, 0, 0, false, false, 0xFFFF, 0xFFFF, 3200, NULL, descriptor_size, name};
222     hid_create_sdp_record(service_buffer, 0x0001, &hid_params);
223 
224     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
225 }
226 
227 //
228 // hfp_hf
229 //
230 
231 #define HFP_HF_RECORD_SIZE_MIN 78
232 
233 static uint16_t hfp_hf_record_size(const char * name){
234     return HFP_HF_RECORD_SIZE_MIN + strlen(name);
235 }
236 
237 TEST(SDPRecordBuilder, HFP_HF){
238     const char * name;
239     int expected_len;
240 
241     name = "";
242     expected_len = hfp_hf_record_size(name);
243     hfp_hf_create_sdp_record(service_buffer, 0, 0, name, 0, 0);
244     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
245 
246     name =test_string;
247     expected_len = hfp_hf_record_size(name);
248     hfp_hf_create_sdp_record(service_buffer, 0, 0, name, 0, 0);
249     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
250 }
251 
252 //
253 // hfp_ag
254 //
255 
256 #define HFP_AG_RECORD_SIZE_MIN 83
257 
258 static uint16_t hfp_ag_record_size(const char * name){
259     return HFP_AG_RECORD_SIZE_MIN + strlen(name);
260 }
261 
262 TEST(SDPRecordBuilder, HFP_AG){
263     const char * name;
264     int expected_len;
265 
266     name = "";
267     expected_len = hfp_ag_record_size(name);
268     hfp_ag_create_sdp_record(service_buffer, 0, 0, name, 0, 0, 0);
269     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
270 
271     name =test_string;
272     expected_len = hfp_ag_record_size(name);
273     hfp_ag_create_sdp_record(service_buffer, 0, 0, name, 0, 0, 0);
274     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
275 }
276 
277 
278 //
279 // hsp_ag
280 //
281 
282 #define HSP_AG_RECORD_SIZE_MIN 72
283 
284 static uint16_t hsp_ag_record_size(const char * name){
285     return HSP_AG_RECORD_SIZE_MIN + strlen(name);
286 }
287 
288 TEST(SDPRecordBuilder, HSP_AG){
289     const char * name;
290     int expected_len;
291 
292     name = "";
293     expected_len = hsp_ag_record_size(name);
294     hsp_ag_create_sdp_record(service_buffer, 0, 0, name);
295     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
296 
297     name =test_string;
298     expected_len = hsp_ag_record_size(name);
299     hsp_ag_create_sdp_record(service_buffer, 0, 0, name);
300     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
301 }
302 
303 //
304 // hsp_hs
305 //
306 
307 #define HSP_HS_RECORD_SIZE_MIN 80
308 
309 static uint16_t hsp_hs_record_size(const char * name){
310     return HSP_HS_RECORD_SIZE_MIN + strlen(name);
311 }
312 
313 TEST(SDPRecordBuilder, HSP_HS){
314     const char * name;
315     int expected_len;
316 
317     name = "";
318     expected_len = hsp_hs_record_size(name);
319     hsp_hs_create_sdp_record(service_buffer, 0, 0, name, 0);
320     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
321 
322     name =test_string;
323     expected_len = hsp_hs_record_size(name);
324     hsp_hs_create_sdp_record(service_buffer, 0, 0, name, 0);
325     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
326 }
327 
328 //
329 // device id
330 //
331 
332 #define DEVICE_ID_RECORD_SIZE 64
333 
334 static uint16_t device_id_record_size(void){
335     return DEVICE_ID_RECORD_SIZE;
336 }
337 
338 TEST(SDPRecordBuilder, DeviceID){
339     int expected_len;
340     expected_len = device_id_record_size();
341     device_id_create_sdp_record(service_buffer, 0, 0, 0, 0, 0);
342     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
343 }
344 
345 
346 //
347 // pan
348 //
349 
350 #define PAN_RECORD_MIN_LEN 104
351 
352 static const char default_panu_service_name[] = "Personal Ad-hoc User Service";
353 static const char default_panu_service_desc[] = "Personal Ad-hoc User Service";
354 
355 static const char default_nap_service_name[] = "Network Access Point Service";
356 static const char default_nap_service_desc[] = "Personal Ad-hoc Network Service which provides access to a network";
357 
358 static const char default_gn_service_name[] = "Group Ad-hoc Network Service";
359 static const char default_gn_service_desc[] = "Personal Group Ad-hoc Network Service";
360 
361 // network_packet_types (X bytes x nr network packet types)
362 // name. default name or name
363 // ipv4 subnet, if yes + x
364 // ipv6 subnet, if yes + x
365 
366 static uint16_t pan_sdp_record_size(uint16_t * network_packet_types, const char *name, const char *description, const char *IPv4Subnet,
367     const char *IPv6Subnet, const char * default_name, const char * default_desc){
368     int num_network_packet_types;
369     for (num_network_packet_types=0; network_packet_types && *network_packet_types; num_network_packet_types++, network_packet_types++);
370     int name_len = name        ? strlen(name)        : strlen(default_name);
371     int desc_len = description ? strlen(description) : strlen(default_desc);
372     int ipv4_len = IPv4Subnet  ? 5 + strlen(IPv4Subnet) : 0;
373     int ipv6_len = IPv6Subnet  ? 5 + strlen(IPv6Subnet) : 0;
374     uint16_t res = PAN_RECORD_MIN_LEN + name_len + desc_len + ipv4_len + ipv6_len + num_network_packet_types * 3;   // tyoe + uint16_t
375     return res;
376 }
377 
378 static uint16_t pan_panu_sdp_record_size(uint16_t * network_packet_types, const char *name, const char *description){
379     return pan_sdp_record_size(network_packet_types, name, description, NULL, NULL, default_panu_service_name, default_panu_service_desc);
380 }
381 
382 static uint16_t pan_gn_sdp_record_size(uint16_t * network_packet_types, const char *name, const char *description, const char *IPv4Subnet,
383     const char *IPv6Subnet){
384     return pan_sdp_record_size(network_packet_types, name, description, IPv4Subnet, IPv6Subnet, default_gn_service_name, default_gn_service_desc);
385 }
386 
387 static uint16_t pan_nap_sdp_record_size(uint16_t * network_packet_types, const char *name, const char *description, const char *IPv4Subnet,
388     const char *IPv6Subnet){
389     return pan_sdp_record_size(network_packet_types, name, description, IPv4Subnet, IPv6Subnet, default_nap_service_name, default_nap_service_desc) + 14;
390 }
391 
392 TEST(SDPRecordBuilder, PANU){
393     int expected_len;
394     const char * name;
395     const char * desc;
396     uint16_t * network_packet_types;
397 
398     // empty name
399     name = "";
400     desc = "";
401     network_packet_types = NULL;
402     expected_len = pan_panu_sdp_record_size(network_packet_types, name, desc);
403     pan_create_panu_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE);
404     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
405 
406     // default name
407     name = NULL;
408     desc = NULL;
409     network_packet_types = NULL;
410     expected_len = pan_panu_sdp_record_size(network_packet_types, name, desc);
411     pan_create_panu_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE);
412     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
413 
414     // empty list
415     name = NULL;
416     desc = NULL;
417     network_packet_types = (uint16_t *) &uint16_list_empty;
418     expected_len = pan_panu_sdp_record_size(network_packet_types, name, desc);
419     pan_create_panu_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE);
420     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
421 
422     // single element
423     name = NULL;
424     desc = NULL;
425     network_packet_types = (uint16_t *) &uint16_list_single_element;
426     expected_len = pan_panu_sdp_record_size(network_packet_types, name, desc);
427     pan_create_panu_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE);
428     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
429 }
430 
431 TEST(SDPRecordBuilder, GN){
432     int expected_len;
433     const char * name;
434     const char * desc;
435     uint16_t * network_packet_types;
436     const char *IPv4Subnet;
437     const char *IPv6Subnet;
438 
439     // empty name
440     name = "";
441     desc = "";
442     network_packet_types = NULL;
443     IPv4Subnet = NULL;
444     IPv6Subnet = NULL;
445     expected_len = pan_gn_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
446     pan_create_gn_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, IPv4Subnet, IPv6Subnet);
447     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
448 
449     // test ipv4 param
450     name = "";
451     desc = "";
452     network_packet_types = NULL;
453     IPv4Subnet = NULL;
454     IPv6Subnet = "";
455     expected_len = pan_gn_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
456     pan_create_gn_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, IPv4Subnet, IPv6Subnet);
457     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
458 
459     // test ipv6 param
460     name = "";
461     desc = "";
462     network_packet_types = NULL;
463     IPv4Subnet = "";
464     IPv6Subnet = "";
465     expected_len = pan_gn_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
466     pan_create_gn_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, IPv4Subnet, IPv6Subnet);
467     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
468 }
469 
470 TEST(SDPRecordBuilder, NAP){
471     int expected_len;
472     const char * name;
473     const char * desc;
474     uint16_t * network_packet_types;
475     const char *IPv4Subnet;
476     const char *IPv6Subnet;
477 
478     // empty name
479     name = "";
480     desc = "";
481     network_packet_types = NULL;
482     IPv4Subnet = NULL;
483     IPv6Subnet = NULL;
484     expected_len = pan_nap_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
485     pan_create_nap_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, PAN_NET_ACCESS_TYPE_PSTN, 0, IPv4Subnet, IPv6Subnet);
486     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
487 
488     // test ipv4 param
489     name = "";
490     desc = "";
491     network_packet_types = NULL;
492     IPv4Subnet = NULL;
493     IPv6Subnet = "";
494     expected_len = pan_nap_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
495     pan_create_nap_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, PAN_NET_ACCESS_TYPE_PSTN, 0, IPv4Subnet, IPv6Subnet);
496     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
497 
498     // test ipv6 param
499     name = "";
500     desc = "";
501     network_packet_types = NULL;
502     IPv4Subnet = "";
503     IPv6Subnet = "";
504     expected_len = pan_nap_sdp_record_size(network_packet_types, name, desc, IPv4Subnet, IPv6Subnet);
505     pan_create_nap_sdp_record(service_buffer, 0, network_packet_types, name, desc, BNEP_SECURITY_NONE, PAN_NET_ACCESS_TYPE_PSTN, 0, IPv4Subnet, IPv6Subnet);
506     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
507 }
508 
509 //
510 // SPP: Record + strlen(service_name)
511 //
512 
513 #define SPP_RECORD_MIN_LEN 84
514 
515 static uint16_t spp_sdp_record_size_for_service_name(const char * service_name){
516     return SPP_RECORD_MIN_LEN + strlen(service_name);
517 }
518 
519 TEST(SDPRecordBuilder, SPP){
520     int expected_len = spp_sdp_record_size_for_service_name(test_string);
521     spp_create_sdp_record(service_buffer, 0, 0, test_string);
522     CHECK_EQUAL(de_get_len(service_buffer), expected_len);
523 }
524 
525 int main (int argc, const char * argv[]){
526     return CommandLineTestRunner::RunAllTests(argc, argv);
527 }
528