Skip to content

Commit 01988cb

Browse files
committed
GATTC write support
1 parent 9375e30 commit 01988cb

File tree

4 files changed

+75
-9
lines changed

4 files changed

+75
-9
lines changed

include/mgos_bt_gattc.h

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ enum mgos_bt_gattc_event {
3434
MGOS_BT_GATTC_EV_DISCOVERY_RESULT, /* mgos_bt_gattc_discovery_result_arg */
3535
MGOS_BT_GATTC_EV_DISCOVERY_DONE, /* mgos_bt_gattc_discovery_done_arg */
3636
MGOS_BT_GATTC_EV_READ_RESULT, /* mgos_bt_gattc_read_result_arg */
37+
MGOS_BT_GATTC_EV_WRITE_RESULT, /* mgos_bt_gattc_write_result_arg */
3738
MGOS_BT_GATTC_EV_NOTIFY, /* mgos_bt_gattc_notify_arg */
3839
};
3940

@@ -59,6 +60,12 @@ struct mgos_bt_gattc_read_result_arg {
5960
struct mg_str data; /* Data that has been read */
6061
};
6162

63+
struct mgos_bt_gattc_write_result_arg {
64+
struct mgos_bt_gatt_conn conn; /* Device address */
65+
uint16_t handle; /* Characteristic handle */
66+
bool ok; /* Success indicator. */
67+
};
68+
6269
struct mgos_bt_gattc_notify_arg {
6370
struct mgos_bt_gatt_conn conn; /* Device address */
6471
uint16_t handle; /* Characteristic handle */

mjs_fs/api_bt_gattc.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,30 @@ let GATTC = {
1313
read: ffi('bool mgos_bt_gattc_read(int, int)'),
1414
getReadResult: function(evdata) { return s2o(evdata, GATTC._rrd); },
1515

16+
write: function(c, h, data, resp_required) {
17+
return GATTC._write(c, h, data, !!resp_required);
18+
},
19+
getWriteResult: function(evdata) { return s2o(evdata, GATTC._wrd); },
20+
1621
// NB: does not work at present, TODO
1722
subscribe: ffi('bool mgos_bt_gattc_subscribe(int, int)'),
1823
getNotifyArg: function(evdata) { return s2o(evdata, GATTC._nad); },
1924

20-
// NB: does not work at present, TODO
21-
write: ffi('bool mgos_bt_gattc_write_js(int, int, struct mg_str *)'),
22-
2325
disconnect: ffi('bool mgos_bt_gattc_disconnect(int)'),
2426

2527
_cd: ffi('void *mgos_bt_gatt_js_get_conn_def(void)')(),
2628
_rrd: ffi('void *mgos_bt_gattc_js_get_read_result_def(void)')(),
29+
_wrd: ffi('void *mgos_bt_gattc_js_get_write_result_def(void)')(),
2730
_nad: ffi('void *mgos_bt_gattc_js_get_notify_arg_def(void)')(),
2831
_drad: ffi('void *mgos_bt_gattc_js_get_discovery_result_arg_def(void)')(),
2932
_ddad: ffi('void *mgos_bt_gattc_js_get_discovery_done_arg_def(void)')(),
33+
_write: ffi('bool mgos_bt_gattc_write_js(int, int, struct mg_str *, bool)'),
3034
};
3135

3236
GATTC.EV_CONNECT = GATTC.EV_GRP + 0;
3337
GATTC.EV_DISCONNECT = GATTC.EV_GRP + 1;
3438
GATTC.EV_DISCOVERY_RESULT = GATTC.EV_GRP + 2;
3539
GATTC.EV_DISCOVERY_DONE = GATTC.EV_GRP + 3;
3640
GATTC.EV_READ_RESULT = GATTC.EV_GRP + 4;
37-
GATTC.EV_NOTIFY = GATTC.EV_GRP + 5;
41+
GATTC.EV_WRITE_RESULT = GATTC.EV_GRP + 5;
42+
GATTC.EV_NOTIFY = GATTC.EV_GRP + 6;

src/esp32/esp32_bt_gattc.c

+43-3
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ static int esp32_bt_gattc_read_cb(uint16_t conn_id,
258258

259259
bool mgos_bt_gattc_read(uint16_t conn_id, uint16_t handle) {
260260
LOG(LL_DEBUG, ("READ c %d ah %d", conn_id, handle));
261+
int ret;
261262
bool res = false;
262263
esp32_bt_rlock();
263264
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
@@ -275,11 +276,12 @@ bool mgos_bt_gattc_read(uint16_t conn_id, uint16_t handle) {
275276
pr->conn = conn;
276277
pr->handle = handle;
277278
mbuf_init(&pr->data, 0);
278-
if (ble_gattc_read_long(conn_id, handle, 0, esp32_bt_gattc_read_cb, pr) ==
279-
0) {
279+
ret = ble_gattc_read_long(conn_id, handle, 0, esp32_bt_gattc_read_cb, pr);
280+
if (ret == 0) {
280281
SLIST_INSERT_HEAD(&conn->pending_reads, pr, next);
281282
res = true;
282283
} else {
284+
LOG(LL_ERROR, ("ret = %d", ret));
283285
esp32_bt_gattc_pending_read_free(pr);
284286
}
285287
out:
@@ -293,11 +295,49 @@ bool mgos_bt_gattc_subscribe(uint16_t conn_id, uint16_t handle) {
293295
return false;
294296
}
295297

298+
static int esp32_bt_gattc_write_cb(uint16_t conn_id,
299+
const struct ble_gatt_error *err,
300+
struct ble_gatt_attr *attr, void *arg) {
301+
bool resp_required = (bool) (uintptr_t) arg;
302+
LOG(LL_DEBUG, ("WRITE_CB c %d err %p st %d attr %p ah %d rr %d", conn_id, err,
303+
(err ? err->status : -1), attr, (attr ? attr->handle : 0),
304+
resp_required));
305+
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
306+
if (conn == NULL) return BLE_ATT_ERR_UNLIKELY;
307+
if (resp_required) {
308+
struct mgos_bt_gattc_write_result_arg rarg = {
309+
.conn = conn->gc,
310+
.handle = attr->handle,
311+
.ok = (err->status == 0),
312+
};
313+
mgos_event_trigger(MGOS_BT_GATTC_EV_WRITE_RESULT, &rarg);
314+
}
315+
return 0;
316+
}
317+
296318
bool mgos_bt_gattc_write(uint16_t conn_id, uint16_t handle, struct mg_str data,
297319
bool resp_required) {
320+
LOG(LL_DEBUG, ("WRITE c %d ah %d rr %d", conn_id, handle, resp_required));
298321
struct esp32_bt_gattc_conn *conn = find_conn_by_id(conn_id);
299322
if (conn == NULL) return false;
300-
return false;
323+
int ret;
324+
uint16_t mtu = ble_att_mtu(conn_id);
325+
if (data.len < mtu - 1) {
326+
if (resp_required) {
327+
ret = ble_gattc_write_flat(conn_id, handle, data.p, data.len,
328+
esp32_bt_gattc_write_cb, (void *) 1);
329+
} else {
330+
ret = ble_gattc_write_no_rsp_flat(conn_id, handle, data.p, data.len);
331+
}
332+
} else {
333+
struct os_mbuf *om = ble_hs_mbuf_from_flat(data.p, data.len);
334+
ret = ble_gattc_write_long(conn_id, handle, 0, om, esp32_bt_gattc_write_cb,
335+
(void *) resp_required);
336+
}
337+
if (ret != 0) {
338+
LOG(LL_ERROR, ("ret = %d", ret));
339+
}
340+
return (ret == 0);
301341
}
302342

303343
static int esp32_bt_gattc_add_disc_result_entry(

src/mgos_bt_js.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ bool mgos_bt_gattc_connect_js(const char *addr_s) {
103103
}
104104

105105
bool mgos_bt_gattc_write_js(int conn_id, uint16_t handle,
106-
const struct mg_str *data) {
107-
return mgos_bt_gattc_write(conn_id, handle, *data, true /* resp_required */);
106+
const struct mg_str *data, bool resp_required) {
107+
return mgos_bt_gattc_write(conn_id, handle, *data, resp_required);
108108
}
109109

110110
static const struct mjs_c_struct_member gattc_discovery_result_arg_def[] = {
@@ -155,6 +155,20 @@ const struct mjs_c_struct_member *mgos_bt_gattc_js_get_read_result_def(void) {
155155
return gattc_read_result_def;
156156
}
157157

158+
static const struct mjs_c_struct_member gattc_write_result_def[] = {
159+
{"conn", offsetof(struct mgos_bt_gattc_write_result_arg, conn),
160+
MJS_STRUCT_FIELD_TYPE_STRUCT, gatt_conn_def},
161+
{"handle", offsetof(struct mgos_bt_gattc_write_result_arg, handle),
162+
MJS_STRUCT_FIELD_TYPE_UINT16, NULL},
163+
{"ok", offsetof(struct mgos_bt_gattc_write_result_arg, ok),
164+
MJS_STRUCT_FIELD_TYPE_BOOL, NULL},
165+
{NULL},
166+
};
167+
168+
const struct mjs_c_struct_member *mgos_bt_gattc_js_get_write_result_def(void) {
169+
return gattc_write_result_def;
170+
}
171+
158172
const struct mjs_c_struct_member *mgos_bt_gattc_js_get_notify_arg_def(void) {
159173
return gattc_read_result_def; /* Currently they are the same */
160174
}

0 commit comments

Comments
 (0)