tests: Bluetooth: Tester: Add support for PAST
This adds support for BTP commands and events required for running PAST tests. struct btp_gap_ev_periodic_transfer_received_ev is also adjusted to match BTP specification. Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
This commit is contained in:
parent
821e9f3c6a
commit
256401ed2b
@ -40,6 +40,8 @@ CONFIG_BT_GATT_DYNAMIC_DB=y
|
||||
CONFIG_BT_EXT_ADV=y
|
||||
CONFIG_BT_PER_ADV=y
|
||||
CONFIG_BT_PER_ADV_SYNC=y
|
||||
CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y
|
||||
CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y
|
||||
CONFIG_BT_RX_STACK_SIZE=4096
|
||||
|
||||
CONFIG_BT_TESTING=y
|
||||
|
||||
@ -313,6 +313,8 @@ struct btp_gap_padv_sync_transfer_start_cmd {
|
||||
uint16_t service_data;
|
||||
} __packed;
|
||||
|
||||
#define BTP_GAP_PADV_SYNC_TRANSFER_RECV_FLAG_REPORTS_DISABLED 0x01
|
||||
|
||||
#define BTP_GAP_PADV_SYNC_TRANSFER_RECV 0x29
|
||||
struct btp_gap_padv_sync_transfer_recv_cmd {
|
||||
bt_addr_le_t address;
|
||||
@ -464,13 +466,10 @@ struct btp_gap_ev_periodic_report_ev {
|
||||
|
||||
#define BTP_GAP_EV_PERIODIC_TRANSFER_RECEIVED 0x90
|
||||
struct btp_gap_ev_periodic_transfer_received_ev {
|
||||
bt_addr_le_t adv_address;
|
||||
uint16_t sync_handle;
|
||||
uint8_t tx_power;
|
||||
uint8_t rssi;
|
||||
uint8_t cte_type;
|
||||
uint8_t data_status;
|
||||
uint8_t data_len;
|
||||
uint8_t data[];
|
||||
uint8_t status;
|
||||
bt_addr_le_t peer_address;
|
||||
} __packed;
|
||||
|
||||
#define BTP_GAP_EV_ENCRYPTION_CHANGE 0x91
|
||||
|
||||
@ -1873,6 +1873,30 @@ static void pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
|
||||
{
|
||||
LOG_DBG("");
|
||||
|
||||
/* sync transfer received */
|
||||
if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) && info->conn != NULL) {
|
||||
struct btp_gap_ev_periodic_transfer_received_ev ev;
|
||||
struct bt_conn_info conn_info;
|
||||
|
||||
if (pa_sync != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pa_sync = sync;
|
||||
|
||||
bt_conn_get_info(info->conn, &conn_info);
|
||||
|
||||
bt_addr_le_copy(&ev.adv_address, &sync->addr);
|
||||
ev.sync_handle = sys_cpu_to_le16(sync->handle);
|
||||
ev.status = 0;
|
||||
bt_addr_le_copy(&ev.peer_address, conn_info.le.dst);
|
||||
|
||||
tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_TRANSFER_RECEIVED,
|
||||
&ev, sizeof(ev));
|
||||
return;
|
||||
}
|
||||
|
||||
/* locally initiated */
|
||||
if (sync == pa_sync) {
|
||||
struct btp_gap_ev_periodic_sync_established_ev ev;
|
||||
|
||||
@ -1904,9 +1928,43 @@ static void pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
|
||||
}
|
||||
}
|
||||
|
||||
static struct net_buf_simple *periodic_adv_buf =
|
||||
NET_BUF_SIMPLE(sizeof(struct btp_gap_ev_periodic_report_ev) + UINT8_MAX);
|
||||
|
||||
static void pa_sync_recv_cb(struct bt_le_per_adv_sync *sync,
|
||||
const struct bt_le_per_adv_sync_recv_info *info,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
struct btp_gap_ev_periodic_report_ev *ev;
|
||||
|
||||
LOG_DBG("");
|
||||
|
||||
/* cleanup */
|
||||
net_buf_simple_init(periodic_adv_buf, 0);
|
||||
|
||||
ev = net_buf_simple_add(periodic_adv_buf, sizeof(*ev));
|
||||
|
||||
ev->sync_handle = sys_cpu_to_le16(sync->handle);
|
||||
ev->rssi = info->rssi;
|
||||
ev->cte_type = info->cte_type;
|
||||
|
||||
/* TODO BTP has fragmented data (as in HCI) */
|
||||
if (buf->len > UINT8_MAX) {
|
||||
ev->data_len = UINT8_MAX;
|
||||
} else {
|
||||
ev->data_len = buf->len;
|
||||
}
|
||||
|
||||
memcpy(net_buf_simple_add(periodic_adv_buf, ev->data_len), buf->data, ev->data_len);
|
||||
|
||||
tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_REPORT,
|
||||
ev, sizeof(*ev) + ev->data_len);
|
||||
}
|
||||
|
||||
static struct bt_le_per_adv_sync_cb pa_sync_cb = {
|
||||
.synced = pa_sync_synced_cb,
|
||||
.term = pa_sync_terminated_cb,
|
||||
.recv = pa_sync_recv_cb,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BT_PER_ADV)
|
||||
@ -2164,6 +2222,114 @@ static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len,
|
||||
|
||||
return BTP_STATUS_VAL(err);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
|
||||
static uint8_t padv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len,
|
||||
void *rsp, uint16_t *rsp_len)
|
||||
{
|
||||
const struct btp_gap_padv_sync_transfer_set_info_cmd *cp = cmd;
|
||||
struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0);
|
||||
struct bt_conn *conn;
|
||||
int err;
|
||||
|
||||
if (ext_adv == NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
if (cp->address.type == BTP_BR_ADDRESS_TYPE) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
|
||||
if (conn == NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
err = bt_le_per_adv_set_info_transfer(ext_adv, conn,
|
||||
sys_le16_to_cpu(cp->service_data));
|
||||
|
||||
bt_conn_unref(conn);
|
||||
|
||||
if (err < 0) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
return BTP_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t padv_padv_sync_transfer_start(const void *cmd, uint16_t cmd_len,
|
||||
void *rsp, uint16_t *rsp_len)
|
||||
{
|
||||
const struct btp_gap_padv_sync_transfer_start_cmd *cp = cmd;
|
||||
struct bt_conn *conn;
|
||||
int err;
|
||||
|
||||
if (pa_sync == NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
if (cp->address.type == BTP_BR_ADDRESS_TYPE) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
|
||||
if (conn == NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
err = bt_le_per_adv_sync_transfer(pa_sync, conn,
|
||||
sys_le16_to_cpu(cp->service_data));
|
||||
|
||||
bt_conn_unref(conn);
|
||||
|
||||
if (err < 0) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
return BTP_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) */
|
||||
|
||||
#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
|
||||
static uint8_t padv_padv_sync_transfer_recv(const void *cmd, uint16_t cmd_len,
|
||||
void *rsp, uint16_t *rsp_len)
|
||||
{
|
||||
const struct btp_gap_padv_sync_transfer_recv_cmd *cp = cmd;
|
||||
struct bt_le_per_adv_sync_transfer_param param = {0};
|
||||
struct bt_conn *conn;
|
||||
int err;
|
||||
|
||||
if (pa_sync != NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
if (cp->address.type == BTP_BR_ADDRESS_TYPE) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
|
||||
if (conn == NULL) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
param.skip = sys_le16_to_cpu(cp->skip);
|
||||
param.timeout = sys_le16_to_cpu(cp->sync_timeout);
|
||||
|
||||
if ((cp->flags & BTP_GAP_PADV_SYNC_TRANSFER_RECV_FLAG_REPORTS_DISABLED) != 0) {
|
||||
param.options |= BT_LE_PER_ADV_SYNC_TRANSFER_OPT_REPORTING_INITIALLY_DISABLED;
|
||||
}
|
||||
|
||||
err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m);
|
||||
|
||||
bt_conn_unref(conn);
|
||||
|
||||
if (err < 0) {
|
||||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
return BTP_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) */
|
||||
#endif /* defined(CONFIG_BT_PER_ADV) */
|
||||
|
||||
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
|
||||
@ -2350,6 +2516,25 @@ static const struct btp_handler handlers[] = {
|
||||
.expect_len = sizeof(struct btp_gap_padv_create_sync_cmd),
|
||||
.func = padv_create_sync,
|
||||
},
|
||||
#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
|
||||
{
|
||||
.opcode = BTP_GAP_PADV_SYNC_TRANSFER_SET_INFO,
|
||||
.expect_len = sizeof(struct btp_gap_padv_sync_transfer_set_info_cmd),
|
||||
.func = padv_sync_transfer_set_info,
|
||||
},
|
||||
{
|
||||
.opcode = BTP_GAP_PADV_SYNC_TRANSFER_START,
|
||||
.expect_len = sizeof(struct btp_gap_padv_sync_transfer_start_cmd),
|
||||
.func = padv_padv_sync_transfer_start,
|
||||
},
|
||||
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) */
|
||||
#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
|
||||
{
|
||||
.opcode = BTP_GAP_PADV_SYNC_TRANSFER_RECV,
|
||||
.expect_len = sizeof(struct btp_gap_padv_sync_transfer_recv_cmd),
|
||||
.func = padv_padv_sync_transfer_recv,
|
||||
},
|
||||
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) */
|
||||
#endif /* defined(CONFIG_BT_PER_ADV) */
|
||||
#endif /* defined(CONFIG_BT_EXT_ADV) */
|
||||
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user