/* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * * 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/Gap.h" namespace { ble_error_t convert_address_type( ble::peer_address_type_t input_type, const BLEProtocol::AddressBytes_t address, BLEProtocol::AddressType_t& output_type ) { typedef ble::random_address_type_t RandomAddressType_t; typedef ble::peer_address_type_t PeerAddressType_t; typedef BLEProtocol::AddressType LegacyAddressType_t; // best effort; peerAddrTypeIn should not be used when privacy is on. switch(input_type.value()) { case PeerAddressType_t::PUBLIC: case PeerAddressType_t::PUBLIC_IDENTITY: output_type = LegacyAddressType_t::PUBLIC; break; case PeerAddressType_t::RANDOM: { RandomAddressType_t random_address_type(RandomAddressType_t::STATIC); ble_error_t err = Gap::getRandomAddressType(address, &random_address_type); if (err) { return err; } switch (random_address_type.value()) { case RandomAddressType_t::STATIC: output_type = LegacyAddressType_t::RANDOM_STATIC; break; case RandomAddressType_t::NON_RESOLVABLE_PRIVATE: output_type = LegacyAddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE; break; case RandomAddressType_t::RESOLVABLE_PRIVATE: output_type = LegacyAddressType_t::RANDOM_PRIVATE_RESOLVABLE; break; } break; } case PeerAddressType_t::RANDOM_STATIC_IDENTITY: output_type = LegacyAddressType_t::RANDOM_STATIC; break; } return BLE_ERROR_NONE; } ble::peer_address_type_t convert_legacy_address_type( BLEProtocol::AddressType_t legacy_address ) { if (legacy_address == BLEProtocol::AddressType::PUBLIC) { return ble::peer_address_type_t::PUBLIC; } else { return ble::peer_address_type_t::RANDOM; } } } // end of anonymous namespace namespace ble { namespace interface { #if BLE_FEATURE_WHITELIST template uint8_t LegacyGap::getMaxWhitelistSize(void) const { return impl()->getMaxWhitelistSize_(); } template ble_error_t LegacyGap::getWhitelist(Whitelist_t &whitelist) const { return impl()->getWhitelist_(whitelist); } template ble_error_t LegacyGap::setWhitelist(const Whitelist_t &whitelist) { return impl()->setWhitelist_(whitelist); } #endif // BLE_FEATURE_WHITELIST template void LegacyGap::processConnectionEvent( Handle_t handle, Role_t role, PeerAddressType_t peerAddrType, const BLEProtocol::AddressBytes_t peerAddr, BLEProtocol::AddressType_t ownAddrType, const BLEProtocol::AddressBytes_t ownAddr, const ConnectionParams_t *connectionParams, const uint8_t *peerResolvableAddr, const uint8_t *localResolvableAddr ) { /* Update Gap state */ state.advertising = 0; state.connected = 1; ++connectionCount; ConnectionCallbackParams_t callbackParams( handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams, peerResolvableAddr, localResolvableAddr ); connectionCallChain.call(&callbackParams); } template ble_error_t LegacyGap::setAddress( BLEProtocol::AddressType_t type, const BLEProtocol::AddressBytes_t address ) { return impl()->setAddress_(type, address); } template ble_error_t LegacyGap::getAddress( BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address ) { return impl()->getAddress_(typeP, address); } #if BLE_ROLE_BROADCASTER template ble_error_t LegacyGap::stopAdvertising(void) { return impl()->stopAdvertising_(); } #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_CENTRAL template ble_error_t LegacyGap::connect( const BLEProtocol::AddressBytes_t peerAddr, PeerAddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams ) { return impl()->connect_( peerAddr, peerAddrType, connectionParams, scanParams ); } template ble_error_t LegacyGap::connect( const BLEProtocol::AddressBytes_t peerAddr, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams ) { return impl()->connect_( peerAddr, peerAddrType, connectionParams, scanParams ); } #endif // BLE_ROLE_CENTRAL #if BLE_FEATURE_CONNECTABLE template ble_error_t LegacyGap::disconnect( Handle_t connectionHandle, DisconnectionReason_t reason ) { return impl()->disconnect_(connectionHandle, reason); } template ble_error_t LegacyGap::disconnect(DisconnectionReason_t reason) { return impl()->disconnect_(reason); } template ble_error_t LegacyGap::updateConnectionParams( Handle_t handle, const ConnectionParams_t *params ) { return impl()->updateConnectionParams_(handle, params); } #endif // BLE_FEATURE_CONNECTABLE template ble_error_t LegacyGap::setTxPower(int8_t txPower) { return impl()->setTxPower_(txPower); } template void LegacyGap::getPermittedTxPowerValues( const int8_t **valueArrayPP, size_t *countP ) { return impl()->getPermittedTxPowerValues_(valueArrayPP, countP); } #if BLE_FEATURE_WHITELIST #if BLE_ROLE_BROADCASTER template ble_error_t LegacyGap::setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode) { return impl()->setAdvertisingPolicyMode_(mode); } template typename LegacyGap::AdvertisingPolicyMode_t LegacyGap::getAdvertisingPolicyMode(void) const { return impl()->getAdvertisingPolicyMode_(); } #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_OBSERVER template ble_error_t LegacyGap::setScanningPolicyMode(ScanningPolicyMode_t mode) { return impl()->setScanningPolicyMode_(mode); } template typename LegacyGap::ScanningPolicyMode_t LegacyGap::getScanningPolicyMode(void) const { return impl()->getScanningPolicyMode_(); } #endif // BLE_ROLE_OBSERVER #if BLE_ROLE_CENTRAL template ble_error_t LegacyGap::setInitiatorPolicyMode(InitiatorPolicyMode_t mode) { return impl()->setInitiatorPolicyMode_(mode); } template typename LegacyGap::InitiatorPolicyMode_t LegacyGap::getInitiatorPolicyMode(void) const { return impl()->getInitiatorPolicyMode_(); } #endif // BLE_ROLE_CENTRAL #endif // BLE_FEATURE_WHITELIST #if BLE_ROLE_OBSERVER template ble_error_t LegacyGap::startRadioScan(const GapScanningParams &scanningParams) { return impl()->startRadioScan_(scanningParams); } #endif // BLE_ROLE_OBSERVER template ble_error_t LegacyGap::initRadioNotification(void) { return impl()->initRadioNotification_(); } /* -------- deprecated template implementation -------- */ #if defined(__GNUC__) && !defined(__CC_ARM) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #elif defined(__CC_ARM) #pragma push #pragma diag_suppress 1361 #endif template typename LegacyGap::GapState_t LegacyGap::getState(void) const { return state; } #if BLE_ROLE_BROADCASTER template void LegacyGap::setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { _advParams.setAdvertisingType(advType); } template void LegacyGap::setAdvertisingInterval(uint16_t interval) { if (interval == 0) { stopAdvertising(); } else if (interval < getMinAdvertisingInterval()) { interval = getMinAdvertisingInterval(); } _advParams.setInterval(interval); } template void LegacyGap::setAdvertisingTimeout(uint16_t timeout) { _advParams.setTimeout(timeout); } template ble_error_t LegacyGap::startAdvertising(void) { ble_error_t rc; if ((rc = startAdvertising(_advParams)) == BLE_ERROR_NONE) { state.advertising = 1; } return rc; } template void LegacyGap::clearAdvertisingPayload(void) { _advPayload.clear(); setAdvertisingData(_advPayload, _scanResponse); } template ble_error_t LegacyGap::accumulateAdvertisingPayload(uint8_t flags) { GapAdvertisingData advPayloadCopy = _advPayload; ble_error_t rc; if ((rc = advPayloadCopy.addFlags(flags)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(advPayloadCopy, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = advPayloadCopy; } return rc; } template ble_error_t LegacyGap::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { GapAdvertisingData advPayloadCopy = _advPayload; ble_error_t rc; if ((rc = advPayloadCopy.addAppearance(app)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(advPayloadCopy, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = advPayloadCopy; } return rc; } template ble_error_t LegacyGap::accumulateAdvertisingPayloadTxPower(int8_t power) { GapAdvertisingData advPayloadCopy = _advPayload; ble_error_t rc; if ((rc = advPayloadCopy.addTxPower(power)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(advPayloadCopy, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = advPayloadCopy; } return rc; } template ble_error_t LegacyGap::accumulateAdvertisingPayload( GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len ) { GapAdvertisingData advPayloadCopy = _advPayload; ble_error_t rc; if ((rc = advPayloadCopy.addData(type, data, len)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(advPayloadCopy, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = advPayloadCopy; } return rc; } template ble_error_t LegacyGap::updateAdvertisingPayload( GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len ) { GapAdvertisingData advPayloadCopy = _advPayload; ble_error_t rc; if ((rc = advPayloadCopy.updateData(type, data, len)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(advPayloadCopy, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = advPayloadCopy; } return rc; } template ble_error_t LegacyGap::setAdvertisingPayload(const GapAdvertisingData &payload) { ble_error_t rc = setAdvertisingData(payload, _scanResponse); if (rc == BLE_ERROR_NONE) { _advPayload = payload; } return rc; } template const GapAdvertisingData &LegacyGap::getAdvertisingPayload(void) const { return _advPayload; } template ble_error_t LegacyGap::accumulateScanResponse( GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len ) { GapAdvertisingData scanResponseCopy = _scanResponse; ble_error_t rc; if ((rc = scanResponseCopy.addData(type, data, len)) != BLE_ERROR_NONE) { return rc; } rc = setAdvertisingData(_advPayload, scanResponseCopy); if (rc == BLE_ERROR_NONE) { _scanResponse = scanResponseCopy; } return rc; } template void LegacyGap::clearScanResponse(void) { _scanResponse.clear(); setAdvertisingData(_advPayload, _scanResponse); } #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_OBSERVER template ble_error_t LegacyGap::setScanParams( uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning ) { ble_error_t rc; if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { _scanningParams.setActiveScanning(activeScanning); return BLE_ERROR_NONE; } return rc; } template ble_error_t LegacyGap::setScanParams(const GapScanningParams& scanningParams) { return setScanParams( scanningParams.getInterval(), scanningParams.getWindow(), scanningParams.getTimeout(), scanningParams.getActiveScanning() ); } template ble_error_t LegacyGap::setScanInterval(uint16_t interval) { return _scanningParams.setInterval(interval); } template ble_error_t LegacyGap::setScanWindow(uint16_t window) { ble_error_t rc; if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) { return rc; } /* If scanning is already active, propagate the new setting to the stack. */ if (scanningActive) { return startRadioScan(_scanningParams); } return BLE_ERROR_NONE; } template ble_error_t LegacyGap::setScanTimeout(uint16_t timeout) { ble_error_t rc; if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) { return rc; } /* If scanning is already active, propagate the new settings to the stack. */ if (scanningActive) { return startRadioScan(_scanningParams); } return BLE_ERROR_NONE; } template ble_error_t LegacyGap::setActiveScanning(bool activeScanning) { _scanningParams.setActiveScanning(activeScanning); /* If scanning is already active, propagate the new settings to the stack. */ if (scanningActive) { return startRadioScan(_scanningParams); } return BLE_ERROR_NONE; } template ble_error_t LegacyGap::startScan( void (*callback)(const AdvertisementCallbackParams_t *params) ) { ble_error_t err = BLE_ERROR_NONE; if (callback) { if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { scanningActive = true; onAdvertisementReport.attach(callback); } } return err; } #endif // BLE_ROLE_OBSERVER #if BLE_ROLE_BROADCASTER template GapAdvertisingParams &LegacyGap::getAdvertisingParams(void) { return _advParams; } template const GapAdvertisingParams &LegacyGap::getAdvertisingParams(void) const { return _advParams; } template void LegacyGap::setAdvertisingParams(const GapAdvertisingParams &newParams) { _advParams = newParams; } #endif // BLE_ROLE_BROADCASTER template void LegacyGap::onTimeout(TimeoutEventCallback_t callback) { timeoutCallbackChain.add(callback); } template typename LegacyGap::TimeoutEventCallbackChain_t& LegacyGap::onTimeout() { return timeoutCallbackChain; } #if BLE_FEATURE_CONNECTABLE template void LegacyGap::onConnection(ConnectionEventCallback_t callback) { connectionCallChain.add(callback); } template typename LegacyGap::ConnectionEventCallbackChain_t& LegacyGap::onConnection() { return connectionCallChain; } template void LegacyGap::onDisconnection(DisconnectionEventCallback_t callback) { disconnectionCallChain.add(callback); } template typename LegacyGap::DisconnectionEventCallbackChain_t& LegacyGap::onDisconnection() { return disconnectionCallChain; } #endif // BLE_FEATURE_CONNECTABLE template void LegacyGap::onRadioNotification(void (*callback)(bool param)) { radioNotificationCallback.attach(callback); } template void LegacyGap::onShutdown(const GapShutdownCallback_t& callback) { shutdownCallChain.add(callback); } template typename LegacyGap::GapShutdownCallbackChain_t& LegacyGap::onShutdown() { return shutdownCallChain; } template LegacyGap::AdvertisementCallbackParams_t::AdvertisementCallbackParams_t() : peerAddr(), rssi(), isScanResponse(), type(), advertisingDataLen(0), advertisingData(NULL), addressType(), peerAddrType(PeerAddressType_t::PUBLIC) { } template ble_error_t LegacyGap::getRandomAddressType( const BLEProtocol::AddressBytes_t address, RandomAddressType_t* type ) { // see section Device address in Bluetooth Link Layer specification // (Vol 6 - Part B) switch (address[5] >> 6) { case 0x03: *type = RandomAddressType_t::STATIC; return BLE_ERROR_NONE; case 0x00: *type = RandomAddressType_t::NON_RESOLVABLE_PRIVATE; return BLE_ERROR_NONE; case 0x01: *type = RandomAddressType_t::RESOLVABLE_PRIVATE; return BLE_ERROR_NONE; default: return BLE_ERROR_INVALID_PARAM; } } template LegacyGap::ConnectionCallbackParams_t::ConnectionCallbackParams_t( Handle_t handleIn, Role_t roleIn, BLEProtocol::AddressType_t peerAddrTypeIn, const uint8_t *peerAddrIn, BLEProtocol::AddressType_t ownAddrTypeIn, const uint8_t *ownAddrIn, const ConnectionParams_t *connectionParamsIn, const uint8_t *peerResolvableAddrIn, const uint8_t *localResolvableAddrIn ) : handle(handleIn), role(roleIn), peerAddrType(peerAddrTypeIn), peerAddr(), ownAddrType(ownAddrTypeIn), ownAddr(), connectionParams(connectionParamsIn), peerResolvableAddr(), localResolvableAddr(), peerAddressType(convert_legacy_address_type(peerAddrTypeIn)) { constructor_helper( peerAddrIn, ownAddrIn, peerResolvableAddrIn, localResolvableAddrIn ); } template LegacyGap::ConnectionCallbackParams_t::ConnectionCallbackParams_t( Handle_t handleIn, Role_t roleIn, PeerAddressType_t peerAddrTypeIn, const uint8_t *peerAddrIn, BLEProtocol::AddressType_t ownAddrTypeIn, const uint8_t *ownAddrIn, const ConnectionParams_t *connectionParamsIn, const uint8_t *peerResolvableAddrIn, const uint8_t *localResolvableAddrIn ) : handle(handleIn), role(roleIn), peerAddrType(), peerAddr(), ownAddrType(ownAddrTypeIn), ownAddr(), connectionParams(connectionParamsIn), peerResolvableAddr(), localResolvableAddr(), peerAddressType(peerAddrTypeIn) { constructor_helper( peerAddrIn, ownAddrIn, peerResolvableAddrIn, localResolvableAddrIn ); convert_address_type(peerAddrTypeIn, peerAddrIn, peerAddrType); } template void LegacyGap::ConnectionCallbackParams_t::constructor_helper( const uint8_t *peerAddrIn, const uint8_t *ownAddrIn, const uint8_t *peerResolvableAddrIn, const uint8_t *localResolvableAddrIn ) { memcpy(peerAddr, peerAddrIn, ADDR_LEN); if (ownAddrIn) { memcpy(ownAddr, ownAddrIn, ADDR_LEN); } else { memset(ownAddr, 0, ADDR_LEN); } if (peerResolvableAddrIn) { memcpy(peerResolvableAddr, peerResolvableAddrIn, ADDR_LEN); } else { memset(ownAddr, 0, ADDR_LEN); } if (localResolvableAddrIn) { memcpy(localResolvableAddr, localResolvableAddrIn, ADDR_LEN); } else { memset(ownAddr, 0, ADDR_LEN); } } #if BLE_ROLE_CENTRAL template ble_error_t LegacyGap::connect( const BLEProtocol::AddressBytes_t peerAddr, DeprecatedAddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams ) { return connect( peerAddr, (BLEProtocol::AddressType_t) peerAddrType, connectionParams, scanParams ); } #endif // BLE_ROLE_CENTRAL template void LegacyGap::processConnectionEvent( Handle_t handle, Role_t role, BLEProtocol::AddressType_t peerAddrType, const BLEProtocol::AddressBytes_t peerAddr, BLEProtocol::AddressType_t ownAddrType, const BLEProtocol::AddressBytes_t ownAddr, const ConnectionParams_t *connectionParams, const uint8_t *peerResolvableAddr, const uint8_t *localResolvableAddr ) { /* Update Gap state */ state.advertising = 0; state.connected = 1; ++connectionCount; ConnectionCallbackParams_t callbackParams( handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams, peerResolvableAddr, localResolvableAddr ); connectionCallChain.call(&callbackParams); } template void LegacyGap::processAdvertisementReport( const BLEProtocol::AddressBytes_t peerAddr, int8_t rssi, bool isScanResponse, GapAdvertisingParams::AdvertisingType_t type, uint8_t advertisingDataLen, const uint8_t *advertisingData, BLEProtocol::AddressType_t addressType ) { AdvertisementCallbackParams_t params; memcpy(params.peerAddr, peerAddr, ADDR_LEN); params.rssi = rssi; params.isScanResponse = isScanResponse; params.type = type; params.advertisingDataLen = advertisingDataLen; params.advertisingData = advertisingData; params.addressType = addressType; params.peerAddrType = convert_legacy_address_type(addressType); onAdvertisementReport.call(¶ms); } template void LegacyGap::processAdvertisementReport( const BLEProtocol::AddressBytes_t peerAddr, int8_t rssi, bool isScanResponse, GapAdvertisingParams::AdvertisingType_t type, uint8_t advertisingDataLen, const uint8_t *advertisingData, PeerAddressType_t addressType ) { AdvertisementCallbackParams_t params; memcpy(params.peerAddr, peerAddr, ADDR_LEN); params.rssi = rssi; params.isScanResponse = isScanResponse; params.type = type; params.advertisingDataLen = advertisingDataLen; params.advertisingData = advertisingData; params.peerAddrType = addressType; convert_address_type( addressType, peerAddr, params.addressType ); onAdvertisementReport.call(¶ms); } #if defined(__GNUC__) && !defined(__CC_ARM) #pragma GCC diagnostic pop #elif defined(__CC_ARM) #pragma pop #endif #if BLE_ROLE_BROADCASTER template uint16_t LegacyGap::getMinAdvertisingInterval(void) const { return impl()->getMinAdvertisingInterval_(); } template uint16_t LegacyGap::getMinNonConnectableAdvertisingInterval(void) const { return impl()->getMinNonConnectableAdvertisingInterval_(); } template uint16_t LegacyGap::getMaxAdvertisingInterval(void) const { return impl()->getMaxAdvertisingInterval_(); } #endif // BLE_ROLE_BROADCASTER #if BLE_FEATURE_CONNECTABLE template ble_error_t LegacyGap::getPreferredConnectionParams(ConnectionParams_t *params) { return impl()->getPreferredConnectionParams_(params); } template ble_error_t LegacyGap::setPreferredConnectionParams( const ConnectionParams_t *params ) { return impl()->setPreferredConnectionParams_(params); } #endif // BLE_FEATURE_CONNECTABLE #if BLE_FEATURE_GATT_SERVER template ble_error_t LegacyGap::setDeviceName(const uint8_t *deviceName) { return impl()->setDeviceName_(deviceName); } template ble_error_t LegacyGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) { return impl()->getDeviceName_(deviceName, lengthP); } template ble_error_t LegacyGap::setAppearance(GapAdvertisingData::Appearance appearance) { return impl()->setAppearance_(appearance); } template ble_error_t LegacyGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) { return impl()->getAppearance_(appearanceP); } #endif // BLE_FEATURE_GATT_SERVER #if BLE_ROLE_BROADCASTER template ble_error_t LegacyGap::setAdvertisingData( const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse ) { return impl()->setAdvertisingData_(advData, scanResponse); } template ble_error_t LegacyGap::startAdvertising(const GapAdvertisingParams ¶ms) { return impl()->startAdvertising_(params); } #endif // BLE_ROLE_BROADCASTER template ble_error_t LegacyGap::reset(void) { return impl()->reset_(); } template LegacyGap::LegacyGap() : _advParams(), _advPayload(), _scanningParams(), _scanResponse(), connectionCount(0), state(), scanningActive(false), timeoutCallbackChain(), radioNotificationCallback(), onAdvertisementReport(), connectionCallChain(), disconnectionCallChain() { #if BLE_ROLE_BROADCASTER _advPayload.clear(); _scanResponse.clear(); #endif // BLE_ROLE_BROADCASTER } template void LegacyGap::processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { /* Update Gap state */ --connectionCount; if (!connectionCount) { state.connected = 0; } DisconnectionCallbackParams_t callbackParams(handle, reason); disconnectionCallChain.call(&callbackParams); } template void LegacyGap::processTimeoutEvent(TimeoutSource_t source) { if (source == TIMEOUT_SRC_ADVERTISING) { /* Update gap state if the source is an advertising timeout */ state.advertising = 0; } if (timeoutCallbackChain) { timeoutCallbackChain(source); } } template uint16_t LegacyGap::getMinAdvertisingInterval_(void) const { return 0; } template uint16_t LegacyGap::getMinNonConnectableAdvertisingInterval_(void) const { return 0; } template uint16_t LegacyGap::getMaxAdvertisingInterval_(void) const { return 0xFFFF; } template ble_error_t LegacyGap::reset_(void) { /* Notify that the instance is about to shut down */ shutdownCallChain.call(this); shutdownCallChain.clear(); /* Clear Gap state */ state.advertising = 0; state.connected = 0; #if BLE_FEATURE_CONNECTABLE connectionCount = 0; #endif /* Clear scanning state */ #if BLE_ROLE_OBSERVER scanningActive = false; #endif #if BLE_ROLE_BROADCASTER /* Clear advertising and scanning data */ _advPayload.clear(); _scanResponse.clear(); #endif // BLE_ROLE_BROADCASTER /* Clear callbacks */ timeoutCallbackChain.clear(); #if BLE_FEATURE_CONNECTABLE connectionCallChain.clear(); disconnectionCallChain.clear(); #endif // BLE_FEATURE_CONNECTABLE radioNotificationCallback = NULL; #if BLE_ROLE_OBSERVER onAdvertisementReport = NULL; #endif this->_eventHandler = NULL; return BLE_ERROR_NONE; } // ----------------------------------------------------------------------------- /* ------------------------- Default implementations ------------------------ */ // ----------------------------------------------------------------------------- template uint8_t LegacyGap::getMaxWhitelistSize_(void) const { return 0; } template ble_error_t LegacyGap::getWhitelist_(Whitelist_t &whitelist) const { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setWhitelist_(const Whitelist_t &whitelist) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setAddress_( BLEProtocol::AddressType_t type, const BLEProtocol::AddressBytes_t address ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::getAddress_( BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::stopAdvertising_(void) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::connect_( const BLEProtocol::AddressBytes_t peerAddr, PeerAddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::connect_( const BLEProtocol::AddressBytes_t peerAddr, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::disconnect_( Handle_t connectionHandle, DisconnectionReason_t reason ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::disconnect_(DisconnectionReason_t reason) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::updateConnectionParams_( Handle_t handle, const ConnectionParams_t *params ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setTxPower_(int8_t txPower) { return BLE_ERROR_NOT_IMPLEMENTED; } template void LegacyGap::getPermittedTxPowerValues_( const int8_t **valueArrayPP, size_t *countP ) { *countP = 0; } template ble_error_t LegacyGap::setAdvertisingPolicyMode_(AdvertisingPolicyMode_t mode) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setScanningPolicyMode_(ScanningPolicyMode_t mode) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setInitiatorPolicyMode_(InitiatorPolicyMode_t mode) { return BLE_ERROR_NOT_IMPLEMENTED; } template typename LegacyGap::AdvertisingPolicyMode_t LegacyGap::getAdvertisingPolicyMode_(void) const { return LegacyGap::ADV_POLICY_IGNORE_WHITELIST; } template typename LegacyGap::ScanningPolicyMode_t LegacyGap::getScanningPolicyMode_(void) const { return LegacyGap::SCAN_POLICY_IGNORE_WHITELIST; } template typename LegacyGap::InitiatorPolicyMode_t LegacyGap::getInitiatorPolicyMode_(void) const { return LegacyGap::INIT_POLICY_IGNORE_WHITELIST; } template ble_error_t LegacyGap::startRadioScan_(const GapScanningParams &scanningParams) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::initRadioNotification_(void) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::getPreferredConnectionParams_(ConnectionParams_t *params) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setPreferredConnectionParams_( const ConnectionParams_t *params ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setDeviceName_(const uint8_t *deviceName) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::getDeviceName_(uint8_t *deviceName, unsigned *lengthP) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setAppearance_(GapAdvertisingData::Appearance appearance) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::getAppearance_(GapAdvertisingData::Appearance *appearanceP) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::setAdvertisingData_( const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse ) { return BLE_ERROR_NOT_IMPLEMENTED; } template ble_error_t LegacyGap::startAdvertising_(const GapAdvertisingParams ¶ms) { return BLE_ERROR_NOT_IMPLEMENTED; } } // namespace interface } // namespace ble