From 7aeafe2ae9f16af74d22604b3090641a664b2da2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 29 Nov 2019 12:48:38 +1100 Subject: [PATCH] extmod/modbluetooth: Add optional 4th arg to gattc_write for write mode. This allows the user to explicitly select the behaviour of the write to the remote peripheral. This is needed for peripherals that have characteristics with WRITE_NO_RESPONSE set (instead of normal WRITE). The function's signature is now: BLE.gattc_write(conn_handle, value_handle, data, mode=0) mode=0 means write without response, while mode=1 means write with response. The latter was the original behaviour so this commit is a change in behaviour of this method, and one should specify 1 as the 4th argument to get back the old behaviour. In the future there could be more modes supported, such as long writes. --- docs/library/ubluetooth.rst | 15 +++++++++++++-- extmod/modbluetooth.c | 8 ++++++-- extmod/modbluetooth.h | 6 +++++- extmod/modbluetooth_nimble.c | 11 +++++++++-- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/docs/library/ubluetooth.rst b/docs/library/ubluetooth.rst index 2d3af1bb6b..fd4c012d29 100644 --- a/docs/library/ubluetooth.rst +++ b/docs/library/ubluetooth.rst @@ -310,12 +310,23 @@ Central Role (GATT Client) On success, the ``_IRQ_GATTC_READ_RESULT`` event will be raised. -.. method:: BLE.gattc_write(conn_handle, value_handle, data) +.. method:: BLE.gattc_write(conn_handle, value_handle, data, mode=0) Issue a remote write to a connected peripheral for the specified characteristic or descriptor handle. - On success, the ``_IRQ_GATTC_WRITE_STATUS`` event will be raised. + The argument *mode* specifies the write behaviour, with the currently + supported values being: + + * ``mode=0`` (default) is a write-without-response: the write will + be sent to the remote peripheral but no confirmation will be + returned, and no event will be raised. + * ``mode=1`` is a write-with-response: the remote peripheral is + requested to send a response/acknowledgement that it received the + data. + + If a response is received from the remote peripheral the + ``_IRQ_GATTC_WRITE_STATUS`` event will be raised. class UUID diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 2293e03673..74f73c1f2b 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -641,9 +641,13 @@ STATIC mp_obj_t bluetooth_ble_gattc_write(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo = {0}; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); size_t len = bufinfo.len; - return bluetooth_handle_errno(mp_bluetooth_gattc_write(conn_handle, value_handle, bufinfo.buf, &len)); + unsigned int mode = MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE; + if (n_args == 5) { + mode = mp_obj_get_int(args[4]); + } + return bluetooth_handle_errno(mp_bluetooth_gattc_write(conn_handle, value_handle, bufinfo.buf, &len, mode)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gattc_write_obj, 4, 4, bluetooth_ble_gattc_write); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gattc_write_obj, 4, 5, bluetooth_ble_gattc_write); #endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index 8a3ab414fd..fbae67bc45 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -65,6 +65,10 @@ #define MP_BLUETOOTH_CHARACTERISTIC_FLAG_WRITE (1 << 3) #define MP_BLUETOOTH_CHARACTERISTIC_FLAG_NOTIFY (1 << 4) +// For mp_bluetooth_gattc_write, the mode parameter +#define MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE (0) +#define MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE (1) + // Type value also doubles as length. #define MP_BLUETOOTH_UUID_TYPE_16 (2) #define MP_BLUETOOTH_UUID_TYPE_32 (4) @@ -219,7 +223,7 @@ int mp_bluetooth_gattc_discover_descriptors(uint16_t conn_handle, uint16_t start int mp_bluetooth_gattc_read(uint16_t conn_handle, uint16_t value_handle); // Write the value to the remote peripheral. -int mp_bluetooth_gattc_write(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t *value_len); +int mp_bluetooth_gattc_write(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t *value_len, unsigned int mode); #endif ///////////////////////////////////////////////////////////////////////////// diff --git a/extmod/modbluetooth_nimble.c b/extmod/modbluetooth_nimble.c index 83eb4b88a6..930dd06d11 100644 --- a/extmod/modbluetooth_nimble.c +++ b/extmod/modbluetooth_nimble.c @@ -816,8 +816,15 @@ STATIC int ble_gatt_attr_write_cb(uint16_t conn_handle, const struct ble_gatt_er } // Write the value to the remote peripheral. -int mp_bluetooth_gattc_write(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t *value_len) { - int err = ble_gattc_write_flat(conn_handle, value_handle, value, *value_len, &ble_gatt_attr_write_cb, NULL); +int mp_bluetooth_gattc_write(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t *value_len, unsigned int mode) { + int err; + if (mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) { + err = ble_gattc_write_no_rsp_flat(conn_handle, value_handle, value, *value_len); + } else if (mode == MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE) { + err = ble_gattc_write_flat(conn_handle, value_handle, value, *value_len, &ble_gatt_attr_write_cb, NULL); + } else { + err = BLE_HS_EINVAL; + } return ble_hs_err_to_errno(err); }