wip: partial discovery responses; compiles; not tested
This commit is contained in:
parent
0a60aee3e4
commit
a995a5c58f
@ -43,6 +43,8 @@
|
||||
#include "shared-bindings/_bleio/__init__.h"
|
||||
#include "shared-bindings/_bleio/Adapter.h"
|
||||
#include "shared-bindings/_bleio/Address.h"
|
||||
#include "shared-bindings/_bleio/Characteristic.h"
|
||||
#include "shared-bindings/_bleio/Service.h"
|
||||
#include "shared-bindings/nvm/ByteArray.h"
|
||||
#include "shared-bindings/_bleio/Connection.h"
|
||||
#include "shared-bindings/_bleio/ScanEntry.h"
|
||||
@ -70,6 +72,12 @@
|
||||
|
||||
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
|
||||
|
||||
STATIC void check_enabled(bleio_adapter_obj_t *adapter) {
|
||||
if (!common_hal_bleio_adapter_get_enabled(adapter)) {
|
||||
mp_raise_bleio_BluetoothError(translate("Adapter not enabled"));
|
||||
}
|
||||
}
|
||||
|
||||
// STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
|
||||
// bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
|
||||
|
||||
@ -232,6 +240,14 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
|
||||
|
||||
self->enabled = enabled;
|
||||
|
||||
// We must poll for input from the HCI adapter.
|
||||
// TODO Can we instead trigger an interrupt on UART input traffic?
|
||||
if (enabled) {
|
||||
supervisor_enable_tick();
|
||||
} else {
|
||||
supervisor_disable_tick();
|
||||
}
|
||||
|
||||
// Stop any current activity; reset to known state.
|
||||
check_hci_error(hci_reset());
|
||||
self->now_advertising = false;
|
||||
@ -253,6 +269,8 @@ bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
|
||||
}
|
||||
|
||||
bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
bt_addr_t addr;
|
||||
check_hci_error(hci_read_bd_addr(&addr));
|
||||
|
||||
@ -306,6 +324,8 @@ void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* na
|
||||
// }
|
||||
|
||||
mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) {
|
||||
check_enabled(self);
|
||||
|
||||
if (self->scan_results != NULL) {
|
||||
if (!shared_module_bleio_scanresults_get_done(self->scan_results)) {
|
||||
mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan."));
|
||||
@ -350,6 +370,8 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
|
||||
}
|
||||
|
||||
void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
check_hci_error(hci_le_set_scan_enable(BT_HCI_LE_SCAN_DISABLE, BT_HCI_LE_SCAN_FILTER_DUP_DISABLE));
|
||||
shared_module_bleio_scanresults_set_done(self->scan_results, true);
|
||||
self->scan_results = NULL;
|
||||
@ -385,6 +407,8 @@ void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
|
||||
|
||||
mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) {
|
||||
|
||||
check_enabled(self);
|
||||
|
||||
// ble_gap_addr_t addr;
|
||||
|
||||
// addr.addr_type = address->type;
|
||||
@ -482,6 +506,8 @@ STATIC void check_data_fit(size_t data_len, bool connectable) {
|
||||
// }
|
||||
|
||||
uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len) {
|
||||
check_enabled(self);
|
||||
|
||||
if (self->now_advertising) {
|
||||
if (self->circuitpython_advertising) {
|
||||
common_hal_bleio_adapter_stop_advertising(self);
|
||||
@ -603,6 +629,8 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
|
||||
}
|
||||
|
||||
void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
|
||||
check_enabled(self);
|
||||
|
||||
// interval value has already been validated.
|
||||
|
||||
check_data_fit(advertising_data_bufinfo->len, connectable);
|
||||
@ -638,6 +666,8 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
|
||||
}
|
||||
|
||||
void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
self->now_advertising = false;
|
||||
self->extended_advertising = false;
|
||||
self->circuitpython_advertising = false;
|
||||
@ -651,10 +681,14 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
|
||||
}
|
||||
|
||||
bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
return self->now_advertising;
|
||||
}
|
||||
|
||||
bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||
bleio_connection_internal_t *connection = &bleio_connections[i];
|
||||
if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
|
||||
@ -665,6 +699,8 @@ bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
if (self->connection_objs != NULL) {
|
||||
return self->connection_objs;
|
||||
}
|
||||
@ -685,17 +721,31 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
|
||||
}
|
||||
|
||||
void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
|
||||
check_enabled(self);
|
||||
|
||||
//FIX bonding_erase_storage();
|
||||
}
|
||||
|
||||
uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute) {
|
||||
check_enabled(adapter);
|
||||
|
||||
// The handle is the index of this attribute in the attributes list.
|
||||
uint16_t handle = (uint16_t) adapter->attributes->len;
|
||||
mp_obj_list_append(adapter->attributes, attribute);
|
||||
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
|
||||
adapter->last_added_service_handle = handle;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
adapter->last_added_characteristic_handle = handle;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle) {
|
||||
check_enabled(adapter);
|
||||
|
||||
if (handle == 0 || handle >= adapter->attributes->len) {
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -703,6 +753,8 @@ mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t han
|
||||
}
|
||||
|
||||
uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter) {
|
||||
check_enabled(adapter);
|
||||
|
||||
return adapter->attributes->len - 1;
|
||||
}
|
||||
|
||||
@ -713,6 +765,10 @@ void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
|
||||
}
|
||||
|
||||
void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
|
||||
if (!common_hal_bleio_adapter_get_enabled(adapter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
common_hal_bleio_adapter_stop_scan(adapter);
|
||||
if (adapter->now_advertising) {
|
||||
common_hal_bleio_adapter_stop_advertising(adapter);
|
||||
@ -731,6 +787,10 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
|
||||
}
|
||||
|
||||
void bleio_adapter_background(bleio_adapter_obj_t* adapter) {
|
||||
if (!common_hal_bleio_adapter_get_enabled(adapter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adapter->advertising_timeout_msecs > 0 &&
|
||||
supervisor_ticks_ms64() - adapter->advertising_start_ticks > adapter->advertising_timeout_msecs) {
|
||||
adapter->advertising_timeout_msecs = 0;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "shared-bindings/_bleio/Service.h"
|
||||
|
||||
// Return the type of the attribute.
|
||||
ble_attribute_type bleio_attribute_type_uuid(mp_obj_t *attribute) {
|
||||
ble_attribute_type_uuid bleio_attribute_type_uuid(mp_obj_t *attribute) {
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
return BLE_TYPE_CHARACTERISTIC;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ typedef enum {
|
||||
BLE_TYPE_SECONDARY_SERVICE = 0x2801,
|
||||
BLE_TYPE_CHARACTERISTIC = 0x2803,
|
||||
BLE_TYPE_DESCRIPTOR = 0x2900
|
||||
} ble_attribute_type;
|
||||
} ble_attribute_type_uuid;
|
||||
|
||||
// typedef struct
|
||||
// {
|
||||
@ -45,6 +45,6 @@ typedef enum {
|
||||
|
||||
// } ble_gap_conn_sec_mode_t;
|
||||
|
||||
// extern void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode);
|
||||
ble_attribute_type_uuid bleio_attribute_type_uuid(mp_obj_t *attribute);
|
||||
|
||||
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "common-hal/_bleio/Attribute.h"
|
||||
#include "shared-bindings/_bleio/__init__.h"
|
||||
#include "shared-bindings/_bleio/Characteristic.h"
|
||||
#include "shared-bindings/_bleio/UUID.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23
|
||||
@ -685,6 +686,7 @@ bool att_indicate(uint16_t handle, const uint8_t* value, int length) {
|
||||
|
||||
STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_error_rsp *rsp = (struct bt_att_error_rsp *) data;
|
||||
|
||||
if (dlen != sizeof(struct bt_att_error_rsp)) {
|
||||
// Incorrect size; ignore.
|
||||
return;
|
||||
@ -700,7 +702,8 @@ STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
|
||||
STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_exchange_mtu_req *req = (struct bt_att_exchange_mtu_req *) data;
|
||||
if (dlen != sizeof(req)) {
|
||||
|
||||
if (dlen != sizeof(struct bt_att_exchange_mtu_req)) {
|
||||
send_error(conn_handle, BT_ATT_OP_MTU_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
}
|
||||
@ -720,7 +723,7 @@ STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
|
||||
|
||||
struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_exchange_mtu_req r;
|
||||
struct bt_att_exchange_mtu_rsp r;
|
||||
} rsp = { {
|
||||
.code = BT_ATT_OP_MTU_RSP,
|
||||
}, {
|
||||
@ -732,12 +735,12 @@ STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
|
||||
}
|
||||
|
||||
STATIC void process_mtu_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_exchange_mtu_rsp *rsp = (struct bt_att_exchange_mtu_rsp *) data;
|
||||
|
||||
if (dlen != sizeof(struct bt_att_exchange_mtu_rsp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct bt_att_exchange_mtu_rsp *rsp = (struct bt_att_exchange_mtu_rsp *) data;
|
||||
|
||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||
if (bleio_connections[i].conn_handle == conn_handle) {
|
||||
bleio_connections[i].mtu = rsp->mtu;
|
||||
@ -879,69 +882,82 @@ STATIC void process_find_by_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t
|
||||
|
||||
void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_read_group_req *req = (struct bt_att_read_group_req *) data;
|
||||
uint16_t uuid = req->uuid[0] | (req->uuid[1] << 8);
|
||||
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
|
||||
|
||||
if (dlen != sizeof(struct bt_att_find_type_req) ||
|
||||
(uuid != BLE_TYPE_PRIMARY_SERVICE &&
|
||||
uuid != BLE_TYPE_SECONDARY_SERVICE)) {
|
||||
if (dlen != sizeof(struct bt_att_read_group_req) + sizeof(type_uuid) ||
|
||||
(type_uuid != BLE_TYPE_PRIMARY_SERVICE &&
|
||||
type_uuid != BLE_TYPE_SECONDARY_SERVICE)) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t response[mtu];
|
||||
uint16_t response_length;
|
||||
typedef struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_read_group_rsp r;
|
||||
} rsp_t;
|
||||
|
||||
response[0] = BT_ATT_OP_READ_GROUP_RSP;
|
||||
response[1] = 0x00;
|
||||
response_length = 2;
|
||||
uint8_t rsp_bytes[mtu];
|
||||
rsp_t *rsp = (rsp_t *) &rsp_bytes;
|
||||
rsp->h.code = BT_ATT_OP_READ_GROUP_RSP;
|
||||
rsp->r.len = 0;
|
||||
|
||||
// FIX
|
||||
// for (uint16_t i = (readByGroupReq->start_handle - 1); i < GATT.attributeCount() && i <= (readByGroupReq->end_handle - 1); i++) {
|
||||
//FIX
|
||||
// BLELocalAttribute* attribute = GATT.attribute(i);
|
||||
// Keeps track of total length of the response.
|
||||
size_t rsp_length = sizeof(rsp_t);
|
||||
|
||||
// if (readByGroupReq->uuid != attribute->type()) {
|
||||
// // not the type
|
||||
// continue;
|
||||
// }
|
||||
bool no_data = true;
|
||||
|
||||
// int uuidLen = attribute->uuidLength();
|
||||
// size_t infoSize = (uuidLen == 2) ? 6 : 20;
|
||||
// All the data chunks must have uuid's that are the same size.
|
||||
// Keep track fo the first one to make sure.
|
||||
size_t sizeof_first_service_uuid = 0;
|
||||
const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
|
||||
for (uint16_t handle = req->start_handle;
|
||||
handle <= max_attribute_handle && handle <= req->end_handle;
|
||||
handle++) {
|
||||
no_data = false;
|
||||
|
||||
// if (response[1] == 0) {
|
||||
// response[1] = infoSize;
|
||||
// }
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
if (type_uuid != bleio_attribute_type_uuid(attribute_obj)) {
|
||||
// Not a primary or secondary service.
|
||||
continue;
|
||||
}
|
||||
// Now we know it's a service.
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
// if (response[1] != infoSize) {
|
||||
// // different size
|
||||
// break;
|
||||
// }
|
||||
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
|
||||
// in this transmission.
|
||||
const uint8_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
|
||||
if (sizeof_first_service_uuid == 0) {
|
||||
sizeof_first_service_uuid = sizeof_service_uuid;
|
||||
} else if (sizeof_first_service_uuid != sizeof_service_uuid) {
|
||||
// Mismatched sizes. Transmit just what we have so far in this batch.
|
||||
break;
|
||||
}
|
||||
|
||||
// BLELocalService* service = (BLELocalService*)attribute;
|
||||
// Size of bt_att_group_data chunk with uuid.
|
||||
const uint16_t data_length = sizeof(struct bt_att_group_data) + sizeof_service_uuid;
|
||||
|
||||
// // add the start handle
|
||||
// uint16_t start_handle = service->start_handle();
|
||||
// memcpy(&response[response_length], &start_handle, sizeof(start_handle));
|
||||
// response_length += sizeof(start_handle);
|
||||
if (rsp_length + data_length > mtu) {
|
||||
// No room for another bt_att_group_data chunk.
|
||||
break;
|
||||
}
|
||||
|
||||
// // add the end handle
|
||||
// uint16_t end_handle = service->end_handle();
|
||||
// memcpy(&response[response_length], &end_handle, sizeof(end_handle));
|
||||
// response_length += sizeof(end_handle);
|
||||
// Pass the length of ONE bt_att_group_data chunk. There may be multiple ones in this transmission.
|
||||
rsp->r.len = data_length;
|
||||
|
||||
// // add the UUID
|
||||
// memcpy(&response[response_length], service->uuidData(), uuidLen);
|
||||
// response_length += uuidLen;
|
||||
uint8_t group_data_bytes[data_length];
|
||||
struct bt_att_group_data *group_data = (struct bt_att_group_data *) group_data_bytes;
|
||||
|
||||
// if ((response_length + infoSize) > mtu) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
group_data->start_handle = service->start_handle;
|
||||
group_data->end_handle = service->end_handle;
|
||||
common_hal_bleio_uuid_pack_into(service->uuid, group_data->value);
|
||||
|
||||
if (response_length == 2) {
|
||||
rsp_length += data_length;
|
||||
}
|
||||
|
||||
if (no_data) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
|
||||
} else {
|
||||
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
|
||||
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -986,7 +1002,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
handle = req->handle;
|
||||
response_opcode = BT_ATT_OP_READ_RSP;
|
||||
|
||||
} else {
|
||||
} else if (opcode == BT_ATT_OP_READ_BLOB_REQ) {
|
||||
if (dlen != sizeof(struct bt_att_read_blob_req)) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_BLOB_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
@ -996,8 +1012,11 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
handle = req->handle;
|
||||
offset = req->offset;
|
||||
response_opcode = BT_ATT_OP_READ_BLOB_RSP;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//FIX
|
||||
(void) offset;
|
||||
(void) handle;
|
||||
|
@ -95,7 +95,6 @@ STATIC uint8_t acl_data_buffer[ACL_DATA_BUFFER_SIZE];
|
||||
STATIC size_t acl_data_len;
|
||||
|
||||
STATIC size_t num_command_packets_allowed;
|
||||
STATIC size_t max_pkt;
|
||||
STATIC size_t pending_pkt;
|
||||
|
||||
// Results from parsing a command response packet.
|
||||
@ -107,77 +106,13 @@ STATIC uint8_t* cmd_response_data;
|
||||
|
||||
STATIC volatile bool hci_poll_in_progress = false;
|
||||
|
||||
STATIC bool debug = true;
|
||||
#define DEBUG_HCI 1
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
if (debug) {
|
||||
h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *) pkt_data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI COMMAND (%x) opcode: %04x, len: %d, data: ",
|
||||
tx ? "TX->" : "RX<-",
|
||||
pkt->pkt_type, pkt->opcode, pkt->param_len);
|
||||
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||
}
|
||||
if (pkt_len != sizeof(h4_hci_cmd_pkt_t) + pkt->param_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
if (debug) {
|
||||
// mp_printf(&mp_plat_print, "\\ PKT_DATA: ");
|
||||
// for (size_t i = 0; i < pkt_len; i++) {
|
||||
// mp_printf(&mp_plat_print, "%02x ", pkt_data[i]);
|
||||
// }
|
||||
// mp_printf(&mp_plat_print, "\n");
|
||||
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *) pkt_data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI ACLDATA (%x) handle: %04x, pb: %d, bc: %d, data_len: %d, ",
|
||||
tx ? "TX->" : "RX<-", pkt->pkt_type, pkt->handle, pkt->pb, pkt->bc, pkt->data_len);
|
||||
|
||||
if (pkt->pb != ACL_DATA_PB_MIDDLE) {
|
||||
// This is the start of a fragmented acl_data packet or is a full packet.
|
||||
acl_data_t *acl = (acl_data_t *) pkt->data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"acl data_len: %d, cid: %04x, data: ",
|
||||
acl->acl_data_len, acl->cid);
|
||||
for (size_t i = 0; i < acl->acl_data_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", acl->acl_data[i]);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < pkt->data_len; i++) {
|
||||
mp_printf(&mp_plat_print, "more data: %02x ", pkt->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pkt_len != sizeof(h4_hci_acl_pkt_t) + pkt->data_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
if (debug) {
|
||||
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *) pkt_data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI EVENT (%x) evt: %02x, param_len: %d, data: ",
|
||||
tx ? "TX->" : "RX<-",
|
||||
pkt->pkt_type, pkt->evt, pkt->param_len);
|
||||
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||
}
|
||||
if (pkt_len != sizeof(h4_hci_evt_pkt_t) + pkt->param_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH");
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
||||
}
|
||||
#if DEBUG_HCI
|
||||
#include "hci_debug.c"
|
||||
#endif // DEBUG_HCI
|
||||
|
||||
STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t*) pkt_data;
|
||||
@ -194,7 +129,7 @@ STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
}
|
||||
|
||||
acl_data_t *acl = (acl_data_t *) &acl_data_buffer;
|
||||
if (acl_data_len != acl->acl_data_len) {
|
||||
if (acl_data_len != sizeof(acl) + acl->acl_data_len) {
|
||||
// We don't have the full packet yet.
|
||||
return;
|
||||
}
|
||||
@ -330,9 +265,9 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
|
||||
}
|
||||
|
||||
default:
|
||||
if (debug) {
|
||||
mp_printf(&mp_plat_print, "process_evt_pkt: Unknown event: %02x\n");
|
||||
}
|
||||
#if DEBUG_HCI
|
||||
mp_printf(&mp_plat_print, "process_evt_pkt: Unknown event: %02x\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -374,7 +309,8 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||
bool packet_is_complete = false;
|
||||
|
||||
// Read bytes until we run out, or accumulate a complete packet.
|
||||
while (common_hal_busio_uart_rx_characters_available(common_hal_bleio_adapter_obj.hci_uart)) {
|
||||
while (!packet_is_complete &&
|
||||
common_hal_busio_uart_rx_characters_available(common_hal_bleio_adapter_obj.hci_uart)) {
|
||||
common_hal_busio_uart_read(common_hal_bleio_adapter_obj.hci_uart, rx_buffer + rx_idx, 1, &errcode);
|
||||
if (errcode) {
|
||||
hci_poll_in_progress = false;
|
||||
@ -417,25 +353,25 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
|
||||
|
||||
switch (rx_buffer[0]) {
|
||||
case H4_ACL:
|
||||
if (debug) {
|
||||
dump_acl_pkt(false, pkt_len, rx_buffer);
|
||||
}
|
||||
#if DEBUG_HCI
|
||||
dump_acl_pkt(false, pkt_len, rx_buffer);
|
||||
#endif
|
||||
|
||||
process_acl_data_pkt(pkt_len, rx_buffer);
|
||||
break;
|
||||
|
||||
case H4_EVT:
|
||||
if (debug) {
|
||||
dump_evt_pkt(false, pkt_len, rx_buffer);
|
||||
}
|
||||
#if DEBUG_HCI
|
||||
dump_evt_pkt(false, pkt_len, rx_buffer);
|
||||
#endif
|
||||
|
||||
process_evt_pkt(pkt_len, rx_buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (debug) {
|
||||
mp_printf(&mp_plat_print, "Unknown HCI packet type: %d\n", rx_buffer[0]);
|
||||
}
|
||||
#if DEBUG_HCI
|
||||
mp_printf(&mp_plat_print, "Unknown HCI packet type: %d\n", rx_buffer[0]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -478,9 +414,9 @@ STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* para
|
||||
|
||||
memcpy(cmd_pkt->params, params, params_len);
|
||||
|
||||
if (debug) {
|
||||
#if DEBUG_HCI
|
||||
dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
int result = write_pkt(tx_buffer, cmd_pkt_len);
|
||||
if (result != HCI_OK) {
|
||||
@ -519,32 +455,31 @@ STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* para
|
||||
|
||||
hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint8_t data_len, uint8_t *data) {
|
||||
int result;
|
||||
while (pending_pkt >= max_pkt) {
|
||||
while (pending_pkt >= common_hal_bleio_adapter_obj.max_acl_num_buffers) {
|
||||
result = hci_poll_for_incoming_pkt();
|
||||
if (result != HCI_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// data_len does not include cid
|
||||
const size_t cid_len = sizeof_field(acl_data_t, cid);
|
||||
// buf_len is size of entire packet including header.
|
||||
const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + cid_len + data_len;
|
||||
const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + sizeof(acl_data_t) + data_len;
|
||||
uint8_t tx_buffer[buf_len];
|
||||
|
||||
h4_hci_acl_pkt_t *acl_pkt = (h4_hci_acl_pkt_t *) tx_buffer;
|
||||
acl_data_t *acl_data = (acl_data_t *) acl_pkt->data;
|
||||
acl_pkt->pkt_type = H4_ACL;
|
||||
acl_pkt->handle = handle;
|
||||
acl_pkt->data_len = (uint8_t)(cid_len + data_len);
|
||||
acl_data->acl_data_len = (uint8_t) data_len;
|
||||
acl_pkt->pb = ACL_DATA_PB_FIRST_FLUSH;
|
||||
acl_pkt->data_len = (uint8_t)(sizeof(acl_data_t) + data_len);
|
||||
acl_data->acl_data_len = data_len;
|
||||
acl_data->cid = cid;
|
||||
|
||||
memcpy(&tx_buffer[sizeof(h4_hci_acl_pkt_t)], data, data_len);
|
||||
memcpy(&acl_data->acl_data, data, data_len);
|
||||
|
||||
if (debug) {
|
||||
#if DEBUG_HCI
|
||||
dump_acl_pkt(true, buf_len, tx_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
pending_pkt++;
|
||||
|
||||
|
335
devices/ble_hci/common-hal/_bleio/hci_debug.c
Normal file
335
devices/ble_hci/common-hal/_bleio/hci_debug.c
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is #include'd in hci.c when HCI_DEBUG is non-zero.
|
||||
|
||||
STATIC const char* att_opcode_name(uint16_t opcode) {
|
||||
switch (opcode) {
|
||||
case BT_ATT_OP_ERROR_RSP: return "ERROR_RSP";
|
||||
case BT_ATT_OP_MTU_REQ: return "MTU_REQ";
|
||||
case BT_ATT_OP_MTU_RSP: return "MTU_RSP";
|
||||
case BT_ATT_OP_FIND_INFO_REQ: return "FIND_INFO_REQ";
|
||||
case BT_ATT_OP_FIND_INFO_RSP: return "FIND_INFO_RSP";
|
||||
case BT_ATT_OP_FIND_TYPE_REQ: return "FIND_TYPE_REQ";
|
||||
case BT_ATT_OP_FIND_TYPE_RSP: return "FIND_TYPE_RSP";
|
||||
case BT_ATT_OP_READ_TYPE_REQ: return "READ_TYPE_REQ";
|
||||
case BT_ATT_OP_READ_TYPE_RSP: return "READ_TYPE_RSP";
|
||||
case BT_ATT_OP_READ_REQ: return "READ_REQ";
|
||||
case BT_ATT_OP_READ_RSP: return "READ_RSP";
|
||||
case BT_ATT_OP_READ_BLOB_REQ: return "READ_BLOB_REQ";
|
||||
case BT_ATT_OP_READ_BLOB_RSP: return "READ_BLOB_RSP";
|
||||
case BT_ATT_OP_READ_MULT_REQ: return "READ_MULT_REQ";
|
||||
case BT_ATT_OP_READ_MULT_RSP: return "READ_MULT_RSP";
|
||||
case BT_ATT_OP_READ_GROUP_REQ: return "READ_GROUP_REQ";
|
||||
case BT_ATT_OP_READ_GROUP_RSP: return "READ_GROUP_RSP";
|
||||
case BT_ATT_OP_WRITE_REQ: return "WRITE_REQ";
|
||||
case BT_ATT_OP_WRITE_RSP: return "WRITE_RSP";
|
||||
case BT_ATT_OP_PREPARE_WRITE_REQ: return "PREPARE_WRITE_REQ";
|
||||
case BT_ATT_OP_PREPARE_WRITE_RSP: return "PREPARE_WRITE_RSP";
|
||||
case BT_ATT_OP_EXEC_WRITE_REQ: return "EXEC_WRITE_REQ";
|
||||
case BT_ATT_OP_EXEC_WRITE_RSP: return "EXEC_WRITE_RSP";
|
||||
case BT_ATT_OP_NOTIFY: return "NOTIFY";
|
||||
case BT_ATT_OP_INDICATE: return "INDICATE";
|
||||
case BT_ATT_OP_CONFIRM: return "CONFIRM";
|
||||
case BT_ATT_OP_READ_MULT_VL_REQ: return "READ_MULT_VL_REQ";
|
||||
case BT_ATT_OP_READ_MULT_VL_RSP: return "READ_MULT_VL_RSP";
|
||||
case BT_ATT_OP_NOTIFY_MULT: return "NOTIFY_MULT";
|
||||
case BT_ATT_OP_WRITE_CMD: return "WRITE_CMD";
|
||||
case BT_ATT_OP_SIGNED_WRITE_CMD: return "SIGNED_WRITE_CMD";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const char* hci_evt_name(uint8_t evt) {
|
||||
switch (evt) {
|
||||
case BT_HCI_EVT_UNKNOWN: return "UNKNOWN";
|
||||
case BT_HCI_EVT_VENDOR: return "VENDOR";
|
||||
case BT_HCI_EVT_INQUIRY_COMPLETE: return "INQUIRY_COMPLETE";
|
||||
case BT_HCI_EVT_CONN_COMPLETE: return "CONN_COMPLETE";
|
||||
case BT_HCI_EVT_CONN_REQUEST: return "CONN_REQUEST";
|
||||
case BT_HCI_EVT_DISCONN_COMPLETE: return "DISCONN_COMPLETE";
|
||||
case BT_HCI_EVT_AUTH_COMPLETE: return "AUTH_COMPLETE";
|
||||
case BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE: return "REMOTE_NAME_REQ_COMPLETE";
|
||||
case BT_HCI_EVT_ENCRYPT_CHANGE: return "ENCRYPT_CHANGE";
|
||||
case BT_HCI_EVT_REMOTE_FEATURES: return "REMOTE_FEATURES";
|
||||
case BT_HCI_EVT_REMOTE_VERSION_INFO: return "REMOTE_VERSION_INFO";
|
||||
case BT_HCI_EVT_CMD_COMPLETE: return "CMD_COMPLETE";
|
||||
case BT_HCI_EVT_CMD_STATUS: return "CMD_STATUS";
|
||||
case BT_HCI_EVT_ROLE_CHANGE: return "ROLE_CHANGE";
|
||||
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: return "NUM_COMPLETED_PACKETS";
|
||||
case BT_HCI_EVT_PIN_CODE_REQ: return "PIN_CODE_REQ";
|
||||
case BT_HCI_EVT_LINK_KEY_REQ: return "LINK_KEY_REQ";
|
||||
case BT_HCI_EVT_LINK_KEY_NOTIFY: return "LINK_KEY_NOTIFY";
|
||||
case BT_HCI_EVT_DATA_BUF_OVERFLOW: return "DATA_BUF_OVERFLOW";
|
||||
case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: return "INQUIRY_RESULT_WITH_RSSI";
|
||||
case BT_HCI_EVT_REMOTE_EXT_FEATURES: return "REMOTE_EXT_FEATURES";
|
||||
case BT_HCI_EVT_SYNC_CONN_COMPLETE: return "SYNC_CONN_COMPLETE";
|
||||
case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: return "EXTENDED_INQUIRY_RESULT";
|
||||
case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE: return "ENCRYPT_KEY_REFRESH_COMPLETE";
|
||||
case BT_HCI_EVT_IO_CAPA_REQ: return "IO_CAPA_REQ";
|
||||
case BT_HCI_EVT_IO_CAPA_RESP: return "IO_CAPA_RESP";
|
||||
case BT_HCI_EVT_USER_CONFIRM_REQ: return "USER_CONFIRM_REQ";
|
||||
case BT_HCI_EVT_USER_PASSKEY_REQ: return "USER_PASSKEY_REQ";
|
||||
case BT_HCI_EVT_SSP_COMPLETE: return "SSP_COMPLETE";
|
||||
case BT_HCI_EVT_USER_PASSKEY_NOTIFY: return "USER_PASSKEY_NOTIFY";
|
||||
case BT_HCI_EVT_LE_META_EVENT: return "LE_META_EVENT";
|
||||
case BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP: return "AUTH_PAYLOAD_TIMEOUT_EXP";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const char* hci_evt_le_name(uint8_t evt_le) {
|
||||
switch (evt_le) {
|
||||
case BT_HCI_EVT_LE_CONN_COMPLETE: return "LE_CONN_COMPLETE";
|
||||
case BT_HCI_EVT_LE_ADVERTISING_REPORT: return "LE_ADVERTISING_REPORT";
|
||||
case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE: return "LE_CONN_UPDATE_COMPLETE";
|
||||
case BT_HCI_EVT_LE_LTK_REQUEST: return "LE_LTK_REQUEST";
|
||||
case BT_HCI_EVT_LE_CONN_PARAM_REQ: return "LE_CONN_PARAM_REQ";
|
||||
case BT_HCI_EVT_LE_DATA_LEN_CHANGE: return "LE_DATA_LEN_CHANGE";
|
||||
case BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE: return "LE_P256_PUBLIC_KEY_COMPLETE";
|
||||
case BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE: return "LE_GENERATE_DHKEY_COMPLETE";
|
||||
case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: return "LE_ENH_CONN_COMPLETE";
|
||||
case BT_HCI_EVT_LE_DIRECT_ADV_REPORT: return "LE_DIRECT_ADV_REPORT";
|
||||
case BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE: return "LE_PHY_UPDATE_COMPLETE";
|
||||
case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: return "LE_EXT_ADVERTISING_REPORT";
|
||||
case BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED: return "LE_PER_ADV_SYNC_ESTABLISHED";
|
||||
case BT_HCI_EVT_LE_PER_ADVERTISING_REPORT: return "LE_PER_ADVERTISING_REPORT";
|
||||
case BT_HCI_EVT_LE_PER_ADV_SYNC_LOST: return "LE_PER_ADV_SYNC_LOST";
|
||||
case BT_HCI_EVT_LE_SCAN_TIMEOUT: return "LE_SCAN_TIMEOUT";
|
||||
case BT_HCI_EVT_LE_ADV_SET_TERMINATED: return "LE_ADV_SET_TERMINATED";
|
||||
case BT_HCI_EVT_LE_SCAN_REQ_RECEIVED: return "LE_SCAN_REQ_RECEIVED";
|
||||
case BT_HCI_EVT_LE_CHAN_SEL_ALGO: return "LE_CHAN_SEL_ALGO";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const char* hci_opcode_name(uint16_t opcode) {
|
||||
switch (opcode) {
|
||||
case BT_OP_NOP: return "NOP";
|
||||
case BT_HCI_OP_INQUIRY: return "INQUIRY";
|
||||
case BT_HCI_OP_INQUIRY_CANCEL: return "INQUIRY_CANCEL";
|
||||
case BT_HCI_OP_CONNECT: return "CONNECT";
|
||||
case BT_HCI_OP_DISCONNECT: return "DISCONNECT";
|
||||
case BT_HCI_OP_CONNECT_CANCEL: return "CONNECT_CANCEL";
|
||||
case BT_HCI_OP_ACCEPT_CONN_REQ: return "ACCEPT_CONN_REQ";
|
||||
case BT_HCI_OP_SETUP_SYNC_CONN: return "SETUP_SYNC_CONN";
|
||||
case BT_HCI_OP_ACCEPT_SYNC_CONN_REQ: return "ACCEPT_SYNC_CONN_REQ";
|
||||
case BT_HCI_OP_REJECT_CONN_REQ: return "REJECT_CONN_REQ";
|
||||
case BT_HCI_OP_LINK_KEY_REPLY: return "LINK_KEY_REPLY";
|
||||
case BT_HCI_OP_LINK_KEY_NEG_REPLY: return "LINK_KEY_NEG_REPLY";
|
||||
case BT_HCI_OP_PIN_CODE_REPLY: return "PIN_CODE_REPLY";
|
||||
case BT_HCI_OP_PIN_CODE_NEG_REPLY: return "PIN_CODE_NEG_REPLY";
|
||||
case BT_HCI_OP_AUTH_REQUESTED: return "AUTH_REQUESTED";
|
||||
case BT_HCI_OP_SET_CONN_ENCRYPT: return "SET_CONN_ENCRYPT";
|
||||
case BT_HCI_OP_REMOTE_NAME_REQUEST: return "REMOTE_NAME_REQUEST";
|
||||
case BT_HCI_OP_REMOTE_NAME_CANCEL: return "REMOTE_NAME_CANCEL";
|
||||
case BT_HCI_OP_READ_REMOTE_FEATURES: return "READ_REMOTE_FEATURES";
|
||||
case BT_HCI_OP_READ_REMOTE_EXT_FEATURES: return "READ_REMOTE_EXT_FEATURES";
|
||||
case BT_HCI_OP_READ_REMOTE_VERSION_INFO: return "READ_REMOTE_VERSION_INFO";
|
||||
case BT_HCI_OP_IO_CAPABILITY_REPLY: return "IO_CAPABILITY_REPLY";
|
||||
case BT_HCI_OP_USER_CONFIRM_REPLY: return "USER_CONFIRM_REPLY";
|
||||
case BT_HCI_OP_USER_CONFIRM_NEG_REPLY: return "USER_CONFIRM_NEG_REPLY";
|
||||
case BT_HCI_OP_USER_PASSKEY_REPLY: return "USER_PASSKEY_REPLY";
|
||||
case BT_HCI_OP_USER_PASSKEY_NEG_REPLY: return "USER_PASSKEY_NEG_REPLY";
|
||||
case BT_HCI_OP_IO_CAPABILITY_NEG_REPLY: return "IO_CAPABILITY_NEG_REPLY";
|
||||
case BT_HCI_OP_SET_EVENT_MASK: return "SET_EVENT_MASK";
|
||||
case BT_HCI_OP_RESET: return "RESET";
|
||||
case BT_HCI_OP_WRITE_LOCAL_NAME: return "WRITE_LOCAL_NAME";
|
||||
case BT_HCI_OP_WRITE_PAGE_TIMEOUT: return "WRITE_PAGE_TIMEOUT";
|
||||
case BT_HCI_OP_WRITE_SCAN_ENABLE: return "WRITE_SCAN_ENABLE";
|
||||
case BT_HCI_OP_READ_TX_POWER_LEVEL: return "READ_TX_POWER_LEVEL";
|
||||
case BT_HCI_OP_SET_CTL_TO_HOST_FLOW: return "SET_CTL_TO_HOST_FLOW";
|
||||
case BT_HCI_OP_HOST_BUFFER_SIZE: return "HOST_BUFFER_SIZE";
|
||||
case BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS: return "HOST_NUM_COMPLETED_PACKETS";
|
||||
case BT_HCI_OP_WRITE_INQUIRY_MODE: return "WRITE_INQUIRY_MODE";
|
||||
case BT_HCI_OP_WRITE_SSP_MODE: return "WRITE_SSP_MODE";
|
||||
case BT_HCI_OP_SET_EVENT_MASK_PAGE_2: return "SET_EVENT_MASK_PAGE_2";
|
||||
case BT_HCI_OP_LE_WRITE_LE_HOST_SUPP: return "LE_WRITE_LE_HOST_SUPP";
|
||||
case BT_HCI_OP_WRITE_SC_HOST_SUPP: return "WRITE_SC_HOST_SUPP";
|
||||
case BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT: return "READ_AUTH_PAYLOAD_TIMEOUT";
|
||||
case BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT: return "WRITE_AUTH_PAYLOAD_TIMEOUT";
|
||||
case BT_HCI_OP_READ_LOCAL_VERSION_INFO: return "READ_LOCAL_VERSION_INFO";
|
||||
case BT_HCI_OP_READ_SUPPORTED_COMMANDS: return "READ_SUPPORTED_COMMANDS";
|
||||
case BT_HCI_OP_READ_LOCAL_EXT_FEATURES: return "READ_LOCAL_EXT_FEATURES";
|
||||
case BT_HCI_OP_READ_LOCAL_FEATURES: return "READ_LOCAL_FEATURES";
|
||||
case BT_HCI_OP_READ_BUFFER_SIZE: return "READ_BUFFER_SIZE";
|
||||
case BT_HCI_OP_READ_BD_ADDR: return "READ_BD_ADDR";
|
||||
case BT_HCI_OP_READ_RSSI: return "READ_RSSI";
|
||||
case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE: return "READ_ENCRYPTION_KEY_SIZE";
|
||||
case BT_HCI_OP_LE_SET_EVENT_MASK: return "LE_SET_EVENT_MASK";
|
||||
case BT_HCI_OP_LE_READ_BUFFER_SIZE: return "LE_READ_BUFFER_SIZE";
|
||||
case BT_HCI_OP_LE_READ_LOCAL_FEATURES: return "LE_READ_LOCAL_FEATURES";
|
||||
case BT_HCI_OP_LE_SET_RANDOM_ADDRESS: return "LE_SET_RANDOM_ADDRESS";
|
||||
case BT_HCI_OP_LE_SET_ADV_PARAM: return "LE_SET_ADV_PARAM";
|
||||
case BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER: return "LE_READ_ADV_CHAN_TX_POWER";
|
||||
case BT_HCI_OP_LE_SET_ADV_DATA: return "LE_SET_ADV_DATA";
|
||||
case BT_HCI_OP_LE_SET_SCAN_RSP_DATA: return "LE_SET_SCAN_RSP_DATA";
|
||||
case BT_HCI_OP_LE_SET_ADV_ENABLE: return "LE_SET_ADV_ENABLE";
|
||||
case BT_HCI_OP_LE_SET_SCAN_PARAM: return "LE_SET_SCAN_PARAM";
|
||||
case BT_HCI_OP_LE_SET_SCAN_ENABLE: return "LE_SET_SCAN_ENABLE";
|
||||
case BT_HCI_OP_LE_CREATE_CONN: return "LE_CREATE_CONN";
|
||||
case BT_HCI_OP_LE_CREATE_CONN_CANCEL: return "LE_CREATE_CONN_CANCEL";
|
||||
case BT_HCI_OP_LE_READ_WL_SIZE: return "LE_READ_WL_SIZE";
|
||||
case BT_HCI_OP_LE_CLEAR_WL: return "LE_CLEAR_WL";
|
||||
case BT_HCI_OP_LE_ADD_DEV_TO_WL: return "LE_ADD_DEV_TO_WL";
|
||||
case BT_HCI_OP_LE_REM_DEV_FROM_WL: return "LE_REM_DEV_FROM_WL";
|
||||
case BT_HCI_OP_LE_CONN_UPDATE: return "LE_CONN_UPDATE";
|
||||
case BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF: return "LE_SET_HOST_CHAN_CLASSIF";
|
||||
case BT_HCI_OP_LE_READ_CHAN_MAP: return "LE_READ_CHAN_MAP";
|
||||
case BT_HCI_OP_LE_READ_REMOTE_FEATURES: return "LE_READ_REMOTE_FEATURES";
|
||||
case BT_HCI_OP_LE_ENCRYPT: return "LE_ENCRYPT";
|
||||
case BT_HCI_OP_LE_RAND: return "LE_RAND";
|
||||
case BT_HCI_OP_LE_START_ENCRYPTION: return "LE_START_ENCRYPTION";
|
||||
case BT_HCI_OP_LE_LTK_REQ_REPLY: return "LE_LTK_REQ_REPLY";
|
||||
case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY: return "LE_LTK_REQ_NEG_REPLY";
|
||||
case BT_HCI_OP_LE_READ_SUPP_STATES: return "LE_READ_SUPP_STATES";
|
||||
case BT_HCI_OP_LE_RX_TEST: return "LE_RX_TEST";
|
||||
case BT_HCI_OP_LE_TX_TEST: return "LE_TX_TEST";
|
||||
case BT_HCI_OP_LE_TEST_END: return "LE_TEST_END";
|
||||
case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY: return "LE_CONN_PARAM_REQ_REPLY";
|
||||
case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY: return "LE_CONN_PARAM_REQ_NEG_REPLY";
|
||||
case BT_HCI_OP_LE_SET_DATA_LEN: return "LE_SET_DATA_LEN";
|
||||
case BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN: return "LE_READ_DEFAULT_DATA_LEN";
|
||||
case BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN: return "LE_WRITE_DEFAULT_DATA_LEN";
|
||||
case BT_HCI_OP_LE_P256_PUBLIC_KEY: return "LE_P256_PUBLIC_KEY";
|
||||
case BT_HCI_OP_LE_GENERATE_DHKEY: return "LE_GENERATE_DHKEY";
|
||||
case BT_HCI_OP_LE_ADD_DEV_TO_RL: return "LE_ADD_DEV_TO_RL";
|
||||
case BT_HCI_OP_LE_REM_DEV_FROM_RL: return "LE_REM_DEV_FROM_RL";
|
||||
case BT_HCI_OP_LE_CLEAR_RL: return "LE_CLEAR_RL";
|
||||
case BT_HCI_OP_LE_READ_RL_SIZE: return "LE_READ_RL_SIZE";
|
||||
case BT_HCI_OP_LE_READ_PEER_RPA: return "LE_READ_PEER_RPA";
|
||||
case BT_HCI_OP_LE_READ_LOCAL_RPA: return "LE_READ_LOCAL_RPA";
|
||||
case BT_HCI_OP_LE_SET_ADDR_RES_ENABLE: return "LE_SET_ADDR_RES_ENABLE";
|
||||
case BT_HCI_OP_LE_SET_RPA_TIMEOUT: return "LE_SET_RPA_TIMEOUT";
|
||||
case BT_HCI_OP_LE_READ_MAX_DATA_LEN: return "LE_READ_MAX_DATA_LEN";
|
||||
case BT_HCI_OP_LE_READ_PHY: return "LE_READ_PHY";
|
||||
case BT_HCI_OP_LE_SET_DEFAULT_PHY: return "LE_SET_DEFAULT_PHY";
|
||||
case BT_HCI_OP_LE_SET_PHY: return "LE_SET_PHY";
|
||||
case BT_HCI_OP_LE_ENH_RX_TEST: return "LE_ENH_RX_TEST";
|
||||
case BT_HCI_OP_LE_ENH_TX_TEST: return "LE_ENH_TX_TEST";
|
||||
case BT_HCI_OP_LE_SET_ADV_SET_RANDOM_ADDR: return "LE_SET_ADV_SET_RANDOM_ADDR";
|
||||
case BT_HCI_OP_LE_SET_EXT_ADV_PARAM: return "LE_SET_EXT_ADV_PARAM";
|
||||
case BT_HCI_OP_LE_SET_EXT_ADV_DATA: return "LE_SET_EXT_ADV_DATA";
|
||||
case BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA: return "LE_SET_EXT_SCAN_RSP_DATA";
|
||||
case BT_HCI_OP_LE_SET_EXT_ADV_ENABLE: return "LE_SET_EXT_ADV_ENABLE";
|
||||
case BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN: return "LE_READ_MAX_ADV_DATA_LEN";
|
||||
case BT_HCI_OP_LE_READ_NUM_ADV_SETS: return "LE_READ_NUM_ADV_SETS";
|
||||
case BT_HCI_OP_LE_REMOVE_ADV_SET: return "LE_REMOVE_ADV_SET";
|
||||
case BT_HCI_OP_CLEAR_ADV_SETS: return "CLEAR_ADV_SETS";
|
||||
case BT_HCI_OP_LE_SET_PER_ADV_PARAM: return "LE_SET_PER_ADV_PARAM";
|
||||
case BT_HCI_OP_LE_SET_PER_ADV_DATA: return "LE_SET_PER_ADV_DATA";
|
||||
case BT_HCI_OP_LE_SET_PER_ADV_ENABLE: return "LE_SET_PER_ADV_ENABLE";
|
||||
case BT_HCI_OP_LE_SET_EXT_SCAN_PARAM: return "LE_SET_EXT_SCAN_PARAM";
|
||||
case BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE: return "LE_SET_EXT_SCAN_ENABLE";
|
||||
case BT_HCI_OP_LE_EXT_CREATE_CONN: return "LE_EXT_CREATE_CONN";
|
||||
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC: return "LE_PER_ADV_CREATE_SYNC";
|
||||
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL: return "LE_PER_ADV_CREATE_SYNC_CANCEL";
|
||||
case BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC: return "LE_PER_ADV_TERMINATE_SYNC";
|
||||
case BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST: return "LE_ADD_DEV_TO_PER_ADV_LIST";
|
||||
case BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST: return "LE_REM_DEV_FROM_PER_ADV_LIST";
|
||||
case BT_HCI_OP_LE_CLEAR_PER_ADV_LIST: return "LE_CLEAR_PER_ADV_LIST";
|
||||
case BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE: return "LE_READ_PER_ADV_LIST_SIZE";
|
||||
case BT_HCI_OP_LE_READ_TX_POWER: return "LE_READ_TX_POWER";
|
||||
case BT_HCI_OP_LE_READ_RF_PATH_COMP: return "LE_READ_RF_PATH_COMP";
|
||||
case BT_HCI_OP_LE_WRITE_RF_PATH_COMP: return "LE_WRITE_RF_PATH_COMP";
|
||||
case BT_HCI_OP_LE_SET_PRIVACY_MODE: return "LE_SET_PRIVACY_MODE";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *) pkt_data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI COMMAND (%x) op: %s (%04x), len: %d, data: ",
|
||||
tx ? "TX->" : "RX<-",
|
||||
pkt->pkt_type,
|
||||
hci_opcode_name(pkt->opcode), pkt->opcode, pkt->param_len);
|
||||
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||
}
|
||||
if (pkt_len != sizeof(h4_hci_cmd_pkt_t) + pkt->param_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
||||
|
||||
STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *) pkt_data;
|
||||
acl_data_t *acl = (acl_data_t *) pkt->data;
|
||||
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI ACLDATA (%x) ",
|
||||
tx ? "TX->" : "RX<-", pkt->pkt_type);
|
||||
|
||||
if (pkt->pb != ACL_DATA_PB_MIDDLE && acl->cid == BT_L2CAP_CID_ATT) {
|
||||
// This is the start of a fragmented acl_data packet or is a full packet,
|
||||
// and is an ATT protocol packet.
|
||||
mp_printf(&mp_plat_print, "att: %s, ", att_opcode_name(acl->acl_data[0]));
|
||||
}
|
||||
|
||||
mp_printf(&mp_plat_print,
|
||||
"handle: %04x, pb: %d, bc: %d, data_len: %d, ",
|
||||
pkt->handle, pkt->pb, pkt->bc, pkt->data_len);
|
||||
|
||||
if (pkt->pb != ACL_DATA_PB_MIDDLE) {
|
||||
// This is the start of a fragmented acl_data packet or is a full packet.
|
||||
mp_printf(&mp_plat_print,
|
||||
"acl data_len: %d, cid: %04x, data: ",
|
||||
acl->acl_data_len, acl->cid);
|
||||
for (size_t i = 0; i < acl->acl_data_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", acl->acl_data[i]);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < pkt->data_len; i++) {
|
||||
mp_printf(&mp_plat_print, "more data: %02x ", pkt->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pkt_len != sizeof(h4_hci_acl_pkt_t) + pkt->data_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
||||
|
||||
STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
|
||||
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *) pkt_data;
|
||||
mp_printf(&mp_plat_print,
|
||||
"%s HCI EVENT (%x) evt: %s (%02x), param_len: %d, data: ",
|
||||
tx ? "TX->" : "RX<-",
|
||||
pkt->pkt_type,
|
||||
pkt->evt == BT_HCI_EVT_LE_META_EVENT
|
||||
? hci_evt_le_name(pkt->params[0])
|
||||
: hci_evt_name(pkt->evt),
|
||||
pkt->evt, pkt->param_len);
|
||||
for (size_t i = 0; i < pkt->param_len; i++) {
|
||||
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
|
||||
}
|
||||
if (pkt_len != sizeof(h4_hci_evt_pkt_t) + pkt->param_len) {
|
||||
mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
|
||||
}
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
}
|
@ -112,7 +112,7 @@ CFLAGS += $(OPTIMIZATION_FLAGS) -DNDEBUG
|
||||
$(echo PERIPHERALS_CHIP_FAMILY=$(PERIPHERALS_CHIP_FAMILY))
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -ggdb
|
||||
CFLAGS += -ggdb -Og
|
||||
# You may want to disable -flto if it interferes with debugging.
|
||||
CFLAGS += -flto -flto-partition=none
|
||||
# You may want to enable these flags to make setting breakpoints easier.
|
||||
|
Loading…
Reference in New Issue
Block a user