mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-15 02:07:21 +00:00
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:
@@ -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
@@ -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,
|
||||
¶ms);
|
||||
¶ms, 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
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user