2016-11-16 15:38:25 -05:00
|
|
|
/*
|
2017-08-04 12:05:38 -04:00
|
|
|
* This file is part of the MicroPython project, http://micropython.org/
|
2016-11-16 15:38:25 -05:00
|
|
|
*
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
|
|
|
* Copyright (c) 2016 Glenn Ruben Bakke
|
2018-07-19 14:33:24 -04:00
|
|
|
* Copyright (c) 2018 Artur Pacholec
|
2016-11-16 15:38:25 -05:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2017-05-11 12:37:48 -04:00
|
|
|
#if BLUETOOTH_SD
|
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2017-02-12 08:24:15 -05:00
|
|
|
#include <stdbool.h>
|
2017-02-09 17:56:32 -05:00
|
|
|
|
2018-07-13 08:51:50 -04:00
|
|
|
#if (BLUETOOTH_SD == 132)
|
2018-06-20 14:43:59 -04:00
|
|
|
#define NRF52 // Needed for SD132 v2
|
2018-07-13 08:51:50 -04:00
|
|
|
#endif
|
2018-06-20 14:43:59 -04:00
|
|
|
|
2018-07-19 16:59:18 -04:00
|
|
|
#include "shared-bindings/bleio/Characteristic.h"
|
2018-07-19 14:59:32 -04:00
|
|
|
#include "shared-bindings/bleio/ScanEntry.h"
|
2018-07-19 16:10:16 -04:00
|
|
|
#include "shared-bindings/bleio/Service.h"
|
|
|
|
#include "shared-bindings/bleio/UUID.h"
|
2018-07-19 14:33:24 -04:00
|
|
|
#include "shared-module/bleio/Device.h"
|
|
|
|
#include "py/objstr.h"
|
2017-02-09 17:56:32 -05:00
|
|
|
#include "py/runtime.h"
|
2018-08-16 16:34:12 -04:00
|
|
|
#include "supervisor/shared/translate.h"
|
2017-02-17 13:10:24 -05:00
|
|
|
#include "ble_drv.h"
|
2016-11-16 15:38:25 -05:00
|
|
|
#include "mpconfigport.h"
|
|
|
|
#include "nrf_sdm.h"
|
2018-07-13 08:51:50 -04:00
|
|
|
#include "nrfx_power.h"
|
2016-11-16 15:38:25 -05:00
|
|
|
#include "ble_gap.h"
|
2018-07-19 14:33:24 -04:00
|
|
|
#include "ble_hci.h"
|
2016-11-16 15:38:25 -05:00
|
|
|
#include "ble.h" // sd_ble_uuid_encode
|
|
|
|
|
2017-02-15 17:57:23 -05:00
|
|
|
#define BLE_DRIVER_LOG printf
|
|
|
|
|
2017-02-27 17:40:39 -05:00
|
|
|
#define BLE_ADV_LENGTH_FIELD_SIZE 1
|
|
|
|
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
|
|
|
|
#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
|
|
|
|
|
|
|
|
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
|
|
|
|
#define UNIT_0_625_MS (625)
|
|
|
|
#define UNIT_10_MS (10000)
|
|
|
|
#define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout.
|
|
|
|
#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS)
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
#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)
|
2017-02-27 17:40:39 -05:00
|
|
|
#define BLE_SLAVE_LATENCY 0
|
|
|
|
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
|
2017-02-15 17:57:23 -05:00
|
|
|
|
2018-06-18 17:11:30 -04:00
|
|
|
#ifndef BLE_GAP_ADV_MAX_SIZE
|
|
|
|
#define BLE_GAP_ADV_MAX_SIZE 31
|
|
|
|
#endif
|
|
|
|
|
2017-02-09 17:56:32 -05:00
|
|
|
#define SD_TEST_OR_ENABLE() \
|
2017-02-17 13:02:24 -05:00
|
|
|
if (ble_drv_stack_enabled() == 0) { \
|
|
|
|
(void)ble_drv_stack_enable(); \
|
2017-02-09 17:56:32 -05:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:48:04 -05:00
|
|
|
static volatile bool m_adv_in_progress;
|
|
|
|
static volatile bool m_tx_in_progress;
|
2017-02-15 17:32:42 -05:00
|
|
|
|
2017-03-29 17:34:33 -04:00
|
|
|
static ble_drv_gap_evt_callback_t gap_event_handler;
|
|
|
|
static ble_drv_gatts_evt_callback_t gatts_event_handler;
|
2017-04-01 18:30:16 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
static bleio_device_obj_t *mp_gap_observer;
|
|
|
|
static bleio_device_obj_t *mp_gatts_observer;
|
2017-05-14 11:14:57 -04:00
|
|
|
|
|
|
|
static volatile bool m_primary_service_found;
|
|
|
|
static volatile bool m_characteristic_found;
|
2017-05-30 13:29:46 -04:00
|
|
|
static volatile bool m_write_done;
|
2017-05-14 11:14:57 -04:00
|
|
|
|
2017-05-15 17:00:10 -04:00
|
|
|
static volatile ble_drv_adv_evt_callback_t adv_event_handler;
|
|
|
|
static volatile ble_drv_gattc_evt_callback_t gattc_event_handler;
|
|
|
|
static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle;
|
2017-04-01 18:30:16 -04:00
|
|
|
|
2018-07-18 04:22:11 -04:00
|
|
|
static bleio_scanner_obj_t *mp_adv_observer;
|
2018-07-19 14:33:24 -04:00
|
|
|
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;
|
2018-07-18 17:47:06 -04:00
|
|
|
static bleio_characteristic_obj_t *mp_gattc_char_data_observer;
|
2018-07-19 14:33:24 -04:00
|
|
|
static bleio_address_obj_t *mp_connect_address;
|
2017-02-12 08:24:15 -05:00
|
|
|
|
2018-06-18 17:11:30 -04:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
|
|
|
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
|
|
|
|
static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
|
|
|
|
|
|
|
|
static ble_data_t m_scan_buffer =
|
|
|
|
{
|
|
|
|
m_scan_buffer_data,
|
|
|
|
BLE_GAP_SCAN_BUFFER_MIN
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
#include "nrf_nvic.h"
|
|
|
|
|
2017-05-24 17:24:14 -04:00
|
|
|
nrf_nvic_state_t nrf_nvic_state = {0};
|
2016-11-16 15:38:25 -05:00
|
|
|
|
|
|
|
void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!");
|
2016-11-16 15:38:25 -05:00
|
|
|
}
|
2018-02-07 15:45:46 -05:00
|
|
|
|
2017-02-17 13:02:24 -05:00
|
|
|
uint32_t ble_drv_stack_enable(void) {
|
2017-03-02 16:48:04 -05:00
|
|
|
m_adv_in_progress = false;
|
|
|
|
m_tx_in_progress = false;
|
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
nrf_clock_lf_cfg_t clock_config = {
|
|
|
|
.source = NRF_CLOCK_LF_SRC_XTAL,
|
|
|
|
.rc_ctiv = 0,
|
|
|
|
.rc_temp_ctiv = 0,
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 4)
|
2018-02-02 15:01:01 -05:00
|
|
|
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
|
|
|
|
#else
|
2016-11-16 15:38:25 -05:00
|
|
|
.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2016-11-16 15:38:25 -05:00
|
|
|
};
|
2018-07-13 08:51:50 -04:00
|
|
|
|
|
|
|
#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
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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);
|
2016-11-16 15:38:25 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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);
|
2018-06-18 17:11:30 -04:00
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
// Enable BLE stack.
|
2018-07-19 14:33:24 -04:00
|
|
|
uint32_t app_ram_start;
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 2)
|
2016-11-16 15:38:25 -05:00
|
|
|
ble_enable_params_t ble_enable_params;
|
|
|
|
memset(&ble_enable_params, 0x00, sizeof(ble_enable_params));
|
|
|
|
ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
|
2017-02-13 11:06:13 -05:00
|
|
|
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;
|
2016-11-16 15:38:25 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
app_ram_start = 0x200039c0;
|
2016-11-16 15:38:25 -05:00
|
|
|
err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); // 8K SD headroom from linker script.
|
2018-02-07 15:45:46 -05:00
|
|
|
#else
|
2018-07-19 14:33:24 -04:00
|
|
|
app_ram_start = 0x20004000;
|
2018-02-02 15:01:01 -05:00
|
|
|
err_code = sd_ble_enable(&app_ram_start);
|
2016-11-16 15:38:25 -05:00
|
|
|
#endif
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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);
|
2017-02-27 17:40:39 -05:00
|
|
|
}
|
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
return err_code;
|
|
|
|
}
|
|
|
|
|
2017-02-17 13:02:24 -05:00
|
|
|
void ble_drv_stack_disable(void) {
|
2016-11-16 15:38:25 -05:00
|
|
|
sd_softdevice_disable();
|
|
|
|
}
|
|
|
|
|
2017-02-17 13:02:24 -05:00
|
|
|
uint8_t ble_drv_stack_enabled(void) {
|
2016-11-16 15:38:25 -05:00
|
|
|
uint8_t is_enabled;
|
|
|
|
uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (err_code != NRF_SUCCESS) {
|
|
|
|
BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code);
|
|
|
|
}
|
2016-11-16 15:38:25 -05:00
|
|
|
|
|
|
|
return is_enabled;
|
|
|
|
}
|
|
|
|
|
2018-07-19 14:40:33 -04:00
|
|
|
void ble_drv_address_get(bleio_address_obj_t *address) {
|
2017-04-02 10:41:08 -04:00
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
2016-11-16 15:38:25 -05:00
|
|
|
ble_gap_addr_t local_ble_addr;
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 2)
|
2017-04-24 17:05:08 -04:00
|
|
|
uint32_t err_code = sd_ble_gap_address_get(&local_ble_addr);
|
2018-02-07 15:45:46 -05:00
|
|
|
#else
|
|
|
|
uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr);
|
2016-11-16 15:38:25 -05:00
|
|
|
#endif
|
2017-04-02 10:41:08 -04:00
|
|
|
|
|
|
|
if (err_code != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 17:21:44 -04:00
|
|
|
translate("Can not query for the device address.")));
|
2017-04-02 10:41:08 -04:00
|
|
|
}
|
|
|
|
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \
|
2017-02-27 17:40:39 -05:00
|
|
|
"address: " HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT ":" \
|
|
|
|
HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT "\n", \
|
|
|
|
local_ble_addr.addr_type, \
|
|
|
|
local_ble_addr.addr[5], local_ble_addr.addr[4], local_ble_addr.addr[3], \
|
|
|
|
local_ble_addr.addr[2], local_ble_addr.addr[1], local_ble_addr.addr[0]);
|
2016-11-16 15:38:25 -05:00
|
|
|
|
2018-07-19 14:40:33 -04:00
|
|
|
address->type = local_ble_addr.addr_type;
|
|
|
|
memcpy(address->value, local_ble_addr.addr, BLEIO_ADDRESS_BYTES);
|
2016-11-16 15:38:25 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
bool ble_drv_uuid_add_vs(uint8_t *uuid, uint8_t *idx) {
|
2017-02-09 17:56:32 -05:00
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (sd_ble_uuid_vs_add((ble_uuid128_t const *)uuid, idx) != 0) {
|
2017-02-09 17:56:32 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not add Vendor Specific 128-bit UUID.")));
|
2017-02-09 17:56:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-10 15:09:03 -05:00
|
|
|
|
2018-07-18 19:01:41 -04:00
|
|
|
void ble_drv_service_add(bleio_service_obj_t *service) {
|
2017-02-10 15:09:03 -05:00
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
2018-07-18 19:01:41 -04:00
|
|
|
ble_uuid_t uuid = {
|
|
|
|
.type = BLE_UUID_TYPE_BLE,
|
|
|
|
.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8)
|
|
|
|
};
|
2017-02-10 15:09:03 -05:00
|
|
|
|
2018-07-18 19:01:41 -04:00
|
|
|
if (service->uuid->type == UUID_TYPE_128BIT) {
|
|
|
|
uuid.type = service->uuid->uuid_vs_idx;
|
2018-07-18 17:47:06 -04:00
|
|
|
}
|
2017-02-12 17:03:55 -05:00
|
|
|
|
2018-07-18 19:01:41 -04:00
|
|
|
uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
|
|
|
|
if (service->is_secondary) {
|
|
|
|
service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
|
2017-02-12 17:03:55 -05:00
|
|
|
}
|
2018-07-18 17:47:06 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (sd_ble_gatts_service_add(service_type, &uuid, &service->handle) != 0) {
|
2018-07-18 19:01:41 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
|
|
|
translate("Can not add Service.")));
|
|
|
|
}
|
2017-02-10 15:09:03 -05:00
|
|
|
}
|
2017-02-11 10:01:50 -05:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) {
|
2017-02-11 10:01:50 -05:00
|
|
|
ble_gatts_char_md_t char_md;
|
|
|
|
ble_gatts_attr_md_t cccd_md;
|
|
|
|
ble_gatts_attr_t attr_char_value;
|
|
|
|
ble_uuid_t uuid;
|
|
|
|
ble_gatts_attr_md_t attr_md;
|
|
|
|
|
|
|
|
memset(&char_md, 0, sizeof(char_md));
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
char_md.char_props.broadcast = characteristic->props.broadcast;
|
|
|
|
char_md.char_props.read = characteristic->props.read;
|
|
|
|
char_md.char_props.write_wo_resp = characteristic->props.write_wo_resp;
|
|
|
|
char_md.char_props.write = characteristic->props.write;
|
|
|
|
char_md.char_props.notify = characteristic->props.notify;
|
|
|
|
char_md.char_props.indicate = characteristic->props.indicate;
|
2017-02-20 14:24:27 -05:00
|
|
|
|
2017-02-11 10:01:50 -05:00
|
|
|
char_md.p_char_user_desc = NULL;
|
|
|
|
char_md.p_char_pf = NULL;
|
|
|
|
char_md.p_user_desc_md = NULL;
|
|
|
|
char_md.p_sccd_md = NULL;
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
if (characteristic->props.notify || characteristic->props.notify) {
|
2017-02-20 14:24:27 -05:00
|
|
|
memset(&cccd_md, 0, sizeof(cccd_md));
|
|
|
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
|
|
|
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
|
|
|
|
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
|
|
char_md.p_cccd_md = &cccd_md;
|
|
|
|
} else {
|
|
|
|
char_md.p_cccd_md = NULL;
|
|
|
|
}
|
2017-02-11 10:01:50 -05:00
|
|
|
|
2018-07-18 19:01:41 -04:00
|
|
|
uuid.type = BLE_UUID_TYPE_BLE;
|
2018-07-18 17:47:06 -04:00
|
|
|
if (characteristic->uuid->type == UUID_TYPE_128BIT)
|
|
|
|
uuid.type = characteristic->uuid->uuid_vs_idx;
|
|
|
|
|
|
|
|
uuid.uuid = characteristic->uuid->value[0];
|
|
|
|
uuid.uuid += characteristic->uuid->value[1] << 8;
|
2017-02-11 10:01:50 -05:00
|
|
|
|
|
|
|
memset(&attr_md, 0, sizeof(attr_md));
|
|
|
|
|
|
|
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
|
|
|
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
|
|
|
|
|
|
|
|
attr_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
|
|
attr_md.rd_auth = 0;
|
|
|
|
attr_md.wr_auth = 0;
|
|
|
|
attr_md.vlen = 1;
|
|
|
|
|
|
|
|
memset(&attr_char_value, 0, sizeof(attr_char_value));
|
|
|
|
|
|
|
|
attr_char_value.p_uuid = &uuid;
|
|
|
|
attr_char_value.p_attr_md = &attr_md;
|
|
|
|
attr_char_value.init_len = sizeof(uint8_t);
|
|
|
|
attr_char_value.init_offs = 0;
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 2)
|
2017-02-11 10:01:50 -05:00
|
|
|
attr_char_value.max_len = (GATT_MTU_SIZE_DEFAULT - 3);
|
2018-02-07 15:45:46 -05:00
|
|
|
#else
|
|
|
|
attr_char_value.max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3);
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-02-11 10:01:50 -05:00
|
|
|
|
|
|
|
ble_gatts_char_handles_t handles;
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
uint32_t err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle,
|
|
|
|
&char_md,
|
|
|
|
&attr_char_value,
|
|
|
|
&handles);
|
|
|
|
if (err_code != 0) {
|
2017-02-11 10:01:50 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-07-18 17:47:06 -04:00
|
|
|
translate("Can not add Characteristic. status: 0x%08lX"), err_code));
|
2017-02-11 10:01:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// apply handles to object instance
|
2018-07-18 17:47:06 -04:00
|
|
|
characteristic->handle = handles.value_handle;
|
|
|
|
characteristic->user_desc_handle = handles.user_desc_handle;
|
|
|
|
characteristic->cccd_handle = handles.cccd_handle;
|
|
|
|
characteristic->sccd_handle = handles.sccd_handle;
|
2017-02-11 10:01:50 -05:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-11 11:41:16 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
// TODO: Replace with just bleio_device_obj_t + data
|
|
|
|
bool ble_drv_advertise_data(bleio_advertisement_data_t *adv_params) {
|
2017-02-11 11:41:16 -05:00
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
|
|
|
uint8_t byte_pos = 0;
|
|
|
|
uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
GET_STR_DATA_LEN(adv_params->device_name, name_data, name_len);
|
2017-02-11 11:41:16 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (name_len > 0) {
|
|
|
|
ble_gap_conn_sec_mode_t sec_mode;
|
2017-02-11 11:41:16 -05:00
|
|
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
|
|
|
|
|
|
|
|
if (sd_ble_gap_device_name_set(&sec_mode,
|
2018-07-19 14:33:24 -04:00
|
|
|
name_data,
|
|
|
|
name_len) != 0) {
|
2017-02-27 17:40:39 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not apply device name in the stack.")));
|
2017-02-11 11:41:16 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + name_len);
|
2017-02-12 17:03:55 -05:00
|
|
|
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
|
2018-07-19 14:33:24 -04:00
|
|
|
|
|
|
|
// TODO: Shorten if too long
|
2017-02-11 11:41:16 -05:00
|
|
|
adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
|
2017-02-11 12:02:22 -05:00
|
|
|
byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
|
2018-07-19 14:33:24 -04:00
|
|
|
|
|
|
|
memcpy(&adv_data[byte_pos], name_data, name_len);
|
|
|
|
|
|
|
|
byte_pos += name_len;
|
2017-02-11 11:41:16 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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) {
|
2017-04-02 09:45:02 -04:00
|
|
|
adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE);
|
|
|
|
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
|
2018-07-19 14:33:24 -04:00
|
|
|
|
2017-04-02 09:45:02 -04:00
|
|
|
adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS;
|
|
|
|
byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE;
|
2018-07-19 14:33:24 -04:00
|
|
|
|
2017-04-02 09:45:02 -04:00
|
|
|
adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
|
|
|
byte_pos += 1;
|
|
|
|
}
|
2017-02-11 12:02:22 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(adv_params->services);
|
|
|
|
if (service_list->len > 0) {
|
2017-02-17 15:47:38 -05:00
|
|
|
bool type_16bit_present = false;
|
|
|
|
bool type_128bit_present = false;
|
2017-02-12 17:03:55 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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) {
|
2017-02-17 15:47:38 -05:00
|
|
|
type_16bit_present = true;
|
2017-02-12 09:20:41 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (service->uuid->type == UUID_TYPE_128BIT) {
|
2017-02-17 15:47:38 -05:00
|
|
|
type_128bit_present = true;
|
2017-02-12 17:03:55 -05:00
|
|
|
}
|
2017-02-17 15:47:38 -05:00
|
|
|
}
|
2017-02-12 09:20:41 -05:00
|
|
|
|
2017-02-17 15:47:38 -05:00
|
|
|
if (type_16bit_present) {
|
|
|
|
uint8_t size_byte_pos = byte_pos;
|
|
|
|
|
|
|
|
// skip length byte for now, apply total length post calculation
|
|
|
|
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
|
|
|
|
|
|
|
|
adv_data[byte_pos] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE;
|
|
|
|
byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
|
|
|
|
|
|
|
|
uint8_t uuid_total_size = 0;
|
|
|
|
uint8_t encoded_size = 0;
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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;
|
|
|
|
}
|
2017-02-17 15:47:38 -05:00
|
|
|
|
|
|
|
ble_uuid_t uuid;
|
2018-07-19 14:33:24 -04:00
|
|
|
uuid.type = BLE_UUID_TYPE_BLE;
|
|
|
|
uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8);
|
|
|
|
|
2017-02-17 15:47:38 -05:00
|
|
|
// 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,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not encode UUID, to check length.")));
|
2017-02-17 15:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// do encoding into the adv buffer
|
|
|
|
if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can encode UUID into the advertisement packet.")));
|
2017-02-17 15:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
uuid_total_size += encoded_size; // size of entry
|
|
|
|
byte_pos += encoded_size; // relative to adv data packet
|
2017-02-12 17:03:55 -05:00
|
|
|
}
|
2017-02-17 15:47:38 -05:00
|
|
|
|
|
|
|
adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
|
2017-02-12 09:20:41 -05:00
|
|
|
}
|
|
|
|
|
2017-02-17 15:47:38 -05:00
|
|
|
if (type_128bit_present) {
|
|
|
|
uint8_t size_byte_pos = byte_pos;
|
|
|
|
|
|
|
|
// skip length byte for now, apply total length post calculation
|
|
|
|
byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
|
|
|
|
|
|
|
|
adv_data[byte_pos] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
|
|
|
|
byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
|
|
|
|
|
|
|
|
uint8_t uuid_total_size = 0;
|
|
|
|
uint8_t encoded_size = 0;
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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;
|
|
|
|
}
|
2017-02-17 15:47:38 -05:00
|
|
|
|
|
|
|
ble_uuid_t uuid;
|
2018-07-19 14:33:24 -04:00
|
|
|
uuid.type = service->uuid->uuid_vs_idx;
|
|
|
|
uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8);
|
2017-02-17 15:47:38 -05:00
|
|
|
|
|
|
|
// 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,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not encode UUID, to check length.")));
|
2017-02-17 15:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// do encoding into the adv buffer
|
|
|
|
if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can encode UUID into the advertisement packet.")));
|
2017-02-17 15:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
uuid_total_size += encoded_size; // size of entry
|
|
|
|
byte_pos += encoded_size; // relative to adv data packet
|
|
|
|
}
|
2017-02-12 09:20:41 -05:00
|
|
|
|
2017-02-17 15:47:38 -05:00
|
|
|
adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
|
|
|
|
}
|
|
|
|
}
|
2017-02-11 12:02:22 -05:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
if (bufinfo.len > 0) {
|
|
|
|
if (byte_pos + bufinfo.len > BLE_GAP_ADV_MAX_SIZE) {
|
2017-04-02 09:45:02 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can not fit data into the advertisement packet.")));
|
2017-04-02 09:45:02 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
memcpy(adv_data, bufinfo.buf, bufinfo.len);
|
|
|
|
byte_pos += bufinfo.len;
|
2017-04-02 09:45:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t err_code;
|
2018-06-18 17:11:30 -04:00
|
|
|
#if (BLUETOOTH_SD == 132)
|
2017-04-02 09:45:02 -04:00
|
|
|
if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
|
2017-02-11 11:41:16 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code));
|
2017-02-11 11:41:16 -05:00
|
|
|
}
|
2018-06-18 17:11:30 -04:00
|
|
|
#endif
|
2017-02-11 11:41:16 -05:00
|
|
|
|
2017-02-13 11:06:13 -05:00
|
|
|
static ble_gap_adv_params_t m_adv_params;
|
2017-02-11 11:41:16 -05:00
|
|
|
|
|
|
|
// initialize advertising params
|
|
|
|
memset(&m_adv_params, 0, sizeof(m_adv_params));
|
2018-07-19 14:33:24 -04:00
|
|
|
if (adv_params->connectable) {
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
|
2018-02-02 15:01:01 -05:00
|
|
|
#else
|
2017-04-02 12:34:56 -04:00
|
|
|
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-04-02 12:34:56 -04:00
|
|
|
} else {
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
|
2018-02-02 15:01:01 -05:00
|
|
|
#else
|
2017-04-02 12:34:56 -04:00
|
|
|
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-04-02 12:34:56 -04:00
|
|
|
}
|
2017-04-04 15:22:49 -04:00
|
|
|
|
2017-02-13 11:06:13 -05:00
|
|
|
m_adv_params.p_peer_addr = NULL; // undirected advertisement
|
|
|
|
m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); // approx 8 ms
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
|
|
|
|
m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
|
2018-02-02 15:01:01 -05:00
|
|
|
m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
|
|
|
|
#else
|
2018-06-18 17:11:30 -04:00
|
|
|
m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
|
2018-10-03 03:56:30 -04:00
|
|
|
m_adv_params.timeout = 0; // infinite advertisement
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-02-11 11:41:16 -05:00
|
|
|
|
2017-04-04 15:22:49 -04:00
|
|
|
ble_drv_advertise_stop();
|
2017-02-12 08:24:15 -05:00
|
|
|
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
const ble_gap_adv_data_t ble_gap_adv_data = {
|
|
|
|
.adv_data = {
|
|
|
|
.p_data = adv_data,
|
|
|
|
.len = byte_pos
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code));
|
2018-06-18 17:11:30 -04:00
|
|
|
}
|
|
|
|
err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT);
|
2018-02-07 15:45:46 -05:00
|
|
|
#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4)
|
|
|
|
err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);
|
2018-02-02 15:01:01 -05:00
|
|
|
#else
|
2017-04-02 09:45:02 -04:00
|
|
|
err_code = sd_ble_gap_adv_start(&m_adv_params);
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-02-13 11:06:13 -05:00
|
|
|
if (err_code != 0) {
|
2017-02-11 11:41:16 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can not start advertisement. status: 0x%02x"), (uint16_t)err_code));
|
2017-02-11 11:41:16 -05:00
|
|
|
}
|
|
|
|
|
2017-02-12 08:24:15 -05:00
|
|
|
m_adv_in_progress = true;
|
|
|
|
|
2017-02-11 11:41:16 -05:00
|
|
|
return true;
|
|
|
|
}
|
2017-02-12 18:18:47 -05:00
|
|
|
|
2017-04-04 15:22:49 -04:00
|
|
|
void ble_drv_advertise_stop(void) {
|
|
|
|
if (m_adv_in_progress == true) {
|
|
|
|
uint32_t err_code;
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
if ((err_code = sd_ble_gap_adv_stop(m_adv_handle)) != 0) {
|
2018-02-02 15:01:01 -05:00
|
|
|
#else
|
2017-04-04 15:22:49 -04:00
|
|
|
if ((err_code = sd_ble_gap_adv_stop()) != 0) {
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-04-04 15:22:49 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-10-03 03:56:30 -04:00
|
|
|
translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code));
|
2017-04-04 15:22:49 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
m_adv_in_progress = false;
|
|
|
|
}
|
|
|
|
|
2017-03-30 17:38:01 -04:00
|
|
|
void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
|
2017-02-18 15:11:39 -05:00
|
|
|
ble_gatts_value_t gatts_value;
|
|
|
|
memset(&gatts_value, 0, sizeof(gatts_value));
|
|
|
|
|
|
|
|
gatts_value.len = len;
|
|
|
|
gatts_value.offset = 0;
|
|
|
|
gatts_value.p_value = p_data;
|
|
|
|
|
|
|
|
uint32_t err_code = sd_ble_gatts_value_get(conn_handle,
|
|
|
|
handle,
|
|
|
|
&gatts_value);
|
|
|
|
if (err_code != 0) {
|
2017-03-26 15:05:06 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code));
|
2017-02-18 15:11:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-02-20 15:26:19 -05:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
|
2018-07-19 14:33:24 -04:00
|
|
|
bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
|
|
|
|
uint16_t conn_handle = device->conn_handle;
|
2017-02-18 15:11:39 -05:00
|
|
|
ble_gatts_value_t gatts_value;
|
2018-07-18 17:47:06 -04:00
|
|
|
|
2017-02-18 15:11:39 -05:00
|
|
|
memset(&gatts_value, 0, sizeof(gatts_value));
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
gatts_value.len = bufinfo->len;
|
2017-02-18 15:11:39 -05:00
|
|
|
gatts_value.offset = 0;
|
2018-07-18 17:47:06 -04:00
|
|
|
gatts_value.p_value = bufinfo->buf;
|
2017-02-18 15:11:39 -05:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value);
|
2017-02-18 15:11:39 -05:00
|
|
|
|
|
|
|
if (err_code != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
|
2017-02-18 15:11:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
|
2018-07-19 14:33:24 -04:00
|
|
|
bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
|
|
|
|
uint16_t conn_handle = device->conn_handle;
|
2017-02-18 15:11:39 -05:00
|
|
|
ble_gatts_hvx_params_t hvx_params;
|
2018-07-18 17:47:06 -04:00
|
|
|
uint16_t hvx_len = bufinfo->len;
|
2017-02-18 15:11:39 -05:00
|
|
|
|
|
|
|
memset(&hvx_params, 0, sizeof(hvx_params));
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
hvx_params.handle = characteristic->handle;
|
2017-02-18 15:11:39 -05:00
|
|
|
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
|
|
|
hvx_params.offset = 0;
|
|
|
|
hvx_params.p_len = &hvx_len;
|
2018-07-18 17:47:06 -04:00
|
|
|
hvx_params.p_data = bufinfo->buf;
|
2017-02-18 15:11:39 -05:00
|
|
|
|
2017-03-26 15:05:06 -04:00
|
|
|
while (m_tx_in_progress) {
|
2018-07-19 14:33:24 -04:00
|
|
|
#ifdef MICROPY_VM_HOOK_LOOP
|
|
|
|
MICROPY_VM_HOOK_LOOP
|
|
|
|
#endif
|
2017-03-26 15:05:06 -04:00
|
|
|
}
|
2017-02-18 15:11:39 -05:00
|
|
|
|
2017-02-27 17:40:39 -05:00
|
|
|
m_tx_in_progress = true;
|
|
|
|
uint32_t err_code;
|
|
|
|
if ((err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params)) != 0) {
|
2017-02-18 15:11:39 -05:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not notify attribute value. status: 0x%02x"), (uint16_t)err_code));
|
2017-02-18 15:11:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler) {
|
|
|
|
mp_gap_observer = device;
|
2017-03-14 03:13:32 -04:00
|
|
|
gap_event_handler = evt_handler;
|
2017-02-15 17:32:42 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler) {
|
|
|
|
mp_gatts_observer = device;
|
2017-03-14 03:13:32 -04:00
|
|
|
gatts_event_handler = evt_handler;
|
2017-02-18 18:08:05 -05:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler) {
|
|
|
|
mp_gattc_observer = device;
|
2017-03-26 16:57:07 -04:00
|
|
|
gattc_event_handler = evt_handler;
|
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *device, ble_drv_adv_evt_callback_t evt_handler) {
|
|
|
|
mp_adv_observer = device;
|
2017-03-14 03:13:32 -04:00
|
|
|
adv_event_handler = evt_handler;
|
2017-03-14 03:04:24 -04:00
|
|
|
}
|
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) {
|
2018-07-18 19:01:41 -04:00
|
|
|
bleio_service_obj_t *service = characteristic->service;
|
2018-07-19 14:33:24 -04:00
|
|
|
bleio_device_obj_t *device = MP_OBJ_TO_PTR(service->device);
|
2018-07-18 19:01:41 -04:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
mp_gattc_char_data_observer = characteristic;
|
2017-04-01 18:30:16 -04:00
|
|
|
gattc_char_data_handle = cb;
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0);
|
2017-04-01 18:30:16 -04:00
|
|
|
if (err_code != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code));
|
2017-04-01 18:30:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
while (gattc_char_data_handle != NULL) {
|
2018-07-19 14:33:24 -04:00
|
|
|
#ifdef MICROPY_VM_HOOK_LOOP
|
|
|
|
MICROPY_VM_HOOK_LOOP
|
|
|
|
#endif
|
2017-04-01 18:30:16 -04:00
|
|
|
}
|
|
|
|
}
|
2017-03-12 15:18:37 -04:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
|
2018-07-19 14:33:24 -04:00
|
|
|
bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device);
|
|
|
|
uint16_t conn_handle = device->conn_handle;
|
2017-05-30 13:29:46 -04:00
|
|
|
|
|
|
|
ble_gattc_write_params_t write_params;
|
2018-07-18 17:47:06 -04:00
|
|
|
write_params.write_op = BLE_GATT_OP_WRITE_REQ;
|
2017-05-30 13:29:46 -04:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
if (characteristic->props.write_wo_resp) {
|
2017-05-30 13:29:46 -04:00
|
|
|
write_params.write_op = BLE_GATT_OP_WRITE_CMD;
|
|
|
|
}
|
2017-05-14 13:00:22 -04:00
|
|
|
|
2017-05-30 13:29:46 -04:00
|
|
|
write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL;
|
2018-07-18 17:47:06 -04:00
|
|
|
write_params.handle = characteristic->handle;
|
2017-05-30 13:29:46 -04:00
|
|
|
write_params.offset = 0;
|
2018-07-18 17:47:06 -04:00
|
|
|
write_params.len = bufinfo->len;
|
|
|
|
write_params.p_value = bufinfo->buf;
|
2017-05-14 13:52:58 -04:00
|
|
|
|
2018-07-18 17:47:06 -04:00
|
|
|
m_write_done = (write_params.write_op == BLE_GATT_OP_WRITE_CMD);
|
2017-05-14 13:52:58 -04:00
|
|
|
|
2017-05-30 17:23:31 -04:00
|
|
|
uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
|
2017-05-30 13:29:46 -04:00
|
|
|
if (err_code != 0) {
|
2017-05-14 13:52:58 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code));
|
2017-05-30 13:29:46 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
while (m_write_done != true) {
|
|
|
|
#ifdef MICROPY_VM_HOOK_LOOP
|
|
|
|
MICROPY_VM_HOOK_LOOP
|
|
|
|
#endif
|
2017-05-30 13:29:46 -04:00
|
|
|
}
|
2017-05-14 13:00:22 -04:00
|
|
|
}
|
2018-07-19 14:33:24 -04:00
|
|
|
|
2018-07-18 04:22:11 -04:00
|
|
|
void ble_drv_scan_start(uint16_t interval, uint16_t window) {
|
2017-03-12 17:46:40 -04:00
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
2017-03-12 15:18:37 -04:00
|
|
|
ble_gap_scan_params_t scan_params;
|
2018-02-02 15:01:01 -05:00
|
|
|
memset(&scan_params, 0, sizeof(ble_gap_scan_params_t));
|
|
|
|
|
2017-03-12 15:18:37 -04:00
|
|
|
scan_params.active = 1;
|
2018-07-18 04:22:11 -04:00
|
|
|
scan_params.interval = MSEC_TO_UNITS(interval, UNIT_0_625_MS);
|
|
|
|
scan_params.window = MSEC_TO_UNITS(window, UNIT_0_625_MS);
|
2018-02-02 15:01:01 -05:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
2018-06-18 17:11:30 -04:00
|
|
|
scan_params.scan_phys = BLE_GAP_PHY_1MBPS;
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2018-06-18 17:11:30 -04:00
|
|
|
scan_params.timeout = 0; // Infinite
|
2017-03-12 15:18:37 -04:00
|
|
|
|
2017-03-12 17:46:40 -04:00
|
|
|
uint32_t err_code;
|
2018-06-18 17:11:30 -04:00
|
|
|
#if (BLUETOOTH_SD == 140)
|
|
|
|
if ((err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer)) != 0) {
|
|
|
|
#else
|
2017-03-12 17:46:40 -04:00
|
|
|
if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) {
|
2018-06-18 17:11:30 -04:00
|
|
|
#endif
|
2017-03-12 17:46:40 -04:00
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
2018-08-16 16:34:12 -04:00
|
|
|
translate("Can not start scanning. status: 0x%02x"), (uint16_t)err_code));
|
2017-03-12 17:46:40 -04:00
|
|
|
}
|
2017-03-12 14:50:38 -04:00
|
|
|
}
|
|
|
|
|
2018-07-17 11:00:37 -04:00
|
|
|
void ble_drv_scan_continue(void) {
|
|
|
|
SD_TEST_OR_ENABLE();
|
|
|
|
|
|
|
|
#if (BLUETOOTH_SD == 140)
|
|
|
|
uint32_t err_code;
|
|
|
|
if ((err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer)) != 0) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
|
|
|
"Can not continue scanning. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-03-12 14:50:38 -04:00
|
|
|
void ble_drv_scan_stop(void) {
|
2017-03-12 15:18:37 -04:00
|
|
|
sd_ble_gap_scan_stop();
|
2017-03-12 14:50:38 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:59:32 -04:00
|
|
|
STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry) {
|
|
|
|
if (memcmp(entry->address.value, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) {
|
2018-07-19 14:33:24 -04:00
|
|
|
ble_drv_adv_report_handler_set(NULL, NULL);
|
2017-03-23 16:03:40 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
ble_gap_scan_params_t scan_params;
|
|
|
|
memset(&scan_params, 0, sizeof(scan_params));
|
2017-03-23 16:03:40 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
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;
|
2017-03-23 16:03:40 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
ble_gap_addr_t addr;
|
|
|
|
memset(&addr, 0, sizeof(addr));
|
2017-03-23 16:03:40 -04:00
|
|
|
|
2018-07-19 14:59:32 -04:00
|
|
|
addr.addr_type = entry->address.type;
|
|
|
|
memcpy(addr.addr, entry->address.value, BLEIO_ADDRESS_BYTES);
|
2017-03-26 14:43:43 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n",
|
|
|
|
addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], addr.addr_type);
|
|
|
|
|
|
|
|
ble_gap_conn_params_t conn_params = {
|
|
|
|
.min_conn_interval = BLE_MIN_CONN_INTERVAL,
|
|
|
|
.max_conn_interval = BLE_MAX_CONN_INTERVAL,
|
|
|
|
.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT,
|
|
|
|
.slave_latency = BLE_SLAVE_LATENCY,
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t err_code;
|
|
|
|
#if (BLE_API_VERSION == 2)
|
|
|
|
if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) {
|
|
|
|
#else
|
|
|
|
if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) {
|
|
|
|
#endif
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
|
|
|
"Can not connect. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-26 14:43:43 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_connect(bleio_device_obj_t *device) {
|
|
|
|
SD_TEST_OR_ENABLE();
|
2017-03-26 14:43:43 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
mp_connect_address = &device->address;
|
|
|
|
ble_drv_adv_report_handler_set(NULL, ble_drv_connect_scan_callback);
|
2017-03-26 14:43:43 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
ble_drv_scan_start(100, 100);
|
|
|
|
}
|
2017-03-23 16:03:40 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void ble_drv_disconnect(bleio_device_obj_t *device) {
|
|
|
|
sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
|
2017-03-23 16:03:40 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 16:10:16 -04:00
|
|
|
bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle) {
|
2018-07-19 14:33:24 -04:00
|
|
|
mp_gattc_disc_service_observer = device;
|
2017-03-28 17:37:19 -04:00
|
|
|
|
2017-05-13 12:03:50 -04:00
|
|
|
m_primary_service_found = false;
|
|
|
|
|
2018-07-19 16:10:16 -04:00
|
|
|
uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL);
|
|
|
|
if (err_code != NRF_SUCCESS) {
|
|
|
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
|
|
|
"Failed to discover serivices. status: 0x" HEX2_FMT, (uint16_t)err_code));
|
2017-03-30 16:41:19 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 16:10:16 -04:00
|
|
|
while (mp_gattc_disc_service_observer != NULL) {
|
2018-07-19 14:33:24 -04:00
|
|
|
#ifdef MICROPY_VM_HOOK_LOOP
|
|
|
|
MICROPY_VM_HOOK_LOOP
|
|
|
|
#endif
|
2017-03-30 16:41:19 -04:00
|
|
|
}
|
2017-03-28 17:37:19 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
return m_primary_service_found;
|
2017-03-26 16:59:30 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 16:59:18 -04:00
|
|
|
bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) {
|
2018-07-19 14:33:24 -04:00
|
|
|
BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle);
|
2017-03-30 16:41:19 -04:00
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
mp_gattc_disc_char_observer = service;
|
2017-03-30 16:41:19 -04:00
|
|
|
|
|
|
|
ble_gattc_handle_range_t handle_range;
|
|
|
|
handle_range.start_handle = start_handle;
|
2018-07-19 14:33:24 -04:00
|
|
|
handle_range.end_handle = service->end_handle;
|
2017-03-30 16:41:19 -04:00
|
|
|
|
2017-05-14 11:11:29 -04:00
|
|
|
m_characteristic_found = false;
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range);
|
2017-03-30 16:41:19 -04:00
|
|
|
if (err_code != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-07-19 16:59:18 -04:00
|
|
|
while (mp_gattc_disc_char_observer != NULL) {
|
2018-07-19 14:33:24 -04:00
|
|
|
#ifdef MICROPY_VM_HOOK_LOOP
|
|
|
|
MICROPY_VM_HOOK_LOOP
|
|
|
|
#endif
|
2017-03-30 16:41:19 -04:00
|
|
|
}
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
return m_characteristic_found;
|
2017-03-26 16:59:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ble_drv_discover_descriptors(void) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-07-19 14:59:32 -04:00
|
|
|
STATIC void on_adv_report(ble_gap_evt_adv_report_t *report) {
|
|
|
|
bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
|
|
|
|
entry->base.type = &bleio_scanentry_type;
|
|
|
|
|
|
|
|
entry->rssi = report->rssi;
|
|
|
|
|
|
|
|
entry->address.type = report->peer_addr.addr_type;
|
|
|
|
memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES);
|
|
|
|
|
|
|
|
#if (BLUETOOTH_SD == 140)
|
|
|
|
entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data);
|
|
|
|
#else
|
|
|
|
entry->data = mp_obj_new_bytearray(report->dlen, report->data);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (adv_event_handler != NULL) {
|
|
|
|
adv_event_handler(mp_adv_observer, entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-19 16:10:16 -04:00
|
|
|
STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response) {
|
|
|
|
BLE_DRIVER_LOG(">>> service count: %d\n", response->count);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < response->count; ++i) {
|
|
|
|
const ble_gattc_service_t *gattc_service = &response->services[i];
|
|
|
|
|
|
|
|
bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
|
|
|
|
service->base.type = &bleio_service_type;
|
|
|
|
service->char_list = mp_obj_new_list(0, NULL);
|
|
|
|
service->start_handle = gattc_service->handle_range.start_handle;
|
|
|
|
service->end_handle = gattc_service->handle_range.end_handle;
|
|
|
|
service->handle = gattc_service->handle_range.start_handle;
|
|
|
|
service->device = mp_gattc_disc_service_observer;
|
|
|
|
|
|
|
|
bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
|
|
|
|
uuid->base.type = &bleio_uuid_type;
|
|
|
|
uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT;
|
|
|
|
uuid->value[0] = gattc_service->uuid.uuid & 0xFF;
|
|
|
|
uuid->value[1] = gattc_service->uuid.uuid >> 8;
|
|
|
|
service->uuid = uuid;
|
|
|
|
|
|
|
|
mp_obj_list_append(mp_gattc_disc_service_observer->service_list, service);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response->count > 0) {
|
|
|
|
m_primary_service_found = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// mark end of service discovery
|
|
|
|
mp_gattc_disc_service_observer = NULL;
|
|
|
|
}
|
|
|
|
|
2018-07-19 16:59:18 -04:00
|
|
|
STATIC void on_characteristic_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response) {
|
|
|
|
BLE_DRIVER_LOG(">>> characteristic count: %d\n", response->count);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < response->count; ++i) {
|
|
|
|
const ble_gattc_char_t *gattc_char = &response->chars[i];
|
|
|
|
|
|
|
|
bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
|
|
|
|
characteristic->base.type = &bleio_characteristic_type;
|
|
|
|
|
|
|
|
bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
|
|
|
|
uuid->base.type = &bleio_uuid_type;
|
|
|
|
uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT;
|
|
|
|
uuid->value[0] = gattc_char->uuid.uuid & 0xFF;
|
|
|
|
uuid->value[1] = gattc_char->uuid.uuid >> 8;
|
|
|
|
characteristic->uuid = uuid;
|
|
|
|
|
|
|
|
characteristic->props.broadcast = gattc_char->char_props.broadcast;
|
|
|
|
characteristic->props.indicate = gattc_char->char_props.indicate;
|
|
|
|
characteristic->props.notify = gattc_char->char_props.notify;
|
|
|
|
characteristic->props.read = gattc_char->char_props.read;
|
|
|
|
characteristic->props.write = gattc_char->char_props.write;
|
|
|
|
characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp;
|
|
|
|
characteristic->handle = gattc_char->handle_value;
|
|
|
|
|
|
|
|
characteristic->service_handle = mp_gattc_disc_char_observer->handle;
|
|
|
|
characteristic->service = mp_gattc_disc_char_observer;
|
|
|
|
|
|
|
|
mp_obj_list_append(mp_gattc_disc_char_observer->char_list, MP_OBJ_FROM_PTR(characteristic));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response->count > 0) {
|
|
|
|
m_characteristic_found = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// mark end of characteristic discovery
|
|
|
|
mp_gattc_disc_char_observer = NULL;
|
|
|
|
}
|
|
|
|
|
2018-07-19 16:10:16 -04:00
|
|
|
STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) {
|
2018-07-19 14:33:24 -04:00
|
|
|
printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id);
|
|
|
|
|
2017-02-12 18:18:47 -05:00
|
|
|
switch (p_ble_evt->header.evt_id) {
|
|
|
|
case BLE_GAP_EVT_CONNECTED:
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("GAP CONNECT\n");
|
2017-02-17 11:32:42 -05:00
|
|
|
m_adv_in_progress = false;
|
2017-03-14 03:13:32 -04:00
|
|
|
gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
|
2017-03-02 16:48:04 -05:00
|
|
|
|
2017-02-27 17:40:39 -05:00
|
|
|
ble_gap_conn_params_t conn_params;
|
|
|
|
(void)sd_ble_gap_ppcp_get(&conn_params);
|
|
|
|
(void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, &conn_params);
|
2017-02-12 18:18:47 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GAP_EVT_DISCONNECTED:
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("GAP DISCONNECT\n");
|
2017-03-14 03:13:32 -04:00
|
|
|
gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
|
2017-02-18 18:08:05 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GATTS_EVT_HVC:
|
2017-03-14 03:13:32 -04:00
|
|
|
gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gatts_evt.params.hvc.handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
|
2017-02-12 18:18:47 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GATTS_EVT_WRITE:
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("GATTS write\n");
|
2017-02-22 13:54:02 -05:00
|
|
|
|
2017-03-02 15:25:51 -05:00
|
|
|
uint16_t handle = p_ble_evt->evt.gatts_evt.params.write.handle;
|
2017-02-22 13:54:02 -05:00
|
|
|
uint16_t data_len = p_ble_evt->evt.gatts_evt.params.write.len;
|
|
|
|
uint8_t * p_data = &p_ble_evt->evt.gatts_evt.params.write.data[0];
|
|
|
|
|
2017-03-14 03:13:32 -04:00
|
|
|
gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, handle, data_len, p_data);
|
2017-02-14 14:18:53 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
|
2017-02-15 17:57:23 -05:00
|
|
|
BLE_DRIVER_LOG("GAP CONN PARAM UPDATE\n");
|
2017-02-12 18:18:47 -05:00
|
|
|
break;
|
|
|
|
|
2017-02-27 17:40:39 -05:00
|
|
|
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
|
|
|
// No system attributes have been stored.
|
|
|
|
(void)sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
|
|
|
|
break;
|
|
|
|
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 4)
|
2017-02-27 17:40:39 -05:00
|
|
|
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
|
|
|
|
BLE_DRIVER_LOG("GATTS EVT EXCHANGE MTU REQUEST\n");
|
|
|
|
(void)sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, 23); // MAX MTU size
|
|
|
|
break;
|
2017-02-28 17:13:02 -05:00
|
|
|
#endif
|
2017-02-27 17:40:39 -05:00
|
|
|
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 4)
|
2018-02-02 15:01:01 -05:00
|
|
|
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
|
|
|
|
#else
|
2017-02-27 17:40:39 -05:00
|
|
|
case BLE_EVT_TX_COMPLETE:
|
2018-02-02 15:01:01 -05:00
|
|
|
#endif
|
2017-02-27 17:40:39 -05:00
|
|
|
BLE_DRIVER_LOG("BLE EVT TX COMPLETE\n");
|
|
|
|
m_tx_in_progress = false;
|
|
|
|
break;
|
|
|
|
|
2017-03-02 16:48:04 -05:00
|
|
|
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
|
2017-03-12 15:20:15 -04:00
|
|
|
BLE_DRIVER_LOG("BLE EVT SEC PARAMS REQUEST\n");
|
|
|
|
// pairing not supported
|
|
|
|
(void)sd_ble_gap_sec_params_reply(p_ble_evt->evt.gatts_evt.conn_handle,
|
|
|
|
BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
|
|
|
|
NULL, NULL);
|
|
|
|
break;
|
2017-03-02 16:48:04 -05:00
|
|
|
|
2017-03-12 15:18:37 -04:00
|
|
|
case BLE_GAP_EVT_ADV_REPORT:
|
2018-07-19 14:59:32 -04:00
|
|
|
on_adv_report(&p_ble_evt->evt.gap_evt.params.adv_report);
|
2017-03-26 15:02:25 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
|
|
|
|
BLE_DRIVER_LOG("BLE EVT CONN PARAM UPDATE REQUEST\n");
|
|
|
|
|
|
|
|
(void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle,
|
|
|
|
&p_ble_evt->evt.gap_evt.params.conn_param_update_request.conn_params);
|
2017-03-12 15:20:15 -04:00
|
|
|
break;
|
2017-03-28 17:37:19 -04:00
|
|
|
|
|
|
|
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
|
2018-07-19 16:10:16 -04:00
|
|
|
on_primary_srv_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
|
2017-03-30 16:41:19 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GATTC_EVT_CHAR_DISC_RSP:
|
2018-07-19 16:59:18 -04:00
|
|
|
on_characteristic_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
|
2017-03-28 17:37:19 -04:00
|
|
|
break;
|
|
|
|
|
2017-03-30 17:18:49 -04:00
|
|
|
case BLE_GATTC_EVT_READ_RSP:
|
2017-04-01 10:34:26 -04:00
|
|
|
BLE_DRIVER_LOG("BLE EVT READ RESPONSE, offset: 0x"HEX2_FMT", length: 0x"HEX2_FMT"\n",
|
|
|
|
p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
|
|
|
|
p_ble_evt->evt.gattc_evt.params.read_rsp.len);
|
|
|
|
|
|
|
|
gattc_char_data_handle(mp_gattc_char_data_observer,
|
|
|
|
p_ble_evt->evt.gattc_evt.params.read_rsp.len,
|
|
|
|
p_ble_evt->evt.gattc_evt.params.read_rsp.data);
|
|
|
|
|
|
|
|
// mark end of read
|
|
|
|
gattc_char_data_handle = NULL;
|
|
|
|
|
2017-03-30 17:18:49 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GATTC_EVT_WRITE_RSP:
|
|
|
|
BLE_DRIVER_LOG("BLE EVT WRITE RESPONSE\n");
|
2017-05-30 13:29:46 -04:00
|
|
|
m_write_done = true;
|
2017-03-30 17:18:49 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BLE_GATTC_EVT_HVX:
|
|
|
|
BLE_DRIVER_LOG("BLE EVT HVX RESPONSE\n");
|
|
|
|
break;
|
2017-03-12 15:18:37 -04:00
|
|
|
|
2017-02-12 18:18:47 -05:00
|
|
|
default:
|
2017-02-27 17:40:39 -05:00
|
|
|
BLE_DRIVER_LOG(">>> unhandled evt: 0x" HEX2_FMT "\n", p_ble_evt->header.evt_id);
|
2017-02-12 18:18:47 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-07 15:45:46 -05:00
|
|
|
#if (BLE_API_VERSION == 2)
|
2017-02-12 18:18:47 -05:00
|
|
|
static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attribute__ ((aligned (4)));
|
|
|
|
#else
|
2018-02-07 15:45:46 -05:00
|
|
|
static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)] __attribute__ ((aligned (4)));
|
2017-02-12 18:18:47 -05:00
|
|
|
#endif
|
|
|
|
|
2018-07-19 14:33:24 -04:00
|
|
|
void SD_EVT_IRQHandler(void) {
|
2017-02-12 18:18:47 -05:00
|
|
|
uint32_t evt_id;
|
|
|
|
uint32_t err_code;
|
|
|
|
do {
|
|
|
|
err_code = sd_evt_get(&evt_id);
|
|
|
|
// TODO: handle non ble events
|
|
|
|
} while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS);
|
|
|
|
|
|
|
|
uint16_t evt_len = sizeof(m_ble_evt_buf);
|
|
|
|
do {
|
|
|
|
err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len);
|
|
|
|
ble_evt_handler((ble_evt_t *)m_ble_evt_buf);
|
|
|
|
} while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS);
|
|
|
|
}
|
2017-05-11 12:37:48 -04:00
|
|
|
|
|
|
|
#endif // BLUETOOTH_SD
|