1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <stddef.h>
21 #include <errno.h>
22 #include <string.h>
23 #include "testutil/testutil.h"
24 #include "nimble/hci_common.h"
25 #include "host/ble_hs_test.h"
26 #include "host/ble_uuid.h"
27 #include "ble_hs_test_util.h"
28
29 static uint8_t *ble_att_svr_test_attr_r_1;
30 static uint16_t ble_att_svr_test_attr_r_1_len;
31 static uint8_t *ble_att_svr_test_attr_r_2;
32 static uint16_t ble_att_svr_test_attr_r_2_len;
33
34 static uint8_t ble_att_svr_test_attr_w_1[1024];
35 static uint16_t ble_att_svr_test_attr_w_1_len;
36 static uint8_t ble_att_svr_test_attr_w_2[1024];
37 static uint16_t ble_att_svr_test_attr_w_2_len;
38
39 static uint16_t ble_att_svr_test_n_conn_handle;
40 static uint16_t ble_att_svr_test_n_attr_handle;
41 static uint8_t ble_att_svr_test_attr_n[1024];
42 static uint16_t ble_att_svr_test_attr_n_len;
43
44 static int
ble_att_svr_test_misc_gap_cb(struct ble_gap_event * event,void * arg)45 ble_att_svr_test_misc_gap_cb(struct ble_gap_event *event, void *arg)
46 {
47 int rc;
48
49 switch (event->type) {
50 case BLE_GAP_EVENT_NOTIFY_RX:
51 ble_att_svr_test_n_conn_handle = event->notify_rx.conn_handle;
52 ble_att_svr_test_n_attr_handle = event->notify_rx.attr_handle;
53 TEST_ASSERT_FATAL(OS_MBUF_PKTLEN(event->notify_rx.om) <=
54 sizeof ble_att_svr_test_attr_n);
55 ble_att_svr_test_attr_n_len = OS_MBUF_PKTLEN(event->notify_rx.om);
56 rc = os_mbuf_copydata(event->notify_rx.om, 0,
57 ble_att_svr_test_attr_n_len,
58 ble_att_svr_test_attr_n);
59 TEST_ASSERT_FATAL(rc == 0);
60 break;
61
62 default:
63 break;
64 }
65
66 return 0;
67 }
68
69 /**
70 * @return The handle of the new test connection.
71 */
72 static uint16_t
ble_att_svr_test_misc_init(uint16_t mtu)73 ble_att_svr_test_misc_init(uint16_t mtu)
74 {
75 struct ble_l2cap_chan *chan;
76 struct ble_hs_conn *conn;
77 int rc;
78
79 ble_hs_test_util_init();
80
81 ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
82 ble_att_svr_test_misc_gap_cb, NULL);
83
84 ble_hs_lock();
85
86 rc = ble_hs_misc_conn_chan_find(2, BLE_L2CAP_CID_ATT, &conn, &chan);
87 TEST_ASSERT_FATAL(rc == 0);
88
89 if (mtu != 0) {
90 chan->my_mtu = mtu;
91 chan->peer_mtu = mtu;
92 chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
93 }
94
95 ble_hs_unlock();
96
97 ble_att_svr_test_attr_r_1_len = 0;
98 ble_att_svr_test_attr_r_2_len = 0;
99 ble_att_svr_test_attr_w_1_len = 0;
100
101 return 2;
102 }
103
104 static int
ble_att_svr_test_misc_attr_fn_r_1(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)105 ble_att_svr_test_misc_attr_fn_r_1(uint16_t conn_handle, uint16_t attr_handle,
106 uint8_t op, uint16_t offset,
107 struct os_mbuf **om, void *arg)
108 {
109 int rc;
110
111 switch (op) {
112 case BLE_ATT_ACCESS_OP_READ:
113 if (offset > ble_att_svr_test_attr_r_1_len) {
114 return BLE_ATT_ERR_INVALID_OFFSET;
115 }
116
117 rc = os_mbuf_append(*om, ble_att_svr_test_attr_r_1 + offset,
118 ble_att_svr_test_attr_r_1_len - offset);
119 TEST_ASSERT_FATAL(rc == 0);
120 return 0;
121
122 default:
123 return BLE_ATT_ERR_UNLIKELY;
124 }
125 }
126
127 static int
ble_att_svr_test_misc_attr_fn_r_2(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)128 ble_att_svr_test_misc_attr_fn_r_2(uint16_t conn_handle, uint16_t attr_handle,
129 uint8_t op, uint16_t offset,
130 struct os_mbuf **om, void *arg)
131 {
132 int rc;
133
134 switch (op) {
135 case BLE_ATT_ACCESS_OP_READ:
136 if (offset > ble_att_svr_test_attr_r_2_len) {
137 return BLE_ATT_ERR_INVALID_OFFSET;
138 }
139
140 rc = os_mbuf_append(*om, ble_att_svr_test_attr_r_2 + offset,
141 ble_att_svr_test_attr_r_2_len - offset);
142 TEST_ASSERT_FATAL(rc == 0);
143 return 0;
144
145 default:
146 return BLE_ATT_ERR_UNLIKELY;
147 }
148 }
149
150 static int
ble_att_svr_test_misc_attr_fn_r_err(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)151 ble_att_svr_test_misc_attr_fn_r_err(uint16_t conn_handle, uint16_t attr_handle,
152 uint8_t op, uint16_t offset,
153 struct os_mbuf **om, void *arg)
154 {
155 int rc;
156
157 rc = os_mbuf_append(*om, (uint8_t[4]){1,2,3,4}, 4);
158 TEST_ASSERT_FATAL(rc == 0);
159
160 return BLE_ATT_ERR_UNLIKELY;
161 }
162
163 #define BLE_ATT_SVR_TEST_LAST_SVC 11
164 #define BLE_ATT_SVR_TEST_LAST_ATTR 24
165
166 static int
ble_att_svr_test_misc_attr_fn_r_group(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)167 ble_att_svr_test_misc_attr_fn_r_group(uint16_t conn_handle,
168 uint16_t attr_handle,
169 uint8_t op,
170 uint16_t offset,
171 struct os_mbuf **om,
172 void *arg)
173 {
174 uint8_t *src;
175 int rc;
176
177 /* Service 0x1122 from 1 to 5 */
178 /* Service 0x2233 from 6 to 10 */
179 /* Service 010203...0f from 11 to 24 */
180
181 static uint8_t vals[25][16] = {
182 [1] = { 0x22, 0x11 },
183 [2] = { 0x01, 0x11 },
184 [3] = { 0x02, 0x11 },
185 [4] = { 0x03, 0x11 },
186 [5] = { 0x04, 0x11 },
187 [6] = { 0x33, 0x22 },
188 [7] = { 0x01, 0x22 },
189 [8] = { 0x02, 0x22 },
190 [9] = { 0x03, 0x22 },
191 [10] = { 0x04, 0x22 },
192 [11] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
193 [12] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
194 [13] = { 0xdd, 0xdd },
195 [14] = { 0x55, 0x55 },
196 [15] = { 0xdd, 0xdd },
197 [16] = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
198 [17] = { 0xdd, 0xdd },
199 [18] = { 0x66, 0x66 },
200 [19] = { 0xdd, 0xdd },
201 [20] = { 0x77, 0x77 },
202 [21] = { 0xdd, 0xdd },
203 [22] = { 0x88, 0x88 },
204 [23] = { 0xdd, 0xdd },
205 [24] = { 0x99, 0x99 },
206 };
207
208 static uint8_t zeros[14];
209
210 if (op != BLE_ATT_ACCESS_OP_READ) {
211 return -1;
212 }
213
214 TEST_ASSERT_FATAL(attr_handle >= 1 &&
215 attr_handle <= BLE_ATT_SVR_TEST_LAST_ATTR);
216
217 src = &vals[attr_handle][0];
218 if (memcmp(src + 2, zeros, 14) == 0) {
219 rc = os_mbuf_append(*om, src, 2);
220 } else {
221 rc = os_mbuf_append(*om, src, 16);
222 }
223 if (rc != 0) {
224 return BLE_ATT_ERR_INSUFFICIENT_RES;
225 }
226
227 return 0;
228 }
229
230 static void
ble_att_svr_test_misc_register_uuid(const ble_uuid_t * uuid,uint8_t flags,uint16_t expected_handle,ble_att_svr_access_fn * fn)231 ble_att_svr_test_misc_register_uuid(const ble_uuid_t *uuid, uint8_t flags,
232 uint16_t expected_handle,
233 ble_att_svr_access_fn *fn)
234 {
235 uint16_t handle;
236 int rc;
237
238 rc = ble_att_svr_register(uuid, flags, 0, &handle, fn, NULL);
239 TEST_ASSERT_FATAL(rc == 0);
240 TEST_ASSERT_FATAL(handle == expected_handle);
241 }
242
243 static void
ble_att_svr_test_misc_register_group_attrs(void)244 ble_att_svr_test_misc_register_group_attrs(void)
245 {
246 /* Service 0x1122 from 1 to 5 */
247 /* Service 0x2233 from 6 to 10 */
248 /* Service 010203...0f from 11 to 24 */
249
250 static const ble_uuid16_t uuid_svc =
251 BLE_UUID16_INIT(BLE_ATT_UUID_PRIMARY_SERVICE);
252 static const ble_uuid16_t uuid_inc =
253 BLE_UUID16_INIT(BLE_ATT_UUID_INCLUDE);
254 static const ble_uuid16_t uuid_chr =
255 BLE_UUID16_INIT(BLE_ATT_UUID_CHARACTERISTIC);
256 static ble_uuid16_t uuids[24];
257
258 int i;
259
260 /* Service 0x1122 from 1 to 5 */
261 ble_att_svr_test_misc_register_uuid(&uuid_svc.u, HA_FLAG_PERM_RW, 1,
262 ble_att_svr_test_misc_attr_fn_r_group);
263 for (i = 2; i <= 5; i++) {
264 if ((i - 2) % 2 == 0) {
265 ble_att_svr_test_misc_register_uuid(&uuid_chr.u, HA_FLAG_PERM_RW, i,
266 ble_att_svr_test_misc_attr_fn_r_group);
267 } else {
268 uuids[i] = *BLE_UUID16(BLE_UUID16_DECLARE(i));
269 ble_att_svr_test_misc_register_uuid(&uuids[i].u, HA_FLAG_PERM_RW, i,
270 ble_att_svr_test_misc_attr_fn_r_group);
271 }
272 }
273
274 /* Service 0x2233 from 6 to 10 */
275 ble_att_svr_test_misc_register_uuid(&uuid_svc.u, HA_FLAG_PERM_RW, 6,
276 ble_att_svr_test_misc_attr_fn_r_group);
277 for (i = 7; i <= 10; i++) {
278 ble_att_svr_test_misc_register_uuid(&uuid_inc.u, HA_FLAG_PERM_RW, i,
279 ble_att_svr_test_misc_attr_fn_r_group);
280 }
281
282 /* Service 010203...0f from 11 to 24 */
283 ble_att_svr_test_misc_register_uuid(&uuid_svc.u, HA_FLAG_PERM_RW, 11,
284 ble_att_svr_test_misc_attr_fn_r_group);
285 for (i = 12; i <= 24; i++) {
286 if ((i - 12) % 2 == 0) {
287 ble_att_svr_test_misc_register_uuid(&uuid_chr.u, HA_FLAG_PERM_RW, i,
288 ble_att_svr_test_misc_attr_fn_r_group);
289 } else {
290 uuids[i] = *BLE_UUID16(BLE_UUID16_DECLARE(i));
291 ble_att_svr_test_misc_register_uuid(&uuids[i].u, HA_FLAG_PERM_RW, i,
292 ble_att_svr_test_misc_attr_fn_r_group);
293 }
294 }
295 }
296
297 static int
ble_att_svr_test_misc_attr_fn_rw_1(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)298 ble_att_svr_test_misc_attr_fn_rw_1(uint16_t conn_handle, uint16_t attr_handle,
299 uint8_t op, uint16_t offset,
300 struct os_mbuf **om, void *arg)
301 {
302 int rc;
303
304 switch (op) {
305 case BLE_ATT_ACCESS_OP_READ:
306 if (offset > ble_att_svr_test_attr_w_1_len) {
307 return BLE_ATT_ERR_INVALID_OFFSET;
308 }
309
310 rc = os_mbuf_append(*om, ble_att_svr_test_attr_w_1 + offset,
311 ble_att_svr_test_attr_w_1_len - offset);
312 TEST_ASSERT_FATAL(rc == 0);
313 return 0;
314
315 case BLE_ATT_ACCESS_OP_WRITE:
316 rc = os_mbuf_copydata(*om, 0, OS_MBUF_PKTLEN(*om),
317 ble_att_svr_test_attr_w_1);
318 TEST_ASSERT_FATAL(rc == 0);
319 ble_att_svr_test_attr_w_1_len = OS_MBUF_PKTLEN(*om);
320 return 0;
321
322 default:
323 return BLE_ATT_ERR_UNLIKELY;
324 }
325 }
326
327 static int
ble_att_svr_test_misc_attr_fn_w_1(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)328 ble_att_svr_test_misc_attr_fn_w_1(uint16_t conn_handle, uint16_t attr_handle,
329 uint8_t op, uint16_t offset,
330 struct os_mbuf **om, void *arg)
331 {
332 int rc;
333
334 switch (op) {
335 case BLE_ATT_ACCESS_OP_WRITE:
336 rc = os_mbuf_copydata(*om, 0, OS_MBUF_PKTLEN(*om),
337 ble_att_svr_test_attr_w_1);
338 TEST_ASSERT_FATAL(rc == 0);
339 ble_att_svr_test_attr_w_1_len = OS_MBUF_PKTLEN(*om);
340 return 0;
341
342 default:
343 return BLE_ATT_ERR_UNLIKELY;
344 }
345 }
346
347 static int
ble_att_svr_test_misc_attr_fn_w_2(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)348 ble_att_svr_test_misc_attr_fn_w_2(uint16_t conn_handle, uint16_t attr_handle,
349 uint8_t op, uint16_t offset,
350 struct os_mbuf **om, void *arg)
351 {
352 int rc;
353
354 switch (op) {
355 case BLE_ATT_ACCESS_OP_WRITE:
356 rc = os_mbuf_copydata(*om, 0, OS_MBUF_PKTLEN(*om),
357 ble_att_svr_test_attr_w_2);
358 TEST_ASSERT_FATAL(rc == 0);
359 ble_att_svr_test_attr_w_2_len = OS_MBUF_PKTLEN(*om);
360 return 0;
361
362 default:
363 return BLE_ATT_ERR_UNLIKELY;
364 }
365 }
366
367 static int
ble_att_svr_test_misc_attr_fn_w_fail(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)368 ble_att_svr_test_misc_attr_fn_w_fail(uint16_t conn_handle,
369 uint16_t attr_handle,
370 uint8_t op, uint16_t offset,
371 struct os_mbuf **om, void *arg)
372 {
373 return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
374 }
375
376 static void
ble_att_svr_test_misc_verify_w_1(void * data,int data_len)377 ble_att_svr_test_misc_verify_w_1(void *data, int data_len)
378 {
379 TEST_ASSERT(ble_att_svr_test_attr_w_1_len == data_len);
380 TEST_ASSERT(memcmp(ble_att_svr_test_attr_w_1, data, data_len) == 0);
381 }
382
383 static void
ble_att_svr_test_misc_verify_w_2(void * data,int data_len)384 ble_att_svr_test_misc_verify_w_2(void *data, int data_len)
385 {
386 TEST_ASSERT(ble_att_svr_test_attr_w_2_len == data_len);
387 TEST_ASSERT(memcmp(ble_att_svr_test_attr_w_2, data, data_len) == 0);
388 }
389
390 static void
ble_att_svr_test_misc_rx_read_mult_req(uint16_t conn_handle,uint16_t * handles,int num_handles,int success)391 ble_att_svr_test_misc_rx_read_mult_req(uint16_t conn_handle,
392 uint16_t *handles, int num_handles,
393 int success)
394 {
395 int rc;
396
397 rc = ble_hs_test_util_rx_att_read_mult_req(conn_handle, handles,
398 num_handles);
399 if (success) {
400 TEST_ASSERT(rc == 0);
401 } else {
402 TEST_ASSERT(rc != 0);
403 }
404 }
405
406 static void
ble_att_svr_test_misc_verify_tx_read_mult_rsp(uint16_t conn_handle,struct ble_hs_test_util_flat_attr * attrs,int num_attrs)407 ble_att_svr_test_misc_verify_tx_read_mult_rsp(
408 uint16_t conn_handle, struct ble_hs_test_util_flat_attr *attrs,
409 int num_attrs)
410 {
411 struct ble_l2cap_chan *chan;
412 struct os_mbuf *om;
413 uint16_t attr_len;
414 uint16_t mtu;
415 uint8_t u8;
416 int rc;
417 int off;
418 int i;
419
420 om = ble_hs_test_util_prev_tx_dequeue();
421
422 rc = os_mbuf_copydata(om, 0, 1, &u8);
423 TEST_ASSERT(rc == 0);
424 TEST_ASSERT(u8 == BLE_ATT_OP_READ_MULT_RSP);
425
426 ble_hs_lock();
427
428 rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
429 NULL, &chan);
430 TEST_ASSERT_FATAL(rc == 0);
431 mtu = ble_att_chan_mtu(chan);
432
433 ble_hs_unlock();
434
435 off = 1;
436 for (i = 0; i < num_attrs; i++) {
437 attr_len = min(attrs[i].value_len, mtu - off);
438
439 rc = os_mbuf_cmpf(om, off, attrs[i].value, attr_len);
440 TEST_ASSERT(rc == 0);
441
442 off += attr_len;
443 }
444
445 TEST_ASSERT(OS_MBUF_PKTLEN(om) == off);
446 }
447
448 static void
ble_att_svr_test_misc_verify_all_read_mult(uint16_t conn_handle,struct ble_hs_test_util_flat_attr * attrs,int num_attrs)449 ble_att_svr_test_misc_verify_all_read_mult(
450 uint16_t conn_handle, struct ble_hs_test_util_flat_attr *attrs,
451 int num_attrs)
452 {
453 uint16_t handles[256];
454 int i;
455
456 TEST_ASSERT_FATAL(num_attrs <= sizeof handles / sizeof handles[0]);
457
458 for (i = 0; i < num_attrs; i++) {
459 handles[i] = attrs[i].handle;
460 }
461
462 ble_att_svr_test_misc_rx_read_mult_req(conn_handle, handles, num_attrs, 1);
463 ble_att_svr_test_misc_verify_tx_read_mult_rsp(conn_handle,
464 attrs, num_attrs);
465 }
466
467 static void
ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle)468 ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle)
469 {
470 struct ble_l2cap_chan *chan;
471 struct ble_hs_conn *conn;
472 uint16_t my_mtu;
473 int rc;
474
475 ble_hs_lock();
476
477 rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
478 assert(rc == 0);
479 my_mtu = chan->my_mtu;
480
481 ble_hs_unlock();
482
483 ble_hs_test_util_verify_tx_mtu_cmd(0, my_mtu);
484 }
485
486 struct ble_att_svr_test_type_value_entry {
487 uint16_t first; /* 0 on last entry */
488 uint16_t last;
489 };
490
491 static void
ble_att_svr_test_misc_verify_tx_find_type_value_rsp(struct ble_att_svr_test_type_value_entry * entries)492 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
493 struct ble_att_svr_test_type_value_entry *entries)
494 {
495 struct ble_att_svr_test_type_value_entry *entry;
496 struct os_mbuf *om;
497 uint16_t u16;
498 uint8_t op;
499 int off;
500 int rc;
501
502 off = 0;
503
504 om = ble_hs_test_util_prev_tx_dequeue_pullup();
505
506 rc = os_mbuf_copydata(om, off, 1, &op);
507 TEST_ASSERT(rc == 0);
508 off += 1;
509
510 TEST_ASSERT(op == BLE_ATT_OP_FIND_TYPE_VALUE_RSP);
511
512 for (entry = entries; entry->first != 0; entry++) {
513 rc = os_mbuf_copydata(om, off, 2, &u16);
514 TEST_ASSERT(rc == 0);
515 put_le16(&u16, u16);
516 TEST_ASSERT(u16 == entry->first);
517 off += 2;
518
519 rc = os_mbuf_copydata(om, off, 2, &u16);
520 TEST_ASSERT(rc == 0);
521 put_le16(&u16, u16);
522 TEST_ASSERT(u16 == entry->last);
523 off += 2;
524 }
525
526 /* Ensure there is no extra data in the response. */
527 TEST_ASSERT(off == OS_MBUF_PKTHDR(om)->omp_len);
528 }
529
530 /** Returns the number of entries successfully verified. */
531
532 struct ble_att_svr_test_type_entry {
533 uint16_t handle; /* 0 on last entry */
534 void *value;
535 int value_len;
536 };
537
538 /** Returns the number of entries successfully verified. */
539 static void
ble_att_svr_test_misc_verify_tx_read_type_rsp(struct ble_att_svr_test_type_entry * entries)540 ble_att_svr_test_misc_verify_tx_read_type_rsp(
541 struct ble_att_svr_test_type_entry *entries)
542 {
543 struct ble_att_svr_test_type_entry *entry;
544 struct ble_att_read_type_rsp rsp;
545 struct os_mbuf *om;
546 uint16_t handle;
547 uint8_t buf[512];
548 int off;
549 int rc;
550
551 om = ble_hs_test_util_prev_tx_dequeue_pullup();
552 TEST_ASSERT(om);
553
554 ble_att_read_type_rsp_parse(om->om_data, om->om_len, &rsp);
555
556 off = BLE_ATT_READ_TYPE_RSP_BASE_SZ;
557 for (entry = entries; entry->handle != 0; entry++) {
558 TEST_ASSERT_FATAL(rsp.batp_length ==
559 BLE_ATT_READ_TYPE_ADATA_BASE_SZ + entry->value_len);
560
561 rc = os_mbuf_copydata(om, off, 2, &handle);
562 TEST_ASSERT(rc == 0);
563 handle = get_le16(&handle);
564 TEST_ASSERT(handle == entry->handle);
565 off += 2;
566
567 rc = os_mbuf_copydata(om, off, entry->value_len, buf);
568 TEST_ASSERT(rc == 0);
569 TEST_ASSERT(memcmp(entry->value, buf, entry->value_len) == 0);
570 off += entry->value_len;
571 }
572
573 /* Ensure there is no extra data in the response. */
574 TEST_ASSERT(off == OS_MBUF_PKTLEN(om));
575 }
576
577 static void
ble_att_svr_test_misc_verify_tx_prep_write_rsp(uint16_t attr_handle,uint16_t offset,void * data,int data_len)578 ble_att_svr_test_misc_verify_tx_prep_write_rsp(uint16_t attr_handle,
579 uint16_t offset,
580 void *data, int data_len)
581 {
582 struct ble_att_prep_write_cmd rsp;
583 struct os_mbuf *om;
584 uint8_t buf[1024];
585 int rc;
586
587 om = ble_hs_test_util_prev_tx_dequeue();
588
589 rc = os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), buf);
590 TEST_ASSERT_FATAL(rc == 0);
591
592 ble_att_prep_write_rsp_parse(buf, sizeof buf, &rsp);
593
594 TEST_ASSERT(rsp.bapc_handle == attr_handle);
595 TEST_ASSERT(rsp.bapc_offset == offset);
596 TEST_ASSERT(memcmp(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, data,
597 data_len) == 0);
598
599 TEST_ASSERT(OS_MBUF_PKTLEN(om) ==
600 BLE_ATT_PREP_WRITE_CMD_BASE_SZ + data_len);
601 }
602
603 static void
ble_att_svr_test_misc_verify_tx_exec_write_rsp(void)604 ble_att_svr_test_misc_verify_tx_exec_write_rsp(void)
605 {
606 struct os_mbuf *om;
607
608 om = ble_hs_test_util_prev_tx_dequeue_pullup();
609 TEST_ASSERT(om);
610
611 ble_att_exec_write_rsp_parse(om->om_data, om->om_len);
612 }
613
614 static void
ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu,uint16_t peer_sent,uint16_t peer_actual,uint16_t chan_mtu)615 ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent,
616 uint16_t peer_actual, uint16_t chan_mtu)
617 {
618 struct ble_att_mtu_cmd req;
619 struct ble_l2cap_chan *chan;
620 struct ble_hs_conn *conn;
621 uint16_t conn_handle;
622 uint8_t buf[BLE_ATT_MTU_CMD_SZ];
623 int rc;
624
625 conn_handle = ble_att_svr_test_misc_init(my_mtu);
626
627 req.bamc_mtu = peer_sent;
628 ble_att_mtu_req_write(buf, sizeof buf, &req);
629
630 rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
631 buf, sizeof buf);
632 TEST_ASSERT(rc == 0);
633
634 ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle);
635
636 ble_hs_lock();
637 rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
638 &conn, &chan);
639 TEST_ASSERT_FATAL(rc == 0);
640 TEST_ASSERT(chan->peer_mtu == peer_actual);
641 TEST_ASSERT(ble_att_chan_mtu(chan) == chan_mtu);
642 ble_hs_unlock();
643
644 }
645
646 static void
ble_att_svr_test_misc_prep_write(uint16_t conn_handle,uint16_t attr_handle,uint16_t offset,void * data,int data_len,uint8_t error_code)647 ble_att_svr_test_misc_prep_write(uint16_t conn_handle, uint16_t attr_handle,
648 uint16_t offset, void *data,
649 int data_len, uint8_t error_code)
650 {
651 int rc;
652
653 rc = ble_hs_test_util_rx_att_prep_write_req(conn_handle, attr_handle,
654 offset, data, data_len);
655 if (error_code == 0) {
656 TEST_ASSERT(rc == 0);
657 ble_att_svr_test_misc_verify_tx_prep_write_rsp(attr_handle, offset,
658 data, data_len);
659 } else {
660 TEST_ASSERT(rc != 0);
661 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_PREP_WRITE_REQ,
662 attr_handle, error_code);
663 }
664 }
665
666 static void
ble_att_svr_test_misc_exec_write(uint16_t conn_handle,uint8_t flags,uint8_t error_code,uint16_t error_handle)667 ble_att_svr_test_misc_exec_write(uint16_t conn_handle, uint8_t flags,
668 uint8_t error_code, uint16_t error_handle)
669 {
670 int rc;
671
672 rc = ble_hs_test_util_rx_att_exec_write_req(conn_handle, flags);
673 if (error_code == 0) {
674 TEST_ASSERT(rc == 0);
675 ble_att_svr_test_misc_verify_tx_exec_write_rsp();
676 } else {
677 TEST_ASSERT(rc != 0);
678 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_EXEC_WRITE_REQ,
679 error_handle, error_code);
680 }
681 }
682
683 static void
ble_att_svr_test_misc_rx_notify(uint16_t conn_handle,uint16_t attr_handle,void * attr_val,int attr_len,int good)684 ble_att_svr_test_misc_rx_notify(uint16_t conn_handle, uint16_t attr_handle,
685 void *attr_val, int attr_len, int good)
686 {
687 struct ble_att_notify_req req;
688 uint8_t buf[1024];
689 int off;
690 int rc;
691
692 req.banq_handle = attr_handle;
693 ble_att_notify_req_write(buf, sizeof buf, &req);
694 off = BLE_ATT_NOTIFY_REQ_BASE_SZ;
695
696 memcpy(buf + off, attr_val, attr_len);
697 off += attr_len;
698
699 rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
700 buf, off);
701 if (good) {
702 TEST_ASSERT(rc == 0);
703 } else {
704 TEST_ASSERT(rc == BLE_HS_EBADDATA);
705 }
706 }
707
708 static void
ble_att_svr_test_misc_verify_notify(uint16_t conn_handle,uint16_t attr_handle,void * attr_val,int attr_len,int good)709 ble_att_svr_test_misc_verify_notify(uint16_t conn_handle, uint16_t attr_handle,
710 void *attr_val, int attr_len, int good)
711 {
712 ble_att_svr_test_n_conn_handle = 0xffff;
713 ble_att_svr_test_n_attr_handle = 0;
714 ble_att_svr_test_attr_n_len = 0;
715
716 ble_att_svr_test_misc_rx_notify(conn_handle, attr_handle, attr_val,
717 attr_len, good);
718
719 if (good) {
720 TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn_handle);
721 TEST_ASSERT(ble_att_svr_test_n_attr_handle == attr_handle);
722 TEST_ASSERT(ble_att_svr_test_attr_n_len == attr_len);
723 TEST_ASSERT(memcmp(ble_att_svr_test_attr_n, attr_val, attr_len) == 0);
724 } else {
725 TEST_ASSERT(ble_att_svr_test_n_conn_handle == 0xffff);
726 TEST_ASSERT(ble_att_svr_test_n_attr_handle == 0);
727 TEST_ASSERT(ble_att_svr_test_attr_n_len == 0);
728 }
729 }
730
731 static void
ble_att_svr_test_misc_verify_tx_indicate_rsp(void)732 ble_att_svr_test_misc_verify_tx_indicate_rsp(void)
733 {
734 struct os_mbuf *om;
735
736 om = ble_hs_test_util_prev_tx_dequeue_pullup();
737 TEST_ASSERT(om);
738
739 ble_att_indicate_rsp_parse(om->om_data, om->om_len);
740 }
741
742 static void
ble_att_svr_test_misc_rx_indicate(uint16_t conn_handle,uint16_t attr_handle,void * attr_val,int attr_len,int good)743 ble_att_svr_test_misc_rx_indicate(uint16_t conn_handle, uint16_t attr_handle,
744 void *attr_val, int attr_len, int good)
745 {
746 int rc;
747
748 rc = ble_hs_test_util_rx_att_indicate_req(conn_handle, attr_handle,
749 attr_val, attr_len);
750 if (good) {
751 TEST_ASSERT(rc == 0);
752 } else {
753 TEST_ASSERT(rc == BLE_HS_EBADDATA);
754 }
755 }
756
757 static void
ble_att_svr_test_misc_verify_indicate(uint16_t conn_handle,uint16_t attr_handle,void * attr_val,int attr_len,int good)758 ble_att_svr_test_misc_verify_indicate(uint16_t conn_handle,
759 uint16_t attr_handle,
760 void *attr_val, int attr_len, int good)
761 {
762 ble_att_svr_test_n_conn_handle = 0xffff;
763 ble_att_svr_test_n_attr_handle = 0;
764 ble_att_svr_test_attr_n_len = 0;
765
766 ble_att_svr_test_misc_rx_indicate(conn_handle, attr_handle, attr_val,
767 attr_len, good);
768
769 if (good) {
770 TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn_handle);
771 TEST_ASSERT(ble_att_svr_test_n_attr_handle == attr_handle);
772 TEST_ASSERT(ble_att_svr_test_attr_n_len == attr_len);
773 TEST_ASSERT(memcmp(ble_att_svr_test_attr_n, attr_val, attr_len) == 0);
774 ble_att_svr_test_misc_verify_tx_indicate_rsp();
775 } else {
776 TEST_ASSERT(ble_att_svr_test_n_conn_handle == 0xffff);
777 TEST_ASSERT(ble_att_svr_test_n_attr_handle == 0);
778 TEST_ASSERT(ble_att_svr_test_attr_n_len == 0);
779 TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() == 0);
780 }
781 }
782
TEST_CASE(ble_att_svr_test_mtu)783 TEST_CASE(ble_att_svr_test_mtu)
784 {
785 /*** MTU too low; should pretend peer sent default value instead. */
786 ble_att_svr_test_misc_mtu_exchange(BLE_ATT_MTU_DFLT, 5,
787 BLE_ATT_MTU_DFLT, BLE_ATT_MTU_DFLT);
788
789 /*** MTUs equal. */
790 ble_att_svr_test_misc_mtu_exchange(50, 50, 50, 50);
791
792 /*** Peer's higher than mine. */
793 ble_att_svr_test_misc_mtu_exchange(50, 100, 100, 50);
794
795 /*** Mine higher than peer's. */
796 ble_att_svr_test_misc_mtu_exchange(100, 50, 50, 50);
797 }
798
TEST_CASE(ble_att_svr_test_read)799 TEST_CASE(ble_att_svr_test_read)
800 {
801 struct ble_hs_conn *conn;
802 struct os_mbuf *om;
803 uint16_t attr_handle;
804 uint16_t conn_handle;
805 const ble_uuid_t *uuid_sec = BLE_UUID128_DECLARE( \
806 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
807 const ble_uuid_t *uuid_bad = BLE_UUID128_DECLARE( \
808 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
809 const ble_uuid_t *uuid = BLE_UUID128_DECLARE( \
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, );
811 int rc;
812
813 conn_handle = ble_att_svr_test_misc_init(0);
814
815 /*** Nonexistent attribute. */
816 attr_handle = 0;
817 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
818 TEST_ASSERT(rc != 0);
819 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, 0,
820 BLE_ATT_ERR_INVALID_HANDLE);
821
822 /*** Application error. */
823 rc = ble_att_svr_register(uuid_bad, HA_FLAG_PERM_RW, 0, &attr_handle,
824 ble_att_svr_test_misc_attr_fn_r_err, NULL);
825 TEST_ASSERT(rc == 0);
826
827 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
828 TEST_ASSERT(rc == BLE_HS_EAPP);
829 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, attr_handle,
830 BLE_ATT_ERR_UNLIKELY);
831
832 /*** Successful read. */
833 ble_att_svr_test_attr_r_1 = (uint8_t[]){0,1,2,3,4,5,6,7};
834 ble_att_svr_test_attr_r_1_len = 8;
835 rc = ble_att_svr_register(uuid, HA_FLAG_PERM_RW, 0, &attr_handle,
836 ble_att_svr_test_misc_attr_fn_r_1, NULL);
837 TEST_ASSERT(rc == 0);
838
839 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
840 TEST_ASSERT(rc == 0);
841 ble_hs_test_util_verify_tx_read_rsp(
842 ble_att_svr_test_attr_r_1, ble_att_svr_test_attr_r_1_len);
843
844 /*** Partial read. */
845 ble_att_svr_test_attr_r_1 =
846 (uint8_t[]){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
847 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39};
848 ble_att_svr_test_attr_r_1_len = 40;
849
850 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
851 TEST_ASSERT(rc == 0);
852 ble_hs_test_util_verify_tx_read_rsp(ble_att_svr_test_attr_r_1,
853 BLE_ATT_MTU_DFLT - 1);
854
855 /*** Read requires encryption. */
856 /* Insufficient authentication. */
857 rc = ble_att_svr_register(uuid_sec, BLE_ATT_F_READ | BLE_ATT_F_READ_ENC, 0,
858 &attr_handle,
859 ble_att_svr_test_misc_attr_fn_r_1, NULL);
860 TEST_ASSERT(rc == 0);
861
862 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
863 TEST_ASSERT(rc == BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN));
864 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, attr_handle,
865 BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
866
867 /* Security check bypassed for local reads. */
868 rc = ble_att_svr_read_local(attr_handle, &om);
869 TEST_ASSERT_FATAL(rc == 0);
870 TEST_ASSERT(OS_MBUF_PKTLEN(om) == ble_att_svr_test_attr_r_1_len);
871 TEST_ASSERT(os_mbuf_cmpf(om, 0, ble_att_svr_test_attr_r_1,
872 ble_att_svr_test_attr_r_1_len) == 0);
873 rc = os_mbuf_free_chain(om);
874 TEST_ASSERT_FATAL(rc == 0);
875
876 /* Ensure no response got sent. */
877 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
878
879 /* Encrypt link; success. */
880 ble_hs_lock();
881 conn = ble_hs_conn_find(conn_handle);
882 conn->bhc_sec_state.encrypted = 1;
883 ble_hs_unlock();
884
885 rc = ble_hs_test_util_rx_att_read_req(conn_handle, attr_handle);
886 TEST_ASSERT(rc == 0);
887 ble_hs_test_util_verify_tx_read_rsp(ble_att_svr_test_attr_r_1,
888 BLE_ATT_MTU_DFLT - 1);
889 }
890
TEST_CASE(ble_att_svr_test_read_blob)891 TEST_CASE(ble_att_svr_test_read_blob)
892 {
893 uint16_t attr_handle;
894 uint16_t conn_handle;
895 const ble_uuid_t *uuid = BLE_UUID128_DECLARE( \
896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
897 int rc;
898
899 conn_handle = ble_att_svr_test_misc_init(0);
900
901 /*** Nonexistent attribute. */
902 rc = ble_hs_test_util_rx_att_read_blob_req(conn_handle, 0, 0);
903 TEST_ASSERT(rc != 0);
904 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_BLOB_REQ, 0,
905 BLE_ATT_ERR_INVALID_HANDLE);
906
907 /*** Successful partial read. */
908 ble_att_svr_test_attr_r_1 =
909 (uint8_t[]){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
910 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39};
911 ble_att_svr_test_attr_r_1_len = 40;
912 rc = ble_att_svr_register(uuid, HA_FLAG_PERM_RW, 0, &attr_handle,
913 ble_att_svr_test_misc_attr_fn_r_1, NULL);
914 TEST_ASSERT(rc == 0);
915
916 rc = ble_hs_test_util_rx_att_read_blob_req(conn_handle, attr_handle, 0);
917 TEST_ASSERT(rc == 0);
918 ble_hs_test_util_verify_tx_read_blob_rsp(ble_att_svr_test_attr_r_1,
919 BLE_ATT_MTU_DFLT - 1);
920
921 /*** Read remainder of attribute. */
922 rc = ble_hs_test_util_rx_att_read_blob_req(conn_handle, attr_handle,
923 BLE_ATT_MTU_DFLT - 1);
924 TEST_ASSERT(rc == 0);
925 ble_hs_test_util_verify_tx_read_blob_rsp(
926 ble_att_svr_test_attr_r_1 + BLE_ATT_MTU_DFLT - 1,
927 40 - (BLE_ATT_MTU_DFLT - 1));
928
929 /*** Zero-length read. */
930 rc = ble_hs_test_util_rx_att_read_blob_req(conn_handle, attr_handle,
931 ble_att_svr_test_attr_r_1_len);
932 TEST_ASSERT(rc == 0);
933 ble_hs_test_util_verify_tx_read_blob_rsp(ble_att_svr_test_attr_r_1,
934 0);
935 }
936
TEST_CASE(ble_att_svr_test_read_mult)937 TEST_CASE(ble_att_svr_test_read_mult)
938 {
939 uint16_t conn_handle;
940 int rc;
941
942 conn_handle = ble_att_svr_test_misc_init(0);
943
944 struct ble_hs_test_util_flat_attr attrs[2] = {
945 {
946 .handle = 0,
947 .offset = 0,
948 .value = { 1, 2, 3, 4 },
949 .value_len = 4,
950 },
951 {
952 .handle = 0,
953 .offset = 0,
954 .value = { 2, 3, 4, 5, 6 },
955 .value_len = 5,
956 },
957 };
958
959 ble_att_svr_test_attr_r_1 = attrs[0].value;
960 ble_att_svr_test_attr_r_1_len = attrs[0].value_len;
961 ble_att_svr_test_attr_r_2 = attrs[1].value;
962 ble_att_svr_test_attr_r_2_len = attrs[1].value_len;
963
964 rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x1111), HA_FLAG_PERM_RW, 0,
965 &attrs[0].handle,
966 ble_att_svr_test_misc_attr_fn_r_1, NULL);
967 TEST_ASSERT(rc == 0);
968
969 rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x2222), HA_FLAG_PERM_RW, 0,
970 &attrs[1].handle,
971 ble_att_svr_test_misc_attr_fn_r_2, NULL);
972 TEST_ASSERT(rc == 0);
973
974 /*** Single nonexistent attribute. */
975 ble_att_svr_test_misc_rx_read_mult_req(
976 conn_handle, ((uint16_t[]){ 100 }), 1, 0);
977 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
978 100, BLE_ATT_ERR_INVALID_HANDLE);
979
980 /*** Single attribute. */
981 ble_att_svr_test_misc_verify_all_read_mult(conn_handle, &attrs[0], 1);
982
983 /*** Two attributes. */
984 ble_att_svr_test_misc_verify_all_read_mult(conn_handle, attrs, 2);
985
986 /*** Reverse order. */
987 ble_att_svr_test_misc_verify_all_read_mult(conn_handle, attrs, 2);
988
989 /*** Second attribute nonexistent; verify only error txed. */
990 ble_att_svr_test_misc_rx_read_mult_req(
991 conn_handle, ((uint16_t[]){ attrs[0].handle, 100 }), 2, 0);
992 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
993 100, BLE_ATT_ERR_INVALID_HANDLE);
994
995 /*** Response too long; verify only MTU bytes sent. */
996 attrs[0].value_len = 20;
997 memcpy(attrs[0].value,
998 ((uint8_t[]){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}),
999 attrs[0].value_len);
1000 ble_att_svr_test_attr_r_1_len = attrs[0].value_len;
1001
1002 attrs[1].value_len = 20;
1003 memcpy(attrs[1].value,
1004 ((uint8_t[]){
1005 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39
1006 }),
1007 attrs[1].value_len);
1008 ble_att_svr_test_attr_r_2_len = attrs[1].value_len;
1009
1010 ble_att_svr_test_misc_verify_all_read_mult(conn_handle, attrs, 2);
1011
1012 }
1013
TEST_CASE(ble_att_svr_test_write)1014 TEST_CASE(ble_att_svr_test_write)
1015 {
1016 struct ble_hs_conn *conn;
1017 uint16_t conn_handle;
1018 uint16_t attr_handle;
1019 const ble_uuid_t *uuid_sec = BLE_UUID128_DECLARE( \
1020 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1021 const ble_uuid_t *uuid_rw = BLE_UUID128_DECLARE( \
1022 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1023 const ble_uuid_t *uuid_r = BLE_UUID128_DECLARE( \
1024 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1025 int rc;
1026
1027 static const uint8_t attr_val[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
1028
1029 conn_handle = ble_att_svr_test_misc_init(0);
1030
1031 /*** Nonexistent attribute. */
1032 rc = ble_hs_test_util_rx_att_write_req(conn_handle, 0,
1033 attr_val, sizeof attr_val);
1034 TEST_ASSERT(rc != 0);
1035 ble_hs_test_util_verify_tx_err_rsp(
1036 BLE_ATT_OP_WRITE_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
1037
1038 /*** Write not permitted if non-local. */
1039 /* Non-local write (fail). */
1040 rc = ble_att_svr_register(uuid_r, BLE_ATT_F_READ, 0, &attr_handle,
1041 ble_att_svr_test_misc_attr_fn_w_1, NULL);
1042 TEST_ASSERT(rc == 0);
1043
1044 rc = ble_hs_test_util_rx_att_write_req(conn_handle, attr_handle,
1045 attr_val, sizeof attr_val);
1046 TEST_ASSERT(rc == BLE_HS_EREJECT);
1047 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
1048 attr_handle,
1049 BLE_ATT_ERR_WRITE_NOT_PERMITTED);
1050
1051 /* Local write (success). */
1052 rc = ble_hs_test_util_write_local_flat(attr_handle,
1053 attr_val, sizeof attr_val);
1054 TEST_ASSERT(rc == 0);
1055
1056 /* Ensure no response got sent. */
1057 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
1058
1059 /*** Successful write. */
1060 rc = ble_att_svr_register(uuid_rw, HA_FLAG_PERM_RW, 0, &attr_handle,
1061 ble_att_svr_test_misc_attr_fn_w_1, NULL);
1062 TEST_ASSERT(rc == 0);
1063
1064 rc = ble_hs_test_util_rx_att_write_req(conn_handle, attr_handle,
1065 attr_val, sizeof attr_val);
1066 TEST_ASSERT(rc == 0);
1067 ble_hs_test_util_verify_tx_write_rsp();
1068
1069 /*** Write requires encryption. */
1070 /* Insufficient authentication. */
1071 rc = ble_att_svr_register(uuid_sec, BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_ENC,
1072 0, &attr_handle,
1073 ble_att_svr_test_misc_attr_fn_w_1, NULL);
1074 TEST_ASSERT(rc == 0);
1075
1076 rc = ble_hs_test_util_rx_att_write_req(conn_handle, attr_handle,
1077 attr_val, sizeof attr_val);
1078 TEST_ASSERT(rc == BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN));
1079 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
1080 attr_handle,
1081 BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
1082
1083 /* Security check bypassed for local writes. */
1084 rc = ble_hs_test_util_write_local_flat(attr_handle,
1085 attr_val, sizeof attr_val);
1086 TEST_ASSERT(rc == 0);
1087
1088 /* Ensure no response got sent. */
1089 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
1090
1091 /* Encrypt link; success. */
1092 ble_hs_lock();
1093 conn = ble_hs_conn_find(conn_handle);
1094 conn->bhc_sec_state.encrypted = 1;
1095 ble_hs_unlock();
1096
1097 rc = ble_hs_test_util_rx_att_write_req(conn_handle, attr_handle,
1098 attr_val, sizeof attr_val);
1099 TEST_ASSERT(rc == 0);
1100 ble_hs_test_util_verify_tx_write_rsp();
1101 }
1102
TEST_CASE(ble_att_svr_test_find_info)1103 TEST_CASE(ble_att_svr_test_find_info)
1104 {
1105 uint16_t conn_handle;
1106 uint16_t handle1;
1107 uint16_t handle2;
1108 uint16_t handle3;
1109 const ble_uuid_t *uuid1 =
1110 BLE_UUID128_DECLARE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15);
1111 const ble_uuid_t *uuid2 =
1112 BLE_UUID128_DECLARE(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
1113 const ble_uuid_t *uuid3 = BLE_UUID16_DECLARE(0x000f);
1114 int rc;
1115
1116 conn_handle = ble_att_svr_test_misc_init(128);
1117
1118 /*** Start handle of 0. */
1119 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 0, 0);
1120 TEST_ASSERT(rc != 0);
1121 ble_hs_test_util_verify_tx_err_rsp(
1122 BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
1123
1124 /*** Start handle > end handle. */
1125 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 101, 100);
1126 TEST_ASSERT(rc != 0);
1127 ble_hs_test_util_verify_tx_err_rsp(
1128 BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE);
1129
1130 /*** No attributes. */
1131 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300);
1132 TEST_ASSERT(rc != 0);
1133 ble_hs_test_util_verify_tx_err_rsp(
1134 BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
1135
1136 /*** Range too late. */
1137 rc = ble_att_svr_register(uuid1, HA_FLAG_PERM_RW, 0, &handle1,
1138 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1139 TEST_ASSERT(rc == 0);
1140
1141 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300);
1142 TEST_ASSERT(rc != 0);
1143 ble_hs_test_util_verify_tx_err_rsp(
1144 BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
1145
1146 /*** One 128-bit entry. */
1147 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle1);
1148 TEST_ASSERT(rc == 0);
1149 ble_hs_test_util_verify_tx_find_info_rsp(
1150 ((struct ble_hs_test_util_att_info_entry[]) { {
1151 .handle = handle1,
1152 .uuid = BLE_UUID128_DECLARE(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),
1153 }, {
1154 .handle = 0,
1155 } }));
1156
1157 /*** Two 128-bit entries. */
1158 rc = ble_att_svr_register(uuid2, HA_FLAG_PERM_RW, 0, &handle2,
1159 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1160 TEST_ASSERT(rc == 0);
1161
1162 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle2);
1163 TEST_ASSERT(rc == 0);
1164 ble_hs_test_util_verify_tx_find_info_rsp(
1165 ((struct ble_hs_test_util_att_info_entry[]) { {
1166 .handle = handle1,
1167 .uuid = BLE_UUID128_DECLARE(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),
1168 }, {
1169 .handle = handle2,
1170 .uuid = BLE_UUID128_DECLARE(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16),
1171 }, {
1172 .handle = 0,
1173 } }));
1174
1175 /*** Two 128-bit entries; 16-bit entry doesn't get sent. */
1176 rc = ble_att_svr_register(uuid3, HA_FLAG_PERM_RW, 0, &handle3,
1177 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1178 TEST_ASSERT(rc == 0);
1179
1180 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle3);
1181 TEST_ASSERT(rc == 0);
1182 ble_hs_test_util_verify_tx_find_info_rsp(
1183 ((struct ble_hs_test_util_att_info_entry[]) { {
1184 .handle = handle1,
1185 .uuid = BLE_UUID128_DECLARE(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),
1186 }, {
1187 .handle = handle2,
1188 .uuid = BLE_UUID128_DECLARE(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16),
1189 }, {
1190 .handle = 0,
1191 } }));
1192
1193 /*** Remaining 16-bit entry requested. */
1194 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle3, handle3);
1195 TEST_ASSERT(rc == 0);
1196 ble_hs_test_util_verify_tx_find_info_rsp(
1197 ((struct ble_hs_test_util_att_info_entry[]) { {
1198 .handle = handle3,
1199 .uuid = BLE_UUID16_DECLARE(0x000f),
1200 }, {
1201 .handle = 0,
1202 } }));
1203
1204 }
1205
TEST_CASE(ble_att_svr_test_find_type_value)1206 TEST_CASE(ble_att_svr_test_find_type_value)
1207 {
1208 uint16_t conn_handle;
1209 uint16_t handle1;
1210 uint16_t handle2;
1211 uint16_t handle3;
1212 uint16_t handle4;
1213 uint16_t handle5;
1214 uint16_t handle_desc;
1215 const ble_uuid_t *uuid1 = BLE_UUID16_DECLARE(0x2800);
1216 const ble_uuid_t *uuid2 = BLE_UUID16_DECLARE(0x2803);
1217 const ble_uuid_t *uuid3 =
1218 BLE_UUID128_DECLARE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
1219 int rc;
1220
1221 conn_handle = ble_att_svr_test_misc_init(128);
1222
1223 ble_att_svr_test_attr_r_1 = (uint8_t[]){0x99, 0x99};
1224 ble_att_svr_test_attr_r_1_len = 2;
1225
1226 /*** Start handle of 0. */
1227 rc = ble_hs_test_util_rx_att_find_type_value_req(
1228 conn_handle, 0, 0, 0x2800, ble_att_svr_test_attr_r_1,
1229 ble_att_svr_test_attr_r_1_len);
1230 TEST_ASSERT(rc != 0);
1231 ble_hs_test_util_verify_tx_err_rsp(
1232 BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 0,
1233 BLE_ATT_ERR_INVALID_HANDLE);
1234
1235 /*** Start handle > end handle. */
1236 rc = ble_hs_test_util_rx_att_find_type_value_req(
1237 conn_handle, 101, 100, 0x2800, ble_att_svr_test_attr_r_1,
1238 ble_att_svr_test_attr_r_1_len);
1239 TEST_ASSERT(rc != 0);
1240 ble_hs_test_util_verify_tx_err_rsp(
1241 BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 101,
1242 BLE_ATT_ERR_INVALID_HANDLE);
1243
1244 /*** No attributes. */
1245 rc = ble_hs_test_util_rx_att_find_type_value_req(
1246 conn_handle, 200, 300, 0x2800, ble_att_svr_test_attr_r_1,
1247 ble_att_svr_test_attr_r_1_len);
1248 TEST_ASSERT(rc != 0);
1249 ble_hs_test_util_verify_tx_err_rsp(
1250 BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
1251 BLE_ATT_ERR_ATTR_NOT_FOUND);
1252
1253 /*** Range too late. */
1254 rc = ble_att_svr_register(uuid1, HA_FLAG_PERM_RW, 0, &handle1,
1255 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1256 TEST_ASSERT(rc == 0);
1257
1258 rc = ble_hs_test_util_rx_att_find_type_value_req(
1259 conn_handle, 200, 300, 0x2800, ble_att_svr_test_attr_r_1,
1260 ble_att_svr_test_attr_r_1_len);
1261 TEST_ASSERT(rc != 0);
1262 ble_hs_test_util_verify_tx_err_rsp(
1263 BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
1264 BLE_ATT_ERR_ATTR_NOT_FOUND);
1265
1266 /*** One entry, one attribute. */
1267 rc = ble_hs_test_util_rx_att_find_type_value_req(
1268 conn_handle, handle1, handle1, 0x2800, ble_att_svr_test_attr_r_1,
1269 ble_att_svr_test_attr_r_1_len);
1270 TEST_ASSERT(rc == 0);
1271 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
1272 ((struct ble_att_svr_test_type_value_entry[]) { {
1273 .first = handle1,
1274 .last = handle1,
1275 }, {
1276 .first = 0,
1277 } }));
1278
1279 /*** One entry, two attributes. */
1280 rc = ble_att_svr_register(uuid2, HA_FLAG_PERM_RW, 0, &handle2,
1281 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1282 TEST_ASSERT(rc == 0);
1283
1284 rc = ble_hs_test_util_rx_att_find_type_value_req(
1285 conn_handle, handle1, handle2, 0x2800, ble_att_svr_test_attr_r_1,
1286 ble_att_svr_test_attr_r_1_len);
1287 TEST_ASSERT(rc == 0);
1288 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
1289 ((struct ble_att_svr_test_type_value_entry[]) { {
1290 .first = handle1,
1291 .last = handle2,
1292 }, {
1293 .first = 0,
1294 } }));
1295
1296 /*** Entry 1: four attributes; entry 2 (invalid value): one attribute;
1297 * entry 3: one attribute; Check that invalid value is not returned. */
1298 ble_att_svr_test_attr_r_2 = (uint8_t[]){0x00, 0x00};
1299 ble_att_svr_test_attr_r_2_len = 2;
1300
1301 rc = ble_att_svr_register(uuid3, HA_FLAG_PERM_RW, 0, &handle_desc,
1302 ble_att_svr_test_misc_attr_fn_r_2, NULL);
1303 TEST_ASSERT(rc == 0);
1304
1305 rc = ble_att_svr_register(uuid2, HA_FLAG_PERM_RW, 0, &handle3,
1306 ble_att_svr_test_misc_attr_fn_r_2, NULL);
1307 TEST_ASSERT(rc == 0);
1308
1309 rc = ble_att_svr_register(uuid1, HA_FLAG_PERM_RW, 0, &handle4,
1310 ble_att_svr_test_misc_attr_fn_r_2, NULL);
1311 TEST_ASSERT(rc == 0);
1312
1313 rc = ble_att_svr_register(uuid1, HA_FLAG_PERM_RW, 0, &handle5,
1314 ble_att_svr_test_misc_attr_fn_r_1, NULL);
1315 TEST_ASSERT(rc == 0);
1316
1317 rc = ble_hs_test_util_rx_att_find_type_value_req(
1318 conn_handle, 0x0001, 0xffff, 0x2800, ble_att_svr_test_attr_r_1,
1319 ble_att_svr_test_attr_r_1_len);
1320 TEST_ASSERT(rc == 0);
1321 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
1322 ((struct ble_att_svr_test_type_value_entry[]) { {
1323 .first = handle1,
1324 .last = handle3,
1325 }, {
1326 .first = handle5,
1327 .last = handle5,
1328 }, {
1329 .first = 0,
1330 } }));
1331
1332 /*** As above, check proper range is returned with smaller search range */
1333 rc = ble_hs_test_util_rx_att_find_type_value_req(
1334 conn_handle, 0x0001, 0x0001, 0x2800, ble_att_svr_test_attr_r_1,
1335 ble_att_svr_test_attr_r_1_len);
1336 TEST_ASSERT(rc == 0);
1337 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
1338 ((struct ble_att_svr_test_type_value_entry[]) { {
1339 .first = handle1,
1340 .last = handle3,
1341 }, {
1342 .first = 0,
1343 } }));
1344
1345 /*** As above, check grouping by Characteristic UUID */
1346 rc = ble_hs_test_util_rx_att_find_type_value_req(
1347 conn_handle, handle1, handle3, 0x2803, ble_att_svr_test_attr_r_1,
1348 ble_att_svr_test_attr_r_1_len);
1349 TEST_ASSERT(rc == 0);
1350 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
1351 ((struct ble_att_svr_test_type_value_entry[]) { {
1352 .first = handle2,
1353 .last = handle_desc,
1354 }, {
1355 .first = 0,
1356 } }));
1357 }
1358
1359 static void
ble_att_svr_test_misc_read_type(uint16_t mtu)1360 ble_att_svr_test_misc_read_type(uint16_t mtu)
1361 {
1362 uint16_t conn_handle;
1363 int rc;
1364
1365 conn_handle = ble_att_svr_test_misc_init(mtu);
1366
1367 /*** Start handle of 0. */
1368 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 0, 0,
1369 BLE_ATT_UUID_PRIMARY_SERVICE);
1370 TEST_ASSERT(rc != 0);
1371 ble_hs_test_util_verify_tx_err_rsp(
1372 BLE_ATT_OP_READ_TYPE_REQ, 0,
1373 BLE_ATT_ERR_INVALID_HANDLE);
1374
1375 /*** Start handle > end handle. */
1376 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 101, 100,
1377 BLE_ATT_UUID_PRIMARY_SERVICE);
1378 TEST_ASSERT(rc != 0);
1379 ble_hs_test_util_verify_tx_err_rsp(
1380 BLE_ATT_OP_READ_TYPE_REQ, 101,
1381 BLE_ATT_ERR_INVALID_HANDLE);
1382
1383 /*** No attributes. */
1384 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 1, 0xffff,
1385 BLE_ATT_UUID_PRIMARY_SERVICE);
1386 TEST_ASSERT(rc != 0);
1387 ble_hs_test_util_verify_tx_err_rsp(
1388 BLE_ATT_OP_READ_TYPE_REQ, 1,
1389 BLE_ATT_ERR_ATTR_NOT_FOUND);
1390
1391 /*** Range too late. */
1392 ble_att_svr_test_misc_register_group_attrs();
1393 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 200, 300,
1394 BLE_ATT_UUID_PRIMARY_SERVICE);
1395 TEST_ASSERT(rc != 0);
1396 ble_hs_test_util_verify_tx_err_rsp(
1397 BLE_ATT_OP_READ_TYPE_REQ, 200,
1398 BLE_ATT_ERR_ATTR_NOT_FOUND);
1399
1400 /*** One characteristic from one service. */
1401 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 1, 2,
1402 BLE_ATT_UUID_CHARACTERISTIC);
1403 TEST_ASSERT(rc == 0);
1404 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1405 ((struct ble_att_svr_test_type_entry[]) { {
1406 .handle = 2,
1407 .value = (uint8_t[]){ 0x01, 0x11 },
1408 .value_len = 2,
1409 }, {
1410 .handle = 0,
1411 } }));
1412
1413 /*** Both characteristics from one service. */
1414 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 1, 10,
1415 BLE_ATT_UUID_CHARACTERISTIC);
1416 TEST_ASSERT(rc == 0);
1417 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1418 ((struct ble_att_svr_test_type_entry[]) { {
1419 .handle = 2,
1420 .value = (uint8_t[]){ 0x01, 0x11 },
1421 .value_len = 2,
1422 }, {
1423 .handle = 4,
1424 .value = (uint8_t[]){ 0x03, 0x11 },
1425 .value_len = 2,
1426 }, {
1427 .handle = 0,
1428 } }));
1429
1430 /*** Ensure 16-bit and 128-bit values are retrieved separately. */
1431 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 11, 0xffff,
1432 BLE_ATT_UUID_CHARACTERISTIC);
1433 TEST_ASSERT(rc == 0);
1434 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1435 ((struct ble_att_svr_test_type_entry[]) { {
1436 .handle = 12,
1437 .value = (uint8_t[]){ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
1438 .value_len = 16,
1439 }, {
1440 .handle = 0,
1441 } }));
1442
1443 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 13, 0xffff,
1444 BLE_ATT_UUID_CHARACTERISTIC);
1445 TEST_ASSERT(rc == 0);
1446 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1447 ((struct ble_att_svr_test_type_entry[]) { {
1448 .handle = 14,
1449 .value = (uint8_t[]){ 0x55, 0x55 },
1450 .value_len = 2,
1451 }, {
1452 .handle = 0,
1453 } }));
1454
1455 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 15, 0xffff,
1456 BLE_ATT_UUID_CHARACTERISTIC);
1457 TEST_ASSERT(rc == 0);
1458 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1459 ((struct ble_att_svr_test_type_entry[]) { {
1460 .handle = 16,
1461 .value = (uint8_t[]){ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
1462 .value_len = 16,
1463 }, {
1464 .handle = 0,
1465 } }));
1466
1467 /*** Read until the end of the attribute list. */
1468 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 17, 0xffff,
1469 BLE_ATT_UUID_CHARACTERISTIC);
1470 TEST_ASSERT(rc == 0);
1471 ble_att_svr_test_misc_verify_tx_read_type_rsp(
1472 ((struct ble_att_svr_test_type_entry[]) { {
1473 .handle = 18,
1474 .value = (uint8_t[]){ 0x66, 0x66 },
1475 .value_len = 2,
1476 }, {
1477 .handle = 20,
1478 .value = (uint8_t[]){ 0x77, 0x77 },
1479 .value_len = 2,
1480 }, {
1481 .handle = 22,
1482 .value = (uint8_t[]){ 0x88, 0x88 },
1483 .value_len = 2,
1484 }, {
1485 .handle = 24,
1486 .value = (uint8_t[]){ 0x99, 0x99 },
1487 .value_len = 2,
1488 }, {
1489 .handle = 0,
1490 } }));
1491
1492 }
1493
TEST_CASE(ble_att_svr_test_read_type)1494 TEST_CASE(ble_att_svr_test_read_type)
1495 {
1496 ble_att_svr_test_misc_read_type(0);
1497 ble_att_svr_test_misc_read_type(128);
1498 }
1499
TEST_CASE(ble_att_svr_test_read_group_type)1500 TEST_CASE(ble_att_svr_test_read_group_type)
1501 {
1502 uint16_t conn_handle;
1503 int rc;
1504
1505 conn_handle = ble_att_svr_test_misc_init(128);
1506
1507 /*** Start handle of 0. */
1508 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1509 conn_handle, 0, 0, BLE_ATT_UUID_PRIMARY_SERVICE);
1510 TEST_ASSERT(rc != 0);
1511 ble_hs_test_util_verify_tx_err_rsp(
1512 BLE_ATT_OP_READ_GROUP_TYPE_REQ, 0,
1513 BLE_ATT_ERR_INVALID_HANDLE);
1514
1515 /*** Start handle > end handle. */
1516 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1517 conn_handle, 101, 100, BLE_ATT_UUID_PRIMARY_SERVICE);
1518 TEST_ASSERT(rc != 0);
1519 ble_hs_test_util_verify_tx_err_rsp(
1520 BLE_ATT_OP_READ_GROUP_TYPE_REQ, 101,
1521 BLE_ATT_ERR_INVALID_HANDLE);
1522
1523 /*** Invalid group UUID (0x1234). */
1524 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1525 conn_handle, 110, 150, 0x1234);
1526 TEST_ASSERT(rc != 0);
1527 ble_hs_test_util_verify_tx_err_rsp(
1528 BLE_ATT_OP_READ_GROUP_TYPE_REQ, 110,
1529 BLE_ATT_ERR_UNSUPPORTED_GROUP);
1530
1531 /*** No attributes. */
1532 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1533 conn_handle, 1, 0xffff, BLE_ATT_UUID_PRIMARY_SERVICE);
1534 TEST_ASSERT(rc != 0);
1535 ble_hs_test_util_verify_tx_err_rsp(
1536 BLE_ATT_OP_READ_GROUP_TYPE_REQ, 1,
1537 BLE_ATT_ERR_ATTR_NOT_FOUND);
1538
1539 /*** Range too late. */
1540 ble_att_svr_test_misc_register_group_attrs();
1541
1542 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1543 conn_handle, 200, 300, BLE_ATT_UUID_PRIMARY_SERVICE);
1544 TEST_ASSERT(rc != 0);
1545 ble_hs_test_util_verify_tx_err_rsp(
1546 BLE_ATT_OP_READ_GROUP_TYPE_REQ, 200,
1547 BLE_ATT_ERR_ATTR_NOT_FOUND);
1548
1549 /*** One 16-bit UUID service. */
1550 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1551 conn_handle, 1, 5, BLE_ATT_UUID_PRIMARY_SERVICE);
1552 TEST_ASSERT(rc == 0);
1553 ble_hs_test_util_verify_tx_read_group_type_rsp(
1554 ((struct ble_hs_test_util_att_group_type_entry[]) { {
1555 .start_handle = 1,
1556 .end_handle = 5,
1557 .uuid = BLE_UUID16_DECLARE(0x1122),
1558 }, {
1559 .start_handle = 0,
1560 } }));
1561
1562 /*** Two 16-bit UUID services. */
1563 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1564 conn_handle, 1, 10, BLE_ATT_UUID_PRIMARY_SERVICE);
1565 TEST_ASSERT(rc == 0);
1566 ble_hs_test_util_verify_tx_read_group_type_rsp(
1567 ((struct ble_hs_test_util_att_group_type_entry[]) { {
1568 .start_handle = 1,
1569 .end_handle = 5,
1570 .uuid = BLE_UUID16_DECLARE(0x1122),
1571 }, {
1572 .start_handle = 6,
1573 .end_handle = 10,
1574 .uuid = BLE_UUID16_DECLARE(0x2233),
1575 }, {
1576 .start_handle = 0,
1577 } }));
1578
1579 /*** Two 16-bit UUID services; ensure 128-bit service not returned. */
1580 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1581 conn_handle, 1, 100, BLE_ATT_UUID_PRIMARY_SERVICE);
1582 TEST_ASSERT(rc == 0);
1583 ble_hs_test_util_verify_tx_read_group_type_rsp(
1584 ((struct ble_hs_test_util_att_group_type_entry[]) { {
1585 .start_handle = 1,
1586 .end_handle = 5,
1587 .uuid = BLE_UUID16_DECLARE(0x1122),
1588 }, {
1589 .start_handle = 6,
1590 .end_handle = 10,
1591 .uuid = BLE_UUID16_DECLARE(0x2233),
1592 }, {
1593 .start_handle = 0,
1594 } }));
1595
1596 /*** One 128-bit service. */
1597 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1598 conn_handle, 11, 100, BLE_ATT_UUID_PRIMARY_SERVICE);
1599 TEST_ASSERT(rc == 0);
1600 ble_hs_test_util_verify_tx_read_group_type_rsp(
1601 ((struct ble_hs_test_util_att_group_type_entry[]) { {
1602 .start_handle = 11,
1603 .end_handle = 0xffff,
1604 .uuid = BLE_UUID128_DECLARE(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16),
1605 }, {
1606 .start_handle = 0,
1607 } }));
1608
1609 }
1610
TEST_CASE(ble_att_svr_test_prep_write)1611 TEST_CASE(ble_att_svr_test_prep_write)
1612 {
1613 struct ble_hs_conn *conn;
1614 uint16_t conn_handle;
1615 int i;
1616
1617 static uint8_t data[1024];
1618
1619 conn_handle = ble_att_svr_test_misc_init(205);
1620
1621 /* Initialize some attribute data. */
1622 for (i = 0; i < sizeof data; i++) {
1623 data[i] = i;
1624 }
1625
1626 /* Register two writable attributes. */
1627 ble_att_svr_test_misc_register_uuid(BLE_UUID16_DECLARE(0x1234),
1628 HA_FLAG_PERM_RW, 1,
1629 ble_att_svr_test_misc_attr_fn_w_1);
1630 ble_att_svr_test_misc_register_uuid(BLE_UUID16_DECLARE(0x8989),
1631 HA_FLAG_PERM_RW, 2,
1632 ble_att_svr_test_misc_attr_fn_w_2);
1633
1634 /* 3: not writable. */
1635 ble_att_svr_test_misc_register_uuid(BLE_UUID16_DECLARE(0xabab),
1636 BLE_ATT_F_READ, 3,
1637 ble_att_svr_test_misc_attr_fn_r_1);
1638 /* 4: Encryption required. */
1639 ble_att_svr_test_misc_register_uuid(
1640 BLE_UUID16_DECLARE(0xabac), BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_ENC, 4,
1641 ble_att_svr_test_misc_attr_fn_w_1);
1642
1643 /* 5: Encryption+authentication required. */
1644 ble_att_svr_test_misc_register_uuid(
1645 BLE_UUID16_DECLARE(0xabad),
1646 BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_ENC | BLE_ATT_F_WRITE_AUTHEN,
1647 5, ble_att_svr_test_misc_attr_fn_w_1);
1648
1649 /* 6: Write callback always fails. */
1650 ble_att_svr_test_misc_register_uuid(
1651 BLE_UUID16_DECLARE(0xabae), BLE_ATT_F_WRITE, 6,
1652 ble_att_svr_test_misc_attr_fn_w_fail);
1653
1654 /*** Empty write succeeds. */
1655 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1656 0, 0);
1657
1658 /*** Empty cancel succeeds. */
1659 ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
1660
1661 /*** Failure for prep write to nonexistent attribute. */
1662 ble_att_svr_test_misc_prep_write(conn_handle, 53525, 0, data, 10,
1663 BLE_ATT_ERR_INVALID_HANDLE);
1664
1665 /*** Failure due to write-not-permitted. */
1666 ble_att_svr_test_misc_prep_write(conn_handle, 3, 0, data, 35,
1667 BLE_ATT_ERR_WRITE_NOT_PERMITTED);
1668
1669 /*** Failure due to insufficient authentication (encryption required). */
1670 ble_att_svr_test_misc_prep_write(conn_handle, 4, 0, data, 1,
1671 BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
1672
1673 /*** Encrypt connection; ensure previous prep write now succeeds. */
1674 ble_hs_lock();
1675 conn = ble_hs_conn_find(2);
1676 TEST_ASSERT_FATAL(conn != NULL);
1677 conn->bhc_sec_state.encrypted = 1;
1678 ble_hs_unlock();
1679
1680 ble_att_svr_test_misc_prep_write(conn_handle, 4, 0, data, 1, 0);
1681 ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
1682
1683 /*** Failure due to insufficient authentication (not authenticated). */
1684 ble_att_svr_test_misc_prep_write(conn_handle, 5, 0, data, 35,
1685 BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
1686
1687 /*** Failure for write starting at nonzero offset. */
1688 ble_att_svr_test_misc_prep_write(conn_handle, 1, 1, data, 10, 0);
1689 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1690 BLE_ATT_ERR_INVALID_OFFSET, 1);
1691 ble_att_svr_test_misc_verify_w_1(NULL, 0);
1692
1693 /*** Success for clear starting at nonzero offset. */
1694 ble_att_svr_test_misc_prep_write(conn_handle, 1, 1, data, 10, 0);
1695 ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
1696 ble_att_svr_test_misc_verify_w_1(NULL, 0);
1697
1698 /*** Failure for write with gap. */
1699 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 10, 0);
1700 ble_att_svr_test_misc_prep_write(conn_handle, 1, 11, data, 10, 0);
1701 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1702 BLE_ATT_ERR_INVALID_OFFSET, 1);
1703 ble_att_svr_test_misc_verify_w_1(NULL, 0);
1704
1705 /*** Success for clear with gap. */
1706 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 10, 0);
1707 ble_att_svr_test_misc_prep_write(conn_handle, 1, 11, data, 10, 0);
1708 ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
1709 ble_att_svr_test_misc_verify_w_1(NULL, 0);
1710
1711 /*** Failure for overlong write. */
1712 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 200, 0);
1713 ble_att_svr_test_misc_prep_write(conn_handle, 1, 200, data + 200, 200, 0);
1714 ble_att_svr_test_misc_prep_write(conn_handle, 1, 400, data + 400, 200, 0);
1715 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1716 BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN, 1);
1717 ble_att_svr_test_misc_verify_w_1(NULL, 0);
1718
1719 /*** Successful two part write. */
1720 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 20, 0);
1721 ble_att_svr_test_misc_prep_write(conn_handle, 1, 20, data + 20, 20, 0);
1722 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1723 0, 0);
1724 ble_att_svr_test_misc_verify_w_1(data, 40);
1725
1726 /*** Successful three part write. */
1727 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 35, 0);
1728 ble_att_svr_test_misc_prep_write(conn_handle, 1, 35, data + 35, 43, 0);
1729 ble_att_svr_test_misc_prep_write(conn_handle, 1, 78, data + 78, 1, 0);
1730 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1731 0, 0);
1732 ble_att_svr_test_misc_verify_w_1(data, 79);
1733
1734 /*** Successful two part write to two attributes. */
1735 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 7, 0);
1736 ble_att_svr_test_misc_prep_write(conn_handle, 1, 7, data + 7, 10, 0);
1737 ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 20, 0);
1738 ble_att_svr_test_misc_prep_write(conn_handle, 2, 20, data + 20, 10, 0);
1739 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1740 0, 0);
1741 ble_att_svr_test_misc_verify_w_1(data, 17);
1742 ble_att_svr_test_misc_verify_w_2(data, 30);
1743
1744 /*** Fail write to second attribute; ensure first write doesn't occur. */
1745 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 5, 0);
1746 ble_att_svr_test_misc_prep_write(conn_handle, 1, 5, data + 5, 2, 0);
1747 ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 11, 0);
1748 ble_att_svr_test_misc_prep_write(conn_handle, 2, 12, data + 11, 19, 0);
1749 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1750 BLE_ATT_ERR_INVALID_OFFSET, 2);
1751 ble_att_svr_test_misc_verify_w_1(data, 17);
1752 ble_att_svr_test_misc_verify_w_2(data, 30);
1753
1754 /*** Successful out of order write to two attributes. */
1755 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 9, 0);
1756 ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 18, 0);
1757 ble_att_svr_test_misc_prep_write(conn_handle, 1, 9, data + 9, 3, 0);
1758 ble_att_svr_test_misc_prep_write(conn_handle, 2, 18, data + 18, 43, 0);
1759 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1760 0, 0);
1761 ble_att_svr_test_misc_verify_w_1(data, 12);
1762 ble_att_svr_test_misc_verify_w_2(data, 61);
1763
1764 /*** Fail due to attribute callback error. */
1765 ble_att_svr_test_misc_prep_write(conn_handle, 6, 0, data, 35, 0);
1766 ble_att_svr_test_misc_prep_write(conn_handle, 6, 35, data + 35, 43, 0);
1767 ble_att_svr_test_misc_prep_write(conn_handle, 6, 78, data + 78, 1, 0);
1768 ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_EXECUTE,
1769 BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN, 6);
1770 }
1771
TEST_CASE(ble_att_svr_test_notify)1772 TEST_CASE(ble_att_svr_test_notify)
1773 {
1774 uint16_t conn_handle;
1775
1776 conn_handle = ble_att_svr_test_misc_init(0);
1777
1778 /*** Successful notifies; verify callback is executed. */
1779 /* 3-length attribute. */
1780 ble_att_svr_test_misc_verify_notify(conn_handle, 10,
1781 (uint8_t[]) { 1, 2, 3 }, 3, 1);
1782 /* 1-length attribute. */
1783 ble_att_svr_test_misc_verify_notify(conn_handle, 1,
1784 (uint8_t[]) { 0xff }, 1, 1);
1785 /* 0-length attribute. */
1786 ble_att_svr_test_misc_verify_notify(conn_handle, 43, NULL, 0, 1);
1787
1788 /*** Bad notifies; verify callback is not executed. */
1789 /* Attribute handle of 0. */
1790 ble_att_svr_test_misc_verify_notify(conn_handle, 0,
1791 (uint8_t[]) { 1, 2, 3 }, 3, 0);
1792
1793 }
1794
TEST_CASE(ble_att_svr_test_prep_write_tmo)1795 TEST_CASE(ble_att_svr_test_prep_write_tmo)
1796 {
1797 int32_t ticks_from_now;
1798 uint16_t conn_handle;
1799 int rc;
1800 int i;
1801
1802 static uint8_t data[1024];
1803
1804 conn_handle = ble_att_svr_test_misc_init(205);
1805
1806 /* Initialize some attribute data. */
1807 for (i = 0; i < sizeof data; i++) {
1808 data[i] = i;
1809 }
1810
1811 /* Register a writable attribute. */
1812 ble_att_svr_test_misc_register_uuid(BLE_UUID16_DECLARE(0x1234),
1813 HA_FLAG_PERM_RW, 1,
1814 ble_att_svr_test_misc_attr_fn_w_1);
1815
1816 /* Ensure timer is not set. */
1817 ticks_from_now = ble_hs_conn_timer();
1818 TEST_ASSERT_FATAL(ticks_from_now == BLE_HS_FOREVER);
1819
1820 /* Receive a prepare write request. */
1821 ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 7, 0);
1822
1823 /* Ensure timer will expire in 30 seconds. */
1824 ticks_from_now = ble_hs_conn_timer();
1825 TEST_ASSERT(ticks_from_now == BLE_HS_ATT_SVR_QUEUED_WRITE_TMO);
1826
1827 /* Almost let the timer expire. */
1828 os_time_advance(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO - 1);
1829 ticks_from_now = ble_hs_conn_timer();
1830 TEST_ASSERT(ticks_from_now == 1);
1831
1832 /* Receive a second prepare write request. */
1833 ble_att_svr_test_misc_prep_write(conn_handle, 1, 7, data + 7, 10, 0);
1834
1835 /* Ensure timer got reset. */
1836 ticks_from_now = ble_hs_conn_timer();
1837 TEST_ASSERT(ticks_from_now == BLE_HS_ATT_SVR_QUEUED_WRITE_TMO);
1838
1839 /* Allow the timer to expire. */
1840 ble_hs_test_util_hci_ack_set_disconnect(0);
1841 os_time_advance(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO);
1842 ticks_from_now = ble_hs_conn_timer();
1843 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
1844
1845 /* Ensure connection was terminated. */
1846 ble_hs_test_util_hci_verify_tx_disconnect(2, BLE_ERR_REM_USER_CONN_TERM);
1847
1848 /* Free connection. This is needed so that the prep write mbufs get
1849 * freed and no mbuf leak gets reported.
1850 */
1851 rc = ble_hs_atomic_conn_delete(conn_handle);
1852 TEST_ASSERT_FATAL(rc == 0);
1853 }
1854
TEST_CASE(ble_att_svr_test_indicate)1855 TEST_CASE(ble_att_svr_test_indicate)
1856 {
1857 uint16_t conn_handle;
1858
1859 conn_handle = ble_att_svr_test_misc_init(0);
1860
1861 /*** Successful indicates; verify callback is executed. */
1862 /* 3-length attribute. */
1863 ble_att_svr_test_misc_verify_indicate(conn_handle, 10,
1864 (uint8_t[]) { 1, 2, 3 }, 3, 1);
1865 /* 1-length attribute. */
1866 ble_att_svr_test_misc_verify_indicate(conn_handle, 1,
1867 (uint8_t[]) { 0xff }, 1, 1);
1868 /* 0-length attribute. */
1869 ble_att_svr_test_misc_verify_indicate(conn_handle, 43, NULL, 0, 1);
1870
1871 /*** Bad indicates; verify callback is not executed. */
1872 /* Attribute handle of 0. */
1873 ble_att_svr_test_misc_verify_indicate(conn_handle, 0,
1874 (uint8_t[]) { 1, 2, 3 }, 3, 0);
1875 }
1876
TEST_CASE(ble_att_svr_test_oom)1877 TEST_CASE(ble_att_svr_test_oom)
1878 {
1879 struct os_mbuf *oms;
1880 uint16_t conn_handle;
1881 int rc;
1882
1883 conn_handle = ble_att_svr_test_misc_init(0);
1884
1885 /* Register an attribute (primary service) for incoming read commands. */
1886 ble_att_svr_test_misc_register_uuid(
1887 BLE_UUID16_DECLARE(BLE_ATT_UUID_PRIMARY_SERVICE),
1888 HA_FLAG_PERM_RW, 1, ble_att_svr_test_misc_attr_fn_rw_1);
1889 ble_att_svr_test_attr_w_1_len = 2;
1890 ble_att_svr_test_attr_w_1[0] = 0x12;
1891 ble_att_svr_test_attr_w_1[1] = 0x34;
1892
1893 /* Exhaust the msys pool. Leave one mbuf for the forthcoming request. */
1894 oms = ble_hs_test_util_mbuf_alloc_all_but(1);
1895
1896 /*** MTU; always respond affirmatively, even when no mbufs. */
1897
1898 /* Receive a request. */
1899 rc = ble_hs_test_util_rx_att_mtu_cmd(conn_handle, 1, 100);
1900 TEST_ASSERT_FATAL(rc == 0);
1901
1902 /* Ensure we were able to send a real response. */
1903 ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle);
1904
1905 /*** Find information; always respond affirmatively, even when no mbufs. */
1906 ble_hs_test_util_prev_tx_dequeue();
1907
1908 /* Receive a request. */
1909 rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 1, 100);
1910 TEST_ASSERT_FATAL(rc == 0);
1911
1912 /* Ensure we were able to send a real response. */
1913 ble_hs_test_util_verify_tx_find_info_rsp(
1914 (struct ble_hs_test_util_att_info_entry[]) {
1915 { .handle = 1, .uuid = BLE_UUID16_DECLARE(BLE_ATT_UUID_PRIMARY_SERVICE) },
1916 { 0 },
1917 });
1918
1919 /*** Find by type value. */
1920 ble_hs_test_util_prev_tx_dequeue();
1921
1922 /* Receive a request. */
1923 rc = ble_hs_test_util_rx_att_find_type_value_req(
1924 conn_handle, 1, 100, 0x0001, ((uint8_t[2]){0x99, 0x99}), 2);
1925 TEST_ASSERT_FATAL(rc == BLE_HS_ENOMEM);
1926
1927 /* Ensure we were able to send an error response. */
1928 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 1,
1929 BLE_ATT_ERR_INSUFFICIENT_RES);
1930
1931 /*** Read by type; always respond affirmatively, even when no mbufs. */
1932 ble_hs_test_util_prev_tx_dequeue();
1933
1934 /* Receive a request. */
1935 rc = ble_hs_test_util_rx_att_read_type_req16(conn_handle, 100, 0xffff,
1936 BLE_ATT_UUID_PRIMARY_SERVICE);
1937 TEST_ASSERT_FATAL(rc == BLE_HS_ENOENT);
1938
1939 /* Ensure we were able to send a non-OOM error response. */
1940 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_TYPE_REQ, 100,
1941 BLE_ATT_ERR_ATTR_NOT_FOUND);
1942
1943 /*** Read; always respond affirmatively, even when no mbufs. */
1944 ble_hs_test_util_prev_tx_dequeue();
1945
1946 /* Receive a request. */
1947 rc = ble_hs_test_util_rx_att_read_req(conn_handle, 1);
1948 TEST_ASSERT_FATAL(rc == 0);
1949
1950 /* Ensure we were able to send a real response. */
1951 ble_hs_test_util_verify_tx_read_rsp(ble_att_svr_test_attr_w_1,
1952 ble_att_svr_test_attr_w_1_len);
1953
1954 /*** Read blob; always respond affirmatively, even when no mbufs. */
1955 ble_hs_test_util_prev_tx_dequeue();
1956
1957 /* Receive a request. */
1958 rc = ble_hs_test_util_rx_att_read_blob_req(conn_handle, 1, 0);
1959 TEST_ASSERT_FATAL(rc == 0);
1960
1961 /* Ensure we were able to send a real response. */
1962 ble_hs_test_util_verify_tx_read_blob_rsp(ble_att_svr_test_attr_w_1,
1963 ble_att_svr_test_attr_w_1_len);
1964
1965 /*** Read multiple. */
1966 ble_hs_test_util_prev_tx_dequeue();
1967
1968 /* Receive a request. */
1969 rc = ble_hs_test_util_rx_att_read_mult_req(conn_handle,
1970 ((uint16_t[2]){0x0001, 0x0002}),
1971 2);
1972 TEST_ASSERT_FATAL(rc == BLE_HS_ENOMEM);
1973
1974 /* Ensure we were able to send an error response. */
1975 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ, 0,
1976 BLE_ATT_ERR_INSUFFICIENT_RES);
1977
1978 /***
1979 * Read by group type; always respond affirmatively, even when no
1980 * mbufs.
1981 */
1982 ble_hs_test_util_prev_tx_dequeue();
1983
1984 /* Receive a request. */
1985 rc = ble_hs_test_util_rx_att_read_group_type_req16(
1986 conn_handle, 11, 100, BLE_ATT_UUID_PRIMARY_SERVICE);
1987 TEST_ASSERT_FATAL(rc == BLE_HS_ENOENT);
1988
1989 /* Ensure we were able to send a non-OOM error response. */
1990 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_GROUP_TYPE_REQ, 11,
1991 BLE_ATT_ERR_ATTR_NOT_FOUND);
1992
1993 /*** Write. */
1994 ble_hs_test_util_prev_tx_dequeue();
1995
1996 /* Receive a request. */
1997 rc = ble_hs_test_util_rx_att_write_req(conn_handle, 1,
1998 ((uint8_t[1]){1}), 1);
1999 TEST_ASSERT_FATAL(rc == BLE_HS_ENOMEM);
2000
2001 /* Ensure we were able to send an error response. */
2002 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ, 1,
2003 BLE_ATT_ERR_INSUFFICIENT_RES);
2004
2005 /*** Write command; no response. */
2006 ble_hs_test_util_prev_tx_dequeue();
2007
2008 /* Receive a request. */
2009 rc = ble_hs_test_util_rx_att_write_cmd(conn_handle, 1,
2010 ((uint8_t[1]){1}), 1);
2011 TEST_ASSERT_FATAL(rc == 0);
2012
2013 /* Ensure no response sent. */
2014 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
2015
2016 /*** Prepare write. */
2017 ble_hs_test_util_prev_tx_dequeue();
2018
2019 /* Receive a request. */
2020 rc = ble_hs_test_util_rx_att_prep_write_req(conn_handle, 1, 0,
2021 ((uint8_t[1]){1}), 1);
2022 TEST_ASSERT_FATAL(rc == BLE_HS_ENOMEM);
2023
2024 /* Ensure we were able to send an error response. */
2025 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_PREP_WRITE_REQ, 1,
2026 BLE_ATT_ERR_INSUFFICIENT_RES);
2027
2028 /*** Notify; no response. */
2029 ble_hs_test_util_prev_tx_dequeue();
2030
2031 /* Receive a request. */
2032 rc = ble_hs_test_util_rx_att_notify_req(conn_handle, 1,
2033 ((uint8_t[1]){1}), 1);
2034 TEST_ASSERT_FATAL(rc == 0);
2035
2036 /* Ensure no response sent. */
2037 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
2038
2039 /*** Indicate. */
2040 ble_hs_test_util_prev_tx_dequeue();
2041
2042 /* Receive a request. */
2043 rc = ble_hs_test_util_rx_att_indicate_req(conn_handle, 1,
2044 ((uint8_t[1]){1}), 1);
2045 TEST_ASSERT_FATAL(rc == BLE_HS_ENOMEM);
2046
2047 /* Ensure we were able to send a real response. */
2048 ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_INDICATE_REQ, 1,
2049 BLE_ATT_ERR_INSUFFICIENT_RES);
2050
2051 rc = os_mbuf_free_chain(oms);
2052 TEST_ASSERT_FATAL(rc == 0);
2053 }
2054
TEST_CASE(ble_att_svr_test_unsupported_req)2055 TEST_CASE(ble_att_svr_test_unsupported_req)
2056 {
2057 uint16_t conn_handle;
2058 int rc;
2059 uint8_t buf[] = {0x3f, 0x00, 0x00, 0x01, 0x02, 0x03};
2060
2061 conn_handle = ble_att_svr_test_misc_init(0);
2062
2063 /* Put handle into buf */
2064 (*(uint16_t *)&buf[1]) = htole16(conn_handle);
2065 rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
2066 buf, sizeof buf);
2067 TEST_ASSERT(rc != 0);
2068 ble_hs_test_util_verify_tx_err_rsp(0x3f, 0,
2069 BLE_ATT_ERR_REQ_NOT_SUPPORTED);
2070
2071 /* Check for no response when unknown command is sent */
2072 buf[0] = 0x4f;
2073 rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
2074 buf, sizeof buf);
2075 TEST_ASSERT(rc != 0);
2076
2077 /* Ensure no response sent. */
2078 TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
2079 }
2080
TEST_SUITE(ble_att_svr_suite)2081 TEST_SUITE(ble_att_svr_suite)
2082 {
2083 /* When checking for mbuf leaks, ensure no stale prep entries. */
2084 static struct ble_hs_test_util_mbuf_params mbuf_params = {
2085 .prev_tx = 1,
2086 .rx_queue = 1,
2087 .prep_list = 0,
2088 };
2089
2090 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, &mbuf_params);
2091
2092 ble_att_svr_test_mtu();
2093 ble_att_svr_test_read();
2094 ble_att_svr_test_read_blob();
2095 ble_att_svr_test_read_mult();
2096 ble_att_svr_test_write();
2097 ble_att_svr_test_find_info();
2098 ble_att_svr_test_find_type_value();
2099 ble_att_svr_test_read_type();
2100 ble_att_svr_test_read_group_type();
2101 ble_att_svr_test_prep_write();
2102 ble_att_svr_test_prep_write_tmo();
2103 ble_att_svr_test_notify();
2104 ble_att_svr_test_indicate();
2105 ble_att_svr_test_oom();
2106 ble_att_svr_test_unsupported_req();
2107 }
2108
2109 int
ble_att_svr_test_all(void)2110 ble_att_svr_test_all(void)
2111 {
2112 ble_att_svr_suite();
2113
2114 return tu_any_failed;
2115 }
2116