1 /* btp_core.c - Bluetooth Core service */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 * Copyright (c) 2023 Codecoup
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <zephyr/sys/atomic.h>
11 #include <zephyr/types.h>
12 #include <string.h>
13
14 #include <zephyr/toolchain.h>
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/bluetooth/gatt.h>
18 #include <zephyr/bluetooth/hci.h>
19
20 #include <zephyr/sys/byteorder.h>
21 #include <zephyr/net_buf.h>
22
23 #include <hci_core.h>
24
25 #include <zephyr/logging/log.h>
26 #define LOG_MODULE_NAME bttester_core
27 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
28
29 #include "btp/btp.h"
30
31 static ATOMIC_DEFINE(registered_services, BTP_SERVICE_ID_MAX);
32
supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)33 static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
34 void *rsp, uint16_t *rsp_len)
35 {
36 struct btp_core_read_supported_commands_rp *rp = rsp;
37
38 tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_COMMANDS);
39 tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_SERVICES);
40 tester_set_bit(rp->data, BTP_CORE_REGISTER_SERVICE);
41 tester_set_bit(rp->data, BTP_CORE_UNREGISTER_SERVICE);
42
43 *rsp_len = sizeof(*rp) + 1;
44
45 return BTP_STATUS_SUCCESS;
46 }
47
supported_services(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)48 static uint8_t supported_services(const void *cmd, uint16_t cmd_len,
49 void *rsp, uint16_t *rsp_len)
50 {
51 struct btp_core_read_supported_services_rp *rp = rsp;
52
53 /* octet 0 */
54 tester_set_bit(rp->data, BTP_SERVICE_ID_CORE);
55 tester_set_bit(rp->data, BTP_SERVICE_ID_GAP);
56 tester_set_bit(rp->data, BTP_SERVICE_ID_GATT);
57 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
58 tester_set_bit(rp->data, BTP_SERVICE_ID_L2CAP);
59 #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
60 #if defined(CONFIG_BT_MESH)
61 tester_set_bit(rp->data, BTP_SERVICE_ID_MESH);
62 #endif /* CONFIG_BT_MESH */
63
64 /* octet 1 */
65 #if defined(CONFIG_BT_VCP_VOL_REND)
66 tester_set_bit(rp->data, BTP_SERVICE_ID_VCS);
67 #endif /* CONFIG_BT_VCP_VOL_REND */
68 #if defined(CONFIG_BT_IAS) || defined(CONFIG_BT_IAS_CLIENT)
69 tester_set_bit(rp->data, BTP_SERVICE_ID_IAS);
70 #endif /* CONFIG_BT_IAS */
71 #if defined(CONFIG_BT_AICS) || defined(CONFIG_BT_AICS_CLIENT)
72 tester_set_bit(rp->data, BTP_SERVICE_ID_AICS);
73 #endif /*CONFIG_BT_AICS */
74 #if defined(CONFIG_BT_VOCS) || defined(CONFIG_BT_VOCS_CLIENT)
75 tester_set_bit(rp->data, BTP_SERVICE_ID_VOCS);
76 #endif /* CONFIG_BT_VOCS */
77 #if defined(CONFIG_BT_HAS) || defined(CONFIG_BT_HAS_CLIENT)
78 tester_set_bit(rp->data, BTP_SERVICE_ID_HAS);
79 #endif /* CONFIG_BT_HAS */
80 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
81 tester_set_bit(rp->data, BTP_SERVICE_ID_CSIS);
82 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
83 #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR)
84 tester_set_bit(rp->data, BTP_SERVICE_ID_MICP);
85 #endif /* CONFIG_BT_MICP_MIC_DEV */
86 #if defined(CONFIG_BT_TBS_CLIENT)
87 tester_set_bit(rp->data, BTP_SERVICE_ID_CCP);
88 #endif /* CONFIG_BT_TBS_CLIENT */
89 #if defined(CONFIG_BT_VCP_VOL_CTLR)
90 tester_set_bit(rp->data, BTP_SERVICE_ID_VCP);
91 #endif /* CONFIG_BT_VCP_VOL_CTLR */
92 #if defined(CONFIG_BT_CAP_ACCEPTOR)
93 tester_set_bit(rp->data, BTP_SERVICE_ID_CAS);
94 #endif /* CONFIG_BT_CAP_ACCEPTOR */
95 #if defined(CONFIG_BT_MCC)
96 tester_set_bit(rp->data, BTP_SERVICE_ID_MCP);
97 #endif /* CONFIG_BT_MCC */
98 #if defined(CONFIG_BT_MCS)
99 tester_set_bit(rp->data, BTP_SERVICE_ID_GMCS);
100 #endif /* CONFIG_BT_MCS */
101 #if defined(CONFIG_BT_HAS)
102 tester_set_bit(rp->data, BTP_SERVICE_ID_HAP);
103 #endif /* CONFIG_BT_HAS */
104 #if defined(CONFIG_BT_TBS)
105 tester_set_bit(rp->data, BTP_SERVICE_ID_TBS);
106 #endif /*CONFIG_BT_TBS */
107 #if defined(CONFIG_BT_TMAP)
108 tester_set_bit(rp->data, BTP_SERVICE_ID_TMAP);
109 #endif /* CONFIG_BT_TMAP */
110 #if defined(CONFIG_BT_PBP)
111 tester_set_bit(rp->data, BTP_SERVICE_ID_PBP);
112 #endif /* CONFIG_BT_PBP */
113
114 *rsp_len = sizeof(*rp) + 2;
115
116 return BTP_STATUS_SUCCESS;
117 }
118
register_service(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)119 static uint8_t register_service(const void *cmd, uint16_t cmd_len,
120 void *rsp, uint16_t *rsp_len)
121 {
122 const struct btp_core_register_service_cmd *cp = cmd;
123 uint8_t status;
124
125 /* invalid service */
126 if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
127 return BTP_STATUS_FAILED;
128 }
129
130 /* already registered */
131 if (atomic_test_bit(registered_services, cp->id)) {
132 return BTP_STATUS_FAILED;
133 }
134
135 switch (cp->id) {
136 case BTP_SERVICE_ID_GAP:
137 status = tester_init_gap();
138 break;
139 case BTP_SERVICE_ID_GATT:
140 status = tester_init_gatt();
141 break;
142 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
143 case BTP_SERVICE_ID_L2CAP:
144 status = tester_init_l2cap();
145 #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
146 break;
147 #if defined(CONFIG_BT_MESH)
148 case BTP_SERVICE_ID_MESH:
149 status = tester_init_mesh();
150 break;
151 case BTP_SERVICE_ID_MESH_MDL:
152 status = tester_init_mmdl();
153 break;
154 #endif /* CONFIG_BT_MESH */
155 #if defined(CONFIG_BT_VCP_VOL_REND) || defined(CONFIG_BT_VCP_VOL_CTLR)
156 case BTP_SERVICE_ID_VCS:
157 status = tester_init_vcs();
158 break;
159 case BTP_SERVICE_ID_VOCS:
160 status = tester_init_vocs();
161 break;
162 case BTP_SERVICE_ID_AICS:
163 status = tester_init_aics();
164 break;
165 case BTP_SERVICE_ID_VCP:
166 status = tester_init_vcp();
167 break;
168 #endif /* CONFIG_BT_VCP_VOL_REND */
169 #if defined(CONFIG_BT_IAS)
170 case BTP_SERVICE_ID_IAS:
171 status = tester_init_ias();
172 break;
173 #endif /* CONFIG_BT_IAS */
174 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \
175 defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
176 case BTP_SERVICE_ID_PACS:
177 status = tester_init_pacs();
178 break;
179 case BTP_SERVICE_ID_ASCS:
180 status = tester_init_ascs();
181 break;
182 case BTP_SERVICE_ID_BAP:
183 status = tester_init_bap();
184 break;
185 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \
186 * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK
187 */
188 #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR)
189 case BTP_SERVICE_ID_MICP:
190 status = tester_init_micp();
191 break;
192 case BTP_SERVICE_ID_MICS:
193 status = tester_init_mics();
194 break;
195 #endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */
196 #if defined(CONFIG_BT_HAS)
197 case BTP_SERVICE_ID_HAS:
198 status = tester_init_has();
199 break;
200 #endif /* CONFIG_BT_HAS */
201 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
202 case BTP_SERVICE_ID_CSIS:
203 status = tester_init_csis();
204 break;
205 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
206 #if defined(CONFIG_BT_CSIP_SET_COORDINATOR)
207 case BTP_SERVICE_ID_CSIP:
208 status = tester_init_csip();
209 break;
210 #endif /* CONFIG_BT_CSIP_SET_COORDINATOR */
211 #if defined(CONFIG_BT_TBS_CLIENT)
212 case BTP_SERVICE_ID_CCP:
213 status = tester_init_ccp();
214 break;
215 #endif /* CONFIG_BT_TBS_CLIENT */
216 #if defined(CONFIG_BT_CAP_ACCEPTOR)
217 case BTP_SERVICE_ID_CAS:
218 status = tester_init_cas();
219 break;
220 #endif /* CONFIG_BT_CAP_ACCEPTOR */
221 #if defined(CONFIG_BT_CAP_INITIATOR)
222 case BTP_SERVICE_ID_CAP:
223 status = tester_init_cap();
224 break;
225 #endif /* CONFIG_BT_CAP_INITIATOR */
226 #if defined(CONFIG_BT_MCC)
227 case BTP_SERVICE_ID_MCP:
228 status = tester_init_mcp();
229 break;
230 #endif /* CONFIG_BT_MCC */
231 #if defined(CONFIG_BT_MCS)
232 case BTP_SERVICE_ID_GMCS:
233 status = tester_init_mcs();
234 break;
235 #endif /* CONFIG_BT_MCS */
236 #if defined(CONFIG_BT_HAS)
237 case BTP_SERVICE_ID_HAP:
238 status = tester_init_hap();
239 break;
240 #endif /* CONFIG_BT_HAS */
241 #if defined(CONFIG_BT_TBS)
242 case BTP_SERVICE_ID_TBS:
243 status = tester_init_tbs();
244 break;
245 #endif /* CONFIG_BT_TBS */
246 #if defined(CONFIG_BT_TMAP)
247 case BTP_SERVICE_ID_TMAP:
248 status = tester_init_tmap();
249 break;
250 #endif /* CONFIG_BT_TMAP */
251 #if defined(CONFIG_BT_OTS)
252 case BTP_SERVICE_ID_OTS:
253 status = tester_init_ots();
254 break;
255 #endif /* CONFIG_BT_OTS */
256 #if defined(CONFIG_BT_PBP)
257 case BTP_SERVICE_ID_PBP:
258 status = tester_init_pbp();
259 break;
260 #endif /* CONFIG_BT_PBP */
261 default:
262 LOG_WRN("unknown id: 0x%02x", cp->id);
263 status = BTP_STATUS_FAILED;
264 break;
265 }
266
267 if (status == BTP_STATUS_SUCCESS) {
268 atomic_set_bit(registered_services, cp->id);
269 }
270
271 return status;
272 }
273
unregister_service(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)274 static uint8_t unregister_service(const void *cmd, uint16_t cmd_len,
275 void *rsp, uint16_t *rsp_len)
276 {
277 const struct btp_core_unregister_service_cmd *cp = cmd;
278 uint8_t status;
279
280 /* invalid service ID */
281 if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
282 return BTP_STATUS_FAILED;
283 }
284
285 /* not registered */
286 if (!atomic_test_bit(registered_services, cp->id)) {
287 return BTP_STATUS_FAILED;
288 }
289
290 switch (cp->id) {
291 case BTP_SERVICE_ID_GAP:
292 status = tester_unregister_gap();
293 break;
294 case BTP_SERVICE_ID_GATT:
295 status = tester_unregister_gatt();
296 break;
297 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
298 case BTP_SERVICE_ID_L2CAP:
299 status = tester_unregister_l2cap();
300 break;
301 #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
302 #if defined(CONFIG_BT_MESH)
303 case BTP_SERVICE_ID_MESH:
304 status = tester_unregister_mesh();
305 break;
306 case BTP_SERVICE_ID_MESH_MDL:
307 status = tester_unregister_mmdl();
308 break;
309 #endif /* CONFIG_BT_MESH */
310 #if defined(CONFIG_BT_VCP_VOL_REND)
311 case BTP_SERVICE_ID_VCS:
312 status = tester_unregister_vcs();
313 break;
314 case BTP_SERVICE_ID_AICS:
315 status = tester_unregister_aics();
316 break;
317 case BTP_SERVICE_ID_VOCS:
318 status = tester_unregister_vocs();
319 break;
320 #endif /* CONFIG_BT_VCP_VOL_REND */
321 #if defined(CONFIG_BT_IAS)
322 case BTP_SERVICE_ID_IAS:
323 status = tester_unregister_ias();
324 break;
325 #endif /* CONFIG_BT_IAS */
326 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \
327 defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
328 case BTP_SERVICE_ID_PACS:
329 status = tester_unregister_pacs();
330 break;
331 case BTP_SERVICE_ID_ASCS:
332 status = tester_unregister_ascs();
333 break;
334 case BTP_SERVICE_ID_BAP:
335 status = tester_unregister_bap();
336 break;
337 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \
338 * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK
339 */
340 #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR)
341 case BTP_SERVICE_ID_MICP:
342 status = tester_unregister_micp();
343 break;
344 case BTP_SERVICE_ID_MICS:
345 status = tester_unregister_mics();
346 break;
347 #endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */
348 #if defined(CONFIG_BT_HAS)
349 case BTP_SERVICE_ID_HAS:
350 status = tester_unregister_has();
351 break;
352 #endif /* CONFIG_BT_HAS */
353 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
354 case BTP_SERVICE_ID_CSIS:
355 status = tester_unregister_csis();
356 break;
357 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
358 #if defined(CONFIG_BT_CSIP_SET_COORDINATOR)
359 case BTP_SERVICE_ID_CSIP:
360 status = tester_unregister_csip();
361 break;
362 #endif /* CONFIG_BT_CSIP_SET_COORDINATOR */
363 #if defined(CONFIG_BT_TBS_CLIENT)
364 case BTP_SERVICE_ID_CCP:
365 status = tester_unregister_ccp();
366 break;
367 #endif /* CONFIG_BT_TBS_CLIENT */
368 #if defined(CONFIG_BT_CAP_ACCEPTOR)
369 case BTP_SERVICE_ID_CAS:
370 status = tester_unregister_cas();
371 break;
372 #endif /* CONFIG_BT_CAP_ACCEPTOR */
373 #if defined(CONFIG_BT_CAP_INITIATOR)
374 case BTP_SERVICE_ID_CAP:
375 status = tester_unregister_cap();
376 break;
377 #endif /* CONFIG_BT_CAP_INITIATOR */
378 #if defined(CONFIG_BT_MCC)
379 case BTP_SERVICE_ID_MCP:
380 status = tester_unregister_mcp();
381 break;
382 #endif /* CONFIG_BT_MCC */
383 #if defined(CONFIG_BT_MCS)
384 case BTP_SERVICE_ID_GMCS:
385 status = tester_unregister_mcs();
386 break;
387 #endif /* CONFIG_BT_MCS */
388 #if defined(CONFIG_BT_HAS)
389 case BTP_SERVICE_ID_HAP:
390 status = tester_unregister_hap();
391 break;
392 #endif /* CONFIG_BT_HAS */
393 #if defined(CONFIG_BT_TBS)
394 case BTP_SERVICE_ID_TBS:
395 status = tester_unregister_tbs();
396 break;
397 #endif /* CONFIG_BT_TBS */
398 #if defined(CONFIG_BT_TMAP)
399 case BTP_SERVICE_ID_TMAP:
400 status = tester_unregister_tmap();
401 break;
402 #endif /* CONFIG_BT_TMAP */
403 #if defined(CONFIG_BT_OTS)
404 case BTP_SERVICE_ID_OTS:
405 status = tester_unregister_ots();
406 break;
407 #endif /* CONFIG_BT_OTS */
408 #if defined(CONFIG_BT_PBP)
409 case BTP_SERVICE_ID_PBP:
410 status = tester_unregister_pbp();
411 break;
412 #endif /* CONFIG_BT_PBP */
413 default:
414 LOG_WRN("unknown id: 0x%x", cp->id);
415 status = BTP_STATUS_FAILED;
416 break;
417 }
418
419 if (status == BTP_STATUS_SUCCESS) {
420 atomic_clear_bit(registered_services, cp->id);
421 }
422
423 return BTP_STATUS_FAILED;
424 }
425
426 static const struct btp_handler handlers[] = {
427 {
428 .opcode = BTP_CORE_READ_SUPPORTED_COMMANDS,
429 .index = BTP_INDEX_NONE,
430 .expect_len = 0,
431 .func = supported_commands,
432 },
433 {
434 .opcode = BTP_CORE_READ_SUPPORTED_SERVICES,
435 .index = BTP_INDEX_NONE,
436 .expect_len = 0,
437 .func = supported_services,
438 },
439 {
440 .opcode = BTP_CORE_REGISTER_SERVICE,
441 .index = BTP_INDEX_NONE,
442 .expect_len = sizeof(struct btp_core_register_service_cmd),
443 .func = register_service,
444 },
445 {
446 .opcode = BTP_CORE_UNREGISTER_SERVICE,
447 .index = BTP_INDEX_NONE,
448 .expect_len = sizeof(struct btp_core_unregister_service_cmd),
449 .func = unregister_service,
450 },
451 };
452
tester_init_core(void)453 void tester_init_core(void)
454 {
455 tester_register_command_handlers(BTP_SERVICE_ID_CORE, handlers,
456 ARRAY_SIZE(handlers));
457 atomic_set_bit(registered_services, BTP_SERVICE_ID_CORE);
458 }
459