Skip to content
Snippets Groups Projects
Commit 62791cdf authored by schneider's avatar schneider
Browse files

Merge branch 'schneider/attc-queue' into 'master'

BLE: Use synchronous BLE events and ATTC write queue

See merge request !455
parents cd98e490 453b066a
Branches
Tags
1 merge request!455BLE: Use synchronous BLE events and ATTC write queue
Pipeline #5157 passed
......@@ -13,15 +13,29 @@ enum notification_status {
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 {
// Characteristic (and descriptor) value storage.
mp_gatts_db_t gatts_db;
mp_gatts_db_t gatts_status;
mp_obj_t attc_pending;
} mp_bluetooth_card10_root_pointers_t;
#define GATTS_DB (MP_STATE_PORT(bluetooth_card10_root_pointers)->gatts_db)
#define 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 {
enum notification_status notification_status;
......@@ -99,6 +113,8 @@ static void handle_att_event(struct epic_att_event *att_event)
uint16_t end_handle =
(v[i + 3] << 8) | v[i + 2];
mp_obj_bluetooth_uuid_t service_uuid;
service_uuid.base.type =
&mp_type_bluetooth_uuid;
if (entry_size == 6) {
memcpy(service_uuid.data, v + i + 4, 2);
service_uuid.type =
......@@ -142,6 +158,8 @@ static void handle_att_event(struct epic_att_event *att_event)
uint16_t value_handle =
(v[i + 4] << 8) | v[i + 3];
mp_obj_bluetooth_uuid_t characteristic_uuid;
characteristic_uuid.base.type =
&mp_type_bluetooth_uuid;
if (entry_size == 2 + 1 + 2 + 2) {
memcpy(characteristic_uuid.data,
v + i + 5,
......@@ -189,6 +207,8 @@ static void handle_att_event(struct epic_att_event *att_event)
uint16_t descriptor_handle =
(v[i + 1] << 8) | v[i];
mp_obj_bluetooth_uuid_t descriptor_uuid;
descriptor_uuid.base.type =
&mp_type_bluetooth_uuid;
if (entry_size == 2 + 2) {
memcpy(descriptor_uuid.data,
v + i + 2,
......@@ -260,6 +280,73 @@ static void handle_att_event(struct epic_att_event *att_event)
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
}
......@@ -345,6 +432,7 @@ int mp_bluetooth_init(void)
mp_bluetooth_gatts_db_create(&GATTS_DB);
mp_bluetooth_gatts_db_create(&GATTS_STATUS);
ATTC_PENDING = mp_obj_new_list(0, NULL);
mp_interrupt_set_callback(
MP_ROM_INT(EPIC_INT_BLE), (mp_obj_t *)&ble_event_obj
......@@ -617,6 +705,8 @@ int mp_bluetooth_gatts_notify_send(
const uint8_t *value,
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_lookup(GATTS_STATUS, value_handle);
e->notification_status = NOTIFICATION_STATUS_PENDING;
......@@ -642,6 +732,8 @@ int mp_bluetooth_gatts_notify_send(
// Indicate the central.
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_lookup(GATTS_STATUS, value_handle);
e->notification_status = NOTIFICATION_STATUS_PENDING;
......@@ -775,6 +867,7 @@ int mp_bluetooth_gattc_discover_descriptors(
// Initiate read of a value from the remote peripheral.
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);
}
......@@ -786,17 +879,37 @@ int mp_bluetooth_gattc_write(
size_t *value_len,
unsigned int mode
) {
int err;
if (mode == MP_BLUETOOTH_WRITE_MODE_NO_RESPONSE) {
err = epic_ble_attc_write_no_rsp(
conn_handle, value_handle, value, *value_len
);
} else if (mode == MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE) {
err = epic_ble_attc_write(
conn_handle, value_handle, value, *value_len
);
} else {
err = MP_EINVAL;
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) {
err = epic_ble_attc_write_no_rsp(
conn_handle, value_handle, value, *value_len
);
} else if (mode == MP_BLUETOOTH_WRITE_MODE_WITH_RESPONSE) {
err = epic_ble_attc_write(
conn_handle, value_handle, value, *value_len
);
}
}
return err;
}
......
......@@ -56,6 +56,7 @@ int mp_hal_csprng_read_int(void);
#define MICROPY_PY_BLUETOOTH (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE (1)
#define MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS (1)
/* Modules */
#define MODULE_BHI160_ENABLED (1)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment