wip; compiles; much commented out

This commit is contained in:
Dan Halbert 2020-06-26 17:23:20 -04:00
parent 57bac9a1fc
commit 1bc2e979eb
19 changed files with 1340 additions and 1675 deletions

View File

@ -31,9 +31,8 @@
#include <stdio.h>
#include <string.h>
#include "bonding.h"
#include "py/gc.h"
#include "py/mphal.h"
#include "py/objstr.h"
#include "py/runtime.h"
#include "supervisor/shared/safe_mode.h"
@ -74,111 +73,111 @@
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
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;
// 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;
// // For debugging.
// // mp_printf(&mp_plat_print, "Adapter event: 0x%04x\n", ble_evt->header.evt_id);
// // For debugging.
// // mp_printf(&mp_plat_print, "Adapter event: 0x%04x\n", ble_evt->header.evt_id);
// switch (ble_evt->header.evt_id) {
// case BLE_GAP_EVT_CONNECTED: {
// // Find an empty connection. One must always be available because the SD has the same
// // total connection limit.
// bleio_connection_internal_t *connection;
// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// connection = &bleio_connections[i];
// if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
// break;
// }
// }
// switch (ble_evt->header.evt_id) {
// case BLE_GAP_EVT_CONNECTED: {
// // Find an empty connection. One must always be available because the SD has the same
// // total connection limit.
// bleio_connection_internal_t *connection;
// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// connection = &bleio_connections[i];
// if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
// break;
// }
// }
// // Central has connected.
// ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
// // Central has connected.
// ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
// connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
// connection->connection_obj = mp_const_none;
// connection->pair_status = PAIR_NOT_PAIRED;
// connection->mtu = 0;
// connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
// connection->connection_obj = mp_const_none;
// connection->pair_status = PAIR_NOT_PAIRED;
// connection->mtu = 0;
// ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
// self->connection_objs = NULL;
// ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
// self->connection_objs = NULL;
// // Save the current connection parameters.
// memcpy(&connection->conn_params, &connected->conn_params, sizeof(ble_gap_conn_params_t));
// // Save the current connection parameters.
// memcpy(&connection->conn_params, &connected->conn_params, sizeof(ble_gap_conn_params_t));
// #if CIRCUITPY_VERBOSE_BLE
// ble_gap_conn_params_t *cp = &connected->conn_params;
// mp_printf(&mp_plat_print, "conn params: min_ci %d max_ci %d s_l %d sup_timeout %d\n", cp->min_conn_interval, cp->max_conn_interval, cp->slave_latency, cp->conn_sup_timeout);
// #endif
// #if CIRCUITPY_VERBOSE_BLE
// ble_gap_conn_params_t *cp = &connected->conn_params;
// mp_printf(&mp_plat_print, "conn params: min_ci %d max_ci %d s_l %d sup_timeout %d\n", cp->min_conn_interval, cp->max_conn_interval, cp->slave_latency, cp->conn_sup_timeout);
// #endif
// // See if connection interval set by Central is out of range.
// // If so, negotiate our preferred range.
// ble_gap_conn_params_t conn_params;
// sd_ble_gap_ppcp_get(&conn_params);
// if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
// conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
// sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
// }
// self->current_advertising_data = NULL;
// break;
// }
// case BLE_GAP_EVT_DISCONNECTED: {
// // Find the connection that was disconnected.
// bleio_connection_internal_t *connection;
// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// connection = &bleio_connections[i];
// if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
// break;
// }
// }
// ble_drv_remove_event_handler(connection_on_ble_evt, connection);
// connection->conn_handle = BLE_CONN_HANDLE_INVALID;
// connection->pair_status = PAIR_NOT_PAIRED;
// if (connection->connection_obj != mp_const_none) {
// bleio_connection_obj_t* obj = connection->connection_obj;
// obj->connection = NULL;
// obj->disconnect_reason = ble_evt->evt.gap_evt.params.disconnected.reason;
// }
// self->connection_objs = NULL;
// // See if connection interval set by Central is out of range.
// // If so, negotiate our preferred range.
// ble_gap_conn_params_t conn_params;
// sd_ble_gap_ppcp_get(&conn_params);
// if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
// conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
// sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
// }
// self->current_advertising_data = NULL;
// break;
// }
// case BLE_GAP_EVT_DISCONNECTED: {
// // Find the connection that was disconnected.
// bleio_connection_internal_t *connection;
// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// connection = &bleio_connections[i];
// if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
// break;
// }
// }
// ble_drv_remove_event_handler(connection_on_ble_evt, connection);
// connection->conn_handle = BLE_CONN_HANDLE_INVALID;
// connection->pair_status = PAIR_NOT_PAIRED;
// if (connection->connection_obj != mp_const_none) {
// bleio_connection_obj_t* obj = connection->connection_obj;
// obj->connection = NULL;
// obj->disconnect_reason = ble_evt->evt.gap_evt.params.disconnected.reason;
// }
// self->connection_objs = NULL;
// break;
// }
// break;
// }
// case BLE_GAP_EVT_ADV_SET_TERMINATED:
// self->current_advertising_data = NULL;
// break;
// case BLE_GAP_EVT_ADV_SET_TERMINATED:
// self->current_advertising_data = NULL;
// break;
// default:
// // For debugging.
// // mp_printf(&mp_plat_print, "Unhandled adapter event: 0x%04x\n", ble_evt->header.evt_id);
// return false;
// break;
// }
return true;
}
// default:
// // For debugging.
// // mp_printf(&mp_plat_print, "Unhandled adapter event: 0x%04x\n", ble_evt->header.evt_id);
// return false;
// break;
// }
// return true;
// }
STATIC void get_address(bleio_adapter_obj_t *self, ble_gap_addr_t *address) {
// STATIC void get_address(bleio_adapter_obj_t *self, ble_gap_addr_t *address) {
// check_nrf_error(sd_ble_gap_addr_get(address));
}
// }
char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 , 0};
STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
uint8_t len = sizeof(default_ble_name) - 1;
// STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
// // uint8_t len = sizeof(default_ble_name) - 1;
ble_gap_addr_t local_address;
get_address(self, &local_address);
// // ble_gap_addr_t local_address;
// // get_address(self, &local_address);
default_ble_name[len - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
default_ble_name[len - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
default_ble_name[len - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
default_ble_name[len - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
// // default_ble_name[len - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
// // default_ble_name[len - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
// // default_ble_name[len - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
// // default_ble_name[len - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
// // default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
}
// common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
// }
void common_hal_bleio_adapter_construct(bleio_adapter_obj_t *self, mcu_pin_obj_t *tx, mcu_pin_obj_t *rx, mcu_pin_obj_t *rts, mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size, mcu_pin_obj_t* spi_cs, mcu_pin_obj_t* gpio0, mcu_pin_obj_t *reset, bool reset_high) {
void common_hal_bleio_adapter_construct(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size, const mcu_pin_obj_t* spi_cs, const mcu_pin_obj_t* gpio0, const mcu_pin_obj_t *reset, bool reset_high) {
self->tx = tx;
self->rx = rx;
self->rts = rts;
@ -206,9 +205,9 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
// common_hal UART takes rts and cts, but is currently not implemented for many ports.
// In addition, rts and cts may be pins that are not part of the serial peripheral
// used for tx and rx, so use GPIO for them.
common_hal_busio_uart_construct(&self->hci_uart, tx, rx, NULL, NULL, NULL, false,
BLEIO_HCI_BAUDRATE, 8, PARITY_NONE, 1, 0.0f,
BLEIO_HCI_BUFFER_SIZE, NULL, false);
common_hal_busio_uart_construct(&self->hci_uart, self->tx, self->rx, NULL, NULL, NULL, false,
self->baudrate, 8, PARITY_NONE, 1, 0.0f,
self->buffer_size, NULL, false);
// RTS is output, active high
common_hal_digitalio_digitalinout_construct(&self->rts_digitalio, self->rts);
@ -220,9 +219,9 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
// SPI_CS and GPI0 are used to signal entering BLE mode.
// SPI_CS should be low, and GPI0 should be high
common_hal_digitalio_digitalinout_construct(&self->spi_cs_digitalio, self->spi_cs);
common_hal_digitalio_digitalinout_construct(&self->gpio0_digitalio, self->gpi0);
common_hal_digitalio_digitalinout_construct(&self->gpio0_digitalio, self->gpio0);
common_hal_digitalio_digitalinout_switch_to_output(&self->spi_cs_digitalio, false, DRIVE_MODE_PUSH_PULL);
common_hal_digitalio_digitalinout_switch_to_output(&self->gpio0_digitalio, true DRIVE_MODE_PUSH_PULL);
common_hal_digitalio_digitalinout_switch_to_output(&self->gpio0_digitalio, true, DRIVE_MODE_PUSH_PULL);
// RESET is output, start in non-reset state.
common_hal_digitalio_digitalinout_construct(&self->reset_digitalio, self->reset);
@ -252,7 +251,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
common_hal_digitalio_digitalinout_deinit(&self->rts_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->cts_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->spi_cs_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->gpi0_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->gpio0_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->reset_digitalio);
}
@ -263,13 +262,13 @@ 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) {
common_hal_bleio_adapter_set_enabled(self, true);
ble_gap_addr_t local_address;
get_address(self, &local_address);
// ble_gap_addr_t local_address;
// get_address(self, &local_address);
bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
address->base.type = &bleio_address_type;
common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
// common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
return address;
}
@ -460,12 +459,12 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
// sd_ble_gap_data_length_update(conn_handle, NULL, NULL);
// Make the connection object and return it.
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
if (connection->conn_handle == conn_handle) {
return bleio_connection_new_from_internal(connection);
}
}
// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// bleio_connection_internal_t *connection = &bleio_connections[i];
// if (connection->conn_handle == conn_handle) {
// return bleio_connection_new_from_internal(connection);
// }
// }
mp_raise_bleio_BluetoothError(translate("Failed to connect: internal error"));
@ -473,13 +472,13 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
}
// The nRF SD 6.1.0 can only do one concurrent advertisement so share the advertising handle.
uint8_t adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
//FIX uint8_t adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
STATIC void check_data_fit(size_t data_len, bool connectable) {
if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED ||
(connectable && data_len > BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED)) {
mp_raise_ValueError(translate("Data too large for advertisement packet"));
}
//FIX if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED ||
// (connectable && data_len > BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED)) {
// mp_raise_ValueError(translate("Data too large for advertisement packet"));
// }
}
// STATIC bool advertising_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
@ -607,30 +606,31 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
// the same data while cycling the MAC address -- otherwise, what's the
// point of randomizing the MAC address?
if (!timeout) {
if (anonymous) {
// The Nordic macro is in units of 10ms. Convert to seconds.
uint32_t adv_timeout_max_secs = UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS);
uint32_t rotate_timeout_max_secs = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S;
timeout = MIN(adv_timeout_max_secs, rotate_timeout_max_secs);
}
else {
timeout = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
}
//FIX if (anonymous) {
// // The Nordic macro is in units of 10ms. Convert to seconds.
// uint32_t adv_timeout_max_secs = UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS);
// uint32_t rotate_timeout_max_secs = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S;
// timeout = MIN(adv_timeout_max_secs, rotate_timeout_max_secs);
// }
// else {
// timeout = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
// }
} else {
if (SEC_TO_UNITS(timeout, UNIT_10_MS) > BLE_GAP_ADV_TIMEOUT_LIMITED_MAX) {
mp_raise_bleio_BluetoothError(translate("Timeout is too long: Maximum timeout length is %d seconds"),
UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS));
}
//FIX if (SEC_TO_UNITS(timeout, UNIT_10_MS) > BLE_GAP_ADV_TIMEOUT_LIMITED_MAX) {
// mp_raise_bleio_BluetoothError(translate("Timeout is too long: Maximum timeout length is %d seconds"),
// UNITS_TO_SEC(BLE_GAP_ADV_TIMEOUT_LIMITED_MAX, UNIT_10_MS));
// }
}
// The advertising data buffers must not move, because the SoftDevice depends on them.
// So make them long-lived and reuse them onwards.
if (self->advertising_data == NULL) {
self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true);
}
if (self->scan_response_data == NULL) {
self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true);
}
//FIX GET CORRECT SIZE
// if (self->advertising_data == NULL) {
// self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true);
// }
// if (self->scan_response_data == NULL) {
// self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true);
// }
memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
@ -690,7 +690,7 @@ 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) {
bonding_erase_storage();
//FIX bonding_erase_storage();
}
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {

View File

@ -52,15 +52,15 @@ typedef struct {
bleio_scanresults_obj_t* scan_results;
mp_obj_t name;
mp_obj_tuple_t *connection_objs;
mcu_pin_obj_t* tx;
mcu_pin_obj_t* rx;
mcu_pin_obj_t* rts;
mcu_pin_obj_t* cts;
const mcu_pin_obj_t* tx;
const mcu_pin_obj_t* rx;
const mcu_pin_obj_t* rts;
const mcu_pin_obj_t* cts;
uint32_t baudrate;
uint16_t buffer_size;
mcu_pin_obj_t* spi_cs;
mcu_pin_obj_t* gpio0;
mcu_pin_obj_t* reset;
const mcu_pin_obj_t* spi_cs;
const mcu_pin_obj_t* gpio0;
const mcu_pin_obj_t* reset;
bool reset_high;
busio_uart_obj_t hci_uart;
digitalio_digitalinout_obj_t rts_digitalio;

View File

@ -27,34 +27,34 @@
#include "shared-bindings/_bleio/Attribute.h"
// Convert a _bleio security mode to a ble_gap_conn_sec_mode_t setting.
void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) {
switch (security_mode) {
case SECURITY_MODE_NO_ACCESS:
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm);
break;
// void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) {
// switch (security_mode) {
// case SECURITY_MODE_NO_ACCESS:
// BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm);
// break;
case SECURITY_MODE_OPEN:
BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm);
break;
// case SECURITY_MODE_OPEN:
// BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm);
// break;
case SECURITY_MODE_ENC_NO_MITM:
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm);
break;
// case SECURITY_MODE_ENC_NO_MITM:
// BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm);
// break;
case SECURITY_MODE_ENC_WITH_MITM:
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm);
break;
// case SECURITY_MODE_ENC_WITH_MITM:
// BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm);
// break;
case SECURITY_MODE_LESC_ENC_WITH_MITM:
BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm);
break;
// case SECURITY_MODE_LESC_ENC_WITH_MITM:
// BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm);
// break;
case SECURITY_MODE_SIGNED_NO_MITM:
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm);
break;
// case SECURITY_MODE_SIGNED_NO_MITM:
// BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm);
// break;
case SECURITY_MODE_SIGNED_WITH_MITM:
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm);
break;
}
}
// case SECURITY_MODE_SIGNED_WITH_MITM:
// BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm);
// break;
// }
// }

