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