xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/test/src/ble_gatt_conn_test.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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