Skip to content

Commit

Permalink
GATTC notifications support
Browse files Browse the repository at this point in the history
  • Loading branch information
rojer committed Dec 6, 2021
1 parent 01988cb commit c223f66
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 36 deletions.
2 changes: 1 addition & 1 deletion include/esp32/esp32_bt_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void esp32_bt_rlock(void);
void esp32_bt_runlock(void);

struct os_mbuf;
char *esp32_bt_mbuf_to_flat(const struct os_mbuf *om, uint16_t *len);
struct mg_str esp32_bt_mbuf_to_flat(const struct os_mbuf *om);

#ifdef __cplusplus
}
Expand Down
12 changes: 11 additions & 1 deletion include/mgos_bt_gattc.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,27 @@ struct mgos_bt_gattc_write_result_arg {
struct mgos_bt_gattc_notify_arg {
struct mgos_bt_gatt_conn conn; /* Device address */
uint16_t handle; /* Characteristic handle */
bool is_indication; /* True if this is an indication. */
struct mg_str data; /* Notification data sent by the server */
};

bool mgos_bt_gattc_connect(const struct mgos_bt_addr *addr);

bool mgos_bt_gattc_discover(uint16_t conn_id);

bool mgos_bt_gattc_disconnect(uint16_t conn_id);

bool mgos_bt_gattc_read(uint16_t conn_id, uint16_t handle);
bool mgos_bt_gattc_subscribe(uint16_t conn_id, uint16_t handle);

bool mgos_bt_gattc_write(uint16_t conn_id, uint16_t handle, struct mg_str data,
bool resp_required);

// Note that the handle here is the handle of the CCCD for the attribute,
// not the attribute itself. Usually CCCD immediately follows the attribute
// so att_handle + 1 is a reasonable guess here.
bool mgos_bt_gattc_set_notify_mode_cccd(uint16_t conn_id, uint16_t cccd_handle,
enum mgos_bt_gatt_notify_mode mode);

#ifdef __cplusplus
}
#endif
11 changes: 7 additions & 4 deletions mjs_fs/api_bt_gattc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ let GATTC = {
},
getWriteResult: function(evdata) { return s2o(evdata, GATTC._wrd); },

// NB: does not work at present, TODO
subscribe: ffi('bool mgos_bt_gattc_subscribe(int, int)'),
setNotifyModeCCCD: ffi('bool mgos_bt_gattc_set_notify_mode_cccd(int, int, int)'),
getNotifyArg: function(evdata) { return s2o(evdata, GATTC._nad); },

disconnect: ffi('bool mgos_bt_gattc_disconnect(int)'),

_cd: ffi('void *mgos_bt_gatt_js_get_conn_def(void)')(),
_rrd: ffi('void *mgos_bt_gattc_js_get_read_result_def(void)')(),
_wrd: ffi('void *mgos_bt_gattc_js_get_write_result_def(void)')(),
_rrd: ffi('void *mgos_bt_gattc_js_get_read_result_arg_def(void)')(),
_wrd: ffi('void *mgos_bt_gattc_js_get_write_result_arg_def(void)')(),
_nad: ffi('void *mgos_bt_gattc_js_get_notify_arg_def(void)')(),
_drad: ffi('void *mgos_bt_gattc_js_get_discovery_result_arg_def(void)')(),
_ddad: ffi('void *mgos_bt_gattc_js_get_discovery_done_arg_def(void)')(),
Expand All @@ -40,3 +39,7 @@ GATTC.EV_DISCOVERY_DONE = GATTC.EV_GRP + 3;
GATTC.EV_READ_RESULT = GATTC.EV_GRP + 4;
GATTC.EV_WRITE_RESULT = GATTC.EV_GRP + 5;
GATTC.EV_NOTIFY = GATTC.EV_GRP + 6;

GATTC.NOTIFY_MODE_OFF = 0;
GATTC.NOTIFY_MODE_NOTIFY = 1;
GATTC.NOTIFY_MODE_INDICATE = 2;
15 changes: 7 additions & 8 deletions src/esp32/esp32_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,20 +359,19 @@ static void esp32_bt_start(void *arg) {
(void) arg;
}

