Replace Broadcaster with enhanced Peripheral

This commit is contained in:
Dan Halbert 2019-06-03 20:40:05 -04:00
parent 63ac37946d
commit 613e12f99f
13 changed files with 90 additions and 450 deletions

View File

@ -1,98 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "ble.h"
#include "ble_drv.h"
#include "ble_hci.h"
#include "nrf_soc.h"
#include "py/runtime.h"
#include "common-hal/bleio/Broadcaster.h"
#include "shared-bindings/bleio/Adapter.h"
#include "shared-bindings/bleio/Broadcaster.h"
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval) {
common_hal_bleio_adapter_set_enabled(true);
const mp_float_t min = BLE_GAP_ADV_INTERVAL_MIN * ADV_INTERVAL_UNIT_FLOAT_SECS;
const mp_float_t max = BLE_GAP_ADV_INTERVAL_MAX * ADV_INTERVAL_UNIT_FLOAT_SECS;
if (interval < min || interval > max) {
// Would like to print range using the constants above, but vargs would convert to double.
mp_raise_ValueError(translate("interval not in range 0.0020 to 10.24"));
}
self->interval = interval;
}
void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data) {
uint32_t err_code;
if (data->len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
mp_raise_ValueError(translate("Data too large for advertisement packet"));
}
memcpy(self->adv_data, data->buf, data->len);
ble_gap_adv_params_t m_adv_params = {
.interval = (uint32_t) (self->interval / ADV_INTERVAL_UNIT_FLOAT_SECS),
.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED,
.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
.filter_policy = BLE_GAP_ADV_FP_ANY,
.primary_phy = BLE_GAP_PHY_1MBPS,
};
common_hal_bleio_broadcaster_stop_advertising(self);
const ble_gap_adv_data_t ble_gap_adv_data = {
.adv_data.p_data = self->adv_data,
.adv_data.len = data->len,
};
err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params);
if (err_code == NRF_SUCCESS) {
err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
}
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
}
}
void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self) {
if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) {
return;
}
const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);
}
}

View File

