This is an automated email from the ASF dual-hosted git repository. janc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push: new 4d01f96d apps/bttester: add support for Periodic Sync Transfer 4d01f96d is described below commit 4d01f96d7b7507d4404dfa737c99b35fb6b2b952 Author: Krzysztof Kopyściński <krzysztof.kopyscin...@codecoup.pl> AuthorDate: Mon Aug 1 12:51:54 2022 +0200 apps/bttester: add support for Periodic Sync Transfer Added BTP commands required to execute Periodic Advertising tests. Added support for using basic functionalities of Extended Advertising. --- apps/bttester/src/btp/btp_gap.h | 99 +++++++++ apps/bttester/src/btp_gap.c | 448 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 540 insertions(+), 7 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 93b62c48..65b56818 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -70,6 +70,7 @@ struct btp_gap_read_controller_index_list_rp { #define BTP_GAP_SETTINGS_PRIVACY 13 #define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 #define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 +#define BTP_GAP_SETTINGS_PERIODIC_ADVERTISING 18 #define BTP_GAP_READ_CONTROLLER_INFO 0x03 struct btp_gap_read_controller_info_rp { @@ -257,6 +258,67 @@ struct btp_gap_set_filter_accept_list_cmd { uint8_t list_len; ble_addr_t addrs[]; } __packed; + +#define GAP_PADV_CONFIGURE 0x22 +struct gap_periodic_adv_configure_cmd { + uint8_t flags; + uint16_t itvl_min; + uint16_t itvl_max; +} __packed; + +struct btp_gap_periodic_adv_configure_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_START 0x23 +struct gap_periodic_adv_start_cmd { + uint8_t flags; +} __packed; + +struct btp_gap_periodic_adv_start_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_STOP 0x24 +struct btp_gap_periodic_adv_stop_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_SET_DATA 0x25 +struct gap_periodic_adv_set_data_cmd { + uint16_t adv_data_len; + uint8_t adv_data[0]; +} __packed; + +#define GAP_PADV_CREATE_SYNC 0x26 +struct gap_periodic_adv_create_sync_cmd { + ble_addr_t addr; + uint8_t adv_sid; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_SET_INFO 0x27 +struct gap_periodic_adv_sync_transfer_set_info_cmd { + ble_addr_t addr; + uint16_t svc_data; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_START 0x28 +struct gap_periodic_adv_sync_transfer_start_cmd { + uint16_t sync_handle; + ble_addr_t addr; + uint16_t svc_data; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_RECV 0x29 +struct gap_periodic_adv_sync_transfer_recv_cmd { + ble_addr_t addr; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; /* events */ #define BTP_GAP_EV_NEW_SETTINGS 0x80 struct btp_gap_new_settings_ev { @@ -342,3 +404,40 @@ struct btp_gap_sec_pairing_failed_ev { ble_addr_t address; uint8_t reason; } __packed; + +#define GAP_EV_PERIODIC_SYNC_ESTABLISHED 0x8d +struct gap_periodic_sync_est_ev { + ble_addr_t peer_addr; + uint16_t sync_handle; + uint8_t status; +} __packed; + +#define GAP_EV_PERIODIC_SYNC_LOST 0x8e +struct gap_periodic_sync_lost_ev { + uint16_t sync_handle; + uint8_t reason; +} __packed; + +#define GAP_EV_PERIODIC_REPORT 0x8f +struct gap_periodic_report_ev { + uint16_t sync_handle; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint8_t data_status; + uint8_t data_length; + uint8_t data[247]; +} __packed; + +#define GAP_EV_PERIODIC_TRANSFER_RECEIVED 0x90 +struct gap_periodic_transfer_recieved_ev { + uint8_t status; + uint16_t sync_handle; + uint16_t conn_handle; + uint16_t service_data; + uint8_t sid; + ble_addr_t adv_addr; + uint8_t adv_phy; + uint16_t per_adv_itvl; + uint8_t adv_clk_accuracy; +} __packed; \ No newline at end of file diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 8056eaf1..5d30cbb0 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -156,8 +156,24 @@ supported_commands(const void *cmd, uint16_t cmd_len, tester_set_bit(rp->data, BTP_GAP_OOB_SC_GET_LOCAL_DATA); tester_set_bit(rp->data, BTP_GAP_OOB_SC_SET_REMOTE_DATA); tester_set_bit(rp->data, BTP_GAP_SET_MITM); + tester_set_bit(rp->data, BTP_GAP_SET_FILTER_ACCEPT_LIST); + + /* octet 4 */ +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + tester_set_bit(rp->data, GAP_PADV_CONFIGURE); + tester_set_bit(rp->data, GAP_PADV_START); + tester_set_bit(rp->data, GAP_PADV_SET_DATA); + tester_set_bit(rp->data, GAP_PADV_CREATE_SYNC); +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_SET_INFO); + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); +#endif - *rsp_len = sizeof(*rp) + 4; + *rsp_len = sizeof(*rp) + 4 + + (MYNEWT_VAL(BLE_PERIODIC_ADV) || + MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) ? 1 : 0); return BTP_STATUS_SUCCESS; } @@ -247,10 +263,20 @@ controller_info(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_EXT_ADV) +int adv_duration = 0; +static struct ble_gap_ext_adv_params adv_params = { + .primary_phy = BLE_HCI_LE_PHY_1M, + .secondary_phy = BLE_HCI_LE_PHY_1M, + .sid = 1, + .legacy_pdu = 1, +}; +#else static struct ble_gap_adv_params adv_params = { .conn_mode = BLE_GAP_CONN_MODE_NON, .disc_mode = BLE_GAP_DISC_MODE_NON, }; +#endif #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) static void rotate_nrpa_cb(struct os_event *ev) @@ -295,10 +321,20 @@ set_connectable(const void *cmd, uint16_t cmd_len, if (cp->connectable) { current_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE); +#if MYNEWT_VAL(BLE_EXT_ADV) + adv_params.connectable = 1; + adv_params.scannable = 1; +#else adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; +#endif } else { current_settings &= ~BIT(BTP_GAP_SETTINGS_CONNECTABLE); +#if MYNEWT_VAL(BLE_EXT_ADV) + adv_params.connectable = 0; + adv_params.scannable = 0; +#else adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; +#endif } rp->current_settings = htole32(current_settings); @@ -314,6 +350,7 @@ static uint8_t set_discoverable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { +#if !MYNEWT_VAL(BLE_EXT_ADV) const struct btp_gap_set_discoverable_cmd *cp = cmd; struct btp_gap_set_discoverable_rp *rp = rsp; @@ -346,6 +383,9 @@ set_discoverable(const void *cmd, uint16_t cmd_len, *rsp_len = sizeof(*rp); return BTP_STATUS_SUCCESS; +#else + return BTP_STATUS_FAILED; +#endif } static uint8_t @@ -457,11 +497,28 @@ start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - err = ble_gap_adv_set_data(buf, buf_len); - if (err != 0) { +#if MYNEWT_VAL(BLE_EXT_ADV) + struct os_mbuf *ad_buf; + + adv_params.own_addr_type = own_addr_type; + err = ble_gap_ext_adv_configure(0, &adv_params, NULL, gap_event_cb, NULL); + if (err) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", err); return BTP_STATUS_FAILED; } + ad_buf = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + + if (os_mbuf_append(ad_buf, buf, buf_len)) { + os_mbuf_free_chain(ad_buf); + return BTP_STATUS_FAILED; + } + + err = ble_gap_ext_adv_set_data(0, ad_buf); +#else + err = ble_gap_adv_set_data(buf, buf_len); +#endif + if (sd_len) { buf_len = 0; @@ -478,9 +535,13 @@ start_advertising(const void *cmd, uint16_t cmd_len, } } +#if !MYNEWT_VAL(BLE_EXT_ADV) if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); } +#else + adv_duration = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); +#endif /* In NimBLE, own_addr_type is configured in `controller_info` function. * Let's just verify restrictions for Privacy options. @@ -513,8 +574,13 @@ start_advertising(const void *cmd, uint16_t cmd_len, OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT)); } #endif + +#if MYNEWT_VAL(BLE_EXT_ADV) + err = ble_gap_ext_adv_start(0, duration_ms, 0); +#else err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); + &adv_params, gap_event_cb, NULL); +#endif if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); return BTP_STATUS_FAILED; @@ -533,14 +599,18 @@ stop_advertising(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { struct btp_gap_stop_advertising_rp *rp = rsp; - int err; SYS_LOG_DBG(""); - err = ble_gap_adv_stop(); - if (err != 0) { +#if MYNEWT_VAL(BLE_EXT_ADV) + if (ble_gap_ext_adv_stop(0) != 0) { + return BTP_STATUS_FAILED; + } +#else + if (ble_gap_adv_stop() != 0) { return BTP_STATUS_FAILED; } +#endif current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); rp->current_settings = htole32(current_settings); @@ -1139,6 +1209,71 @@ bond_lost(uint16_t conn_handle) (uint8_t *) &ev, sizeof(ev)); } +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +static void +sync_established(struct ble_gap_event *event) +{ + struct gap_periodic_sync_est_ev ev; + + ev.status = event->periodic_sync.status; + ev.sync_handle = event->periodic_sync.sync_handle; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_ESTABLISHED, + (uint8_t *) &ev, sizeof(ev)); +} + +static void +sync_lost(struct ble_gap_event *event) +{ + struct gap_periodic_sync_lost_ev ev; + + ev.reason = event->periodic_sync_lost.reason; + ev.sync_handle = event->periodic_sync_lost.sync_handle; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_LOST, + (uint8_t *) &ev, sizeof(ev)); +} + +static void +periodic_report(struct ble_gap_event *event) +{ + struct gap_periodic_report_ev ev; + + ev.sync_handle = event->periodic_report.sync_handle; + ev.tx_power = event->periodic_report.tx_power; + ev.rssi = event->periodic_report.rssi; + ev.cte_type = 0xFF; + ev.data_status = event->periodic_report.data_status; + ev.data_length = event->periodic_report.data_length; + memcpy(ev.data, event->periodic_report.data, + event->periodic_report.data_length); + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_REPORT, + (uint8_t *) &ev, sizeof(ev)); +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +static void +periodic_transfer_received(struct ble_gap_event *event) +{ + struct gap_periodic_transfer_recieved_ev ev; + + ev.status = event->periodic_transfer.status; + ev.sync_handle = event->periodic_transfer.sync_handle; + ev.conn_handle = event->periodic_transfer.conn_handle; + ev.service_data = event->periodic_transfer.service_data; + ev.sid = event->periodic_transfer.sid; + ev.adv_addr = event->periodic_transfer.adv_addr; + ev.adv_phy = event->periodic_transfer.adv_phy; + ev.per_adv_itvl = event->periodic_transfer.per_adv_itvl; + ev.adv_clk_accuracy = event->periodic_transfer.adv_clk_accuracy; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_TRANSFER_RECEIVED, + (uint8_t *) &ev, sizeof(ev)); +} +#endif + static void print_bytes(const uint8_t *bytes, int len) { @@ -1386,6 +1521,58 @@ gap_event_cb(struct ble_gap_event *event, void *arg) event->pairing_complete.status); } break; +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + case BLE_GAP_EVENT_PERIODIC_SYNC: + console_printf("Periodic Sync established: " + "sync_handle=%d, status=%d sid=%d adv_addr=", + event->periodic_sync.sync_handle, + event->periodic_sync.status, event->periodic_sync.sid); + print_addr(event->periodic_sync.adv_addr.val); + console_printf("adv_phy=%d per_adv_ival=%d adv_clk_accuracy=%d\n", + event->periodic_sync.adv_phy, + event->periodic_sync.per_adv_ival, + event->periodic_sync.adv_clk_accuracy); + sync_established(event); + break; + case BLE_GAP_EVENT_PERIODIC_REPORT: + console_printf("Periodic Sync Report: " + "sync_handle=%d, tx_power=%d rssi=%d data_status=%d" + "data_length=%d data=", + event->periodic_report.sync_handle, + event->periodic_report.tx_power, + event->periodic_report.rssi, + event->periodic_report.data_status, + event->periodic_report.data_length); + print_bytes(event->periodic_report.data, + event->periodic_report.data_length); + console_printf("\n"); + periodic_report(event); + break; + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: + console_printf("Periodic Sync lost: " + "sync_handle=%d, reason=%d\n", + event->periodic_sync_lost.sync_handle, + event->periodic_sync_lost.reason); + sync_lost(event); + break; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + case BLE_GAP_EVENT_PERIODIC_TRANSFER: + console_printf("Periodic transfer received:" + "status=%d, sync_handle=%d, conn_handle=%d, service_data=%d, sid=%d addr=", + event->periodic_transfer.status, + event->periodic_transfer.sync_handle, + event->periodic_transfer.conn_handle, + event->periodic_transfer.service_data, + event->periodic_transfer.sid); + print_addr(event->periodic_sync.adv_addr.val); + console_printf(" adv_phy=%d, per_adv_itvl=%d, adv_clk_accuracy=%d\n", + event->periodic_transfer.adv_phy, + event->periodic_transfer.per_adv_itvl, + event->periodic_transfer.adv_clk_accuracy); + periodic_transfer_received(event); + break; +#endif default: break; } @@ -1766,6 +1953,213 @@ set_filter_accept_list(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +static uint8_t +periodic_adv_configure(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct ble_gap_ext_adv_params ext_params = {0}; + struct ble_gap_periodic_adv_params params = {0}; + const struct gap_periodic_adv_configure_cmd *cp = cmd; + struct btp_gap_periodic_adv_configure_rp *rp = rsp; + + int rc; + + memset(¶ms, 0, sizeof(params)); + params.include_tx_power = cp->flags & 0x01; + params.itvl_min = cp->itvl_min; + params.itvl_max = cp->itvl_max; + + ext_params.connectable = 0; + ext_params.scannable = 0; + ext_params.legacy_pdu = 0; + ext_params.anonymous = 0; + ext_params.own_addr_type = own_addr_type; + ext_params.primary_phy = BLE_HCI_LE_PHY_1M; + ext_params.secondary_phy = BLE_HCI_LE_PHY_1M; + ext_params.sid = 1; + + rc = ble_gap_ext_adv_configure(1, &ext_params, NULL, gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_configure(1, ¶ms); + if (rc) { + SYS_LOG_ERR("Failed to configure periodic advertiser; rc=%d\n" + "params.itvl_min %d\n" + "params.itvl_max %d\n", rc, params.itvl_min, + params.itvl_max); + return BTP_STATUS_FAILED; + } + + current_settings |= BIT(BTP_GAP_SETTINGS_PERIODIC_ADVERTISING); + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + struct btp_gap_periodic_adv_start_rp *rp = rsp; + + rc = ble_gap_ext_adv_start(1, 0, 0); + if (rc) { + SYS_LOG_ERR("Failed to start extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_start(1); + if (rc) { + SYS_LOG_ERR("Failed to start periodic advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_set_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct os_mbuf *adv_data; + const struct gap_periodic_adv_set_data_cmd *cp = cmd; + int rc; + uint16_t data_len = le16toh(cp->adv_data_len); + + adv_data = os_msys_get_pkthdr(data_len, 0); + if (!adv_data) { + return BTP_STATUS_FAILED; + } + + if (os_mbuf_append(adv_data, cp->adv_data, data_len)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_set_data(1, adv_data); + if (rc) { + SYS_LOG_ERR("Failed to set periodic advertiser data; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_create_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_create_sync_cmd *cp = cmd; + struct ble_gap_periodic_sync_params params; + struct ble_gap_disc_params scan_params = {0}; + int rc; + + params.reports_disabled = BIT(0) & cp->flags; + params.skip = cp->skip; + params.sync_timeout = cp->sync_timeout; + SYS_LOG_DBG("\nreports_disabled %d\nskip %d\nsync_timeout %d\n", + params.reports_disabled, params.skip, params.sync_timeout); + + scan_params.passive = 0; + scan_params.limited = 0; + scan_params.filter_duplicates = 0; + + ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &scan_params, NULL, NULL); + rc = ble_gap_periodic_adv_sync_create(&cp->addr, cp->adv_sid, ¶ms, + gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to create sync; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +static uint8_t +periodic_adv_sync_transfer_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_start_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_sync_transfer(cp->sync_handle, desc.conn_handle, + cp->svc_data); + if (rc) { + SYS_LOG_ERR("Failed to initiate sync transfer; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_sync_transfer_recv(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_recv_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + struct ble_gap_periodic_sync_params params; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + params.reports_disabled = BIT(0) & cp->flags; + params.skip = cp->skip; + params.sync_timeout = cp->sync_timeout; + + rc = ble_gap_periodic_adv_sync_receive(desc.conn_handle, ¶ms, + gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to receive periodic sync; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_set_info_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_sync_set_info(1, desc.conn_handle, + cp->svc_data); + if (rc) { + SYS_LOG_ERR("Failed to set info; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -1889,6 +2283,46 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_accept_list, }, +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + { + .opcode = GAP_PADV_CONFIGURE, + .expect_len = sizeof(struct gap_periodic_adv_configure_cmd), + .func = periodic_adv_configure, + }, + { + .opcode = GAP_PADV_START, + .expect_len = sizeof(struct gap_periodic_adv_start_cmd), + .func = periodic_adv_start, + }, + { + .opcode = GAP_PADV_SET_DATA, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = periodic_adv_set_data, + }, + { + .opcode = GAP_PADV_CREATE_SYNC, + .expect_len = sizeof(struct gap_periodic_adv_create_sync_cmd), + .func = periodic_adv_create_sync, + }, +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + { + .opcode = GAP_PADV_SYNC_TRANSFER_SET_INFO, + .expect_len = + sizeof(struct gap_periodic_adv_sync_transfer_set_info_cmd), + .func = periodic_adv_sync_transfer_set_info, + }, + { + .opcode = GAP_PADV_SYNC_TRANSFER_START, + .expect_len = sizeof(struct gap_periodic_adv_sync_transfer_start_cmd), + .func = periodic_adv_sync_transfer_start, + }, + { + .opcode = GAP_PADV_SYNC_TRANSFER_RECV, + .expect_len = sizeof(struct gap_periodic_adv_sync_transfer_recv_cmd), + .func = periodic_adv_sync_transfer_recv, + }, +#endif }; static void