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 <string.h>
21 #include <errno.h>
22 #include "testutil/testutil.h"
23 #include "nimble/ble.h"
24 #include "host/ble_hs_test.h"
25 #include "ble_hs_test_util.h"
26
27 #define BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE 0x9383
28 #define BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE 0x1234
29
30 static uint8_t ble_gatt_conn_test_write_value[] = { 1, 3, 64, 21, 6 };
31
32 struct ble_gatt_conn_test_arg {
33 uint16_t exp_conn_handle;
34 int exp_status;
35 int called;
36 };
37
38 static struct ble_gap_event ble_gatt_conn_test_gap_event;
39
40 static void
ble_gatt_conn_test_util_init(void)41 ble_gatt_conn_test_util_init(void)
42 {
43 ble_hs_test_util_init();
44 memset(&ble_gatt_conn_test_gap_event, -1,
45 sizeof ble_gatt_conn_test_gap_event);
46 }
47
48 static int
ble_gatt_conn_test_indicate_cb(struct ble_gap_event * event,void * arg)49 ble_gatt_conn_test_indicate_cb(struct ble_gap_event *event, void *arg)
50 {
51 /* Only record indication failures. */
52 if (event->type == BLE_GAP_EVENT_NOTIFY_TX &&
53 event->notify_tx.status != 0) {
54
55 ble_gatt_conn_test_gap_event = *event;
56 }
57 return 0;
58 }
59
60 static int
ble_gatt_conn_test_attr_cb(uint16_t conn_handle,uint16_t attr_handle,uint8_t op,uint16_t offset,struct os_mbuf ** om,void * arg)61 ble_gatt_conn_test_attr_cb(uint16_t conn_handle, uint16_t attr_handle,
62 uint8_t op, uint16_t offset, struct os_mbuf **om,
63 void *arg)
64 {
65 uint8_t *buf;
66
67 switch (op) {
68 case BLE_ATT_ACCESS_OP_READ:
69 buf = os_mbuf_extend(*om, 1);
70 TEST_ASSERT_FATAL(buf != NULL);
71 *buf = 1;
72 return 0;
73
74 default:
75 return -1;
76 }
77 }
78
79 static int
ble_gatt_conn_test_mtu_cb(uint16_t conn_handle,const struct ble_gatt_error * error,uint16_t mtu,void * arg)80 ble_gatt_conn_test_mtu_cb(uint16_t conn_handle,
81 const struct ble_gatt_error *error,
82 uint16_t mtu, void *arg)
83 {
84 struct ble_gatt_conn_test_arg *cb_arg;
85
86 cb_arg = arg;
87
88 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
89 TEST_ASSERT(!cb_arg->called);
90 TEST_ASSERT_FATAL(error != NULL);
91 TEST_ASSERT(error->status == cb_arg->exp_status);
92 TEST_ASSERT(mtu == 0);
93
94 cb_arg->called++;
95
96 return 0;
97 }
98
99 static int
ble_gatt_conn_test_disc_all_svcs_cb(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_svc * service,void * arg)100 ble_gatt_conn_test_disc_all_svcs_cb(uint16_t conn_handle,
101 const struct ble_gatt_error *error,
102 const struct ble_gatt_svc *service,
103 void *arg)
104 {
105 struct ble_gatt_conn_test_arg *cb_arg;
106
107 cb_arg = arg;
108
109 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
110 TEST_ASSERT(!cb_arg->called);
111 TEST_ASSERT_FATAL(error != NULL);
112 TEST_ASSERT(error->status == cb_arg->exp_status);
113 TEST_ASSERT(service == NULL);
114
115 cb_arg->called++;
116
117 return 0;
118 }
119
120 static int
ble_gatt_conn_test_disc_svc_uuid_cb(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_svc * service,void * arg)121 ble_gatt_conn_test_disc_svc_uuid_cb(uint16_t conn_handle,
122 const struct ble_gatt_error *error,
123 const struct ble_gatt_svc *service,
124 void *arg)
125 {
126 struct ble_gatt_conn_test_arg *cb_arg;
127
128 cb_arg = arg;
129
130 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
131 TEST_ASSERT(!cb_arg->called);
132 TEST_ASSERT_FATAL(error != NULL);
133 TEST_ASSERT(error->status == cb_arg->exp_status);
134 TEST_ASSERT(service == NULL);
135
136 cb_arg->called++;
137
138 return 0;
139 }
140
141 static int
ble_gatt_conn_test_find_inc_svcs_cb(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_svc * service,void * arg)142 ble_gatt_conn_test_find_inc_svcs_cb(uint16_t conn_handle,
143 const struct ble_gatt_error *error,
144 const struct ble_gatt_svc *service,
145 void *arg)
146 {
147 struct ble_gatt_conn_test_arg *cb_arg;
148
149 cb_arg = arg;
150
151 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
152 TEST_ASSERT(!cb_arg->called);
153 TEST_ASSERT_FATAL(error != NULL);
154 TEST_ASSERT(error->status == cb_arg->exp_status);
155 TEST_ASSERT(service == NULL);
156
157 cb_arg->called++;
158
159 return 0;
160 }
161
162 static int
ble_gatt_conn_test_disc_all_chrs_cb(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_chr * chr,void * arg)163 ble_gatt_conn_test_disc_all_chrs_cb(uint16_t conn_handle,
164 const struct ble_gatt_error *error,
165 const struct ble_gatt_chr *chr, void *arg)
166 {
167 struct ble_gatt_conn_test_arg *cb_arg;
168
169 cb_arg = arg;
170
171 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
172 TEST_ASSERT(!cb_arg->called);
173 TEST_ASSERT_FATAL(error != NULL);
174 TEST_ASSERT(error->status == cb_arg->exp_status);
175 TEST_ASSERT(chr == NULL);
176
177 cb_arg->called++;
178
179 return 0;
180 }
181
182 static int
ble_gatt_conn_test_disc_chr_uuid_cb(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_chr * chr,void * arg)183 ble_gatt_conn_test_disc_chr_uuid_cb(uint16_t conn_handle,
184 const struct ble_gatt_error *error,
185 const struct ble_gatt_chr *chr, void *arg)
186 {
187 struct ble_gatt_conn_test_arg *cb_arg;
188
189 cb_arg = arg;
190
191 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
192 TEST_ASSERT(!cb_arg->called);
193 TEST_ASSERT_FATAL(error != NULL);
194 TEST_ASSERT(error->status == cb_arg->exp_status);
195 TEST_ASSERT(chr == NULL);
196
197 cb_arg->called++;
198
199 return 0;
200 }
201
202 static int
ble_gatt_conn_test_disc_all_dscs_cb(uint16_t conn_handle,const struct ble_gatt_error * error,uint16_t chr_def_handle,const struct ble_gatt_dsc * dsc,void * arg)203 ble_gatt_conn_test_disc_all_dscs_cb(uint16_t conn_handle,
204 const struct ble_gatt_error *error,
205 uint16_t chr_def_handle,
206 const struct ble_gatt_dsc *dsc,
207 void *arg)
208 {
209 struct ble_gatt_conn_test_arg *cb_arg;
210
211 cb_arg = arg;
212
213 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
214 TEST_ASSERT(!cb_arg->called);
215 TEST_ASSERT_FATAL(error != NULL);
216 TEST_ASSERT(error->status == cb_arg->exp_status);
217 TEST_ASSERT(dsc == NULL);
218
219 cb_arg->called++;
220
221 return 0;
222 }
223
224 static int
ble_gatt_conn_test_read_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)225 ble_gatt_conn_test_read_cb(uint16_t conn_handle,
226 const struct ble_gatt_error *error,
227 struct ble_gatt_attr *attr, void *arg)
228 {
229 struct ble_gatt_conn_test_arg *cb_arg;
230
231 cb_arg = arg;
232
233 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
234 TEST_ASSERT(!cb_arg->called);
235 TEST_ASSERT_FATAL(error != NULL);
236 TEST_ASSERT(error->status == cb_arg->exp_status);
237 TEST_ASSERT(attr == NULL);
238
239 cb_arg->called++;
240
241 return 0;
242 }
243
244 static int
ble_gatt_conn_test_read_uuid_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)245 ble_gatt_conn_test_read_uuid_cb(uint16_t conn_handle,
246 const struct ble_gatt_error *error,
247 struct ble_gatt_attr *attr, void *arg)
248 {
249 struct ble_gatt_conn_test_arg *cb_arg;
250
251 cb_arg = arg;
252
253 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
254 TEST_ASSERT(!cb_arg->called);
255 TEST_ASSERT_FATAL(error != NULL);
256 TEST_ASSERT(error->status == cb_arg->exp_status);
257 TEST_ASSERT(attr == NULL);
258
259 cb_arg->called++;
260
261 return 0;
262 }
263
264 static int
ble_gatt_conn_test_read_long_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)265 ble_gatt_conn_test_read_long_cb(uint16_t conn_handle,
266 const struct ble_gatt_error *error,
267 struct ble_gatt_attr *attr, void *arg)
268 {
269 struct ble_gatt_conn_test_arg *cb_arg;
270
271 cb_arg = arg;
272
273 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
274 TEST_ASSERT(!cb_arg->called);
275 TEST_ASSERT_FATAL(error != NULL);
276 TEST_ASSERT(error->status == cb_arg->exp_status);
277 TEST_ASSERT(attr == NULL);
278
279 cb_arg->called++;
280
281 return 0;
282 }
283 static int
ble_gatt_conn_test_read_mult_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)284 ble_gatt_conn_test_read_mult_cb(uint16_t conn_handle,
285 const struct ble_gatt_error *error,
286 struct ble_gatt_attr *attr, void *arg)
287 {
288 struct ble_gatt_conn_test_arg *cb_arg;
289
290 cb_arg = arg;
291
292 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
293 TEST_ASSERT(!cb_arg->called);
294 TEST_ASSERT_FATAL(error != NULL);
295 TEST_ASSERT(error->status == cb_arg->exp_status);
296 TEST_ASSERT(attr->om == NULL);
297
298 cb_arg->called++;
299
300 return 0;
301 }
302
303 static int
ble_gatt_conn_test_write_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)304 ble_gatt_conn_test_write_cb(uint16_t conn_handle,
305 const struct ble_gatt_error *error,
306 struct ble_gatt_attr *attr,
307 void *arg)
308 {
309 struct ble_gatt_conn_test_arg *cb_arg;
310
311 cb_arg = arg;
312
313 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
314 TEST_ASSERT(!cb_arg->called);
315 TEST_ASSERT_FATAL(error != NULL);
316 TEST_ASSERT(error->status == cb_arg->exp_status);
317 TEST_ASSERT(attr != NULL);
318 TEST_ASSERT(attr->handle == BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE);
319
320 cb_arg->called++;
321
322 return 0;
323 }
324
325 static int
ble_gatt_conn_test_write_long_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)326 ble_gatt_conn_test_write_long_cb(uint16_t conn_handle,
327 const struct ble_gatt_error *error,
328 struct ble_gatt_attr *attr, void *arg)
329 {
330 struct ble_gatt_conn_test_arg *cb_arg;
331
332 cb_arg = arg;
333
334 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
335 TEST_ASSERT(!cb_arg->called);
336 TEST_ASSERT_FATAL(error != NULL);
337 TEST_ASSERT(error->status == cb_arg->exp_status);
338 TEST_ASSERT(attr != NULL);
339 TEST_ASSERT(attr->handle == BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE);
340
341 cb_arg->called++;
342
343 return 0;
344 }
345
346 static int
ble_gatt_conn_test_write_rel_cb(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attrs,uint8_t num_attrs,void * arg)347 ble_gatt_conn_test_write_rel_cb(uint16_t conn_handle,
348 const struct ble_gatt_error *error,
349 struct ble_gatt_attr *attrs,
350 uint8_t num_attrs,
351 void *arg)
352 {
353 struct ble_gatt_conn_test_arg *cb_arg;
354
355 cb_arg = arg;
356
357 TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
358 TEST_ASSERT(!cb_arg->called);
359 TEST_ASSERT_FATAL(error != NULL);
360 TEST_ASSERT(error->status == cb_arg->exp_status);
361 TEST_ASSERT(attrs != NULL);
362
363 cb_arg->called++;
364
365 return 0;
366 }
367
TEST_CASE(ble_gatt_conn_test_disconnect)368 TEST_CASE(ble_gatt_conn_test_disconnect)
369 {
370 struct ble_gatt_conn_test_arg mtu_arg = { 0, BLE_HS_ENOTCONN };
371 struct ble_gatt_conn_test_arg disc_all_svcs_arg = { 0, BLE_HS_ENOTCONN };
372 struct ble_gatt_conn_test_arg disc_svc_uuid_arg = { 0, BLE_HS_ENOTCONN };
373 struct ble_gatt_conn_test_arg find_inc_svcs_arg = { 0, BLE_HS_ENOTCONN };
374 struct ble_gatt_conn_test_arg disc_all_chrs_arg = { 0, BLE_HS_ENOTCONN };
375 struct ble_gatt_conn_test_arg disc_chr_uuid_arg = { 0, BLE_HS_ENOTCONN };
376 struct ble_gatt_conn_test_arg disc_all_dscs_arg = { 0, BLE_HS_ENOTCONN };
377 struct ble_gatt_conn_test_arg read_arg = { 0, BLE_HS_ENOTCONN };
378 struct ble_gatt_conn_test_arg read_uuid_arg = { 0, BLE_HS_ENOTCONN };
379 struct ble_gatt_conn_test_arg read_long_arg = { 0, BLE_HS_ENOTCONN };
380 struct ble_gatt_conn_test_arg read_mult_arg = { 0, BLE_HS_ENOTCONN };
381 struct ble_gatt_conn_test_arg write_arg = { 0, BLE_HS_ENOTCONN };
382 struct ble_gatt_conn_test_arg write_long_arg = { 0, BLE_HS_ENOTCONN };
383 struct ble_gatt_conn_test_arg write_rel_arg = { 0, BLE_HS_ENOTCONN };
384 struct ble_gatt_attr attr;
385 uint16_t attr_handle;
386 uint16_t offset = 0;
387 int rc;
388
389 ble_gatt_conn_test_util_init();
390
391 /*** Register an attribute to allow indicatations to be sent. */
392 rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x1212), BLE_ATT_F_READ, 0,
393 &attr_handle,
394 ble_gatt_conn_test_attr_cb, NULL);
395 TEST_ASSERT(rc == 0);
396
397 /* Create three connections. */
398 ble_hs_test_util_create_conn(1, ((uint8_t[]){1,2,3,4,5,6,7,8}),
399 ble_gatt_conn_test_indicate_cb, NULL);
400 ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
401 ble_gatt_conn_test_indicate_cb, NULL);
402 ble_hs_test_util_create_conn(3, ((uint8_t[]){3,4,5,6,7,8,9,10}),
403 ble_gatt_conn_test_indicate_cb, NULL);
404
405 /*** Schedule some GATT procedures. */
406 /* Connection 1. */
407 mtu_arg.exp_conn_handle = 1;
408 ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg);
409
410 disc_all_svcs_arg.exp_conn_handle = 1;
411 rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb,
412 &disc_all_svcs_arg);
413 TEST_ASSERT_FATAL(rc == 0);
414
415 disc_svc_uuid_arg.exp_conn_handle = 1;
416 rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16_DECLARE(0x1111),
417 ble_gatt_conn_test_disc_svc_uuid_cb,
418 &disc_svc_uuid_arg);
419 TEST_ASSERT_FATAL(rc == 0);
420
421 find_inc_svcs_arg.exp_conn_handle = 1;
422 rc = ble_gattc_find_inc_svcs(1, 1, 0xffff,
423 ble_gatt_conn_test_find_inc_svcs_cb,
424 &find_inc_svcs_arg);
425 TEST_ASSERT_FATAL(rc == 0);
426
427 disc_all_chrs_arg.exp_conn_handle = 1;
428 rc = ble_gattc_disc_all_chrs(1, 1, 0xffff,
429 ble_gatt_conn_test_disc_all_chrs_cb,
430 &disc_all_chrs_arg);
431 TEST_ASSERT_FATAL(rc == 0);
432
433 /* Connection 2. */
434 disc_all_dscs_arg.exp_conn_handle = 2;
435 rc = ble_gattc_disc_all_dscs(2, 3, 0xffff,
436 ble_gatt_conn_test_disc_all_dscs_cb,
437 &disc_all_dscs_arg);
438
439 disc_chr_uuid_arg.exp_conn_handle = 2;
440 rc = ble_gattc_disc_chrs_by_uuid(2, 2, 0xffff, BLE_UUID16_DECLARE(0x2222),
441 ble_gatt_conn_test_disc_chr_uuid_cb,
442 &disc_chr_uuid_arg);
443
444 read_arg.exp_conn_handle = 2;
445 rc = ble_gattc_read(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE,
446 ble_gatt_conn_test_read_cb, &read_arg);
447 TEST_ASSERT_FATAL(rc == 0);
448
449 read_uuid_arg.exp_conn_handle = 2;
450 rc = ble_gattc_read_by_uuid(2, 1, 0xffff, BLE_UUID16_DECLARE(0x3333),
451 ble_gatt_conn_test_read_uuid_cb,
452 &read_uuid_arg);
453 TEST_ASSERT_FATAL(rc == 0);
454
455 read_long_arg.exp_conn_handle = 2;
456 rc = ble_gattc_read_long(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, offset,
457 ble_gatt_conn_test_read_long_cb, &read_long_arg);
458 TEST_ASSERT_FATAL(rc == 0);
459
460 /* Connection 3. */
461 read_mult_arg.exp_conn_handle = 3;
462 rc = ble_gattc_read_mult(3, ((uint16_t[3]){5,6,7}), 3,
463 ble_gatt_conn_test_read_mult_cb, &read_mult_arg);
464 TEST_ASSERT_FATAL(rc == 0);
465
466 write_arg.exp_conn_handle = 3;
467 rc = ble_hs_test_util_gatt_write_flat(
468 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
469 ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
470 ble_gatt_conn_test_write_cb, &write_arg);
471 TEST_ASSERT_FATAL(rc == 0);
472
473 write_long_arg.exp_conn_handle = 3;
474 rc = ble_hs_test_util_gatt_write_long_flat(
475 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
476 ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
477 ble_gatt_conn_test_write_long_cb, &write_long_arg);
478 TEST_ASSERT_FATAL(rc == 0);
479
480 attr.handle = 8;
481 attr.offset = 0;
482 attr.om = os_msys_get_pkthdr(0, 0);
483 write_rel_arg.exp_conn_handle = 3;
484 rc = ble_gattc_write_reliable(
485 3, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg);
486 TEST_ASSERT_FATAL(rc == 0);
487
488 rc = ble_gattc_indicate(3, attr_handle);
489 TEST_ASSERT_FATAL(rc == 0);
490
491 /*** Start the procedures. */
492
493 /*** Break the connections; verify proper callbacks got called. */
494 /* Connection 1. */
495 ble_gattc_connection_broken(1);
496 TEST_ASSERT(mtu_arg.called == 1);
497 TEST_ASSERT(disc_all_svcs_arg.called == 1);
498 TEST_ASSERT(disc_svc_uuid_arg.called == 1);
499 TEST_ASSERT(find_inc_svcs_arg.called == 1);
500 TEST_ASSERT(disc_all_chrs_arg.called == 1);
501 TEST_ASSERT(disc_chr_uuid_arg.called == 0);
502 TEST_ASSERT(disc_all_dscs_arg.called == 0);
503 TEST_ASSERT(read_arg.called == 0);
504 TEST_ASSERT(read_uuid_arg.called == 0);
505 TEST_ASSERT(read_long_arg.called == 0);
506 TEST_ASSERT(read_mult_arg.called == 0);
507 TEST_ASSERT(write_arg.called == 0);
508 TEST_ASSERT(write_long_arg.called == 0);
509 TEST_ASSERT(write_rel_arg.called == 0);
510 TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255);
511
512 /* Connection 2. */
513 ble_gattc_connection_broken(2);
514 TEST_ASSERT(mtu_arg.called == 1);
515 TEST_ASSERT(disc_all_svcs_arg.called == 1);
516 TEST_ASSERT(disc_svc_uuid_arg.called == 1);
517 TEST_ASSERT(find_inc_svcs_arg.called == 1);
518 TEST_ASSERT(disc_all_chrs_arg.called == 1);
519 TEST_ASSERT(disc_chr_uuid_arg.called == 1);
520 TEST_ASSERT(disc_all_dscs_arg.called == 1);
521 TEST_ASSERT(read_arg.called == 1);
522 TEST_ASSERT(read_uuid_arg.called == 1);
523 TEST_ASSERT(read_long_arg.called == 1);
524 TEST_ASSERT(read_mult_arg.called == 0);
525 TEST_ASSERT(write_arg.called == 0);
526 TEST_ASSERT(write_long_arg.called == 0);
527 TEST_ASSERT(write_rel_arg.called == 0);
528 TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255);
529
530 /* Connection 3. */
531 ble_gattc_connection_broken(3);
532 TEST_ASSERT(mtu_arg.called == 1);
533 TEST_ASSERT(disc_all_svcs_arg.called == 1);
534 TEST_ASSERT(disc_svc_uuid_arg.called == 1);
535 TEST_ASSERT(find_inc_svcs_arg.called == 1);
536 TEST_ASSERT(disc_all_chrs_arg.called == 1);
537 TEST_ASSERT(disc_chr_uuid_arg.called == 1);
538 TEST_ASSERT(disc_all_dscs_arg.called == 1);
539 TEST_ASSERT(read_arg.called == 1);
540 TEST_ASSERT(read_uuid_arg.called == 1);
541 TEST_ASSERT(read_long_arg.called == 1);
542 TEST_ASSERT(read_mult_arg.called == 1);
543 TEST_ASSERT(write_arg.called == 1);
544 TEST_ASSERT(write_long_arg.called == 1);
545 TEST_ASSERT(write_rel_arg.called == 1);
546 TEST_ASSERT(ble_gatt_conn_test_gap_event.type == BLE_GAP_EVENT_NOTIFY_TX);
547 TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.status ==
548 BLE_HS_ENOTCONN);
549 TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.conn_handle == 3);
550 TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.attr_handle ==
551 attr_handle);
552 TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.indication);
553 }
554
555 static void
ble_gatt_conn_test_util_timeout(uint16_t conn_handle,struct ble_gatt_conn_test_arg * arg)556 ble_gatt_conn_test_util_timeout(uint16_t conn_handle,
557 struct ble_gatt_conn_test_arg *arg)
558 {
559 struct hci_disconn_complete evt;
560 int32_t ticks_from_now;
561
562 ticks_from_now = ble_gattc_timer();
563 TEST_ASSERT(ticks_from_now == 30 * OS_TICKS_PER_SEC);
564
565 os_time_advance(29 * OS_TICKS_PER_SEC);
566 ticks_from_now = ble_gattc_timer();
567 TEST_ASSERT(ticks_from_now == 1 * OS_TICKS_PER_SEC);
568
569 ble_hs_test_util_hci_ack_set_disconnect(0);
570 os_time_advance(1 * OS_TICKS_PER_SEC);
571 ticks_from_now = ble_gattc_timer();
572 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
573
574 /* Ensure connection was terminated due to proecedure timeout. */
575 evt.connection_handle = conn_handle;
576 evt.status = 0;
577 evt.reason = BLE_ERR_REM_USER_CONN_TERM;
578 ble_hs_test_util_hci_rx_disconn_complete_event(&evt);
579
580 /* Ensure GATT callback was called with timeout status. */
581 if (arg != NULL) {
582 TEST_ASSERT(arg->called == 1);
583 }
584 }
585
TEST_CASE(ble_gatt_conn_test_timeout)586 TEST_CASE(ble_gatt_conn_test_timeout)
587 {
588 static const uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
589
590 struct ble_gatt_conn_test_arg mtu_arg = { 1, BLE_HS_ETIMEOUT };
591 struct ble_gatt_conn_test_arg disc_all_svcs_arg = { 1, BLE_HS_ETIMEOUT };
592 struct ble_gatt_conn_test_arg disc_svc_uuid_arg = { 1, BLE_HS_ETIMEOUT };
593 struct ble_gatt_conn_test_arg find_inc_svcs_arg = { 1, BLE_HS_ETIMEOUT };
594 struct ble_gatt_conn_test_arg disc_all_chrs_arg = { 1, BLE_HS_ETIMEOUT };
595 struct ble_gatt_conn_test_arg disc_chr_uuid_arg = { 1, BLE_HS_ETIMEOUT };
596 struct ble_gatt_conn_test_arg disc_all_dscs_arg = { 1, BLE_HS_ETIMEOUT };
597 struct ble_gatt_conn_test_arg read_arg = { 1, BLE_HS_ETIMEOUT };
598 struct ble_gatt_conn_test_arg read_uuid_arg = { 1, BLE_HS_ETIMEOUT };
599 struct ble_gatt_conn_test_arg read_long_arg = { 1, BLE_HS_ETIMEOUT };
600 struct ble_gatt_conn_test_arg read_mult_arg = { 1, BLE_HS_ETIMEOUT };
601 struct ble_gatt_conn_test_arg write_arg = { 1, BLE_HS_ETIMEOUT };
602 struct ble_gatt_conn_test_arg write_long_arg = { 1, BLE_HS_ETIMEOUT };
603 struct ble_gatt_conn_test_arg write_rel_arg = { 1, BLE_HS_ETIMEOUT };
604
605 struct ble_gatt_attr attr;
606 int32_t ticks_from_now;
607 uint16_t attr_handle;
608 uint16_t offset = 0;
609 int rc;
610
611 ble_gatt_conn_test_util_init();
612
613 ticks_from_now = ble_gattc_timer();
614 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
615
616 /*** Register an attribute to allow indicatations to be sent. */
617 rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x1212), BLE_ATT_F_READ, 0,
618 &attr_handle,
619 ble_gatt_conn_test_attr_cb, NULL);
620 TEST_ASSERT(rc == 0);
621
622 /*** MTU. */
623 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
624 rc = ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg);
625 TEST_ASSERT_FATAL(rc == 0);
626 ble_gatt_conn_test_util_timeout(1, &mtu_arg);
627
628 /*** Discover all services. */
629 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
630 rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb,
631 &disc_all_svcs_arg);
632 TEST_ASSERT_FATAL(rc == 0);
633 ble_gatt_conn_test_util_timeout(1, &disc_all_svcs_arg);
634
635 /*** Discover services by UUID. */
636 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
637 rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16_DECLARE(0x1111),
638 ble_gatt_conn_test_disc_svc_uuid_cb,
639 &disc_svc_uuid_arg);
640 TEST_ASSERT_FATAL(rc == 0);
641 ble_gatt_conn_test_util_timeout(1, &disc_svc_uuid_arg);
642
643 /*** Find included services. */
644 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
645 rc = ble_gattc_find_inc_svcs(1, 1, 0xffff,
646 ble_gatt_conn_test_find_inc_svcs_cb,
647 &find_inc_svcs_arg);
648 TEST_ASSERT_FATAL(rc == 0);
649 ble_gatt_conn_test_util_timeout(1, &find_inc_svcs_arg);
650
651 /*** Discover all characteristics. */
652 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
653 rc = ble_gattc_disc_all_chrs(1, 1, 0xffff,
654 ble_gatt_conn_test_disc_all_chrs_cb,
655 &disc_all_chrs_arg);
656 TEST_ASSERT_FATAL(rc == 0);
657 ble_gatt_conn_test_util_timeout(1, &disc_all_chrs_arg);
658
659 /*** Discover all descriptors. */
660 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
661 rc = ble_gattc_disc_all_dscs(1, 3, 0xffff,
662 ble_gatt_conn_test_disc_all_dscs_cb,
663 &disc_chr_uuid_arg);
664 TEST_ASSERT_FATAL(rc == 0);
665 ble_gatt_conn_test_util_timeout(1, &disc_chr_uuid_arg);
666
667 /*** Discover characteristics by UUID. */
668 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
669 rc = ble_gattc_disc_chrs_by_uuid(1, 2, 0xffff, BLE_UUID16_DECLARE(0x2222),
670 ble_gatt_conn_test_disc_chr_uuid_cb,
671 &disc_all_dscs_arg);
672 TEST_ASSERT_FATAL(rc == 0);
673 ble_gatt_conn_test_util_timeout(1, &disc_all_dscs_arg);
674
675 /*** Read. */
676 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
677 rc = ble_gattc_read(1, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE,
678 ble_gatt_conn_test_read_cb, &read_arg);
679 TEST_ASSERT_FATAL(rc == 0);
680 ble_gatt_conn_test_util_timeout(1, &read_arg);
681
682 /*** Read by UUID. */
683 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
684 rc = ble_gattc_read_by_uuid(1, 1, 0xffff, BLE_UUID16_DECLARE(0x3333),
685 ble_gatt_conn_test_read_uuid_cb,
686 &read_uuid_arg);
687 TEST_ASSERT_FATAL(rc == 0);
688 ble_gatt_conn_test_util_timeout(1, &read_uuid_arg);
689
690 /*** Read long. */
691 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
692 rc = ble_gattc_read_long(1, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, offset,
693 ble_gatt_conn_test_read_long_cb,
694 &read_long_arg);
695 TEST_ASSERT_FATAL(rc == 0);
696 ble_gatt_conn_test_util_timeout(1, &read_long_arg);
697
698 /*** Read multiple. */
699 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
700 rc = ble_gattc_read_mult(1, ((uint16_t[3]){5,6,7}), 3,
701 ble_gatt_conn_test_read_mult_cb,
702 &read_mult_arg);
703 TEST_ASSERT_FATAL(rc == 0);
704 ble_gatt_conn_test_util_timeout(1, &read_mult_arg);
705
706 /*** Write. */
707 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
708 rc = ble_hs_test_util_gatt_write_flat(
709 1, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
710 ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
711 ble_gatt_conn_test_write_cb, &write_arg);
712 TEST_ASSERT_FATAL(rc == 0);
713 ble_gatt_conn_test_util_timeout(1, &write_arg);
714
715 /*** Write long. */
716 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
717 rc = ble_hs_test_util_gatt_write_long_flat(
718 1, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
719 ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
720 ble_gatt_conn_test_write_long_cb, &write_long_arg);
721 TEST_ASSERT_FATAL(rc == 0);
722 ble_gatt_conn_test_util_timeout(1, &write_long_arg);
723
724 /*** Write reliable. */
725 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
726 attr.handle = 8;
727 attr.offset = 0;
728 attr.om = os_msys_get_pkthdr(0, 0);
729 rc = ble_gattc_write_reliable(
730 1, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg);
731 TEST_ASSERT_FATAL(rc == 0);
732 ble_gatt_conn_test_util_timeout(1, &write_rel_arg);
733
734 /*** Indication. */
735 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
736 rc = ble_gattc_indicate(1, attr_handle);
737 TEST_ASSERT_FATAL(rc == 0);
738 ble_gatt_conn_test_util_timeout(1, NULL);
739 }
740
TEST_SUITE(ble_gatt_conn_suite)741 TEST_SUITE(ble_gatt_conn_suite)
742 {
743 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
744
745 ble_gatt_conn_test_disconnect();
746 ble_gatt_conn_test_timeout();
747 }
748
749 int
ble_gatt_conn_test_all(void)750 ble_gatt_conn_test_all(void)
751 {
752 ble_gatt_conn_suite();
753
754 return tu_any_failed;
755 }
756