View File

@ -29,6 +29,13 @@
#include "shared-module/_bleio/Attribute.h"
extern void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode);
// typedef struct
// {
// uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
// uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
// } 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);
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H

View File

@ -33,70 +33,70 @@
#include "shared-bindings/_bleio/Service.h"
#include "common-hal/_bleio/Adapter.h"
#include "common-hal/_bleio/bonding.h"
STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
uint16_t cccd;
ble_gatts_value_t value = {
.p_value = (uint8_t*) &cccd,
.len = 2,
};
// STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
// uint16_t cccd;
// // ble_gatts_value_t value = {
// // .p_value = (uint8_t*) &cccd,
// // .len = 2,
// // };
const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value);
// // const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value);
if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
// CCCD is not set, so say that neither Notify nor Indicate is enabled.
cccd = 0;
} else {
check_nrf_error(err_code);
}
// // if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
// // // CCCD is not set, so say that neither Notify nor Indicate is enabled.
// // cccd = 0;
// // } else {
// // check_nrf_error(err_code);
// // }
return cccd;
}
// return cccd;
// }
STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
uint16_t hvx_len = bufinfo->len;
// STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
// uint16_t hvx_len = bufinfo->len;
ble_gatts_hvx_params_t hvx_params = {
.handle = handle,
.type = hvx_type,
.offset = 0,
.p_len = &hvx_len,
.p_data = bufinfo->buf,
};
// ble_gatts_hvx_params_t hvx_params = {
// .handle = handle,
// .type = hvx_type,
// .offset = 0,
// .p_len = &hvx_len,
// .p_data = bufinfo->buf,
// };
while (1) {
const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
if (err_code == NRF_SUCCESS) {
break;
}
// TX buffer is full
// We could wait for an event indicating the write is complete, but just retrying is easier.
if (err_code == NRF_ERROR_RESOURCES) {
RUN_BACKGROUND_TASKS;
continue;
}
// while (1) {
// const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
// if (err_code == NRF_SUCCESS) {
// break;
// }
// // TX buffer is full
// // We could wait for an event indicating the write is complete, but just retrying is easier.
// if (err_code == NRF_ERROR_RESOURCES) {
// RUN_BACKGROUND_TASKS;
// continue;
// }
// Some real error has occurred.
check_nrf_error(err_code);
}
}
// // Some real error has occurred.
// check_nrf_error(err_code);
// }
// }
void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
self->service = service;
self->uuid = uuid;
self->handle = BLE_GATT_HANDLE_INVALID;
//FIX self->handle = BLE_GATT_HANDLE_INVALID;
self->props = props;
self->read_perm = read_perm;
self->write_perm = write_perm;
self->descriptor_list = NULL;
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) {
mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
max_length_max, fixed_length ? "True" : "False");
}
//FIX
// 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) {
// 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->fixed_length = fixed_length;
@ -159,25 +159,26 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
uint16_t conn_handle = connection->conn_handle;
if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
if (conn_handle == BLE_CONN_HANDLE_INVALID) {
continue;
}
uint16_t cccd = 0;
//FIX
// uint16_t cccd = 0;
const bool notify = self->props & CHAR_PROP_NOTIFY;
const bool indicate = self->props & CHAR_PROP_INDICATE;
if (notify | indicate) {
cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
}
// const bool notify = self->props & CHAR_PROP_NOTIFY;
// const bool indicate = self->props & CHAR_PROP_INDICATE;
// if (notify | indicate) {
// cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
// }
// It's possible that both notify and indicate are set.
if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
}
if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
}
// // It's possible that both notify and indicate are set.
// if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
// characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
// }
// if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
// characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
// }
}
}
}
@ -192,34 +193,35 @@ bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties
}
void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor) {
ble_uuid_t desc_uuid;
bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid);
//FIX
// ble_uuid_t desc_uuid;
// bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid);
ble_gatts_attr_md_t desc_attr_md = {
// Data passed is not in a permanent location and should be copied.
.vloc = BLE_GATTS_VLOC_STACK,
.vlen = !descriptor->fixed_length,
};
// ble_gatts_attr_md_t desc_attr_md = {
// // Data passed is not in a permanent location and should be copied.
// .vloc = BLE_GATTS_VLOC_STACK,
// .vlen = !descriptor->fixed_length,
// };
bleio_attribute_gatts_set_security_mode(&desc_attr_md.read_perm, descriptor->read_perm);
bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm);
// bleio_attribute_gatts_set_security_mode(&desc_attr_md.read_perm, descriptor->read_perm);
// bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm);
mp_buffer_info_t desc_value_bufinfo;
mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ);
// mp_buffer_info_t desc_value_bufinfo;
// mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ);
ble_gatts_attr_t desc_attr = {
.p_uuid = &desc_uuid,
.p_attr_md = &desc_attr_md,
.init_len = desc_value_bufinfo.len,
.p_value = desc_value_bufinfo.buf,
.init_offs = 0,
.max_len = descriptor->max_length,
};
// ble_gatts_attr_t desc_attr = {
// .p_uuid = &desc_uuid,
// .p_attr_md = &desc_attr_md,
// .init_len = desc_value_bufinfo.len,
// .p_value = desc_value_bufinfo.buf,
// .init_offs = 0,
// .max_len = descriptor->max_length,
// };
check_nrf_error(sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle));
// check_nrf_error(sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle));
descriptor->next = self->descriptor_list;
self->descriptor_list = descriptor;
// descriptor->next = self->descriptor_list;
// self->descriptor_list = descriptor;
}
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
@ -234,33 +236,34 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
common_hal_bleio_check_connected(conn_handle);
uint16_t cccd_value =
(notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
(indicate ? BLE_GATT_HVX_INDICATION : 0);
//FIX
// uint16_t cccd_value =
// (notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
// (indicate ? BLE_GATT_HVX_INDICATION : 0);
ble_gattc_write_params_t write_params = {
.write_op = BLE_GATT_OP_WRITE_REQ,
.handle = self->cccd_handle,
.p_value = (uint8_t *) &cccd_value,
.len = 2,
};
// ble_gattc_write_params_t write_params = {
// .write_op = BLE_GATT_OP_WRITE_REQ,
// .handle = self->cccd_handle,
// .p_value = (uint8_t *) &cccd_value,
// .len = 2,
// };
while (1) {
uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
if (err_code == NRF_SUCCESS) {
break;
}
// while (1) {
// uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
// if (err_code == NRF_SUCCESS) {
// break;
// }
// Write with response will return NRF_ERROR_BUSY if the response has not been received.
// Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
// We could wait for an event indicating the write is complete, but just retrying is easier.
RUN_BACKGROUND_TASKS;
continue;
}
// // Write with response will return NRF_ERROR_BUSY if the response has not been received.
// // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
// if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
// // We could wait for an event indicating the write is complete, but just retrying is easier.
// RUN_BACKGROUND_TASKS;
// continue;
// }
// Some real error occurred.
check_nrf_error(err_code);
}
// // Some real error occurred.
// check_nrf_error(err_code);
// }
}

