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.
208 lines
7.0 KiB
208 lines
7.0 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.
|
|
*/
|
|
|
|
#include "eatt_impl.h"
|
|
#include "stack/l2cap/l2c_int.h"
|
|
|
|
using bluetooth::eatt::eatt_impl;
|
|
|
|
namespace bluetooth {
|
|
namespace eatt {
|
|
|
|
struct EattExtension::impl {
|
|
impl() = default;
|
|
~impl() = default;
|
|
|
|
void Start() {
|
|
if (eatt_impl_) {
|
|
LOG(ERROR) << "Eatt already started";
|
|
return;
|
|
};
|
|
|
|
/* Register server for Eatt */
|
|
memset(®_info_, 0, sizeof(reg_info_));
|
|
reg_info_.pL2CA_CreditBasedConnectInd_Cb = eatt_connect_ind;
|
|
reg_info_.pL2CA_CreditBasedConnectCfm_Cb = eatt_connect_cfm;
|
|
reg_info_.pL2CA_CreditBasedReconfigCompleted_Cb = eatt_reconfig_completed;
|
|
reg_info_.pL2CA_DisconnectInd_Cb = eatt_disconnect_ind;
|
|
reg_info_.pL2CA_Error_Cb = eatt_error_cb;
|
|
reg_info_.pL2CA_DataInd_Cb = eatt_data_ind;
|
|
|
|
if (L2CA_RegisterLECoc(BT_PSM_EATT, reg_info_, BTM_SEC_NONE, {}) == 0) {
|
|
LOG(ERROR) << __func__ << " cannot register EATT";
|
|
} else {
|
|
eatt_impl_ = std::make_unique<eatt_impl>();
|
|
}
|
|
}
|
|
|
|
void Stop() {
|
|
if (!eatt_impl_) {
|
|
LOG(ERROR) << "Eatt not started";
|
|
return;
|
|
}
|
|
eatt_impl_.reset(nullptr);
|
|
L2CA_DeregisterLECoc(BT_PSM_EATT);
|
|
}
|
|
|
|
bool IsRunning() { return eatt_impl_ ? true : false; }
|
|
|
|
static eatt_impl* GetImplInstance(void) {
|
|
auto* instance = EattExtension::GetInstance();
|
|
return instance->pimpl_->eatt_impl_.get();
|
|
}
|
|
|
|
static void eatt_connect_ind(const RawAddress& bda,
|
|
std::vector<uint16_t>& lcids, uint16_t psm,
|
|
uint16_t peer_mtu, uint8_t identifier) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl)
|
|
p_eatt_impl->eatt_l2cap_connect_ind(bda, lcids, psm, peer_mtu,
|
|
identifier);
|
|
}
|
|
|
|
static void eatt_connect_cfm(const RawAddress& bda, uint16_t lcid,
|
|
uint16_t peer_mtu, uint16_t result) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl)
|
|
p_eatt_impl->eatt_l2cap_connect_cfm(bda, lcid, peer_mtu, result);
|
|
}
|
|
|
|
static void eatt_reconfig_completed(const RawAddress& bda, uint16_t lcid,
|
|
bool is_local_cfg,
|
|
tL2CAP_LE_CFG_INFO* p_cfg) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl)
|
|
p_eatt_impl->eatt_l2cap_reconfig_completed(bda, lcid, is_local_cfg,
|
|
p_cfg);
|
|
}
|
|
|
|
static void eatt_error_cb(uint16_t lcid, uint16_t reason) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl) p_eatt_impl->eatt_l2cap_error_cb(lcid, reason);
|
|
}
|
|
|
|
static void eatt_disconnect_ind(uint16_t lcid, bool please_confirm) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl)
|
|
p_eatt_impl->eatt_l2cap_disconnect_ind(lcid, please_confirm);
|
|
}
|
|
|
|
static void eatt_data_ind(uint16_t lcid, BT_HDR* data_p) {
|
|
auto p_eatt_impl = GetImplInstance();
|
|
if (p_eatt_impl) p_eatt_impl->eatt_l2cap_data_ind(lcid, data_p);
|
|
}
|
|
|
|
std::unique_ptr<eatt_impl> eatt_impl_;
|
|
tL2CAP_APPL_INFO reg_info_;
|
|
};
|
|
|
|
void EattExtension::AddFromStorage(const RawAddress& bd_addr) {
|
|
eatt_impl* p_eatt_impl = EattExtension::impl::GetImplInstance();
|
|
if (p_eatt_impl) p_eatt_impl->add_from_storage(bd_addr);
|
|
}
|
|
|
|
EattExtension::EattExtension() : pimpl_(std::make_unique<impl>()) {}
|
|
|
|
bool EattExtension::IsEattSupportedByPeer(const RawAddress& bd_addr) {
|
|
return pimpl_->eatt_impl_->is_eatt_supported_by_peer(bd_addr);
|
|
}
|
|
|
|
void EattExtension::Connect(const RawAddress& bd_addr) {
|
|
pimpl_->eatt_impl_->connect(bd_addr);
|
|
}
|
|
|
|
void EattExtension::Disconnect(const RawAddress& bd_addr) {
|
|
pimpl_->eatt_impl_->disconnect(bd_addr);
|
|
}
|
|
|
|
void EattExtension::Reconfigure(const RawAddress& bd_addr, uint16_t cid,
|
|
uint16_t mtu) {
|
|
pimpl_->eatt_impl_->reconfigure(bd_addr, cid, mtu);
|
|
}
|
|
void EattExtension::ReconfigureAll(const RawAddress& bd_addr, uint16_t mtu) {
|
|
pimpl_->eatt_impl_->reconfigure_all(bd_addr, mtu);
|
|
}
|
|
|
|
EattChannel* EattExtension::FindEattChannelByCid(const RawAddress& bd_addr,
|
|
uint16_t cid) {
|
|
return pimpl_->eatt_impl_->find_eatt_channel_by_cid(bd_addr, cid);
|
|
}
|
|
|
|
EattChannel* EattExtension::FindEattChannelByTransId(const RawAddress& bd_addr,
|
|
uint32_t trans_id) {
|
|
return pimpl_->eatt_impl_->find_eatt_channel_by_transid(bd_addr, trans_id);
|
|
}
|
|
|
|
bool EattExtension::IsIndicationPending(const RawAddress& bd_addr,
|
|
uint16_t indication_handle) {
|
|
return pimpl_->eatt_impl_->is_indication_pending(bd_addr, indication_handle);
|
|
}
|
|
|
|
EattChannel* EattExtension::GetChannelAvailableForIndication(
|
|
const RawAddress& bd_addr) {
|
|
return pimpl_->eatt_impl_->get_channel_available_for_indication(bd_addr);
|
|
}
|
|
|
|
void EattExtension::FreeGattResources(const RawAddress& bd_addr) {
|
|
pimpl_->eatt_impl_->free_gatt_resources(bd_addr);
|
|
}
|
|
|
|
bool EattExtension::IsOutstandingMsgInSendQueue(const RawAddress& bd_addr) {
|
|
return pimpl_->eatt_impl_->is_outstanding_msg_in_send_queue(bd_addr);
|
|
}
|
|
|
|
EattChannel* EattExtension::GetChannelWithQueuedData(
|
|
const RawAddress& bd_addr) {
|
|
return pimpl_->eatt_impl_->get_channel_with_queued_data(bd_addr);
|
|
}
|
|
|
|
EattChannel* EattExtension::GetChannelAvailableForClientRequest(
|
|
const RawAddress& bd_addr) {
|
|
return pimpl_->eatt_impl_->get_channel_available_for_client_request(bd_addr);
|
|
}
|
|
|
|
/* Start stop GATT indication timer per CID */
|
|
void EattExtension::StartIndicationConfirmationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid) {
|
|
pimpl_->eatt_impl_->start_indication_confirm_timer(bd_addr, cid);
|
|
}
|
|
|
|
void EattExtension::StopIndicationConfirmationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid) {
|
|
pimpl_->eatt_impl_->stop_indication_confirm_timer(bd_addr, cid);
|
|
}
|
|
|
|
/* Start stop application indication timeout */
|
|
void EattExtension::StartAppIndicationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid) {
|
|
pimpl_->eatt_impl_->start_app_indication_timer(bd_addr, cid);
|
|
}
|
|
|
|
void EattExtension::StopAppIndicationTimer(const RawAddress& bd_addr,
|
|
uint16_t cid) {
|
|
pimpl_->eatt_impl_->stop_app_indication_timer(bd_addr, cid);
|
|
}
|
|
|
|
void EattExtension::Start() { pimpl_->Start(); }
|
|
|
|
void EattExtension::Stop() { pimpl_->Stop(); }
|
|
|
|
EattExtension::~EattExtension() = default;
|
|
|
|
} // namespace eatt
|
|
} // namespace bluetooth
|