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) || defined(CONFIG_BT_GTBS)
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
111 *rsp_len = sizeof(*rp) + 2;
112
113 return BTP_STATUS_SUCCESS;
114 }
115
register_service(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)116 static uint8_t register_service(const void *cmd, uint16_t cmd_len,
117 void *rsp, uint16_t *rsp_len)
118 {
119 const struct btp_core_register_service_cmd *cp = cmd;
120 uint8_t status;
121
122 /* invalid service */
123 if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
124 return BTP_STATUS_FAILED;
125 }
126
127 /* already registered */
128 if (atomic_test_bit(registered_services, cp->id)) {
129 return BTP_STATUS_FAILED;
130 }
131
132 switch (cp->id) {
133 case BTP_SERVICE_ID_GAP:
134 status = tester_init_gap();
135 break;
136 case BTP_SERVICE_ID_GATT:
137 status = tester_init_gatt();
138 break;
139 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
140 case BTP_SERVICE_ID_L2CAP:
141 status = tester_init_l2cap();
142 #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
143 break;
144 #if defined(CONFIG_BT_MESH)
145 case BTP_SERVICE_ID_MESH:
146 status = tester_init_mesh();
147 break;
148 case BTP_SERVICE_ID_MESH_MDL:
149 status = tester_init_mmdl();
150 break;
151 #endif /* CONFIG_BT_MESH */
152 #if defined(CONFIG_BT_VCP_VOL_REND) || defined(CONFIG_BT_VCP_VOL_CTLR)
153 case BTP_SERVICE_ID_VCS:
154 status = tester_init_vcs();
155 break;
156 case BTP_SERVICE_ID_VOCS:
157 status = tester_init_vocs();
158 break;
159 case BTP_SERVICE_ID_AICS:
160 status = tester_init_aics();
161 break;
162 case BTP_SERVICE_ID_VCP:
163 status = tester_init_vcp();
164 break;
165 #endif /* CONFIG_BT_VCP_VOL_REND */
166 #if defined(CONFIG_BT_IAS)
167 case BTP_SERVICE_ID_IAS:
168 status = tester_init_ias();
169 break;
170 #endif /* CONFIG_BT_IAS */
171 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \
172 defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
173 case BTP_SERVICE_ID_PACS:
174 status = tester_init_pacs();
175 break;
176 case BTP_SERVICE_ID_ASCS:
177 status = tester_init_ascs();
178 break;
179 case BTP_SERVICE_ID_BAP:
180 status = tester_init_bap();
181 break;
182 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \
183 * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK
184 */
185 #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR)
186 case BTP_SERVICE_ID_MICP:
187 status = tester_init_micp();
188 break;
189 case BTP_SERVICE_ID_MICS:
190 status = tester_init_mics();
191 break;
192 #endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */
193 #if defined(CONFIG_BT_HAS)
194 case BTP_SERVICE_ID_HAS:
195 status = tester_init_has();
196 break;
197 #endif /* CONFIG_BT_HAS */
198 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
199 case BTP_SERVICE_ID_CSIS:
200 status = tester_init_csis();
201 break;
202 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
203 #if defined(CONFIG_BT_CSIP_SET_COORDINATOR)
204 case BTP_SERVICE_ID_CSIP:
205 status = tester_init_csip();
206 break;
207 #endif /* CONFIG_BT_CSIP_SET_COORDINATOR */
208 #if defined(CONFIG_BT_TBS_CLIENT)
209 case BTP_SERVICE_ID_CCP:
210 status = tester_init_ccp();
211 break;
212 #endif /* CONFIG_BT_TBS_CLIENT */
213 #if defined(CONFIG_BT_CAP_ACCEPTOR)
214 case BTP_SERVICE_ID_CAS:
215 status = tester_init_cas();
216 break;
217 #endif /* CONFIG_BT_CAP_ACCEPTOR */
218 #if defined(CONFIG_BT_CAP_INITIATOR)
219 case BTP_SERVICE_ID_CAP:
220 status = tester_init_cap();
221 break;
222 #endif /* CONFIG_BT_CAP_INITIATOR */
223 #if defined(CONFIG_BT_MCC)
224 case BTP_SERVICE_ID_MCP:
225 status = tester_init_mcp();
226 break;
227 #endif /* CONFIG_BT_MCC */
228 #if defined(CONFIG_BT_MCS)
229 case BTP_SERVICE_ID_GMCS:
230 status = tester_init_mcs();
231 break;
232 #endif /* CONFIG_BT_MCS */
233 #if defined(CONFIG_BT_HAS)
234 case BTP_SERVICE_ID_HAP:
235 status = tester_init_hap();
236 break;
237 #endif /* CONFIG_BT_HAS */
238 #if defined(CONFIG_BT_TBS) || defined(CONFIG_BT_GTBS)
239 case BTP_SERVICE_ID_TBS:
240 status = tester_init_tbs();
241 break;
242 #endif /* CONFIG_BT_TBS */
243 #if defined(CONFIG_BT_TMAP)
244 case BTP_SERVICE_ID_TMAP:
245 status = tester_init_tmap();
246 break;
247 #endif /* CONFIG_BT_TMAP */
248 #if defined(CONFIG_BT_OTS)
249 case BTP_SERVICE_ID_OTS:
250 status = tester_init_ots();
251 break;
252 #endif /* CONFIG_BT_OTS */
253 default:
254 LOG_WRN("unknown id: 0x%02x", cp->id);
255 status = BTP_STATUS_FAILED;
256 break;
257 }
258
259 if (status == BTP_STATUS_SUCCESS) {
260 atomic_set_bit(registered_services, cp->id);
261 }
262
263 return status;
264 }
265
unregister_service(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)266 static uint8_t unregister_service(const void *cmd, uint16_t cmd_len,
267 void *rsp, uint16_t *rsp_len)
268 {
269 const struct btp_core_unregister_service_cmd *cp = cmd;
270 uint8_t status;
271
272 /* invalid service ID */
273 if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
274 return BTP_STATUS_FAILED;
275 }
276
277 /* not registered */
278 if (!atomic_test_bit(registered_services, cp->id)) {
279 return BTP_STATUS_FAILED;
280 }
281
282 switch (cp->id) {
283 case BTP_SERVICE_ID_GAP:
284 status = tester_unregister_gap();
285 break;
286 case BTP_SERVICE_ID_GATT:
287 status = tester_unregister_gatt();
288 break;
289 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
290 case BTP_SERVICE_ID_L2CAP:
291 status = tester_unregister_l2cap();
292 break;
293 #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
294 #if defined(CONFIG_BT_MESH)
295 case BTP_SERVICE_ID_MESH:
296 status = tester_unregister_mesh();
297 break;
298 case BTP_SERVICE_ID_MESH_MDL:
299 status = tester_unregister_mmdl();
300 break;
301 #endif /* CONFIG_BT_MESH */
302 #if defined(CONFIG_BT_VCP_VOL_REND)
303 case BTP_SERVICE_ID_VCS:
304 status = tester_unregister_vcs();
305 break;
306 case BTP_SERVICE_ID_AICS:
307 status = tester_unregister_aics();
308 break;
309 case BTP_SERVICE_ID_VOCS:
310 status = tester_unregister_vocs();
311 break;
312 #endif /* CONFIG_BT_VCP_VOL_REND */
313 #if defined(CONFIG_BT_IAS)
314 case BTP_SERVICE_ID_IAS:
315 status = tester_unregister_ias();
316 break;
317 #endif /* CONFIG_BT_IAS */
318 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \
319 defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
320 case BTP_SERVICE_ID_PACS:
321 status = tester_unregister_pacs();
322 break;
323 case BTP_SERVICE_ID_ASCS:
324 status = tester_unregister_ascs();
325 break;
326 case BTP_SERVICE_ID_BAP:
327 status = tester_unregister_bap();
328 break;
329 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \
330 * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK
331 */
332 #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR)
333 case BTP_SERVICE_ID_MICP:
334 status = tester_unregister_micp();
335 break;
336 case BTP_SERVICE_ID_MICS:
337 status = tester_unregister_mics();
338 break;
339 #endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */
340 #if defined(CONFIG_BT_HAS)
341 case BTP_SERVICE_ID_HAS:
342 status = tester_unregister_has();
343 break;
344 #endif /* CONFIG_BT_HAS */
345 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
346 case BTP_SERVICE_ID_CSIS:
347 status = tester_unregister_csis();
348 break;
349 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
350 #if defined(CONFIG_BT_CSIP_SET_COORDINATOR)
351 case BTP_SERVICE_ID_CSIP:
352 status = tester_unregister_csip();
353 break;
354 #endif /* CONFIG_BT_CSIP_SET_COORDINATOR */
355 #if defined(CONFIG_BT_TBS_CLIENT)
356 case BTP_SERVICE_ID_CCP:
357 status = tester_unregister_ccp();
358 break;
359 #endif /* CONFIG_BT_TBS_CLIENT */
360 #if defined(CONFIG_BT_CAP_ACCEPTOR)
361 case BTP_SERVICE_ID_CAS:
362 status = tester_unregister_cas();
363 break;
364 #endif /* CONFIG_BT_CAP_ACCEPTOR */
365 #if defined(CONFIG_BT_CAP_INITIATOR)
366 case BTP_SERVICE_ID_CAP:
367 status = tester_unregister_cap();
368 break;
369 #endif /* CONFIG_BT_CAP_INITIATOR */
370 #if defined(CONFIG_BT_MCC)
371 case BTP_SERVICE_ID_MCP:
372 status = tester_unregister_mcp();
373 break;
374 #endif /* CONFIG_BT_MCC */
375 #if defined(CONFIG_BT_MCS)
376 case BTP_SERVICE_ID_GMCS:
377 status = tester_unregister_mcs();
378 break;
379 #endif /* CONFIG_BT_MCS */
380 #if defined(CONFIG_BT_HAS)
381 case BTP_SERVICE_ID_HAP:
382 status = tester_unregister_hap();
383 break;
384 #endif /* CONFIG_BT_HAS */
385 #if defined(CONFIG_BT_TBS)
386 case BTP_SERVICE_ID_TBS:
387 status = tester_unregister_tbs();
388 break;
389 #endif /* CONFIG_BT_TBS */
390 #if defined(CONFIG_BT_TMAP)
391 case BTP_SERVICE_ID_TMAP:
392 status = tester_unregister_tmap();
393 break;
394 #endif /* CONFIG_BT_TMAP */
395 #if defined(CONFIG_BT_OTS)
396 case BTP_SERVICE_ID_OTS:
397 status = tester_unregister_ots();
398 break;
399 #endif /* CONFIG_BT_OTS */
400 default:
401 LOG_WRN("unknown id: 0x%x", cp->id);
402 status = BTP_STATUS_FAILED;
403 break;
404 }
405
406 if (status == BTP_STATUS_SUCCESS) {
407 atomic_clear_bit(registered_services, cp->id);
408 }
409
410 return BTP_STATUS_FAILED;
411 }
412
413 static const struct btp_handler handlers[] = {
414 {
415 .opcode = BTP_CORE_READ_SUPPORTED_COMMANDS,
416 .index = BTP_INDEX_NONE,
417 .expect_len = 0,
418 .func = supported_commands,
419 },
420 {
421 .opcode = BTP_CORE_READ_SUPPORTED_SERVICES,
422 .index = BTP_INDEX_NONE,
423 .expect_len = 0,
424 .func = supported_services,
425 },
426 {
427 .opcode = BTP_CORE_REGISTER_SERVICE,
428 .index = BTP_INDEX_NONE,
429 .expect_len = sizeof(struct btp_core_register_service_cmd),
430 .func = register_service,
431 },
432 {
433 .opcode = BTP_CORE_UNREGISTER_SERVICE,
434 .index = BTP_INDEX_NONE,
435 .expect_len = sizeof(struct btp_core_unregister_service_cmd),
436 .func = unregister_service,
437 },
438 };
439
tester_init_core(void)440 void tester_init_core(void)
441 {
442 tester_register_command_handlers(BTP_SERVICE_ID_CORE, handlers,
443 ARRAY_SIZE(handlers));
444 atomic_set_bit(registered_services, BTP_SERVICE_ID_CORE);
445 }
446