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 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 94 TEST_GROUP(ADParser){ 95 void setup(void){ 96 } 97 }; 98 99 TEST(ADParser, TestNamePrefix){ 100 CHECK(nameHasPrefix("BTstack", sizeof(adv_data_2), adv_data_2)); 101 } 102 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 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 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 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 190 int main (int argc, const char * argv[]){ 191 return CommandLineTestRunner::RunAllTests(argc, argv); 192 } 193