Skip to content

Commit

Permalink
Add locking to GAP and GATTC
Browse files Browse the repository at this point in the history
  • Loading branch information
rojer committed Dec 3, 2021
1 parent a4711b0 commit b3dc905
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 33 deletions.
3 changes: 3 additions & 0 deletions include/esp32/esp32_bt_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ int esp32_bt_gatts_event(const struct ble_gap_event *event, void *arg);

extern uint8_t own_addr_type;

void esp32_bt_rlock(void);
void esp32_bt_runlock(void);

#ifdef __cplusplus
}
#endif
11 changes: 11 additions & 0 deletions src/esp32/esp32_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static bool s_inited = false;
static bool s_should_be_running = false;
static TaskHandle_t s_host_task_handle;
static SemaphoreHandle_t s_sem = NULL;
static struct mgos_rlock_type *s_lock = NULL;

enum esp32_bt_state {
ESP32_BT_STOPPED = 0,
Expand Down Expand Up @@ -239,13 +240,23 @@ static void esp32_bt_host_task(void *param) {
}
}

void esp32_bt_rlock(void) {
mgos_rlock(s_lock);
}

void esp32_bt_runlock(void) {
mgos_runlock(s_lock);
}

extern void ble_store_config_init(void);

static bool esp32_bt_init(void) {
if (s_inited) {
return true;
}

s_lock = mgos_rlock_create();

bool ret = false;

if (mgos_sys_config_get_bt_dev_name() != NULL) {
Expand Down
24 changes: 17 additions & 7 deletions src/esp32/esp32_bt_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ bool mgos_bt_gap_scan(const struct mgos_bt_gap_scan_opts *opts) {
}

static int esp32_bt_gap_event(struct ble_gap_event *ev, void *arg) {
int ret = 0;
LOG(LL_DEBUG, ("GAP Event %d", ev->type));
esp32_bt_rlock();
switch (ev->type) {
// Forward GATTS events to the GATTS handler.
case BLE_GAP_EVENT_CONNECT:
Expand All @@ -187,7 +189,7 @@ static int esp32_bt_gap_event(struct ble_gap_event *ev, void *arg) {
case BLE_GAP_EVENT_SUBSCRIBE:
case BLE_GAP_EVENT_NOTIFY_TX:
case BLE_GAP_EVENT_MTU:
esp32_bt_gatts_event(ev, arg);
ret = esp32_bt_gatts_event(ev, arg);
break;
case BLE_GAP_EVENT_ADV_COMPLETE:
s_advertising = false;
Expand All @@ -206,10 +208,11 @@ static int esp32_bt_gap_event(struct ble_gap_event *ev, void *arg) {
}
// Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
// continue with the pairing operation.
return BLE_GAP_REPEAT_PAIRING_RETRY;
ret = BLE_GAP_REPEAT_PAIRING_RETRY;
}
}
return 0;
esp32_bt_runlock();
return ret;
}

bool esp32_bt_gap_start_advertising(void) {
Expand Down Expand Up @@ -303,9 +306,13 @@ bool esp32_bt_gap_start_advertising(void) {
}

static bool esp32_bt_gap_stop_advertising(void) {
if (!s_advertising) return true;
bool res = (ble_gap_adv_stop() == 0);
esp32_bt_rlock();
bool res = !s_advertising;
if (res) goto out;
res = (ble_gap_adv_stop() == 0);
if (res) s_advertising = false;
out:
esp32_bt_runlock();
return res;
}

Expand All @@ -330,7 +337,10 @@ bool mgos_bt_gap_set_scan_rsp_data(struct mg_str scan_rsp_data) {
}

bool mgos_bt_gap_set_adv_enable(bool adv_enable) {
esp32_bt_rlock();
s_adv_enable = adv_enable;
return (s_adv_enable ? esp32_bt_gap_start_advertising()
: esp32_bt_gap_stop_advertising());
bool res = (s_adv_enable ? esp32_bt_gap_start_advertising()
: esp32_bt_gap_stop_advertising());
esp32_bt_rlock();
return res;
}
50 changes: 40 additions & 10 deletions src/esp32/esp32_bt_gattc.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,24 @@ static void esp32_bt_gattc_finish_discovery(struct esp32_bt_gattc_conn *conn,

static int esp32_bt_gattc_event(struct ble_gap_event *ev, void *arg) {
char buf1[MGOS_BT_UUID_STR_LEN];
esp32_bt_rlock();
struct esp32_bt_gattc_conn *conn = validate_conn(arg);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
if (conn == NULL) {
esp32_bt_runlock();
return BLE_ATT_ERR_UNLIKELY;
}
LOG(LL_DEBUG, ("GATTC EV %d", ev->type));
switch (ev->type) {
case BLE_GAP_EVENT_CONNECT: {
uint16_t conn_id = ev->connect.conn_handle;
conn->gc.conn_id = conn_id;
struct ble_gap_conn_desc cd;
ble_gap_conn_find(conn_id, &cd);
LOG(LL_INFO, ("CONNECT %s ch %d st %d",
int8_t conn_rssi = 0;
ble_gap_conn_rssi(conn_id, &conn_rssi);
LOG(LL_INFO, ("CONNECT %s ch %d st %d rssi %d",
esp32_bt_addr_to_str(&cd.peer_ota_addr, buf1), conn_id,
ev->connect.status));
ev->connect.status, -conn_rssi));
ble_gattc_exchange_mtu(conn_id, esp32_bt_gattc_mtu_event, conn);
break;
}
Expand All @@ -179,6 +185,7 @@ static int esp32_bt_gattc_event(struct ble_gap_event *ev, void *arg) {
break;
}
}
esp32_bt_runlock();
return 0;
}

Expand Down Expand Up @@ -262,8 +269,12 @@ static int esp32_bt_gattc_disc_dsc_ev(uint16_t conn_id,
void *arg) {
int ret = 0;
char buf[MGOS_BT_UUID_STR_LEN];
esp32_bt_rlock();
struct esp32_bt_gattc_conn *conn = validate_conn(arg);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
if (conn == NULL) {
esp32_bt_runlock();
return BLE_ATT_ERR_UNLIKELY;
}
switch (err->status) {
case 0:
LOG(LL_DEBUG, ("DISC_DSC ch %d uuid %s h %d", conn_id,
Expand All @@ -282,6 +293,7 @@ static int esp32_bt_gattc_disc_dsc_ev(uint16_t conn_id,
esp32_bt_gattc_finish_discovery(conn, false /* ok */);
}
}
esp32_bt_runlock();
return ret;
}

Expand All @@ -291,8 +303,12 @@ static int esp32_bt_gattc_disc_chr_ev(uint16_t conn_id,
void *arg) {
int ret = 0;
char buf[MGOS_BT_UUID_STR_LEN];
esp32_bt_rlock();
struct esp32_bt_gattc_conn *conn = validate_conn(arg);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
if (conn == NULL) {
esp32_bt_runlock();
return BLE_ATT_ERR_UNLIKELY;
}
switch (err->status) {
case 0:
LOG(LL_DEBUG, ("DISC_CHR ch %d uuid %s dh %d vh %d", conn_id,
Expand All @@ -316,6 +332,7 @@ static int esp32_bt_gattc_disc_chr_ev(uint16_t conn_id,
esp32_bt_gattc_finish_discovery(conn, false /* ok */);
}
}
esp32_bt_runlock();
return ret;
}

Expand All @@ -325,8 +342,12 @@ static int esp32_bt_gattc_disc_svc_ev(uint16_t conn_id,
void *arg) {
int ret = 0;
char buf[MGOS_BT_UUID_STR_LEN];
esp32_bt_rlock();
struct esp32_bt_gattc_conn *conn = validate_conn(arg);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
if (conn == NULL) {
esp32_bt_runlock();
return BLE_ATT_ERR_UNLIKELY;
}
switch (err->status) {
case 0:
LOG(LL_DEBUG, ("DISC_SVC ch %d uuid %s sh %d eh %d", conn_id,
Expand Down Expand Up @@ -354,6 +375,7 @@ static int esp32_bt_gattc_disc_svc_ev(uint16_t conn_id,
esp32_bt_gattc_finish_discovery(conn, false /* ok */);
}
}
esp32_bt_runlock();
return ret;
}

Expand All @@ -364,19 +386,27 @@ static void esp32_bt_gattc_invoke_fd(void *arg) {
}

bool mgos_bt_gattc_discover(uint16_t conn_id) {
int ret = false;
esp32_bt_rlock();
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
if (conn == NULL) return false;
if (!conn->connected || conn->disc_in_progress) return false;
if (conn == NULL) goto out;
if (!conn->connected || conn->disc_in_progress) goto out;
if (conn->disc_done) {
conn->disc_in_progress = true;
mgos_invoke_cb(esp32_bt_gattc_invoke_fd, conn, false /* from_isr */);
return true;
ret = true;
goto out;
}
conn->disc_in_progress = true;
if (ble_gattc_disc_all_svcs(conn_id, esp32_bt_gattc_disc_svc_ev, conn) != 0) {
conn->disc_in_progress = false;
ret = false;
} else {
ret = true;
}
return true;
out:
esp32_bt_runlock();
return ret;
}

bool mgos_bt_gattc_disconnect(uint16_t conn_id) {
Expand Down
28 changes: 12 additions & 16 deletions src/esp32/esp32_bt_gatts.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ struct esp32_bt_gatts_connection_entry {
SLIST_ENTRY(esp32_bt_gatts_connection_entry) next;
};

struct mgos_rlock_type *s_lock;
static SLIST_HEAD(s_svcs, esp32_bt_gatts_service_entry) s_svcs =
SLIST_HEAD_INITIALIZER(s_svcs);
static SLIST_HEAD(s_conns, esp32_bt_gatts_connection_entry) s_conns =
Expand Down Expand Up @@ -300,24 +299,24 @@ static void esp32_bt_gatts_create_sessions(

int mgos_bt_gatts_get_num_connections(void) {
int num = 0;
mgos_rlock(s_lock);
esp32_bt_rlock();
struct esp32_bt_gatts_connection_entry *ce;
SLIST_FOREACH(ce, &s_conns, next) num++;
mgos_runlock(s_lock);
esp32_bt_runlock();
return num;
}

bool mgos_bt_gatts_is_send_queue_empty(void) {
bool res = true;
mgos_rlock(s_lock);
esp32_bt_rlock();
struct esp32_bt_gatts_connection_entry *ce;
SLIST_FOREACH(ce, &s_conns, next) {
if (!STAILQ_EMPTY(&ce->pending_inds)) {
res = false;
break;
}
}
mgos_runlock(s_lock);
esp32_bt_runlock();
return res;
}

Expand Down Expand Up @@ -358,7 +357,7 @@ int esp32_bt_gatts_event(const struct ble_gap_event *ev, void *arg) {
char buf1[MGOS_BT_UUID_STR_LEN], buf2[MGOS_BT_UUID_STR_LEN];
LOG(LL_DEBUG,
("GATTS EV %d hf %d", ev->type, (int) mgos_get_free_heap_size()));
mgos_rlock(s_lock);
esp32_bt_rlock();
switch (ev->type) {
case BLE_GAP_EVENT_CONNECT: {
uint16_t conn_id = ev->connect.conn_handle;
Expand Down Expand Up @@ -525,7 +524,7 @@ int esp32_bt_gatts_event(const struct ble_gap_event *ev, void *arg) {
break;
}
}
mgos_runlock(s_lock);
esp32_bt_runlock();
return ret;
}

Expand Down Expand Up @@ -820,9 +819,9 @@ bool mgos_bt_gatts_register_service(const char *svc_uuid,
bsvc->characteristics = se->ble_chars;
se->ble_svc_def[1].type = BLE_GATT_SVC_TYPE_END;

mgos_rlock(s_lock);
esp32_bt_rlock();
SLIST_INSERT_HEAD(&s_svcs, se, next);
mgos_runlock(s_lock);
esp32_bt_runlock();
esp32_bt_restart();
res = true;
out:
Expand Down Expand Up @@ -867,7 +866,7 @@ void mgos_bt_gatts_send_resp_data(struct mgos_bt_gatts_conn *gsc,
struct mgos_bt_gatts_read_arg *ra,
struct mg_str data) {
if (data.len == 0) return;
mgos_rlock(s_lock);
esp32_bt_rlock();
struct esp32_bt_gatts_session_entry *sse = find_session_by_gsc(gsc);
if (sse == NULL) goto out;
struct esp32_bt_gatts_pending_read *pr = NULL;
Expand All @@ -883,7 +882,7 @@ void mgos_bt_gatts_send_resp_data(struct mgos_bt_gatts_conn *gsc,
}
mbuf_append(&pr->data, data.p, data.len);
out:
mgos_runlock(s_lock);
esp32_bt_runlock();
}

void mgos_bt_gatts_notify(struct mgos_bt_gatts_conn *gsc,
Expand All @@ -897,11 +896,11 @@ void mgos_bt_gatts_notify(struct mgos_bt_gatts_conn *gsc,
pi->handle = handle;
pi->is_ind = (mode == MGOS_BT_GATT_NOTIFY_MODE_INDICATE);
pi->value = mg_strdup(data);
mgos_rlock(s_lock);
esp32_bt_rlock();
STAILQ_INSERT_TAIL(&sse->ce->pending_inds, pi, next);
sse->ce->ind_queue_len++;
esp32_bt_gatts_send_next_ind_locked(sse->ce);
mgos_runlock(s_lock);
esp32_bt_runlock();
}

void mgos_bt_gatts_notify_uuid(struct mgos_bt_gatts_conn *gsc,
Expand All @@ -927,8 +926,5 @@ bool esp32_bt_gatts_start(void) {

bool esp32_bt_gatts_init(void) {
ble_hs_cfg.gatts_register_cb = esp32_gatts_register_cb;
if (s_lock == NULL) {
s_lock = mgos_rlock_create();
}
return true;
}

0 comments on commit b3dc905

Please sign in to comment.