View File

@ -37,44 +37,44 @@
#include "common-hal/_bleio/CharacteristicBuffer.h"
// Push all the data onto the ring buffer. When the buffer is full, new bytes will be dropped.
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
ringbuf_put_n(&self->ringbuf, data, len);
sd_nvic_critical_region_exit(is_nested_critical_region);
}
// STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
// uint8_t is_nested_critical_region;
// sd_nvic_critical_region_enter(&is_nested_critical_region);
// ringbuf_put_n(&self->ringbuf, data, len);
// sd_nvic_critical_region_exit(is_nested_critical_region);
// }
STATIC bool characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
// A client wrote to this server characteristic.
// STATIC bool characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
// bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param;
// switch (ble_evt->header.evt_id) {
// case BLE_GATTS_EVT_WRITE: {
// // A client wrote to this server characteristic.
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
// Event handle must match the handle for my characteristic.
if (evt_write->handle == self->characteristic->handle) {
write_to_ringbuf(self, evt_write->data, evt_write->len);
}
break;
}
// ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
// // Event handle must match the handle for my characteristic.
// if (evt_write->handle == self->characteristic->handle) {
// write_to_ringbuf(self, evt_write->data, evt_write->len);
// }
// break;
// }
case BLE_GATTC_EVT_HVX: {
// A remote service wrote to this characteristic.
// case BLE_GATTC_EVT_HVX: {
// // A remote service wrote to this characteristic.
ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
// Must be a notification, and event handle must match the handle for my characteristic.
if (evt_hvx->type == BLE_GATT_HVX_NOTIFICATION &&
evt_hvx->handle == self->characteristic->handle) {
write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
}
break;
}
default:
return false;
break;
}
return true;
}
// ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
// // Must be a notification, and event handle must match the handle for my characteristic.
// if (evt_hvx->type == BLE_GATT_HVX_NOTIFICATION &&
// evt_hvx->handle == self->characteristic->handle) {
// write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
// }
// break;
// }
// default:
// return false;
// break;
// }
// return true;
// }
// Assumes that timeout and buffer_size have been validated before call.
void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self,
@ -88,7 +88,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
// true means long-lived, so it won't be moved.
ringbuf_alloc(&self->ringbuf, buffer_size, true);
ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self);
// FIX ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self);
}
@ -105,31 +105,31 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
}
// Copy received data. Lock out write interrupt handler while copying.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// FIX uint8_t is_nested_critical_region;
// FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len);
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
// FIX sd_nvic_critical_region_exit(is_nested_critical_region);
return num_bytes_read;
}
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
//FIX uint8_t is_nested_critical_region;
//FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
uint16_t count = ringbuf_num_filled(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
//FIX sd_nvic_critical_region_exit(is_nested_critical_region);
return count;
}
void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) {
// prevent conflict with uart irq
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
//FIX uint8_t is_nested_critical_region;
//FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
ringbuf_clear(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
//FIX sd_nvic_critical_region_exit(is_nested_critical_region);
}
bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) {
@ -138,7 +138,7 @@ bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer
void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self);
//FIX ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,6 @@
#include "py/objlist.h"
#include "common-hal/_bleio/__init__.h"
#include "common-hal/_bleio/bonding.h"
#include "shared-module/_bleio/Address.h"
#include "common-hal/_bleio/Service.h"

View File

@ -36,151 +36,152 @@
#include "shared-bindings/_bleio/PacketBuffer.h"
#include "supervisor/shared/tick.h"
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
// This shouldn't happen.
return;
}
// Push all the data onto the ring buffer.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// Make room for the new value by dropping the oldest packets first.
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) {
ringbuf_get(&self->ringbuf);
}
// set an overflow flag?
}
ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t));
ringbuf_put_n(&self->ringbuf, data, len);
sd_nvic_critical_region_exit(is_nested_critical_region);
}
// STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
// if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
// // This shouldn't happen.
// return;
// }
// // Push all the data onto the ring buffer.
// //FIX uint8_t is_nested_critical_region;
// //FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
// // Make room for the new value by dropping the oldest packets first.
// while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
// uint16_t packet_length;
// ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
// for (uint16_t i = 0; i < packet_length; i++) {
// ringbuf_get(&self->ringbuf);
// }
// // set an overflow flag?
// }
// ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t));
// ringbuf_put_n(&self->ringbuf, data, len);
// //FIX sd_nvic_critical_region_exit(is_nested_critical_region);
// }
STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
// Queue up the next outgoing buffer. We use two, one that has been passed to the SD for
// transmission (when packet_queued is true) and the other is `pending` and can still be
// modified. By primarily appending to the `pending` buffer we can reduce the protocol overhead
// of the lower level link and ATT layers.
self->packet_queued = false;
if (self->pending_size > 0) {
uint16_t conn_handle = self->conn_handle;
uint32_t err_code;
if (self->client) {
ble_gattc_write_params_t write_params = {
.write_op = self->write_type,
.handle = self->characteristic->handle,
.p_value = self->outgoing[self->pending_index],
.len = self->pending_size,
};
//FIX
// STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
// // Queue up the next outgoing buffer. We use two, one that has been passed to the SD for
// // transmission (when packet_queued is true) and the other is `pending` and can still be
// // modified. By primarily appending to the `pending` buffer we can reduce the protocol overhead
// // of the lower level link and ATT layers.
// self->packet_queued = false;
// if (self->pending_size > 0) {
// uint16_t conn_handle = self->conn_handle;
// uint32_t err_code;
// if (self->client) {
// ble_gattc_write_params_t write_params = {
// .write_op = self->write_type,
// .handle = self->characteristic->handle,
// .p_value = self->outgoing[self->pending_index],
// .len = self->pending_size,
// };
err_code = sd_ble_gattc_write(conn_handle, &write_params);
} else {
uint16_t hvx_len = self->pending_size;
// err_code = sd_ble_gattc_write(conn_handle, &write_params);
// } else {
// uint16_t hvx_len = self->pending_size;
ble_gatts_hvx_params_t hvx_params = {
.handle = self->characteristic->handle,
.type = self->write_type,
.offset = 0,
.p_len = &hvx_len,
.p_data = self->outgoing[self->pending_index],
};
err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
}
if (err_code != NRF_SUCCESS) {
// On error, simply skip updating the pending buffers so that the next HVC or WRITE
// complete event triggers another attempt.
return err_code;
}
self->pending_size = 0;
self->pending_index = (self->pending_index + 1) % 2;
self->packet_queued = true;
}
return NRF_SUCCESS;
}
// ble_gatts_hvx_params_t hvx_params = {
// .handle = self->characteristic->handle,
// .type = self->write_type,
// .offset = 0,
// .p_len = &hvx_len,
// .p_data = self->outgoing[self->pending_index],
// };
// err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
// }
// if (err_code != NRF_SUCCESS) {
// // On error, simply skip updating the pending buffers so that the next HVC or WRITE
// // complete event triggers another attempt.
// return err_code;
// }
// self->pending_size = 0;
// self->pending_index = (self->pending_index + 1) % 2;
// self->packet_queued = true;
// }
// return NRF_SUCCESS;
// }
STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
const uint16_t evt_id = ble_evt->header.evt_id;
// Check if this is a GATTC event so we can make sure the conn_handle is valid.
if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST) {
return false;
}
// STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
// const uint16_t evt_id = ble_evt->header.evt_id;
// // Check if this is a GATTC event so we can make sure the conn_handle is valid.
// if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST) {
// return false;
// }
uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
if (conn_handle != self->conn_handle) {
return false;
}
switch (evt_id) {
case BLE_GATTC_EVT_HVX: {
// A remote service wrote to this characteristic.
ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
// Must be a notification, and event handle must match the handle for my characteristic.
if (evt_hvx->handle == self->characteristic->handle) {
write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
if (evt_hvx->type == BLE_GATT_HVX_INDICATION) {
sd_ble_gattc_hv_confirm(conn_handle, evt_hvx->handle);
}
}
break;
}
case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: {
queue_next_write(self);
break;
}
case BLE_GATTC_EVT_WRITE_RSP: {
queue_next_write(self);
break;
}
default:
return false;
break;
}
return true;
}
// uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
// bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
// if (conn_handle != self->conn_handle) {
// return false;
// }
// switch (evt_id) {
// case BLE_GATTC_EVT_HVX: {
// // A remote service wrote to this characteristic.
// ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
// // Must be a notification, and event handle must match the handle for my characteristic.
// if (evt_hvx->handle == self->characteristic->handle) {
// write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
// if (evt_hvx->type == BLE_GATT_HVX_INDICATION) {
// sd_ble_gattc_hv_confirm(conn_handle, evt_hvx->handle);
// }
// }
// break;
// }
// case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: {
// queue_next_write(self);
// break;
// }
// case BLE_GATTC_EVT_WRITE_RSP: {
// queue_next_write(self);
// break;
// }
// default:
// return false;
// break;
// }
// return true;
// }
STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
// A client wrote to this server characteristic.
// STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
// bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
// switch (ble_evt->header.evt_id) {
// case BLE_GATTS_EVT_WRITE: {
// uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
// // A client wrote to this server characteristic.
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
// ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
// Event handle must match the handle for my characteristic.
if (evt_write->handle == self->characteristic->handle) {
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
self->conn_handle = conn_handle;
} else if (self->conn_handle != conn_handle) {
return false;
}
write_to_ringbuf(self, evt_write->data, evt_write->len);
} else if (evt_write->handle == self->characteristic->cccd_handle) {
uint16_t cccd = *((uint16_t*) evt_write->data);
if (cccd & BLE_GATT_HVX_NOTIFICATION) {
self->conn_handle = conn_handle;
} else {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
break;
}
case BLE_GAP_EVT_DISCONNECTED: {
if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
case BLE_GATTS_EVT_HVN_TX_COMPLETE: {
queue_next_write(self);
}
default:
return false;
break;
}
return true;
}
// // Event handle must match the handle for my characteristic.
// if (evt_write->handle == self->characteristic->handle) {
// if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
// self->conn_handle = conn_handle;
// } else if (self->conn_handle != conn_handle) {
// return false;
// }
// write_to_ringbuf(self, evt_write->data, evt_write->len);
// } else if (evt_write->handle == self->characteristic->cccd_handle) {
// uint16_t cccd = *((uint16_t*) evt_write->data);
// if (cccd & BLE_GATT_HVX_NOTIFICATION) {
// self->conn_handle = conn_handle;
// } else {
// self->conn_handle = BLE_CONN_HANDLE_INVALID;
// }
// }
// break;
// }
// case BLE_GAP_EVT_DISCONNECTED: {
// if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
// self->conn_handle = BLE_CONN_HANDLE_INVALID;
// }
// }
// case BLE_GATTS_EVT_HVN_TX_COMPLETE: {
// queue_next_write(self);
// }
// default:
// return false;
// break;
// }
// return true;
// }
void common_hal_bleio_packet_buffer_construct(
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
@ -218,32 +219,32 @@ void common_hal_bleio_packet_buffer_construct(
self->outgoing[1] = NULL;
}
if (self->client) {
ble_drv_add_event_handler(packet_buffer_on_ble_client_evt, self);
if (incoming) {
// Prefer notify if both are available.
if (incoming & CHAR_PROP_NOTIFY) {
self->write_type = BLE_GATT_HVX_NOTIFICATION;
common_hal_bleio_characteristic_set_cccd(self->characteristic, true, false);
} else {
common_hal_bleio_characteristic_set_cccd(self->characteristic, false, true);
}
}
if (outgoing) {
self->write_type = BLE_GATT_OP_WRITE_REQ;
if (outgoing & CHAR_PROP_WRITE_NO_RESPONSE) {
self->write_type = BLE_GATT_OP_WRITE_CMD;
}
}
} else {
ble_drv_add_event_handler(packet_buffer_on_ble_server_evt, self);
if (outgoing) {
self->write_type = BLE_GATT_HVX_INDICATION;
if (outgoing & CHAR_PROP_NOTIFY) {
self->write_type = BLE_GATT_HVX_NOTIFICATION;
}
}
}
//FIX if (self->client) {
// ble_drv_add_event_handler(packet_buffer_on_ble_client_evt, self);
// if (incoming) {
// // Prefer notify if both are available.
// if (incoming & CHAR_PROP_NOTIFY) {
// self->write_type = BLE_GATT_HVX_NOTIFICATION;
// common_hal_bleio_characteristic_set_cccd(self->characteristic, true, false);
// } else {
// common_hal_bleio_characteristic_set_cccd(self->characteristic, false, true);
// }
// }
// if (outgoing) {
// self->write_type = BLE_GATT_OP_WRITE_REQ;
// if (outgoing & CHAR_PROP_WRITE_NO_RESPONSE) {
// self->write_type = BLE_GATT_OP_WRITE_CMD;
// }
// }
// } else {
// ble_drv_add_event_handler(packet_buffer_on_ble_server_evt, self);
// if (outgoing) {
// self->write_type = BLE_GATT_HVX_INDICATION;
// if (outgoing & CHAR_PROP_NOTIFY) {
// self->write_type = BLE_GATT_HVX_NOTIFICATION;
// }
// }
// }
}
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
@ -252,8 +253,8 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
}
// Copy received data. Lock out write interrupt handler while copying.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
//FIX uint8_t is_nested_critical_region;
//FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
// Get packet length, which is in first two bytes of packet.
uint16_t packet_length;
@ -274,7 +275,7 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
}
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
//FIX sd_nvic_critical_region_exit(is_nested_critical_region);
return ret;
}
@ -306,8 +307,8 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, u
size_t num_bytes_written = 0;
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
//FIX uint8_t is_nested_critical_region;
//FIX sd_nvic_critical_region_enter(&is_nested_critical_region);
uint8_t* pending = self->outgoing[self->pending_index];
@ -320,11 +321,11 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, u
self->pending_size += len;
num_bytes_written += len;
sd_nvic_critical_region_exit(is_nested_critical_region);
//FIX sd_nvic_critical_region_exit(is_nested_critical_region);
// If no writes are queued then sneak in this data.
if (!self->packet_queued) {
queue_next_write(self);
//FIX queue_next_write(self);
}
return num_bytes_written;
}
@ -397,6 +398,6 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
if (!common_hal_bleio_packet_buffer_deinited(self)) {
ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self);
//FIX ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self);
}
}

