apps/btshell: Add option to restart advertising after disconnect

This patch takes into account both legacy and extended advertising. When using
legacy advertising (BLE_EXT_ADV: 0) all advertising parameters are remembered
to use when restarting. When using extended advertising the parameters
per instance are remembered by the host. For ext adv the app remembers
the handle of the connection that issued Advertising Complete Event.
Later, at a Disconnect Event, the code checks if we should restart advertising
for an instance related to that connection.
This commit is contained in:
Michał Narajowski
2018-10-18 19:03:25 +02:00
parent cecad355ad
commit 6fd09c31ef
3 changed files with 144 additions and 6 deletions
+5 -1
View File
@@ -120,10 +120,14 @@ int btshell_write_reliable(uint16_t conn_handle,
int btshell_ext_adv_configure(uint8_t instance,
const struct ble_gap_ext_adv_params *params,
int8_t *selected_tx_power);
int btshell_ext_adv_start(uint8_t instance, int duration,
int max_events, bool restart);
int btshell_ext_adv_stop(uint8_t instance);
#endif
int btshell_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
int32_t duration_ms,
const struct ble_gap_adv_params *params);
const struct ble_gap_adv_params *params,
bool restart);
int btshell_adv_stop(void);
int btshell_conn_initiate(uint8_t own_addr_type, const ble_addr_t *peer_addr,
int32_t duration_ms,
+19 -3
View File
@@ -338,6 +338,7 @@ cmd_advertise_start(int argc, char **argv)
int max_events;
uint8_t instance;
int duration;
bool restart;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
@@ -368,7 +369,13 @@ cmd_advertise_start(int argc, char **argv)
return rc;
}
rc = ble_gap_ext_adv_start(instance, duration, max_events);
restart = parse_arg_bool_dflt("restart", 0, &rc);
if (rc != 0) {
console_printf("invalid 'restart' parameter\n");
return rc;
}
rc = btshell_ext_adv_start(instance, duration, max_events, restart);
if (rc) {
console_printf("failed to start advertising instance\n");
return rc;
@@ -399,7 +406,7 @@ cmd_advertise_stop(int argc, char **argv)
return rc;
}
rc = ble_gap_ext_adv_stop(instance);
rc = btshell_ext_adv_stop(instance);
if (rc) {
console_printf("failed to stop advertising instance\n");
return rc;
@@ -488,6 +495,7 @@ static const struct shell_param advertise_start_params[] = {
{"instance", "default: 0"},
{"duration", "advertising duration in 10ms units, default: 0 (forever)"},
{"max_events", "max number of advertising events, default: 0 (no limit)"},
{"restart", "restart advertising after disconnect, usage: =[0-1], default: 0"},
{NULL, NULL}
};
@@ -543,6 +551,7 @@ cmd_advertise(int argc, char **argv)
ble_addr_t peer_addr;
ble_addr_t *peer_addr_param = &peer_addr;
uint8_t own_addr_type;
bool restart;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
@@ -589,6 +598,12 @@ cmd_advertise(int argc, char **argv)
return rc;
}
restart = parse_arg_bool_dflt("restart", 0, &rc);
if (rc != 0) {
console_printf("invalid 'restart' parameter\n");
return rc;
}
own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
BLE_OWN_ADDR_PUBLIC, &rc);
if (rc != 0) {
@@ -635,7 +650,7 @@ cmd_advertise(int argc, char **argv)
}
rc = btshell_adv_start(own_addr_type, peer_addr_param, duration_ms,
&params);
&params, restart);
if (rc != 0) {
console_printf("advertise fail: %d\n", rc);
return rc;
@@ -658,6 +673,7 @@ static const struct shell_param advertise_params[] = {
{"interval_max", "usage: =[0-UINT16_MAX], default: 0"},
{"high_duty", "usage: =[0-1], default: 0"},
{"duration", "usage: =[1-INT32_MAX], default: INT32_MAX"},
{"restart", "restart advertising after disconnect, usage: =[0-1], default: 0"},
{NULL, NULL}
};
+120 -2
View File
@@ -129,6 +129,21 @@ int btshell_full_disc_prev_chr_val;
#define BTSHELL_AUTO_DEVICE_NAME ""
#endif
#if MYNEWT_VAL(BLE_EXT_ADV)
struct {
bool restart;
uint16_t conn_handle;
} ext_adv_restart[BLE_ADV_INSTANCES];
#endif
static struct {
bool restart;
uint8_t own_addr_type;
ble_addr_t direct_addr;
int32_t duration_ms;
struct ble_gap_adv_params params;
} adv_params;
static void
btshell_print_error(char *msg, uint16_t conn_handle,
const struct ble_gatt_error *error)
@@ -985,6 +1000,43 @@ common_data:
}
#endif
static int
btshell_gap_event(struct ble_gap_event *event, void *arg);
static int
btshell_restart_adv(struct ble_gap_event *event)
{
int rc = 0;
#if MYNEWT_VAL(BLE_EXT_ADV)
uint8_t i;
#endif
if (event->type != BLE_GAP_EVENT_DISCONNECT) {
return -1;
}
#if MYNEWT_VAL(BLE_EXT_ADV)
for (i = 0; i < BLE_ADV_INSTANCES; ++i) {
if (ext_adv_restart[i].restart &&
(ext_adv_restart[i].conn_handle ==
event->disconnect.conn.conn_handle)) {
rc = ble_gap_ext_adv_start(i, 0, 0);
break;
}
}
#else
if (!adv_params.restart) {
return 0;
}
rc = ble_gap_adv_start(adv_params.own_addr_type, &adv_params.direct_addr,
adv_params.duration_ms, &adv_params.params,
btshell_gap_event, NULL);
#endif
return rc;
}
static int
btshell_gap_event(struct ble_gap_event *event, void *arg)
{
@@ -1014,7 +1066,8 @@ btshell_gap_event(struct ble_gap_event *event, void *arg)
if (conn_idx != -1) {
btshell_conn_delete_idx(conn_idx);
}
return 0;
return btshell_restart_adv(event);
#if MYNEWT_VAL(BLE_EXT_ADV)
case BLE_GAP_EVENT_EXT_DISC:
btshell_decode_event_type(&event->ext_disc, arg);
@@ -1074,6 +1127,9 @@ btshell_gap_event(struct ble_gap_event *event, void *arg)
console_printf("advertise complete; reason=%d, instance=%u, handle=%d\n",
event->adv_complete.reason, event->adv_complete.instance,
event->adv_complete.conn_handle);
ext_adv_restart[event->adv_complete.instance].conn_handle =
event->adv_complete.conn_handle;
#else
console_printf("advertise complete; reason=%d\n",
event->adv_complete.reason);
@@ -1439,6 +1495,36 @@ btshell_ext_adv_configure(uint8_t instance,
return ble_gap_ext_adv_configure(instance, params, selected_tx_power,
btshell_gap_event, NULL);
}
int
btshell_ext_adv_start(uint8_t instance, int duration,
int max_events, bool restart)
{
int rc;
/* Advertising restart doesn't make sense
* with limited duration or events
*/
if (restart && (duration == 0) && (max_events == 0)) {
ext_adv_restart[instance].restart = restart;
}
rc = ble_gap_ext_adv_start(instance, duration, max_events);
return rc;
}
int
btshell_ext_adv_stop(uint8_t instance)
{
int rc;
ext_adv_restart[instance].restart = false;
rc = ble_gap_ext_adv_stop(instance);
return rc;
}
#endif
int
@@ -1446,16 +1532,33 @@ btshell_adv_stop(void)
{
int rc;
adv_params.restart = false;
rc = ble_gap_adv_stop();
return rc;
}
int
btshell_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
int32_t duration_ms, const struct ble_gap_adv_params *params)
int32_t duration_ms, const struct ble_gap_adv_params *params,
bool restart)
{
int rc;
if (restart) {
adv_params.restart = restart;
adv_params.own_addr_type = own_addr_type;
adv_params.duration_ms = duration_ms;
if (direct_addr) {
memcpy(&adv_params.direct_addr, direct_addr, sizeof(adv_params.direct_addr));
}
if (params) {
memcpy(&adv_params.params, params, sizeof(adv_params.params));
}
}
rc = ble_gap_adv_start(own_addr_type, direct_addr, duration_ms, params,
btshell_gap_event, NULL);
return rc;
@@ -2042,6 +2145,19 @@ btshell_l2cap_send(uint16_t conn_handle, uint16_t idx, uint16_t bytes)
#endif
}
static void
btshell_init_ext_adv_restart(void)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
int i;
for (i = 0; i < BLE_ADV_INSTANCES; ++i) {
ext_adv_restart[i].conn_handle = BLE_HS_CONN_HANDLE_NONE;
}
#endif
}
/**
* main
*
@@ -2116,6 +2232,8 @@ main(int argc, char **argv)
os_callout_init(&btshell_tx_timer, os_eventq_dflt_get(),
btshell_tx_timer_cb, NULL);
btshell_init_ext_adv_restart();
while (1) {
os_eventq_run(os_eventq_dflt_get());
}