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
att_read_callback(hci_con_handle_t con_handle,uint16_t attribute_handle,uint16_t offset,uint8_t * buffer,uint16_t buffer_size)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
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)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
att_read_multiple_request(uint16_t num_value_handles,uint16_t * value_handles)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
att_write_request(uint16_t request_type,uint16_t attribute_handle,uint16_t value_length,const uint8_t * value)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
att_prepare_write_request(uint16_t request_type,uint16_t attribute_handle,uint16_t value_offset)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
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)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
TEST_GROUP(AttDb)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
TEST(AttDb,SetDB_NullAddress)194 TEST(AttDb, SetDB_NullAddress){
195 // test some function
196 att_set_db(NULL);
197 }
198
199
TEST(AttDb,MtuExchange)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
TEST(AttDb,handle_read_multiple_request)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
TEST(AttDb,handle_write_request)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
TEST(AttDb,handle_prepare_write_request)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
TEST(AttDb,att_uuid_for_handle)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
TEST(AttDb,gatt_server_get_handle_range)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
TEST(AttDb,gatt_server_get_handle_range_for_service)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
TEST(AttDb,gatt_server_get_value_handle_for_characteristic_with_uuid128)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
TEST(AttDb,gatt_server_get_client_configuration_handle_for_characteristic)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
TEST(AttDb,handle_signed_write_command)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
TEST(AttDb,handle_write_command)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
TEST(AttDb,att_read_callback_handle_blob)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
TEST(AttDb,att_read_callback_handle_byte)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
TEST(AttDb,att_read_callback_handle_little_endian_16)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
TEST(AttDb,att_read_callback_handle_little_endian_32)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
main(int argc,const char * argv[])912 int main (int argc, const char * argv[]){
913 return CommandLineTestRunner::RunAllTests(argc, argv);
914 }
915