xref: /btstack/test/att_db/att_db_test.cpp (revision 6fc08a499bec60bdcd9ce5e4f5d33a20a984d7d9)
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