Skip to content
Snippets Groups Projects
Commit 453b066a authored by schneider's avatar schneider
Browse files

feat(mp-ble): add ATTC write queue

parent c8054e44
No related branches found
No related tags found
1 merge request!455BLE: Use synchronous BLE events and ATTC write queue
Pipeline #5156 passed
...@@ -13,15 +13,29 @@ enum notification_status { ...@@ -13,15 +13,29 @@ enum notification_status {
NOTIFICATION_STATUS_OVERFLOW NOTIFICATION_STATUS_OVERFLOW
}; };
typedef struct _pendig_gattc_operation_obj_t {
mp_obj_base_t base;
uint16_t conn_handle;
uint16_t value_handle;
unsigned int mode;
uint16_t value_len;
uint8_t value[];
} pending_gattc_operation_obj_t;
STATIC const mp_obj_type_t pending_gattc_operation_type;
typedef struct _mp_bluetooth_card10_root_pointers_t { typedef struct _mp_bluetooth_card10_root_pointers_t {
// Characteristic (and descriptor) value storage. // Characteristic (and descriptor) value storage.
mp_gatts_db_t gatts_db; mp_gatts_db_t gatts_db;
mp_gatts_db_t gatts_status; mp_gatts_db_t gatts_status;
mp_obj_t attc_pending;
} mp_bluetooth_card10_root_pointers_t; } mp_bluetooth_card10_root_pointers_t;
#define GATTS_DB (MP_STATE_PORT(bluetooth_card10_root_pointers)->gatts_db) #define GATTS_DB (MP_STATE_PORT(bluetooth_card10_root_pointers)->gatts_db)
#define GATTS_STATUS \ #define GATTS_STATUS \
(MP_STATE_PORT(bluetooth_card10_root_pointers)->gatts_status) (MP_STATE_PORT(bluetooth_card10_root_pointers)->gatts_status)
#define ATTC_PENDING \
(MP_STATE_PORT(bluetooth_card10_root_pointers)->attc_pending)
typedef struct { typedef struct {
enum notification_status notification_status; enum notification_status notification_status;
...@@ -266,6 +280,73 @@ static void handle_att_event(struct epic_att_event *att_event) ...@@ -266,6 +280,73 @@ static void handle_att_event(struct epic_att_event *att_event)
att_event->hdr.status att_event->hdr.status
); );
} }
bool send_attc = false;
size_t len;
mp_obj_t *items;
if (att_event->hdr.event == ATTC_WRITE_CMD_RSP) {
mp_obj_list_get(ATTC_PENDING, &len, &items);
for (size_t i = 0; i < len; i++) {
pending_gattc_operation_obj_t *op =
MP_OBJ_TO_PTR(items[i]);
if (op->mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE &&
op->conn_handle == 1 &&
op->value_handle == att_event->handle) {
mp_obj_subscr(
ATTC_PENDING,
MP_OBJ_NEW_SMALL_INT(i),
MP_OBJ_NULL
);
send_attc = true;
break;
}
}
}
if (att_event->hdr.event == ATTC_WRITE_RSP) {
mp_obj_list_get(ATTC_PENDING, &len, &items);
for (size_t i = 0; i < len; i++) {
pending_gattc_operation_obj_t *op =
MP_OBJ_TO_PTR(items[i]);
if (op->mode == MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE &&
op->conn_handle == 1 &&
op->value_handle == att_event->handle) {
mp_obj_subscr(
ATTC_PENDING,
MP_OBJ_NEW_SMALL_INT(i),
MP_OBJ_NULL
);
send_attc = true;
break;
}
}
}
if (send_attc) {
mp_obj_list_get(ATTC_PENDING, &len, &items);
if (len > 0) {
pending_gattc_operation_obj_t *op =
MP_OBJ_TO_PTR(items[0]);
if (op->mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) {
epic_ble_attc_write_no_rsp(
op->conn_handle,
op->value_handle,
op->value,
op->value_len
);
} else if (
op->mode ==
MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE) {
epic_ble_attc_write(
op->conn_handle,
op->value_handle,
op->value,
op->value_len
);
}
}
}
#endif #endif
} }
...@@ -351,6 +432,7 @@ int mp_bluetooth_init(void) ...@@ -351,6 +432,7 @@ int mp_bluetooth_init(void)
mp_bluetooth_gatts_db_create(&GATTS_DB); mp_bluetooth_gatts_db_create(&GATTS_DB);
mp_bluetooth_gatts_db_create(&GATTS_STATUS); mp_bluetooth_gatts_db_create(&GATTS_STATUS);
ATTC_PENDING = mp_obj_new_list(0, NULL);
mp_interrupt_set_callback( mp_interrupt_set_callback(
MP_ROM_INT(EPIC_INT_BLE), (mp_obj_t *)&ble_event_obj MP_ROM_INT(EPIC_INT_BLE), (mp_obj_t *)&ble_event_obj
...@@ -623,6 +705,8 @@ int mp_bluetooth_gatts_notify_send( ...@@ -623,6 +705,8 @@ int mp_bluetooth_gatts_notify_send(
const uint8_t *value, const uint8_t *value,
size_t value_len size_t value_len
) { ) {
// TODO: We could make use of a list similar to GATTC operations to
// avoid polling for the return value in this function
gatts_status_entry_t *e = gatts_status_entry_t *e =
gatts_status_lookup(GATTS_STATUS, value_handle); gatts_status_lookup(GATTS_STATUS, value_handle);
e->notification_status = NOTIFICATION_STATUS_PENDING; e->notification_status = NOTIFICATION_STATUS_PENDING;
...@@ -648,6 +732,8 @@ int mp_bluetooth_gatts_notify_send( ...@@ -648,6 +732,8 @@ int mp_bluetooth_gatts_notify_send(
// Indicate the central. // Indicate the central.
int mp_bluetooth_gatts_indicate(uint16_t conn_handle, uint16_t value_handle) int mp_bluetooth_gatts_indicate(uint16_t conn_handle, uint16_t value_handle)
{ {
// TODO: We could make use of a list similar to GATTC operations to
// avoid polling for the return value in this function
gatts_status_entry_t *e = gatts_status_entry_t *e =
gatts_status_lookup(GATTS_STATUS, value_handle); gatts_status_lookup(GATTS_STATUS, value_handle);
e->notification_status = NOTIFICATION_STATUS_PENDING; e->notification_status = NOTIFICATION_STATUS_PENDING;
...@@ -781,6 +867,7 @@ int mp_bluetooth_gattc_discover_descriptors( ...@@ -781,6 +867,7 @@ int mp_bluetooth_gattc_discover_descriptors(
// Initiate read of a value from the remote peripheral. // Initiate read of a value from the remote peripheral.
int mp_bluetooth_gattc_read(uint16_t conn_handle, uint16_t value_handle) int mp_bluetooth_gattc_read(uint16_t conn_handle, uint16_t value_handle)
{ {
// TODO: Make use of ATTC_PENDING list
return epic_ble_attc_read(conn_handle, value_handle); return epic_ble_attc_read(conn_handle, value_handle);
} }
...@@ -792,7 +879,28 @@ int mp_bluetooth_gattc_write( ...@@ -792,7 +879,28 @@ int mp_bluetooth_gattc_write(
size_t *value_len, size_t *value_len,
unsigned int mode unsigned int mode
) { ) {
int err; int err = 0;
if (mode != MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE &&
mode != MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) {
return MP_EINVAL;
}
pending_gattc_operation_obj_t *op = m_new_obj_var(
pending_gattc_operation_obj_t, uint8_t, *value_len
);
op->base.type = &pending_gattc_operation_type;
op->conn_handle = conn_handle;
op->value_handle = value_handle;
op->mode = mode;
op->value_len = *value_len;
memcpy(op->value, value, *value_len);
mp_obj_list_append(ATTC_PENDING, MP_OBJ_FROM_PTR(op));
size_t len;
mp_obj_t *items;
mp_obj_list_get(ATTC_PENDING, &len, &items);
if (len == 1) {
if (mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) { if (mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) {
err = epic_ble_attc_write_no_rsp( err = epic_ble_attc_write_no_rsp(
conn_handle, value_handle, value, *value_len conn_handle, value_handle, value, *value_len
...@@ -801,8 +909,7 @@ int mp_bluetooth_gattc_write( ...@@ -801,8 +909,7 @@ int mp_bluetooth_gattc_write(
err = epic_ble_attc_write( err = epic_ble_attc_write(
conn_handle, value_handle, value, *value_len conn_handle, value_handle, value, *value_len
); );
} else { }
err = MP_EINVAL;
} }
return err; return err;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment