mbed-os/connectivity/FEATURE_BLE/source/generic/GattServerImpl.h

391 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 "ble/common/CallChainOfFunctionPointersWithContext.h"
#include "ble/gatt/GattService.h"
#include "ble/gatt/GattAttribute.h"
#include "GattServerEvents.h"
#include "ble/gatt/GattCallbackParamTypes.h"
#include <stddef.h>
#include <ble/GattServer.h>
#include "ble/common/blecommon.h"
#include "ble/Gap.h"
#include "wsf_types.h"
#include "att_api.h"
#include "SecurityManager.h"
#include "ble/gatt/GattCallbackParamTypes.h"
#include "source/pal/PalSigningMonitor.h"
#include "source/BLEInstanceBase.h"
namespace ble {
// fwd declaration of PalAttClient and BLE
class PalAttClient;
class BLE;
namespace impl {
class GattServer : public PalSigningMonitor {
friend ble::BLE;
friend ble::PalAttClient;
friend PalSigningMonitor;
friend BLEInstanceBase;
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 &params);
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
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;
};
} // namespace impl
} // ble
#endif /* ifndef MBED_CORDIO_GATT_SERVER_H__ */