View File

@ -40,22 +40,24 @@ uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uu
self->connection = NULL;
self->is_secondary = is_secondary;
ble_uuid_t nordic_uuid;
bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nordic_uuid);
//FIX
// ble_uuid_t nordic_uuid;
// bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nordic_uuid);
uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
if (is_secondary) {
service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
}
// uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
// if (is_secondary) {
// service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
// }
vm_used_ble = true;
return sd_ble_gatts_service_add(service_type, &nordic_uuid, &self->handle);
//FIX return sd_ble_gatts_service_add(service_type, &nordic_uuid, &self->handle);
return 0;
}
void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
check_nrf_error(_common_hal_bleio_service_construct(self, uuid, is_secondary,
mp_obj_new_list(0, NULL)));
//FIX check_nrf_error(_common_hal_bleio_service_construct(self, uuid, is_secondary,
// mp_obj_new_list(0, NULL)));
}
void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection) {
@ -86,62 +88,62 @@ bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
bleio_characteristic_obj_t *characteristic,
mp_buffer_info_t *initial_value_bufinfo) {
ble_gatts_char_md_t char_md = {
.char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0,
.char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0,
.char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0,
.char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0,
.char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0,
.char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0,
};
// ble_gatts_char_md_t char_md = {
// .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0,
// .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0,
// .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0,
// .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0,
// .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0,
// .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0,
// };
ble_gatts_attr_md_t cccd_md = {
.vloc = BLE_GATTS_VLOC_STACK,
};
// ble_gatts_attr_md_t cccd_md = {
// .vloc = BLE_GATTS_VLOC_STACK,
// };
ble_uuid_t char_uuid;
bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid);
// ble_uuid_t char_uuid;
// bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid);
ble_gatts_attr_md_t char_attr_md = {
.vloc = BLE_GATTS_VLOC_STACK,
.vlen = !characteristic->fixed_length,
};
// ble_gatts_attr_md_t char_attr_md = {
// .vloc = BLE_GATTS_VLOC_STACK,
// .vlen = !characteristic->fixed_length,
// };
if (char_md.char_props.notify || char_md.char_props.indicate) {
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
// Make CCCD write permission match characteristic read permission.
bleio_attribute_gatts_set_security_mode(&cccd_md.write_perm, characteristic->read_perm);
// if (char_md.char_props.notify || char_md.char_props.indicate) {
// BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
// // Make CCCD write permission match characteristic read permission.
// bleio_attribute_gatts_set_security_mode(&cccd_md.write_perm, characteristic->read_perm);
char_md.p_cccd_md = &cccd_md;
}
// char_md.p_cccd_md = &cccd_md;
// }
bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm);
bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm);
#if CIRCUITPY_VERBOSE_BLE
// Turn on read authorization so that we receive an event to print on every read.
char_attr_md.rd_auth = true;
#endif
// bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm);
// bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm);
// #if CIRCUITPY_VERBOSE_BLE
// // Turn on read authorization so that we receive an event to print on every read.
// char_attr_md.rd_auth = true;
// #endif
ble_gatts_attr_t char_attr = {
.p_uuid = &char_uuid,
.p_attr_md = &char_attr_md,
.init_len = 0,
.p_value = NULL,
.init_offs = 0,
.max_len = characteristic->max_length,
};
// ble_gatts_attr_t char_attr = {
// .p_uuid = &char_uuid,
// .p_attr_md = &char_attr_md,
// .init_len = 0,
// .p_value = NULL,
// .init_offs = 0,
// .max_len = characteristic->max_length,
// };
ble_gatts_char_handles_t char_handles;
// ble_gatts_char_handles_t char_handles;
check_nrf_error(sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles));
// check_nrf_error(sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles));
characteristic->user_desc_handle = char_handles.user_desc_handle;
characteristic->cccd_handle = char_handles.cccd_handle;
characteristic->sccd_handle = char_handles.sccd_handle;
characteristic->handle = char_handles.value_handle;
#if CIRCUITPY_VERBOSE_BLE
mp_printf(&mp_plat_print, "Char handle %x user %x cccd %x sccd %x\n", characteristic->handle, characteristic->user_desc_handle, characteristic->cccd_handle, characteristic->sccd_handle);
#endif
// characteristic->user_desc_handle = char_handles.user_desc_handle;
// characteristic->cccd_handle = char_handles.cccd_handle;
// characteristic->sccd_handle = char_handles.sccd_handle;
// characteristic->handle = char_handles.value_handle;
// #if CIRCUITPY_VERBOSE_BLE
// mp_printf(&mp_plat_print, "Char handle %x user %x cccd %x sccd %x\n", characteristic->handle, characteristic->user_desc_handle, characteristic->cccd_handle, characteristic->sccd_handle);
// #endif
mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
// mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
}

View File

@ -37,35 +37,36 @@
// 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.
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
self->nrf_ble_uuid.uuid = uuid16;
if (uuid128 == NULL) {
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
} else {
ble_uuid128_t vs_uuid;
memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128));
//FIX self->nrf_ble_uuid.uuid = uuid16;
// if (uuid128 == NULL) {
// self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
// } else {
// ble_uuid128_t vs_uuid;
// memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128));
// Register this vendor-specific UUID. Bytes 12 and 13 will be zero.
check_nrf_error(sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type));
vm_used_ble = true;
}
// // Register this vendor-specific UUID. Bytes 12 and 13 will be zero.
// 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) {
// return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 16 : 128;
//FIX return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 16 : 128;
return 0;
}
uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
// return self->nrf_ble_uuid.uuid;
//FIX return self->nrf_ble_uuid.uuid;
return 0;
}
void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
uint8_t length;
// check_nrf_error(sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128));
//FIX uint8_t length;
//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) {
// if (self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE) {
//FIX if (self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE) {
// buf[0] = self->nrf_ble_uuid.uuid & 0xff;
// buf[1] = self->nrf_ble_uuid.uuid >> 8;
// } else {
@ -73,6 +74,7 @@ void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* 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"));

