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 #include <stdint.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 #include "CppUTest/TestHarness.h" 45 #include "CppUTest/CommandLineTestRunner.h" 46 47 #include "hci.h" 48 #include "ble/att_db.h" 49 #include "ble/att_db_util.h" 50 #include "btstack_util.h" 51 #include "bluetooth.h" 52 53 #include "btstack_crypto.h" 54 #include "bluetooth_gatt.h" 55 56 typedef enum { 57 READ_CALLBACK_MODE_RETURN_DEFAULT = 0, 58 READ_CALLBACK_MODE_RETURN_ONE_BYTE, 59 READ_CALLBACK_MODE_RETURN_PENDING 60 } read_callback_mode_t; 61 62 typedef enum { 63 WRITE_CALLBACK_MODE_RETURN_DEFAULT = 0, 64 WRITE_CALLBACK_MODE_RETURN_ERROR_WRITE_RESPONSE_PENDING, 65 WRITE_CALLBACK_MODE_RETURN_INVALID_ATTRIBUTE_VALUE_LENGTH 66 } write_callback_mode_t; 67 68 69 static uint8_t battery_level = 100; 70 static uint8_t cgm_status = 0; 71 72 static uint8_t att_request[200]; 73 static uint8_t att_response[1000]; 74 75 static read_callback_mode_t read_callback_mode = READ_CALLBACK_MODE_RETURN_DEFAULT; 76 static write_callback_mode_t write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 77 78 // these can be tweaked to report errors or some data as needed by test case 79 static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ 80 switch (read_callback_mode){ 81 case READ_CALLBACK_MODE_RETURN_ONE_BYTE: 82 return att_read_callback_handle_byte(0x55, offset, buffer, buffer_size); 83 case READ_CALLBACK_MODE_RETURN_PENDING: 84 return ATT_READ_RESPONSE_PENDING; 85 default: 86 return 0; 87 } 88 } 89 90 static int att_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ 91 switch (write_callback_mode){ 92 case WRITE_CALLBACK_MODE_RETURN_ERROR_WRITE_RESPONSE_PENDING: 93 return ATT_ERROR_WRITE_RESPONSE_PENDING; 94 case WRITE_CALLBACK_MODE_RETURN_INVALID_ATTRIBUTE_VALUE_LENGTH: 95 return ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH; 96 default: 97 return 0; 98 } 99 } 100 101 static uint16_t att_read_multiple_request(uint16_t num_value_handles, uint16_t * value_handles){ 102 att_request[0] = ATT_READ_MULTIPLE_REQUEST; 103 int i; 104 int offset = 1; 105 for (i=0;i<num_value_handles;i++){ 106 little_endian_store_16(att_request, offset, value_handles[i]); 107 offset += 2; 108 } 109 return offset; 110 } 111 112 static uint16_t att_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_length, const uint8_t * value){ 113 att_request[0] = request_type; 114 little_endian_store_16(att_request, 1, attribute_handle); 115 (void)memcpy(&att_request[3], value, value_length); 116 return 3 + value_length; 117 } 118 119 static uint16_t att_prepare_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_offset){ 120 att_request[0] = request_type; 121 little_endian_store_16(att_request, 1, attribute_handle); 122 little_endian_store_16(att_request, 3, value_offset); 123 return 5; 124 } 125 126 // ignore for now 127 extern "C" void btstack_crypto_aes128_cmac_generator(btstack_crypto_aes128_cmac_t * request, const uint8_t * key, uint16_t size, uint8_t (*get_byte_callback)(uint16_t pos), uint8_t * hash, void (* callback)(void * arg), void * callback_arg){ 128 } 129 130 TEST_GROUP(AttDb){ 131 att_connection_t att_connection; 132 uint16_t att_request_len; 133 uint16_t att_response_len; 134 uint8_t callback_buffer[10]; 135 136 void setup(void){ 137 memset(&callback_buffer, 0, sizeof(callback_buffer)); 138 139 read_callback_mode = READ_CALLBACK_MODE_RETURN_ONE_BYTE; 140 memset(&att_connection, 0, sizeof(att_connection)); 141 att_connection.max_mtu = 150; 142 att_connection.mtu = ATT_DEFAULT_MTU; 143 144 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 145 read_callback_mode = READ_CALLBACK_MODE_RETURN_DEFAULT; 146 147 // init att db util and add a service and characteristic 148 att_db_util_init(); 149 // 0x180F 150 att_db_util_add_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); 151 // 0x2A19 152 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_WRITE | ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 153 // 0x2A1B 154 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_STATE, ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 155 // 0x2A1A 156 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_POWER_STATE, ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); 157 // 0x2A49 158 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_FEATURE, ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 159 // 0x2A35 160 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_MEASUREMENT, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); 161 // 0x2A38 162 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 163 164 const uint8_t uuid128[] = {0x00, 0x00, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 165 att_db_util_add_characteristic_uuid128(uuid128, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 166 167 // 0x2AA7 168 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_MEASUREMENT, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); 169 170 // 0x2AAB 171 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 172 // 0x2A5C 173 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE, ATT_PROPERTY_AUTHENTICATED_SIGNED_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 174 175 const uint8_t uuid128_service[] = {0xAA, 0xBB, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 176 att_db_util_add_service_uuid128(uuid128_service); 177 // 0x2AA9 178 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_STATUS, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &cgm_status, 1); 179 180 const uint8_t uuid128_chr_no_notify[] = {0xAA, 0xCC, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 181 att_db_util_add_characteristic_uuid128(uuid128_chr_no_notify, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 182 183 att_db_util_add_included_service_uuid16(0x50, 0x51, 0xAACC); 184 185 // const uint8_t uuid128_incl_service[] = {0xAA, 0xEE, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 186 // att_db_util_add_included_service_uuid128(0x50, 0x51, uuid128_incl_service); 187 // set callbacks 188 att_set_db(att_db_util_get_address()); 189 att_set_read_callback(&att_read_callback); 190 att_set_write_callback(&att_write_callback); 191 } 192 }; 193 194 TEST(AttDb, SetDB_NullAddress){ 195 // test some function 196 att_set_db(NULL); 197 } 198 199 200 TEST(AttDb, MtuExchange){ 201 // test some function 202 att_request_len = 3; 203 const uint8_t att_request[3] = { ATT_EXCHANGE_MTU_REQUEST, 0, att_connection.max_mtu}; 204 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 205 CHECK_EQUAL(att_request_len, att_response_len); 206 const uint8_t expected_response[] = { ATT_EXCHANGE_MTU_RESPONSE, att_connection.max_mtu, 0}; 207 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 208 } 209 210 211 TEST(AttDb, handle_read_multiple_request){ 212 uint16_t value_handles[2]; 213 uint16_t num_value_handles; 214 215 // less then two values 216 num_value_handles = 0; 217 memset(&value_handles, 0, sizeof(value_handles)); 218 { 219 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 220 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 221 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 222 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, 0, 0, ATT_ERROR_INVALID_PDU}; 223 CHECK_EQUAL(sizeof(expected_response), att_response_len); 224 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 225 } 226 227 num_value_handles = 1; 228 value_handles[0] = 0x1; 229 { 230 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 231 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 232 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 233 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, 0, 0, ATT_ERROR_INVALID_PDU}; 234 CHECK_EQUAL(sizeof(expected_response), att_response_len); 235 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 236 } 237 238 // invalid handle 239 num_value_handles = 2; 240 value_handles[0] = 0x0; 241 { 242 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 243 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 244 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 245 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, 0, 0, ATT_ERROR_INVALID_HANDLE}; 246 CHECK_EQUAL(sizeof(expected_response), att_response_len); 247 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 248 } 249 250 num_value_handles = 2; 251 value_handles[0] = 0xF1; 252 value_handles[1] = 0xF2; 253 { 254 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 255 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 256 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 257 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, value_handles[0], 0, ATT_ERROR_INVALID_HANDLE}; 258 CHECK_EQUAL(sizeof(expected_response), att_response_len); 259 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 260 } 261 262 // handle read not permitted 263 num_value_handles = 2; 264 value_handles[0] = 0x05; 265 value_handles[1] = 0x06; 266 { 267 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 268 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 269 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 270 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, value_handles[1], 0, ATT_ERROR_READ_NOT_PERMITTED}; 271 CHECK_EQUAL(sizeof(expected_response), att_response_len); 272 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 273 } 274 275 // security validation (single case) 276 num_value_handles = 2; 277 value_handles[0] = 0x05; 278 value_handles[1] = 0x09; 279 { 280 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 281 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 282 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 283 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, ATT_READ_MULTIPLE_REQUEST, value_handles[1], 0, ATT_ERROR_INSUFFICIENT_AUTHENTICATION}; 284 CHECK_EQUAL(sizeof(expected_response), att_response_len); 285 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 286 } 287 288 289 // static read 290 num_value_handles = 2; 291 value_handles[0] = 0x03; 292 value_handles[1] = 0x05; 293 { 294 read_callback_mode = READ_CALLBACK_MODE_RETURN_ONE_BYTE; 295 296 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 297 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 298 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 299 const uint8_t expected_response[] = {ATT_READ_MULTIPLE_RESPONSE, 0x64, 0x10, 0x06, 0x00, 0x1B, 0x2A}; 300 CHECK_EQUAL(sizeof(expected_response), att_response_len); 301 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 302 303 read_callback_mode = READ_CALLBACK_MODE_RETURN_DEFAULT; 304 } 305 306 #ifdef ENABLE_ATT_DELAYED_RESPONSE 307 // dynamic read 308 num_value_handles = 2; 309 value_handles[0] = 0x03; 310 value_handles[1] = 0x0c; 311 { 312 read_callback_mode = READ_CALLBACK_MODE_RETURN_PENDING; 313 314 att_request_len = att_read_multiple_request(num_value_handles, value_handles); 315 CHECK_EQUAL(1 + 2 * num_value_handles, att_request_len); 316 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 317 const uint8_t expected_response[] = {ATT_READ_MULTIPLE_RESPONSE, 0x64}; 318 CHECK_EQUAL(sizeof(expected_response), att_response_len); 319 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 320 321 read_callback_mode = READ_CALLBACK_MODE_RETURN_DEFAULT; 322 } 323 #endif 324 } 325 326 TEST(AttDb, handle_write_request){ 327 uint16_t attribute_handle = 0x03; 328 329 // not sufficient request length 330 { 331 att_request[0] = ATT_WRITE_REQUEST; 332 att_request_len = 1; 333 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 334 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], 0x00, 0x00, ATT_ERROR_INVALID_PDU}; 335 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 336 CHECK_EQUAL(sizeof(expected_response), att_response_len); 337 } 338 339 { 340 att_request[0] = ATT_WRITE_REQUEST; 341 att_request[1] = 0x03; 342 att_request_len = 2; 343 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 344 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], 0x00, 0x00, ATT_ERROR_INVALID_PDU}; 345 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 346 CHECK_EQUAL(sizeof(expected_response), att_response_len); 347 } 348 349 // invalid handle 350 { 351 att_request[0] = ATT_WRITE_REQUEST; 352 att_request[1] = 0; 353 att_request[2] = 0; 354 att_request_len = 3; 355 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 356 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INVALID_HANDLE}; 357 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 358 CHECK_EQUAL(sizeof(expected_response), att_response_len); 359 } 360 361 // write not permited: invalid write callback 362 { 363 att_set_write_callback(NULL); 364 365 const uint8_t value[] = {0x50}; 366 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 367 CHECK_EQUAL(3 + sizeof(value), att_request_len); 368 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 369 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 370 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 371 CHECK_EQUAL(sizeof(expected_response), att_response_len); 372 373 att_set_write_callback(&att_write_callback); 374 } 375 376 // write not permited: no ATT_PROPERTY_WRITE 377 { 378 const uint8_t value[] = {0x50}; 379 attribute_handle = 0x000c; // 0x2A49 380 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 381 CHECK_EQUAL(3 + sizeof(value), att_request_len); 382 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 383 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 384 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 385 CHECK_EQUAL(sizeof(expected_response), att_response_len); 386 } 387 388 // write not permited: no ATT_PROPERTY_DYNAMIC 389 { 390 const uint8_t value[] = {0x50}; 391 attribute_handle = 0x0003; 392 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 393 CHECK_EQUAL(3 + sizeof(value), att_request_len); 394 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 395 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 396 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 397 CHECK_EQUAL(sizeof(expected_response), att_response_len); 398 } 399 400 // security validation 401 { 402 const uint8_t value[] = {0x50}; 403 attribute_handle = 0x000f; // 0x2A35 404 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 405 CHECK_EQUAL(3 + sizeof(value), att_request_len); 406 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 407 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INSUFFICIENT_AUTHENTICATION}; 408 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 409 CHECK_EQUAL(sizeof(expected_response), att_response_len); 410 } 411 412 // att_persistent_ccc_cache: ATT_PROPERTY_UUID16 413 // att_persistent_ccc_cache: ATT_PROPERTY_UUID128 414 415 // some callback error other then ATT_INTERNAL_WRITE_RESPONSE_PENDING 416 { 417 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_INVALID_ATTRIBUTE_VALUE_LENGTH; 418 419 const uint8_t value[] = {0x50}; 420 attribute_handle = 0x0011; // 0x2A38 421 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 422 CHECK_EQUAL(3 + sizeof(value), att_request_len); 423 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 424 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH}; 425 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 426 CHECK_EQUAL(sizeof(expected_response), att_response_len); 427 428 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 429 } 430 431 #ifdef ENABLE_ATT_DELAYED_RESPONSE 432 // delayed response 433 { 434 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_ERROR_WRITE_RESPONSE_PENDING; 435 436 const uint8_t value[] = {0x50}; 437 attribute_handle = 0x0011; // 0x2A38 438 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 439 CHECK_EQUAL(3 + sizeof(value), att_request_len); 440 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 441 CHECK_EQUAL(ATT_INTERNAL_WRITE_RESPONSE_PENDING, att_response_len); 442 443 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 444 } 445 #endif 446 447 // correct write 448 { 449 const uint8_t value[] = {0x50}; 450 attribute_handle = 0x0011; 451 att_request_len = att_write_request(ATT_WRITE_REQUEST, attribute_handle, sizeof(value), value); 452 CHECK_EQUAL(3 + sizeof(value), att_request_len); 453 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 454 const uint8_t expected_response[] = {ATT_WRITE_RESPONSE}; 455 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 456 CHECK_EQUAL(sizeof(expected_response), att_response_len); 457 } 458 } 459 460 TEST(AttDb, handle_prepare_write_request){ 461 uint16_t attribute_handle = 0x0011; 462 uint16_t value_offset = 0x10; 463 464 // not sufficient request length 465 { 466 att_request[0] = ATT_PREPARE_WRITE_REQUEST; 467 att_request_len = 1; 468 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 469 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], 0x00, 0x00, ATT_ERROR_INVALID_PDU}; 470 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 471 CHECK_EQUAL(sizeof(expected_response), att_response_len); 472 } 473 474 // write not permited: invalid write callback 475 { 476 att_set_write_callback(NULL); 477 478 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 479 CHECK_EQUAL(5, att_request_len); 480 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 481 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 482 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 483 CHECK_EQUAL(sizeof(expected_response), att_response_len); 484 485 att_set_write_callback(&att_write_callback); 486 } 487 488 // invalid handle 489 { 490 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, 0, 0); 491 CHECK_EQUAL(5, att_request_len); 492 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 493 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INVALID_HANDLE}; 494 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 495 CHECK_EQUAL(sizeof(expected_response), att_response_len); 496 } 497 498 // write not permited: no ATT_PROPERTY_WRITE 499 { 500 attribute_handle = 0x000c; // 0x2A49 501 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 502 CHECK_EQUAL(5, att_request_len); 503 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 504 505 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 506 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 507 CHECK_EQUAL(sizeof(expected_response), att_response_len); 508 } 509 510 511 // write not permited: no ATT_PROPERTY_DYNAMIC 512 { 513 attribute_handle = 0x0003; 514 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 515 CHECK_EQUAL(5, att_request_len); 516 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 517 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_WRITE_NOT_PERMITTED}; 518 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 519 CHECK_EQUAL(sizeof(expected_response), att_response_len); 520 } 521 522 // security validation 523 { 524 attribute_handle = 0x000f; // 0x2A35 525 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 526 CHECK_EQUAL(5, att_request_len); 527 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 528 const uint8_t expected_response[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INSUFFICIENT_AUTHENTICATION}; 529 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 530 CHECK_EQUAL(sizeof(expected_response), att_response_len); 531 } 532 533 // some callback error other then ATT_INTERNAL_WRITE_RESPONSE_PENDING 534 { 535 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_INVALID_ATTRIBUTE_VALUE_LENGTH; 536 537 attribute_handle = 0x0011; // 0x2A38 538 539 // prepare write 540 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 541 CHECK_EQUAL(5, att_request_len); 542 543 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 544 const uint8_t expected_response_prepare_write[] = {ATT_PREPARE_WRITE_RESPONSE, 0x11, 0x00, 0x10, 0x00}; 545 MEMCMP_EQUAL(expected_response_prepare_write, att_response, att_response_len); 546 CHECK_EQUAL(sizeof(expected_response_prepare_write), att_response_len); 547 548 // execute write 549 att_request_len = att_prepare_write_request(ATT_EXECUTE_WRITE_REQUEST, attribute_handle, value_offset); 550 CHECK_EQUAL(5, att_request_len); 551 552 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 553 const uint8_t expected_response_write_execute[] = {ATT_ERROR_RESPONSE, att_request[0], att_request[1], att_request[2], ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH}; 554 MEMCMP_EQUAL(expected_response_write_execute, att_response, att_response_len); 555 CHECK_EQUAL(sizeof(expected_response_write_execute), att_response_len); 556 557 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 558 } 559 560 #ifdef ENABLE_ATT_DELAYED_RESPONSE 561 // delayed response 562 { 563 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_ERROR_WRITE_RESPONSE_PENDING; 564 565 attribute_handle = 0x0011; // 0x2A38 566 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 567 CHECK_EQUAL(5, att_request_len); 568 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 569 570 571 CHECK_EQUAL(ATT_INTERNAL_WRITE_RESPONSE_PENDING, att_response_len); 572 573 write_callback_mode = WRITE_CALLBACK_MODE_RETURN_DEFAULT; 574 } 575 #endif 576 577 // correct write 578 { 579 attribute_handle = 0x0011; 580 att_request_len = att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, attribute_handle, value_offset); 581 CHECK_EQUAL(5, att_request_len); 582 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 583 const uint8_t expected_response[] = {ATT_PREPARE_WRITE_RESPONSE, 0x11, 0x00, 0x10, 0x00}; 584 MEMCMP_EQUAL(expected_response, att_response, att_response_len); 585 CHECK_EQUAL(sizeof(expected_response), att_response_len); 586 } 587 } 588 589 TEST(AttDb, att_uuid_for_handle){ 590 // existing attribute handle 591 uint16_t uuid = att_uuid_for_handle(0x0011); 592 uint16_t expected_response = 0x2A38; 593 CHECK_EQUAL(expected_response, uuid); 594 595 // unknown attribute handle 596 uuid = att_uuid_for_handle(0xFF00); 597 expected_response = 0; 598 CHECK_EQUAL(expected_response, uuid); 599 600 // attribute handle for uuid128 601 uuid = att_uuid_for_handle(0x0014); 602 expected_response = 0; 603 CHECK_EQUAL(expected_response, uuid); 604 } 605 606 TEST(AttDb, gatt_server_get_handle_range){ 607 uint16_t start_handle; 608 uint16_t end_handle; 609 610 bool service_exists = gatt_server_get_handle_range_for_service_with_uuid16(0x00, &start_handle, &end_handle); 611 CHECK_EQUAL(false, service_exists); 612 613 uint16_t attribute_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0x00); 614 CHECK_EQUAL(0x00, attribute_handle); 615 616 attribute_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 617 uint16_t configuration_handle = gatt_server_get_server_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, attribute_handle); 618 CHECK_EQUAL(0x00, configuration_handle); 619 } 620 621 TEST(AttDb, gatt_server_get_handle_range_for_service){ 622 uint16_t start_handle; 623 uint16_t end_handle; 624 625 const uint8_t uuid128_1[] = {0x00, 0x00, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 626 const uint8_t uuid128_2[] = {0xAA, 0xBB, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 627 const uint8_t uuid128_3[] = {0xAA, 0xDD, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 628 629 630 bool service_exists = gatt_server_get_handle_range_for_service_with_uuid128(uuid128_1, &start_handle, &end_handle); 631 CHECK_EQUAL(false, service_exists); 632 633 service_exists = gatt_server_get_handle_range_for_service_with_uuid128(uuid128_2, &start_handle, &end_handle); 634 CHECK_EQUAL(true, service_exists); 635 636 uint16_t out_included_service_handle; 637 uint16_t out_included_service_start_handle; 638 uint16_t out_included_service_end_handle; 639 640 service_exists = gatt_server_get_included_service_with_uuid16(0, 0xffff, 0xAA, 641 &out_included_service_handle, &out_included_service_start_handle, &out_included_service_end_handle); 642 CHECK_EQUAL(false, service_exists); 643 644 service_exists = gatt_server_get_included_service_with_uuid16(0, 0, 0xAA, 645 &out_included_service_handle, &out_included_service_start_handle, &out_included_service_end_handle); 646 CHECK_EQUAL(false, service_exists); 647 648 service_exists = gatt_server_get_included_service_with_uuid16(0, 0xffff, 0xAACC, 649 &out_included_service_handle, &out_included_service_start_handle, &out_included_service_end_handle); 650 CHECK_EQUAL(true, service_exists); 651 } 652 653 654 TEST(AttDb, gatt_server_get_value_handle_for_characteristic_with_uuid128){ 655 const uint8_t uuid128_1[] = {0x00, 0x00, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 656 const uint8_t uuid128_2[] = {0xAA, 0xBB, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 657 658 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid128(0, 0xffff, uuid128_1); 659 CHECK_EQUAL(20, value_handle); 660 CHECK_EQUAL(false, att_is_persistent_ccc(value_handle)); 661 CHECK_EQUAL(false, att_is_persistent_ccc(0x60)); 662 663 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid128(0, 0xffff, uuid128_2); 664 CHECK_EQUAL(0, value_handle); 665 666 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid128(0, 0, uuid128_2); 667 CHECK_EQUAL(0, value_handle); 668 669 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid128(0xffff, 0, uuid128_2); 670 CHECK_EQUAL(0, value_handle); 671 } 672 673 674 TEST(AttDb, gatt_server_get_client_configuration_handle_for_characteristic){ 675 const uint8_t uuid128_1[] = {0x00, 0x00, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 676 const uint8_t uuid128_2[] = {0xAA, 0xBB, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 677 const uint8_t uuid128_3[] = {0xAA, 0xCC, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 678 679 uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(0, 0xffff, uuid128_1); 680 CHECK_EQUAL(21, value_handle); 681 682 value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(0, 0xffff, uuid128_2); 683 CHECK_EQUAL(0, value_handle); 684 685 value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(0, 0, uuid128_2); 686 CHECK_EQUAL(0, value_handle); 687 688 value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(0xffff, 0, uuid128_2); 689 CHECK_EQUAL(0, value_handle); 690 691 value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(0xffff, 0, uuid128_3); 692 CHECK_EQUAL(0, value_handle); 693 694 695 value_handle = gatt_server_get_descriptor_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_MEASUREMENT, GATT_SERVER_CHARACTERISTICS_CONFIGURATION); 696 CHECK_EQUAL(0, value_handle); 697 698 value_handle = gatt_server_get_descriptor_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, GATT_SERVER_CHARACTERISTICS_CONFIGURATION); 699 CHECK_EQUAL(0, value_handle); 700 701 value_handle = gatt_server_get_descriptor_handle_for_characteristic_with_uuid16(0, 0, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, GATT_SERVER_CHARACTERISTICS_CONFIGURATION); 702 CHECK_EQUAL(0, value_handle); 703 } 704 705 706 TEST(AttDb, handle_signed_write_command){ 707 uint16_t attribute_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE); 708 709 att_request[0] = ATT_SIGNED_WRITE_COMMAND; 710 att_request_len = 1; 711 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 712 CHECK_EQUAL(0, att_response_len); 713 } 714 715 TEST(AttDb, handle_write_command){ 716 uint16_t attribute_handle = 0x03; 717 att_dump_attributes(); 718 719 // not sufficient request length 720 { 721 att_request[0] = ATT_WRITE_COMMAND; 722 att_request_len = 1; 723 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 724 CHECK_EQUAL(0, att_response_len); 725 } 726 727 { 728 att_request[0] = ATT_WRITE_COMMAND; 729 att_request[1] = 0x03; 730 att_request_len = 2; 731 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 732 CHECK_EQUAL(0, att_response_len); 733 } 734 735 // invalid write callback 736 { 737 att_set_write_callback(NULL); 738 739 const uint8_t value[] = {0x50}; 740 att_request_len = att_write_request(ATT_WRITE_COMMAND, attribute_handle, sizeof(value), value); 741 CHECK_EQUAL(3 + sizeof(value), att_request_len); 742 743 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 744 CHECK_EQUAL(0, att_response_len); 745 746 att_set_write_callback(&att_write_callback); 747 } 748 749 // invalid handle 750 { 751 att_request[0] = ATT_WRITE_COMMAND; 752 att_request[1] = 0; 753 att_request[2] = 0; 754 att_request_len = 3; 755 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 756 CHECK_EQUAL(0, att_response_len); 757 } 758 759 // write not permited: no ATT_PROPERTY_DYNAMIC 760 { 761 const uint8_t value[] = {0x50}; 762 attribute_handle = 0x0003; 763 att_request_len = att_write_request(ATT_WRITE_COMMAND, attribute_handle, sizeof(value), value); 764 CHECK_EQUAL(3 + sizeof(value), att_request_len); 765 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 766 CHECK_EQUAL(0, att_response_len); 767 } 768 769 // write not permited: no ATT_PROPERTY_WRITE_WITHOUT_RESPONSE 770 { 771 const uint8_t value[] = {0x50}; 772 attribute_handle = 0x000c; // 0x2A49 773 att_request_len = att_write_request(ATT_WRITE_COMMAND, attribute_handle, sizeof(value), value); 774 CHECK_EQUAL(3 + sizeof(value), att_request_len); 775 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 776 CHECK_EQUAL(0, att_response_len); 777 } 778 779 // security validation 780 { 781 const uint8_t value[] = {0x50}; 782 attribute_handle = 0x0017; // 0x2AA7 783 att_request_len = att_write_request(ATT_WRITE_COMMAND, attribute_handle, sizeof(value), value); 784 CHECK_EQUAL(3 + sizeof(value), att_request_len); 785 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 786 CHECK_EQUAL(0, att_response_len); 787 } 788 789 // correct write 790 { 791 const uint8_t value[] = {0x50}; 792 attribute_handle = 0x001A; // 0x2AAB 793 att_request_len = att_write_request(ATT_WRITE_COMMAND, attribute_handle, sizeof(value), value); 794 CHECK_EQUAL(3 + sizeof(value), att_request_len); 795 att_response_len = att_handle_request(&att_connection, (uint8_t *) att_request, att_request_len, att_response); 796 CHECK_EQUAL(0, att_response_len); 797 } 798 } 799 800 TEST(AttDb, att_read_callback_handle_blob){ 801 { 802 const uint8_t blob[] = {0x44, 0x55}; 803 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 0, NULL, 0); 804 CHECK_EQUAL(2, blob_size); 805 } 806 807 { 808 const uint8_t blob[] = {}; 809 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 0, callback_buffer, sizeof(callback_buffer)); 810 CHECK_EQUAL(0, blob_size); 811 } 812 813 { 814 const uint8_t blob[] = {}; 815 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 10, callback_buffer, sizeof(callback_buffer)); 816 CHECK_EQUAL(0, blob_size); 817 } 818 819 { 820 const uint8_t blob[] = {0x55}; 821 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 0, callback_buffer, sizeof(callback_buffer)); 822 CHECK_EQUAL(1, blob_size); 823 } 824 825 { 826 const uint8_t blob[] = {0x55}; 827 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 10, callback_buffer, sizeof(callback_buffer)); 828 CHECK_EQUAL(0, blob_size); 829 } 830 831 { 832 const uint8_t blob[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA}; 833 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 0, callback_buffer, sizeof(callback_buffer)); 834 CHECK_EQUAL(10, blob_size); 835 } 836 837 { 838 const uint8_t blob[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA}; 839 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 1, callback_buffer, sizeof(callback_buffer)); 840 CHECK_EQUAL(9, blob_size); 841 } 842 843 { 844 const uint8_t blob[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA}; 845 uint16_t blob_size = att_read_callback_handle_blob(blob, sizeof(blob), 10, callback_buffer, sizeof(callback_buffer)); 846 CHECK_EQUAL(0, blob_size); 847 } 848 } 849 850 TEST(AttDb, att_read_callback_handle_byte){ 851 { 852 uint16_t blob_size = att_read_callback_handle_byte(0x55, 0, NULL, 0); 853 CHECK_EQUAL(1, blob_size); 854 } 855 856 { 857 uint16_t blob_size = att_read_callback_handle_byte(0x55, 10, callback_buffer, sizeof(callback_buffer)); 858 CHECK_EQUAL(0, blob_size); 859 } 860 861 { 862 uint16_t blob_size = att_read_callback_handle_byte(0x55, 0, callback_buffer, sizeof(callback_buffer)); 863 CHECK_EQUAL(1, blob_size); 864 } 865 } 866 867 TEST(AttDb, att_read_callback_handle_little_endian_16){ 868 { 869 uint16_t blob_size = att_read_callback_handle_little_endian_16(0x1122, 0, NULL, 0); 870 CHECK_EQUAL(2, blob_size); 871 } 872 873 { 874 uint16_t blob_size = att_read_callback_handle_little_endian_16(0x1122, 10, callback_buffer, sizeof(callback_buffer)); 875 CHECK_EQUAL(0, blob_size); 876 } 877 878 { 879 uint16_t blob_size = att_read_callback_handle_little_endian_16(0x1122, 1, callback_buffer, sizeof(callback_buffer)); 880 CHECK_EQUAL(1, blob_size); 881 } 882 883 { 884 uint16_t blob_size = att_read_callback_handle_little_endian_16(0x1122, 0, callback_buffer, sizeof(callback_buffer)); 885 CHECK_EQUAL(2, blob_size); 886 } 887 } 888 889 TEST(AttDb, att_read_callback_handle_little_endian_32){ 890 { 891 uint16_t blob_size = att_read_callback_handle_little_endian_32(0x11223344, 0, NULL, 0); 892 CHECK_EQUAL(4, blob_size); 893 } 894 895 { 896 uint16_t blob_size = att_read_callback_handle_little_endian_32(0x11223344, 10, callback_buffer, sizeof(callback_buffer)); 897 CHECK_EQUAL(0, blob_size); 898 } 899 900 { 901 uint16_t blob_size = att_read_callback_handle_little_endian_32(0x11223344, 3, callback_buffer, sizeof(callback_buffer)); 902 CHECK_EQUAL(1, blob_size); 903 } 904 905 { 906 uint16_t blob_size = att_read_callback_handle_little_endian_32(0x11223344, 0, callback_buffer, sizeof(callback_buffer)); 907 CHECK_EQUAL(4, blob_size); 908 } 909 } 910 911 912 int main (int argc, const char * argv[]){ 913 return CommandLineTestRunner::RunAllTests(argc, argv); 914 } 915