xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/test/src/ble_gatts_reg_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_uuid.h"
25 #include "host/ble_hs_test.h"
26 #include "ble_hs_test_util.h"
27 
28 #define BLE_GATTS_REG_TEST_MAX_ENTRIES  256
29 
30 struct ble_gatts_reg_test_entry {
31     uint8_t op;
32     ble_uuid_any_t uuid;
33     uint16_t handle;
34     uint16_t val_handle; /* If a characteristic. */
35 
36     const struct ble_gatt_svc_def *svc;
37     const struct ble_gatt_chr_def *chr;
38     const struct ble_gatt_dsc_def *dsc;
39 };
40 
41 static struct ble_gatts_reg_test_entry
42 ble_gatts_reg_test_entries[BLE_GATTS_REG_TEST_MAX_ENTRIES];
43 
44 static int ble_gatts_reg_test_num_entries;
45 
46 static void
ble_gatts_reg_test_init(void)47 ble_gatts_reg_test_init(void)
48 {
49     ble_hs_test_util_init();
50     ble_gatts_reg_test_num_entries = 0;
51 }
52 
53 static void
ble_gatts_reg_test_misc_reg_cb(struct ble_gatt_register_ctxt * ctxt,void * arg)54 ble_gatts_reg_test_misc_reg_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
55 {
56     struct ble_gatts_reg_test_entry *entry;
57 
58     TEST_ASSERT_FATAL(ble_gatts_reg_test_num_entries <
59                       BLE_GATTS_REG_TEST_MAX_ENTRIES);
60 
61     entry = ble_gatts_reg_test_entries + ble_gatts_reg_test_num_entries++;
62     memset(entry, 0, sizeof *entry);
63 
64     entry->op = ctxt->op;
65     switch (ctxt->op) {
66     case BLE_GATT_REGISTER_OP_SVC:
67         ble_uuid_to_any(ctxt->svc.svc_def->uuid, &entry->uuid);
68         entry->handle = ctxt->svc.handle;
69         entry->svc = ctxt->svc.svc_def;
70         break;
71 
72     case BLE_GATT_REGISTER_OP_CHR:
73         ble_uuid_to_any(ctxt->chr.chr_def->uuid, &entry->uuid);
74         entry->handle = ctxt->chr.def_handle;
75         entry->val_handle = ctxt->chr.val_handle;
76         entry->svc = ctxt->chr.svc_def;
77         entry->chr = ctxt->chr.chr_def;
78         break;
79 
80     case BLE_GATT_REGISTER_OP_DSC:
81         ble_uuid_to_any(ctxt->dsc.dsc_def->uuid, &entry->uuid);
82         entry->handle = ctxt->dsc.handle;
83         entry->svc = ctxt->dsc.svc_def;
84         entry->chr = ctxt->dsc.chr_def;
85         entry->dsc = ctxt->dsc.dsc_def;
86         break;
87 
88     default:
89         TEST_ASSERT(0);
90         break;
91     }
92 }
93 
94 static void
ble_gatts_reg_test_misc_lookup_good(struct ble_gatts_reg_test_entry * entry)95 ble_gatts_reg_test_misc_lookup_good(struct ble_gatts_reg_test_entry *entry)
96 {
97     uint16_t chr_def_handle;
98     uint16_t chr_val_handle;
99     uint16_t svc_handle;
100     uint16_t dsc_handle;
101     int rc;
102 
103     switch (entry->op) {
104     case BLE_GATT_REGISTER_OP_SVC:
105         rc = ble_gatts_find_svc(&entry->uuid.u, &svc_handle);
106         TEST_ASSERT_FATAL(rc == 0);
107         TEST_ASSERT(svc_handle == entry->handle);
108         break;
109 
110     case BLE_GATT_REGISTER_OP_CHR:
111         rc = ble_gatts_find_chr(entry->svc->uuid, entry->chr->uuid,
112                                 &chr_def_handle, &chr_val_handle);
113         TEST_ASSERT_FATAL(rc == 0);
114         TEST_ASSERT(chr_def_handle == entry->handle);
115         TEST_ASSERT(chr_val_handle == entry->val_handle);
116         break;
117 
118     case BLE_GATT_REGISTER_OP_DSC:
119         rc = ble_gatts_find_dsc(entry->svc->uuid, entry->chr->uuid,
120                                 entry->dsc->uuid, &dsc_handle);
121         break;
122 
123     default:
124         TEST_ASSERT(0);
125         break;
126     }
127 }
128 
129 static void
ble_gatts_reg_test_misc_lookup_bad(struct ble_gatts_reg_test_entry * entry)130 ble_gatts_reg_test_misc_lookup_bad(struct ble_gatts_reg_test_entry *entry)
131 {
132     struct ble_gatts_reg_test_entry *cur;
133     ble_uuid_any_t wrong_uuid;
134     int rc;
135     int i;
136 
137     switch (entry->op) {
138     case BLE_GATT_REGISTER_OP_SVC:
139         /* Wrong service UUID. */
140         ble_uuid_to_any(entry->svc->uuid, &wrong_uuid);
141         wrong_uuid.u16.value++;
142         rc = ble_gatts_find_svc(&wrong_uuid.u, NULL);
143         TEST_ASSERT(rc == BLE_HS_ENOENT);
144         break;
145 
146     case BLE_GATT_REGISTER_OP_CHR:
147         /* Correct service UUID, wrong characteristic UUID. */
148         ble_uuid_to_any(entry->chr->uuid, &wrong_uuid);
149         wrong_uuid.u16.value++;
150         rc = ble_gatts_find_chr(entry->svc->uuid, &wrong_uuid.u, NULL, NULL);
151         TEST_ASSERT(rc == BLE_HS_ENOENT);
152 
153         /* Incorrect service UUID, correct characteristic UUID. */
154         ble_uuid_to_any(entry->svc->uuid, &wrong_uuid);
155         wrong_uuid.u16.value++;
156         rc = ble_gatts_find_chr(&wrong_uuid.u, entry->chr->uuid, NULL, NULL);
157         TEST_ASSERT(rc == BLE_HS_ENOENT);
158 
159         /* Existing (but wrong) service, correct characteristic UUID. */
160         for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
161             cur = ble_gatts_reg_test_entries + i;
162             switch (cur->op) {
163             case BLE_GATT_REGISTER_OP_SVC:
164                 if (cur->svc != entry->svc) {
165                     rc = ble_gatts_find_chr(cur->svc->uuid,
166                                             entry->chr->uuid,
167                                             NULL, NULL);
168                     TEST_ASSERT(rc == BLE_HS_ENOENT);
169                 }
170                 break;
171 
172             case BLE_GATT_REGISTER_OP_CHR:
173                 /* Characteristic that isn't in this service. */
174                 if (cur->svc != entry->svc) {
175                     rc = ble_gatts_find_chr(entry->svc->uuid,
176                                             cur->chr->uuid,
177                                             NULL, NULL);
178                     TEST_ASSERT(rc == BLE_HS_ENOENT);
179                 }
180                 break;
181 
182             case BLE_GATT_REGISTER_OP_DSC:
183                 /* Use descriptor UUID instead of characteristic UUID. */
184                 rc = ble_gatts_find_chr(entry->svc->uuid,
185                                         cur->dsc->uuid,
186                                         NULL, NULL);
187                 TEST_ASSERT(rc == BLE_HS_ENOENT);
188                 break;
189 
190             default:
191                 TEST_ASSERT(0);
192                 break;
193             }
194         }
195         break;
196 
197     case BLE_GATT_REGISTER_OP_DSC:
198         /* Correct svc/chr UUID, wrong dsc UUID. */
199         ble_uuid_to_any(entry->dsc->uuid, &wrong_uuid);
200         wrong_uuid.u128.value[15]++;
201         rc = ble_gatts_find_dsc(entry->svc->uuid, entry->chr->uuid,
202                                 &wrong_uuid.u, NULL);
203         TEST_ASSERT(rc == BLE_HS_ENOENT);
204 
205         /* Incorrect svc UUID, correct chr/dsc UUID. */
206         ble_uuid_to_any(entry->svc->uuid, &wrong_uuid);
207         wrong_uuid.u128.value[15]++;
208         rc = ble_gatts_find_dsc(&wrong_uuid.u, entry->chr->uuid,
209                                 entry->dsc->uuid, NULL);
210         TEST_ASSERT(rc == BLE_HS_ENOENT);
211 
212         for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
213             cur = ble_gatts_reg_test_entries + i;
214             switch (cur->op) {
215             case BLE_GATT_REGISTER_OP_SVC:
216                 /* Existing (but wrong) svc, correct chr/dsc UUID. */
217                 if (cur->svc != entry->svc) {
218                     rc = ble_gatts_find_dsc(cur->svc->uuid,
219                                             entry->chr->uuid,
220                                             entry->dsc->uuid,
221                                             NULL);
222                     TEST_ASSERT(rc == BLE_HS_ENOENT);
223                 }
224                 break;
225 
226             case BLE_GATT_REGISTER_OP_CHR:
227                 /* Existing (but wrong) svc/chr, correct dsc UUID. */
228                 if (cur->chr != entry->chr) {
229                     rc = ble_gatts_find_dsc(cur->svc->uuid,
230                                             cur->chr->uuid,
231                                             entry->dsc->uuid,
232                                             NULL);
233                     TEST_ASSERT(rc == BLE_HS_ENOENT);
234                 }
235                 break;
236 
237             case BLE_GATT_REGISTER_OP_DSC:
238                 /* Descriptor that isn't in this characteristic. */
239                 if (cur->chr != entry->chr) {
240                     rc = ble_gatts_find_dsc(cur->svc->uuid,
241                                             cur->chr->uuid,
242                                             entry->dsc->uuid,
243                                             NULL);
244                     TEST_ASSERT(rc == BLE_HS_ENOENT);
245                 }
246                 break;
247 
248             default:
249                 TEST_ASSERT(0);
250                 break;
251             }
252         }
253         break;
254 
255     default:
256         TEST_ASSERT(0);
257         break;
258     }
259 }
260 
261 static void
ble_gatts_reg_test_misc_verify_entry(uint8_t op,const ble_uuid_t * uuid)262 ble_gatts_reg_test_misc_verify_entry(uint8_t op, const ble_uuid_t *uuid)
263 {
264     struct ble_gatts_reg_test_entry *entry;
265     int i;
266 
267     for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
268         entry = ble_gatts_reg_test_entries + i;
269         if (entry->op == op && ble_uuid_cmp(&entry->uuid.u, uuid) == 0) {
270             break;
271         }
272     }
273     TEST_ASSERT_FATAL(entry != NULL);
274 
275     /* Verify that characteristic value handle was properly assigned at
276      * registration.
277      */
278     if (op == BLE_GATT_REGISTER_OP_CHR) {
279         TEST_ASSERT(*entry->chr->val_handle == entry->val_handle);
280     }
281 
282     /* Verify that the entry can be looked up. */
283     ble_gatts_reg_test_misc_lookup_good(entry);
284 
285     /* Verify that "barely incorrect" UUID information doesn't retrieve any
286      * handles.
287      */
288     ble_gatts_reg_test_misc_lookup_bad(entry);
289 }
290 
291 static int
ble_gatts_reg_test_misc_dummy_access(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)292 ble_gatts_reg_test_misc_dummy_access(uint16_t conn_handle,
293                                      uint16_t attr_handle,
294                                      struct ble_gatt_access_ctxt *ctxt,
295                                      void *arg)
296 {
297     return 0;
298 }
299 
TEST_CASE(ble_gatts_reg_test_svc_return)300 TEST_CASE(ble_gatts_reg_test_svc_return)
301 {
302     int rc;
303 
304     /*** Missing UUID. */
305     ble_gatts_reg_test_init();
306     struct ble_gatt_svc_def svcs_no_uuid[] = { {
307         .type = BLE_GATT_SVC_TYPE_PRIMARY,
308     }, {
309         0
310     } };
311 
312     rc = ble_gatts_register_svcs(svcs_no_uuid, NULL, NULL);
313     TEST_ASSERT(rc == BLE_HS_EINVAL);
314 
315     /*** Circular dependency. */
316     ble_gatts_reg_test_init();
317     struct ble_gatt_svc_def svcs_circ[] = { {
318         .type = BLE_GATT_SVC_TYPE_PRIMARY,
319         .uuid = BLE_UUID16_DECLARE(0x1234),
320         .includes = (const struct ble_gatt_svc_def*[]) { svcs_circ + 1, NULL },
321     }, {
322         .type = BLE_GATT_SVC_TYPE_SECONDARY,
323         .uuid = BLE_UUID16_DECLARE(0x1234),
324         .includes = (const struct ble_gatt_svc_def*[]) { svcs_circ + 0, NULL },
325     }, {
326         0
327     } };
328 
329     rc = ble_gatts_register_svcs(svcs_circ, NULL, NULL);
330     TEST_ASSERT(rc == BLE_HS_EINVAL);
331 
332     /*** Success. */
333     ble_gatts_reg_test_init();
334     struct ble_gatt_svc_def svcs_good[] = { {
335         .type = BLE_GATT_SVC_TYPE_PRIMARY,
336         .uuid = BLE_UUID16_DECLARE(0x1234),
337         .includes = (const struct ble_gatt_svc_def*[]) { svcs_good + 1, NULL },
338     }, {
339         .type = BLE_GATT_SVC_TYPE_SECONDARY,
340         .uuid = BLE_UUID16_DECLARE(0x1234),
341     }, {
342         0
343     } };
344 
345     rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
346     TEST_ASSERT(rc == 0);
347 }
348 
TEST_CASE(ble_gatts_reg_test_chr_return)349 TEST_CASE(ble_gatts_reg_test_chr_return)
350 {
351     int rc;
352 
353     /*** Missing callback. */
354     ble_gatts_reg_test_init();
355     struct ble_gatt_svc_def svcs_no_chr_cb[] = { {
356         .type = BLE_GATT_SVC_TYPE_PRIMARY,
357         .uuid = BLE_UUID16_DECLARE(0x1234),
358         .characteristics = (struct ble_gatt_chr_def[]) { {
359             .uuid = BLE_UUID16_DECLARE(0x1111),
360             .flags = BLE_GATT_CHR_F_READ,
361         }, {
362             0
363         } },
364     }, {
365         0
366     } };
367 
368     rc = ble_gatts_register_svcs(svcs_no_chr_cb, NULL, NULL);
369     TEST_ASSERT(rc == BLE_HS_EINVAL);
370 
371     /*** Success. */
372     ble_gatts_reg_test_init();
373     struct ble_gatt_svc_def svcs_good[] = { {
374         .type = BLE_GATT_SVC_TYPE_PRIMARY,
375         .uuid = BLE_UUID16_DECLARE(0x1234),
376         .characteristics = (struct ble_gatt_chr_def[]) { {
377             .uuid = BLE_UUID16_DECLARE(0x1111),
378             .access_cb = ble_gatts_reg_test_misc_dummy_access,
379             .flags = BLE_GATT_CHR_F_READ,
380         }, {
381             0
382         } },
383     }, {
384         0
385     } };
386 
387     rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
388     TEST_ASSERT(rc == 0);
389 }
390 
TEST_CASE(ble_gatts_reg_test_dsc_return)391 TEST_CASE(ble_gatts_reg_test_dsc_return)
392 {
393     int rc;
394 
395     /*** Missing callback. */
396     ble_gatts_reg_test_init();
397     struct ble_gatt_svc_def svcs_no_dsc_cb[] = { {
398         .type = BLE_GATT_SVC_TYPE_PRIMARY,
399         .uuid = BLE_UUID16_DECLARE(0x1234),
400         .characteristics = (struct ble_gatt_chr_def[]) { {
401             .uuid = BLE_UUID16_DECLARE(0x1111),
402             .access_cb = ble_gatts_reg_test_misc_dummy_access,
403             .flags = BLE_GATT_CHR_F_READ,
404             .descriptors = (struct ble_gatt_dsc_def[]) { {
405                 .uuid = BLE_UUID16_DECLARE(0x8888),
406                 .att_flags = 5,
407             }, {
408                 0
409             } },
410         }, {
411             0
412         } },
413     }, {
414         0
415     } };
416 
417     rc = ble_gatts_register_svcs(svcs_no_dsc_cb, NULL, NULL);
418     TEST_ASSERT(rc == BLE_HS_EINVAL);
419 
420     /*** Success. */
421     ble_gatts_reg_test_init();
422     struct ble_gatt_svc_def svcs_good[] = { {
423         .type = BLE_GATT_SVC_TYPE_PRIMARY,
424         .uuid = BLE_UUID16_DECLARE(0x1234),
425         .characteristics = (struct ble_gatt_chr_def[]) { {
426             .uuid = BLE_UUID16_DECLARE(0x1111),
427             .access_cb = ble_gatts_reg_test_misc_dummy_access,
428             .flags = BLE_GATT_CHR_F_READ,
429             .descriptors = (struct ble_gatt_dsc_def[]) { {
430                 .uuid = BLE_UUID16_DECLARE(0x8888),
431                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
432                 .att_flags = 5,
433             }, {
434                 0
435             } },
436         }, {
437             0
438         } },
439     }, {
440         0
441     } };
442 
443     rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
444     TEST_ASSERT(rc == 0);
445 }
446 
447 static void
ble_gatts_reg_test_misc_svcs(struct ble_gatt_svc_def * svcs)448 ble_gatts_reg_test_misc_svcs(struct ble_gatt_svc_def *svcs)
449 {
450     const struct ble_gatt_svc_def *svc;
451     const struct ble_gatt_chr_def *chr;
452     const struct ble_gatt_dsc_def *dsc;
453     int rc;
454 
455     ble_gatts_reg_test_init();
456 
457     /* Register all the attributes. */
458     rc = ble_gatts_register_svcs(svcs, ble_gatts_reg_test_misc_reg_cb,
459                                  NULL);
460     TEST_ASSERT_FATAL(rc == 0);
461 
462     /* Verify that the appropriate callbacks were executed. */
463     for (svc = svcs; svc->type != BLE_GATT_SVC_TYPE_END; svc++) {
464         ble_gatts_reg_test_misc_verify_entry(BLE_GATT_REGISTER_OP_SVC,
465                                              svc->uuid);
466 
467         if (svc->characteristics != NULL) {
468             for (chr = svc->characteristics; chr->uuid != NULL; chr++) {
469                 ble_gatts_reg_test_misc_verify_entry(BLE_GATT_REGISTER_OP_CHR,
470                                                      chr->uuid);
471 
472                 if (chr->descriptors != NULL) {
473                     for (dsc = chr->descriptors; dsc->uuid != NULL; dsc++) {
474                         ble_gatts_reg_test_misc_verify_entry(
475                             BLE_GATT_REGISTER_OP_DSC, dsc->uuid);
476                     }
477                 }
478             }
479         }
480     }
481 }
482 
TEST_CASE(ble_gatts_reg_test_svc_cb)483 TEST_CASE(ble_gatts_reg_test_svc_cb)
484 {
485     /*** 1 primary. */
486     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
487         .type = BLE_GATT_SVC_TYPE_PRIMARY,
488         .uuid = BLE_UUID16_DECLARE(0x1234),
489     }, {
490         0
491     } });
492 
493     /*** 3 primary. */
494     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
495         .type = BLE_GATT_SVC_TYPE_PRIMARY,
496         .uuid = BLE_UUID16_DECLARE(0x1234),
497     }, {
498         .type = BLE_GATT_SVC_TYPE_PRIMARY,
499         .uuid = BLE_UUID16_DECLARE(0x2234),
500     }, {
501         .type = BLE_GATT_SVC_TYPE_PRIMARY,
502         .uuid = BLE_UUID16_DECLARE(0x3234),
503     }, {
504         0
505     } });
506 
507     /*** 1 primary, 1 secondary. */
508     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
509         .type = BLE_GATT_SVC_TYPE_PRIMARY,
510         .uuid = BLE_UUID16_DECLARE(0x1234),
511     }, {
512         .type = BLE_GATT_SVC_TYPE_SECONDARY,
513         .uuid = BLE_UUID16_DECLARE(0x2222),
514     }, {
515         0
516     } });
517 
518     /*** 1 primary, 1 secondary, 1 include. */
519     struct ble_gatt_svc_def svcs[] = {
520         [0] = {
521             .type = BLE_GATT_SVC_TYPE_PRIMARY,
522             .uuid = BLE_UUID16_DECLARE(0x1234),
523             .includes = (const struct ble_gatt_svc_def*[]) { svcs + 1, NULL, },
524         },
525         [1] = {
526             .type = BLE_GATT_SVC_TYPE_SECONDARY,
527             .uuid = BLE_UUID16_DECLARE(0x2222),
528         }, {
529             0
530         }
531     };
532     ble_gatts_reg_test_misc_svcs(svcs);
533 }
534 
TEST_CASE(ble_gatts_reg_test_chr_cb)535 TEST_CASE(ble_gatts_reg_test_chr_cb)
536 {
537     uint16_t val_handles[16];
538 
539     /*** 1 characteristic. */
540     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
541         .type = BLE_GATT_SVC_TYPE_PRIMARY,
542         .uuid = BLE_UUID16_DECLARE(0x1234),
543         .characteristics = (struct ble_gatt_chr_def[]) { {
544             .uuid = BLE_UUID16_DECLARE(0x1111),
545             .access_cb = ble_gatts_reg_test_misc_dummy_access,
546             .flags = BLE_GATT_CHR_F_READ,
547             .val_handle = val_handles + 0,
548         }, {
549             0
550         } },
551     }, {
552         0
553     } });
554 
555     /*** 3 characteristics. */
556     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
557         .type = BLE_GATT_SVC_TYPE_PRIMARY,
558         .uuid = BLE_UUID16_DECLARE(0x1234),
559         .characteristics = (struct ble_gatt_chr_def[]) { {
560             .uuid = BLE_UUID16_DECLARE(0x1111),
561             .access_cb = ble_gatts_reg_test_misc_dummy_access,
562             .flags = BLE_GATT_CHR_F_READ,
563             .val_handle = val_handles + 0,
564         }, {
565             .uuid = BLE_UUID16_DECLARE(0x2222),
566             .access_cb = ble_gatts_reg_test_misc_dummy_access,
567             .flags = BLE_GATT_CHR_F_WRITE,
568             .val_handle = val_handles + 1,
569         }, {
570             0
571         } },
572     }, {
573         .type = BLE_GATT_SVC_TYPE_SECONDARY,
574         .uuid = BLE_UUID16_DECLARE(0x5678),
575         .characteristics = (struct ble_gatt_chr_def[]) { {
576             .uuid = BLE_UUID16_DECLARE(0x3333),
577             .access_cb = ble_gatts_reg_test_misc_dummy_access,
578             .flags = BLE_GATT_CHR_F_READ,
579             .val_handle = val_handles + 2,
580         }, {
581             0
582         } },
583     }, {
584         0
585     } });
586 }
587 
TEST_CASE(ble_gatts_reg_test_dsc_cb)588 TEST_CASE(ble_gatts_reg_test_dsc_cb)
589 {
590     uint16_t val_handles[16];
591 
592     /*** 1 descriptor. */
593     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
594         .type = BLE_GATT_SVC_TYPE_PRIMARY,
595         .uuid = BLE_UUID16_DECLARE(0x1234),
596         .characteristics = (struct ble_gatt_chr_def[]) { {
597             .uuid = BLE_UUID16_DECLARE(0x1111),
598             .access_cb = ble_gatts_reg_test_misc_dummy_access,
599             .flags = BLE_GATT_CHR_F_READ,
600             .val_handle = val_handles + 0,
601             .descriptors = (struct ble_gatt_dsc_def[]) { {
602                 .uuid = BLE_UUID16_DECLARE(0x111a),
603                 .att_flags = 5,
604                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
605             }, {
606                 0
607             } },
608         }, {
609             0
610         } },
611     }, {
612         0
613     } });
614 
615     /*** 5+ descriptors. */
616     ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
617         .type = BLE_GATT_SVC_TYPE_PRIMARY,
618         .uuid = BLE_UUID16_DECLARE(0x1234),
619         .characteristics = (struct ble_gatt_chr_def[]) { {
620             .uuid = BLE_UUID16_DECLARE(0x1111),
621             .access_cb = ble_gatts_reg_test_misc_dummy_access,
622             .flags = BLE_GATT_CHR_F_READ,
623             .val_handle = val_handles + 0,
624             .descriptors = (struct ble_gatt_dsc_def[]) { {
625                 .uuid = BLE_UUID16_DECLARE(0x111a),
626                 .att_flags = 5,
627                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
628             }, {
629                 0
630             } },
631         }, {
632             .uuid = BLE_UUID16_DECLARE(0x2222),
633             .access_cb = ble_gatts_reg_test_misc_dummy_access,
634             .flags = BLE_GATT_CHR_F_WRITE,
635             .val_handle = val_handles + 1,
636         }, {
637             0
638         } },
639     }, {
640         .type = BLE_GATT_SVC_TYPE_SECONDARY,
641         .uuid = BLE_UUID16_DECLARE(0x5678),
642         .characteristics = (struct ble_gatt_chr_def[]) { {
643             .uuid = BLE_UUID16_DECLARE(0x3333),
644             .access_cb = ble_gatts_reg_test_misc_dummy_access,
645             .flags = BLE_GATT_CHR_F_READ,
646             .val_handle = val_handles + 2,
647             .descriptors = (struct ble_gatt_dsc_def[]) { {
648                 .uuid = BLE_UUID16_DECLARE(0x333a),
649                 .att_flags = 5,
650                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
651             }, {
652                 .uuid = BLE_UUID16_DECLARE(0x333b),
653                 .att_flags = 5,
654                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
655             }, {
656                 .uuid = BLE_UUID16_DECLARE(0x333c),
657                 .att_flags = 5,
658                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
659             }, {
660                 .uuid = BLE_UUID16_DECLARE(0x333e),
661                 .att_flags = 5,
662                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
663             }, {
664                 0
665             } },
666         }, {
667             .uuid = BLE_UUID16_DECLARE(0x4444),
668             .access_cb = ble_gatts_reg_test_misc_dummy_access,
669             .flags = BLE_GATT_CHR_F_READ,
670             .val_handle = val_handles + 3,
671             .descriptors = (struct ble_gatt_dsc_def[]) { {
672                 .uuid = BLE_UUID16_DECLARE(0x444a),
673                 .att_flags = 5,
674                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
675             }, {
676                 .uuid = BLE_UUID16_DECLARE(0x444b),
677                 .att_flags = 5,
678                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
679             }, {
680                 .uuid = BLE_UUID16_DECLARE(0x444c),
681                 .att_flags = 5,
682                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
683             }, {
684                 .uuid = BLE_UUID16_DECLARE(0x444e),
685                 .att_flags = 5,
686                 .access_cb = ble_gatts_reg_test_misc_dummy_access,
687             }, {
688                 0
689             } },
690         }, {
691             0
692         } },
693     }, {
694         0
695     } });
696 }
697 
TEST_SUITE(ble_gatts_reg_suite)698 TEST_SUITE(ble_gatts_reg_suite)
699 {
700     tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
701 
702     ble_gatts_reg_test_svc_return();
703     ble_gatts_reg_test_chr_return();
704     ble_gatts_reg_test_dsc_return();
705 
706     ble_gatts_reg_test_svc_cb();
707     ble_gatts_reg_test_chr_cb();
708     ble_gatts_reg_test_dsc_cb();
709 }
710 
711 int
ble_gatts_reg_test_all(void)712 ble_gatts_reg_test_all(void)
713 {
714     ble_gatts_reg_suite();
715 
716     return tu_any_failed;
717 }
718