View File

@ -33,7 +33,7 @@
typedef struct {
mp_obj_base_t base;
// Use the native way of storing UUID's:
//FIX Use the native way of storing UUID's:
// - ble_uuid_t.uuid is a 16-bit uuid.
// - ble_uuid_t.type is BLE_UUID_TYPE_BLE if it's a 16-bit Bluetooth SIG UUID.
// or is BLE_UUID_TYPE_VENDOR_BEGIN and higher, which indexes into a table of registered

View File

@ -40,52 +40,53 @@
#include "common-hal/_bleio/__init__.h"
void check_nrf_error(uint32_t err_code) {
if (err_code == NRF_SUCCESS) {
return;
}
switch (err_code) {
case NRF_ERROR_TIMEOUT:
mp_raise_msg(&mp_type_TimeoutError, NULL);
return;
case BLE_ERROR_INVALID_CONN_HANDLE:
mp_raise_bleio_ConnectionError(translate("Not connected"));
return;
default:
mp_raise_bleio_BluetoothError(translate("Unknown soft device error: %04x"), err_code);
break;
}
}
//FIX to check HCI error
// void check_nrf_error(uint32_t err_code) {
// if (err_code == NRF_SUCCESS) {
// return;
// }
// switch (err_code) {
// case NRF_ERROR_TIMEOUT:
// mp_raise_msg(&mp_type_TimeoutError, NULL);
// return;
// case BLE_ERROR_INVALID_CONN_HANDLE:
// mp_raise_bleio_ConnectionError(translate("Not connected"));
// return;
// default:
// mp_raise_bleio_BluetoothError(translate("Unknown soft device error: %04x"), err_code);
// break;
// }
// }
void check_gatt_status(uint16_t gatt_status) {
if (gatt_status == BLE_GATT_STATUS_SUCCESS) {
return;
}
switch (gatt_status) {
case BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION:
mp_raise_bleio_SecurityError(translate("Insufficient authentication"));
return;
case BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION:
mp_raise_bleio_SecurityError(translate("Insufficient encryption"));
return;
default:
mp_raise_bleio_BluetoothError(translate("Unknown gatt error: 0x%04x"), gatt_status);
}
}
// void check_gatt_status(uint16_t gatt_status) {
// if (gatt_status == BLE_GATT_STATUS_SUCCESS) {
// return;
// }
// switch (gatt_status) {
// case BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION:
// mp_raise_bleio_SecurityError(translate("Insufficient authentication"));
// return;
// case BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION:
// mp_raise_bleio_SecurityError(translate("Insufficient encryption"));
// return;
// default:
// mp_raise_bleio_BluetoothError(translate("Unknown gatt error: 0x%04x"), gatt_status);
// }
// }
void check_sec_status(uint8_t sec_status) {
if (sec_status == BLE_GAP_SEC_STATUS_SUCCESS) {
return;
}
// void check_sec_status(uint8_t sec_status) {
// if (sec_status == BLE_GAP_SEC_STATUS_SUCCESS) {
// return;
// }
switch (sec_status) {
case BLE_GAP_SEC_STATUS_UNSPECIFIED:
mp_raise_bleio_SecurityError(translate("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored."));
return;
default:
mp_raise_bleio_SecurityError(translate("Unknown security error: 0x%04x"), sec_status);
}
}
// switch (sec_status) {
// case BLE_GAP_SEC_STATUS_UNSPECIFIED:
// mp_raise_bleio_SecurityError(translate("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored."));
// return;
// default:
// mp_raise_bleio_SecurityError(translate("Unknown security error: 0x%04x"), sec_status);
// }
// }
// Turn off BLE on a reset or reload.
void bleio_reset() {
@ -98,7 +99,7 @@ void bleio_reset() {
return;
}
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
bonding_reset();
//FIX bonding_reset();
supervisor_start_bluetooth();
}
@ -121,124 +122,127 @@ size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = buf,
.len = len,
};
//FIX ble_gatts_value_t gatts_value = {
// .p_value = buf,
// .len = len,
// };
check_nrf_error(sd_ble_gatts_value_get(conn_handle, handle, &gatts_value));
// check_nrf_error(sd_ble_gatts_value_get(conn_handle, handle, &gatts_value));
return gatts_value.len;
// return gatts_value.len;
return 0;
}
void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = bufinfo->buf,
.len = bufinfo->len,
};
//FIX ble_gatts_value_t gatts_value = {
// .p_value = bufinfo->buf,
// .len = bufinfo->len,
// };
check_nrf_error(sd_ble_gatts_value_set(conn_handle, handle, &gatts_value));
// check_nrf_error(sd_ble_gatts_value_set(conn_handle, handle, &gatts_value));
}
typedef struct {
uint8_t* buf;
size_t len;
size_t final_len;
uint16_t conn_handle;
volatile uint16_t status;
volatile bool done;
} read_info_t;
//FIX
// typedef struct {
// uint8_t* buf;
// size_t len;
// size_t final_len;
// uint16_t conn_handle;
// volatile uint16_t status;
// volatile bool done;
// } read_info_t;
STATIC bool _on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
read_info_t* read = param;
switch (ble_evt->header.evt_id) {
// STATIC bool _on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
// read_info_t* read = param;
// switch (ble_evt->header.evt_id) {
// More events may be handled later, so keep this as a switch.
// // More events may be handled later, so keep this as a switch.
case BLE_GATTC_EVT_READ_RSP: {
ble_gattc_evt_t* evt = &ble_evt->evt.gattc_evt;
ble_gattc_evt_read_rsp_t *response = &evt->params.read_rsp;
if (read && evt->conn_handle == read->conn_handle) {
read->status = evt->gatt_status;
size_t len = MIN(read->len, response->len);
memcpy(read->buf, response->data, len);
read->final_len = len;
// Indicate to busy-wait loop that we've read the attribute value.
read->done = true;
}
break;
}
// case BLE_GATTC_EVT_READ_RSP: {
// ble_gattc_evt_t* evt = &ble_evt->evt.gattc_evt;
// ble_gattc_evt_read_rsp_t *response = &evt->params.read_rsp;
// if (read && evt->conn_handle == read->conn_handle) {
// read->status = evt->gatt_status;
// size_t len = MIN(read->len, response->len);
// memcpy(read->buf, response->data, len);
// read->final_len = len;
// // Indicate to busy-wait loop that we've read the attribute value.
// read->done = true;
// }
// break;
// }
default:
// For debugging.
// mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
return false;
break;
}
return true;
}
// default:
// // For debugging.
// // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
// return false;
// break;
// }
// return true;
// }
size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
common_hal_bleio_check_connected(conn_handle);
read_info_t read_info;
read_info.buf = buf;
read_info.len = len;
read_info.final_len = 0;
read_info.conn_handle = conn_handle;
// Set to true by the event handler.
read_info.done = false;
ble_drv_add_event_handler(_on_gattc_read_rsp_evt, &read_info);
//FIX read_info_t read_info;
// read_info.buf = buf;
// read_info.len = len;
// read_info.final_len = 0;
// read_info.conn_handle = conn_handle;
// // Set to true by the event handler.
// read_info.done = false;
// ble_drv_add_event_handler(_on_gattc_read_rsp_evt, &read_info);
uint32_t nrf_error = NRF_ERROR_BUSY;
while (nrf_error == NRF_ERROR_BUSY) {
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
}
if (nrf_error != NRF_SUCCESS) {
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
check_nrf_error(nrf_error);
}
// uint32_t nrf_error = NRF_ERROR_BUSY;
// while (nrf_error == NRF_ERROR_BUSY) {
// nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
// }
// if (nrf_error != NRF_SUCCESS) {
// ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
// check_nrf_error(nrf_error);
// }
while (!read_info.done) {
RUN_BACKGROUND_TASKS;
}
// while (!read_info.done) {
// RUN_BACKGROUND_TASKS;
// }
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
check_gatt_status(read_info.status);
return read_info.final_len;
// ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
// check_gatt_status(read_info.status);
// return read_info.final_len;
return 0;
}
void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) {
common_hal_bleio_check_connected(conn_handle);
ble_gattc_write_params_t write_params = {
.write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ,
.handle = handle,
.p_value = bufinfo->buf,
.len = bufinfo->len,
};
//FIX
// ble_gattc_write_params_t write_params = {
// .write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ,
// .handle = handle,
// .p_value = bufinfo->buf,
// .len = bufinfo->len,
// };
while (1) {
uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
if (err_code == NRF_SUCCESS) {
break;
}
// while (1) {
// uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
// if (err_code == NRF_SUCCESS) {
// break;
// }
// Write with response will return NRF_ERROR_BUSY if the response has not been received.
// Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
// We could wait for an event indicating the write is complete, but just retrying is easier.
MICROPY_VM_HOOK_LOOP;
continue;
}
// Some real error occurred.
check_nrf_error(err_code);
}
// // Write with response will return NRF_ERROR_BUSY if the response has not been received.
// // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
// if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
// // We could wait for an event indicating the write is complete, but just retrying is easier.
// MICROPY_VM_HOOK_LOOP;
// continue;
// }
// // Some real error occurred.
// check_nrf_error(err_code);
// }
}
void common_hal_bleio_gc_collect(void) {

View File

@ -27,6 +27,8 @@
#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
#include <stdbool.h>
void bleio_reset(void);
typedef struct {
@ -39,6 +41,13 @@ typedef struct {
// 20 bytes max (23 - 3).
#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3)
//FIX
#define BLE_GATT_HANDLE_INVALID 0x0000
#define BLE_CONN_HANDLE_INVALID 0xFFFF
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
// These helpers raise the appropriate exceptions if the code doesn't equal success.
void check_nrf_error(uint32_t err_code);
void check_gatt_status(uint16_t gatt_status);

View File

@ -1,306 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 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.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "shared-bindings/nvm/ByteArray.h"
#include "supervisor/shared/tick.h"
#include "bonding.h"
// Internal flash area reserved for bonding storage.
#define BONDING_PAGES_START_ADDR CIRCUITPY_BLE_CONFIG_START_ADDR
#define BONDING_PAGES_END_ADDR (CIRCUITPY_BLE_CONFIG_START_ADDR + CIRCUITPY_BLE_CONFIG_SIZE)
// First and last four bytes are magic bytes for id and version. Data is in between.
// 'BD01'
const uint32_t BONDING_FLAG = ('1' | '0' << 8 | 'D' << 16 | 'B' << 24);
#define BONDING_DATA_START_ADDR (BONDING_PAGES_START_ADDR + sizeof(BONDING_FLAG))
#define BONDING_DATA_END_ADDR (BONDING_PAGES_END_ADDR - sizeof(BONDING_FLAG))
#define BONDING_START_FLAG_ADDR BONDING_PAGES_START_ADDR
#define BONDING_END_FLAG_ADDR BONDING_DATA_END_ADDR
// Save both system and user service info.
#define SYS_ATTR_FLAGS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS)
#if BONDING_DEBUG
void bonding_print_block(bonding_block_t *block) {
printf("at 0x%08lx: is_central: %1d, type: 0x%x, ediv: 0x%04x, data_length: %d\n",
(uint32_t) block, block->is_central, block->type, block->ediv, block->data_length);
}
void bonding_print_keys(bonding_keys_t *keys) {
for (size_t i = 0; i < sizeof(bonding_keys_t); i ++) {
printf("%x", ((uint8_t*) keys)[i]);
}
printf("\n");
}
#endif
STATIC size_t compute_block_size(uint16_t data_length) {
// Round data size up to the nearest 32-bit address.
return sizeof(bonding_block_t) + ((data_length + 3) & ~0x3);
}
void bonding_erase_storage(void) {
// Erase all pages in the bonding area.
for(uint32_t page_address = BONDING_PAGES_START_ADDR;
page_address < BONDING_PAGES_END_ADDR;
page_address += FLASH_PAGE_SIZE) {
// Argument is page number, not address.
sd_flash_page_erase_sync(page_address / FLASH_PAGE_SIZE);
}
// Write marker words at the beginning and the end of the bonding area.
uint32_t flag = BONDING_FLAG;
sd_flash_write_sync((uint32_t *) BONDING_START_FLAG_ADDR, &flag, 1);
sd_flash_write_sync((uint32_t *) BONDING_END_FLAG_ADDR, &flag, 1);
}
// Given NULL to start or block address, return the address of the next valid block.
// The last block returned is the unused block at the end.
// Return NULL if we have run off the end of the bonding space.
STATIC bonding_block_t *next_block(bonding_block_t *block) {
while (1) {
// Advance to next block.
if (block == NULL) {
return (bonding_block_t *) BONDING_DATA_START_ADDR;
} else if (block->type == BLOCK_UNUSED) {
// Already at last block (the unused block).
return NULL;
}
// Advance to next block.
block = (bonding_block_t *) ((uint8_t *) block + compute_block_size(block->data_length));
if (block >= (bonding_block_t *) BONDING_DATA_END_ADDR) {
// Went past end of bonding space.
return NULL;
}
if (block->type != BLOCK_INVALID) {
// Found an empty or a valid block.
return block;
}
// Invalid block (was erased); try again.
}
}
// Find the block with given is_central, type and ediv value.
// If type == BLOCK_UNUSED, ediv is ignored and the the sole unused block at the end is returned.
// If not found, return NULL.
STATIC bonding_block_t *find_existing_block(bool is_central, bonding_block_type_t type, uint16_t ediv) {
bonding_block_t *block = NULL;
while (1) {
block = next_block(block);
if (block == NULL) {
return NULL;
}
// If types match, and block is unused, just return it.
// Otherwise check that is_central and ediv match.
if (type == block->type) {
if (type == BLOCK_UNUSED ||
(is_central == block->is_central && ediv == block->ediv)) {
return block;
}
}
}
}
// Get an empty block large enough to store data_length data.
STATIC bonding_block_t* find_unused_block(uint16_t data_length) {
bonding_block_t *unused_block = find_existing_block(true, BLOCK_UNUSED, EDIV_INVALID);
// If no more room, erase all existing blocks and start over.
if (!unused_block ||
(uint8_t *) unused_block + compute_block_size(data_length) >= (uint8_t *) BONDING_DATA_END_ADDR) {
bonding_erase_storage();
unused_block = (bonding_block_t *) BONDING_DATA_START_ADDR;
}
return unused_block;
}
// Set the header word to all 0's, to mark the block as invalid.
// We don't change data_length, so we can still skip over this block.
STATIC void invalidate_block(bonding_block_t *block) {
uint32_t zero = 0;
sd_flash_write_sync((uint32_t *) block, &zero, 1);
}
// Write bonding block header.
STATIC void write_block_header(bonding_block_t *dest_block, bonding_block_t *source_block_header) {
sd_flash_write_sync((uint32_t *) dest_block, (uint32_t *) source_block_header, sizeof(bonding_block_t) / 4);
}
// Write variable-length data at end of bonding block.
STATIC void write_block_data(bonding_block_t *dest_block, uint8_t *data, uint16_t data_length) {
// Minimize the number of writes. Datasheet says no more than two writes per word before erasing again.
// Start writing after the current header.
uint32_t *flash_word_p = (uint32_t *) ((uint8_t *) dest_block + sizeof(bonding_block_t));
while (1) {
uint32_t word = 0xffffffff;
memcpy(&word, data, data_length >= 4 ? 4 : data_length);
sd_flash_write_sync(flash_word_p, &word, 1);
if (data_length <= 4) {
break;
}
data_length -= 4;
data += 4;
// Increment by word size.
flash_word_p++;
}
}
STATIC void write_sys_attr_block(bleio_connection_internal_t *connection) {
uint16_t length = 0;
// First find out how big a buffer we need, then fetch the data.
if(sd_ble_gatts_sys_attr_get(connection->conn_handle, NULL, &length, SYS_ATTR_FLAGS) != NRF_SUCCESS) {
return;
}
uint8_t sys_attr[length];
if(sd_ble_gatts_sys_attr_get(connection->conn_handle, sys_attr, &length, SYS_ATTR_FLAGS) != NRF_SUCCESS) {
return;
}
// Is there an existing sys_attr block that matches the current sys_attr data?
bonding_block_t *existing_block =
find_existing_block(connection->is_central, BLOCK_SYS_ATTR, connection->ediv);
if (existing_block) {
if (length == existing_block->data_length &&
memcmp(sys_attr, existing_block->data, length) == 0) {
// Identical block found. No need to store again.
return;
}
// Data doesn't match. Invalidate block and store a new one.
invalidate_block(existing_block);
}
bonding_block_t block_header = {
.is_central = connection->is_central,
.type = BLOCK_SYS_ATTR,
.ediv = connection->ediv,
.conn_handle = connection->conn_handle,
.data_length = length,
};
bonding_block_t *new_block = find_unused_block(length);
write_block_header(new_block, &block_header);
write_block_data(new_block, sys_attr, length);
return;
}
STATIC void write_keys_block(bleio_connection_internal_t *connection) {
uint16_t const ediv = connection->is_central
? connection->bonding_keys.peer_enc.master_id.ediv
: connection->bonding_keys.own_enc.master_id.ediv;
// Is there an existing keys block that matches?
bonding_block_t *existing_block = find_existing_block(connection->is_central, BLOCK_KEYS, ediv);
if (existing_block) {
if (existing_block->data_length == sizeof(bonding_keys_t) &&
memcmp(existing_block->data, &connection->bonding_keys, sizeof(bonding_keys_t)) == 0) {
// Identical block found. No need to store again.
return;
}
// Data doesn't match. Invalidate block and store a new one.
invalidate_block(existing_block);
}
bonding_block_t block_header = {
.is_central = connection->is_central,
.type = BLOCK_KEYS,
.ediv = ediv,
.conn_handle = connection->conn_handle,
.data_length = sizeof(bonding_keys_t),
};
bonding_block_t *new_block = find_unused_block(sizeof(bonding_keys_t));
write_block_header(new_block, &block_header);
write_block_data(new_block, (uint8_t *) &connection->bonding_keys, sizeof(bonding_keys_t));
}
void bonding_clear_keys(bonding_keys_t *bonding_keys) {
memset((uint8_t*) bonding_keys, 0, sizeof(bonding_keys_t));
}
void bonding_reset(void) {
if (BONDING_FLAG != *((uint32_t *) BONDING_START_FLAG_ADDR) ||
BONDING_FLAG != *((uint32_t *) BONDING_END_FLAG_ADDR)) {
bonding_erase_storage();
}
}
// Write bonding blocks to flash. Requests have been queued during evt handlers.
void bonding_background(void) {
// A paired connection will request that its keys and CCCD values be stored.
// The CCCD store whenever a CCCD value is written.
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
// Wait at least one second before saving CCCD, to consolidate
// writes that involve multiple CCCDs. For instance, for HID,
// three CCCD's are set in short succession by the HID client.
if (connection->do_bond_cccds) {
uint64_t current_ticks_ms = supervisor_ticks_ms64();
if (current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
write_sys_attr_block(connection);
connection->do_bond_cccds = false;
}
}
if (connection->do_bond_keys) {
write_keys_block(connection);
connection->do_bond_keys = false;
}
}
}
bool bonding_load_cccd_info(bool is_central, uint16_t conn_handle, uint16_t ediv) {
bonding_block_t *block = find_existing_block(is_central, BLOCK_SYS_ATTR, ediv);
if (block == NULL) {
return false;
}
return NRF_SUCCESS ==
sd_ble_gatts_sys_attr_set(conn_handle, block->data, block->data_length, SYS_ATTR_FLAGS);
}
bool bonding_load_keys(bool is_central, uint16_t ediv, bonding_keys_t *bonding_keys) {
bonding_block_t *block = find_existing_block(is_central, BLOCK_KEYS, ediv);
if (block == NULL) {
return false;
}
if (sizeof(bonding_keys_t) != block->data_length) {
// bonding_keys_t is a fixed length, so lengths should match.
return false;
}
memcpy(bonding_keys, block->data, block->data_length);
return true;
}

View File

@ -1,83 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 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.
*/
#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_BONDING_H
#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_BONDING_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "common-hal/_bleio/__init__.h"
#define EDIV_INVALID (0xffff)
#define BONDING_DEBUG (1)
#if BONDING_DEBUG
#define BONDING_DEBUG_PRINTF(...) printf(__VA_ARGS__)
#define BONDING_DEBUG_PRINT_BLOCK(block) bonding_print_block(block)
#define BONDING_DEBUG_PRINT_KEYS(keys) bonding_print_keys(keys)
#else
#define BONDING_DEBUG_PRINTF(...)
#define BONDING_DEBUG_PRINT_BLOCK(block)
#define BONDING_DEBUG_PRINT_KEYS(keys)
#endif
// Bonding data is stored in variable-length blocks consecutively in
// erased flash (all 1's). The blocks are 32-bit aligned, though the
// data may be any number of bytes. We hop through the blocks using
// the size field to find the next block. When we hit a word that is
// all 1's, we have reached the end of the blocks. We can write a new
// block there.
typedef enum {
BLOCK_INVALID = 0, // Ignore this block
BLOCK_KEYS = 1, // Block contains bonding keys.
BLOCK_SYS_ATTR = 2, // Block contains sys_attr values (CCCD settings, etc.).
BLOCK_UNUSED = 0xff, // Initial erased value.
} bonding_block_type_t;
typedef struct {
bool is_central: 1; // 1 if data is for a central role.
uint16_t reserved: 7; // Not currently used
bonding_block_type_t type: 8; // What kind of data is stored in.
uint16_t ediv; // ediv value; used as a lookup key.
uint16_t conn_handle; // Connection handle: used when a BLOCK_SYS_ATTR is queued to write.
// Not used as a key, etc.
uint16_t data_length; // Length of data in bytes, including ediv, not including padding.
// End of block header. 32-bit boundary here.
uint8_t data[]; // Rest of data in the block. Needs to be 32-bit aligned.
// Block is padded to 32-bit alignment.
} bonding_block_t;
void bonding_background(void);
void bonding_erase_storage(void);
void bonding_reset(void);
void bonding_clear_keys(bonding_keys_t *bonding_keys);
bool bonding_load_cccd_info(bool is_central, uint16_t conn_handle, uint16_t ediv);
bool bonding_load_keys(bool is_central, uint16_t ediv, bonding_keys_t *bonding_keys);
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_BONDING_H

View File

@ -317,6 +317,13 @@ SRC_COMMON_HAL_ALL = \
watchdog/WatchDogTimer.c \
watchdog/__init__.c \
ifeq ($(CIRCUITPY_BLEIO_HCI),1)
SRC_C +=\
common_hal/_bleio/hci.c \
endif
SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL))
# These don't have corresponding files in each port but are still located in
@ -463,6 +470,11 @@ $(filter $(SRC_PATTERNS), \
displayio/display_core.c \
)
SRC_COMMON_HAL_INTERNAL = \
$(filter $(SRC_PATTERNS), \
_bleio/ \
)
ifeq ($(INTERNAL_LIBM),1)
SRC_LIBM = \
$(addprefix lib/,\

View File

@ -90,10 +90,10 @@ STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args,
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 115200 } },
{ MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 256 } },
{ MP_QSTR_spi_cs, MP_ARG_KW_ONLY }| MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_gpio0, MP_ARG_KW_ONLY }| MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset, MP_ARG_KW_ONLY }| MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset_high, MP_ARG_KW_ONLY |MP_ARG_BOOL },
{ MP_QSTR_spi_cs, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_gpio0, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset_high, MP_ARG_KW_ONLY | MP_ARG_BOOL },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -108,13 +108,23 @@ STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args,
const mcu_pin_obj_t *reset = validate_obj_is_free_pin(args[ARG_reset].u_obj);
const bool reset_high = args[ARG_reset_high].u_bool;
if (args[ARG_baudrate].u_int <= 0) {
mp_raise_ValueError(translate("baudrate must be > 0"));
}
const uint32_t baudrate = args[ARG_baudrate].u_int;
if (args[ARG_buffer_size].u_int <= 1) {
mp_raise_ValueError(translate("buffer_size must be >= 1"));
}
const uint32_t buffer_size = args[ARG_buffer_size].u_int;
common_hal_bleio_adapter_construct(&common_hal_bleio_adapter_obj, tx, rx, rts, cts,
args[ARG_baudrate], arg[ARG_buffer_size],
baudrate, buffer_size,
spi_cs, gpio0,
reset, reset_high);
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
return MP_OBJ_FROM_PTR(service);
return MP_OBJ_FROM_PTR(&common_hal_bleio_adapter_obj);
}
#endif
//|

View File

@ -37,6 +37,10 @@
const mp_obj_type_t bleio_adapter_type;
#if CIRCUITPY_BLEIO_HCI
void common_hal_bleio_adapter_construct(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size, const mcu_pin_obj_t* spi_cs, const mcu_pin_obj_t* gpio0, const mcu_pin_obj_t *reset, bool reset_high);
#endif
extern bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);