snapshot
This commit is contained in:
parent
b08b0264cc
commit
6494bbdc64
|
@ -633,7 +633,12 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
|
||||||
self->now_advertising = false;
|
self->now_advertising = false;
|
||||||
self->extended_advertising = false;
|
self->extended_advertising = false;
|
||||||
self->circuitpython_advertising = false;
|
self->circuitpython_advertising = false;
|
||||||
check_hci_error(hci_le_set_advertising_enable(BT_HCI_LE_ADV_DISABLE));
|
int result = hci_le_set_advertising_enable(BT_HCI_LE_ADV_DISABLE);
|
||||||
|
// OK if we're already stopped.
|
||||||
|
if (result != BT_HCI_ERR_CMD_DISALLOWED) {
|
||||||
|
check_hci_error(result);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO startup CircuitPython advertising again.
|
//TODO startup CircuitPython advertising again.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,4 +709,6 @@ void bleio_adapter_background(bleio_adapter_obj_t* adapter) {
|
||||||
adapter->advertising_timeout_msecs = 0;
|
adapter->advertising_timeout_msecs = 0;
|
||||||
common_hal_bleio_adapter_stop_advertising(adapter);
|
common_hal_bleio_adapter_stop_advertising(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hci_poll_for_incoming_pkt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,12 +91,10 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
|
||||||
self->write_perm = write_perm;
|
self->write_perm = write_perm;
|
||||||
self->descriptor_list = NULL;
|
self->descriptor_list = NULL;
|
||||||
|
|
||||||
//FIX
|
const mp_int_t max_length_max = 512;
|
||||||
// const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
|
if (max_length < 0 || max_length > max_length_max) {
|
||||||
// if (max_length < 0 || max_length > max_length_max) {
|
mp_raise_ValueError(translate("max_length must be <= 512"));
|
||||||
// mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
|
}
|
||||||
// max_length_max, fixed_length ? "True" : "False");
|
|
||||||
// }
|
|
||||||
self->max_length = max_length;
|
self->max_length = max_length;
|
||||||
self->fixed_length = fixed_length;
|
self->fixed_length = fixed_length;
|
||||||
|
|
||||||
|
|
|
@ -36,55 +36,35 @@
|
||||||
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
||||||
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
||||||
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
||||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
|
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[16]) {
|
||||||
//FIX self->nrf_ble_uuid.uuid = uuid16;
|
self->size = uuid128 == NULL ? 16 : 128;
|
||||||
// if (uuid128 == NULL) {
|
self->uuid16 = uuid16;
|
||||||
// self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
|
if (uuid128) {
|
||||||
// } else {
|
memcpy(self->uuid128, uuid128, 16);
|
||||||
// ble_uuid128_t vs_uuid;
|
self->uuid128[12] = uuid16 & 0xff;
|
||||||
// memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128));
|
self->uuid128[13] = uuid16 >> 8;
|
||||||
|
} else {
|
||||||
// // Register this vendor-specific UUID. Bytes 12 and 13 will be zero.
|
memset(self->uuid128, 0, 16);
|
||||||
// check_nrf_error(sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type));
|
}
|
||||||
// vm_used_ble = true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) {
|
uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) {
|
||||||
//FIX return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 16 : 128;
|
return self->size;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
|
uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
|
||||||
//FIX return self->nrf_ble_uuid.uuid;
|
return self->uuid16;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
|
void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
|
||||||
//FIX uint8_t length;
|
memcpy(uuid128, self->uuid128, 16);
|
||||||
//FIX check_nrf_error(sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
|
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
|
||||||
//FIX if (self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE) {
|
if (self->size == 16) {
|
||||||
// buf[0] = self->nrf_ble_uuid.uuid & 0xff;
|
buf[0] = self->uuid16 & 0xff;
|
||||||
// buf[1] = self->nrf_ble_uuid.uuid >> 8;
|
buf[1] = self->uuid16 >> 8;
|
||||||
// } else {
|
} else {
|
||||||
// common_hal_bleio_uuid_get_uuid128(self, buf);
|
common_hal_bleio_uuid_get_uuid128(self, buf);
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIX
|
|
||||||
// void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) {
|
|
||||||
// if (nrf_ble_uuid->type == BLE_UUID_TYPE_UNKNOWN) {
|
|
||||||
// mp_raise_bleio_BluetoothError(translate("Unexpected nrfx uuid type"));
|
|
||||||
// }
|
|
||||||
// self->nrf_ble_uuid.uuid = nrf_ble_uuid->uuid;
|
|
||||||
// self->nrf_ble_uuid.type = nrf_ble_uuid->type;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Fill in a ble_uuid_t from my values.
|
|
||||||
// void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) {
|
|
||||||
// nrf_ble_uuid->uuid = self->nrf_ble_uuid.uuid;
|
|
||||||
// nrf_ble_uuid->type = self->nrf_ble_uuid.type;
|
|
||||||
// }
|
|
||||||
|
|
|
@ -33,15 +33,9 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
//FIX Use the native way of storing UUID's:
|
uint8_t size;
|
||||||
// - ble_uuid_t.uuid is a 16-bit uuid.
|
uint16_t uuid16;
|
||||||
// - ble_uuid_t.type is BLE_UUID_TYPE_BLE if it's a 16-bit Bluetooth SIG UUID.
|
uint8_t uuid128[16];
|
||||||
// or is BLE_UUID_TYPE_VENDOR_BEGIN and higher, which indexes into a table of registered
|
|
||||||
// 128-bit UUIDs.
|
|
||||||
// ble_uuid_t nrf_ble_uuid;
|
|
||||||
} bleio_uuid_obj_t;
|
} bleio_uuid_obj_t;
|
||||||
|
|
||||||
// void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid);
|
|
||||||
// void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
|
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "supervisor/shared/tick.h"
|
#include "supervisor/shared/tick.h"
|
||||||
#include "shared-bindings/_bleio/__init__.h"
|
#include "shared-bindings/_bleio/__init__.h"
|
||||||
#include "common-hal/_bleio/Adapter.h"
|
#include "common-hal/_bleio/Adapter.h"
|
||||||
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
|
||||||
// HCI H4 protocol packet types: first byte in the packet.
|
// HCI H4 protocol packet types: first byte in the packet.
|
||||||
#define H4_CMD 0x01
|
#define H4_CMD 0x01
|
||||||
|
@ -61,44 +62,61 @@ STATIC uint8_t* cmd_response_data;
|
||||||
|
|
||||||
//FIX STATIC uint8_t acl_pkt_buffer[ACL_PKT_BUFFER_SIZE];
|
//FIX STATIC uint8_t acl_pkt_buffer[ACL_PKT_BUFFER_SIZE];
|
||||||
|
|
||||||
|
STATIC volatile bool hci_poll_in_progress = false;
|
||||||
|
|
||||||
STATIC bool debug = true;
|
STATIC bool debug = true;
|
||||||
|
|
||||||
// These are the headers of the full packets that are sent over the serial interface.
|
// These are the headers of the full packets that are sent over the serial interface.
|
||||||
// They all have a one-byte type-field at the front, one of the H4_xxx packet types.
|
// They all have a one-byte type-field at the front, one of the H4_xxx packet types.
|
||||||
|
|
||||||
typedef struct __attribute__ ((packed)) {
|
typedef struct __attribute__ ((packed)) {
|
||||||
uint8_t pkt_type;
|
uint8_t pkt_type;
|
||||||
uint16_t opcode;
|
uint16_t opcode;
|
||||||
uint8_t param_len;
|
uint8_t param_len;
|
||||||
} h4_hci_cmd_hdr_t;
|
uint8_t params[];
|
||||||
|
} h4_hci_cmd_pkt_t;
|
||||||
|
|
||||||
|
#define ACLDATA_PB_FIRST_NON_FLUSH 0
|
||||||
|
#define ACLDATA_HCI_PB_MIDDLE 1
|
||||||
|
#define ACLDATA_PB_FIRST_FLUSH 2
|
||||||
|
#define ACLDATA_PB_FULL 3
|
||||||
|
|
||||||
typedef struct __attribute__ ((packed)) {
|
typedef struct __attribute__ ((packed)) {
|
||||||
uint8_t pkt_type;
|
uint8_t pkt_type;
|
||||||
uint16_t handle;
|
uint16_t handle : 12;
|
||||||
uint16_t total_data_len;
|
uint8_t pb: 2; // Packet boundary flag: ACLDATA_PB values.
|
||||||
uint16_t acl_data_len;
|
uint8_t bc: 2; // Broadcast flag: always 0b00 for BLE.
|
||||||
uint16_t cid;
|
uint16_t data_len; // Total data length, including acl_data header.
|
||||||
} h4_hci_acl_hdr_t;
|
uint8_t data[]; // Data following the header
|
||||||
|
} h4_hci_acl_pkt_t;
|
||||||
|
|
||||||
|
// L2CAP data, which is in h4_hci_acl_pkt_t.data
|
||||||
|
typedef struct __attribute__ ((packed)) {
|
||||||
|
uint16_t l2cap_data_len; // Length of acl_data. Does not include this header.
|
||||||
|
uint16_t cid; // Channel ID.
|
||||||
|
uint8_t l2cap_data[];
|
||||||
|
} l2cap_data_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct __attribute__ ((packed)) {
|
typedef struct __attribute__ ((packed)) {
|
||||||
uint8_t pkt_type;
|
uint8_t pkt_type;
|
||||||
uint8_t evt;
|
uint8_t evt;
|
||||||
uint8_t param_len;
|
uint8_t param_len;
|
||||||
} h4_hci_evt_hdr_t;
|
uint8_t params[];
|
||||||
|
} h4_hci_evt_pkt_t;
|
||||||
|
|
||||||
|
|
||||||
STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
h4_hci_cmd_hdr_t *pkt = (h4_hci_cmd_hdr_t *) pkt_data;
|
h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *) pkt_data;
|
||||||
mp_printf(&mp_plat_print,
|
mp_printf(&mp_plat_print,
|
||||||
"%s HCI COMMAND (%x) opcode: %04x, len: %d, data: ",
|
"%s HCI COMMAND (%x) opcode: %04x, len: %d, data: ",
|
||||||
tx ? "TX->" : "RX<-",
|
tx ? "TX->" : "RX<-",
|
||||||
pkt->pkt_type, pkt->opcode, pkt->param_len);
|
pkt->pkt_type, pkt->opcode, pkt->param_len);
|
||||||
uint8_t i;
|
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||||
for (i = sizeof(h4_hci_cmd_hdr_t); i < pkt_len; i++) {
|
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||||
mp_printf(&mp_plat_print, "%02x ", pkt_data[i]);
|
|
||||||
}
|
}
|
||||||
if (i != pkt->param_len + sizeof(h4_hci_cmd_hdr_t)) {
|
if (pkt_len != sizeof(h4_hci_cmd_pkt_t) + pkt->param_len) {
|
||||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||||
}
|
}
|
||||||
mp_printf(&mp_plat_print, "\n");
|
mp_printf(&mp_plat_print, "\n");
|
||||||
|
@ -107,16 +125,16 @@ STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
|
|
||||||
STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
h4_hci_acl_hdr_t *pkt = (h4_hci_acl_hdr_t *) pkt_data;
|
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *) pkt_data;
|
||||||
|
l2cap_data_t *l2cap = (l2cap_data_t *) pkt->data;
|
||||||
mp_printf(&mp_plat_print,
|
mp_printf(&mp_plat_print,
|
||||||
"%s HCI ACLDATA (%x) handle: %04x, total_data_len: %d, acl_data_len: %d, cid: %04x, data: ",
|
"%s HCI ACLDATA (%x) handle: %04x, pb: %d, bc: %d, data_len: %d, l2cap_data_len: %d, cid: %04x, l2cap_data: ",
|
||||||
tx ? "TX->" : "RX<-",
|
tx ? "TX->" : "RX<-",
|
||||||
pkt->pkt_type, pkt->handle, pkt->total_data_len, pkt->acl_data_len, pkt->cid);
|
pkt->pkt_type, pkt->handle, pkt->data_len, l2cap->l2cap_data_len, l2cap->cid);
|
||||||
uint8_t i;
|
for (size_t i = 0; i < l2cap->l2cap_data_len; i++) {
|
||||||
for (i = sizeof(h4_hci_acl_hdr_t); i < pkt_len; i++) {
|
mp_printf(&mp_plat_print, "%02x ", l2cap->l2cap_data[i]);
|
||||||
mp_printf(&mp_plat_print, "%02x ", pkt_data[i]);
|
|
||||||
}
|
}
|
||||||
if (i != pkt->acl_data_len + sizeof(h4_hci_acl_hdr_t)) {
|
if (pkt_len != sizeof(h4_hci_acl_pkt_t) + pkt->data_len) {
|
||||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||||
}
|
}
|
||||||
mp_printf(&mp_plat_print, "\n");
|
mp_printf(&mp_plat_print, "\n");
|
||||||
|
@ -125,16 +143,15 @@ STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
|
|
||||||
STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
h4_hci_evt_hdr_t *pkt = (h4_hci_evt_hdr_t *) pkt_data;
|
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *) pkt_data;
|
||||||
mp_printf(&mp_plat_print,
|
mp_printf(&mp_plat_print,
|
||||||
"%s HCI EVENT (%x) evt: %02x, param_len: %d, data: ",
|
"%s HCI EVENT (%x) evt: %02x, param_len: %d, data: ",
|
||||||
tx ? "TX->" : "RX<-",
|
tx ? "TX->" : "RX<-",
|
||||||
pkt->pkt_type, pkt->evt, pkt->param_len);
|
pkt->pkt_type, pkt->evt, pkt->param_len);
|
||||||
uint8_t i;
|
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||||
for (i = sizeof(h4_hci_evt_hdr_t); i < pkt_len; i++) {
|
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||||
mp_printf(&mp_plat_print, "%02x ", pkt_data[i]);
|
|
||||||
}
|
}
|
||||||
if (i != pkt->param_len + sizeof(h4_hci_evt_hdr_t)) {
|
if (pkt_len != sizeof(h4_hci_evt_pkt_t) + pkt->param_len) {
|
||||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||||
}
|
}
|
||||||
mp_printf(&mp_plat_print, "\n");
|
mp_printf(&mp_plat_print, "\n");
|
||||||
|
@ -143,7 +160,7 @@ STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
|
|
||||||
STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
|
STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||||
//FIX pkt_len is +1 than before, because it includes the pkt_type.
|
//FIX pkt_len is +1 than before, because it includes the pkt_type.
|
||||||
// h4_hci_acl_hdr_t *aclHdr = (h4_hci_acl_hdr_t*)pkt_data;
|
// h4_hci_acl_pkt_t *aclHdr = (h4_hci_acl_pkt_t*)pkt_data;
|
||||||
|
|
||||||
// uint16_t aclFlags = (aclHdr->handle & 0xf000) >> 12;
|
// uint16_t aclFlags = (aclHdr->handle & 0xf000) >> 12;
|
||||||
|
|
||||||
|
@ -202,15 +219,14 @@ STATIC void process_num_comp_pkts(uint16_t handle, uint16_t num_pkts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
|
||||||
{
|
{
|
||||||
h4_hci_evt_hdr_t *evt_hdr = (h4_hci_evt_hdr_t*) pkt;
|
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t*) pkt_data;
|
||||||
// The data itself, after the header.
|
|
||||||
uint8_t *evt_data = pkt + sizeof(h4_hci_evt_hdr_t);
|
|
||||||
|
|
||||||
switch (evt_hdr->evt) {
|
switch (pkt->evt) {
|
||||||
case BT_HCI_EVT_DISCONN_COMPLETE: {
|
case BT_HCI_EVT_DISCONN_COMPLETE: {
|
||||||
struct bt_hci_evt_disconn_complete *disconn_complete = (struct bt_hci_evt_disconn_complete*) evt_data;
|
struct bt_hci_evt_disconn_complete *disconn_complete =
|
||||||
|
(struct bt_hci_evt_disconn_complete*) pkt->params;
|
||||||
(void) disconn_complete;
|
(void) disconn_complete;
|
||||||
//FIX
|
//FIX
|
||||||
// ATT.removeConnection(disconn_complete->handle, disconn_complete->reason);
|
// ATT.removeConnection(disconn_complete->handle, disconn_complete->reason);
|
||||||
|
@ -226,7 +242,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
struct bt_hci_evt_cc_status cc_status;
|
struct bt_hci_evt_cc_status cc_status;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct cmd_complete_with_status *evt = (struct cmd_complete_with_status *) evt_data;
|
struct cmd_complete_with_status *evt = (struct cmd_complete_with_status *) pkt->params;
|
||||||
|
|
||||||
num_command_packets_allowed = evt->cmd_complete.ncmd;
|
num_command_packets_allowed = evt->cmd_complete.ncmd;
|
||||||
|
|
||||||
|
@ -235,15 +251,15 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
cmd_response_status = evt->cc_status.status;
|
cmd_response_status = evt->cc_status.status;
|
||||||
// All the bytes following cmd_complete, -including- the status byte, which is
|
// All the bytes following cmd_complete, -including- the status byte, which is
|
||||||
// included in all the _bt_hci_rp_* structs.
|
// included in all the _bt_hci_rp_* structs.
|
||||||
cmd_response_data = &evt_data[sizeof_field(struct cmd_complete_with_status, cmd_complete)];
|
cmd_response_data = (uint8_t *) &evt->cc_status;
|
||||||
// Includes status byte.
|
// Includes status byte.
|
||||||
cmd_response_len = evt_hdr->param_len - sizeof_field(struct cmd_complete_with_status, cmd_complete);
|
cmd_response_len = pkt->param_len - sizeof_field(struct cmd_complete_with_status, cmd_complete);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BT_HCI_EVT_CMD_STATUS: {
|
case BT_HCI_EVT_CMD_STATUS: {
|
||||||
struct bt_hci_evt_cmd_status *evt = (struct bt_hci_evt_cmd_status *) evt_data;
|
struct bt_hci_evt_cmd_status *evt = (struct bt_hci_evt_cmd_status *) pkt->params;
|
||||||
|
|
||||||
num_command_packets_allowed = evt->ncmd;
|
num_command_packets_allowed = evt->ncmd;
|
||||||
|
|
||||||
|
@ -257,7 +273,8 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
}
|
}
|
||||||
|
|
||||||
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: {
|
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: {
|
||||||
struct bt_hci_evt_num_completed_packets *evt = (struct bt_hci_evt_num_completed_packets *) evt_data;
|
struct bt_hci_evt_num_completed_packets *evt =
|
||||||
|
(struct bt_hci_evt_num_completed_packets *) pkt->params;
|
||||||
|
|
||||||
// Start at zero-th pair: (conn handle, num completed packets).
|
// Start at zero-th pair: (conn handle, num completed packets).
|
||||||
struct bt_hci_handle_count *handle_and_count = &(evt->h[0]);
|
struct bt_hci_handle_count *handle_and_count = &(evt->h[0]);
|
||||||
|
@ -269,15 +286,14 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
}
|
}
|
||||||
|
|
||||||
case BT_HCI_EVT_LE_META_EVENT: {
|
case BT_HCI_EVT_LE_META_EVENT: {
|
||||||
struct bt_hci_evt_le_meta_event *meta_evt = (struct bt_hci_evt_le_meta_event *) evt_data;
|
struct bt_hci_evt_le_meta_event *meta_evt = (struct bt_hci_evt_le_meta_event *) pkt->params;
|
||||||
// Start of the encapsulated LE event.
|
uint8_t *le_evt = pkt->params + sizeof (struct bt_hci_evt_le_meta_event);
|
||||||
uint8_t *le_evt = evt_data + sizeof (struct bt_hci_evt_le_meta_event);
|
|
||||||
|
|
||||||
if (meta_evt->subevent == BT_HCI_EVT_LE_CONN_COMPLETE) {
|
if (meta_evt->subevent == BT_HCI_EVT_LE_CONN_COMPLETE) {
|
||||||
struct bt_hci_evt_le_conn_complete *le_conn_complete =
|
struct bt_hci_evt_le_conn_complete *le_conn_complete =
|
||||||
(struct bt_hci_evt_le_conn_complete *) le_evt;
|
(struct bt_hci_evt_le_conn_complete *) le_evt;
|
||||||
|
|
||||||
if (le_conn_complete->status == 0x00) {
|
if (le_conn_complete->status == BT_HCI_ERR_SUCCESS) {
|
||||||
// ATT.addConnection(le_conn_complete->handle,
|
// ATT.addConnection(le_conn_complete->handle,
|
||||||
// le_conn_complete->role,
|
// le_conn_complete->role,
|
||||||
// le_conn_complete->peer_addr //FIX struct
|
// le_conn_complete->peer_addr //FIX struct
|
||||||
|
@ -286,13 +302,6 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
// le_conn_complete->supv_timeout
|
// le_conn_complete->supv_timeout
|
||||||
// le_conn_complete->clock_accuracy);
|
// le_conn_complete->clock_accuracy);
|
||||||
|
|
||||||
// L2CAPSignaling.addConnection(le_conn_complete->handle,
|
|
||||||
// le_conn_complete->role,
|
|
||||||
// le_conn_complete->peer_addr, //FIX struct
|
|
||||||
// le_conn_complete->interval,
|
|
||||||
// le_conn_complete->latency,
|
|
||||||
// le_conn_complete->supv_timeout,
|
|
||||||
// le_conn_complete->clock_accuracy);
|
|
||||||
}
|
}
|
||||||
} else if (meta_evt->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
|
} else if (meta_evt->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
|
||||||
struct bt_hci_evt_le_advertising_info *le_advertising_info =
|
struct bt_hci_evt_le_advertising_info *le_advertising_info =
|
||||||
|
@ -319,9 +328,19 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
|
||||||
void hci_init(void) {
|
void hci_init(void) {
|
||||||
rx_idx = 0;
|
rx_idx = 0;
|
||||||
pending_pkt = 0;
|
pending_pkt = 0;
|
||||||
|
hci_poll_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hci_result_t hci_poll_for_incoming_pkt(void) {
|
hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||||
|
if (hci_poll_in_progress) {
|
||||||
|
return HCI_OK;
|
||||||
|
}
|
||||||
|
common_hal_mcu_disable_interrupts();
|
||||||
|
if (!hci_poll_in_progress) {
|
||||||
|
hci_poll_in_progress = true;
|
||||||
|
}
|
||||||
|
common_hal_mcu_enable_interrupts();
|
||||||
|
|
||||||
// Assert RTS low to say we're ready to read data.
|
// Assert RTS low to say we're ready to read data.
|
||||||
common_hal_digitalio_digitalinout_set_value(adapter->rts_digitalinout, false);
|
common_hal_digitalio_digitalinout_set_value(adapter->rts_digitalinout, false);
|
||||||
|
|
||||||
|
@ -332,21 +351,22 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||||
while (common_hal_busio_uart_rx_characters_available(adapter->hci_uart)) {
|
while (common_hal_busio_uart_rx_characters_available(adapter->hci_uart)) {
|
||||||
common_hal_busio_uart_read(adapter->hci_uart, rx_buffer + rx_idx, 1, &errcode);
|
common_hal_busio_uart_read(adapter->hci_uart, rx_buffer + rx_idx, 1, &errcode);
|
||||||
if (errcode) {
|
if (errcode) {
|
||||||
|
hci_poll_in_progress = false;
|
||||||
return HCI_READ_ERROR;
|
return HCI_READ_ERROR;
|
||||||
}
|
}
|
||||||
rx_idx++;
|
rx_idx++;
|
||||||
|
|
||||||
switch (rx_buffer[0]) {
|
switch (rx_buffer[0]) {
|
||||||
case H4_ACL:
|
case H4_ACL:
|
||||||
if (rx_idx > sizeof(h4_hci_acl_hdr_t) &&
|
if (rx_idx > sizeof(h4_hci_acl_pkt_t) &&
|
||||||
rx_idx >= sizeof(h4_hci_acl_hdr_t) + ((h4_hci_acl_hdr_t *) rx_buffer)->total_data_len) {
|
rx_idx >= sizeof(h4_hci_acl_pkt_t) + ((h4_hci_acl_pkt_t *) rx_buffer)->data_len) {
|
||||||
packet_is_complete = true;
|
packet_is_complete = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case H4_EVT:
|
case H4_EVT:
|
||||||
if (rx_idx > sizeof(h4_hci_evt_hdr_t) &&
|
if (rx_idx > sizeof(h4_hci_evt_pkt_t) &&
|
||||||
rx_idx >= sizeof(h4_hci_evt_hdr_t) + ((h4_hci_evt_hdr_t *) rx_buffer)->param_len) {
|
rx_idx >= sizeof(h4_hci_evt_pkt_t) + ((h4_hci_evt_pkt_t *) rx_buffer)->param_len) {
|
||||||
packet_is_complete = true;
|
packet_is_complete = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -359,6 +379,7 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packet_is_complete) {
|
if (!packet_is_complete) {
|
||||||
|
hci_poll_in_progress = false;
|
||||||
return HCI_OK;
|
return HCI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +412,7 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||||
|
|
||||||
common_hal_digitalio_digitalinout_set_value(adapter->rts_digitalinout, true);
|
common_hal_digitalio_digitalinout_set_value(adapter->rts_digitalinout, true);
|
||||||
|
|
||||||
|
hci_poll_in_progress = false;
|
||||||
return HCI_OK;
|
return HCI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,22 +438,22 @@ STATIC hci_result_t write_pkt(uint8_t *buffer, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* params) {
|
STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* params) {
|
||||||
uint8_t tx_buffer[sizeof(h4_hci_cmd_hdr_t) + params_len];
|
uint8_t cmd_pkt_len = sizeof(h4_hci_cmd_pkt_t) + params_len;
|
||||||
|
uint8_t tx_buffer[cmd_pkt_len];
|
||||||
|
|
||||||
// cmd header is at the beginning of tx_buffer
|
// cmd header is at the beginning of tx_buffer
|
||||||
h4_hci_cmd_hdr_t *cmd_hdr = (h4_hci_cmd_hdr_t *) tx_buffer;
|
h4_hci_cmd_pkt_t *cmd_pkt = (h4_hci_cmd_pkt_t *) tx_buffer;
|
||||||
cmd_hdr->pkt_type = H4_CMD;
|
cmd_pkt->pkt_type = H4_CMD;
|
||||||
cmd_hdr->opcode = opcode;
|
cmd_pkt->opcode = opcode;
|
||||||
cmd_hdr->param_len = params_len;
|
cmd_pkt->param_len = params_len;
|
||||||
|
|
||||||
// Copy the params data into the space after the header.
|
memcpy(cmd_pkt->params, params, params_len);
|
||||||
memcpy(&tx_buffer[sizeof(h4_hci_cmd_hdr_t)], params, params_len);
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer);
|
dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = write_pkt(tx_buffer, sizeof(h4_hci_cmd_hdr_t) + params_len);
|
int result = write_pkt(tx_buffer, cmd_pkt_len);
|
||||||
if (result != HCI_OK) {
|
if (result != HCI_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -477,19 +499,20 @@ STATIC int __attribute__((unused)) send_acl_pkt(uint16_t handle, uint8_t cid, vo
|
||||||
}
|
}
|
||||||
|
|
||||||
// data_len does not include cid.
|
// data_len does not include cid.
|
||||||
const size_t cid_len = sizeof_field(h4_hci_acl_hdr_t, cid);
|
const size_t cid_len = sizeof_field(l2cap_data_t, cid);
|
||||||
// buf_len is size of entire packet including header.
|
// buf_len is size of entire packet including header.
|
||||||
const size_t buf_len = sizeof(h4_hci_acl_hdr_t) + cid_len + data_len;
|
const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + cid_len + data_len;
|
||||||
uint8_t tx_buffer[buf_len];
|
uint8_t tx_buffer[buf_len];
|
||||||
|
|
||||||
h4_hci_acl_hdr_t *acl_hdr = (h4_hci_acl_hdr_t *) tx_buffer;
|
h4_hci_acl_pkt_t *acl_pkt = (h4_hci_acl_pkt_t *) tx_buffer;
|
||||||
acl_hdr->pkt_type = H4_ACL;
|
l2cap_data_t *l2cap = (l2cap_data_t *) acl_pkt->data;
|
||||||
acl_hdr->handle = handle;
|
acl_pkt->pkt_type = H4_ACL;
|
||||||
acl_hdr->total_data_len = (uint8_t)(cid_len + data_len);
|
acl_pkt->handle = handle;
|
||||||
acl_hdr->acl_data_len = (uint8_t) data_len;
|
acl_pkt->data_len = (uint8_t)(cid_len + data_len);
|
||||||
acl_hdr->cid = cid;
|
l2cap->l2cap_data_len = (uint8_t) data_len;
|
||||||
|
l2cap->cid = cid;
|
||||||
|
|
||||||
memcpy(&tx_buffer[sizeof(h4_hci_acl_hdr_t)], data, data_len);
|
memcpy(&tx_buffer[sizeof(h4_hci_acl_pkt_t)], data, data_len);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dump_acl_pkt(true, buf_len, tx_buffer);
|
dump_acl_pkt(true, buf_len, tx_buffer);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "common-hal/_bleio/hci_include/hci.h"
|
#include "common-hal/_bleio/hci_include/hci.h"
|
||||||
|
#include "common-hal/_bleio/hci_include/hci_err.h"
|
||||||
|
|
||||||
// Incomplete forward declaration to get around mutually-dependent include files.
|
// Incomplete forward declaration to get around mutually-dependent include files.
|
||||||
typedef struct _bleio_adapter_obj_t bleio_adapter_obj_t;
|
typedef struct _bleio_adapter_obj_t bleio_adapter_obj_t;
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
||||||
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
||||||
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
||||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
|
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[16]) {
|
||||||
self->nrf_ble_uuid.uuid = uuid16;
|
self->nrf_ble_uuid.uuid = uuid16;
|
||||||
if (uuid128 == NULL) {
|
if (uuid128 == NULL) {
|
||||||
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
|
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
|
||||||
|
|
|
@ -34,7 +34,7 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
||||||
|
|
||||||
extern const mp_obj_type_t bleio_uuid_type;
|
extern const mp_obj_type_t bleio_uuid_type;
|
||||||
|
|
||||||
extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[]);
|
extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]);
|
||||||
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
|
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
|
||||||
extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
|
extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
|
||||||
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
|
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
|
||||||
|
|
Loading…
Reference in New Issue