/* 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. */ #ifndef MBED_CORDIO_GATT_SERVER_H__ #define MBED_CORDIO_GATT_SERVER_H__ #include <cstddef> #include "wsf_types.h" #include "att_api.h" #include "ble/GattServer.h" #include "ble/Gap.h" #include "ble/SecurityManager.h" #include "ble/gatt/GattService.h" #include "ble/gatt/GattAttribute.h" #include "ble/gatt/GattCallbackParamTypes.h" #include "ble/gatt/GattCallbackParamTypes.h" #include "ble/common/CallChainOfFunctionPointersWithContext.h" #include "ble/common/blecommon.h" #include "source/BLEInstanceBase.h" #include "source/generic/GattServerEvents.h" #include "source/pal/PalSigningMonitor.h" namespace ble { // fwd declaration of PalAttClient, PalGenericAccessService and BLE class PalAttClient; class PalGenericAccessService; class BLE; namespace impl { class GattServer : public PalSigningMonitor { friend ble::BLE; friend ble::PalAttClient; friend PalSigningMonitor; friend PalGenericAccessService; using EventHandler = ble::GattServer::EventHandler; using DataSentCallback_t = ble::GattServer::DataSentCallback_t ; using DataSentCallbackChain_t = ble::GattServer::DataSentCallbackChain_t ; using DataWrittenCallback_t = ble::GattServer::DataWrittenCallback_t ; using DataWrittenCallbackChain_t = ble::GattServer::DataWrittenCallbackChain_t ; using DataReadCallback_t = ble::GattServer::DataReadCallback_t; using DataReadCallbackChain_t = ble::GattServer::DataReadCallbackChain_t; using GattServerShutdownCallback_t = ble::GattServer::GattServerShutdownCallback_t; using GattServerShutdownCallbackChain_t = ble::GattServer::GattServerShutdownCallbackChain_t; using EventCallback_t = ble::GattServer::EventCallback_t; // inherited typedefs have the wrong types so we have to redefine them public: void setEventHandler(EventHandler *handler); ble_error_t reset(ble::GattServer* server); ble_error_t addService(GattService &service); ble_error_t read( GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP ); ble_error_t read( ble::connection_handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP ); ble_error_t write( GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false ); ble_error_t write( ble::connection_handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false ); ble_error_t areUpdatesEnabled( const GattCharacteristic &characteristic, bool *enabledP ); ble_error_t areUpdatesEnabled( ble::connection_handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP ); ble::Gap::PreferredConnectionParams_t getPreferredConnectionParams(); void setPreferredConnectionParams(const ble::Gap::PreferredConnectionParams_t ¶ms); bool isOnDataReadAvailable() const; void onDataSent(const DataSentCallback_t &callback); DataSentCallbackChain_t &onDataSent(); void onDataWritten(const DataWrittenCallback_t &callback) { dataWrittenCallChain.add(callback); } DataWrittenCallbackChain_t &onDataWritten(); ble_error_t onDataRead(const DataReadCallback_t &callback); DataReadCallbackChain_t &onDataRead(); void onShutdown(const GattServerShutdownCallback_t &callback); GattServerShutdownCallbackChain_t &onShutdown(); void onUpdatesEnabled(EventCallback_t callback); void onUpdatesDisabled(EventCallback_t callback); void onConfirmationReceived(EventCallback_t callback); /* Entry points for the underlying stack to report events back to the user. */ protected: void handleDataWrittenEvent(const GattWriteCallbackParams *params); void handleDataReadEvent(const GattReadCallbackParams *params); void handleEvent( GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle ); void handleDataSentEvent(unsigned count); /* ===================================================================== */ /* private implementation follows */ #if 0 // Disabled until reworked and reintroduced to GattServer API public: /** * @see ble::GattServer::setDeviceName */ ble_error_t setDeviceName(const uint8_t *deviceName); /** * @see ble::GattServer::getDeviceName */ void getDeviceName(const uint8_t*& name, uint16_t& length); /** * @see ble::GattServer::setAppearance */ void setAppearance(GapAdvertisingData::Appearance appearance); /** * @see ble::GattServer::getAppearance */ GapAdvertisingData::Appearance getAppearance(); #endif // Disabled until reworked and reintroduced to GattServer API public: /** * Return the singleton of ble::GattServer. */ static GattServer &getInstance(); static void att_cb(const attEvt_t *pEvt); /** * Initialize the GattServer and add mandatory services (generic access and * generic attribute service). */ void initialize(); static uint8_t atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle); void set_signing_event_handler( PalSigningMonitorEventHandler *signing_event_handler ) override; private: GattServer(); GattServer(const GattServer &); const GattServer &operator=(const GattServer &); EventHandler *getEventHandler(); void add_default_services(); static uint16_t compute_attributes_count(GattService &service); void insert_service_attribute( GattService &service, attsAttr_t *&attribute_it ); ble_error_t insert_characteristic( GattCharacteristic *characteristic, attsAttr_t *&attribute_it ); bool is_characteristic_valid(GattCharacteristic *characteristic); void insert_characteristic_declaration_attribute( GattCharacteristic *characteristic, attsAttr_t *&attribute_it ); ble_error_t insert_characteristic_value_attribute( GattCharacteristic *characteristic, attsAttr_t *&attribute_it ); ble_error_t insert_descriptor( GattCharacteristic *characteristic, GattAttribute *descriptor, attsAttr_t *&attribute_it, bool &cccd_created ); ble_error_t insert_cccd( GattCharacteristic *characteristic, attsAttr_t *&attribute_it ); static void cccd_cb(attsCccEvt_t *pEvt); static uint8_t atts_read_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, attsAttr_t *pAttr); static uint8_t atts_write_cb( dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr ); void add_generic_access_service(); void add_generic_attribute_service(); void *alloc_block(size_t block_size); GattCharacteristic *get_auth_char(uint16_t value_handle); bool get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t &idx) const; bool get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t &idx) const; bool is_update_authorized(connection_handle_t connection, GattAttribute::Handle_t value_handle); struct alloc_block_t { alloc_block_t *next; uint8_t data[1]; }; struct internal_service_t { attsGroup_t attGroup; internal_service_t *next; }; private: /** * Event handler provided by the application. */ EventHandler *eventHandler; /** * The total number of services added to the ATT table. */ uint8_t serviceCount; /** * The total number of characteristics added to the ATT table. */ uint8_t characteristicCount; /** * Callchain containing all registered callback handlers for data sent * events. */ DataSentCallbackChain_t dataSentCallChain; /** * Callchain containing all registered callback handlers for data written * events. */ DataWrittenCallbackChain_t dataWrittenCallChain; /** * Callchain containing all registered callback handlers for data read * events. */ DataReadCallbackChain_t dataReadCallChain; /** * Callchain containing all registered callback handlers for shutdown * events. */ GattServerShutdownCallbackChain_t shutdownCallChain; /** * The registered callback handler for updates enabled events. */ EventCallback_t updatesEnabledCallback; /** * The registered callback handler for updates disabled events. */ EventCallback_t updatesDisabledCallback; /** * The registered callback handler for confirmation received events. */ EventCallback_t confirmationReceivedCallback; PalSigningMonitorEventHandler *_signing_event_handler; attsCccSet_t cccds[MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT]; uint16_t cccd_values[MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT]; uint16_t cccd_handles[MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT]; uint8_t cccd_cnt; GattCharacteristic *_auth_char[MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CHARACTERISTIC_AUTHORISATION_COUNT]; uint8_t _auth_char_count; struct { attsGroup_t service; attsAttr_t attributes[7]; uint8_t device_name_declaration_value[5]; uint16_t device_name_length; uint8_t appearance_declaration_value[5]; uint16_t appearance; uint8_t ppcp_declaration_value[5]; uint8_t ppcp[8]; uint8_t *&device_name_value() { return attributes[2].pValue; } } generic_access_service; struct { attsGroup_t service; attsAttr_t attributes[4]; uint8_t service_changed_declaration[5]; } generic_attribute_service; internal_service_t *registered_service; alloc_block_t *allocated_blocks; uint16_t currentHandle; bool default_services_added; }; } // namespace impl } // ble #endif /* ifndef MBED_CORDIO_GATT_SERVER_H__ */