char *esp32_bt_mbuf_to_flat(const struct os_mbuf *om, uint16_t *len) {
*len = 0;
if (om == NULL) return NULL;
struct mg_str esp32_bt_mbuf_to_flat(const struct os_mbuf *om) {
struct mg_str res = MG_NULL_STR;
if (om == NULL) return res;
char *data = NULL;
uint16_t data_len = OS_MBUF_PKTLEN(om);
if (data_len > 0) {
data = malloc(data_len);
if (data == NULL) {
return NULL;
}
if (data == NULL) return res;
ble_hs_mbuf_to_flat(om, data, data_len, &data_len);
}
*len = data_len;
return data;
res.p = data;
res.len = data_len;
return res;
}

bool mgos_bt_common_init(void) {
Expand Down
43 changes: 32 additions & 11 deletions src/esp32/esp32_bt_gattc.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ static int esp32_bt_gattc_event(struct ble_gap_event *ev, void *arg) {
free(conn);
break;
}
case BLE_GAP_EVENT_NOTIFY_RX: {
struct esp32_bt_gattc_conn *conn =
find_conn_by_id(ev->notify_rx.conn_handle);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
struct mg_str data = esp32_bt_mbuf_to_flat(ev->notify_rx.om);
struct mgos_bt_gattc_notify_arg narg = {
.conn = conn->gc,
.handle = ev->notify_rx.attr_handle,
.is_indication = ev->notify_rx.indication,
.data = data,
};
mgos_event_trigger(MGOS_BT_GATTC_EV_NOTIFY, &narg);
mg_strfree(&data);
break;
}
}
esp32_bt_runlock();
return 0;
Expand Down Expand Up @@ -234,12 +249,11 @@ static int esp32_bt_gattc_read_cb(uint16_t conn_id,
struct esp32_bt_gattc_conn *conn = validate_conn(pr->conn);
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
if (err->status == 0) {
uint16_t data_len = 0;
char *data = esp32_bt_mbuf_to_flat(attr->om, &data_len);
struct mg_str data = esp32_bt_mbuf_to_flat(attr->om);
LOG(LL_DEBUG,
("READ_PART c %d ah %d len %d", conn_id, pr->handle, data_len));
mbuf_append(&pr->data, data, data_len);
free(data);
("READ_PART c %d ah %d len %d", conn_id, pr->handle, data.len));
mbuf_append(&pr->data, data.p, data.len);
mg_strfree(&data);
return 0;
}
SLIST_REMOVE(&conn->pending_reads, pr, esp32_bt_gattc_pending_read, next);
Expand Down Expand Up @@ -289,12 +303,6 @@ bool mgos_bt_gattc_read(uint16_t conn_id, uint16_t handle) {
return res;
}

bool mgos_bt_gattc_subscribe(uint16_t conn_id, uint16_t handle) {
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
if (conn == NULL) return false;
return false;
}

static int esp32_bt_gattc_write_cb(uint16_t conn_id,
const struct ble_gatt_error *err,
struct ble_gatt_attr *attr, void *arg) {
Expand Down Expand Up @@ -340,6 +348,19 @@ bool mgos_bt_gattc_write(uint16_t conn_id, uint16_t handle, struct mg_str data,
return (ret == 0);
}

bool mgos_bt_gattc_set_notify_mode_cccd(uint16_t conn_id, uint16_t cccd_handle,
enum mgos_bt_gatt_notify_mode mode) {
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
if (conn == NULL) return false;
uint8_t data[2] = {mode, 0};
int ret =
ble_gattc_write_no_rsp_flat(conn_id, cccd_handle, data, sizeof(data));
if (ret != 0) {
LOG(LL_ERROR, ("ret = %d", ret));
}
return (ret == 0);
}

static int esp32_bt_gattc_add_disc_result_entry(
struct esp32_bt_gattc_conn *conn,
const struct esp32_bt_gattc_disc_result *cdre) {
Expand Down
7 changes: 3 additions & 4 deletions src/esp32/esp32_bt_gatts.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,12 +643,11 @@ static int esp32_gatts_attr_access_cb(uint16_t ch, uint16_t ah,
}
case BLE_GATT_ACCESS_OP_WRITE_CHR:
case BLE_GATT_ACCESS_OP_WRITE_DSC: {
uint16_t data_len = 0;
char *data = esp32_bt_mbuf_to_flat(ctxt->om, &data_len);
struct mg_str data = esp32_bt_mbuf_to_flat(ctxt->om);
struct mgos_bt_gatts_write_arg warg = {
.svc_uuid = sse->se->uuid,
.handle = ah,
.data = mg_mk_str_n(data, data_len),
.data = data,
.trans_id = 0,
.offset = 0,
.need_rsp = true,
Expand Down Expand Up @@ -677,7 +676,7 @@ static int esp32_gatts_attr_access_cb(uint16_t ch, uint16_t ah,
(int) warg.data.len, st));
}
res = esp32_gatts_get_att_err(st);
free(data);
mg_strfree(&data);
break;
}
}
Expand Down
28 changes: 21 additions & 7 deletions src/mgos_bt_js.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const struct mjs_c_struct_member *mgos_bt_gattc_js_get_discovery_done_arg_def(
return gattc_discovery_done_arg_def;
}

static const struct mjs_c_struct_member gattc_read_result_def[] = {
static const struct mjs_c_struct_member gattc_read_result_arg_def[] = {
{"conn", offsetof(struct mgos_bt_gattc_read_result_arg, conn),
MJS_STRUCT_FIELD_TYPE_STRUCT, gatt_conn_def},
{"handle", offsetof(struct mgos_bt_gattc_read_result_arg, handle),
Expand All @@ -151,11 +151,12 @@ static const struct mjs_c_struct_member gattc_read_result_def[] = {
{NULL},
};

const struct mjs_c_struct_member *mgos_bt_gattc_js_get_read_result_def(void) {
return gattc_read_result_def;
const struct mjs_c_struct_member *mgos_bt_gattc_js_get_read_result_arg_def(
void) {
return gattc_read_result_arg_def;
}

static const struct mjs_c_struct_member gattc_write_result_def[] = {
static const struct mjs_c_struct_member gattc_write_result_arg_def[] = {
{"conn", offsetof(struct mgos_bt_gattc_write_result_arg, conn),
MJS_STRUCT_FIELD_TYPE_STRUCT, gatt_conn_def},
{"handle", offsetof(struct mgos_bt_gattc_write_result_arg, handle),
Expand All @@ -165,12 +166,25 @@ static const struct mjs_c_struct_member gattc_write_result_def[] = {
{NULL},
};

const struct mjs_c_struct_member *mgos_bt_gattc_js_get_write_result_def(void) {
return gattc_write_result_def;
const struct mjs_c_struct_member *mgos_bt_gattc_js_get_write_result_arg_def(
void) {
return gattc_write_result_arg_def;
}

static const struct mjs_c_struct_member gattc_notify_arg_def[] = {
{"conn", offsetof(struct mgos_bt_gattc_notify_arg, conn),
MJS_STRUCT_FIELD_TYPE_STRUCT, gatt_conn_def},
{"handle", offsetof(struct mgos_bt_gattc_notify_arg, handle),
MJS_STRUCT_FIELD_TYPE_UINT16, NULL},
{"isIndication", offsetof(struct mgos_bt_gattc_notify_arg, is_indication),
MJS_STRUCT_FIELD_TYPE_BOOL, NULL},
{"data", offsetof(struct mgos_bt_gattc_notify_arg, data),
MJS_STRUCT_FIELD_TYPE_MG_STR, NULL},
{NULL},
};

const struct mjs_c_struct_member *mgos_bt_gattc_js_get_notify_arg_def(void) {
return gattc_read_result_def; /* Currently they are the same */
return gattc_notify_arg_def;
}

static const struct mjs_c_struct_member gatts_read_arg_def[] = {
Expand Down

0 comments on commit c223f66

Please sign in to comment.