diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index 7e1bfe9920..adfd12845e 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -31,9 +31,8 @@ #include #include -#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) { diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.h b/devices/ble_hci/common-hal/_bleio/Adapter.h index 9d4d5abf86..f045f920f4 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.h +++ b/devices/ble_hci/common-hal/_bleio/Adapter.h @@ -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; diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.c b/devices/ble_hci/common-hal/_bleio/Attribute.c index c55914b10d..30a0ebcf05 100644 --- a/devices/ble_hci/common-hal/_bleio/Attribute.c +++ b/devices/ble_hci/common-hal/_bleio/Attribute.c @@ -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; +// } +// } diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.h b/devices/ble_hci/common-hal/_bleio/Attribute.h index cd9c86ca39..f527bcf740 100644 --- a/devices/ble_hci/common-hal/_bleio/Attribute.h +++ b/devices/ble_hci/common-hal/_bleio/Attribute.h @@ -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 diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.c b/devices/ble_hci/common-hal/_bleio/Characteristic.c index d507cecca4..ff08bf15c4 100644 --- a/devices/ble_hci/common-hal/_bleio/Characteristic.c +++ b/devices/ble_hci/common-hal/_bleio/Characteristic.c @@ -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); + // } } diff --git a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c index 6f848f8583..c4eb6a19fe 100644 --- a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c @@ -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); } } diff --git a/devices/ble_hci/common-hal/_bleio/Connection.c b/devices/ble_hci/common-hal/_bleio/Connection.c index 6c63f4261f..913f120feb 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.c +++ b/devices/ble_hci/common-hal/_bleio/Connection.c @@ -44,24 +44,22 @@ #include "shared-bindings/_bleio/UUID.h" #include "supervisor/shared/tick.h" -#include "common-hal/_bleio/bonding.h" - #define BLE_ADV_LENGTH_FIELD_SIZE 1 #define BLE_ADV_AD_TYPE_FIELD_SIZE 1 #define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 -static const ble_gap_sec_params_t pairing_sec_params = { - .bond = 1, - .mitm = 0, - .lesc = 0, - .keypress = 0, - .oob = 0, - .io_caps = BLE_GAP_IO_CAPS_NONE, - .min_key_size = 7, - .max_key_size = 16, - .kdist_own = { .enc = 1, .id = 1}, - .kdist_peer = { .enc = 1, .id = 1}, -}; +// static const ble_gap_sec_params_t pairing_sec_params = { +// .bond = 1, +// .mitm = 0, +// .lesc = 0, +// .keypress = 0, +// .oob = 0, +// .io_caps = BLE_GAP_IO_CAPS_NONE, +// .min_key_size = 7, +// .max_key_size = 16, +// .kdist_own = { .enc = 1, .id = 1}, +// .kdist_peer = { .enc = 1, .id = 1}, +// }; #define CONNECTION_DEBUG (1) #if CONNECTION_DEBUG @@ -73,259 +71,259 @@ static const ble_gap_sec_params_t pairing_sec_params = { static volatile bool m_discovery_in_process; static volatile bool m_discovery_successful; -static bleio_service_obj_t *m_char_discovery_service; -static bleio_characteristic_obj_t *m_desc_discovery_characteristic; +//FIX static bleio_service_obj_t *m_char_discovery_service; +//FIX static bleio_characteristic_obj_t *m_desc_discovery_characteristic; -bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { - bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in; +// bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { +// bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in; - if (BLE_GAP_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GAP_EVT_LAST && - ble_evt->evt.gap_evt.conn_handle != self->conn_handle) { - return false; - } - if (BLE_GATTS_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST && - ble_evt->evt.gatts_evt.conn_handle != self->conn_handle) { - return false; - } +// if (BLE_GAP_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GAP_EVT_LAST && +// ble_evt->evt.gap_evt.conn_handle != self->conn_handle) { +// return false; +// } +// if (BLE_GATTS_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST && +// ble_evt->evt.gatts_evt.conn_handle != self->conn_handle) { +// return false; +// } - switch (ble_evt->header.evt_id) { - case BLE_GAP_EVT_DISCONNECTED: - // Adapter.c does the work for this event. - break; +// switch (ble_evt->header.evt_id) { +// case BLE_GAP_EVT_DISCONNECTED: +// // Adapter.c does the work for this event. +// break; - case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { - ble_gap_phys_t const phys = { - .rx_phys = BLE_GAP_PHY_AUTO, - .tx_phys = BLE_GAP_PHY_AUTO, - }; - sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys); - break; - } +// case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { +// ble_gap_phys_t const phys = { +// .rx_phys = BLE_GAP_PHY_AUTO, +// .tx_phys = BLE_GAP_PHY_AUTO, +// }; +// sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys); +// break; +// } - case BLE_GAP_EVT_PHY_UPDATE: { // 0x22 - break; - } +// case BLE_GAP_EVT_PHY_UPDATE: { // 0x22 +// break; +// } - case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: - // SoftDevice will respond to a length update request. - sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL); - break; +// case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: +// // SoftDevice will respond to a length update request. +// sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL); +// break; - case BLE_GAP_EVT_DATA_LENGTH_UPDATE: { // 0x24 - break; - } +// case BLE_GAP_EVT_DATA_LENGTH_UPDATE: { // 0x24 +// break; +// } - case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: { - ble_gatts_evt_exchange_mtu_request_t *request = - &ble_evt->evt.gatts_evt.params.exchange_mtu_request; +// case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: { +// ble_gatts_evt_exchange_mtu_request_t *request = +// &ble_evt->evt.gatts_evt.params.exchange_mtu_request; - uint16_t new_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX; - if (request->client_rx_mtu < new_mtu) { - new_mtu = request->client_rx_mtu; - } - if (new_mtu < BLE_GATT_ATT_MTU_DEFAULT) { - new_mtu = BLE_GATT_ATT_MTU_DEFAULT; - } - if (self->mtu > 0) { - new_mtu = self->mtu; - } +// uint16_t new_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX; +// if (request->client_rx_mtu < new_mtu) { +// new_mtu = request->client_rx_mtu; +// } +// if (new_mtu < BLE_GATT_ATT_MTU_DEFAULT) { +// new_mtu = BLE_GATT_ATT_MTU_DEFAULT; +// } +// if (self->mtu > 0) { +// new_mtu = self->mtu; +// } - self->mtu = new_mtu; - sd_ble_gatts_exchange_mtu_reply(self->conn_handle, new_mtu); - break; - } +// self->mtu = new_mtu; +// sd_ble_gatts_exchange_mtu_reply(self->conn_handle, new_mtu); +// break; +// } - case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: { - ble_gattc_evt_exchange_mtu_rsp_t *response = - &ble_evt->evt.gattc_evt.params.exchange_mtu_rsp; +// case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: { +// ble_gattc_evt_exchange_mtu_rsp_t *response = +// &ble_evt->evt.gattc_evt.params.exchange_mtu_rsp; - self->mtu = response->server_rx_mtu; - break; - } +// self->mtu = response->server_rx_mtu; +// break; +// } - case BLE_GATTS_EVT_WRITE: - // A client wrote a value. - // If we are bonded and it's a CCCD (UUID 0x2902), store the CCCD value. - if (self->conn_handle != BLE_CONN_HANDLE_INVALID && - self->pair_status == PAIR_PAIRED && - ble_evt->evt.gatts_evt.params.write.uuid.type == BLE_UUID_TYPE_BLE && - ble_evt->evt.gatts_evt.params.write.uuid.uuid == 0x2902) { - // - // Save sys_attr data (CCCD state) in bonding area at - // next opportunity, but also remember time of this - // request, so we can consolidate closely-spaced requests. - self->do_bond_cccds = true; - self->do_bond_cccds_request_time = supervisor_ticks_ms64(); - } - // Return false so other handlers get this event as well. - return false; +// case BLE_GATTS_EVT_WRITE: +// // A client wrote a value. +// // If we are bonded and it's a CCCD (UUID 0x2902), store the CCCD value. +// if (self->conn_handle != BLE_CONN_HANDLE_INVALID && +// self->pair_status == PAIR_PAIRED && +// ble_evt->evt.gatts_evt.params.write.uuid.type == BLE_UUID_TYPE_BLE && +// ble_evt->evt.gatts_evt.params.write.uuid.uuid == 0x2902) { +// // +// // Save sys_attr data (CCCD state) in bonding area at +// // next opportunity, but also remember time of this +// // request, so we can consolidate closely-spaced requests. +// self->do_bond_cccds = true; +// self->do_bond_cccds_request_time = supervisor_ticks_ms64(); +// } +// // Return false so other handlers get this event as well. +// return false; - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); - break; +// case BLE_GATTS_EVT_SYS_ATTR_MISSING: +// sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); +// break; - #if CIRCUITPY_VERBOSE_BLE - // Use read authorization to snoop on all reads when doing verbose debugging. - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { +// #if CIRCUITPY_VERBOSE_BLE +// // Use read authorization to snoop on all reads when doing verbose debugging. +// case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { - ble_gatts_evt_rw_authorize_request_t *request = - &ble_evt->evt.gatts_evt.params.authorize_request; +// ble_gatts_evt_rw_authorize_request_t *request = +// &ble_evt->evt.gatts_evt.params.authorize_request; - mp_printf(&mp_plat_print, "Read %x offset %d ", request->request.read.handle, request->request.read.offset); - uint8_t value_bytes[22]; - ble_gatts_value_t value; - value.offset = request->request.read.offset; - value.len = 22; - value.p_value = value_bytes; +// mp_printf(&mp_plat_print, "Read %x offset %d ", request->request.read.handle, request->request.read.offset); +// uint8_t value_bytes[22]; +// ble_gatts_value_t value; +// value.offset = request->request.read.offset; +// value.len = 22; +// value.p_value = value_bytes; - sd_ble_gatts_value_get(self->conn_handle, request->request.read.handle, &value); - size_t len = value.len; - if (len > 22) { - len = 22; - } - for (uint8_t i = 0; i < len; i++) { - mp_printf(&mp_plat_print, " %02x", value_bytes[i]); - } - mp_printf(&mp_plat_print, "\n"); - ble_gatts_rw_authorize_reply_params_t reply; - reply.type = request->type; - reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; - reply.params.read.update = false; - reply.params.read.offset = request->request.read.offset; - sd_ble_gatts_rw_authorize_reply(self->conn_handle, &reply); - break; - } - #endif +// sd_ble_gatts_value_get(self->conn_handle, request->request.read.handle, &value); +// size_t len = value.len; +// if (len > 22) { +// len = 22; +// } +// for (uint8_t i = 0; i < len; i++) { +// mp_printf(&mp_plat_print, " %02x", value_bytes[i]); +// } +// mp_printf(&mp_plat_print, "\n"); +// ble_gatts_rw_authorize_reply_params_t reply; +// reply.type = request->type; +// reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; +// reply.params.read.update = false; +// reply.params.read.offset = request->request.read.offset; +// sd_ble_gatts_rw_authorize_reply(self->conn_handle, &reply); +// break; +// } +// #endif - case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55 - break; - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { - self->conn_params_updating = true; - ble_gap_evt_conn_param_update_request_t *request = - &ble_evt->evt.gap_evt.params.conn_param_update_request; - sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params); - break; - } - case BLE_GAP_EVT_CONN_PARAM_UPDATE: { // 0x12 - ble_gap_evt_conn_param_update_t *result = - &ble_evt->evt.gap_evt.params.conn_param_update; +// case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55 +// break; +// case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { +// self->conn_params_updating = true; +// ble_gap_evt_conn_param_update_request_t *request = +// &ble_evt->evt.gap_evt.params.conn_param_update_request; +// sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params); +// break; +// } +// case BLE_GAP_EVT_CONN_PARAM_UPDATE: { // 0x12 +// ble_gap_evt_conn_param_update_t *result = +// &ble_evt->evt.gap_evt.params.conn_param_update; - #if CIRCUITPY_VERBOSE_BLE - ble_gap_conn_params_t *cp = &ble_evt->evt.gap_evt.params.conn_param_update.conn_params; - mp_printf(&mp_plat_print, "conn params updated: 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 = &ble_evt->evt.gap_evt.params.conn_param_update.conn_params; +// mp_printf(&mp_plat_print, "conn params updated: 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 - memcpy(&self->conn_params, &result->conn_params, sizeof(ble_gap_conn_params_t)); - self->conn_params_updating = false; - break; - } - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { - // First time pairing. - // 1. Either we or peer initiate the process - // 2. Peer asks for security parameters using BLE_GAP_EVT_SEC_PARAMS_REQUEST. - // 3. Pair Key exchange ("just works" implemented now; TODO: out-of-band key pairing) - // 4. Connection is secured: BLE_GAP_EVT_CONN_SEC_UPDATE - // 5. Long-term Keys exchanged: BLE_GAP_EVT_AUTH_STATUS +// memcpy(&self->conn_params, &result->conn_params, sizeof(ble_gap_conn_params_t)); +// self->conn_params_updating = false; +// break; +// } +// case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { +// // First time pairing. +// // 1. Either we or peer initiate the process +// // 2. Peer asks for security parameters using BLE_GAP_EVT_SEC_PARAMS_REQUEST. +// // 3. Pair Key exchange ("just works" implemented now; TODO: out-of-band key pairing) +// // 4. Connection is secured: BLE_GAP_EVT_CONN_SEC_UPDATE +// // 5. Long-term Keys exchanged: BLE_GAP_EVT_AUTH_STATUS - bonding_clear_keys(&self->bonding_keys); - self->ediv = EDIV_INVALID; - ble_gap_sec_keyset_t keyset = { - .keys_own = { - .p_enc_key = &self->bonding_keys.own_enc, - .p_id_key = NULL, - .p_sign_key = NULL, - .p_pk = NULL - }, +// bonding_clear_keys(&self->bonding_keys); +// self->ediv = EDIV_INVALID; +// ble_gap_sec_keyset_t keyset = { +// .keys_own = { +// .p_enc_key = &self->bonding_keys.own_enc, +// .p_id_key = NULL, +// .p_sign_key = NULL, +// .p_pk = NULL +// }, - .keys_peer = { - .p_enc_key = &self->bonding_keys.peer_enc, - .p_id_key = &self->bonding_keys.peer_id, - .p_sign_key = NULL, - .p_pk = NULL - } - }; +// .keys_peer = { +// .p_enc_key = &self->bonding_keys.peer_enc, +// .p_id_key = &self->bonding_keys.peer_id, +// .p_sign_key = NULL, +// .p_pk = NULL +// } +// }; - sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, - self->is_central ? NULL : &pairing_sec_params, - &keyset); - break; - } +// sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, +// self->is_central ? NULL : &pairing_sec_params, +// &keyset); +// break; +// } - case BLE_GAP_EVT_LESC_DHKEY_REQUEST: - // TODO for LESC pairing: - // sd_ble_gap_lesc_dhkey_reply(...); - break; +// case BLE_GAP_EVT_LESC_DHKEY_REQUEST: +// // TODO for LESC pairing: +// // sd_ble_gap_lesc_dhkey_reply(...); +// break; - case BLE_GAP_EVT_AUTH_STATUS: { // 0x19 - // Key exchange completed. - ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; - self->sec_status = status->auth_status; - if (status->auth_status == BLE_GAP_SEC_STATUS_SUCCESS) { - self->ediv = self->bonding_keys.own_enc.master_id.ediv; - self->pair_status = PAIR_PAIRED; - // Save keys in bonding area at next opportunity. - self->do_bond_keys = true; - } else { - // Inform busy-waiter pairing has failed. - self->pair_status = PAIR_NOT_PAIRED; - } - break; - } +// case BLE_GAP_EVT_AUTH_STATUS: { // 0x19 +// // Key exchange completed. +// ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; +// self->sec_status = status->auth_status; +// if (status->auth_status == BLE_GAP_SEC_STATUS_SUCCESS) { +// self->ediv = self->bonding_keys.own_enc.master_id.ediv; +// self->pair_status = PAIR_PAIRED; +// // Save keys in bonding area at next opportunity. +// self->do_bond_keys = true; +// } else { +// // Inform busy-waiter pairing has failed. +// self->pair_status = PAIR_NOT_PAIRED; +// } +// break; +// } - case BLE_GAP_EVT_SEC_INFO_REQUEST: { // 0x14 - // Peer asks for the stored keys. - // - load key and return if bonded previously. - // - Else return NULL --> Initiate key exchange - ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request; - (void) sec_info_request; - if ( bonding_load_keys(self->is_central, sec_info_request->master_id.ediv, &self->bonding_keys) ) { - sd_ble_gap_sec_info_reply( - self->conn_handle, - &self->bonding_keys.own_enc.enc_info, - &self->bonding_keys.peer_id.id_info, - NULL); - self->ediv = self->bonding_keys.own_enc.master_id.ediv; - } else { - // We don't have stored keys. Ask for keys. - sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL); - } - break; - } +// case BLE_GAP_EVT_SEC_INFO_REQUEST: { // 0x14 +// // Peer asks for the stored keys. +// // - load key and return if bonded previously. +// // - Else return NULL --> Initiate key exchange +// ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request; +// (void) sec_info_request; +// if ( bonding_load_keys(self->is_central, sec_info_request->master_id.ediv, &self->bonding_keys) ) { +// sd_ble_gap_sec_info_reply( +// self->conn_handle, +// &self->bonding_keys.own_enc.enc_info, +// &self->bonding_keys.peer_id.id_info, +// NULL); +// self->ediv = self->bonding_keys.own_enc.master_id.ediv; +// } else { +// // We don't have stored keys. Ask for keys. +// sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL); +// } +// break; +// } - case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a - // We get this both on first-time pairing and on subsequent pairings using stored keys. - ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; - if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { - // Security setup did not succeed: - // mode 0, level 0 means no access - // mode 1, level 1 means open link - // mode >=1 and/or level >=1 means encryption is set up - self->pair_status = PAIR_NOT_PAIRED; - } else { - if (bonding_load_cccd_info(self->is_central, self->conn_handle, self->ediv)) { - // Did an sd_ble_gatts_sys_attr_set() with the stored sys_attr values. - } else { - // No matching bonding found, so use fresh system attributes. - sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); - } - self->pair_status = PAIR_PAIRED; - } - break; - } +// case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a +// // We get this both on first-time pairing and on subsequent pairings using stored keys. +// ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; +// if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { +// // Security setup did not succeed: +// // mode 0, level 0 means no access +// // mode 1, level 1 means open link +// // mode >=1 and/or level >=1 means encryption is set up +// self->pair_status = PAIR_NOT_PAIRED; +// } else { +// if (bonding_load_cccd_info(self->is_central, self->conn_handle, self->ediv)) { +// // Did an sd_ble_gatts_sys_attr_set() with the stored sys_attr values. +// } else { +// // No matching bonding found, so use fresh system attributes. +// sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); +// } +// self->pair_status = PAIR_PAIRED; +// } +// break; +// } - default: - return false; - } - return true; -} +// default: +// return false; +// } +// return true; +// } void bleio_connection_clear(bleio_connection_internal_t *self) { self->remote_service_list = NULL; - self->conn_handle = BLE_CONN_HANDLE_INVALID; + //FIX self->conn_handle = BLE_CONN_HANDLE_INVALID; self->pair_status = PAIR_NOT_PAIRED; - bonding_clear_keys(&self->bonding_keys); + //FIX bonding_clear_keys(&self->bonding_keys); } bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) { @@ -339,17 +337,18 @@ bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) { if (self->connection == NULL) { return false; } - return self->connection->conn_handle != BLE_CONN_HANDLE_INVALID; + return false; + //FIX return self->connection->conn_handle != BLE_CONN_HANDLE_INVALID; } void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) { - sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + //FIX sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) { self->pair_status = PAIR_WAITING; - check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params)); + //FIX check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params)); while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; @@ -364,369 +363,371 @@ mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_ while (self->conn_params_updating && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; } - return 1.25f * self->conn_params.min_conn_interval; + //FIX return 1.25f * self->conn_params.min_conn_interval; + return 0.0f; } // Return the current negotiated MTU length, minus overhead. mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) { - return (self->mtu == 0 ? BLE_GATT_ATT_MTU_DEFAULT : self->mtu) - 3; + /// FIX return (self->mtu == 0 ? BLE_GATT_ATT_MTU_DEFAULT : self->mtu) - 3; + return 0; } void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) { - self->conn_params_updating = true; - uint16_t interval = new_interval / 1.25f; - self->conn_params.min_conn_interval = interval; - self->conn_params.max_conn_interval = interval; - uint32_t status = NRF_ERROR_BUSY; - while (status == NRF_ERROR_BUSY) { - status = sd_ble_gap_conn_param_update(self->conn_handle, &self->conn_params); - RUN_BACKGROUND_TASKS; - } - check_nrf_error(status); + // self->conn_params_updating = true; + // uint16_t interval = new_interval / 1.25f; + // self->conn_params.min_conn_interval = interval; + // self->conn_params.max_conn_interval = interval; + // uint32_t status = NRF_ERROR_BUSY; + // while (status == NRF_ERROR_BUSY) { + // status = sd_ble_gap_conn_param_update(self->conn_handle, &self->conn_params); + // RUN_BACKGROUND_TASKS; + // } + // check_nrf_error(status); } // service_uuid may be NULL, to discover all services. -STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint16_t start_handle, ble_uuid_t *service_uuid) { - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t nrf_err = NRF_ERROR_BUSY; - while (nrf_err == NRF_ERROR_BUSY) { - nrf_err = sd_ble_gattc_primary_services_discover(connection->conn_handle, start_handle, service_uuid); - } - check_nrf_error(nrf_err); - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC bool discover_next_characteristics(bleio_connection_internal_t* connection, bleio_service_obj_t *service, uint16_t start_handle) { - m_char_discovery_service = service; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = service->end_handle; - - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t err_code = sd_ble_gattc_characteristics_discover(connection->conn_handle, &handle_range); - if (err_code != NRF_SUCCESS) { - return false; - } - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC bool discover_next_descriptors(bleio_connection_internal_t* connection, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { - m_desc_discovery_characteristic = characteristic; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = end_handle; - - m_discovery_successful = false; - m_discovery_in_process = true; - - uint32_t err_code = sd_ble_gattc_descriptors_discover(connection->conn_handle, &handle_range); - if (err_code != NRF_SUCCESS) { - return false; - } - - // Wait for a discovery event. - while (m_discovery_in_process) { - MICROPY_VM_HOOK_LOOP; - } - return m_discovery_successful; -} - -STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_connection_internal_t* connection) { - bleio_service_obj_t* tail = connection->remote_service_list; - - for (size_t i = 0; i < response->count; ++i) { - ble_gattc_service_t *gattc_service = &response->services[i]; - - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - service->base.type = &bleio_service_type; - - // Initialize several fields at once. - bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); - - service->is_remote = true; - service->start_handle = gattc_service->handle_range.start_handle; - service->end_handle = gattc_service->handle_range.end_handle; - service->handle = gattc_service->handle_range.start_handle; - - if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known service UUID. - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); - service->uuid = uuid; - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just set the UUID to NULL. - service->uuid = NULL; - } - - service->next = tail; - tail = service; - } - - connection->remote_service_list = tail; - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} - -STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_connection_internal_t* connection) { - for (size_t i = 0; i < response->count; ++i) { - ble_gattc_char_t *gattc_char = &response->chars[i]; - - bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); - characteristic->base.type = &bleio_characteristic_type; - - bleio_uuid_obj_t *uuid = NULL; - - if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known characteristic UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just leave the UUID as NULL. - } - - bleio_characteristic_properties_t props = - (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) | - (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) | - (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) | - (gattc_char->char_props.read ? CHAR_PROP_READ : 0) | - (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | - (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); - - // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. - common_hal_bleio_characteristic_construct( - characteristic, m_char_discovery_service, gattc_char->handle_value, uuid, - props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, - GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc - NULL); - - mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); - } - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} - -STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_connection_internal_t* connection) { - for (size_t i = 0; i < response->count; ++i) { - ble_gattc_desc_t *gattc_desc = &response->descs[i]; - - // Remember handles for certain well-known descriptors. - switch (gattc_desc->uuid.uuid) { - case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: - m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; - break; - - case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG: - m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; - break; - - case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: - m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; - break; - - default: - // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors, - // so ignore those. - // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors - break; - } - - bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); - descriptor->base.type = &bleio_descriptor_type; - - bleio_uuid_obj_t *uuid = NULL; - - if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { - // Known descriptor UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); - } else { - // The discovery response contained a 128-bit UUID that has not yet been registered with the - // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. - // For now, just leave the UUID as NULL. - } - - common_hal_bleio_descriptor_construct( - descriptor, m_desc_discovery_characteristic, uuid, - SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, - GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes); - descriptor->handle = gattc_desc->handle; - - mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); - } - - if (response->count > 0) { - m_discovery_successful = true; - } - m_discovery_in_process = false; -} - -STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) { - bleio_connection_internal_t* connection = MP_OBJ_TO_PTR(payload); - switch (ble_evt->header.evt_id) { - case BLE_GAP_EVT_DISCONNECTED: - m_discovery_successful = false; - m_discovery_in_process = false; - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, connection); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, connection); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, connection); - break; - - default: - // CONNECTION_DEBUG_PRINTF(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id); - return false; - break; - } - return true; -} - -STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) { - ble_drv_add_event_handler(discovery_on_ble_evt, self); - - // Start over with an empty list. - self->remote_service_list = NULL; - - if (service_uuids_whitelist == mp_const_none) { - // List of service UUID's not given, so discover all available services. - - uint16_t next_service_start_handle = BLE_GATT_HANDLE_START; - - while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) { - // discover_next_services() appends to remote_services_list. - - // Get the most recently discovered service, and then ask for services - // whose handles start after the last attribute handle inside that service. - const bleio_service_obj_t *service = self->remote_service_list; - next_service_start_handle = service->end_handle + 1; - } - } else { - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); - mp_obj_t uuid_obj; - while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { - mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist")); - } - bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - - ble_uuid_t nrf_uuid; - bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid); - - // Service might or might not be discovered; that's ok. Caller has to check - // Central.remote_services to find out. - // We only need to call this once for each service to discover. - discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid); - } - } - - - bleio_service_obj_t *service = self->remote_service_list; - while (service != NULL) { - // Skip the service if it had an unknown (unregistered) UUID. - if (service->uuid == NULL) { - service = service->next; - continue; - } - - uint16_t next_char_start_handle = service->start_handle; - - // Stop when we go past the end of the range of handles for this service or - // discovery call returns nothing. - // discover_next_characteristics() appends to the characteristic_list. - while (next_char_start_handle <= service->end_handle && - discover_next_characteristics(self, service, next_char_start_handle)) { - - - // Get the most recently discovered characteristic, and then ask for characteristics - // whose handles start after the last attribute handle inside that characteristic. - const bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]); - - next_char_start_handle = characteristic->handle + 1; - } - - // Got characteristics for this service. Now discover descriptors for each characteristic. - size_t char_list_len = service->characteristic_list->len; - for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]); - const bool last_characteristic = char_idx == char_list_len - 1; - bleio_characteristic_obj_t *next_characteristic = last_characteristic - ? NULL - : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]); - - // Skip the characteristic if it had an unknown (unregistered) UUID. - if (characteristic->uuid == NULL) { - continue; - } - - uint16_t next_desc_start_handle = characteristic->handle + 1; - - // Don't run past the end of this service or the beginning of the next characteristic. - uint16_t next_desc_end_handle = next_characteristic == NULL - ? service->end_handle - : next_characteristic->handle - 1; - - // Stop when we go past the end of the range of handles for this service or - // discovery call returns nothing. - // discover_next_descriptors() appends to the descriptor_list. - while (next_desc_start_handle <= service->end_handle && - next_desc_start_handle <= next_desc_end_handle && - discover_next_descriptors(self, characteristic, - next_desc_start_handle, next_desc_end_handle)) { - // Get the most recently discovered descriptor, and then ask for descriptors - // whose handles start after that descriptor's handle. - const bleio_descriptor_obj_t *descriptor = characteristic->descriptor_list; - next_desc_start_handle = descriptor->handle + 1; - } - } - service = service->next; - } - - // This event handler is no longer needed. - ble_drv_remove_event_handler(discovery_on_ble_evt, self); - -} +// STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint16_t start_handle, ble_uuid_t *service_uuid) { +// m_discovery_successful = false; +// m_discovery_in_process = true; + +// uint32_t nrf_err = NRF_ERROR_BUSY; +// while (nrf_err == NRF_ERROR_BUSY) { +// nrf_err = sd_ble_gattc_primary_services_discover(connection->conn_handle, start_handle, service_uuid); +// } +// check_nrf_error(nrf_err); + +// // Wait for a discovery event. +// while (m_discovery_in_process) { +// MICROPY_VM_HOOK_LOOP; +// } +// return m_discovery_successful; +// } + +// STATIC bool discover_next_characteristics(bleio_connection_internal_t* connection, bleio_service_obj_t *service, uint16_t start_handle) { +// m_char_discovery_service = service; + +// ble_gattc_handle_range_t handle_range; +// handle_range.start_handle = start_handle; +// handle_range.end_handle = service->end_handle; + +// m_discovery_successful = false; +// m_discovery_in_process = true; + +// uint32_t err_code = sd_ble_gattc_characteristics_discover(connection->conn_handle, &handle_range); +// if (err_code != NRF_SUCCESS) { +// return false; +// } + +// // Wait for a discovery event. +// while (m_discovery_in_process) { +// MICROPY_VM_HOOK_LOOP; +// } +// return m_discovery_successful; +// } + +// STATIC bool discover_next_descriptors(bleio_connection_internal_t* connection, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { +// m_desc_discovery_characteristic = characteristic; + +// ble_gattc_handle_range_t handle_range; +// handle_range.start_handle = start_handle; +// handle_range.end_handle = end_handle; + +// m_discovery_successful = false; +// m_discovery_in_process = true; + +// uint32_t err_code = sd_ble_gattc_descriptors_discover(connection->conn_handle, &handle_range); +// if (err_code != NRF_SUCCESS) { +// return false; +// } + +// // Wait for a discovery event. +// while (m_discovery_in_process) { +// MICROPY_VM_HOOK_LOOP; +// } +// return m_discovery_successful; +// } + +// STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_connection_internal_t* connection) { +// bleio_service_obj_t* tail = connection->remote_service_list; + +// for (size_t i = 0; i < response->count; ++i) { +// ble_gattc_service_t *gattc_service = &response->services[i]; + +// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); +// service->base.type = &bleio_service_type; + +// // Initialize several fields at once. +// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); + +// service->is_remote = true; +// service->start_handle = gattc_service->handle_range.start_handle; +// service->end_handle = gattc_service->handle_range.end_handle; +// service->handle = gattc_service->handle_range.start_handle; + +// if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { +// // Known service UUID. +// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); +// uuid->base.type = &bleio_uuid_type; +// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); +// service->uuid = uuid; +// } else { +// // The discovery response contained a 128-bit UUID that has not yet been registered with the +// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. +// // For now, just set the UUID to NULL. +// service->uuid = NULL; +// } + +// service->next = tail; +// tail = service; +// } + +// connection->remote_service_list = tail; + +// if (response->count > 0) { +// m_discovery_successful = true; +// } +// m_discovery_in_process = false; +// } + +// STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_connection_internal_t* connection) { +// for (size_t i = 0; i < response->count; ++i) { +// ble_gattc_char_t *gattc_char = &response->chars[i]; + +// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); +// characteristic->base.type = &bleio_characteristic_type; + +// bleio_uuid_obj_t *uuid = NULL; + +// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { +// // Known characteristic UUID. +// uuid = m_new_obj(bleio_uuid_obj_t); +// uuid->base.type = &bleio_uuid_type; +// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); +// } else { +// // The discovery response contained a 128-bit UUID that has not yet been registered with the +// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. +// // For now, just leave the UUID as NULL. +// } + +// bleio_characteristic_properties_t props = +// (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) | +// (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) | +// (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) | +// (gattc_char->char_props.read ? CHAR_PROP_READ : 0) | +// (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | +// (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); + +// // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. +// common_hal_bleio_characteristic_construct( +// characteristic, m_char_discovery_service, gattc_char->handle_value, uuid, +// props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, +// GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc +// NULL); + +// mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); +// } + +// if (response->count > 0) { +// m_discovery_successful = true; +// } +// m_discovery_in_process = false; +// } + +// STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_connection_internal_t* connection) { +// for (size_t i = 0; i < response->count; ++i) { +// ble_gattc_desc_t *gattc_desc = &response->descs[i]; + +// // Remember handles for certain well-known descriptors. +// switch (gattc_desc->uuid.uuid) { +// case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: +// m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; +// break; + +// case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG: +// m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; +// break; + +// case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: +// m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; +// break; + +// default: +// // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors, +// // so ignore those. +// // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors +// break; +// } + +// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); +// descriptor->base.type = &bleio_descriptor_type; + +// bleio_uuid_obj_t *uuid = NULL; + +// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { +// // Known descriptor UUID. +// uuid = m_new_obj(bleio_uuid_obj_t); +// uuid->base.type = &bleio_uuid_type; +// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); +// } else { +// // The discovery response contained a 128-bit UUID that has not yet been registered with the +// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. +// // For now, just leave the UUID as NULL. +// } + +// common_hal_bleio_descriptor_construct( +// descriptor, m_desc_discovery_characteristic, uuid, +// SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, +// GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes); +// descriptor->handle = gattc_desc->handle; + +// mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); +// } + +// if (response->count > 0) { +// m_discovery_successful = true; +// } +// m_discovery_in_process = false; +// } + +// STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) { +// bleio_connection_internal_t* connection = MP_OBJ_TO_PTR(payload); +// switch (ble_evt->header.evt_id) { +// case BLE_GAP_EVT_DISCONNECTED: +// m_discovery_successful = false; +// m_discovery_in_process = false; +// break; + +// case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: +// on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, connection); +// break; + +// case BLE_GATTC_EVT_CHAR_DISC_RSP: +// on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, connection); +// break; + +// case BLE_GATTC_EVT_DESC_DISC_RSP: +// on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, connection); +// break; + +// default: +// // CONNECTION_DEBUG_PRINTF(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id); +// return false; +// break; +// } +// return true; +// } + +// STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) { +// ble_drv_add_event_handler(discovery_on_ble_evt, self); + +// // Start over with an empty list. +// self->remote_service_list = NULL; + +// if (service_uuids_whitelist == mp_const_none) { +// // List of service UUID's not given, so discover all available services. + +// uint16_t next_service_start_handle = BLE_GATT_HANDLE_START; + +// while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) { +// // discover_next_services() appends to remote_services_list. + +// // Get the most recently discovered service, and then ask for services +// // whose handles start after the last attribute handle inside that service. +// const bleio_service_obj_t *service = self->remote_service_list; +// next_service_start_handle = service->end_handle + 1; +// } +// } else { +// mp_obj_iter_buf_t iter_buf; +// mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); +// mp_obj_t uuid_obj; +// while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { +// if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { +// mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist")); +// } +// bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); + +// ble_uuid_t nrf_uuid; +// bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid); + +// // Service might or might not be discovered; that's ok. Caller has to check +// // Central.remote_services to find out. +// // We only need to call this once for each service to discover. +// discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid); +// } +// } + + +// bleio_service_obj_t *service = self->remote_service_list; +// while (service != NULL) { +// // Skip the service if it had an unknown (unregistered) UUID. +// if (service->uuid == NULL) { +// service = service->next; +// continue; +// } + +// uint16_t next_char_start_handle = service->start_handle; + +// // Stop when we go past the end of the range of handles for this service or +// // discovery call returns nothing. +// // discover_next_characteristics() appends to the characteristic_list. +// while (next_char_start_handle <= service->end_handle && +// discover_next_characteristics(self, service, next_char_start_handle)) { + + +// // Get the most recently discovered characteristic, and then ask for characteristics +// // whose handles start after the last attribute handle inside that characteristic. +// const bleio_characteristic_obj_t *characteristic = +// MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]); + +// next_char_start_handle = characteristic->handle + 1; +// } + +// // Got characteristics for this service. Now discover descriptors for each characteristic. +// size_t char_list_len = service->characteristic_list->len; +// for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) { +// bleio_characteristic_obj_t *characteristic = +// MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]); +// const bool last_characteristic = char_idx == char_list_len - 1; +// bleio_characteristic_obj_t *next_characteristic = last_characteristic +// ? NULL +// : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]); + +// // Skip the characteristic if it had an unknown (unregistered) UUID. +// if (characteristic->uuid == NULL) { +// continue; +// } + +// uint16_t next_desc_start_handle = characteristic->handle + 1; + +// // Don't run past the end of this service or the beginning of the next characteristic. +// uint16_t next_desc_end_handle = next_characteristic == NULL +// ? service->end_handle +// : next_characteristic->handle - 1; + +// // Stop when we go past the end of the range of handles for this service or +// // discovery call returns nothing. +// // discover_next_descriptors() appends to the descriptor_list. +// while (next_desc_start_handle <= service->end_handle && +// next_desc_start_handle <= next_desc_end_handle && +// discover_next_descriptors(self, characteristic, +// next_desc_start_handle, next_desc_end_handle)) { +// // Get the most recently discovered descriptor, and then ask for descriptors +// // whose handles start after that descriptor's handle. +// const bleio_descriptor_obj_t *descriptor = characteristic->descriptor_list; +// next_desc_start_handle = descriptor->handle + 1; +// } +// } +// service = service->next; +// } + +// // This event handler is no longer needed. +// ble_drv_remove_event_handler(discovery_on_ble_evt, self); + +// } mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) { - discover_remote_services(self->connection, service_uuids_whitelist); + //FIX discover_remote_services(self->connection, service_uuids_whitelist); bleio_connection_ensure_connected(self); // Convert to a tuple and then clear the list so the callee will take ownership. mp_obj_tuple_t *services_tuple = service_linked_list_to_tuple(self->connection->remote_service_list); @@ -756,13 +757,13 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* interna // Find the connection that uses the given conn_handle. Return NULL if not found. bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle) { - bleio_connection_internal_t *connection; - for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - connection = &bleio_connections[i]; - if (connection->conn_handle == conn_handle) { - return connection; - } - } + //FIX bleio_connection_internal_t *connection; + // for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + // connection = &bleio_connections[i]; + // if (connection->conn_handle == conn_handle) { + // return connection; + // } + // } return NULL; } diff --git a/devices/ble_hci/common-hal/_bleio/Connection.h b/devices/ble_hci/common-hal/_bleio/Connection.h index 7ad91aa5c5..bb0c140c55 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.h +++ b/devices/ble_hci/common-hal/_bleio/Connection.h @@ -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" diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c index c3f41bc9d4..65d4139605 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c @@ -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); } } diff --git a/devices/ble_hci/common-hal/_bleio/Service.c b/devices/ble_hci/common-hal/_bleio/Service.c index f194a95dd7..1f9649b6c3 100644 --- a/devices/ble_hci/common-hal/_bleio/Service.c +++ b/devices/ble_hci/common-hal/_bleio/Service.c @@ -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)); } diff --git a/devices/ble_hci/common-hal/_bleio/UUID.c b/devices/ble_hci/common-hal/_bleio/UUID.c index 1c6c35e477..3f5fbe4fe4 100644 --- a/devices/ble_hci/common-hal/_bleio/UUID.c +++ b/devices/ble_hci/common-hal/_bleio/UUID.c @@ -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")); diff --git a/devices/ble_hci/common-hal/_bleio/UUID.h b/devices/ble_hci/common-hal/_bleio/UUID.h index 584a28960b..4a72d38acd 100644 --- a/devices/ble_hci/common-hal/_bleio/UUID.h +++ b/devices/ble_hci/common-hal/_bleio/UUID.h @@ -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 diff --git a/devices/ble_hci/common-hal/_bleio/__init__.c b/devices/ble_hci/common-hal/_bleio/__init__.c index e84bba6626..a09c3a05c5 100644 --- a/devices/ble_hci/common-hal/_bleio/__init__.c +++ b/devices/ble_hci/common-hal/_bleio/__init__.c @@ -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) { diff --git a/devices/ble_hci/common-hal/_bleio/__init__.h b/devices/ble_hci/common-hal/_bleio/__init__.h index 77548dac15..784dcefdcb 100644 --- a/devices/ble_hci/common-hal/_bleio/__init__.h +++ b/devices/ble_hci/common-hal/_bleio/__init__.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H #define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H +#include + 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); diff --git a/devices/ble_hci/common-hal/_bleio/bonding.c b/devices/ble_hci/common-hal/_bleio/bonding.c deleted file mode 100644 index d03e418f7f..0000000000 --- a/devices/ble_hci/common-hal/_bleio/bonding.c +++ /dev/null @@ -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 -#include -#include - -#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; -} diff --git a/devices/ble_hci/common-hal/_bleio/bonding.h b/devices/ble_hci/common-hal/_bleio/bonding.h deleted file mode 100644 index 7fa66972de..0000000000 --- a/devices/ble_hci/common-hal/_bleio/bonding.h +++ /dev/null @@ -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 -#include -#include - -#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 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 811de78664..38ef373126 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -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/,\ diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index 0780e0a327..cf3b62ff18 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -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 //| diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h index 39147b6ebc..3f7cd54304 100644 --- a/shared-bindings/_bleio/Adapter.h +++ b/shared-bindings/_bleio/Adapter.h @@ -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);