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.
pull/1/head
Damien George 2019-11-29 12:48:38 +11:00
parent 9a849cc7ca
commit 7aeafe2ae9
4 changed files with 33 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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
/////////////////////////////////////////////////////////////////////////////

View File

@ -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);
}