1 /* gap.c - Bluetooth GAP Tester */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #include <stdint.h>
9
10 #include <zephyr/bluetooth/addr.h>
11 #include <zephyr/bluetooth/gap.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/types.h>
14 #include <string.h>
15
16 #include <zephyr/toolchain.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/conn.h>
19 #include <zephyr/bluetooth/gatt.h>
20 #include <zephyr/bluetooth/hci.h>
21
22 #include <zephyr/sys/byteorder.h>
23 #include <zephyr/net_buf.h>
24
25 #include <hci_core.h>
26
27 #include <zephyr/logging/log.h>
28 #define LOG_MODULE_NAME bttester_gap
29 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
30
31 #include "btp/btp.h"
32
33 #define CONTROLLER_NAME "btp_tester"
34
35 #define BT_LE_AD_DISCOV_MASK (BT_LE_AD_LIMITED | BT_LE_AD_GENERAL)
36 #if defined(CONFIG_BT_EXT_ADV)
37 #define ADV_BUF_LEN (sizeof(struct btp_gap_device_found_ev) + 2 * CONFIG_BT_EXT_SCAN_BUF_SIZE)
38 #else
39 #define ADV_BUF_LEN (sizeof(struct btp_gap_device_found_ev) + 2 * 31)
40 #endif
41
42 static atomic_t current_settings;
43 struct bt_conn_auth_cb cb;
44 static uint8_t oob_legacy_tk[16] = { 0 };
45
46 static bool filter_list_in_use;
47
48 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
49 static struct bt_le_oob oob_sc_local = { 0 };
50 static struct bt_le_oob oob_sc_remote = { 0 };
51 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
52
53 /* connection parameters for rejection test */
54 #define REJECT_INTERVAL_MIN 0x0C80
55 #define REJECT_INTERVAL_MAX 0x0C80
56 #define REJECT_LATENCY 0x0000
57 #define REJECT_SUPERVISION_TIMEOUT 0x0C80
58
59 #if defined(CONFIG_BT_PRIVACY)
60 static struct {
61 bt_addr_le_t addr;
62 bool supported;
63 } cars[CONFIG_BT_MAX_PAIRED];
64
65 static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err,
66 struct bt_gatt_read_params *params, const void *data,
67 uint16_t length);
68
69 static struct bt_gatt_read_params read_car_params = {
70 .func = read_car_cb,
71 .by_uuid.uuid = BT_UUID_CENTRAL_ADDR_RES,
72 .by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE,
73 .by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE,
74 };
75
read_car_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)76 static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err,
77 struct bt_gatt_read_params *params, const void *data,
78 uint16_t length)
79 {
80 struct bt_conn_info info;
81 bool supported = false;
82
83 if (!err && data && length == 1) {
84 const uint8_t *tmp = data;
85
86 /* only 0 or 1 are valid values */
87 if (tmp[0] == 1) {
88 supported = true;
89 }
90 }
91
92 bt_conn_get_info(conn, &info);
93
94 for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) {
95 if (bt_addr_le_eq(info.le.dst, &cars[i].addr)) {
96 cars[i].supported = supported;
97 break;
98 }
99 }
100
101 return BT_GATT_ITER_STOP;
102 }
103 #endif
104
le_connected(struct bt_conn * conn,uint8_t err)105 static void le_connected(struct bt_conn *conn, uint8_t err)
106 {
107 struct btp_gap_device_connected_ev ev;
108 char addr_str[BT_ADDR_LE_STR_LEN];
109 struct bt_conn_info info;
110
111 (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr_str, sizeof(addr_str));
112 LOG_DBG("%s: 0x%02x", addr_str, err);
113
114 if (err) {
115 return;
116 }
117
118 bt_conn_get_info(conn, &info);
119
120 bt_addr_le_copy(&ev.address, info.le.dst);
121 ev.interval = sys_cpu_to_le16(info.le.interval);
122 ev.latency = sys_cpu_to_le16(info.le.latency);
123 ev.timeout = sys_cpu_to_le16(info.le.timeout);
124
125 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, &ev, sizeof(ev));
126
127 if (info.role == BT_CONN_ROLE_PERIPHERAL) {
128 struct btp_gap_new_settings_ev sev;
129
130 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
131 sev.current_settings = sys_cpu_to_le32(current_settings);
132 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, &sev, sizeof(sev));
133 }
134 }
135
le_disconnected(struct bt_conn * conn,uint8_t reason)136 static void le_disconnected(struct bt_conn *conn, uint8_t reason)
137 {
138 struct btp_gap_device_disconnected_ev ev;
139 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
140 char addr_str[BT_ADDR_LE_STR_LEN];
141
142 (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr_str, sizeof(addr_str));
143 LOG_DBG("%s: 0x%02x", addr_str, reason);
144
145 bt_addr_le_copy(&ev.address, addr);
146
147 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, &ev, sizeof(ev));
148 }
149
le_identity_resolved(struct bt_conn * conn,const bt_addr_le_t * rpa,const bt_addr_le_t * identity)150 static void le_identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa,
151 const bt_addr_le_t *identity)
152 {
153 struct btp_gap_identity_resolved_ev ev;
154
155 bt_addr_le_copy(&ev.address, rpa);
156 bt_addr_le_copy(&ev.identity_address, identity);
157
158 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, &ev, sizeof(ev));
159 }
160
le_param_updated(struct bt_conn * conn,uint16_t interval,uint16_t latency,uint16_t timeout)161 static void le_param_updated(struct bt_conn *conn, uint16_t interval,
162 uint16_t latency, uint16_t timeout)
163 {
164 struct btp_gap_conn_param_update_ev ev;
165 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
166
167 bt_addr_le_copy(&ev.address, addr);
168 ev.interval = sys_cpu_to_le16(interval);
169 ev.latency = sys_cpu_to_le16(latency);
170 ev.timeout = sys_cpu_to_le16(timeout);
171
172 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_CONN_PARAM_UPDATE, &ev, sizeof(ev));
173 }
174
le_param_req(struct bt_conn * conn,struct bt_le_conn_param * param)175 static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
176 {
177 /* reject update if all parameters match reject pattern */
178 if ((param->interval_min == REJECT_INTERVAL_MIN) &&
179 (param->interval_max == REJECT_INTERVAL_MAX) &&
180 (param->latency == REJECT_LATENCY) &&
181 (param->timeout == REJECT_SUPERVISION_TIMEOUT)) {
182 return false;
183 }
184
185 return true;
186 }
187
le_security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)188 static void le_security_changed(struct bt_conn *conn, bt_security_t level,
189 enum bt_security_err err)
190 {
191 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
192 struct btp_gap_sec_level_changed_ev sec_ev;
193 struct btp_gap_bond_lost_ev bond_ev;
194 struct bt_conn_info info;
195
196 switch (err) {
197 case BT_SECURITY_ERR_SUCCESS:
198 bt_addr_le_copy(&sec_ev.address, addr);
199 /* enum matches BTP values */
200 sec_ev.sec_level = level;
201
202 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_LEVEL_CHANGED,
203 &sec_ev, sizeof(sec_ev));
204 break;
205 case BT_SECURITY_ERR_PIN_OR_KEY_MISSING:
206 /* for central role this means that peer have no LTK when we
207 * started encryption procedure
208 *
209 * This means bond is lost and we restart pairing to re-bond
210 */
211 if (bt_conn_get_info(conn, &info) == 0 &&
212 info.role == BT_CONN_ROLE_CENTRAL) {
213 LOG_DBG("Bond lost");
214
215 bt_addr_le_copy(&bond_ev.address, addr);
216
217 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BOND_LOST,
218 &bond_ev, sizeof(bond_ev));
219
220 (void)bt_conn_set_security(conn, BT_SECURITY_L2 | BT_SECURITY_FORCE_PAIR);
221 }
222 break;
223 default:
224 break;
225 }
226 }
227
228 static struct bt_conn_cb conn_callbacks = {
229 .connected = le_connected,
230 .disconnected = le_disconnected,
231 .identity_resolved = le_identity_resolved,
232 .le_param_updated = le_param_updated,
233 .le_param_req = le_param_req,
234 .security_changed = le_security_changed,
235 };
236
supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)237 static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
238 void *rsp, uint16_t *rsp_len)
239 {
240 struct btp_gap_read_supported_commands_rp *rp = rsp;
241
242 /* octet 0 */
243 tester_set_bit(rp->data, BTP_GAP_READ_SUPPORTED_COMMANDS);
244 tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INDEX_LIST);
245 tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INFO);
246 tester_set_bit(rp->data, BTP_GAP_SET_POWERED);
247 tester_set_bit(rp->data, BTP_GAP_SET_CONNECTABLE);
248
249 /* octet 1 */
250 tester_set_bit(rp->data, BTP_GAP_SET_DISCOVERABLE);
251 tester_set_bit(rp->data, BTP_GAP_SET_BONDABLE);
252 tester_set_bit(rp->data, BTP_GAP_START_ADVERTISING);
253 tester_set_bit(rp->data, BTP_GAP_STOP_ADVERTISING);
254 tester_set_bit(rp->data, BTP_GAP_START_DISCOVERY);
255 tester_set_bit(rp->data, BTP_GAP_STOP_DISCOVERY);
256 tester_set_bit(rp->data, BTP_GAP_CONNECT);
257 tester_set_bit(rp->data, BTP_GAP_DISCONNECT);
258
259 /* octet 2 */
260 tester_set_bit(rp->data, BTP_GAP_SET_IO_CAP);
261 tester_set_bit(rp->data, BTP_GAP_PAIR);
262 tester_set_bit(rp->data, BTP_GAP_PASSKEY_ENTRY);
263 tester_set_bit(rp->data, BTP_GAP_PASSKEY_CONFIRM);
264 tester_set_bit(rp->data, BTP_GAP_START_DIRECTED_ADV);
265 tester_set_bit(rp->data, BTP_GAP_CONN_PARAM_UPDATE);
266
267 /* octet 3 */
268 tester_set_bit(rp->data, BTP_GAP_OOB_LEGACY_SET_DATA);
269 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
270 tester_set_bit(rp->data, BTP_GAP_OOB_SC_GET_LOCAL_DATA);
271 tester_set_bit(rp->data, BTP_GAP_OOB_SC_SET_REMOTE_DATA);
272 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
273 tester_set_bit(rp->data, BTP_GAP_SET_MITM);
274 tester_set_bit(rp->data, BTP_GAP_SET_FILTER_LIST);
275 #if defined(CONFIG_BT_EXT_ADV)
276 tester_set_bit(rp->data, BTP_GAP_SET_EXTENDED_ADVERTISING);
277 #endif
278
279 *rsp_len = sizeof(*rp) + 4;
280
281 return BTP_STATUS_SUCCESS;
282 }
283
controller_index_list(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)284 static uint8_t controller_index_list(const void *cmd, uint16_t cmd_len,
285 void *rsp, uint16_t *rsp_len)
286 {
287 struct btp_gap_read_controller_index_list_rp *rp = rsp;
288
289 rp->num = 1U;
290 rp->index[0] = BTP_INDEX;
291
292 *rsp_len = sizeof(*rp) + 1;
293
294 return BTP_STATUS_SUCCESS;
295 }
296
controller_info(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)297 static uint8_t controller_info(const void *cmd, uint16_t cmd_len,
298 void *rsp, uint16_t *rsp_len)
299 {
300 struct btp_gap_read_controller_info_rp *rp = rsp;
301 uint32_t supported_settings;
302 struct bt_le_oob oob_local = { 0 };
303
304 bt_le_oob_get_local(BT_ID_DEFAULT, &oob_local);
305
306 bt_addr_copy(&rp->address, &oob_local.addr.a);
307
308 /*
309 * Re-use the oob data read here in get_oob_sc_local_data()
310 */
311 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
312 oob_sc_local = oob_local;
313 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
314
315 /*
316 * If privacy is used, the device uses random type address, otherwise
317 * static random or public type address is used.
318 */
319 #if !defined(CONFIG_BT_PRIVACY)
320 if (oob_local.addr.type == BT_ADDR_LE_RANDOM) {
321 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_STATIC_ADDRESS);
322 }
323 #endif /* CONFIG_BT_PRIVACY */
324
325 supported_settings = BIT(BTP_GAP_SETTINGS_POWERED);
326 supported_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE);
327 supported_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE);
328 supported_settings |= BIT(BTP_GAP_SETTINGS_LE);
329 supported_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING);
330 supported_settings |= BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
331
332 rp->supported_settings = sys_cpu_to_le32(supported_settings);
333 rp->current_settings = sys_cpu_to_le32(current_settings);
334
335 memcpy(rp->name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME));
336
337 *rsp_len = sizeof(*rp);
338
339 return BTP_STATUS_SUCCESS;
340 }
341
342 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
oob_config_str(int oob_config)343 static const char *oob_config_str(int oob_config)
344 {
345 switch (oob_config) {
346 case BT_CONN_OOB_LOCAL_ONLY:
347 return "Local";
348 case BT_CONN_OOB_REMOTE_ONLY:
349 return "Remote";
350 case BT_CONN_OOB_BOTH_PEERS:
351 return "Local and Remote";
352 case BT_CONN_OOB_NO_DATA:
353 default:
354 return "no";
355 }
356 }
357 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
358
oob_data_request(struct bt_conn * conn,struct bt_conn_oob_info * oob_info)359 static void oob_data_request(struct bt_conn *conn,
360 struct bt_conn_oob_info *oob_info)
361 {
362 struct bt_conn_info info;
363 int err = bt_conn_get_info(conn, &info);
364
365 if (err) {
366 return;
367 }
368
369 char addr[BT_ADDR_LE_STR_LEN];
370
371 bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
372
373 switch (oob_info->type) {
374 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
375 case BT_CONN_OOB_LE_SC:
376 {
377 LOG_DBG("Set %s OOB SC data for %s, ",
378 oob_config_str(oob_info->lesc.oob_config),
379 addr);
380
381 struct bt_le_oob_sc_data *oobd_local =
382 oob_info->lesc.oob_config != BT_CONN_OOB_REMOTE_ONLY ?
383 &oob_sc_local.le_sc_data :
384 NULL;
385
386 struct bt_le_oob_sc_data *oobd_remote =
387 oob_info->lesc.oob_config != BT_CONN_OOB_LOCAL_ONLY ?
388 &oob_sc_remote.le_sc_data :
389 NULL;
390
391 if (oobd_remote) {
392 /* Assume that oob_sc_remote
393 * corresponds to the currently connected peer
394 */
395 bt_addr_le_copy(&oob_sc_remote.addr, info.le.remote);
396 }
397
398 if (oobd_local &&
399 !bt_addr_le_eq(info.le.local, &oob_sc_local.addr)) {
400 bt_addr_le_to_str(info.le.local, addr, sizeof(addr));
401 LOG_DBG("No OOB data available for local %s",
402 addr);
403 bt_conn_auth_cancel(conn);
404 return;
405 }
406
407 err = bt_le_oob_set_sc_data(conn, oobd_local, oobd_remote);
408 if (err) {
409 LOG_DBG("bt_le_oob_set_sc_data failed with: %d", err);
410 }
411
412 break;
413 }
414 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
415
416 #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
417 case BT_CONN_OOB_LE_LEGACY:
418 LOG_DBG("Legacy OOB TK requested from remote %s", addr);
419
420 err = bt_le_oob_set_legacy_tk(conn, oob_legacy_tk);
421 if (err < 0) {
422 LOG_ERR("Failed to set OOB TK: %d", err);
423 }
424
425 break;
426 #endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
427 default:
428 LOG_ERR("Unhandled OOB type %d", oob_info->type);
429 break;
430 }
431 }
432
433 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
get_oob_sc_local_data(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)434 static uint8_t get_oob_sc_local_data(const void *cmd, uint16_t cmd_len,
435 void *rsp, uint16_t *rsp_len)
436 {
437 struct btp_gap_oob_sc_get_local_data_rp *rp = rsp;
438
439 cb.oob_data_request = oob_data_request;
440
441 memcpy(rp->conf, &oob_sc_local.le_sc_data.c[0], sizeof(rp->conf));
442 memcpy(rp->rand, &oob_sc_local.le_sc_data.r[0], sizeof(rp->rand));
443
444 *rsp_len = sizeof(*rp);
445 return BTP_STATUS_SUCCESS;
446 }
447
set_oob_sc_remote_data(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)448 static uint8_t set_oob_sc_remote_data(const void *cmd, uint16_t cmd_len,
449 void *rsp, uint16_t *rsp_len)
450 {
451 const struct btp_gap_oob_sc_set_remote_data_cmd *cp = cmd;
452
453 cb.oob_data_request = oob_data_request;
454 bt_le_oob_set_sc_flag(true);
455
456 /* Note that the .addr field
457 * will be set by the oob_data_request callback
458 */
459 memcpy(&oob_sc_remote.le_sc_data.r[0], cp->rand,
460 sizeof(oob_sc_remote.le_sc_data.r));
461 memcpy(&oob_sc_remote.le_sc_data.c[0], cp->conf,
462 sizeof(oob_sc_remote.le_sc_data.c));
463
464 return BTP_STATUS_SUCCESS;
465 }
466 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
467
set_powered(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)468 static uint8_t set_powered(const void *cmd, uint16_t cmd_len,
469 void *rsp, uint16_t *rsp_len)
470 {
471 const struct btp_gap_set_powered_cmd *cp = cmd;
472 struct btp_gap_set_powered_rp *rp = rsp;
473 int err;
474
475 if (cp->powered) {
476 err = bt_enable(NULL);
477 if (err < 0) {
478 LOG_ERR("Unable to enable Bluetooth: %d", err);
479 return BTP_STATUS_FAILED;
480 }
481 bt_conn_cb_register(&conn_callbacks);
482 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_POWERED);
483 } else {
484 err = bt_disable();
485 if (err < 0) {
486 LOG_ERR("Unable to disable Bluetooth: %d", err);
487 return BTP_STATUS_FAILED;
488 }
489 bt_conn_cb_unregister(&conn_callbacks);
490 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_POWERED);
491 }
492 rp->current_settings = sys_cpu_to_le32(current_settings);
493
494 *rsp_len = sizeof(*rp);
495
496 return BTP_STATUS_SUCCESS;
497 }
498
set_connectable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)499 static uint8_t set_connectable(const void *cmd, uint16_t cmd_len,
500 void *rsp, uint16_t *rsp_len)
501 {
502 const struct btp_gap_set_connectable_cmd *cp = cmd;
503 struct btp_gap_set_connectable_rp *rp = rsp;
504
505 if (cp->connectable) {
506 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE);
507 } else {
508 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE);
509 }
510
511 rp->current_settings = sys_cpu_to_le32(current_settings);
512
513 *rsp_len = sizeof(*rp);
514
515 return BTP_STATUS_SUCCESS;
516 }
517
518 static uint8_t ad_flags = BT_LE_AD_NO_BREDR;
519 static struct bt_data ad[10] = {
520 BT_DATA(BT_DATA_FLAGS, &ad_flags, sizeof(ad_flags)),
521 };
522 static struct bt_data sd[10];
523
524 #if defined(CONFIG_BT_EXT_ADV)
525 static struct bt_le_ext_adv *ext_adv;
526
tester_gap_ext_adv_get(void)527 struct bt_le_ext_adv *tester_gap_ext_adv_get(void)
528 {
529 return ext_adv;
530 }
531
tester_gap_start_ext_adv(void)532 int tester_gap_start_ext_adv(void)
533 {
534 int err;
535
536 err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
537 if (err != 0) {
538 LOG_ERR("Failed to start advertising");
539
540 return -EINVAL;
541 }
542
543 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
544
545 return 0;
546 }
547
tester_gap_stop_ext_adv(void)548 int tester_gap_stop_ext_adv(void)
549 {
550 int err;
551
552 err = bt_le_ext_adv_stop(ext_adv);
553 if (err != 0) {
554 LOG_ERR("Failed to stop advertising");
555
556 return -EINVAL;
557 }
558
559 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
560
561 return 0;
562 }
563 #endif /* defined(CONFIG_BT_EXT_ADV) */
564
set_discoverable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)565 static uint8_t set_discoverable(const void *cmd, uint16_t cmd_len,
566 void *rsp, uint16_t *rsp_len)
567 {
568 const struct btp_gap_set_discoverable_cmd *cp = cmd;
569 struct btp_gap_set_discoverable_rp *rp = rsp;
570
571 switch (cp->discoverable) {
572 case BTP_GAP_NON_DISCOVERABLE:
573 ad_flags &= ~(BT_LE_AD_GENERAL | BT_LE_AD_LIMITED);
574 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_DISCOVERABLE);
575 break;
576 case BTP_GAP_GENERAL_DISCOVERABLE:
577 ad_flags &= ~BT_LE_AD_LIMITED;
578 ad_flags |= BT_LE_AD_GENERAL;
579 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_DISCOVERABLE);
580 break;
581 case BTP_GAP_LIMITED_DISCOVERABLE:
582 ad_flags &= ~BT_LE_AD_GENERAL;
583 ad_flags |= BT_LE_AD_LIMITED;
584 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_DISCOVERABLE);
585 break;
586 default:
587 return BTP_STATUS_FAILED;
588 }
589
590 rp->current_settings = sys_cpu_to_le32(current_settings);
591
592 *rsp_len = sizeof(*rp);
593 return BTP_STATUS_SUCCESS;
594 }
595
set_bondable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)596 static uint8_t set_bondable(const void *cmd, uint16_t cmd_len,
597 void *rsp, uint16_t *rsp_len)
598 {
599 const struct btp_gap_set_bondable_cmd *cp = cmd;
600 struct btp_gap_set_bondable_rp *rp = rsp;
601
602 LOG_DBG("bondable: %d", cp->bondable);
603
604 if (cp->bondable) {
605 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_BONDABLE);
606 } else {
607 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_BONDABLE);
608 }
609
610 bt_set_bondable(cp->bondable);
611
612 rp->current_settings = sys_cpu_to_le32(current_settings);
613 *rsp_len = sizeof(*rp);
614 return BTP_STATUS_SUCCESS;
615 }
616
tester_gap_create_adv_instance(struct bt_le_adv_param * param,uint8_t own_addr_type,const struct bt_data * ad,size_t ad_len,const struct bt_data * sd,size_t sd_len,uint32_t * settings)617 int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type,
618 const struct bt_data *ad, size_t ad_len,
619 const struct bt_data *sd, size_t sd_len,
620 uint32_t *settings)
621 {
622 int err = 0;
623
624 if (settings != NULL) {
625 atomic_set(¤t_settings, *settings);
626 }
627
628 if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) {
629 param->options |= BT_LE_ADV_OPT_CONN;
630
631 if (filter_list_in_use) {
632 param->options |= BT_LE_ADV_OPT_FILTER_CONN;
633 }
634 }
635
636 if (filter_list_in_use) {
637 param->options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ;
638 }
639
640 switch (own_addr_type) {
641 case BTP_GAP_ADDR_TYPE_IDENTITY:
642 param->options |= BT_LE_ADV_OPT_USE_IDENTITY;
643 break;
644 #if defined(CONFIG_BT_PRIVACY)
645 case BTP_GAP_ADDR_TYPE_RESOLVABLE_PRIVATE:
646 /* RPA usage is controlled via privacy settings */
647 if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY)) {
648 return -EINVAL;
649 }
650 break;
651 case BTP_GAP_ADDR_TYPE_NON_RESOLVABLE_PRIVATE:
652 /* NRPA is used only for non-connectable advertising */
653 if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) {
654 return -EINVAL;
655 }
656 break;
657 #endif
658 default:
659 return -EINVAL;
660 }
661
662 if (IS_ENABLED(CONFIG_BT_EXT_ADV) && atomic_test_bit(¤t_settings,
663 BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) {
664 param->options |= BT_LE_ADV_OPT_EXT_ADV;
665 if (ext_adv != NULL) {
666 err = bt_le_ext_adv_stop(ext_adv);
667 if (err != 0) {
668 return err;
669 }
670
671 err = bt_le_ext_adv_delete(ext_adv);
672 if (err != 0) {
673 return err;
674 }
675
676 ext_adv = NULL;
677 }
678
679 err = bt_le_ext_adv_create(param, NULL, &ext_adv);
680 if (err != 0) {
681 return BTP_STATUS_FAILED;
682 }
683
684 err = bt_le_ext_adv_set_data(ext_adv, ad, ad_len, sd_len ? sd : NULL, sd_len);
685 }
686
687 return err;
688 }
689
start_advertising(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)690 static uint8_t start_advertising(const void *cmd, uint16_t cmd_len,
691 void *rsp, uint16_t *rsp_len)
692 {
693 const struct btp_gap_start_advertising_cmd *cp = cmd;
694 struct btp_gap_start_advertising_rp *rp = rsp;
695 struct bt_le_adv_param param =
696 BT_LE_ADV_PARAM_INIT(0, BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL);
697 uint8_t own_addr_type;
698 uint32_t duration;
699 uint8_t adv_len;
700 uint8_t sd_len;
701 int err;
702 int i;
703
704 /* This command is very unfortunate since after variable data there is
705 * additional 5 bytes (4 bytes for duration, 1 byte for own address
706 * type.
707 */
708 if ((cmd_len < sizeof(*cp)) ||
709 (cmd_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len +
710 sizeof(duration) + sizeof(own_addr_type))) {
711 return BTP_STATUS_FAILED;
712 }
713
714 /* currently ignored */
715 duration = sys_get_le32(cp->adv_sr_data + cp->adv_data_len + cp->scan_rsp_len);
716 (void)duration;
717 own_addr_type = cp->adv_sr_data[cp->adv_data_len + cp->scan_rsp_len + sizeof(duration)];
718
719 for (i = 0, adv_len = 1U; i < cp->adv_data_len; adv_len++) {
720 if (adv_len >= ARRAY_SIZE(ad)) {
721 LOG_ERR("ad[] Out of memory");
722 return BTP_STATUS_FAILED;
723 }
724
725 ad[adv_len].type = cp->adv_sr_data[i++];
726 ad[adv_len].data_len = cp->adv_sr_data[i++];
727 ad[adv_len].data = &cp->adv_sr_data[i];
728 i += ad[adv_len].data_len;
729 }
730
731 for (sd_len = 0U; i < cp->adv_data_len + cp->scan_rsp_len; sd_len++) {
732 if (sd_len >= ARRAY_SIZE(sd)) {
733 LOG_ERR("sd[] Out of memory");
734 return BTP_STATUS_FAILED;
735 }
736
737 sd[sd_len].type = cp->adv_sr_data[i++];
738 sd[sd_len].data_len = cp->adv_sr_data[i++];
739 sd[sd_len].data = &cp->adv_sr_data[i];
740 i += sd[sd_len].data_len;
741 }
742
743 err = tester_gap_create_adv_instance(¶m, own_addr_type, ad, adv_len, sd, sd_len, NULL);
744 if (err != 0) {
745 return BTP_STATUS_FAILED;
746 }
747
748 #if defined(CONFIG_BT_EXT_ADV)
749 if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) {
750 err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
751 #else
752 if (0) {
753 #endif
754 } else {
755 err = bt_le_adv_start(¶m, ad, adv_len, sd_len ? sd : NULL, sd_len);
756 }
757
758 /* BTP API don't allow to set empty scan response data. */
759 if (err < 0) {
760 LOG_ERR("Failed to start advertising");
761
762 return BTP_STATUS_FAILED;
763 }
764
765 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
766 rp->current_settings = sys_cpu_to_le32(current_settings);
767
768 *rsp_len = sizeof(*rp);
769 return BTP_STATUS_SUCCESS;
770 }
771
772 static uint8_t start_directed_advertising(const void *cmd, uint16_t cmd_len,
773 void *rsp, uint16_t *rsp_len)
774 {
775 const struct btp_gap_start_directed_adv_cmd *cp = cmd;
776 struct btp_gap_start_directed_adv_rp *rp = rsp;
777 struct bt_le_adv_param adv_param;
778 uint16_t options = sys_le16_to_cpu(cp->options);
779
780 adv_param = *BT_LE_ADV_CONN_DIR(&cp->address);
781
782 if (!(options & BTP_GAP_START_DIRECTED_ADV_HD)) {
783 adv_param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY;
784 adv_param.interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
785 adv_param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
786 }
787
788 if (options & BTP_GAP_START_DIRECTED_ADV_PEER_RPA) {
789 #if defined(CONFIG_BT_PRIVACY)
790 /* check if peer supports Central Address Resolution */
791 for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) {
792 if (bt_addr_le_eq(&cp->address, &cars[i].addr)) {
793 if (cars[i].supported) {
794 adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA;
795 }
796 }
797 }
798 #endif
799 }
800
801 if (bt_le_adv_start(&adv_param, NULL, 0, NULL, 0) < 0) {
802 LOG_ERR("Failed to start advertising");
803 return BTP_STATUS_FAILED;
804 }
805
806 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
807 rp->current_settings = sys_cpu_to_le32(current_settings);
808
809 *rsp_len = sizeof(*rp);
810 return BTP_STATUS_SUCCESS;
811 }
812
813 static uint8_t stop_advertising(const void *cmd, uint16_t cmd_len,
814 void *rsp, uint16_t *rsp_len)
815 {
816 struct btp_gap_stop_advertising_rp *rp = rsp;
817 int err;
818
819 err = bt_le_adv_stop();
820 if (err < 0) {
821 tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_ADVERTISING, BTP_STATUS_FAILED);
822 LOG_ERR("Failed to stop advertising: %d", err);
823 return BTP_STATUS_FAILED;
824 }
825
826 atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING);
827 rp->current_settings = sys_cpu_to_le32(current_settings);
828
829 *rsp_len = sizeof(*rp);
830 return BTP_STATUS_SUCCESS;
831 }
832
833 static uint8_t get_ad_flags(struct net_buf_simple *buf_ad)
834 {
835 uint8_t len, i;
836
837 /* Parse advertisement to get flags */
838 for (i = 0U; i < buf_ad->len; i += len - 1) {
839 len = buf_ad->data[i++];
840 if (!len) {
841 break;
842 }
843
844 /* Check if field length is correct */
845 if (len > (buf_ad->len - i) || (buf_ad->len - i) < 1) {
846 break;
847 }
848
849 switch (buf_ad->data[i++]) {
850 case BT_DATA_FLAGS:
851 return buf_ad->data[i];
852 default:
853 break;
854 }
855 }
856
857 return 0;
858 }
859
860 static uint8_t discovery_flags;
861 static struct net_buf_simple *adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN);
862
863 static void store_adv(const bt_addr_le_t *addr, int8_t rssi,
864 struct net_buf_simple *buf_ad)
865 {
866 struct btp_gap_device_found_ev *ev;
867
868 /* cleanup */
869 net_buf_simple_init(adv_buf, 0);
870
871 ev = net_buf_simple_add(adv_buf, sizeof(*ev));
872
873 bt_addr_le_copy(&ev->address, addr);
874 ev->rssi = rssi;
875 ev->flags = BTP_GAP_DEVICE_FOUND_FLAG_AD | BTP_GAP_DEVICE_FOUND_FLAG_RSSI;
876 ev->eir_data_len = buf_ad->len;
877 memcpy(net_buf_simple_add(adv_buf, buf_ad->len), buf_ad->data, buf_ad->len);
878 }
879
880 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t evtype,
881 struct net_buf_simple *buf_ad)
882 {
883 /* if General/Limited Discovery - parse Advertising data to get flags */
884 if (!(discovery_flags & BTP_GAP_DISCOVERY_FLAG_LE_OBSERVE) &&
885 (evtype != BT_GAP_ADV_TYPE_SCAN_RSP)) {
886 uint8_t flags = get_ad_flags(buf_ad);
887
888 /* ignore non-discoverable devices */
889 if (!(flags & BT_LE_AD_DISCOV_MASK)) {
890 LOG_DBG("Non discoverable, skipping");
891 return;
892 }
893
894 /* if Limited Discovery - ignore general discoverable devices */
895 if ((discovery_flags & BTP_GAP_DISCOVERY_FLAG_LIMITED) &&
896 !(flags & BT_LE_AD_LIMITED)) {
897 LOG_DBG("General discoverable, skipping");
898 return;
899 }
900 }
901
902 /* attach Scan Response data */
903 if (evtype == BT_GAP_ADV_TYPE_SCAN_RSP) {
904 struct btp_gap_device_found_ev *ev;
905 bt_addr_le_t a;
906
907 /* skip if there is no pending advertisement */
908 if (!adv_buf->len) {
909 LOG_INF("No pending advertisement, skipping");
910 return;
911 }
912
913 ev = (void *) adv_buf->data;
914
915 bt_addr_le_copy(&a, &ev->address);
916
917 /*
918 * in general, the Scan Response comes right after the
919 * Advertisement, but if not if send stored event and ignore
920 * this one
921 */
922 if (!bt_addr_le_eq(addr, &a)) {
923 LOG_INF("Address does not match, skipping");
924 goto done;
925 }
926
927 ev->eir_data_len += buf_ad->len;
928 ev->flags |= BTP_GAP_DEVICE_FOUND_FLAG_SD;
929
930 memcpy(net_buf_simple_add(adv_buf, buf_ad->len), buf_ad->data, buf_ad->len);
931
932 goto done;
933 }
934
935 /*
936 * if there is another pending advertisement, send it and store the
937 * current one
938 */
939 if (adv_buf->len) {
940 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND,
941 adv_buf->data, adv_buf->len);
942 net_buf_simple_reset(adv_buf);
943 }
944
945 store_adv(addr, rssi, buf_ad);
946
947 /* if Active Scan and scannable event - wait for Scan Response */
948 if ((discovery_flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) &&
949 (evtype == BT_GAP_ADV_TYPE_ADV_IND ||
950 evtype == BT_GAP_ADV_TYPE_ADV_SCAN_IND)) {
951 LOG_DBG("Waiting for scan response");
952 return;
953 }
954 done:
955 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND,
956 adv_buf->data, adv_buf->len);
957 net_buf_simple_reset(adv_buf);
958 }
959
960 static uint8_t start_discovery(const void *cmd, uint16_t cmd_len,
961 void *rsp, uint16_t *rsp_len)
962 {
963 const struct btp_gap_start_discovery_cmd *cp = cmd;
964
965 /* only LE scan is supported */
966 if (cp->flags & BTP_GAP_DISCOVERY_FLAG_BREDR) {
967 LOG_WRN("BR/EDR not supported");
968 return BTP_STATUS_FAILED;
969 }
970
971 if (bt_le_scan_start(cp->flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN ?
972 BT_LE_SCAN_ACTIVE : BT_LE_SCAN_PASSIVE,
973 device_found) < 0) {
974 LOG_ERR("Failed to start scanning");
975 return BTP_STATUS_FAILED;
976 }
977
978 net_buf_simple_init(adv_buf, 0);
979 discovery_flags = cp->flags;
980
981 return BTP_STATUS_SUCCESS;
982 }
983
984 static uint8_t stop_discovery(const void *cmd, uint16_t cmd_len,
985 void *rsp, uint16_t *rsp_len)
986 {
987 int err;
988
989 err = bt_le_scan_stop();
990 if (err < 0) {
991 LOG_ERR("Failed to stop scanning: %d", err);
992 return BTP_STATUS_FAILED;
993 }
994
995 return BTP_STATUS_SUCCESS;
996 }
997
998 static uint8_t connect(const void *cmd, uint16_t cmd_len,
999 void *rsp, uint16_t *rsp_len)
1000 {
1001 /* The conn interval is set to 60ms (0x30). This is to better support test cases where we
1002 * need to connect to multiple peripherals (up to 3). The connection interval should also be
1003 * a multiple of 30ms, as that is ideal to support both 7.5ms and 10ms ISO intervals
1004 */
1005 const uint16_t interval = BT_GAP_MS_TO_CONN_INTERVAL(60U);
1006 const struct bt_le_conn_param *conn_param =
1007 BT_LE_CONN_PARAM(interval, interval, 0U, BT_GAP_MS_TO_CONN_TIMEOUT(4000U));
1008 const struct btp_gap_connect_cmd *cp = cmd;
1009 int err;
1010
1011 if (!bt_addr_le_eq(&cp->address, BT_ADDR_LE_ANY)) {
1012 struct bt_conn *conn = NULL;
1013
1014 err = bt_conn_le_create(&cp->address, BT_CONN_LE_CREATE_CONN, conn_param, &conn);
1015 if (err) {
1016 LOG_ERR("Failed to create connection (%d)", err);
1017 return BTP_STATUS_FAILED;
1018 }
1019
1020 bt_conn_unref(conn);
1021 } else {
1022 err = bt_conn_le_create_auto(BT_CONN_LE_CREATE_CONN, conn_param);
1023 if (err) {
1024 LOG_ERR("Failed to create auto connection (%d)", err);
1025 return BTP_STATUS_FAILED;
1026 }
1027 }
1028
1029 return BTP_STATUS_SUCCESS;
1030 }
1031
1032 static uint8_t disconnect(const void *cmd, uint16_t cmd_len,
1033 void *rsp, uint16_t *rsp_len)
1034 {
1035 const struct btp_gap_disconnect_cmd *cp = cmd;
1036 struct bt_conn *conn;
1037 uint8_t status;
1038
1039 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1040 if (!conn) {
1041 LOG_ERR("Unknown connection");
1042 return BTP_STATUS_FAILED;
1043 }
1044
1045 if (bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN)) {
1046 LOG_ERR("Failed to disconnect");
1047 status = BTP_STATUS_FAILED;
1048 } else {
1049 status = BTP_STATUS_SUCCESS;
1050 }
1051
1052 bt_conn_unref(conn);
1053
1054 return status;
1055 }
1056
1057 static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
1058 {
1059 struct btp_gap_passkey_display_ev ev;
1060 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
1061
1062 bt_addr_le_copy(&ev.address, addr);
1063 ev.passkey = sys_cpu_to_le32(passkey);
1064
1065 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, &ev, sizeof(ev));
1066 }
1067
1068 static void auth_passkey_entry(struct bt_conn *conn)
1069 {
1070 struct btp_gap_passkey_entry_req_ev ev;
1071 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
1072
1073 bt_addr_le_copy(&ev.address, addr);
1074
1075 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, &ev, sizeof(ev));
1076 }
1077
1078 static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
1079 {
1080 struct btp_gap_passkey_confirm_req_ev ev;
1081 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
1082
1083 bt_addr_le_copy(&ev.address, addr);
1084 ev.passkey = sys_cpu_to_le32(passkey);
1085
1086 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, &ev, sizeof(ev));
1087 }
1088
1089 static void auth_cancel(struct bt_conn *conn)
1090 {
1091 /* TODO */
1092 }
1093
1094 enum bt_security_err auth_pairing_accept(struct bt_conn *conn,
1095 const struct bt_conn_pairing_feat *const feat)
1096 {
1097 struct btp_gap_bond_lost_ev ev;
1098 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
1099
1100 if (!bt_addr_le_is_bonded(BT_ID_DEFAULT, addr)) {
1101 return BT_SECURITY_ERR_SUCCESS;
1102 }
1103
1104 /* If a peer is already bonded and tries to pair again then it means that
1105 * the it has lost its bond information.
1106 */
1107 LOG_DBG("Bond lost");
1108
1109 bt_addr_le_copy(&ev.address, addr);
1110
1111 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BOND_LOST, &ev, sizeof(ev));
1112
1113 return BT_SECURITY_ERR_SUCCESS;
1114 }
1115
1116 void auth_pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
1117 {
1118 struct btp_gap_bond_pairing_failed_ev ev;
1119 const bt_addr_le_t *addr = bt_conn_get_dst(conn);
1120
1121 bt_addr_le_copy(&ev.address, addr);
1122 ev.reason = reason;
1123
1124 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PAIRING_FAILED, &ev, sizeof(ev));
1125 }
1126
1127 static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
1128 {
1129 #if defined(CONFIG_BT_PRIVACY)
1130 /* Read peer's Central Address Resolution if bonded */
1131 if (bonded) {
1132 bt_gatt_read(conn, &read_car_params);
1133 }
1134 #endif
1135 }
1136
1137 static struct bt_conn_auth_info_cb auth_info_cb = {
1138 .pairing_failed = auth_pairing_failed,
1139 .pairing_complete = auth_pairing_complete,
1140 };
1141
1142 static uint8_t set_io_cap(const void *cmd, uint16_t cmd_len,
1143 void *rsp, uint16_t *rsp_len)
1144 {
1145 const struct btp_gap_set_io_cap_cmd *cp = cmd;
1146
1147 /* Reset io cap requirements */
1148 (void)memset(&cb, 0, sizeof(cb));
1149 bt_conn_auth_cb_register(NULL);
1150
1151 LOG_DBG("io_cap: %d", cp->io_cap);
1152
1153 switch (cp->io_cap) {
1154 case BTP_GAP_IO_CAP_DISPLAY_ONLY:
1155 cb.cancel = auth_cancel;
1156 cb.passkey_display = auth_passkey_display;
1157 break;
1158 case BTP_GAP_IO_CAP_KEYBOARD_DISPLAY:
1159 cb.cancel = auth_cancel;
1160 cb.passkey_display = auth_passkey_display;
1161 cb.passkey_entry = auth_passkey_entry;
1162 cb.passkey_confirm = auth_passkey_confirm;
1163 break;
1164 case BTP_GAP_IO_CAP_NO_INPUT_OUTPUT:
1165 cb.cancel = auth_cancel;
1166 break;
1167 case BTP_GAP_IO_CAP_KEYBOARD_ONLY:
1168 cb.cancel = auth_cancel;
1169 cb.passkey_entry = auth_passkey_entry;
1170 break;
1171 case BTP_GAP_IO_CAP_DISPLAY_YESNO:
1172 cb.cancel = auth_cancel;
1173 cb.passkey_display = auth_passkey_display;
1174 cb.passkey_confirm = auth_passkey_confirm;
1175 break;
1176 default:
1177 LOG_WRN("Unhandled io_cap: 0x%x", cp->io_cap);
1178 return BTP_STATUS_FAILED;
1179 }
1180
1181 cb.pairing_accept = auth_pairing_accept;
1182
1183 if (bt_conn_auth_cb_register(&cb)) {
1184 return BTP_STATUS_FAILED;
1185 }
1186
1187 return BTP_STATUS_SUCCESS;
1188 }
1189
1190 static uint8_t pair(const void *cmd, uint16_t cmd_len,
1191 void *rsp, uint16_t *rsp_len)
1192 {
1193 const struct btp_gap_pair_cmd *cp = cmd;
1194 struct bt_conn *conn;
1195 int err;
1196
1197 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1198 if (!conn) {
1199 LOG_ERR("Unknown connection");
1200 return BTP_STATUS_FAILED;
1201 }
1202
1203 err = bt_conn_set_security(conn, BT_SECURITY_L2);
1204 if (err < 0) {
1205 LOG_ERR("Failed to set security: %d", err);
1206 bt_conn_unref(conn);
1207 return BTP_STATUS_FAILED;
1208 }
1209
1210 bt_conn_unref(conn);
1211 return BTP_STATUS_SUCCESS;
1212 }
1213
1214 static uint8_t unpair(const void *cmd, uint16_t cmd_len,
1215 void *rsp, uint16_t *rsp_len)
1216 {
1217 const struct btp_gap_unpair_cmd *cp = cmd;
1218 struct bt_conn *conn;
1219 int err;
1220
1221 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1222 if (!conn) {
1223 LOG_INF("Unknown connection");
1224 goto keys;
1225 }
1226
1227 err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
1228
1229 bt_conn_unref(conn);
1230
1231 if (err < 0) {
1232 LOG_ERR("Failed to disconnect: %d", err);
1233 return BTP_STATUS_FAILED;
1234 }
1235 keys:
1236 err = bt_unpair(BT_ID_DEFAULT, &cp->address);
1237 if (err < 0) {
1238 return BTP_STATUS_FAILED;
1239 }
1240
1241 return BTP_STATUS_SUCCESS;
1242 }
1243
1244 static uint8_t passkey_entry(const void *cmd, uint16_t cmd_len,
1245 void *rsp, uint16_t *rsp_len)
1246 {
1247 const struct btp_gap_passkey_entry_cmd *cp = cmd;
1248 struct bt_conn *conn;
1249 int err;
1250
1251 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1252 if (!conn) {
1253 LOG_ERR("Unknown connection");
1254 return BTP_STATUS_FAILED;
1255 }
1256
1257 err = bt_conn_auth_passkey_entry(conn, sys_le32_to_cpu(cp->passkey));
1258 bt_conn_unref(conn);
1259
1260 if (err < 0) {
1261 LOG_ERR("Failed to enter passkey: %d", err);
1262 return BTP_STATUS_FAILED;
1263 }
1264
1265 return BTP_STATUS_SUCCESS;
1266 }
1267
1268 static uint8_t passkey_confirm(const void *cmd, uint16_t cmd_len,
1269 void *rsp, uint16_t *rsp_len)
1270 {
1271 const struct btp_gap_passkey_confirm_cmd *cp = cmd;
1272 struct bt_conn *conn;
1273 int err;
1274
1275 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1276 if (!conn) {
1277 LOG_ERR("Unknown connection");
1278 return BTP_STATUS_FAILED;
1279 }
1280
1281 if (cp->match) {
1282 err = bt_conn_auth_passkey_confirm(conn);
1283 if (err < 0) {
1284 LOG_ERR("Failed to confirm passkey: %d", err);
1285 }
1286 } else {
1287 err = bt_conn_auth_cancel(conn);
1288 if (err < 0) {
1289 LOG_ERR("Failed to cancel auth: %d", err);
1290 }
1291 }
1292
1293 bt_conn_unref(conn);
1294
1295 if (err < 0) {
1296 return BTP_STATUS_FAILED;
1297 }
1298
1299 return BTP_STATUS_SUCCESS;
1300 }
1301
1302 static uint8_t conn_param_update(const void *cmd, uint16_t cmd_len,
1303 void *rsp, uint16_t *rsp_len)
1304 {
1305 const struct btp_gap_conn_param_update_cmd *cp = cmd;
1306 struct bt_le_conn_param param = {
1307 .interval_min = sys_le16_to_cpu(cp->interval_min),
1308 .interval_max = sys_le16_to_cpu(cp->interval_max),
1309 .latency = sys_le16_to_cpu(cp->latency),
1310 .timeout = sys_le16_to_cpu(cp->timeout),
1311 };
1312 struct bt_conn *conn;
1313 int err;
1314
1315 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1316 if (!conn) {
1317 LOG_ERR("Unknown connection");
1318 return BTP_STATUS_FAILED;
1319 }
1320
1321 err = bt_conn_le_param_update(conn, ¶m);
1322 bt_conn_unref(conn);
1323
1324 if (err < 0) {
1325 LOG_ERR("Failed to update params: %d", err);
1326 return BTP_STATUS_FAILED;
1327 }
1328 return BTP_STATUS_SUCCESS;
1329 }
1330
1331 static uint8_t set_mitm(const void *cmd, uint16_t cmd_len,
1332 void *rsp, uint16_t *rsp_len)
1333 {
1334 /* TODO verify if can be done in runtime */
1335 LOG_WRN("Use CONFIG_BT_SMP_ENFORCE_MITM instead");
1336
1337 return BTP_STATUS_SUCCESS;
1338 }
1339
1340 static uint8_t set_oob_legacy_data(const void *cmd, uint16_t cmd_len,
1341 void *rsp, uint16_t *rsp_len)
1342 {
1343 const struct btp_gap_oob_legacy_set_data_cmd *cp = cmd;
1344
1345 memcpy(oob_legacy_tk, cp->oob_data, 16);
1346
1347 bt_le_oob_set_legacy_flag(true);
1348 cb.oob_data_request = oob_data_request;
1349
1350 return BTP_STATUS_SUCCESS;
1351 }
1352
1353 static uint8_t set_filter_list(const void *cmd, uint16_t cmd_len,
1354 void *rsp, uint16_t *rsp_len)
1355 {
1356 const struct btp_gap_set_filter_list *cp = cmd;
1357 int err;
1358
1359 if ((cmd_len < sizeof(*cp)) ||
1360 (cmd_len != sizeof(*cp) + (cp->cnt * sizeof(cp->addr[0])))) {
1361 return BTP_STATUS_FAILED;
1362 }
1363
1364 (void)bt_le_filter_accept_list_clear();
1365
1366 for (int i = 0; i < cp->cnt; i++) {
1367 err = bt_le_filter_accept_list_add(&cp->addr[i]);
1368 if (err < 0) {
1369 return BTP_STATUS_FAILED;
1370 }
1371 }
1372
1373 filter_list_in_use = cp->cnt != 0;
1374
1375 return BTP_STATUS_SUCCESS;
1376 }
1377
1378 static uint8_t set_extended_advertising(const void *cmd, uint16_t cmd_len,
1379 void *rsp, uint16_t *rsp_len)
1380 {
1381 const struct btp_gap_set_extended_advertising_cmd *cp = cmd;
1382 struct btp_gap_set_extended_advertising_rp *rp = rsp;
1383
1384 LOG_DBG("ext adv settings: %u", cp->settings);
1385
1386 if (cp->settings != 0) {
1387 atomic_set_bit(¤t_settings,
1388 BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
1389 } else {
1390 atomic_clear_bit(¤t_settings,
1391 BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
1392 }
1393
1394 rp->current_settings = sys_cpu_to_le32(current_settings);
1395
1396 *rsp_len = sizeof(*rp);
1397 return BTP_STATUS_SUCCESS;
1398 }
1399
1400 #if defined(CONFIG_BT_PER_ADV)
1401 static struct bt_data padv[10];
1402 static struct bt_le_per_adv_sync *pa_sync;
1403
1404 struct bt_le_per_adv_sync *tester_gap_padv_get(void)
1405 {
1406 return pa_sync;
1407 }
1408
1409 static void pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
1410 struct bt_le_per_adv_sync_synced_info *info)
1411 {
1412 LOG_DBG("");
1413
1414 if (sync == pa_sync) {
1415 struct btp_gap_ev_periodic_sync_established_ev ev;
1416
1417 bt_addr_le_copy(&ev.address, info->addr);
1418 ev.sync_handle = sys_cpu_to_le16(sync->handle);
1419 ev.status = 0;
1420
1421 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_SYNC_ESTABLISHED,
1422 &ev, sizeof(ev));
1423 }
1424 }
1425
1426 static void pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
1427 const struct bt_le_per_adv_sync_term_info *info)
1428 {
1429 LOG_DBG("");
1430
1431 if (sync == pa_sync) {
1432 struct btp_gap_ev_periodic_sync_lost_ev ev;
1433
1434 LOG_DBG("PA sync lost with reason %u", info->reason);
1435 pa_sync = NULL;
1436
1437 ev.sync_handle = sys_cpu_to_le16(sync->handle);
1438 ev.reason = info->reason;
1439
1440 tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_SYNC_LOST,
1441 &ev, sizeof(ev));
1442 }
1443 }
1444
1445 static struct bt_le_per_adv_sync_cb pa_sync_cb = {
1446 .synced = pa_sync_synced_cb,
1447 .term = pa_sync_terminated_cb,
1448 };
1449
1450 int tester_gap_padv_configure(const struct bt_le_per_adv_param *param)
1451 {
1452 int err;
1453 struct bt_le_adv_param ext_adv_param =
1454 BT_LE_ADV_PARAM_INIT(0, param->interval_min, param->interval_max, NULL);
1455
1456 if (ext_adv == NULL) {
1457 current_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) |
1458 BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
1459 err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY, ad,
1460 1, NULL, 0, NULL);
1461 if (err != 0) {
1462 return -EINVAL;
1463 }
1464 }
1465
1466 /* Set periodic advertising parameters and the required
1467 * bit in AD Flags of extended advertising.
1468 */
1469 err = bt_le_per_adv_set_param(ext_adv, param);
1470 if (err != 0) {
1471 LOG_DBG("Failed to set periodic advertising parameters (err %d)\n", err);
1472 }
1473
1474 return err;
1475 }
1476
1477 static uint8_t padv_configure(const void *cmd, uint16_t cmd_len,
1478 void *rsp, uint16_t *rsp_len)
1479 {
1480 int err;
1481 uint32_t options = BT_LE_PER_ADV_OPT_NONE;
1482 const struct btp_gap_padv_configure_cmd *cp = cmd;
1483 struct btp_gap_padv_configure_rp *rp = rsp;
1484
1485 if (cp->flags & BTP_GAP_PADV_INCLUDE_TX_POWER) {
1486 options |= BT_LE_PER_ADV_OPT_USE_TX_POWER;
1487 }
1488
1489 err = tester_gap_padv_configure(BT_LE_PER_ADV_PARAM(sys_le16_to_cpu(cp->interval_min),
1490 sys_le16_to_cpu(cp->interval_max),
1491 options));
1492 if (err) {
1493 return BTP_STATUS_FAILED;
1494 }
1495
1496 rp->current_settings = sys_cpu_to_le32(current_settings);
1497
1498 *rsp_len = sizeof(*rp);
1499
1500 return BTP_STATUS_SUCCESS;
1501 }
1502
1503 int tester_gap_padv_start(void)
1504 {
1505 int err;
1506
1507 if (ext_adv == NULL) {
1508 return -EINVAL;
1509 }
1510
1511 if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING)) {
1512 err = tester_gap_start_ext_adv();
1513 if (err != 0) {
1514 return -EINVAL;
1515 }
1516 }
1517
1518 /* Enable Periodic Advertising */
1519 err = bt_le_per_adv_start(ext_adv);
1520 if (err != 0) {
1521 LOG_DBG("Failed to start periodic advertising data: %d", err);
1522 }
1523
1524 return err;
1525 }
1526
1527 static uint8_t padv_start(const void *cmd, uint16_t cmd_len,
1528 void *rsp, uint16_t *rsp_len)
1529 {
1530 int err;
1531 struct btp_gap_padv_start_rp *rp = rsp;
1532
1533 err = tester_gap_padv_start();
1534
1535 if (err) {
1536 return BTP_STATUS_FAILED;
1537 }
1538
1539 rp->current_settings = sys_cpu_to_le32(current_settings);
1540
1541 *rsp_len = sizeof(*rp);
1542
1543 return BTP_STATUS_SUCCESS;
1544 }
1545
1546 int tester_gap_padv_stop(void)
1547 {
1548 int err;
1549
1550 if (ext_adv == NULL) {
1551 /* Ext adv not yet created */
1552 return -ESRCH;
1553 }
1554
1555 /* Enable Periodic Advertising */
1556 err = bt_le_per_adv_stop(ext_adv);
1557 if (err != 0) {
1558 LOG_DBG("Failed to stop periodic advertising data: %d", err);
1559 }
1560
1561 return err;
1562 }
1563
1564 static uint8_t padv_stop(const void *cmd, uint16_t cmd_len,
1565 void *rsp, uint16_t *rsp_len)
1566 {
1567 int err;
1568 struct btp_gap_padv_stop_rp *rp = rsp;
1569
1570 err = tester_gap_padv_stop();
1571
1572 if (err) {
1573 return BTP_STATUS_FAILED;
1574 }
1575
1576 rp->current_settings = sys_cpu_to_le32(current_settings);
1577
1578 *rsp_len = sizeof(*rp);
1579
1580 return BTP_STATUS_SUCCESS;
1581 }
1582
1583 int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len)
1584 {
1585 int err;
1586
1587 if (ext_adv == NULL) {
1588 return -EINVAL;
1589 }
1590
1591 /* Set Periodic Advertising data */
1592 err = bt_le_per_adv_set_data(ext_adv, per_ad, ad_len);
1593 if (err != 0) {
1594 LOG_DBG("Failed to set periodic advertising data: %d", err);
1595 }
1596
1597 return err;
1598 }
1599
1600 static uint8_t padv_set_data(const void *cmd, uint16_t cmd_len,
1601 void *rsp, uint16_t *rsp_len)
1602 {
1603 int err;
1604 uint8_t padv_len = 0U;
1605 const struct btp_gap_padv_set_data_cmd *cp = cmd;
1606
1607 for (uint8_t i = 0; i < cp->data_len; padv_len++) {
1608 if (padv_len >= ARRAY_SIZE(padv)) {
1609 LOG_ERR("padv[] Out of memory");
1610 return BTP_STATUS_FAILED;
1611 }
1612
1613 padv[padv_len].data_len = cp->data[i++] - 1;
1614 padv[padv_len].type = cp->data[i++];
1615 padv[padv_len].data = &cp->data[i];
1616 i += padv[padv_len].data_len;
1617 }
1618
1619 err = tester_gap_padv_set_data(padv, padv_len);
1620
1621 return BTP_STATUS_VAL(err);
1622 }
1623
1624 int tester_gap_padv_create_sync(struct bt_le_per_adv_sync_param *create_params)
1625 {
1626 int err;
1627
1628 if (pa_sync != NULL) {
1629 return -EBUSY;
1630 }
1631
1632 err = bt_le_per_adv_sync_create(create_params, &pa_sync);
1633
1634 if (err != 0) {
1635 LOG_DBG("Unable to sync to PA: %d", err);
1636 }
1637
1638 return err;
1639 }
1640
1641 int tester_gap_padv_stop_sync(void)
1642 {
1643 int err;
1644
1645 if (pa_sync == NULL) {
1646 return -EALREADY;
1647 }
1648
1649 err = bt_le_per_adv_sync_delete(pa_sync);
1650 if (err != 0) {
1651 LOG_DBG("Unable to stop sync to PA: %d", err);
1652 }
1653
1654 return err;
1655 }
1656
1657 static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len,
1658 void *rsp, uint16_t *rsp_len)
1659 {
1660 int err;
1661 const struct btp_gap_padv_create_sync_cmd *cp = cmd;
1662 struct bt_le_per_adv_sync_param create_params = {0};
1663
1664 bt_addr_le_copy(&create_params.addr, &cp->address);
1665 create_params.options = BT_LE_PER_ADV_SYNC_OPT_NONE;
1666 create_params.sid = cp->advertiser_sid;
1667 create_params.skip = sys_le16_to_cpu(cp->skip);
1668 create_params.timeout = sys_le16_to_cpu(cp->sync_timeout);
1669
1670 if (cp->flags & BTP_GAP_PADV_CREATE_SYNC_FLAG_REPORTS_DISABLED) {
1671 create_params.options |= BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED;
1672 }
1673
1674 if (cp->flags & BTP_GAP_PADV_CREATE_SYNC_FLAG_FILTER_DUPLICATES) {
1675 create_params.options |= BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
1676 }
1677
1678 err = tester_gap_padv_create_sync(&create_params);
1679
1680 return BTP_STATUS_VAL(err);
1681 }
1682
1683 static uint8_t padv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len,
1684 void *rsp, uint16_t *rsp_len)
1685 {
1686 const struct btp_gap_padv_sync_transfer_set_info_cmd *cp = cmd;
1687 (void)cp;
1688
1689 /* TODO */
1690
1691 return BTP_STATUS_FAILED;
1692 }
1693
1694 static uint8_t padv_sync_transfer_start(const void *cmd, uint16_t cmd_len,
1695 void *rsp, uint16_t *rsp_len)
1696 {
1697 const struct btp_gap_padv_sync_transfer_start_cmd *cp = cmd;
1698 (void)cp;
1699
1700 /* TODO */
1701
1702 return BTP_STATUS_FAILED;
1703 }
1704
1705 static uint8_t padv_sync_transfer_recv(const void *cmd, uint16_t cmd_len,
1706 void *rsp, uint16_t *rsp_len)
1707 {
1708 const struct btp_gap_padv_sync_transfer_recv_cmd *cp = cmd;
1709 (void)cp;
1710
1711 /* TODO */
1712
1713 return BTP_STATUS_FAILED;
1714 }
1715 #endif /* defined(CONFIG_BT_PER_ADV) */
1716
1717 static const struct btp_handler handlers[] = {
1718 {
1719 .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS,
1720 .index = BTP_INDEX_NONE,
1721 .expect_len = 0,
1722 .func = supported_commands,
1723 },
1724 {
1725 .opcode = BTP_GAP_READ_CONTROLLER_INDEX_LIST,
1726 .index = BTP_INDEX_NONE,
1727 .expect_len = 0,
1728 .func = controller_index_list,
1729 },
1730 {
1731 .opcode = BTP_GAP_READ_CONTROLLER_INFO,
1732 .expect_len = 0,
1733 .func = controller_info,
1734 },
1735 {
1736 .opcode = BTP_GAP_SET_POWERED,
1737 .expect_len = sizeof(struct btp_gap_set_powered_cmd),
1738 .func = set_powered,
1739 },
1740 {
1741 .opcode = BTP_GAP_SET_CONNECTABLE,
1742 .expect_len = sizeof(struct btp_gap_set_connectable_cmd),
1743 .func = set_connectable,
1744 },
1745 {
1746 .opcode = BTP_GAP_SET_DISCOVERABLE,
1747 .expect_len = sizeof(struct btp_gap_set_discoverable_cmd),
1748 .func = set_discoverable,
1749 },
1750 {
1751 .opcode = BTP_GAP_SET_BONDABLE,
1752 .expect_len = sizeof(struct btp_gap_set_bondable_cmd),
1753 .func = set_bondable,
1754 },
1755 {
1756 .opcode = BTP_GAP_START_ADVERTISING,
1757 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
1758 .func = start_advertising,
1759 },
1760 {
1761 .opcode = BTP_GAP_START_DIRECTED_ADV,
1762 .expect_len = sizeof(struct btp_gap_start_directed_adv_cmd),
1763 .func = start_directed_advertising,
1764 },
1765 {
1766 .opcode = BTP_GAP_STOP_ADVERTISING,
1767 .expect_len = 0,
1768 .func = stop_advertising,
1769 },
1770 {
1771 .opcode = BTP_GAP_START_DISCOVERY,
1772 .expect_len = sizeof(struct btp_gap_start_discovery_cmd),
1773 .func = start_discovery,
1774 },
1775 {
1776 .opcode = BTP_GAP_STOP_DISCOVERY,
1777 .expect_len = 0,
1778 .func = stop_discovery,
1779 },
1780 {
1781 .opcode = BTP_GAP_CONNECT,
1782 .expect_len = sizeof(struct btp_gap_connect_cmd),
1783 .func = connect,
1784 },
1785 {
1786 .opcode = BTP_GAP_DISCONNECT,
1787 .expect_len = sizeof(struct btp_gap_disconnect_cmd),
1788 .func = disconnect,
1789 },
1790 {
1791 .opcode = BTP_GAP_SET_IO_CAP,
1792 .expect_len = sizeof(struct btp_gap_set_io_cap_cmd),
1793 .func = set_io_cap,
1794 },
1795 {
1796 .opcode = BTP_GAP_PAIR,
1797 .expect_len = sizeof(struct btp_gap_pair_cmd),
1798 .func = pair,
1799 },
1800 {
1801 .opcode = BTP_GAP_UNPAIR,
1802 .expect_len = sizeof(struct btp_gap_unpair_cmd),
1803 .func = unpair,
1804 },
1805 {
1806 .opcode = BTP_GAP_PASSKEY_ENTRY,
1807 .expect_len = sizeof(struct btp_gap_passkey_entry_cmd),
1808 .func = passkey_entry,
1809 },
1810 {
1811 .opcode = BTP_GAP_PASSKEY_CONFIRM,
1812 .expect_len = sizeof(struct btp_gap_passkey_confirm_cmd),
1813 .func = passkey_confirm,
1814 },
1815 {
1816 .opcode = BTP_GAP_CONN_PARAM_UPDATE,
1817 .expect_len = sizeof(struct btp_gap_conn_param_update_cmd),
1818 .func = conn_param_update,
1819 },
1820 {
1821 .opcode = BTP_GAP_SET_MITM,
1822 .expect_len = sizeof(struct btp_gap_set_mitm),
1823 .func = set_mitm,
1824 },
1825 {
1826 .opcode = BTP_GAP_OOB_LEGACY_SET_DATA,
1827 .expect_len = sizeof(struct btp_gap_oob_legacy_set_data_cmd),
1828 .func = set_oob_legacy_data,
1829 },
1830 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
1831 {
1832 .opcode = BTP_GAP_OOB_SC_GET_LOCAL_DATA,
1833 .expect_len = 0,
1834 .func = get_oob_sc_local_data,
1835 },
1836 {
1837 .opcode = BTP_GAP_OOB_SC_SET_REMOTE_DATA,
1838 .expect_len = sizeof(struct btp_gap_oob_sc_set_remote_data_cmd),
1839 .func = set_oob_sc_remote_data,
1840 },
1841 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
1842 {
1843 .opcode = BTP_GAP_SET_FILTER_LIST,
1844 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
1845 .func = set_filter_list,
1846 },
1847 #if defined(CONFIG_BT_EXT_ADV)
1848 {
1849 .opcode = BTP_GAP_SET_EXTENDED_ADVERTISING,
1850 .expect_len = sizeof(struct btp_gap_set_extended_advertising_cmd),
1851 .func = set_extended_advertising,
1852 },
1853 #if defined(CONFIG_BT_PER_ADV)
1854 {
1855 .opcode = BTP_GAP_PADV_CONFIGURE,
1856 .expect_len = sizeof(struct btp_gap_padv_configure_cmd),
1857 .func = padv_configure,
1858 },
1859 {
1860 .opcode = BTP_GAP_PADV_START,
1861 .expect_len = sizeof(struct btp_gap_padv_start_cmd),
1862 .func = padv_start,
1863 },
1864 {
1865 .opcode = BTP_GAP_PADV_STOP,
1866 .expect_len = sizeof(struct btp_gap_padv_stop_cmd),
1867 .func = padv_stop,
1868 },
1869 {
1870 .opcode = BTP_GAP_PADV_SET_DATA,
1871 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
1872 .func = padv_set_data,
1873 },
1874 {
1875 .opcode = BTP_GAP_PADV_CREATE_SYNC,
1876 .expect_len = sizeof(struct btp_gap_padv_create_sync_cmd),
1877 .func = padv_create_sync,
1878 },
1879 {
1880 .opcode = BTP_GAP_PADV_SYNC_TRANSFER_SET_INFO,
1881 .expect_len = sizeof(struct btp_gap_padv_sync_transfer_set_info_cmd),
1882 .func = padv_sync_transfer_set_info,
1883 },
1884 {
1885 .opcode = BTP_GAP_PADV_SYNC_TRANSFER_START,
1886 .expect_len = sizeof(struct btp_gap_padv_sync_transfer_start_cmd),
1887 .func = padv_sync_transfer_start,
1888 },
1889 {
1890 .opcode = BTP_GAP_PADV_SYNC_TRANSFER_RECV,
1891 .expect_len = sizeof(struct btp_gap_padv_sync_transfer_recv_cmd),
1892 .func = padv_sync_transfer_recv,
1893 },
1894 #endif /* defined(CONFIG_BT_PER_ADV) */
1895 #endif /* defined(CONFIG_BT_EXT_ADV) */
1896 };
1897
1898 uint8_t tester_init_gap(void)
1899 {
1900 int err;
1901
1902 (void)memset(&cb, 0, sizeof(cb));
1903 bt_conn_auth_cb_register(NULL);
1904 cb.pairing_accept = auth_pairing_accept;
1905 if (bt_conn_auth_cb_register(&cb)) {
1906 return BTP_STATUS_FAILED;
1907 }
1908
1909 err = bt_enable(NULL);
1910 if (err < 0) {
1911 LOG_ERR("Unable to enable Bluetooth: %d", err);
1912 return BTP_STATUS_FAILED;
1913 }
1914
1915 atomic_clear(¤t_settings);
1916 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_POWERED);
1917 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE);
1918 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_BONDABLE);
1919 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_LE);
1920 #if defined(CONFIG_BT_PRIVACY)
1921 atomic_set_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY);
1922 #endif /* CONFIG_BT_PRIVACY */
1923
1924 bt_conn_cb_register(&conn_callbacks);
1925 bt_conn_auth_info_cb_register(&auth_info_cb);
1926
1927 #if defined(CONFIG_BT_PER_ADV)
1928 bt_le_per_adv_sync_cb_register(&pa_sync_cb);
1929 #endif /* defined(CONFIG_BT_PER_ADV) */
1930
1931 tester_register_command_handlers(BTP_SERVICE_ID_GAP, handlers,
1932 ARRAY_SIZE(handlers));
1933
1934 return BTP_STATUS_SUCCESS;
1935 }
1936
1937 uint8_t tester_unregister_gap(void)
1938 {
1939 return BTP_STATUS_SUCCESS;
1940 }
1941