mbed-os/connectivity/FEATURE_BLE/libraries/ble-api-implementation/include/ble/internal/GattServerImpl.h

382 lines
11 KiB
C++

/* 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 "CallChainOfFunctionPointersWithContext.h"
#include "ble/common/ble/GattService.h"
#include "ble/common/ble/GattAttribute.h"
#include "ble/common/ble/GattServerEvents.h"
#include "ble/common/ble/GattCallbackParamTypes.h"
#include <stddef.h>
#include "ble/common/ble/blecommon.h"
#include "ble/Gap.h"
#include "wsf_types.h"
#include "att_api.h"
#include "SecurityManager.h"
#include "ble/common/ble/GattCallbackParamTypes.h"
#include "ble/internal/PalSigningMonitor.h"
namespace ble {
// fwd declaration of PalAttClient and BLE
class PalAttClient;
class BLE;
class GattServer :
public ble::interface::GattServer,
public PalSigningMonitor
{
friend ble::BLE;
friend ble::PalAttClient;
friend PalSigningMonitor;
friend BLEInstanceBase;
friend PalGenericAccessService;
// inherited typedefs have the wrong types so we have to redefine them
public:
typedef FunctionPointerWithContext<const GattServer *>
GattServerShutdownCallback_t;
typedef CallChainOfFunctionPointersWithContext<const GattServer*>
GattServerShutdownCallbackChain_t;
public:
void setEventHandler(EventHandler *handler);
ble_error_t reset(void);
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
);
Gap::PreferredConnectionParams_t getPreferredConnectionParams();
void setPreferredConnectionParams(const Gap::PreferredConnectionParams_t& params);
bool isOnDataReadAvailable() const;
void onDataSent(const DataSentCallback_t &callback);
template <typename T>
void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count));
DataSentCallbackChain_t &onDataSent();
void onDataWritten(const DataWrittenCallback_t &callback) {
dataWrittenCallChain.add(callback);
}
template <typename T>
void onDataWritten(
T *objPtr,
void (T::*memberPtr)(const GattWriteCallbackParams *context)
) {
dataWrittenCallChain.add(objPtr, memberPtr);
};
DataWrittenCallbackChain_t &onDataWritten();
ble_error_t onDataRead(const DataReadCallback_t &callback);
template <typename T>
ble_error_t onDataRead(
T *objPtr,
void (T::*memberPtr)(const GattReadCallbackParams *context)
);
DataReadCallbackChain_t &onDataRead();
void onShutdown(const GattServerShutdownCallback_t &callback);
template <typename T>
void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *));
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
private:
GattServer();
GattServer(const GattServer &);
const GattServer& operator=(const GattServer &);
/**
* Return the singleton of the Cordio implementation of ble::GattServer.
*/
static GattServer &getInstance();
/**
* Initialize the GattServer and add mandatory services (generic access and
* generic attribute service).
*/
void initialize();
void set_signing_event_handler(
PalSigningMonitorEventHandler *signing_event_handler
);
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 void att_cb(const attEvt_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);
static uint8_t atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle);
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;
};
} // ble
#endif /* ifndef MBED_CORDIO_GATT_SERVER_H__ */