Import Mbed OS hard-float snapshot
This commit is contained in:
@@ -0,0 +1,605 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "ble/BLE.h"
|
||||
#include "CriticalSectionLock.h"
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_msg.h"
|
||||
#include "wsf_os.h"
|
||||
#include "wsf_buf.h"
|
||||
#include "wsf_timer.h"
|
||||
#include "hci_handler.h"
|
||||
#include "dm_handler.h"
|
||||
#include "l2c_handler.h"
|
||||
#include "att_handler.h"
|
||||
#include "smp_handler.h"
|
||||
#include "l2c_api.h"
|
||||
#include "att_api.h"
|
||||
#include "smp_api.h"
|
||||
#include "hci_drv.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "bstream.h"
|
||||
|
||||
#include "ble/internal/PalAttClient.h"
|
||||
#include "ble/internal/PalSecurityManager.h"
|
||||
#include "ble/internal/PalGap.h"
|
||||
#include "ble/internal/PalSigningMonitor.h"
|
||||
#include "ble/internal/BLEInstanceBase.h"
|
||||
#include "CordioHCIDriver.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
/*! WSF handler ID */
|
||||
wsfHandlerId_t stack_handler_id;
|
||||
|
||||
/* WSF heap allocation */
|
||||
uint8_t *SystemHeapStart;
|
||||
uint32_t SystemHeapSize;
|
||||
|
||||
/**
|
||||
* Weak definition of ble_cordio_get_hci_driver.
|
||||
* A runtime error is generated if the user does not define any
|
||||
* ble_cordio_get_hci_driver.
|
||||
*/
|
||||
MBED_WEAK ble::CordioHCIDriver &ble_cordio_get_hci_driver()
|
||||
{
|
||||
MBED_ASSERT("No HCI driver");
|
||||
printf("Please provide an implementation for the HCI driver");
|
||||
ble::CordioHCIDriver *bad_instance = nullptr;
|
||||
return *bad_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Low level HCI interface between Cordio stack and the port.
|
||||
*/
|
||||
extern "C" uint16_t hci_mbed_os_drv_write(uint8_t type, uint16_t len, uint8_t *pData)
|
||||
{
|
||||
return ble_cordio_get_hci_driver().write(type, len, pData);
|
||||
}
|
||||
|
||||
extern "C" void hci_mbed_os_start_reset_sequence(void)
|
||||
{
|
||||
ble_cordio_get_hci_driver().start_reset_sequence();
|
||||
}
|
||||
|
||||
extern "C" void hci_mbed_os_handle_reset_sequence(uint8_t *msg)
|
||||
{
|
||||
ble_cordio_get_hci_driver().handle_reset_sequence(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will signal to the user code by calling signalEventsToProcess.
|
||||
* It is registered and called into the Wsf Stack.
|
||||
*/
|
||||
extern "C" MBED_WEAK void wsf_mbed_ble_signal_event(void)
|
||||
{
|
||||
BLE::Instance().signalEventsToProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* BLE-API requires an implementation of the following function in order to
|
||||
* obtain its transport handle.
|
||||
*/
|
||||
ble::BLEInstanceBase *createBLEInstance()
|
||||
{
|
||||
return (&(ble::BLEInstanceBase::deviceInstance()));
|
||||
}
|
||||
|
||||
namespace ble {
|
||||
|
||||
BLEInstanceBase::BLEInstanceBase(CordioHCIDriver &hci_driver) :
|
||||
initialization_status(NOT_INITIALIZED),
|
||||
_event_queue(),
|
||||
_last_update_us(0)
|
||||
{
|
||||
_hci_driver = &hci_driver;
|
||||
stack_setup();
|
||||
}
|
||||
|
||||
BLEInstanceBase::~BLEInstanceBase()
|
||||
{}
|
||||
|
||||
/**
|
||||
* The singleton which represents the BLE transport for the BLE.
|
||||
*/
|
||||
BLEInstanceBase &BLEInstanceBase::deviceInstance()
|
||||
{
|
||||
static BLEInstanceBase instance(
|
||||
ble_cordio_get_hci_driver()
|
||||
);
|
||||
return instance;
|
||||
}
|
||||
|
||||
ble_error_t BLEInstanceBase::init(
|
||||
FunctionPointerWithContext<::BLE::InitializationCompleteCallbackContext *> initCallback)
|
||||
{
|
||||
switch (initialization_status) {
|
||||
case NOT_INITIALIZED:
|
||||
_timer.reset();
|
||||
_timer.start();
|
||||
_event_queue.initialize(this);
|
||||
_init_callback = initCallback;
|
||||
start_stack_reset();
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case INITIALIZING:
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
|
||||
case INITIALIZED:
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
bool BLEInstanceBase::hasInitialized() const
|
||||
{
|
||||
return initialization_status == INITIALIZED;
|
||||
}
|
||||
|
||||
ble_error_t BLEInstanceBase::shutdown()
|
||||
{
|
||||
if (initialization_status != INITIALIZED) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
|
||||
initialization_status = NOT_INITIALIZED;
|
||||
_hci_driver->terminate();
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
getGattServer().reset();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
getGattClient().reset();
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
|
||||
getGap().reset();
|
||||
_event_queue.clear();
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
const char *BLEInstanceBase::getVersion()
|
||||
{
|
||||
static const char version[] = "generic-cordio";
|
||||
return version;
|
||||
}
|
||||
|
||||
ble::Gap &BLEInstanceBase::getGap()
|
||||
{
|
||||
static ble::PalGenericAccessService cordio_gap_service;
|
||||
static ble::Gap gap(
|
||||
_event_queue,
|
||||
ble::PalGap::get_gap(),
|
||||
cordio_gap_service,
|
||||
ble::PalSecurityManager::get_security_manager()
|
||||
);
|
||||
|
||||
return gap;
|
||||
}
|
||||
|
||||
const ble::Gap &BLEInstanceBase::getGap() const
|
||||
{
|
||||
BLEInstanceBase &self = const_cast<BLEInstanceBase &>(*this);
|
||||
return const_cast<const ble::Gap &>(self.getGap());
|
||||
};
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
|
||||
GattServer &BLEInstanceBase::getGattServer()
|
||||
{
|
||||
return GattServer::getInstance();
|
||||
}
|
||||
|
||||
const GattServer &BLEInstanceBase::getGattServer() const
|
||||
{
|
||||
return GattServer::getInstance();
|
||||
}
|
||||
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
|
||||
ble::GattClient &BLEInstanceBase::getGattClient()
|
||||
{
|
||||
static ble::GattClient gatt_client(getPalGattClient());
|
||||
|
||||
return gatt_client;
|
||||
}
|
||||
|
||||
PalGattClient &BLEInstanceBase::getPalGattClient()
|
||||
{
|
||||
static PalGattClient pal_gatt_client(PalAttClient::get_client());
|
||||
return pal_gatt_client;
|
||||
}
|
||||
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
|
||||
#if BLE_FEATURE_SECURITY
|
||||
|
||||
SecurityManager &BLEInstanceBase::getSecurityManager()
|
||||
{
|
||||
static PalSigningMonitor signing_event_monitor;
|
||||
static ble::SecurityManager m_instance(
|
||||
ble::PalSecurityManager::get_security_manager(),
|
||||
getGap(),
|
||||
signing_event_monitor
|
||||
);
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
const SecurityManager &BLEInstanceBase::getSecurityManager() const
|
||||
{
|
||||
const BLEInstanceBase &self = const_cast<BLEInstanceBase &>(*this);
|
||||
return const_cast<const SecurityManager &>(self.getSecurityManager());
|
||||
}
|
||||
|
||||
#endif // BLE_FEATURE_SECURITY
|
||||
|
||||
void BLEInstanceBase::waitForEvent()
|
||||
{
|
||||
static Timeout nextTimeout;
|
||||
timestamp_t nextTimestamp;
|
||||
bool_t pTimerRunning;
|
||||
|
||||
callDispatcher();
|
||||
|
||||
if (wsfOsReadyToSleep()) {
|
||||
// setup an mbed timer for the next cordio timeout
|
||||
nextTimestamp = (timestamp_t) (WsfTimerNextExpiration(&pTimerRunning) * WSF_MS_PER_TICK);
|
||||
if (pTimerRunning) {
|
||||
nextTimeout.attach(timeoutCallback, milliseconds(nextTimestamp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BLEInstanceBase::processEvents()
|
||||
{
|
||||
callDispatcher();
|
||||
}
|
||||
|
||||
void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg)
|
||||
{
|
||||
if (msg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if BLE_FEATURE_SECURITY
|
||||
if (ble::PalSecurityManager::get_security_manager().sm_handler(msg)) {
|
||||
return;
|
||||
}
|
||||
#endif // BLE_FEATURE_SECURITY
|
||||
|
||||
switch (msg->event) {
|
||||
case DM_RESET_CMPL_IND: {
|
||||
::BLE::InitializationCompleteCallbackContext context = {
|
||||
::BLE::Instance(::BLE::DEFAULT_INSTANCE),
|
||||
BLE_ERROR_NONE
|
||||
};
|
||||
#if BLE_FEATURE_EXTENDED_ADVERTISING
|
||||
// initialize extended module if supported
|
||||
if (HciGetLeSupFeat() & HCI_LE_SUP_FEAT_LE_EXT_ADV) {
|
||||
#if BLE_ROLE_BROADCASTER
|
||||
DmExtAdvInit();
|
||||
#endif // BLE_ROLE_BROADCASTER
|
||||
#if BLE_ROLE_OBSERVER
|
||||
DmExtScanInit();
|
||||
#endif // BLE_ROLE_OBSERVER
|
||||
#if BLE_ROLE_CENTRAL
|
||||
DmExtConnMasterInit();
|
||||
#endif // BLE_ROLE_CENTRAL
|
||||
#if BLE_ROLE_PERIPHERAL
|
||||
DmExtConnSlaveInit();
|
||||
#endif // BLE_ROLE_PERIPHERAL
|
||||
}
|
||||
#endif // BLE_FEATURE_EXTENDED_ADVERTISING
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
deviceInstance().getGattServer().initialize();
|
||||
#endif
|
||||
deviceInstance().initialization_status = INITIALIZED;
|
||||
_init_callback.call(&context);
|
||||
}
|
||||
break;
|
||||
#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS
|
||||
case DM_UNHANDLED_CMD_CMPL_EVT_IND: {
|
||||
// upcast to unhandled command complete event to access the payload
|
||||
hciUnhandledCmdCmplEvt_t *unhandled = (hciUnhandledCmdCmplEvt_t *) msg;
|
||||
if (unhandled->hdr.status == HCI_SUCCESS && unhandled->hdr.param == HCI_OPCODE_LE_TEST_END) {
|
||||
// unhandled events are not parsed so we need to parse the payload ourselves
|
||||
uint8_t status;
|
||||
uint16_t packet_number;
|
||||
status = unhandled->param[0];
|
||||
BYTES_TO_UINT16(packet_number, unhandled->param + 1);
|
||||
|
||||
_hci_driver->handle_test_end(status == 0, packet_number);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS
|
||||
|
||||
default:
|
||||
ble::PalGap::gap_handler(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BLEInstanceBase::device_manager_cb(dmEvt_t *dm_event)
|
||||
{
|
||||
if (dm_event->hdr.status == HCI_SUCCESS && dm_event->hdr.event == DM_CONN_DATA_LEN_CHANGE_IND) {
|
||||
// this event can only happen after a connection has been established therefore gap is present
|
||||
ble::PalGapEventHandler *handler;
|
||||
handler = ble::PalGap::get_gap().get_event_handler();
|
||||
if (handler) {
|
||||
handler->on_data_length_change(
|
||||
dm_event->hdr.param,
|
||||
dm_event->dataLenChange.maxTxOctets,
|
||||
dm_event->dataLenChange.maxRxOctets
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BLEInstanceBase::deviceInstance().stack_handler(0, &dm_event->hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* AttServerInitDeInitCback callback is used to Initialize/Deinitialize
|
||||
* the CCC Table of the ATT Server when a remote peer requests to Open
|
||||
* or Close the connection.
|
||||
*/
|
||||
void BLEInstanceBase::connection_handler(dmEvt_t *dm_event)
|
||||
{
|
||||
dmConnId_t connId = (dmConnId_t) dm_event->hdr.param;
|
||||
|
||||
switch (dm_event->hdr.event) {
|
||||
case DM_CONN_OPEN_IND:
|
||||
/* set up CCC table with uninitialized (all zero) values */
|
||||
AttsCccInitTable(connId, nullptr);
|
||||
break;
|
||||
case DM_CONN_CLOSE_IND:
|
||||
/* clear CCC table on connection close */
|
||||
AttsCccClearTable(connId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BLEInstanceBase::timeoutCallback()
|
||||
{
|
||||
wsf_mbed_ble_signal_event();
|
||||
}
|
||||
|
||||
void BLEInstanceBase::stack_setup()
|
||||
{
|
||||
MBED_ASSERT(_hci_driver != nullptr);
|
||||
|
||||
wsfHandlerId_t handlerId;
|
||||
|
||||
buf_pool_desc_t buf_pool_desc = _hci_driver->get_buffer_pool_description();
|
||||
|
||||
// use the buffer for the WSF heap
|
||||
SystemHeapStart = buf_pool_desc.buffer_memory;
|
||||
SystemHeapSize = buf_pool_desc.buffer_size;
|
||||
|
||||
// Initialize buffers with the ones provided by the HCI driver
|
||||
uint16_t bytes_used = WsfBufInit(buf_pool_desc.pool_count, (wsfBufPoolDesc_t *) buf_pool_desc.pool_description);
|
||||
|
||||
// Raise assert if not enough memory was allocated
|
||||
MBED_ASSERT(bytes_used != 0);
|
||||
|
||||
SystemHeapStart += bytes_used;
|
||||
SystemHeapSize -= bytes_used;
|
||||
|
||||
// This warning will be raised if we've allocated too much memory
|
||||
if (bytes_used < buf_pool_desc.buffer_size) {
|
||||
MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_INVALID_SIZE),
|
||||
"Too much memory allocated for Cordio memory pool, reduce buf_pool_desc.buffer_size by value below.",
|
||||
buf_pool_desc.buffer_size - bytes_used);
|
||||
}
|
||||
|
||||
WsfTimerInit();
|
||||
|
||||
// Note: SecInit required for RandInit.
|
||||
SecInit();
|
||||
SecRandInit();
|
||||
|
||||
#if BLE_FEATURE_SECURITY
|
||||
SecAesInit();
|
||||
SecCmacInit();
|
||||
SecEccInit();
|
||||
#endif
|
||||
|
||||
handlerId = WsfOsSetNextHandler(HciHandler);
|
||||
HciHandlerInit(handlerId);
|
||||
|
||||
handlerId = WsfOsSetNextHandler(DmHandler);
|
||||
|
||||
#if BLE_ROLE_BROADCASTER
|
||||
DmAdvInit();
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_OBSERVER
|
||||
DmScanInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_CONNECTABLE
|
||||
DmConnInit();
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_CENTRAL
|
||||
DmConnMasterInit();
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_PERIPHERAL
|
||||
DmConnSlaveInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_SECURITY
|
||||
DmSecInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_PHY_MANAGEMENT
|
||||
DmPhyInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_SECURE_CONNECTIONS
|
||||
DmSecLescInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_PRIVACY
|
||||
DmPrivInit();
|
||||
#endif
|
||||
|
||||
DmHandlerInit(handlerId);
|
||||
|
||||
#if BLE_ROLE_PERIPHERAL
|
||||
handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
|
||||
L2cSlaveHandlerInit(handlerId);
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_CONNECTABLE
|
||||
L2cInit();
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_PERIPHERAL
|
||||
L2cSlaveInit();
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_CENTRAL
|
||||
L2cMasterInit();
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_ATT
|
||||
handlerId = WsfOsSetNextHandler(AttHandler);
|
||||
AttHandlerInit(handlerId);
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
AttsInit();
|
||||
AttsIndInit();
|
||||
#if BLE_FEATURE_SECURITY
|
||||
AttsAuthorRegister(GattServer::atts_auth_cb);
|
||||
#endif
|
||||
#if BLE_FEATURE_SIGNING
|
||||
AttsSignInit();
|
||||
#endif
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
AttcInit();
|
||||
#if BLE_FEATURE_SIGNING
|
||||
AttcSignInit();
|
||||
#endif
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
|
||||
#endif // BLE_FEATURE_ATT
|
||||
|
||||
#if BLE_FEATURE_SECURITY
|
||||
handlerId = WsfOsSetNextHandler(SmpHandler);
|
||||
SmpHandlerInit(handlerId);
|
||||
|
||||
#if BLE_ROLE_PERIPHERAL
|
||||
SmprInit();
|
||||
#if BLE_FEATURE_SECURE_CONNECTIONS
|
||||
SmprScInit();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BLE_ROLE_CENTRAL
|
||||
SmpiInit();
|
||||
#if BLE_FEATURE_SECURE_CONNECTIONS
|
||||
SmpiScInit();
|
||||
#endif
|
||||
#endif // BLE_ROLE_CENTRAL
|
||||
|
||||
#endif // BLE_FEATURE_SECURITY
|
||||
|
||||
stack_handler_id = WsfOsSetNextHandler(&BLEInstanceBase::stack_handler);
|
||||
|
||||
HciSetMaxRxAclLen(MBED_CONF_CORDIO_RX_ACL_BUFFER_SIZE);
|
||||
|
||||
DmRegister(BLEInstanceBase::device_manager_cb);
|
||||
#if BLE_FEATURE_CONNECTABLE
|
||||
DmConnRegister(DM_CLIENT_ID_APP, BLEInstanceBase::device_manager_cb);
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
AttConnRegister(BLEInstanceBase::connection_handler);
|
||||
#endif
|
||||
|
||||
#if BLE_FEATURE_ATT
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
AttRegister((attCback_t) ble::PalAttClient::att_client_handler);
|
||||
#else
|
||||
AttRegister((attCback_t) ble::GattServer::att_cb);
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
#endif
|
||||
}
|
||||
|
||||
void BLEInstanceBase::start_stack_reset()
|
||||
{
|
||||
_hci_driver->initialize();
|
||||
DmDevReset();
|
||||
}
|
||||
|
||||
void BLEInstanceBase::callDispatcher()
|
||||
{
|
||||
// process the external event queue
|
||||
_event_queue.process();
|
||||
|
||||
_last_update_us += (uint64_t) _timer.elapsed_time().count();
|
||||
_timer.reset();
|
||||
|
||||
uint64_t last_update_ms = (_last_update_us / 1000);
|
||||
wsfTimerTicks_t wsf_ticks = (last_update_ms / WSF_MS_PER_TICK);
|
||||
|
||||
if (wsf_ticks > 0) {
|
||||
WsfTimerUpdate(wsf_ticks);
|
||||
|
||||
_last_update_us -= (last_update_ms * 1000);
|
||||
}
|
||||
|
||||
wsfOsDispatcher();
|
||||
|
||||
static LowPowerTimeout nextTimeout;
|
||||
CriticalSectionLock critical_section;
|
||||
|
||||
if (wsfOsReadyToSleep()) {
|
||||
// setup an mbed timer for the next Cordio timeout
|
||||
bool_t pTimerRunning;
|
||||
timestamp_t nextTimestamp = (timestamp_t) (WsfTimerNextExpiration(&pTimerRunning) * WSF_MS_PER_TICK);
|
||||
if (pTimerRunning) {
|
||||
nextTimeout.attach(timeoutCallback, milliseconds(nextTimestamp));
|
||||
} else {
|
||||
critical_section.disable();
|
||||
_hci_driver->on_host_stack_inactivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CordioHCIDriver *BLEInstanceBase::_hci_driver = nullptr;
|
||||
|
||||
FunctionPointerWithContext<::BLE::InitializationCompleteCallbackContext *> BLEInstanceBase::_init_callback;
|
||||
|
||||
} // namespace ble
|
||||
@@ -0,0 +1,451 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ble/internal/PalAttClient.h"
|
||||
#include "ble/GattServer.h"
|
||||
#include "ble/internal/PalSimpleAttServerMessage.h"
|
||||
#include "ble/internal/PalGap.h"
|
||||
#include "ble/internal/PalGattClient.h"
|
||||
#include "ble/internal/BLEInstanceBase.h"
|
||||
|
||||
#include "att_api.h"
|
||||
#include "att_defs.h"
|
||||
|
||||
namespace ble {
|
||||
|
||||
PalAttClient::PalAttClient() : _local_sign_counter(0) {}
|
||||
|
||||
PalAttClient::~PalAttClient() {}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::exchange_mtu_request
|
||||
*/
|
||||
ble_error_t PalAttClient::exchange_mtu_request(connection_handle_t connection)
|
||||
{
|
||||
AttcMtuReq(connection, pAttCfg->mtu);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalGattClient::get_mtu_size
|
||||
*/
|
||||
ble_error_t PalAttClient::get_mtu_size(
|
||||
connection_handle_t connection_handle,
|
||||
uint16_t &mtu_size
|
||||
)
|
||||
{
|
||||
mtu_size = AttGetMtu(connection_handle);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::find_information_request
|
||||
*/
|
||||
ble_error_t PalAttClient::find_information_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
)
|
||||
{
|
||||
AttcFindInfoReq(
|
||||
connection_handle,
|
||||
discovery_range.begin,
|
||||
discovery_range.end,
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::find_by_type_value_request
|
||||
*/
|
||||
ble_error_t PalAttClient::find_by_type_value_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range,
|
||||
uint16_t type,
|
||||
const Span<const uint8_t> &value
|
||||
)
|
||||
{
|
||||
AttcFindByTypeValueReq(
|
||||
connection_handle,
|
||||
discovery_range.begin,
|
||||
discovery_range.end,
|
||||
type,
|
||||
value.size(),
|
||||
const_cast<uint8_t *>(value.data()),
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::read_by_type_request
|
||||
*/
|
||||
ble_error_t PalAttClient::read_by_type_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID &type
|
||||
)
|
||||
{
|
||||
AttcReadByTypeReq(
|
||||
connection_handle,
|
||||
read_range.begin,
|
||||
read_range.end,
|
||||
type.getLen(),
|
||||
const_cast<uint8_t *>(type.getBaseUUID()),
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::read_request
|
||||
*/
|
||||
ble_error_t PalAttClient::read_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
)
|
||||
{
|
||||
AttcReadReq(connection_handle, attribute_handle);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::read_blob_request
|
||||
*/
|
||||
ble_error_t PalAttClient::read_blob_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
)
|
||||
{
|
||||
AttcReadLongReq(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
offset,
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::read_multiple_request
|
||||
*/
|
||||
ble_error_t PalAttClient::read_multiple_request(
|
||||
connection_handle_t connection_handle,
|
||||
const Span<const attribute_handle_t> &attribute_handles
|
||||
)
|
||||
{
|
||||
AttcReadMultipleReq(
|
||||
connection_handle,
|
||||
attribute_handles.size(),
|
||||
const_cast<uint16_t *>(attribute_handles.data())
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::read_by_group_type_request
|
||||
*/
|
||||
ble_error_t PalAttClient::read_by_group_type_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID &group_type
|
||||
)
|
||||
{
|
||||
AttcReadByGroupTypeReq(
|
||||
connection_handle,
|
||||
read_range.begin,
|
||||
read_range.end,
|
||||
group_type.getLen(),
|
||||
const_cast<uint8_t *>(group_type.getBaseUUID()),
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::write_request
|
||||
*/
|
||||
ble_error_t PalAttClient::write_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const Span<const uint8_t> &value
|
||||
)
|
||||
{
|
||||
AttcWriteReq(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
value.size(),
|
||||
const_cast<uint8_t *>(value.data())
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::write_command
|
||||
*/
|
||||
ble_error_t PalAttClient::write_command(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const Span<const uint8_t> &value
|
||||
)
|
||||
{
|
||||
AttcWriteCmd(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
value.size(),
|
||||
const_cast<uint8_t *>(value.data())
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::signed_write_command
|
||||
*/
|
||||
ble_error_t PalAttClient::signed_write_command(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const Span<const uint8_t> &value
|
||||
)
|
||||
{
|
||||
AttcSignedWriteCmd(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
_local_sign_counter,
|
||||
value.size(),
|
||||
const_cast<uint8_t *>(value.data())
|
||||
);
|
||||
_local_sign_counter++;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the counter used to sign messages. Counter will be incremented every
|
||||
* time a message is signed.
|
||||
*
|
||||
* @param sign_counter initialise the signing counter to this value
|
||||
*/
|
||||
void PalAttClient::set_sign_counter(
|
||||
sign_count_t sign_counter
|
||||
)
|
||||
{
|
||||
_local_sign_counter = sign_counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::prepare_write_request
|
||||
*/
|
||||
ble_error_t PalAttClient::prepare_write_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset,
|
||||
const Span<const uint8_t> &value
|
||||
)
|
||||
{
|
||||
AttcPrepareWriteReq(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
offset,
|
||||
value.size(),
|
||||
const_cast<uint8_t *>(value.data()),
|
||||
false,
|
||||
false
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::execute_write_request
|
||||
*/
|
||||
ble_error_t PalAttClient::execute_write_request(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
)
|
||||
{
|
||||
AttcExecuteWriteReq(
|
||||
connection_handle,
|
||||
execute
|
||||
);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::initialize
|
||||
*/
|
||||
ble_error_t PalAttClient::initialize()
|
||||
{
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::PalAttClient::terminate
|
||||
*/
|
||||
ble_error_t PalAttClient::terminate()
|
||||
{
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
// singleton of the ARM Cordio client
|
||||
PalAttClient &PalAttClient::get_client()
|
||||
{
|
||||
static PalAttClient _client;
|
||||
return _client;
|
||||
}
|
||||
|
||||
void PalAttClient::when_server_message_received(
|
||||
mbed::Callback<void(connection_handle_t, const AttServerMessage &)> cb
|
||||
)
|
||||
{
|
||||
_server_message_cb = cb;
|
||||
}
|
||||
|
||||
void PalAttClient::when_transaction_timeout(
|
||||
mbed::Callback<void(connection_handle_t)> cb
|
||||
)
|
||||
{
|
||||
_transaction_timeout_cb = cb;
|
||||
}
|
||||
|
||||
// convert an array of byte to an uint16_t
|
||||
uint16_t PalAttClient::to_uint16_t(const uint8_t *array)
|
||||
{
|
||||
uint16_t result;
|
||||
memcpy(&result, array, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool PalAttClient::event_handler(const attEvt_t *event)
|
||||
{
|
||||
if (T::can_convert(event)) {
|
||||
generated_handler(event, T::convert);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PalAttClient::timeout_event_handler(const attEvt_t *event)
|
||||
{
|
||||
if (event->hdr.status != ATT_ERR_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
get_client().on_transaction_timeout(event->hdr.param);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename ResultType>
|
||||
void PalAttClient::generated_handler(
|
||||
const attEvt_t *event, ResultType (*convert)(const attEvt_t *)
|
||||
)
|
||||
{
|
||||
get_client().on_server_event(
|
||||
event->hdr.param,
|
||||
convert(event)
|
||||
);
|
||||
}
|
||||
|
||||
void PalAttClient::on_server_event(
|
||||
connection_handle_t connection_handle,
|
||||
const AttServerMessage &server_message
|
||||
)
|
||||
{
|
||||
if (_server_message_cb) {
|
||||
_server_message_cb(connection_handle, server_message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upon transaction timeout an implementation shall call this function.
|
||||
*
|
||||
* @param connection_handle The handle of the connection of the transaction
|
||||
* which has times out.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.3.3
|
||||
*/
|
||||
void PalAttClient::on_transaction_timeout(
|
||||
connection_handle_t connection_handle
|
||||
)
|
||||
{
|
||||
if (_transaction_timeout_cb) {
|
||||
_transaction_timeout_cb(connection_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void PalAttClient::att_client_handler(const attEvt_t *event)
|
||||
{
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
if (event->hdr.status == ATT_SUCCESS && event->hdr.event == ATT_MTU_UPDATE_IND) {
|
||||
ble::BLEInstanceBase &ble = ble::BLEInstanceBase::deviceInstance();
|
||||
PalGattClientEventHandler *handler = ble.getPalGattClient().get_event_handler();
|
||||
if (handler) {
|
||||
handler->on_att_mtu_change(event->hdr.param, event->mtu);
|
||||
}
|
||||
} else if (event->hdr.event == ATTC_WRITE_CMD_RSP) {
|
||||
ble::BLEInstanceBase &ble = ble::BLEInstanceBase::deviceInstance();
|
||||
PalGattClientEventHandler *handler = ble.getPalGattClient().get_event_handler();
|
||||
if (handler) {
|
||||
handler->on_write_command_sent(
|
||||
event->hdr.param,
|
||||
event->handle,
|
||||
event->hdr.status
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// all handlers are stored in a static array
|
||||
static const event_handler_t handlers[] = {
|
||||
&timeout_event_handler,
|
||||
&event_handler<ErrorResponseConverter>,
|
||||
&event_handler<FindInformationResponseConverter>,
|
||||
&event_handler<FindByTypeValueResponseConverter>,
|
||||
&event_handler<ReadByTypeResponseConverter>,
|
||||
&event_handler<ReadResponseConverter>,
|
||||
&event_handler<ReadBlobResponseConverter>,
|
||||
&event_handler<ReadMultipleResponseConverter>,
|
||||
&event_handler<ReadBygroupTypeResponseConverter>,
|
||||
&event_handler<WriteResponseConverter>,
|
||||
&event_handler<PrepareWriteResponseConverter>,
|
||||
&event_handler<ExecuteWriteResponseConverter>,
|
||||
&event_handler<HandleValueIndicationConverter>,
|
||||
&event_handler<HandleValueNotificationConverter>
|
||||
};
|
||||
|
||||
// event->hdr.param: connection handle
|
||||
// event->header.event: opcode from the request
|
||||
// event->header.status: success or error code ...
|
||||
// event->pValue: starting after opcode for response; starting after opcode + handle for server initiated responses.
|
||||
// event->handle: handle for server initiated responses
|
||||
|
||||
// traverse all handlers and execute them with the event in input.
|
||||
// exit if an handler has handled the event.
|
||||
for (size_t i = 0; i < (sizeof(handlers) / sizeof(handlers[0])); ++i) {
|
||||
if (handlers[i](event)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
// pass events not handled to the server side
|
||||
ble::GattServer::getInstance().att_cb(event);
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
} // ble
|
||||
@@ -0,0 +1,29 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ble/internal/PalEventQueue.h"
|
||||
#include "ble/internal/BLEInstanceBase.h"
|
||||
|
||||
namespace ble {
|
||||
|
||||
void PalEventQueue::signal_event()
|
||||
{
|
||||
_ble_base->signalEventsToProcess();
|
||||
}
|
||||
|
||||
} // namespace ble
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,251 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ble/internal/PalGattClient.h"
|
||||
#include "ble/internal/PalAttClient.h"
|
||||
|
||||
namespace ble {
|
||||
|
||||
PalGattClient::PalGattClient(PalAttClient& client) : _event_handler(nullptr), _client(client)
|
||||
{
|
||||
_client.when_server_message_received(
|
||||
mbed::callback(this, &PalGattClient::on_server_event)
|
||||
);
|
||||
_client.when_transaction_timeout(
|
||||
mbed::callback(
|
||||
this, &PalGattClient::on_transaction_timeout
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::exchange_mtu(connection_handle_t connection)
|
||||
{
|
||||
return _client.exchange_mtu_request(connection);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::get_mtu_size(
|
||||
connection_handle_t connection_handle,
|
||||
uint16_t& mtu_size
|
||||
)
|
||||
{
|
||||
return _client.get_mtu_size(connection_handle, mtu_size);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::discover_primary_service(
|
||||
connection_handle_t connection,
|
||||
attribute_handle_t discovery_range_begining
|
||||
)
|
||||
{
|
||||
return _client.read_by_group_type_request(
|
||||
connection,
|
||||
attribute_handle_range(discovery_range_begining, END_ATTRIBUTE_HANDLE),
|
||||
SERVICE_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::discover_primary_service_by_service_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t discovery_range_begining,
|
||||
const UUID& uuid
|
||||
)
|
||||
{
|
||||
return _client.find_by_type_value_request(
|
||||
connection_handle,
|
||||
attribute_handle_range(discovery_range_begining, END_ATTRIBUTE_HANDLE),
|
||||
SERVICE_TYPE_UUID,
|
||||
Span<const uint8_t>(
|
||||
uuid.getBaseUUID(),
|
||||
(uuid.shortOrLong() == UUID::UUID_TYPE_SHORT) ? 2 : UUID::LENGTH_OF_LONG_UUID
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::find_included_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t service_range
|
||||
)
|
||||
{
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
service_range,
|
||||
INCLUDE_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::discover_characteristics_of_a_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
)
|
||||
{
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
discovery_range,
|
||||
CHARACTERISTIC_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::discover_characteristics_descriptors(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t descriptors_discovery_range
|
||||
)
|
||||
{
|
||||
return _client.find_information_request(
|
||||
connection_handle,
|
||||
descriptors_discovery_range
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::read_attribute_value(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
)
|
||||
{
|
||||
return _client.read_request(
|
||||
connection_handle,
|
||||
attribute_handle
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::read_using_characteristic_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& uuid
|
||||
)
|
||||
{
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
read_range,
|
||||
uuid
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::read_attribute_blob(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
)
|
||||
{
|
||||
return _client.read_blob_request(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
offset
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::read_multiple_characteristic_values(
|
||||
connection_handle_t connection_handle,
|
||||
const Span<const attribute_handle_t>& characteristic_value_handles
|
||||
)
|
||||
{
|
||||
return _client.read_multiple_request(
|
||||
connection_handle,
|
||||
characteristic_value_handles
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const Span<const uint8_t>& value
|
||||
)
|
||||
{
|
||||
return _client.write_command(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::signed_write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const Span<const uint8_t>& value
|
||||
)
|
||||
{
|
||||
return _client.signed_write_command(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::write_attribute(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const Span<const uint8_t>& value
|
||||
)
|
||||
{
|
||||
return _client.write_request(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::queue_prepare_write(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const Span<const uint8_t>& value,
|
||||
uint16_t offset
|
||||
)
|
||||
{
|
||||
return _client.prepare_write_request(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
offset,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::execute_write_queue(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
)
|
||||
{
|
||||
return _client.execute_write_request(connection_handle, execute);
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::initialize()
|
||||
{
|
||||
return _client.initialize();
|
||||
}
|
||||
|
||||
|
||||
ble_error_t PalGattClient::terminate()
|
||||
{
|
||||
return _client.initialize();
|
||||
}
|
||||
|
||||
} // ble
|
||||
@@ -0,0 +1,125 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ble/internal/PalGenericAccessService.h"
|
||||
|
||||
namespace ble {
|
||||
|
||||
#if 0 // Disabled until reworked and reintroduced to GattServer API
|
||||
|
||||
virtual ble_error_t PalGenericAccessService::get_device_name_length(uint8_t& length)
|
||||
{
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
const uint8_t* name = nullptr;
|
||||
uint16_t actual_length = 0;
|
||||
|
||||
gatt_server().getDeviceName(name, actual_length);
|
||||
length = actual_length;
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ble_error_t PalGenericAccessService::get_device_name(Span<uint8_t>& array) {
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
const uint8_t* name = nullptr;
|
||||
uint16_t length = 0;
|
||||
|
||||
gatt_server().getDeviceName(name, length);
|
||||
|
||||
if (length > array.size()) {
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
memcpy(array.data(), name, length);
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
virtual ble_error_t PalGenericAccessService::set_device_name(const uint8_t* device_name) {
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
return gatt_server().setDeviceName(device_name);
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
virtual ble_error_t PalGenericAccessService::get_appearance(
|
||||
GapAdvertisingData::Appearance& appearance
|
||||
) {
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
appearance = gatt_server().getAppearance();
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
virtual ble_error_t PalGenericAccessService::set_appearance(
|
||||
GapAdvertisingData::Appearance appearance
|
||||
) {
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
gatt_server().setAppearance(appearance);
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
#endif // Disabled until reworked and reintroduced to GattServer API
|
||||
|
||||
|
||||
ble_error_t PalGenericAccessService::get_peripheral_preferred_connection_parameters(
|
||||
ble::Gap::PreferredConnectionParams_t& parameters
|
||||
)
|
||||
{
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
parameters = gatt_server().getPreferredConnectionParams();
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
ble_error_t PalGenericAccessService::set_peripheral_preferred_connection_parameters(
|
||||
const ble::Gap::PreferredConnectionParams_t& parameters
|
||||
)
|
||||
{
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
gatt_server().setPreferredConnectionParams(parameters);
|
||||
return BLE_ERROR_NONE;
|
||||
#else
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
ble::GattServer& PalGenericAccessService::gatt_server()
|
||||
{
|
||||
return ble::GattServer::getInstance();
|
||||
}
|
||||
|
||||
} // ble
|
||||
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2020 ARM Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ble/internal/PalSigningMonitor.h"
|
||||
#include "ble/internal/BLEInstanceBase.h"
|
||||
#include "ble/GattClient.h"
|
||||
|
||||
namespace ble {
|
||||
|
||||
void PalSigningMonitor::set_signing_event_handler(SecurityManager *handler)
|
||||
{
|
||||
#if BLE_FEATURE_GATT_CLIENT
|
||||
BLEInstanceBase::deviceInstance().getGattClient().set_signing_event_handler(handler);
|
||||
#endif // BLE_FEATURE_GATT_CLIENT
|
||||
#if BLE_FEATURE_GATT_SERVER
|
||||
BLEInstanceBase::deviceInstance().getGattServer().set_signing_event_handler(handler);
|
||||
#endif // BLE_FEATURE_GATT_SERVER
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user