nrf: Move the Peripheral class to bleio as Device
This was the last class from ubluepy and so that module is now gone. The Device class offers both Peripheral and Central functionality. See the inline docs for more info.
This commit is contained in:
parent
bda734223e
commit
3bd65fbae5
@ -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
|
||||
|
@ -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);
|
||||
|
166
ports/nrf/common-hal/bleio/Device.c
Normal file
166
ports/nrf/common-hal/bleio/Device.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
// (void)sd_ble_gap_ppcp_get(&conn_params);
|
||||
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,
|
||||
};
|
||||
|
||||
// set connection parameters
|
||||
memset(&conn_params, 0, sizeof(conn_params));
|
||||
|
||||
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;
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
void ble_drv_connect(bleio_device_obj_t *device) {
|
||||
SD_TEST_OR_ENABLE();
|
||||
|
||||
mp_gattc_disc_service_observer = obj;
|
||||
mp_connect_address = &device->address;
|
||||
ble_drv_adv_report_handler_set(NULL, ble_drv_connect_scan_callback);
|
||||
|
||||
ble_drv_scan_start(100, 100);
|
||||
}
|
||||
|
||||
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(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 = 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 {
|
||||
|
@ -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);
|
||||
|
||||
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);
|
||||
void ble_drv_disconnect(bleio_device_obj_t *device);
|
||||
|
||||
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_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_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);
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#if BLUETOOTH_SD
|
||||
|
||||
#include "modubluepy.h"
|
||||
#include "ble_drv.h"
|
||||
|
||||
void ble_uart_init0(void);
|
||||
|
@ -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__
|
@ -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
|
@ -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)
|
||||
#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_BLEIO
|
||||
#define MICROPY_PY_BLEIO (0)
|
||||
#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 \
|
||||
|
348
shared-bindings/bleio/Device.c
Normal file
348
shared-bindings/bleio/Device.c
Normal file
@ -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
|
||||
};
|
@ -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
|
@ -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
|
||||
//|
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) },
|
||||
|
@ -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
|
||||
|
45
shared-module/bleio/Device.h
Normal file
45
shared-module/bleio/Device.h
Normal file
@ -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
|
40
shared-module/bleio/ScanEntry.h
Normal file
40
shared-module/bleio/ScanEntry.h
Normal file
@ -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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user