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 rfcomm query tests
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 "bluetooth_data_types.h"
54 #include "btstack_util.h"
55 #include "ad_parser.h"
56
57 static const uint8_t ad_data[] = { 0x02, 0x01, 0x05, /* -- */ 0x03, 0x02, 0xF0, 0xFF};
58 static const uint8_t adv_data_2[] = { 8, 0x09, 'B', 'T', 's', 't', 'a', 'c', 'k' };
59 static const uint8_t adv_data[] = {
60 // Flags general discoverable, BR/EDR not supported
61 0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
62 // Name
63 0x0c, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'L', 'E', ' ', 'S', 't', 'r', 'e', 'a', 'm', 'e', 'r',
64 // Incomplete List of 16-bit Service Class UUIDs -- FF10 - only valid for testing!
65 0x03, BLUETOOTH_DATA_TYPE_INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, 0x10, 0xff,
66
67 17, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS, 0x9e, 0xca, 0xdc, 0x24, 0xe, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x1, 0x0, 0x40, 0x6e,
68
69 17, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS, 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, /* - */ 0x00, 0x80, /* - */ 0x00, 0x10, /* - */ 0x00, 0x00, /* - */ 0x10, 0xaa, 0x00, 0x00
70 };
71
72
nameHasPrefix(const char * name_prefix,uint16_t data_length,const uint8_t * data)73 bool nameHasPrefix(const char * name_prefix, uint16_t data_length, const uint8_t * data){
74 ad_context_t context;
75 int name_prefix_len = strlen(name_prefix);
76 for (ad_iterator_init(&context, data_length, data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){
77 uint8_t data_type = ad_iterator_get_data_type(&context);
78 uint8_t data_len = ad_iterator_get_data_len(&context);
79 const uint8_t * data = ad_iterator_get_data(&context);
80 int compare_len = name_prefix_len;
81 switch(data_type){
82 case 8: // shortented local name
83 case 9: // complete local name
84 if (compare_len > data_len) compare_len = data_len;
85 if (strncmp(name_prefix, (const char*) data, compare_len) == 0) return true;
86 break;
87 default:
88 break;
89 }
90 }
91 return false;
92 }
93
TEST_GROUP(ADParser)94 TEST_GROUP(ADParser){
95 void setup(void){
96 }
97 };
98
TEST(ADParser,TestNamePrefix)99 TEST(ADParser, TestNamePrefix){
100 CHECK(nameHasPrefix("BTstack", sizeof(adv_data_2), adv_data_2));
101 }
102
TEST(ADParser,TestDataParsing)103 TEST(ADParser, TestDataParsing){
104 ad_context_t context;
105 uint8_t expected_len[] = {1, 2};
106 uint8_t expected_type[] = {0x01, 0x02};
107 uint8_t expected_data[][2] = {{0x05, 0x00}, {0xF0, 0xFF}};
108
109 int i = 0;
110 uint8_t ad_len = sizeof(ad_data);
111
112 for (ad_iterator_init(&context, ad_len, ad_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){
113 uint8_t data_type = ad_iterator_get_data_type(&context);
114 uint8_t data_len = ad_iterator_get_data_len(&context);
115 const uint8_t * data = ad_iterator_get_data(&context);
116
117 CHECK_EQUAL(expected_len[i], data_len);
118 CHECK_EQUAL(expected_type[i], data_type);
119
120 int j;
121 for (j = 0; j < data_len; j++){
122 CHECK_EQUAL(expected_data[i][j], data[j]);
123 }
124 i++;
125 }
126 }
127
TEST(ADParser,TestMalformed)128 TEST(ADParser, TestMalformed){
129 ad_context_t context;
130
131 // len = 0xff, but only one byte type
132 uint8_t data[] = { 0xff, 0x01 };
133 ad_iterator_init(&context, sizeof(data), data);
134 CHECK_EQUAL(ad_iterator_has_more(&context), 0);
135
136 // len = 0x01, but not type
137 uint8_t data2[] = { 0x00, 0x01 };
138 ad_iterator_init(&context, sizeof(data2), data2);
139 CHECK_EQUAL(ad_iterator_has_more(&context), 0);
140 }
141
TEST(ADParser,ad_data_contains_uuid16)142 TEST(ADParser, ad_data_contains_uuid16){
143 bool contains_uuid;
144
145 contains_uuid = ad_data_contains_uuid16(sizeof(adv_data_2), adv_data_2, 0x00);
146 CHECK(!contains_uuid);
147
148 contains_uuid = ad_data_contains_uuid16(sizeof(adv_data), adv_data, 0x00);
149 CHECK(!contains_uuid);
150
151 contains_uuid = ad_data_contains_uuid16(sizeof(adv_data), adv_data, 0xff10);
152 CHECK(contains_uuid);
153
154 contains_uuid = ad_data_contains_uuid16(sizeof(adv_data), adv_data, 0xaa10);
155 CHECK(contains_uuid);
156 }
157
TEST(ADParser,ad_data_contains_uuid128)158 TEST(ADParser, ad_data_contains_uuid128){
159 bool contains_uuid;
160 {
161 uint8_t ad_uuid128[16];
162 memset(ad_uuid128, 0, 16);
163 contains_uuid = ad_data_contains_uuid128(sizeof(adv_data_2), adv_data_2, ad_uuid128);
164 CHECK(!contains_uuid);
165
166 contains_uuid = ad_data_contains_uuid128(sizeof(adv_data), adv_data, ad_uuid128);
167 CHECK(!contains_uuid);
168 }
169
170
171 {
172 uint8_t uuid128_le[] = {0x9e, 0xca, 0xdc, 0x24, 0xe, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x1, 0x0, 0x40, 0x6e};
173 uint8_t ad_uuid128[16];
174 reverse_128(uuid128_le, ad_uuid128);
175
176 contains_uuid = ad_data_contains_uuid128(sizeof(adv_data), adv_data, ad_uuid128);
177 CHECK(contains_uuid);
178 }
179
180 {
181 uint8_t uuid128_le[] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x10, 0xaa, 0x00, 0x00};
182 uint8_t ad_uuid128[16];
183 reverse_128(uuid128_le, ad_uuid128);
184
185 contains_uuid = ad_data_contains_uuid128(sizeof(adv_data), adv_data, ad_uuid128);
186 CHECK(contains_uuid);
187 }
188 }
189
main(int argc,const char * argv[])190 int main (int argc, const char * argv[]){
191 return CommandLineTestRunner::RunAllTests(argc, argv);
192 }
193