@ -49,68 +49,12 @@
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
STATIC void check_data_fit(size_t data_len) {
if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
mp_raise_ValueError(translate("Data too large for advertisement packet"));
}
}
STATIC uint32_t start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
common_hal_bleio_adapter_set_enabled(true);
uint32_t err_code;
GET_STR_DATA_LEN(self->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);
err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
if (err_code != NRF_SUCCESS) {
return err_code;
}
}
check_data_fit(advertising_data_bufinfo->len);
memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
check_data_fit(scan_response_data_bufinfo->len);
memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
static ble_gap_adv_params_t m_adv_params = {
.interval = MSEC_TO_UNITS(1000, UNIT_0_625_MS),
.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
.filter_policy = BLE_GAP_ADV_FP_ANY,
.primary_phy = BLE_GAP_PHY_1MBPS,
};
if (!connectable) {
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
}
common_hal_bleio_peripheral_stop_advertising(self);
const ble_gap_adv_data_t ble_gap_adv_data = {
.adv_data.p_data = self->advertising_data,
.adv_data.len = advertising_data_bufinfo->len,
.scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL,
.scan_rsp_data.len = scan_response_data_bufinfo->len,
};
err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params);
if (err_code != NRF_SUCCESS) {
return err_code;
}
err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
return err_code;
}
STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in;
@ -172,12 +116,12 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
}
}
void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self) {
common_hal_bleio_adapter_set_enabled(true);
self->gatt_role = GATT_ROLE_SERVER;
self->conn_handle = BLE_CONN_HANDLE_INVALID;
self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
// Add all the services.
@ -208,13 +152,62 @@ bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) {
return self->conn_handle != BLE_CONN_HANDLE_INVALID;
}
void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
// interval value has already been validated.
if (connectable) {
ble_drv_add_event_handler(peripheral_on_ble_evt, self);
}
const uint32_t err_code = start_advertising(self, connectable,
advertising_data_bufinfo, scan_response_data_bufinfo);
common_hal_bleio_adapter_set_enabled(true);
uint32_t err_code;
GET_STR_DATA_LEN(self->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);
err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code);
}
}
check_data_fit(advertising_data_bufinfo->len);
memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
check_data_fit(scan_response_data_bufinfo->len);
memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
ble_gap_adv_params_t adv_params = {
.interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
.properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
: BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED,
.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
.filter_policy = BLE_GAP_ADV_FP_ANY,
.primary_phy = BLE_GAP_PHY_1MBPS,
};
common_hal_bleio_peripheral_stop_advertising(self);
const ble_gap_adv_data_t ble_gap_adv_data = {
.adv_data.p_data = self->advertising_data,
.adv_data.len = advertising_data_bufinfo->len,
.scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL,
.scan_rsp_data.len = scan_response_data_bufinfo->len,
};
err_code = sd_ble_gap_adv_set_configure(&self->adv_handle, &ble_gap_adv_data, &adv_params);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to configure advertising, err 0x%04x"), err_code);
}
err_code = sd_ble_gap_adv_start(self->adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
}
@ -222,10 +215,10 @@ void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self,
void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) {
if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
if (self->adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
return;
const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
const uint32_t err_code = sd_ble_gap_adv_stop(self->adv_handle);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);

View File

@ -48,6 +48,7 @@ typedef struct {
// there are tricks to get the SD to notice (see DevZone - TBS).
uint8_t advertising_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
uint8_t scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
uint8_t adv_handle;
} bleio_peripheral_obj_t;

View File

@ -221,7 +221,6 @@ $(filter $(SRC_PATTERNS), \
audioio/AudioOut.c \
bleio/__init__.c \
bleio/Adapter.c \
bleio/Broadcaster.c \
bleio/Characteristic.c \
bleio/CharacteristicBuffer.c \
bleio/Descriptor.c \
@ -285,7 +284,6 @@ SRC_BINDINGS_ENUMS += \
$(filter $(SRC_PATTERNS), \
bleio/Address.c \
bleio/AddressType.c \
bleio/AdvertisementData.c \
bleio/ScanEntry.c \
)

View File

@ -1,90 +0,0 @@
/*
* 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 "py/obj.h"
#include "shared-module/bleio/AdvertisementData.h"
//| .. currentmodule:: bleio
//|
//| :class:`AdvertisementData` -- data used during BLE advertising
//| ==============================================================
//|
//| Represents the data to be broadcast during BLE advertising.
//|
STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = {
// Static variables
{ MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) },
{ MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) },
{ MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) },
{ MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) },
{ MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) },
{ MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) },
{ MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) },
{ MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) },
{ MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) },
{ MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) },
{ MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) },
{ MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) },
{ MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) },
{ MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) },
{ MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) },
{ MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) },
{ MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) },
{ MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) },
{ MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) },
{ MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) },
{ MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) },
{ MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) },
{ MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) },
{ MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) },
{ MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) },
{ MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) },
{ MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) },
{ MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) },
{ MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) },
{ MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) },
{ MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) },
{ MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) },
{ MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table);
const mp_obj_type_t bleio_advertisementdata_type = {
{ &mp_type_type },
.name = MP_QSTR_AdvertisementData,
.locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict
};

View File

@ -1,132 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "ble_drv.h"
#include "py/runtime.h"
#include "shared-bindings/bleio/Broadcaster.h"
//| .. currentmodule:: bleio
//|
//| :class:`Broadcaster` -- Broadcast advertising packets.
//| =========================================================
//|
//| Implement a BLE broadcaster which sends data in advertising packets and does not connect.
//| Used for beacons and other one-way data transmission.
//|
//| Usage::
//|
//| import bleio
//| import time
//|
//| # Broadcast once a second.
//| broadcaster = bleio.Broadcaster(interval=1)
//| data = 0
//| # Broadcast a byte of data that's incremented once a minute
//| while True:
//| # data is an entire advertising data packet, starting with flags.
//| broadcaster.start_advertising(data)
//| time.sleep(60)
//| data += 1
//|
//| .. class:: Broadcaster(interval=1)
//|
//| Create a new Broadcaster object.
//| :param float interval: how often to broadcast
//|
STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_interval };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_interval, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
};
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);
mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj);
bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t);
self->base.type = &bleio_broadcaster_type;
// Do port-specific initialization. interval will be validated.
common_hal_bleio_broadcaster_construct(self, interval);
return MP_OBJ_FROM_PTR(self);
}
//| .. method:: start_advertising(data)
//|
//| Start advertising using the given data packet.
//|
//| :param buf data: advertising data packet
//|
STATIC mp_obj_t bleio_broadcaster_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
enum { ARG_data };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
};
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);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
common_hal_bleio_broadcaster_start_advertising(self, &bufinfo);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_broadcaster_start_advertising_obj, 0, bleio_broadcaster_start_advertising);
//| .. method:: stop_advertising()
//|
//| Stop sending advertising packets.
STATIC mp_obj_t bleio_broadcaster_stop_advertising(mp_obj_t self_in) {
bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_bleio_broadcaster_stop_advertising(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_broadcaster_stop_advertising_obj, bleio_broadcaster_stop_advertising);
STATIC const mp_rom_map_elem_t bleio_broadcaster_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_broadcaster_start_advertising_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_broadcaster_stop_advertising_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_broadcaster_locals_dict, bleio_broadcaster_locals_dict_table);
const mp_obj_type_t bleio_broadcaster_type = {
{ &mp_type_type },
.name = MP_QSTR_Broadcaster,
.make_new = bleio_broadcaster_make_new,
.locals_dict = (mp_obj_dict_t*)&bleio_broadcaster_locals_dict
};

View File

@ -1,38 +0,0 @@
/*
* 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_BINDINGS_BLEIO_BROADCASTER_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
#include "common-hal/bleio/Broadcaster.h"
extern const mp_obj_type_t bleio_broadcaster_type;
extern void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval);
extern void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data);
extern void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H

View File

@ -39,7 +39,6 @@
#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"
#include "shared-module/bleio/ScanEntry.h"

View File

@ -27,7 +27,6 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/Device.h"
#include "shared-module/bleio/Service.h"

View File

@ -40,14 +40,18 @@
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/ScanEntry.h"
#include "common-hal/bleio/Peripheral.h"
// TODO: Add unique MAC address part to name
static const char default_name[] = "CIRCUITPY";
#define ADV_INTERVAL_DEFAULT (1.0f)
#define ADV_INTERVAL_MIN (0.0020f)
#define ADV_INTERVAL_MIN_STRING "0.0020"
#define ADV_INTERVAL_MAX (10.24f)
#define ADV_INTERVAL_MAX_STRING "10.24"
//| .. currentmodule:: bleio
//|
//| :class:`Peripheral` -- A BLE peripheral device
@ -75,19 +79,21 @@ static const char default_name[] = "CIRCUITPY";
//| # Wait for connection.
//| pass
//|
//| .. class:: Peripheral(services, *, name='CIRCUITPY')
//| .. class:: Peripheral(services=(), \*, name='CIRCUITPY')
//|
//| Create a new Peripheral object.
//| :param iterable services: the Service objects representing services available from this peripheral.
//| :param str name: The name used when advertising this peripheral
//| :param iterable services: the Service objects representing services available from this peripheral, if any.
//| A non-connectable peripheral will have no services.
//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed,
//| such as when the peripheral is a beacon
//|
STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_services, ARG_name };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} },
{ MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -112,8 +118,11 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
}
const mp_obj_t name = args[ARG_name].u_obj;
if (name == mp_const_none) {
if (name == MP_OBJ_NULL) {
self->name = mp_obj_new_str(default_name, strlen(default_name));
} else if (name == mp_const_none) {
// Make None be the empty string.
self->name = MP_OBJ_NEW_QSTR(MP_QSTR_);
} else if (MP_OBJ_IS_STR(name)) {
self->name = name;
} else {
@ -182,7 +191,7 @@ const mp_obj_property_t bleio_peripheral_name_obj = {
(mp_obj_t)&mp_const_none_obj },
};
//| .. method:: start_advertising(data, *, scan_response=None, connectable=True)
//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=1)
//|
//| Starts advertising the peripheral. The peripheral's name and
//| services are included in the advertisement packets.
@ -190,16 +199,17 @@ const mp_obj_property_t bleio_peripheral_name_obj = {
//| :param buf data: advertising data packet bytes
//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
//|
//| :param float interval: advertising interval, in seconds
//|
STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
enum { ARG_data, ARG_scan_response, ARG_connectable };
enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -210,11 +220,21 @@ STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_ob
// Pass an empty buffer if scan_response not provided.
mp_buffer_info_t scan_response_bufinfo = { 0 };
if (args[ARG_data].u_obj != mp_const_none) {
if (args[ARG_scan_response].u_obj != mp_const_none) {
mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
}
common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool,
if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
args[ARG_interval].u_obj = mp_obj_new_float(1.0F);
}
const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
}
common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval,
&data_bufinfo, &scan_response_bufinfo);
return mp_const_none;

View File

@ -34,7 +34,7 @@ extern const mp_obj_type_t bleio_peripheral_type;
extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self);
extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self);
extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H

View File

@ -28,8 +28,6 @@
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Address.h"
#include "shared-bindings/bleio/AddressType.h"
#include "shared-bindings/bleio/AdvertisementData.h"
#include "shared-bindings/bleio/Broadcaster.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/CharacteristicBuffer.h"
#include "shared-bindings/bleio/Descriptor.h"
@ -57,7 +55,6 @@
//| AddressType
//| AdvertisementData
//| Adapter
//| Broadcaster
//| Characteristic
//| CharacteristicBuffer
// Work-in-progress classes are omitted, and marked as :orphan: in their files.
@ -79,8 +76,6 @@
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) },
{ MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
{ MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) },
{ MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) },
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
{ MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
// { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },

View File

@ -75,11 +75,4 @@ 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