summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xports/nrf/Makefile5
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.c6
-rw-r--r--ports/nrf/common-hal/bleio/Device.c166
-rw-r--r--ports/nrf/common-hal/bleio/Scanner.c3
-rw-r--r--ports/nrf/drivers/bluetooth/ble_drv.c396
-rw-r--r--ports/nrf/drivers/bluetooth/ble_drv.h36
-rw-r--r--ports/nrf/drivers/bluetooth/ble_uart.h1
-rw-r--r--ports/nrf/modules/ubluepy/modubluepy.h126
-rw-r--r--ports/nrf/modules/ubluepy/ubluepy_peripheral.c507
-rw-r--r--ports/nrf/mpconfigport.h33
-rw-r--r--shared-bindings/bleio/Device.c348
-rw-r--r--shared-bindings/bleio/Device.h (renamed from ports/nrf/modules/ubluepy/modubluepy.c)30
-rw-r--r--shared-bindings/bleio/ScanEntry.c5
-rw-r--r--shared-bindings/bleio/ScanEntry.h11
-rw-r--r--shared-bindings/bleio/Service.c6
-rw-r--r--shared-bindings/bleio/__init__.c3
-rw-r--r--shared-module/bleio/AdvertisementData.h9
-rw-r--r--shared-module/bleio/Device.h45
-rw-r--r--shared-module/bleio/ScanEntry.h40
-rw-r--r--shared-module/bleio/Service.h3
20 files changed, 831 insertions, 948 deletions
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index 6112678f5..b059569ab 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -127,10 +127,6 @@ SRC_C += \
peripherals/nrf/timers.c \
supervisor/shared/memory.c
-DRIVERS_SRC_C += $(addprefix modules/,\
- ubluepy/modubluepy.c \
- ubluepy/ubluepy_peripheral.c \
- )
SRC_COMMON_HAL += \
analogio/AnalogIn.c \
@@ -163,6 +159,7 @@ SRC_COMMON_HAL += \
bleio/Adapter.c \
bleio/Characteristic.c \
bleio/Descriptor.c \
+ bleio/Device.c \
bleio/Scanner.c \
bleio/Service.c \
bleio/UUID.c
diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c
index 56afc52c5..938289f2d 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.c
+++ b/ports/nrf/common-hal/bleio/Characteristic.c
@@ -26,6 +26,7 @@
#include "ble_drv.h"
#include "shared-module/bleio/Characteristic.h"
+#include "shared-module/bleio/Device.h"
void data_callback(bleio_characteristic_obj_t *self, uint16_t length, uint8_t *data) {
self->value_data = mp_obj_new_bytearray(length, data);
@@ -36,10 +37,9 @@ void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self
}
void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
- ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(self->service->periph);
- ubluepy_role_type_t role = peripheral->role;
+ const bleio_device_obj_t *device = MP_OBJ_TO_PTR(self->service->device);
- if (role == UBLUEPY_ROLE_PERIPHERAL) {
+ if (device->is_peripheral) {
// TODO: Add indications
if (self->props.notify) {
ble_drv_attr_s_notify(self, bufinfo);
diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c
new file mode 100644
index 000000000..ab2898e72
--- /dev/null
+++ b/ports/nrf/common-hal/bleio/Device.c
@@ -0,0 +1,166 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * 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 <stdio.h>
+
+#include "ble_drv.h"
+#include "ble_gap.h"
+#include "ble_gatt.h"
+#include "ble_types.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Device.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+
+static volatile bool m_disc_evt_received;
+
+STATIC void gap_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) {
+ if (event_id == BLE_GAP_EVT_CONNECTED) {
+ device->conn_handle = conn_handle;
+ } else if (event_id == BLE_GAP_EVT_DISCONNECTED) {
+ device->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+STATIC void gatts_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) {
+
+}
+
+STATIC void gattc_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) {
+ m_disc_evt_received = true;
+}
+
+STATIC void disc_add_service(bleio_device_obj_t *device, ble_drv_service_data_t * service_data) {
+ bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
+ service->base.type = &bleio_service_type;
+
+ bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ uuid->type = (service_data->uuid_type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT;
+ uuid->value[0] = service_data->uuid & 0xFF;
+ uuid->value[1] = service_data->uuid >> 8;
+
+ service->char_list = mp_obj_new_list(0, NULL);
+ service->uuid = uuid;
+ service->device = device;
+ service->handle = service_data->start_handle;
+ service->start_handle = service_data->start_handle;
+ service->end_handle = service_data->end_handle;
+
+ mp_obj_list_append(device->service_list, service);
+}
+
+STATIC void disc_add_char(bleio_service_obj_t *service, ble_drv_char_data_t *chara_data) {
+ bleio_characteristic_obj_t *chara = m_new_obj(bleio_characteristic_obj_t);
+ chara->base.type = &bleio_characteristic_type;
+
+ bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t);
+ p_uuid->base.type = &bleio_uuid_type;
+
+ chara->uuid = p_uuid;
+
+ p_uuid->type = chara_data->uuid_type;
+ p_uuid->value[0] = chara_data->uuid & 0xFF;
+ p_uuid->value[1] = chara_data->uuid >> 8;
+
+ // add characteristic specific data from discovery
+ chara->props.broadcast = chara_data->props.broadcast;
+ chara->props.indicate = chara_data->props.indicate;
+ chara->props.notify = chara_data->props.notify;
+ chara->props.read = chara_data->props.read;
+ chara->props.write = chara_data->props.write;
+ chara->props.write_wo_resp = chara_data->props.write_wo_resp;
+ chara->handle = chara_data->value_handle;
+
+ chara->service_handle = service->handle;
+ chara->service = service;
+
+ mp_obj_list_append(service->char_list, MP_OBJ_FROM_PTR(chara));
+}
+
+
+void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) {
+ if (adv_data->connectable) {
+ ble_drv_gap_event_handler_set(device, gap_event_handler);
+ ble_drv_gatts_event_handler_set(device, gatts_event_handler);
+ }
+
+ ble_drv_advertise_data(adv_data);
+}
+
+void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) {
+ (void)device;
+
+ ble_drv_advertise_stop();
+}
+
+void common_hal_bleio_device_connect(bleio_device_obj_t *device) {
+ ble_drv_gap_event_handler_set(device, gap_event_handler);
+
+ ble_drv_connect(device);
+
+ while (device->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ run_background_tasks();
+// __asm volatile ("wfi");
+ }
+
+ ble_drv_gattc_event_handler_set(device, gattc_event_handler);
+
+ // TODO: read name
+
+ // find services
+ bool found_service = ble_drv_discover_services(device, BLE_GATT_HANDLE_START, disc_add_service);
+ while (found_service) {
+ const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list);
+ const bleio_service_obj_t *service = service_list->items[service_list->len - 1];
+
+ found_service = ble_drv_discover_services(device, service->end_handle + 1, disc_add_service);
+ }
+
+ // find characteristics in each service
+ const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list);
+ for (size_t i = 0; i < service_list->len; ++i) {
+ bleio_service_obj_t *service = service_list->items[i];
+
+ bool found_char = ble_drv_discover_characteristic(device, service, service->start_handle, disc_add_char);
+ while (found_char) {
+ const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list);
+ const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1];
+
+ const uint16_t next_handle = characteristic->handle + 1;
+ if (next_handle >= service->end_handle) {
+ break;
+ }
+
+ found_char = ble_drv_discover_characteristic(device, service, next_handle, disc_add_char);
+ }
+ }
+}
+
+void common_hal_bleio_device_disconnect(bleio_device_obj_t *device) {
+ ble_drv_disconnect(device);
+}
diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c
index ed1987144..0eb50a1f6 100644
--- a/ports/nrf/common-hal/bleio/Scanner.c
+++ b/ports/nrf/common-hal/bleio/Scanner.c
@@ -29,8 +29,9 @@
#include "ble_drv.h"
#include "py/mphal.h"
-#include "shared-bindings/bleio/Scanner.h"
#include "shared-bindings/bleio/ScanEntry.h"
+#include "shared-bindings/bleio/Scanner.h"
+#include "shared-module/bleio/ScanEntry.h"
STATIC void adv_event_handler(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data) {
// TODO: Don't add new entry for each item, group by address and update
diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c
index e421036ae..1ab1d9337 100644
--- a/ports/nrf/drivers/bluetooth/ble_drv.c
+++ b/ports/nrf/drivers/bluetooth/ble_drv.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -34,6 +35,8 @@
#define NRF52 // Needed for SD132 v2
#endif
+#include "shared-module/bleio/Device.h"
+#include "py/objstr.h"
#include "py/runtime.h"
#include "supervisor/shared/translate.h"
#include "ble_drv.h"
@@ -41,15 +44,10 @@
#include "nrf_sdm.h"
#include "nrfx_power.h"
#include "ble_gap.h"
+#include "ble_hci.h"
#include "ble.h" // sd_ble_uuid_encode
-
-#define BLE_DRIVER_VERBOSE 0
-#if BLE_DRIVER_VERBOSE
#define BLE_DRIVER_LOG printf
-#else
-#define BLE_DRIVER_LOG(...)
-#endif
#define BLE_ADV_LENGTH_FIELD_SIZE 1
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
@@ -61,8 +59,8 @@
#define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout.
#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS)
-#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS)
-#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS)
+#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
+#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS)
#define BLE_SLAVE_LATENCY 0
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
@@ -81,8 +79,8 @@ static volatile bool m_tx_in_progress;
static ble_drv_gap_evt_callback_t gap_event_handler;
static ble_drv_gatts_evt_callback_t gatts_event_handler;
-static mp_obj_t mp_gap_observer;
-static mp_obj_t mp_gatts_observer;
+static bleio_device_obj_t *mp_gap_observer;
+static bleio_device_obj_t *mp_gatts_observer;
static volatile bool m_primary_service_found;
static volatile bool m_characteristic_found;
@@ -95,10 +93,11 @@ static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler;
static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle;
static bleio_scanner_obj_t *mp_adv_observer;
-static mp_obj_t mp_gattc_observer;
-static mp_obj_t mp_gattc_disc_service_observer;
-static mp_obj_t mp_gattc_disc_char_observer;
+static bleio_device_obj_t *mp_gattc_observer;
+static bleio_device_obj_t *mp_gattc_disc_service_observer;
+static bleio_service_obj_t *mp_gattc_disc_char_observer;
static bleio_characteristic_obj_t *mp_gattc_char_data_observer;
+static bleio_address_obj_t *mp_connect_address;
#if (BLUETOOTH_SD == 140)
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
@@ -123,18 +122,6 @@ uint32_t ble_drv_stack_enable(void) {
m_adv_in_progress = false;
m_tx_in_progress = false;
-#if BLUETOOTH_LFCLK_RC
- nrf_clock_lf_cfg_t clock_config = {
- .source = NRF_CLOCK_LF_SRC_RC,
- .rc_ctiv = 16,
- .rc_temp_ctiv = 2,
-#if (BLE_API_VERSION == 4)
- .accuracy = 0
-#else
- .xtal_accuracy = 0
-#endif
- };
-#else
nrf_clock_lf_cfg_t clock_config = {
.source = NRF_CLOCK_LF_SRC_XTAL,
.rc_ctiv = 0,
@@ -145,23 +132,22 @@ uint32_t ble_drv_stack_enable(void) {
.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
#endif
};
-#endif
#if (BLUETOOTH_SD == 140)
// The SD takes over the POWER IRQ and will fail if the IRQ is already in use
nrfx_power_uninit();
#endif
- uint32_t err_code = sd_softdevice_enable(&clock_config,
- softdevice_assert_handler);
-
- BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code);
+ uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler);
+ if (err_code != NRF_SUCCESS)
+ BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code);
- err_code = sd_nvic_EnableIRQ(SWI2_EGU2_IRQn);
-
- BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code);
+ err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
+ if (err_code != NRF_SUCCESS)
+ BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code);
// Enable BLE stack.
+ uint32_t app_ram_start;
#if (BLE_API_VERSION == 2)
ble_enable_params_t ble_enable_params;
memset(&ble_enable_params, 0x00, sizeof(ble_enable_params));
@@ -169,48 +155,17 @@ uint32_t ble_drv_stack_enable(void) {
ble_enable_params.gatts_enable_params.service_changed = 0;
ble_enable_params.gap_enable_params.periph_conn_count = 1;
ble_enable_params.gap_enable_params.central_conn_count = 1;
-#endif
-#if (BLE_API_VERSION == 2)
- uint32_t app_ram_start = 0x200039c0;
+ app_ram_start = 0x200039c0;
err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); // 8K SD headroom from linker script.
- BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start);
#else
- uint32_t app_ram_start = 0x20004000;
+ app_ram_start = 0x20004000;
err_code = sd_ble_enable(&app_ram_start);
- BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start);
#endif
-
- BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code);
-
- // set up security mode
- ble_gap_conn_params_t gap_conn_params;
- ble_gap_conn_sec_mode_t sec_mode;
-
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
-
- const char device_name[] = "micr";
-
- if ((err_code = sd_ble_gap_device_name_set(&sec_mode,
- (const uint8_t *)device_name,
- strlen(device_name))) != 0) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- translate("Cannot apply GAP parameters.")));
- }
-
- // set connection parameters
- memset(&gap_conn_params, 0, sizeof(gap_conn_params));
-
- gap_conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL;
- gap_conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL;
- gap_conn_params.slave_latency = BLE_SLAVE_LATENCY;
- gap_conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT;
-
- if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) {
-
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- translate("Cannot set PPCP parameters.")));
+ if (err_code != NRF_SUCCESS) {
+ BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start);
+ BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code);
}
return err_code;
@@ -223,9 +178,10 @@ void ble_drv_stack_disable(void) {
uint8_t ble_drv_stack_enabled(void) {
uint8_t is_enabled;
uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
- (void)err_code;
- BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code);
+ if (err_code != NRF_SUCCESS) {
+ BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code);
+ }
return is_enabled;
}
@@ -256,10 +212,10 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr) {
memcpy(p_addr->addr, local_ble_addr.addr, 6);
}
-bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) {
+bool ble_drv_uuid_add_vs(uint8_t *uuid, uint8_t *idx) {
SD_TEST_OR_ENABLE();
- if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) {
+ if (sd_ble_uuid_vs_add((ble_uuid128_t const *)uuid, idx) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not add Vendor Specific 128-bit UUID.")));
}
@@ -284,9 +240,7 @@ void ble_drv_service_add(bleio_service_obj_t *service) {
service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
}
- if (sd_ble_gatts_service_add(service_type,
- &uuid,
- &service->handle) != 0) {
+ if (sd_ble_gatts_service_add(service_type, &uuid, &service->handle) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not add Service.")));
}
@@ -372,59 +326,66 @@ bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) {
return true;
}
-bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
+// TODO: Replace with just bleio_device_obj_t + data
+bool ble_drv_advertise_data(bleio_advertisement_data_t *adv_params) {
SD_TEST_OR_ENABLE();
uint8_t byte_pos = 0;
uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
- if (p_adv_params->device_name_len > 0) {
- ble_gap_conn_sec_mode_t sec_mode;
+ GET_STR_DATA_LEN(adv_params->device_name, name_data, name_len);
+ if (name_len > 0) {
+ ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
if (sd_ble_gap_device_name_set(&sec_mode,
- p_adv_params->p_device_name,
- p_adv_params->device_name_len) != 0) {
+ name_data,
+ name_len) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not apply device name in the stack.")));
}
- BLE_DRIVER_LOG("Device name applied\n");
-
- adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + p_adv_params->device_name_len);
+ adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + name_len);
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
+
+ // TODO: Shorten if too long
adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
- memcpy(&adv_data[byte_pos], p_adv_params->p_device_name, p_adv_params->device_name_len);
- // increment position counter to see if it fits, and in case more content should
- // follow in this adv packet.
- byte_pos += p_adv_params->device_name_len;
+
+ memcpy(&adv_data[byte_pos], name_data, name_len);
+
+ byte_pos += name_len;
}
- // Add FLAGS only if manually controlled data has not been used.
- if (p_adv_params->data_len == 0) {
- // set flags, default to disc mode
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(adv_params->data, &bufinfo, MP_BUFFER_WRITE);
+
+ // set flags, default to disc mode
+ if (bufinfo.len == 0) {
adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE);
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
+
adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS;
byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE;
+
adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
byte_pos += 1;
}
- if (p_adv_params->num_of_services > 0) {
-
+ const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(adv_params->services);
+ if (service_list->len > 0) {
bool type_16bit_present = false;
bool type_128bit_present = false;
- for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
- bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i];
- if (p_service->uuid->type == UUID_TYPE_16BIT) {
+ for (size_t i = 0; i < service_list->len; ++i) {
+ const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
+
+ if (service->uuid->type == UUID_TYPE_16BIT) {
type_16bit_present = true;
}
- if (p_service->uuid->type == UUID_TYPE_128BIT) {
+ if (service->uuid->type == UUID_TYPE_128BIT) {
type_128bit_present = true;
}
}
@@ -441,13 +402,17 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
uint8_t uuid_total_size = 0;
uint8_t encoded_size = 0;
- for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
- bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i];
+ for (size_t i = 0; i < service_list->len; ++i) {
+ const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
+
+ if (service->uuid->type != UUID_TYPE_16BIT) {
+ continue;
+ }
ble_uuid_t uuid;
- uuid.type = p_service->uuid->type;
- uuid.uuid = p_service->uuid->value[0];
- uuid.uuid += p_service->uuid->value[1] << 8;
+ uuid.type = BLE_UUID_TYPE_BLE;
+ uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8);
+
// calculate total size of uuids
if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
@@ -460,19 +425,8 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
translate("Can encode UUID into the advertisement packet.")));
}
- BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
- for (uint8_t j = 0; j < encoded_size; j++) {
- BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]);
- }
- BLE_DRIVER_LOG("\n");
-
uuid_total_size += encoded_size; // size of entry
byte_pos += encoded_size; // relative to adv data packet
- BLE_DRIVER_LOG("ADV: uuid size: %u, type: %u, uuid: %x%x, vs_idx: %u\n",
- encoded_size, p_service->p_uuid->type,
- p_service->p_uuid->value[1],
- p_service->p_uuid->value[0],
- p_service->p_uuid->uuid_vs_idx);
}
adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
@@ -490,13 +444,16 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
uint8_t uuid_total_size = 0;
uint8_t encoded_size = 0;
- for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
- bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i];
+ for (size_t i = 0; i < service_list->len; ++i) {
+ const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
+
+ if (service->uuid->type != UUID_TYPE_128BIT) {
+ continue;
+ }
ble_uuid_t uuid;
- uuid.type = p_service->uuid->uuid_vs_idx;
- uuid.uuid = p_service->uuid->value[0];
- uuid.uuid += p_service->uuid->value[1] << 8;
+ uuid.type = service->uuid->uuid_vs_idx;
+ uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8);
// calculate total size of uuids
if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
@@ -510,51 +467,37 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
translate("Can encode UUID into the advertisement packet.")));
}
- BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
- for (uint8_t j = 0; j < encoded_size; j++) {
- BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]);
- }
- BLE_DRIVER_LOG("\n");
-
uuid_total_size += encoded_size; // size of entry
byte_pos += encoded_size; // relative to adv data packet
- BLE_DRIVER_LOG("ADV: uuid size: %u, type: %x%x, uuid: %u, vs_idx: %u\n",
- encoded_size, p_service->p_uuid->type,
- p_service->p_uuid->value[1],
- p_service->p_uuid->value[0],
- p_service->p_uuid->uuid_vs_idx);
}
adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
}
}
- if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
- if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
+ if (bufinfo.len > 0) {
+ if (byte_pos + bufinfo.len > BLE_GAP_ADV_MAX_SIZE) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not fit data into the advertisement packet.")));
}
- memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len);
- byte_pos += p_adv_params->data_len;
+ memcpy(adv_data, bufinfo.buf, bufinfo.len);
+ byte_pos += bufinfo.len;
}
- // scan response data not set
uint32_t err_code;
#if (BLUETOOTH_SD == 132)
if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code));
}
- BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos);
#endif
static ble_gap_adv_params_t m_adv_params;
// initialize advertising params
memset(&m_adv_params, 0, sizeof(m_adv_params));
- if (p_adv_params->connectable) {
+ if (adv_params->connectable) {
#if (BLUETOOTH_SD == 140)
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
#else
@@ -643,8 +586,8 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui
}
void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
- ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph);
- uint16_t conn_handle = peripheral->conn_handle;
+ bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
+ uint16_t conn_handle = device->conn_handle;
ble_gatts_value_t gatts_value;
memset(&gatts_value, 0, sizeof(gatts_value));
@@ -662,8 +605,8 @@ void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_
}
void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
- ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph);
- uint16_t conn_handle = peripheral->conn_handle;
+ bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
+ uint16_t conn_handle = device->conn_handle;
ble_gatts_hvx_params_t hvx_params;
uint16_t hvx_len = bufinfo->len;
@@ -676,7 +619,9 @@ void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer
hvx_params.p_data = bufinfo->buf;
while (m_tx_in_progress) {
- ;
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+#endif
}
m_tx_in_progress = true;
@@ -687,50 +632,49 @@ void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer
}
}
-void ble_drv_gap_event_handler_set(mp_obj_t obj, ble_drv_gap_evt_callback_t evt_handler) {
- mp_gap_observer = obj;
+void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler) {
+ mp_gap_observer = device;
gap_event_handler = evt_handler;
}
-void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler) {
- mp_gatts_observer = obj;
+void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler) {
+ mp_gatts_observer = device;
gatts_event_handler = evt_handler;
}
-void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler) {
- mp_gattc_observer = obj;
+void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler) {
+ mp_gattc_observer = device;
gattc_event_handler = evt_handler;
}
-void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler) {
- mp_adv_observer = self;
+void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *device, ble_drv_adv_evt_callback_t evt_handler) {
+ mp_adv_observer = device;
adv_event_handler = evt_handler;
}
-
void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) {
bleio_service_obj_t *service = characteristic->service;
- ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(service->periph);
+ bleio_device_obj_t *device = MP_OBJ_TO_PTR(service->device);
mp_gattc_char_data_observer = characteristic;
gattc_char_data_handle = cb;
- const uint32_t err_code = sd_ble_gattc_read(peripheral->conn_handle,
- characteristic->handle,
- 0);
+ const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0);
if (err_code != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code));
}
while (gattc_char_data_handle != NULL) {
- ;
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+#endif
}
}
void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
- ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph);
- uint16_t conn_handle = peripheral->conn_handle;
+ bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
+ uint16_t conn_handle = device->conn_handle;
ble_gattc_write_params_t write_params;
write_params.write_op = BLE_GATT_OP_WRITE_REQ;
@@ -753,10 +697,13 @@ void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_
translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
}
- while (m_write_done != true) {
- ;
+ while (m_write_done != true) {
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+#endif
}
}
+
void ble_drv_scan_start(uint16_t interval, uint16_t window) {
SD_TEST_OR_ENABLE();
@@ -798,109 +745,108 @@ void ble_drv_scan_stop(void) {
sd_ble_gap_scan_stop();
}
-void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) {
- SD_TEST_OR_ENABLE();
+STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data) {
+ if (memcmp(data->p_peer_addr, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) {
+ ble_drv_adv_report_handler_set(NULL, NULL);
- ble_gap_scan_params_t scan_params;
- scan_params.active = 1;
- scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
- scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
- scan_params.timeout = 0; // Infinite
+ ble_gap_scan_params_t scan_params;
+ memset(&scan_params, 0, sizeof(scan_params));
- ble_gap_addr_t addr;
- memset(&addr, 0, sizeof(addr));
+ scan_params.active = 1;
+ scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
+ scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS);
+ scan_params.timeout = 0;
- addr.addr_type = addr_type;
- memcpy(addr.addr, p_addr, 6);
+ ble_gap_addr_t addr;
+ memset(&addr, 0, sizeof(addr));
- BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n",
- addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5], addr.addr_type);
+ addr.addr_type = data->addr_type;
+ memcpy(addr.addr, data->p_peer_addr, BLEIO_ADDRESS_BYTES);
- ble_gap_conn_params_t conn_params;
+ BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n",
+ addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], addr.addr_type);
+
+ ble_gap_conn_params_t conn_params = {
+ .min_conn_interval = BLE_MIN_CONN_INTERVAL,
+ .max_conn_interval = BLE_MAX_CONN_INTERVAL,
+ .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT,
+ .slave_latency = BLE_SLAVE_LATENCY,
+ };
+
+ uint32_t err_code;
+ #if (BLE_API_VERSION == 2)
+ if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) {
+ #else
+ if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) {
+ #endif
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
+ "Can not connect. status: 0x" HEX2_FMT, (uint16_t)err_code));
+ }
+ }
+}
-// (void)sd_ble_gap_ppcp_get(&conn_params);
+void ble_drv_connect(bleio_device_obj_t *device) {
+ SD_TEST_OR_ENABLE();
- // set connection parameters
- memset(&conn_params, 0, sizeof(conn_params));
+ mp_connect_address = &device->address;
+ ble_drv_adv_report_handler_set(NULL, ble_drv_connect_scan_callback);
- conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL;
- conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL;
- conn_params.slave_latency = BLE_SLAVE_LATENCY;
- conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT;
+ ble_drv_scan_start(100, 100);
+}
- uint32_t err_code;
-#if (BLE_API_VERSION == 2)
- if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) {
-#else
- if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) {
-#endif
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
- translate("Can not connect. status: 0x%02x"), (uint16_t)err_code));
- }
+void ble_drv_disconnect(bleio_device_obj_t *device) {
+ sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}
-bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) {
- BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n",
- conn_handle);
+bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) {
+ BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle);
- mp_gattc_disc_service_observer = obj;
+ mp_gattc_disc_service_observer = device;
disc_add_service_handler = cb;
m_primary_service_found = false;
uint32_t err_code;
- err_code = sd_ble_gattc_primary_services_discover(conn_handle,
- start_handle,
- NULL);
+ err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL);
if (err_code != 0) {
return false;
}
// busy loop until last service has been iterated
while (disc_add_service_handler != NULL) {
- ;
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+#endif
}
- if (m_primary_service_found) {
- return true;
- } else {
- return false;
- }
+ return m_primary_service_found;
}
-bool ble_drv_discover_characteristic(mp_obj_t obj,
- uint16_t conn_handle,
- uint16_t start_handle,
- uint16_t end_handle,
- ble_drv_disc_add_char_callback_t cb) {
- BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n",
- conn_handle);
+bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb) {
+ BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle);
- mp_gattc_disc_char_observer = obj;
+ mp_gattc_disc_char_observer = service;
disc_add_char_handler = cb;
ble_gattc_handle_range_t handle_range;
handle_range.start_handle = start_handle;
- handle_range.end_handle = end_handle;
+ handle_range.end_handle = service->end_handle;
m_characteristic_found = false;
- uint32_t err_code;
- err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
+ uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range);
if (err_code != 0) {
return false;
}
// busy loop until last service has been iterated
while (disc_add_char_handler != NULL) {
- ;
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+#endif
}
- if (m_characteristic_found) {
- return true;
- } else {
- return false;
- }
+ return m_characteristic_found;
}
void ble_drv_discover_descriptors(void) {
@@ -908,12 +854,8 @@ void ble_drv_discover_descriptors(void) {
}
static void ble_evt_handler(ble_evt_t * p_ble_evt) {
-// S132 event ranges.
-// Common 0x01 -> 0x0F
-// GAP 0x10 -> 0x2F
-// GATTC 0x30 -> 0x4F
-// GATTS 0x50 -> 0x6F
-// L2CAP 0x70 -> 0x8F
+ printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id);
+
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED:
BLE_DRIVER_LOG("GAP CONNECT\n");
@@ -1104,7 +1046,7 @@ static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attr
static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)] __attribute__ ((aligned (4)));
#endif
-void SWI2_EGU2_IRQHandler(void) {
+void SD_EVT_IRQHandler(void) {
uint32_t evt_id;
uint32_t err_code;
do {
diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h
index 8c6bd6ce3..e5282db73 100644
--- a/ports/nrf/drivers/bluetooth/ble_drv.h
+++ b/ports/nrf/drivers/bluetooth/ble_drv.h
@@ -32,12 +32,12 @@
#include <stdint.h>
#include <stdbool.h>
+#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/Characteristic.h"
+#include "shared-module/bleio/Device.h"
#include "shared-module/bleio/Scanner.h"
#include "shared-module/bleio/Service.h"
-#include "modubluepy.h"
-
typedef struct {
uint8_t addr[6];
uint8_t addr_type;
@@ -75,12 +75,12 @@ typedef struct {
uint16_t value_handle;
} ble_drv_char_data_t;
-typedef void (*ble_drv_gap_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data);
-typedef void (*ble_drv_gatts_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data);
-typedef void (*ble_drv_gattc_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data);
-typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data);
-typedef void (*ble_drv_disc_add_service_callback_t)(mp_obj_t self, ble_drv_service_data_t * p_service_data);
-typedef void (*ble_drv_disc_add_char_callback_t)(mp_obj_t self, ble_drv_char_data_t * p_desc_data);
+typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data);
+typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data);
+typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data);
+typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data);
+typedef void (*ble_drv_disc_add_service_callback_t)(bleio_device_obj_t *device, ble_drv_service_data_t * p_service_data);
+typedef void (*ble_drv_disc_add_char_callback_t)(bleio_service_obj_t *service, ble_drv_char_data_t * p_desc_data);
typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data);
uint32_t ble_drv_stack_enable(void);
@@ -97,15 +97,15 @@ void ble_drv_service_add(bleio_service_obj_t *service);
bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic);
-bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params);
+bool ble_drv_advertise_data(bleio_advertisement_data_t *p_adv_params);
void ble_drv_advertise_stop(void);
-void ble_drv_gap_event_handler_set(mp_obj_t obs, ble_drv_gap_evt_callback_t evt_handler);
+void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler);
-void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler);
+void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler);
-void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler);
+void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler);
void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data);
@@ -125,15 +125,13 @@ void ble_drv_scan_stop(void);
void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler);
-void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type);
+void ble_drv_connect(bleio_device_obj_t *device);
+
+void ble_drv_disconnect(bleio_device_obj_t *device);
-bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb);
+bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb);
-bool ble_drv_discover_characteristic(mp_obj_t obj,
- uint16_t conn_handle,
- uint16_t start_handle,
- uint16_t end_handle,
- ble_drv_disc_add_char_callback_t cb);
+bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb);
void ble_drv_discover_descriptors(void);
diff --git a/ports/nrf/drivers/bluetooth/ble_uart.h b/ports/nrf/drivers/bluetooth/ble_uart.h
index e67176a26..336624cd3 100644
--- a/ports/nrf/drivers/bluetooth/ble_uart.h
+++ b/ports/nrf/drivers/bluetooth/ble_uart.h
@@ -29,7 +29,6 @@
#if BLUETOOTH_SD
-#include "modubluepy.h"
#include "ble_drv.h"
void ble_uart_init0(void);
diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h
deleted file mode 100644
index e301f0476..000000000
--- a/ports/nrf/modules/ubluepy/modubluepy.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Glenn Ruben Bakke
- *
- * 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 UBLUEPY_H__
-#define UBLUEPY_H__
-
-/* Examples:
-
-Advertisment:
-
-from ubluepy import Peripheral
-p = Peripheral()
-p.advertise(device_name="MicroPython")
-
-DB setup:
-
-from ubluepy import Service, Characteristic, UUID, Peripheral, constants
-from pyb import LED
-
-def event_handler(id, handle, data):
- print("BLE event:", id, "handle:", handle)
- print(data)
-
- if id == constants.EVT_GAP_CONNECTED:
- # connected
- LED(2).on()
- elif id == constants.EVT_GAP_DISCONNECTED:
- # disconnect
- LED(2).off()
- elif id == 80:
- print("id 80, data:", data)
-
-# u0 = UUID("0x180D") # HRM service
-# u1 = UUID("0x2A37") # HRM measurement
-
-u0 = UUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
-u1 = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
-u2 = UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e")
-s = Service(u0)
-c0 = Characteristic(u1, props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP)
-c1 = Characteristic(u2, props = Characteristic.PROP_NOTIFY, attrs = Characteristic.ATTR_CCCD)
-s.addCharacteristic(c0)
-s.addCharacteristic(c1)
-p = Peripheral()
-p.addService(s)
-p.setConnectionHandler(event_handler)
-p.advertise(device_name="micr", services=[s])
-
-*/
-
-#include "common-hal/bleio/UUID.h"
-#include "py/obj.h"
-
-extern const mp_obj_type_t ubluepy_peripheral_type;
-
-typedef enum {
- UBLUEPY_ADDR_TYPE_PUBLIC = 0,
- UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1,
- UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2,
- UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3,
-} ubluepy_addr_type_t;
-
-typedef enum {
- UBLUEPY_ROLE_PERIPHERAL,
- UBLUEPY_ROLE_CENTRAL
-} ubluepy_role_type_t;
-
-typedef struct _ubluepy_peripheral_obj_t {
- mp_obj_base_t base;
- ubluepy_role_type_t role;
- volatile uint16_t conn_handle;
- mp_obj_t delegate;
- mp_obj_t notif_handler;
- mp_obj_t conn_handler;
- mp_obj_t service_list;
-} ubluepy_peripheral_obj_t;
-
-typedef struct _ubluepy_advertise_data_t {
- uint8_t * p_device_name;
- uint8_t device_name_len;
- mp_obj_t * p_services;
- uint8_t num_of_services;
- uint8_t * p_data;
- uint8_t data_len;
- bool connectable;
-} ubluepy_advertise_data_t;
-
-typedef enum _ubluepy_prop_t {
- UBLUEPY_PROP_BROADCAST = 0x01,
- UBLUEPY_PROP_READ = 0x02,
- UBLUEPY_PROP_WRITE_WO_RESP = 0x04,
- UBLUEPY_PROP_WRITE = 0x08,
- UBLUEPY_PROP_NOTIFY = 0x10,
- UBLUEPY_PROP_INDICATE = 0x20,
- UBLUEPY_PROP_AUTH_SIGNED_WR = 0x40,
-} ubluepy_prop_t;
-
-typedef enum _ubluepy_attr_t {
- UBLUEPY_ATTR_CCCD = 0x01,
- UBLUEPY_ATTR_SCCD = 0x02,
-} ubluepy_attr_t;
-
-#endif // UBLUEPY_H__
diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c
deleted file mode 100644
index 3b1a0d279..000000000
--- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2017 Glenn Ruben Bakke
- *
- * 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 <string.h>
-#include "py/obj.h"
-#include "py/runtime.h"
-#include "py/objstr.h"
-#include "py/objlist.h"
-
-#if MICROPY_PY_UBLUEPY
-
-#include "ble_drv.h"
-#include "common-hal/bleio/UUID.h"
-#include "shared-bindings/bleio/Characteristic.h"
-#include "shared-bindings/bleio/Service.h"
-#include "shared-bindings/bleio/UUID.h"
-
-STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) {
- ubluepy_peripheral_obj_t * self = (ubluepy_peripheral_obj_t *)o;
- (void)self;
- mp_printf(print, "Peripheral(conn_handle: " HEX2_FMT ")",
- self->conn_handle);
-}
-
-STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (event_id == 16) { // connect event
- self->conn_handle = conn_handle;
- } else if (event_id == 17) { // disconnect event
- self->conn_handle = 0xFFFF; // invalid connection handle
- }
-
- if (self->conn_handler != mp_const_none) {
- mp_obj_t args[3];
- mp_uint_t num_of_args = 3;
- args[0] = MP_OBJ_NEW_SMALL_INT(event_id);
- args[1] = MP_OBJ_NEW_SMALL_INT(conn_handle);
- if (data != NULL) {
- args[2] = mp_obj_new_bytearray_by_ref(length, data);
- } else {
- args[2] = mp_const_none;
- }
-
- // for now hard-code all events to conn_handler
- mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args);
- }
-
- (void)self;
-}
-
-STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (self->conn_handler != mp_const_none) {
- mp_obj_t args[3];
- mp_uint_t num_of_args = 3;
- args[0] = MP_OBJ_NEW_SMALL_INT(event_id);
- args[1] = MP_OBJ_NEW_SMALL_INT(attr_handle);
- if (data != NULL) {
- args[2] = mp_obj_new_bytearray_by_ref(length, data);
- } else {
- args[2] = mp_const_none;
- }
-
- // for now hard-code all events to conn_handler
- mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args);
- }
-
-}
-
-#if MICROPY_PY_UBLUEPY_CENTRAL
-
-static volatile bool m_disc_evt_received;
-
-STATIC void gattc_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- (void)self;
- m_disc_evt_received = true;
-}
-#endif
-
-STATIC mp_obj_t ubluepy_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
- enum {
- ARG_NEW_DEVICE_ADDR,
- ARG_NEW_ADDR_TYPE
- };
-
- static const mp_arg_t allowed_args[] = {
- { ARG_NEW_DEVICE_ADDR, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { ARG_NEW_ADDR_TYPE, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- // parse args
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- ubluepy_peripheral_obj_t *s = m_new_obj(ubluepy_peripheral_obj_t);
- s->base.type = type;
-
- s->delegate = mp_const_none;
- s->conn_handler = mp_const_none;
- s->notif_handler = mp_const_none;
- s->conn_handle = 0xFFFF;
-
- s->service_list = mp_obj_new_list(0, NULL);
-
- return MP_OBJ_FROM_PTR(s);
-}
-
-/// \method withDelegate(DefaultDelegate)
-/// Set delegate instance for handling Bluetooth LE events.
-///
-STATIC mp_obj_t peripheral_with_delegate(mp_obj_t self_in, mp_obj_t delegate) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->delegate = delegate;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_with_delegate_obj, peripheral_with_delegate);
-
-/// \method setNotificationHandler(func)
-/// Set handler for Bluetooth LE notification events.
-///
-STATIC mp_obj_t peripheral_set_notif_handler(mp_obj_t self_in, mp_obj_t func) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->notif_handler = func;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_notif_handler_obj, peripheral_set_notif_handler);
-
-/// \method setConnectionHandler(func)
-/// Set handler for Bluetooth LE connection events.
-///
-STATIC mp_obj_t peripheral_set_conn_handler(mp_obj_t self_in, mp_obj_t func) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->conn_handler = func;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_conn_handler_obj, peripheral_set_conn_handler);
-
-#if MICROPY_PY_UBLUEPY_PERIPHERAL
-
-/// \method advertise(device_name, [service=[service1, service2, ...]], [data=bytearray], [connectable=True])
-/// Start advertising. Connectable advertisement type by default.
-///
-STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_device_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_services, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- self->role = UBLUEPY_ROLE_PERIPHERAL;
-
- // parse args
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- // ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_obj_t device_name_obj = args[0].u_obj;
- mp_obj_t service_obj = args[1].u_obj;
- mp_obj_t data_obj = args[2].u_obj;
- mp_obj_t connectable_obj = args[3].u_obj;
-
- ubluepy_advertise_data_t adv_data;
- memset(&adv_data, 0, sizeof(ubluepy_advertise_data_t));
-
- if (device_name_obj != mp_const_none && MP_OBJ_IS_STR(device_name_obj)) {
- GET_STR_DATA_LEN(device_name_obj, str_data, str_len);
-
- adv_data.p_device_name = (uint8_t *)str_data;
- adv_data.device_name_len = str_len;
- }
-
- if (service_obj != mp_const_none) {
- mp_obj_t * services = NULL;
- mp_uint_t num_services;
- mp_obj_get_array(service_obj, &num_services, &services);
-
- if (num_services > 0) {
- adv_data.p_services = services;
- adv_data.num_of_services = num_services;
- }
- }
-
- if (data_obj != mp_const_none) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ);
-
- if (bufinfo.len > 0) {
- adv_data.p_data = bufinfo.buf;
- adv_data.data_len = bufinfo.len;
- }
- }
-
- adv_data.connectable = true;
- if (connectable_obj != mp_const_none && !(mp_obj_is_true(connectable_obj))) {
- adv_data.connectable = false;
- } else {
- ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler);
- ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(self), gatts_event_handler);
- }
-
- (void)ble_drv_advertise_data(&adv_data);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_advertise_obj, 0, peripheral_advertise);
-
-/// \method advertise_stop()
-/// Stop advertisement if any onging advertisement.
-///
-STATIC mp_obj_t peripheral_advertise_stop(mp_obj_t self_in) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- (void)self;
-
- ble_drv_advertise_stop();
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_advertise_stop_obj, peripheral_advertise_stop);
-
-#endif // MICROPY_PY_UBLUEPY_PERIPHERAL
-
-/// \method disconnect()
-/// disconnect connection.
-///
-STATIC mp_obj_t peripheral_disconnect(mp_obj_t self_in) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- (void)self;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_disconnect_obj, peripheral_disconnect);
-
-/// \method addService(Service)
-/// Add service to the Peripheral.
-///
-STATIC mp_obj_t peripheral_add_service(mp_obj_t self_in, mp_obj_t service) {
- ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in);
- bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service);
-
- p_service->periph = self_in;
-
- mp_obj_list_append(self->service_list, service);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_add_service_obj, peripheral_add_service);
-
-/// \method getServices()
-/// Return list with all service registered in the Peripheral.
-///
-STATIC mp_obj_t peripheral_get_services(mp_obj_t self_in) {
- ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in);
-
- return self->service_list;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_get_services_obj, peripheral_get_services);
-
-#if MICROPY_PY_UBLUEPY_CENTRAL
-
-void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_data) {
- bleio_service_obj_t * p_service = m_new_obj(bleio_service_obj_t);
- p_service->base.type = &bleio_service_type;
-
- bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t);
- p_uuid->base.type = &bleio_uuid_type;
-
- p_service->uuid = p_uuid;
-
- p_uuid->type = p_service_data->uuid_type;
- p_uuid->value[0] = p_service_data->uuid & 0xFF;
- p_uuid->value[1] = p_service_data->uuid >> 8;
-
- p_service->handle = p_service_data->start_handle;
- p_service->start_handle = p_service_data->start_handle;
- p_service->end_handle = p_service_data->end_handle;
-
- p_service->char_list = mp_obj_new_list(0, NULL);
-
- peripheral_add_service(self, MP_OBJ_FROM_PTR(p_service));
-}
-
-void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data) {
- bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in);
- bleio_characteristic_obj_t * p_char = m_new_obj(bleio_characteristic_obj_t);
- p_char->base.type = &bleio_characteristic_type;
-
- bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t);
- p_uuid->base.type = &bleio_uuid_type;
-
- p_char->uuid = p_uuid;
-
- p_uuid->type = p_desc_data->uuid_type;
- p_uuid->value[0] = p_desc_data->uuid & 0xFF;
- p_uuid->value[1] = p_desc_data->uuid >> 8;
-
- // add characteristic specific data from discovery
- p_char->props.broadcast = p_desc_data->props.broadcast;
- p_char->props.indicate = p_desc_data->props.indicate;
- p_char->props.notify = p_desc_data->props.notify;
- p_char->props.read = p_desc_data->props.read;
- p_char->props.write = p_desc_data->props.write;
- p_char->props.write_wo_resp = p_desc_data->props.write_wo_resp;
- p_char->handle = p_desc_data->value_handle;
-
- // equivalent to ubluepy_service.c - service_add_characteristic()
- // except the registration of the characteristic towards the bluetooth stack
- p_char->service_handle = p_service->handle;
- p_char->service = p_service;
-
- mp_obj_list_append(p_service->char_list, MP_OBJ_FROM_PTR(p_char));
-}
-
-/// \method connect(device_address [, addr_type=ADDR_TYPE_PUBLIC])
-/// Connect to device peripheral with the given device address.
-/// addr_type can be either ADDR_TYPE_PUBLIC (default) or
-/// ADDR_TYPE_RANDOM_STATIC.
-///
-STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_obj_t dev_addr = pos_args[1];
-
- self->role = UBLUEPY_ROLE_CENTRAL;
-
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_addr_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UBLUEPY_ADDR_TYPE_PUBLIC } },
- };
-
- // parse args
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- uint8_t addr_type = args[0].u_int;
-
- ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler);
-
- if (MP_OBJ_IS_STR(dev_addr)) {
- GET_STR_DATA_LEN(dev_addr, str_data, str_len);
- if (str_len == 17) { // Example "11:22:33:aa:bb:cc"
-
- uint8_t * p_addr = m_new(uint8_t, 6);
-
- p_addr[0] = unichar_xdigit_value(str_data[16]);
- p_addr[0] += unichar_xdigit_value(str_data[15]) << 4;
- p_addr[1] = unichar_xdigit_value(str_data[13]);
- p_addr[1] += unichar_xdigit_value(str_data[12]) << 4;
- p_addr[2] = unichar_xdigit_value(str_data[10]);
- p_addr[2] += unichar_xdigit_value(str_data[9]) << 4;
- p_addr[3] = unichar_xdigit_value(str_data[7]);
- p_addr[3] += unichar_xdigit_value(str_data[6]) << 4;
- p_addr[4] = unichar_xdigit_value(str_data[4]);
- p_addr[4] += unichar_xdigit_value(str_data[3]) << 4;
- p_addr[5] = unichar_xdigit_value(str_data[1]);
- p_addr[5] += unichar_xdigit_value(str_data[0]) << 4;
-
- ble_drv_connect(p_addr, addr_type);
-
- m_del(uint8_t, p_addr, 6);
- }
- }
-
- // block until connected
- while (self->conn_handle == 0xFFFF) {
- ;
- }
-
- ble_drv_gattc_event_handler_set(MP_OBJ_FROM_PTR(self), gattc_event_handler);
-
- bool service_disc_retval = ble_drv_discover_services(self, self->conn_handle, 0x0001, disc_add_service);
-
- // continue discovery of primary services ...
- while (service_disc_retval) {
- // locate the last added service
- mp_obj_t * services = NULL;
- mp_uint_t num_services;
- mp_obj_get_array(self->service_list, &num_services, &services);
-
- bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[num_services - 1];
-
- service_disc_retval = ble_drv_discover_services(self,
- self->conn_handle,
- p_service->end_handle + 1,
- disc_add_service);
- }
-
- // For each service perform a characteristic discovery
- mp_obj_t * services = NULL;
- mp_uint_t num_services;
- mp_obj_get_array(self->service_list, &num_services, &services);
-
- for (uint16_t s = 0; s < num_services; s++) {
- bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[s];
- bool char_disc_retval = ble_drv_discover_characteristic(p_service,
- self->conn_handle,
- p_service->start_handle,
- p_service->end_handle,
- disc_add_char);
- // continue discovery of characteristics ...
- while (char_disc_retval) {
- mp_obj_t * characteristics = NULL;
- mp_uint_t num_chars;
- mp_obj_get_array(p_service->char_list, &num_chars, &characteristics);
-
- bleio_characteristic_obj_t * p_char = (bleio_characteristic_obj_t *)characteristics[num_chars - 1];
- uint16_t next_handle = p_char->handle + 1;
- if ((next_handle) < p_service->end_handle) {
- char_disc_retval = ble_drv_discover_characteristic(p_service,
- self->conn_handle,
- next_handle,
- p_service->end_handle,
- disc_add_char);
- } else {
- break;
- }
- }
- }
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_connect_obj, 2, peripheral_connect);
-
-#endif
-
-STATIC const mp_rom_map_elem_t ubluepy_peripheral_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_withDelegate), MP_ROM_PTR(&ubluepy_peripheral_with_delegate_obj) },
- { MP_ROM_QSTR(MP_QSTR_setNotificationHandler), MP_ROM_PTR(&ubluepy_peripheral_set_notif_handler_obj) },
- { MP_ROM_QSTR(MP_QSTR_setConnectionHandler), MP_ROM_PTR(&ubluepy_peripheral_set_conn_handler_obj) },
- { MP_ROM_QSTR(MP_QSTR_getServices), MP_ROM_PTR(&ubluepy_peripheral_get_services_obj) },
-#if MICROPY_PY_UBLUEPY_CENTRAL
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ubluepy_peripheral_connect_obj) },
-#if 0
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_getServiceByUUID), MP_ROM_PTR(&ubluepy_peripheral_get_service_by_uuid_obj) },
- { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_peripheral_get_chars_obj) },
- { MP_ROM_QSTR(MP_QSTR_getDescriptors), MP_ROM_PTR(&ubluepy_peripheral_get_descs_obj) },
- { MP_ROM_QSTR(MP_QSTR_waitForNotifications), MP_ROM_PTR(&ubluepy_peripheral_wait_for_notif_obj) },
- { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) },
- { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) },
-#endif // 0
-#endif // MICROPY_PY_UBLUEPY_CENTRAL
-#if MICROPY_PY_UBLUEPY_PERIPHERAL
- { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) },
- { MP_ROM_QSTR(MP_QSTR_advertise_stop), MP_ROM_PTR(&ubluepy_peripheral_advertise_stop_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_addService), MP_ROM_PTR(&ubluepy_peripheral_add_service_obj) },
-#if 0
- { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_add_char_obj) },
- { MP_ROM_QSTR(MP_QSTR_addDescriptor), MP_ROM_PTR(&ubluepy_peripheral_add_desc_obj) },
- { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) },
- { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) },
-#endif
-#endif
-#if MICROPY_PY_UBLUEPY_BROADCASTER
- { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) },
-#endif
-#if MICROPY_PY_UBLUEPY_OBSERVER
- // Nothing yet.
-#endif
-};
-
-STATIC MP_DEFINE_CONST_DICT(ubluepy_peripheral_locals_dict, ubluepy_peripheral_locals_dict_table);
-
-const mp_obj_type_t ubluepy_peripheral_type = {
- { &mp_type_type },
- .name = MP_QSTR_Peripheral,
- .print = ubluepy_peripheral_print,
- .make_new = ubluepy_peripheral_make_new,
- .locals_dict = (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict
-};
-
-#endif // MICROPY_PY_UBLUEPY
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index b710808b9..62a041ae9 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -129,21 +129,15 @@
#define CIRCUITPY_GAMEPAD_TICKS 0x1f
#if BLUETOOTH_SD
-#define MICROPY_PY_BLEIO (1)
-#define MICROPY_PY_BLE_NUS (0)
-#define MICROPY_PY_UBLUEPY (1)
-#define MICROPY_PY_UBLUEPY_PERIPHERAL (1)
-#define MICROPY_PY_UBLUEPY_CENTRAL (1)
-#define BLUETOOTH_WEBBLUETOOTH_REPL (0)
-#endif
-
-#ifndef MICROPY_PY_BLEIO
-#define MICROPY_PY_BLEIO (0)
+ #define MICROPY_PY_BLEIO (1)
+ #define MICROPY_PY_BLE_NUS (0)
+ #define BLUETOOTH_WEBBLUETOOTH_REPL (0)
+#else
+ #ifndef MICROPY_PY_BLEIO
+ #define MICROPY_PY_BLEIO (0)
+ #endif
#endif
-#ifndef MICROPY_PY_UBLUEPY
-#define MICROPY_PY_UBLUEPY (0)
-#endif
// type definitions for the specific machine
@@ -184,16 +178,8 @@ extern const struct _mp_obj_module_t neopixel_write_module;
extern const struct _mp_obj_module_t usb_hid_module;
extern const struct _mp_obj_module_t bleio_module;
-extern const struct _mp_obj_module_t mp_module_ubluepy;
-
-#if MICROPY_PY_UBLUEPY
-#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) },
-#else
-#define UBLUEPY_MODULE
-#endif
-
#if MICROPY_PY_BLEIO
-#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) },
+#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) },
#else
#define BLEIO_MODULE
#endif
@@ -221,8 +207,7 @@ extern const struct _mp_obj_module_t mp_module_ubluepy;
{ MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \
USBHID_MODULE \
- BLEIO_MODULE \
- UBLUEPY_MODULE \
+ BLEIO_MODULE
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c
new file mode 100644
index 000000000..15ebd51ed
--- /dev/null
+++ b/shared-bindings/bleio/Device.c
@@ -0,0 +1,348 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * 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 <string.h>
+#include <stdio.h>
+
+#include "ble_drv.h"
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/AddressType.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Device.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/Device.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Device` -- BLE device
+//| =========================================================
+//|
+//| Provides access a to BLE device, either in a Peripheral or Central role.
+//| When a device is created without any parameter passed to the constructor,
+//| it will be set to the Peripheral role. If a address is passed, the device
+//| will be a Central. For a Peripheral you can set the `name`, add services
+//| via `add_service` and then start and stop advertising via `start_advertising`
+//| and `stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect`
+//| to the device, once a connection is established, the device's services can
+//| be accessed using `services`.
+//|
+//| Usage::
+//|
+//| import bleio
+//|
+//| # Peripheral
+//| periph = bleio.Device()
+//|
+//| serv = bleio.Service(bleio.UUID(0x180f))
+//| p.add_service(serv)
+//|
+//| chara = bleio.Characteristic(bleio.UUID(0x2919))
+//| chara.read = True
+//| chara.notify = True
+//| serv.add_characteristic(chara)
+//|
+//| periph.start_advertising()
+//|
+//| # Central
+//| scanner = bleio.Scanner()
+//| entries = scanner.scan(2500)
+//|
+//| my_entry = None
+//| for entry in entries:
+//| if entry.name is not None and entry.name == 'MyDevice':
+//| my_entry = entry
+//| break
+//|
+//| central = bleio.Device(my_entry.address)
+//| central.connect()
+//|
+
+//| .. class:: Device(address=None)
+//|
+//| Create a new Device object. If the `address` parameter is not `None`,
+//| the role is set to Central, otherwise it's set to Peripheral.
+//|
+//| :param bleio.Address address: The address of the device to connect to
+//|
+
+//| .. attribute:: name
+//|
+//| For the Peripheral role, this property can be used to read and write the device's name.
+//| For the Central role, this property will equal the name of the remote device, if one was
+//| advertised by the device. In the Central role this property is read-only.
+//|
+
+//| .. attribute:: services
+//|
+//| A `list` of `bleio.Service` that are offered by this device. (read-only)
+//| For a Peripheral device, this list will contain services added using `add_service`,
+//| for a Central, this list will be empty until a connection is established, at which point
+//| it will be filled with the remote device's services.
+//|
+
+//| .. method:: add_service(service)
+//|
+//| Appends the :py:data:`service` to the list of this devices's services.
+//| This method can only be called for Peripheral devices.
+//|
+//| :param bleio.Service service: the service to append
+//|
+
+//| .. method:: connect()
+//|
+//| Attempts a connection to the remote device. If the connection is successful,
+//| the device's services are available via `services`.
+//| This method can only be called for Central devices.
+//|
+
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote device.
+//| This method can only be called for Central devices.
+//|
+
+//| .. method:: start_advertising(connectable=True)
+//|
+//| Starts advertising the device. The device's name and
+//| services are put into the advertisement packets.
+//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device.
+//| This method can only be called for Peripheral devices.
+//|
+
+//| .. method:: stop_advertising()
+//|
+//| Disconnects from the remote device.
+//| This method can only be called for Peripheral devices.
+//|
+static const char default_name[] = "CIRCUITPY";
+
+STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central");
+}
+
+STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 0, 1, true);
+ bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t);
+ self->base.type = &bleio_device_type;
+ self->service_list = mp_obj_new_list(0, NULL);
+ self->notif_handler = mp_const_none;
+ self->conn_handler = mp_const_none;
+ self->conn_handle = 0xFFFF;
+ self->is_peripheral = true;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ //TODO: Add ScanEntry
+ enum { ARG_address };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t address_obj = args[ARG_address].u_obj;
+
+ if (address_obj != mp_const_none) {
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj);
+
+ self->is_peripheral = false;
+ self->address.type = address->type;
+ memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES);
+ } else {
+ self->name = mp_obj_new_str(default_name, strlen(default_name), false);
+ common_hal_bleio_adapter_get_address(&self->address);
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ "Can't add services in Central mode"));
+ }
+
+ service->device = self_in;
+
+ mp_obj_list_append(self->service_list, service);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service);
+
+STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ "Can't connect in Peripheral mode"));
+ }
+
+ common_hal_bleio_device_connect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect);
+
+STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_device_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect);
+
+STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return self->name;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name);
+
+static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ "Can't change the name in Central mode"));
+ }
+
+ self->name = value;
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name);
+
+const mp_obj_property_t bleio_device_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_device_get_name_obj,
+ (mp_obj_t)&bleio_device_set_name_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ "Can't advertise in Central mode"));
+ }
+
+ enum { ARG_connectable };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ // TODO: data
+ bleio_advertisement_data_t adv_data = {
+ .device_name = self->name,
+ .services = mp_obj_new_list(0, NULL),
+ .data = mp_obj_new_bytearray(0, NULL),
+ .connectable = args[ARG_connectable].u_bool
+ };
+
+ mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
+ for (size_t i = 0; i < service_list->len; ++i) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
+ if (!service->is_secondary) {
+ mp_obj_list_append(adv_data.services, service_list->items[i]);
+ }
+ }
+
+ common_hal_bleio_device_start_advertising(self, &adv_data);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising);
+
+STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ "Can't advertise in Central mode"));
+ }
+
+ common_hal_bleio_device_stop_advertising(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising);
+
+STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return self->service_list;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services);
+
+const mp_obj_property_t bleio_device_services_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_device_get_services_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table);
+
+const mp_obj_type_t bleio_device_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Device,
+ .print = bleio_device_print,
+ .make_new = bleio_device_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict
+};
diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/shared-bindings/bleio/Device.h
index f8266a82d..d099e5c43 100644
--- a/ports/nrf/modules/ubluepy/modubluepy.c
+++ b/shared-bindings/bleio/Device.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,25 +24,17 @@
* THE SOFTWARE.
*/
-#include "py/obj.h"
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
-#if MICROPY_PY_UBLUEPY
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/Device.h"
-extern const mp_obj_type_t ubluepy_peripheral_type;
-extern const mp_obj_type_t ubluepy_service_type;
+extern const mp_obj_type_t bleio_device_type;
-STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = {
- { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) },
-#if MICROPY_PY_UBLUEPY_PERIPHERAL
- { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) },
-#endif
-};
+extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data);
+extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device);
+extern void common_hal_bleio_device_connect(bleio_device_obj_t *device);
+extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device);
-STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table);
-
-const mp_obj_module_t mp_module_ubluepy = {
- .base = { &mp_type_module },
- .globals = (mp_obj_dict_t*)&mp_module_ubluepy_globals,
-};
-
-#endif // MICROPY_PY_UBLUEPY
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c
index e38a08909..2eed24cd8 100644
--- a/shared-bindings/bleio/ScanEntry.c
+++ b/shared-bindings/bleio/ScanEntry.c
@@ -32,9 +32,10 @@
#include "py/objstr.h"
#include "py/objtuple.h"
#include "shared-bindings/bleio/Address.h"
-#include "shared-module/bleio/AdvertisementData.h"
-#include "shared-bindings/bleio/UUID.h"
#include "shared-bindings/bleio/ScanEntry.h"
+#include "shared-bindings/bleio/UUID.h"
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/ScanEntry.h"
//| .. currentmodule:: bleio
//|
diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h
index 4a201124e..2b44ba3f4 100644
--- a/shared-bindings/bleio/ScanEntry.h
+++ b/shared-bindings/bleio/ScanEntry.h
@@ -28,16 +28,7 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
-#include "shared-module/bleio/Address.h"
-#include "py/objtype.h"
-
-typedef struct {
- mp_obj_base_t base;
- bleio_address_obj_t address;
- bool connectable;
- int8_t rssi;
- mp_obj_t data;
-} bleio_scanentry_obj_t;
+#include "py/obj.h"
extern const mp_obj_type_t bleio_scanentry_type;
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
index 6451991e9..5b61a2966 100644
--- a/shared-bindings/bleio/Service.c
+++ b/shared-bindings/bleio/Service.c
@@ -73,7 +73,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
mp_arg_check_num(n_args, n_kw, 1, 1, true);
bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t);
self->base.type = &bleio_service_type;
- self->periph = mp_const_none;
+ self->device = mp_const_none;
self->char_list = mp_obj_new_list(0, NULL);
mp_map_t kw_args;
@@ -81,7 +81,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
enum { ARG_uuid, ARG_secondary };
static const mp_arg_t allowed_args[] = {
- { ARG_uuid, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { ARG_uuid, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
@@ -92,7 +92,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t uuid = args[ARG_uuid].u_obj;
- if (uuid == MP_OBJ_NULL) {
+ if (uuid == mp_const_none) {
return MP_OBJ_FROM_PTR(self);
}
diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c
index 9f5a8f8f2..98099422c 100644
--- a/shared-bindings/bleio/__init__.c
+++ b/shared-bindings/bleio/__init__.c
@@ -31,6 +31,7 @@
#include "shared-bindings/bleio/AdvertisementData.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Device.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
#include "shared-bindings/bleio/Service.h"
@@ -57,6 +58,7 @@
//| Adapter
//| Characteristic
//| Descriptor
+//| Device
//| ScanEntry
//| Scanner
//| Service
@@ -76,6 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) },
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
{ MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
+ { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&bleio_device_type) },
{ MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
{ MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
{ MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h
index 2a9addf57..738d53b23 100644
--- a/shared-module/bleio/AdvertisementData.h
+++ b/shared-module/bleio/AdvertisementData.h
@@ -27,6 +27,8 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
+#include "py/obj.h"
+
// Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
enum {
AdFlags = 0x01,
@@ -73,4 +75,11 @@ enum {
AdManufacturerSpecificData = 0xFF,
};
+typedef struct {
+ mp_obj_t device_name;
+ mp_obj_t services;
+ mp_obj_t data;
+ bool connectable;
+} bleio_advertisement_data_t;
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
diff --git a/shared-module/bleio/Device.h b/shared-module/bleio/Device.h
new file mode 100644
index 000000000..afbd8f063
--- /dev/null
+++ b/shared-module/bleio/Device.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * 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_SHARED_MODULE_BLEIO_DEVICE_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H
+
+#include <stdbool.h>
+
+#include "shared-module/bleio/Address.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ bool is_peripheral;
+ mp_obj_t name;
+ bleio_address_obj_t address;
+ uint16_t conn_handle;
+ mp_obj_t service_list;
+ mp_obj_t notif_handler;
+ mp_obj_t conn_handler;
+} bleio_device_obj_t;
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H
diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/bleio/ScanEntry.h
new file mode 100644
index 000000000..2f01669e2
--- /dev/null
+++ b/shared-module/bleio/ScanEntry.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * 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_SHARED_MODULE_BLEIO_SCANENTRY_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
+
+#include "shared-module/bleio/Address.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_address_obj_t address;
+ bool connectable;
+ int8_t rssi;
+ mp_obj_t data;
+} bleio_scanentry_obj_t;
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h
index bd359a41d..1e3f09119 100644
--- a/shared-module/bleio/Service.h
+++ b/shared-module/bleio/Service.h
@@ -27,7 +27,6 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H
-#include "modubluepy.h"
#include "common-hal/bleio/UUID.h"
typedef struct {
@@ -35,7 +34,7 @@ typedef struct {
uint16_t handle;
bool is_secondary;
bleio_uuid_obj_t *uuid;
- mp_obj_t periph;
+ mp_obj_t device;
mp_obj_t char_list;
uint16_t start_handle;
uint16_t end_handle;