| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395 |
- /* gap.c - Bluetooth GAP Tester */
- /*
- * Copyright (c) 2015-2016 Intel Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <base/atomic.h>
- #include <base/types.h>
- #include <string.h>
- #include <errno.h>
- #include <stddef.h>
- #include <string.h>
- #include <base/common.h>
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/conn.h>
- #include <bluetooth/gatt.h>
- #include <bluetooth/hci.h>
- #include <base/byteorder.h>
- #include <common/net_buf.h>
- #include "host/hci_core.h"
- #define LOG_MODULE_NAME bttester_gap
- #include <logging/bt_log.h>
- #include "btp/btp.h"
- #define CONTROLLER_INDEX 0
- #define CONTROLLER_NAME "btp_tester"
- #define BT_LE_AD_DISCOV_MASK (BT_LE_AD_LIMITED | BT_LE_AD_GENERAL)
- #define ADV_BUF_LEN (sizeof(struct gap_device_found_ev) + 2 * 31)
- static atomic_t current_settings;
- struct bt_conn_auth_cb cb;
- static uint8_t oob_legacy_tk[16] = { 0 };
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- static struct bt_le_oob oob_sc_local = { 0 };
- static struct bt_le_oob oob_sc_remote = { 0 };
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- /* connection parameters for rejection test */
- #define REJECT_INTERVAL_MIN 0x0C80
- #define REJECT_INTERVAL_MAX 0x0C80
- #define REJECT_LATENCY 0x0000
- #define REJECT_SUPERVISION_TIMEOUT 0x0C80
- #if defined(CONFIG_BT_PRIVACY)
- static struct {
- bt_addr_le_t addr;
- bool supported;
- } cars[CONFIG_BT_MAX_PAIRED];
- static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err,
- struct bt_gatt_read_params *params, const void *data,
- uint16_t length);
- static struct bt_gatt_read_params read_car_params = {
- .func = read_car_cb,
- .by_uuid.uuid = BT_UUID_CENTRAL_ADDR_RES,
- .by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE,
- .by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE,
- };
- static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err,
- struct bt_gatt_read_params *params, const void *data,
- uint16_t length)
- {
- struct bt_conn_info info;
- bool supported = false;
- if (!err && data && length == 1) {
- const uint8_t *tmp = data;
- /* only 0 or 1 are valid values */
- if (tmp[0] == 1) {
- supported = true;
- }
- }
- bt_conn_get_info(conn, &info);
- for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) {
- if (bt_addr_le_eq(info.le.dst, &cars[i].addr)) {
- cars[i].supported = supported;
- break;
- }
- }
- return BT_GATT_ITER_STOP;
- }
- #endif
- static void le_connected(struct bt_conn *conn, uint8_t err)
- {
- struct gap_device_connected_ev ev;
- struct bt_conn_info info;
- if (err) {
- return;
- }
- bt_conn_get_info(conn, &info);
- memcpy(ev.address, info.le.dst->a.val, sizeof(ev.address));
- ev.address_type = info.le.dst->type;
- ev.interval = sys_cpu_to_le16(info.le.interval);
- ev.latency = sys_cpu_to_le16(info.le.latency);
- ev.timeout = sys_cpu_to_le16(info.le.timeout);
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void le_disconnected(struct bt_conn *conn, uint8_t reason)
- {
- struct gap_device_disconnected_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void le_identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa,
- const bt_addr_le_t *identity)
- {
- struct gap_identity_resolved_ev ev;
- ev.address_type = rpa->type;
- memcpy(ev.address, rpa->a.val, sizeof(ev.address));
- ev.identity_address_type = identity->type;
- memcpy(ev.identity_address, identity->a.val,
- sizeof(ev.identity_address));
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void le_param_updated(struct bt_conn *conn, uint16_t interval,
- uint16_t latency, uint16_t timeout)
- {
- struct gap_conn_param_update_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- ev.interval = sys_cpu_to_le16(interval);
- ev.latency = sys_cpu_to_le16(latency);
- ev.timeout = sys_cpu_to_le16(timeout);
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
- {
- /* reject update if all parameters match reject pattern */
- if ((param->interval_min == REJECT_INTERVAL_MIN) &&
- (param->interval_max == REJECT_INTERVAL_MAX) &&
- (param->latency == REJECT_LATENCY) &&
- (param->timeout == REJECT_SUPERVISION_TIMEOUT)) {
- return false;
- }
- return true;
- }
- static void le_security_changed(struct bt_conn *conn, bt_security_t level,
- enum bt_security_err err)
- {
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- struct gap_sec_level_changed_ev sec_ev;
- struct gap_bond_lost_ev bond_ev;
- struct bt_conn_info info;
- switch (err) {
- case BT_SECURITY_ERR_SUCCESS:
- memcpy(sec_ev.address, addr->a.val, sizeof(sec_ev.address));
- sec_ev.address_type = addr->type;
- /* enum matches BTP values */
- sec_ev.sec_level = level;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED,
- CONTROLLER_INDEX, (uint8_t *) &sec_ev, sizeof(sec_ev));
- break;
- case BT_SECURITY_ERR_PIN_OR_KEY_MISSING:
- /* for central role this means that peer have no LTK when we
- * started encryption procedure
- *
- * This means bond is lost and we restart pairing to re-bond
- */
- if (bt_conn_get_info(conn, &info) == 0 &&
- info.role == BT_CONN_ROLE_CENTRAL) {
- BT_DBG("Bond lost");
- (void)memcpy(bond_ev.address, addr->a.val, sizeof(bond_ev.address));
- bond_ev.address_type = addr->type;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_BOND_LOST,
- CONTROLLER_INDEX, (uint8_t *)&bond_ev, sizeof(bond_ev));
- (void)bt_conn_set_security(conn, BT_SECURITY_L2 | BT_SECURITY_FORCE_PAIR);
- }
- break;
- default:
- break;
- }
- }
- static struct bt_conn_cb conn_callbacks = {
- .connected = le_connected,
- .disconnected = le_disconnected,
- .identity_resolved = le_identity_resolved,
- .le_param_updated = le_param_updated,
- .le_param_req = le_param_req,
- .security_changed = le_security_changed,
- };
- static void supported_commands(uint8_t *data, uint16_t len)
- {
- uint8_t cmds[4];
- struct gap_read_supported_commands_rp *rp = (void *) &cmds;
- (void)memset(cmds, 0, sizeof(cmds));
- tester_set_bit(cmds, GAP_READ_SUPPORTED_COMMANDS);
- tester_set_bit(cmds, GAP_READ_CONTROLLER_INDEX_LIST);
- tester_set_bit(cmds, GAP_READ_CONTROLLER_INFO);
- tester_set_bit(cmds, GAP_SET_CONNECTABLE);
- tester_set_bit(cmds, GAP_SET_DISCOVERABLE);
- tester_set_bit(cmds, GAP_SET_BONDABLE);
- tester_set_bit(cmds, GAP_START_ADVERTISING);
- tester_set_bit(cmds, GAP_START_DIRECTED_ADV);
- tester_set_bit(cmds, GAP_STOP_ADVERTISING);
- tester_set_bit(cmds, GAP_START_DISCOVERY);
- tester_set_bit(cmds, GAP_STOP_DISCOVERY);
- tester_set_bit(cmds, GAP_CONNECT);
- tester_set_bit(cmds, GAP_DISCONNECT);
- tester_set_bit(cmds, GAP_SET_IO_CAP);
- tester_set_bit(cmds, GAP_PAIR);
- tester_set_bit(cmds, GAP_PASSKEY_ENTRY);
- tester_set_bit(cmds, GAP_PASSKEY_CONFIRM);
- tester_set_bit(cmds, GAP_CONN_PARAM_UPDATE);
- tester_set_bit(cmds, GAP_SET_MITM);
- tester_set_bit(cmds, GAP_OOB_LEGACY_SET_DATA);
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- tester_set_bit(cmds, GAP_OOB_SC_GET_LOCAL_DATA);
- tester_set_bit(cmds, GAP_OOB_SC_SET_REMOTE_DATA);
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- tester_set_bit(cmds, GAP_SET_FILTER_LIST);
- tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS,
- CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds));
- }
- static void controller_index_list(uint8_t *data, uint16_t len)
- {
- struct gap_read_controller_index_list_rp *rp;
- uint8_t buf[sizeof(*rp) + 1];
- rp = (void *) buf;
- rp->num = 1U;
- rp->index[0] = CONTROLLER_INDEX;
- tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST,
- BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
- }
- static void controller_info(uint8_t *data, uint16_t len)
- {
- struct gap_read_controller_info_rp rp;
- uint32_t supported_settings;
- (void)memset(&rp, 0, sizeof(rp));
- struct bt_le_oob oob_local = { 0 };
- bt_le_oob_get_local(BT_ID_DEFAULT, &oob_local);
- memcpy(rp.address, &oob_local.addr.a, sizeof(bt_addr_t));
- /*
- * Re-use the oob data read here in get_oob_sc_local_data()
- */
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- oob_sc_local = oob_local;
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- /*
- * If privacy is used, the device uses random type address, otherwise
- * static random or public type address is used.
- */
- #if !defined(CONFIG_BT_PRIVACY)
- if (oob_local.addr.type == BT_ADDR_LE_RANDOM) {
- atomic_set_bit(¤t_settings, GAP_SETTINGS_STATIC_ADDRESS);
- }
- #endif /* CONFIG_BT_PRIVACY */
- supported_settings = BIT(GAP_SETTINGS_POWERED);
- supported_settings |= BIT(GAP_SETTINGS_CONNECTABLE);
- supported_settings |= BIT(GAP_SETTINGS_BONDABLE);
- supported_settings |= BIT(GAP_SETTINGS_LE);
- supported_settings |= BIT(GAP_SETTINGS_ADVERTISING);
- rp.supported_settings = sys_cpu_to_le32(supported_settings);
- rp.current_settings = sys_cpu_to_le32(current_settings);
- memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME));
- tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO,
- CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp));
- }
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- static const char *oob_config_str(int oob_config)
- {
- switch (oob_config) {
- case BT_CONN_OOB_LOCAL_ONLY:
- return "Local";
- case BT_CONN_OOB_REMOTE_ONLY:
- return "Remote";
- case BT_CONN_OOB_BOTH_PEERS:
- return "Local and Remote";
- case BT_CONN_OOB_NO_DATA:
- default:
- return "no";
- }
- }
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- static void oob_data_request(struct bt_conn *conn,
- struct bt_conn_oob_info *oob_info)
- {
- struct bt_conn_info info;
- int err = bt_conn_get_info(conn, &info);
- if (err) {
- return;
- }
- char addr[BT_ADDR_LE_STR_LEN];
- bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
- switch (oob_info->type) {
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- case BT_CONN_OOB_LE_SC:
- {
- BT_DBG("Set %s OOB SC data for %s, ",
- oob_config_str(oob_info->lesc.oob_config),
- addr);
- struct bt_le_oob_sc_data *oobd_local =
- oob_info->lesc.oob_config != BT_CONN_OOB_REMOTE_ONLY ?
- &oob_sc_local.le_sc_data :
- NULL;
- struct bt_le_oob_sc_data *oobd_remote =
- oob_info->lesc.oob_config != BT_CONN_OOB_LOCAL_ONLY ?
- &oob_sc_remote.le_sc_data :
- NULL;
- if (oobd_remote) {
- /* Assume that oob_sc_remote
- * corresponds to the currently connected peer
- */
- bt_addr_le_copy(&oob_sc_remote.addr, info.le.remote);
- }
- if (oobd_local &&
- !bt_addr_le_eq(info.le.local, &oob_sc_local.addr)) {
- bt_addr_le_to_str(info.le.local, addr, sizeof(addr));
- BT_DBG("No OOB data available for local %s",
- addr);
- bt_conn_auth_cancel(conn);
- return;
- }
- err = bt_le_oob_set_sc_data(conn, oobd_local, oobd_remote);
- if (err) {
- BT_DBG("bt_le_oob_set_sc_data failed with: %d", err);
- }
- break;
- }
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
- case BT_CONN_OOB_LE_LEGACY:
- BT_DBG("Legacy OOB TK requested from remote %s", addr);
- err = bt_le_oob_set_legacy_tk(conn, oob_legacy_tk);
- if (err < 0) {
- BT_ERR("Failed to set OOB TK: %d", err);
- }
- break;
- #endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
- default:
- BT_ERR("Unhandled OOB type %d", oob_info->type);
- break;
- }
- }
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- static void get_oob_sc_local_data(void)
- {
- cb.oob_data_request = oob_data_request;
- struct gap_oob_sc_get_local_data_rp rp = { 0 };
- memcpy(&rp.conf[0], &oob_sc_local.le_sc_data.c[0], sizeof(rp.conf));
- memcpy(&rp.rand[0], &oob_sc_local.le_sc_data.r[0], sizeof(rp.rand));
- tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA,
- CONTROLLER_INDEX, (uint8_t *)&rp, sizeof(rp));
- }
- static void set_oob_sc_remote_data(const uint8_t *data, uint16_t len)
- {
- cb.oob_data_request = oob_data_request;
- bt_set_oob_data_flag(true);
- const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *)data;
- /* Note that the .addr field
- * will be set by the oob_data_request callback
- */
- memcpy(&oob_sc_remote.le_sc_data.r[0], &cmd->rand[0],
- sizeof(oob_sc_remote.le_sc_data.r));
- memcpy(&oob_sc_remote.le_sc_data.c[0], &cmd->conf[0],
- sizeof(oob_sc_remote.le_sc_data.c));
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_SC_SET_REMOTE_DATA,
- CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
- }
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- static void set_connectable(uint8_t *data, uint16_t len)
- {
- const struct gap_set_connectable_cmd *cmd = (void *) data;
- struct gap_set_connectable_rp rp;
- if (cmd->connectable) {
- atomic_set_bit(¤t_settings, GAP_SETTINGS_CONNECTABLE);
- } else {
- atomic_clear_bit(¤t_settings, GAP_SETTINGS_CONNECTABLE);
- }
- rp.current_settings = sys_cpu_to_le32(current_settings);
- tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX,
- (uint8_t *) &rp, sizeof(rp));
- }
- static uint8_t ad_flags = BT_LE_AD_NO_BREDR;
- static struct bt_data ad[10] = {
- BT_DATA(BT_DATA_FLAGS, &ad_flags, sizeof(ad_flags)),
- };
- static struct bt_data sd[10];
- static void set_discoverable(uint8_t *data, uint16_t len)
- {
- const struct gap_set_discoverable_cmd *cmd = (void *) data;
- struct gap_set_discoverable_rp rp;
- switch (cmd->discoverable) {
- case GAP_NON_DISCOVERABLE:
- ad_flags &= ~(BT_LE_AD_GENERAL | BT_LE_AD_LIMITED);
- atomic_clear_bit(¤t_settings, GAP_SETTINGS_DISCOVERABLE);
- break;
- case GAP_GENERAL_DISCOVERABLE:
- ad_flags &= ~BT_LE_AD_LIMITED;
- ad_flags |= BT_LE_AD_GENERAL;
- atomic_set_bit(¤t_settings, GAP_SETTINGS_DISCOVERABLE);
- break;
- case GAP_LIMITED_DISCOVERABLE:
- ad_flags &= ~BT_LE_AD_GENERAL;
- ad_flags |= BT_LE_AD_LIMITED;
- atomic_set_bit(¤t_settings, GAP_SETTINGS_DISCOVERABLE);
- break;
- default:
- BT_WARN("unknown mode: 0x%x", cmd->discoverable);
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE,
- CONTROLLER_INDEX, BTP_STATUS_FAILED);
- return;
- }
- rp.current_settings = sys_cpu_to_le32(current_settings);
- tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX,
- (uint8_t *) &rp, sizeof(rp));
- }
- static void set_bondable(uint8_t *data, uint16_t len)
- {
- const struct gap_set_bondable_cmd *cmd = (void *) data;
- struct gap_set_bondable_rp rp;
- BT_DBG("cmd->bondable: %d", cmd->bondable);
- if (cmd->bondable) {
- atomic_set_bit(¤t_settings, GAP_SETTINGS_BONDABLE);
- } else {
- atomic_clear_bit(¤t_settings, GAP_SETTINGS_BONDABLE);
- }
- bt_set_bondable(cmd->bondable);
- rp.current_settings = sys_cpu_to_le32(current_settings);
- tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX,
- (uint8_t *) &rp, sizeof(rp));
- }
- static void start_advertising(const uint8_t *data, uint16_t len)
- {
- const struct gap_start_advertising_cmd *cmd = (void *) data;
- struct gap_start_advertising_rp rp;
- uint8_t adv_len, sd_len;
- bool adv_conn;
- int i;
- BT_ERR("start_advertising 1");
- for (i = 0, adv_len = 1U; i < cmd->adv_data_len; adv_len++) {
- if (adv_len >= ARRAY_SIZE(ad)) {
- BT_ERR("ad[] Out of memory");
- goto fail;
- }
- ad[adv_len].type = cmd->adv_sr_data[i++];
- ad[adv_len].data_len = cmd->adv_sr_data[i++];
- ad[adv_len].data = &cmd->adv_sr_data[i];
- i += ad[adv_len].data_len;
- }
- BT_ERR("start_advertising 2");
- for (sd_len = 0U; i < cmd->adv_data_len+cmd->scan_rsp_len; sd_len++) {
- if (sd_len >= ARRAY_SIZE(sd)) {
- BT_ERR("sd[] Out of memory");
- goto fail;
- }
- sd[sd_len].type = cmd->adv_sr_data[i++];
- sd[sd_len].data_len = cmd->adv_sr_data[i++];
- sd[sd_len].data = &cmd->adv_sr_data[i];
- i += sd[sd_len].data_len;
- }
- BT_ERR("start_advertising 3");
- adv_conn = atomic_test_bit(¤t_settings, GAP_SETTINGS_CONNECTABLE);
- BT_ERR("start_advertising 4");
- /* BTP API don't allow to set empty scan response data. */
- if (bt_le_adv_start(adv_conn ? BT_LE_ADV_CONN : BT_LE_ADV_NCONN,
- ad, adv_len, sd_len ? sd : NULL, sd_len) < 0) {
- BT_ERR("Failed to start advertising");
- goto fail;
- }
- BT_ERR("start_advertising 5");
- atomic_set_bit(¤t_settings, GAP_SETTINGS_ADVERTISING);
- rp.current_settings = sys_cpu_to_le32(current_settings);
- BT_ERR("start_advertising 6");
- tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
- (uint8_t *) &rp, sizeof(rp));
- return;
- fail:
- BT_ERR("start_advertising 7");
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
- }
- static void start_directed_advertising(const uint8_t *data, uint16_t len)
- {
- const struct gap_start_directed_adv_cmd *cmd = (void *)data;
- struct gap_start_directed_adv_rp rp;
- struct bt_le_adv_param adv_param;
- uint16_t options = sys_le16_to_cpu(cmd->options);
- const bt_addr_le_t *peer = (bt_addr_le_t *)data;
- adv_param = *BT_LE_ADV_CONN_DIR(peer);
- if (!(options & GAP_START_DIRECTED_ADV_HD)) {
- adv_param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY;
- adv_param.interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
- adv_param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
- }
- if (options & GAP_START_DIRECTED_ADV_PEER_RPA) {
- #if defined(CONFIG_BT_PRIVACY)
- /* check if peer supports Central Address Resolution */
- for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) {
- if (bt_addr_le_eq(peer, &cars[i].addr)) {
- if (cars[i].supported) {
- adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA;
- }
- }
- }
- #endif
- }
- if (bt_le_adv_start(&adv_param, NULL, 0, NULL, 0) < 0) {
- BT_ERR("Failed to start advertising");
- goto fail;
- }
- atomic_set_bit(¤t_settings, GAP_SETTINGS_ADVERTISING);
- rp.current_settings = sys_cpu_to_le32(current_settings);
- tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECTED_ADV,
- CONTROLLER_INDEX, (uint8_t *)&rp, sizeof(rp));
- return;
- fail:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECTED_ADV, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
- }
- static void stop_advertising(const uint8_t *data, uint16_t len)
- {
- struct gap_stop_advertising_rp rp;
- int err;
- err = bt_le_adv_stop();
- if (err < 0) {
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING,
- CONTROLLER_INDEX, BTP_STATUS_FAILED);
- BT_ERR("Failed to stop advertising: %d", err);
- return;
- }
- atomic_clear_bit(¤t_settings, GAP_SETTINGS_ADVERTISING);
- rp.current_settings = sys_cpu_to_le32(current_settings);
- tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX,
- (uint8_t *) &rp, sizeof(rp));
- }
- static uint8_t get_ad_flags(struct net_buf_simple *ad)
- {
- uint8_t len, i;
- /* Parse advertisement to get flags */
- for (i = 0U; i < ad->len; i += len - 1) {
- len = ad->data[i++];
- if (!len) {
- break;
- }
- /* Check if field length is correct */
- if (len > (ad->len - i) || (ad->len - i) < 1) {
- break;
- }
- switch (ad->data[i++]) {
- case BT_DATA_FLAGS:
- return ad->data[i];
- default:
- break;
- }
- }
- return 0;
- }
- static uint8_t discovery_flags;
- static struct net_buf_simple *adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN);
- static void store_adv(const bt_addr_le_t *addr, int8_t rssi,
- struct net_buf_simple *ad)
- {
- struct gap_device_found_ev *ev;
- /* cleanup */
- net_buf_simple_init(adv_buf, 0);
- ev = net_buf_simple_add(adv_buf, sizeof(*ev));
- memcpy(ev->address, addr->a.val, sizeof(ev->address));
- ev->address_type = addr->type;
- ev->rssi = rssi;
- ev->flags = GAP_DEVICE_FOUND_FLAG_AD | GAP_DEVICE_FOUND_FLAG_RSSI;
- ev->eir_data_len = ad->len;
- memcpy(net_buf_simple_add(adv_buf, ad->len), ad->data, ad->len);
- }
- static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t evtype,
- struct net_buf_simple *ad)
- {
- /* if General/Limited Discovery - parse Advertising data to get flags */
- if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) &&
- (evtype != BT_GAP_ADV_TYPE_SCAN_RSP)) {
- uint8_t flags = get_ad_flags(ad);
- /* ignore non-discoverable devices */
- if (!(flags & BT_LE_AD_DISCOV_MASK)) {
- BT_DBG("Non discoverable, skipping");
- return;
- }
- /* if Limited Discovery - ignore general discoverable devices */
- if ((discovery_flags & GAP_DISCOVERY_FLAG_LIMITED) &&
- !(flags & BT_LE_AD_LIMITED)) {
- BT_DBG("General discoverable, skipping");
- return;
- }
- }
- /* attach Scan Response data */
- if (evtype == BT_GAP_ADV_TYPE_SCAN_RSP) {
- struct gap_device_found_ev *ev;
- bt_addr_le_t a;
- /* skip if there is no pending advertisement */
- if (!adv_buf->len) {
- BT_INFO("No pending advertisement, skipping");
- return;
- }
- ev = (void *) adv_buf->data;
- a.type = ev->address_type;
- memcpy(a.a.val, ev->address, sizeof(a.a.val));
- /*
- * in general, the Scan Response comes right after the
- * Advertisement, but if not if send stored event and ignore
- * this one
- */
- if (!bt_addr_le_eq(addr, &a)) {
- BT_INFO("Address does not match, skipping");
- goto done;
- }
- ev->eir_data_len += ad->len;
- ev->flags |= GAP_DEVICE_FOUND_FLAG_SD;
- memcpy(net_buf_simple_add(adv_buf, ad->len), ad->data, ad->len);
- goto done;
- }
- /*
- * if there is another pending advertisement, send it and store the
- * current one
- */
- if (adv_buf->len) {
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND,
- CONTROLLER_INDEX, adv_buf->data, adv_buf->len);
- net_buf_simple_reset(adv_buf);
- }
- store_adv(addr, rssi, ad);
- /* if Active Scan and scannable event - wait for Scan Response */
- if ((discovery_flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) &&
- (evtype == BT_GAP_ADV_TYPE_ADV_IND ||
- evtype == BT_GAP_ADV_TYPE_ADV_SCAN_IND)) {
- BT_DBG("Waiting for scan response");
- return;
- }
- done:
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND,
- CONTROLLER_INDEX, adv_buf->data, adv_buf->len);
- net_buf_simple_reset(adv_buf);
- }
- static void start_discovery(const uint8_t *data, uint16_t len)
- {
- const struct gap_start_discovery_cmd *cmd = (void *) data;
- uint8_t status;
- /* only LE scan is supported */
- if (cmd->flags & GAP_DISCOVERY_FLAG_BREDR) {
- status = BTP_STATUS_FAILED;
- BT_WARN("BR/EDR not supported");
- goto reply;
- }
- if (bt_le_scan_start(cmd->flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN ?
- BT_LE_SCAN_ACTIVE : BT_LE_SCAN_PASSIVE,
- device_found) < 0) {
- status = BTP_STATUS_FAILED;
- BT_ERR("Failed to start scanning");
- goto reply;
- }
- net_buf_simple_init(adv_buf, 0);
- discovery_flags = cmd->flags;
- status = BTP_STATUS_SUCCESS;
- reply:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DISCOVERY, CONTROLLER_INDEX,
- status);
- }
- static void stop_discovery(const uint8_t *data, uint16_t len)
- {
- uint8_t status = BTP_STATUS_SUCCESS;
- int err;
- err = bt_le_scan_stop();
- if (err < 0) {
- BT_ERR("Failed to stop scanning: %d", err);
- status = BTP_STATUS_FAILED;
- }
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_DISCOVERY, CONTROLLER_INDEX,
- status);
- }
- static void connect(const uint8_t *data, uint16_t len)
- {
- const bt_addr_le_t *addr = (const bt_addr_le_t *)data;
- uint8_t status;
- int err;
- if (!bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
- struct bt_conn *conn;
- err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
- BT_LE_CONN_PARAM_DEFAULT, &conn);
- if (err) {
- BT_ERR("Failed to create connection (%d)", err);
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- bt_conn_unref(conn);
- } else {
- err = bt_conn_le_create_auto(BT_CONN_LE_CREATE_CONN,
- BT_LE_CONN_PARAM_DEFAULT);
- if (err) {
- BT_ERR("Failed to create auto connection (%d)", err);
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- }
- status = BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status);
- }
- static void disconnect(const uint8_t *data, uint16_t len)
- {
- struct bt_conn *conn;
- uint8_t status;
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
- if (!conn) {
- status = BTP_STATUS_FAILED;
- BT_ERR("Unknown connection");
- goto rsp;
- }
- if (bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN)) {
- BT_ERR("Failed to disconnect");
- status = BTP_STATUS_FAILED;
- } else {
- status = BTP_STATUS_SUCCESS;
- }
- bt_conn_unref(conn);
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_DISCONNECT, CONTROLLER_INDEX,
- status);
- }
- static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
- {
- struct gap_passkey_display_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- ev.passkey = sys_cpu_to_le32(passkey);
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void auth_passkey_entry(struct bt_conn *conn)
- {
- struct gap_passkey_entry_req_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
- {
- struct gap_passkey_confirm_req_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- ev.passkey = sys_cpu_to_le32(passkey);
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ,
- CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
- }
- static void auth_cancel(struct bt_conn *conn)
- {
- /* TODO */
- }
- enum bt_security_err auth_pairing_accept(struct bt_conn *conn,
- const struct bt_conn_pairing_feat *const feat)
- {
- struct gap_bond_lost_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- if (!bt_addr_le_is_bonded(BT_ID_DEFAULT, addr)) {
- return BT_SECURITY_ERR_SUCCESS;
- }
- /* If a peer is already bonded and tries to pair again then it means that
- * the it has lost its bond information.
- */
- BT_DBG("Bond lost");
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_BOND_LOST, CONTROLLER_INDEX, (uint8_t *)&ev,
- sizeof(ev));
- return BT_SECURITY_ERR_SUCCESS;
- }
- void auth_pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
- {
- struct gap_bond_pairing_failed_ev ev;
- const bt_addr_le_t *addr = bt_conn_get_dst(conn);
- memcpy(ev.address, addr->a.val, sizeof(ev.address));
- ev.address_type = addr->type;
- ev.reason = reason;
- tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PAIRING_FAILED, CONTROLLER_INDEX,
- (uint8_t *)&ev, sizeof(ev));
- }
- static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
- {
- #if defined(CONFIG_BT_PRIVACY)
- /* Read peer's Central Address Resolution if bonded */
- if (bonded) {
- bt_gatt_read(conn, &read_car_params);
- }
- #endif
- }
- static struct bt_conn_auth_info_cb auth_info_cb = {
- .pairing_failed = auth_pairing_failed,
- .pairing_complete = auth_pairing_complete,
- };
- static void set_io_cap(const uint8_t *data, uint16_t len)
- {
- const struct gap_set_io_cap_cmd *cmd = (void *) data;
- uint8_t status;
- /* Reset io cap requirements */
- (void)memset(&cb, 0, sizeof(cb));
- bt_conn_auth_cb_register(NULL);
- BT_DBG("io_cap: %d", cmd->io_cap);
- switch (cmd->io_cap) {
- case GAP_IO_CAP_DISPLAY_ONLY:
- cb.cancel = auth_cancel;
- cb.passkey_display = auth_passkey_display;
- break;
- case GAP_IO_CAP_KEYBOARD_DISPLAY:
- cb.cancel = auth_cancel;
- cb.passkey_display = auth_passkey_display;
- cb.passkey_entry = auth_passkey_entry;
- cb.passkey_confirm = auth_passkey_confirm;
- break;
- case GAP_IO_CAP_NO_INPUT_OUTPUT:
- cb.cancel = auth_cancel;
- break;
- case GAP_IO_CAP_KEYBOARD_ONLY:
- cb.cancel = auth_cancel;
- cb.passkey_entry = auth_passkey_entry;
- break;
- case GAP_IO_CAP_DISPLAY_YESNO:
- cb.cancel = auth_cancel;
- cb.passkey_display = auth_passkey_display;
- cb.passkey_confirm = auth_passkey_confirm;
- break;
- default:
- BT_WARN("Unhandled io_cap: 0x%x", cmd->io_cap);
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- // cb.pairing_accept = auth_pairing_accept;
- if (bt_conn_auth_cb_register(&cb)) {
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- status = BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_IO_CAP, CONTROLLER_INDEX,
- status);
- }
- static void pair(const uint8_t *data, uint16_t len)
- {
- struct bt_conn *conn;
- uint8_t status;
- int err;
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
- if (!conn) {
- BT_ERR("Unknown connection");
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- err = bt_conn_set_security(conn, BT_SECURITY_L2);
- if (err < 0) {
- BT_ERR("Failed to set security: %d", err);
- status = BTP_STATUS_FAILED;
- bt_conn_unref(conn);
- goto rsp;
- }
- bt_conn_unref(conn);
- status = BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status);
- }
- static void unpair(const uint8_t *data, uint16_t len)
- {
- struct gap_unpair_cmd *cmd = (void *) data;
- struct bt_conn *conn;
- bt_addr_le_t addr;
- uint8_t status;
- int err;
- addr.type = cmd->address_type;
- memcpy(addr.a.val, cmd->address, sizeof(addr.a.val));
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &addr);
- if (!conn) {
- BT_ERR("Unknown connection");
- goto keys;
- }
- err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
- bt_conn_unref(conn);
- if (err < 0) {
- BT_ERR("Failed to disconnect: %d", err);
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- keys:
- err = bt_unpair(BT_ID_DEFAULT, &addr);
- status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status);
- }
- static void passkey_entry(const uint8_t *data, uint16_t len)
- {
- const struct gap_passkey_entry_cmd *cmd = (void *) data;
- struct bt_conn *conn;
- uint8_t status;
- int err;
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
- if (!conn) {
- BT_ERR("Unknown connection");
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- err = bt_conn_auth_passkey_entry(conn, sys_le32_to_cpu(cmd->passkey));
- if (err < 0) {
- BT_ERR("Failed to enter passkey: %d", err);
- }
- bt_conn_unref(conn);
- status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_ENTRY, CONTROLLER_INDEX,
- status);
- }
- static void passkey_confirm(const uint8_t *data, uint16_t len)
- {
- const struct gap_passkey_confirm_cmd *cmd = (void *) data;
- struct bt_conn *conn;
- uint8_t status;
- int err;
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
- if (!conn) {
- BT_ERR("Unknown connection");
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
- if (cmd->match) {
- err = bt_conn_auth_passkey_confirm(conn);
- if (err < 0) {
- BT_ERR("Failed to confirm passkey: %d", err);
- }
- } else {
- err = bt_conn_auth_cancel(conn);
- if (err < 0) {
- BT_ERR("Failed to cancel auth: %d", err);
- }
- }
- bt_conn_unref(conn);
- status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX,
- status);
- }
- static void conn_param_update(const uint8_t *data, uint16_t len)
- {
- const struct gap_conn_param_update_cmd *cmd = (void *) data;
- struct bt_le_conn_param param = {
- .interval_min = sys_le16_to_cpu(cmd->interval_min),
- .interval_max = sys_le16_to_cpu(cmd->interval_max),
- .latency = sys_le16_to_cpu(cmd->latency),
- .timeout = sys_le16_to_cpu(cmd->timeout),
- };
- struct bt_conn *conn;
- uint8_t status = BTP_STATUS_FAILED;
- int err;
- conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
- if (!conn) {
- BT_ERR("Unknown connection");
- goto rsp;
- }
- err = bt_conn_le_param_update(conn, ¶m);
- if (err < 0) {
- BT_ERR("Failed to update params: %d", err);
- }
- bt_conn_unref(conn);
- status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
- rsp:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX,
- status);
- }
- static void set_mitm(const uint8_t *data, uint16_t len)
- {
- BT_WARN("Use CONFIG_BT_SMP_ENFORCE_MITM instead");
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_MITM, CONTROLLER_INDEX,
- BTP_STATUS_SUCCESS);
- }
- static void set_oob_legacy_data(const uint8_t *data, uint16_t len)
- {
- const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data;
- memcpy(oob_legacy_tk, cmd->oob_data, 16);
- bt_set_oob_data_flag(true);
- cb.oob_data_request = oob_data_request;
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_LEGACY_SET_DATA,
- CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
- }
- static void set_filter_list(const uint8_t *data, uint16_t len)
- {
- const struct gap_set_filter_list *cmd = (const void *) data;
- uint8_t status;
- int err;
- if (len < sizeof(*cmd) ||
- len != (sizeof(*cmd) + (cmd->cnt * sizeof(cmd->addr[0])))) {
- status = BTP_STATUS_FAILED;
- goto failed;
- }
- (void)bt_le_filter_accept_list_clear();
- for (int i = 0; i < cmd->cnt; i++) {
- err = bt_le_filter_accept_list_add(&cmd->addr[i]);
- if (err < 0) {
- status = BTP_STATUS_FAILED;
- goto failed;
- }
- }
- status = BTP_STATUS_SUCCESS;
- failed:
- tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_LIST,
- CONTROLLER_INDEX, status);
- }
- void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data,
- uint16_t len)
- {
- BT_DBG("opcode111: 0x%x", opcode);
- switch (opcode) {
- case GAP_READ_SUPPORTED_COMMANDS:
- case GAP_READ_CONTROLLER_INDEX_LIST:
- if (index != BTP_INDEX_NONE){
- tester_rsp(BTP_SERVICE_ID_GAP, opcode, index,
- BTP_STATUS_FAILED);
- BT_WARN("index != BTP_INDEX_NONE: opcode: 0x%x "
- "index: 0x%x", opcode, index);
- return;
- }
- break;
- default:
- BT_DBG("index1111: 0x%02x", index);
- if (index != CONTROLLER_INDEX){
- tester_rsp(BTP_SERVICE_ID_GAP, opcode, index,
- BTP_STATUS_FAILED);
- BT_WARN("index != CONTROLLER_INDEX: opcode: 0x%x "
- "index: 0x%x", opcode, index);
- return;
- }
- break;
- }
- BT_DBG("opcode1: 0x%02x", opcode);
- switch (opcode) {
- case GAP_READ_SUPPORTED_COMMANDS:
- supported_commands(data, len);
- return;
- case GAP_READ_CONTROLLER_INDEX_LIST:
- controller_index_list(data, len);
- return;
- case GAP_READ_CONTROLLER_INFO:
- controller_info(data, len);
- return;
- case GAP_SET_CONNECTABLE:
- set_connectable(data, len);
- return;
- case GAP_SET_DISCOVERABLE:
- set_discoverable(data, len);
- return;
- case GAP_SET_BONDABLE:
- set_bondable(data, len);
- return;
- case GAP_START_ADVERTISING:
- start_advertising(data, len);
- return;
- case GAP_START_DIRECTED_ADV:
- start_directed_advertising(data, len);
- return;
- case GAP_STOP_ADVERTISING:
- stop_advertising(data, len);
- return;
- case GAP_START_DISCOVERY:
- start_discovery(data, len);
- return;
- case GAP_STOP_DISCOVERY:
- stop_discovery(data, len);
- return;
- case GAP_CONNECT:
- connect(data, len);
- return;
- case GAP_DISCONNECT:
- disconnect(data, len);
- return;
- case GAP_SET_IO_CAP:
- set_io_cap(data, len);
- return;
- case GAP_PAIR:
- pair(data, len);
- return;
- case GAP_UNPAIR:
- unpair(data, len);
- return;
- case GAP_PASSKEY_ENTRY:
- passkey_entry(data, len);
- return;
- case GAP_PASSKEY_CONFIRM:
- passkey_confirm(data, len);
- return;
- case GAP_CONN_PARAM_UPDATE:
- conn_param_update(data, len);
- return;
- case GAP_SET_MITM:
- set_mitm(data, len);
- return;
- case GAP_OOB_LEGACY_SET_DATA:
- set_oob_legacy_data(data, len);
- return;
- #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
- case GAP_OOB_SC_GET_LOCAL_DATA:
- get_oob_sc_local_data();
- return;
- case GAP_OOB_SC_SET_REMOTE_DATA:
- set_oob_sc_remote_data(data, len);
- return;
- #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
- case GAP_SET_FILTER_LIST:
- set_filter_list(data, len);
- return;
- default:
- BT_WARN("Unknown opcode: 0x%x", opcode);
- tester_rsp(BTP_SERVICE_ID_GAP, opcode, index,
- BTP_STATUS_UNKNOWN_CMD);
- return;
- }
- }
- static void tester_init_gap_cb(int err)
- {
- if (err) {
- tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE,
- BTP_INDEX_NONE, BTP_STATUS_FAILED);
- BT_WARN("Error: %d", err);
- return;
- }
- atomic_clear(¤t_settings);
- atomic_set_bit(¤t_settings, GAP_SETTINGS_POWERED);
- atomic_set_bit(¤t_settings, GAP_SETTINGS_CONNECTABLE);
- atomic_set_bit(¤t_settings, GAP_SETTINGS_BONDABLE);
- atomic_set_bit(¤t_settings, GAP_SETTINGS_LE);
- #if defined(CONFIG_BT_PRIVACY)
- atomic_set_bit(¤t_settings, GAP_SETTINGS_PRIVACY);
- #endif /* CONFIG_BT_PRIVACY */
- bt_conn_cb_register(&conn_callbacks);
- tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE,
- BTP_STATUS_SUCCESS);
- }
- uint8_t tester_init_gap(void)
- {
- int err;
- // (void)memset(&cb, 0, sizeof(cb));
- // bt_conn_auth_cb_register(NULL);
- // // cb.pairing_accept = auth_pairing_accept;
- // if (bt_conn_auth_cb_register(&cb)) {
- // return BTP_STATUS_FAILED;
- // }
- // bt_conn_auth_info_cb_register(&auth_info_cb);
- // err = bt_enable(tester_init_gap_cb);
- // if (err < 0) {
- // BT_ERR("Unable to enable Bluetooth: %d", err);
- // return BTP_STATUS_FAILED;
- // }
- tester_init_gap_cb(0);
- return BTP_STATUS_SUCCESS;
- }
- uint8_t tester_unregister_gap(void)
- {
- return BTP_STATUS_SUCCESS;
- }
|