You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
7.5 KiB
290 lines
7.5 KiB
/*
|
|
* Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
|
|
* www.ehima.com
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <queue>
|
|
|
|
#include "stack/gatt/gatt_int.h"
|
|
|
|
#define EATT_MIN_MTU_MPS (64)
|
|
#define EATT_DEFAULT_MTU (256)
|
|
#define EATT_MAX_TX_MTU (1024)
|
|
|
|
namespace bluetooth {
|
|
namespace eatt {
|
|
|
|
/* Enums */
|
|
enum class EattChannelState : uint8_t {
|
|
EATT_CHANNEL_PENDING = 0x00,
|
|
EATT_CHANNEL_OPENED,
|
|
EATT_CHANNEL_RECONFIGURING,
|
|
};
|
|
|
|
class EattChannel {
|
|
public:
|
|
/* Pointer to EattDevice */
|
|
RawAddress bda_;
|
|
uint16_t cid_;
|
|
uint16_t tx_mtu_;
|
|
uint16_t rx_mtu_;
|
|
EattChannelState state_;
|
|
|
|
/* Used to keep server commands */
|
|
tGATT_SR_CMD server_outstanding_cmd_;
|
|
/* Used to veryfy indication confirmation*/
|
|
uint16_t indicate_handle_;
|
|
/* local app confirm to indication timer */
|
|
alarm_t* ind_ack_timer_;
|
|
/* indication confirmation timer */
|
|
alarm_t* ind_confirmation_timer_;
|
|
/* GATT client command queue */
|
|
std::queue<tGATT_CMD_Q> cl_cmd_q_;
|
|
|
|
EattChannel(RawAddress& bda, uint16_t cid, uint16_t tx_mtu, uint16_t rx_mtu)
|
|
: bda_(bda),
|
|
cid_(cid),
|
|
rx_mtu_(rx_mtu),
|
|
state_(EattChannelState::EATT_CHANNEL_PENDING),
|
|
indicate_handle_(0),
|
|
ind_ack_timer_(NULL),
|
|
ind_confirmation_timer_(NULL) {
|
|
EattChannelSetTxMTU(tx_mtu);
|
|
}
|
|
|
|
~EattChannel() {
|
|
if (ind_ack_timer_ != NULL) {
|
|
alarm_free(ind_ack_timer_);
|
|
}
|
|
|
|
if (ind_confirmation_timer_ != NULL) {
|
|
alarm_free(ind_confirmation_timer_);
|
|
}
|
|
}
|
|
|
|
void EattChannelSetState(EattChannelState state) {
|
|
if (state_ == EattChannelState::EATT_CHANNEL_PENDING) {
|
|
if (state == EattChannelState::EATT_CHANNEL_OPENED) {
|
|
cl_cmd_q_ = std::queue<tGATT_CMD_Q>();
|
|
memset(&server_outstanding_cmd_, 0, sizeof(tGATT_SR_CMD));
|
|
char name[64];
|
|
sprintf(name, "eatt_ind_ack_timer_%s_cid_0x%04x",
|
|
bda_.ToString().c_str(), cid_);
|
|
ind_ack_timer_ = alarm_new(name);
|
|
|
|
sprintf(name, "eatt_ind_conf_timer_%s_cid_0x%04x",
|
|
bda_.ToString().c_str(), cid_);
|
|
ind_confirmation_timer_ = alarm_new(name);
|
|
}
|
|
}
|
|
state_ = state;
|
|
}
|
|
|
|
void EattChannelSetTxMTU(uint16_t tx_mtu) {
|
|
this->tx_mtu_ = std::min<uint16_t>(tx_mtu, EATT_MAX_TX_MTU);
|
|
}
|
|
};
|
|
|
|
/* Interface class */
|
|
class EattExtension {
|
|
public:
|
|
EattExtension();
|
|
virtual ~EattExtension();
|
|
|
|
static EattExtension* GetInstance() {
|
|
static EattExtension* instance = new EattExtension();
|
|
return instance;
|
|
}
|
|
|
|
static void AddFromStorage(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Checks if EATT is supported on peer device.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*/
|
|
virtual bool IsEattSupportedByPeer(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Connect at maximum 5 EATT channels to peer device.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*/
|
|
virtual void Connect(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Disconnect all EATT channels to peer device.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*/
|
|
virtual void Disconnect(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Reconfigure EATT channel for give CID
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
* @param mtu new maximum transmit unit available of local device
|
|
*/
|
|
virtual void Reconfigure(const RawAddress& bd_addr, uint16_t cid,
|
|
uint16_t mtu);
|
|
|
|
/**
|
|
* Reconfigure all EATT channels to peer device.
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param mtu new maximum transmit unit available of local device
|
|
*/
|
|
virtual void ReconfigureAll(const RawAddress& bd_addr, uint16_t mtu);
|
|
|
|
/* Below methods required by GATT implementation */
|
|
|
|
/**
|
|
* Find EATT channel by cid.
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
*
|
|
* @return Eatt Channel instance.
|
|
*/
|
|
virtual EattChannel* FindEattChannelByCid(const RawAddress& bd_addr,
|
|
uint16_t cid);
|
|
|
|
/**
|
|
* Find EATT channel by transaction id.
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param trans_id transaction id
|
|
*
|
|
* @return pointer to EATT channel.
|
|
*/
|
|
virtual EattChannel* FindEattChannelByTransId(const RawAddress& bd_addr,
|
|
uint32_t trans_id);
|
|
|
|
/**
|
|
* Check if EATT channel on given handle is waiting for a indication
|
|
* confirmation
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param indication_handle handle of the pending indication
|
|
*
|
|
* @return true if confirmation is pending false otherwise
|
|
*/
|
|
virtual bool IsIndicationPending(const RawAddress& bd_addr,
|
|
uint16_t indication_handle);
|
|
|
|
/**
|
|
* Get EATT channel available for indication.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*
|
|
* @return pointer to EATT channel.
|
|
*/
|
|
virtual EattChannel* GetChannelAvailableForIndication(
|
|
const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Free Resources.
|
|
*
|
|
* (Maybe not needed)
|
|
* @param bd_addr peer device address
|
|
*
|
|
*/
|
|
virtual void FreeGattResources(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Check if there is any EATT channels having some msg in its send queue
|
|
*
|
|
* @param bd_addr peer device address
|
|
*
|
|
* @return true when there is at least one EATT channel ready to send
|
|
*/
|
|
virtual bool IsOutstandingMsgInSendQueue(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Get EATT channel ready to send.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*
|
|
* @return pointer to EATT channel.
|
|
*/
|
|
virtual EattChannel* GetChannelWithQueuedData(const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Get EATT channel available to send GATT request.
|
|
*
|
|
* @param bd_addr peer device address
|
|
*
|
|
* @return pointer to EATT channel.
|
|
*/
|
|
virtual EattChannel* GetChannelAvailableForClientRequest(
|
|
const RawAddress& bd_addr);
|
|
|
|
/**
|
|
* Start GATT indication timer per CID.
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
*/
|
|
virtual void StartIndicationConfirmationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid);
|
|
|
|
/**
|
|
* Stop GATT indication timer per CID.
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
*/
|
|
virtual void StopIndicationConfirmationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid);
|
|
|
|
/**
|
|
* Start application time for incoming indication on given CID
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
*/
|
|
virtual void StartAppIndicationTimer(const RawAddress& bd_addr, uint16_t cid);
|
|
|
|
/**
|
|
* Stop application time for incoming indication on given CID
|
|
*
|
|
* @param bd_addr peer device address
|
|
* @param cid channel id
|
|
*/
|
|
virtual void StopAppIndicationTimer(const RawAddress& bd_addr, uint16_t cid);
|
|
|
|
/**
|
|
* Starts the EattExtension module
|
|
*/
|
|
void Start();
|
|
|
|
/**
|
|
* Stops the EattExtension module
|
|
*/
|
|
void Stop();
|
|
|
|
private:
|
|
struct impl;
|
|
std::unique_ptr<impl> pimpl_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(EattExtension);
|
|
};
|
|
|
|
} // namespace eatt
|
|
} // namespace bluetooth
|