/*
* Copyright 2022 The Android Open Source Project
*
* 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 "model/controller/ffi.h"
#include <iostream>
#include "model/controller/dual_mode_controller.h"
#include "model/setup/async_manager.h"
#include "rootcanal/configuration.pb.h"
using namespace rootcanal;
using bluetooth::hci::Address;
namespace hci {
enum Idc {
CMD = 1 ,
ACL,
SCO,
EVT,
ISO,
};
} // namespace hci
extern "C" {
__attribute__((visibility("default" ))) void * ffi_controller_new(
uint8_t const address[6 ],
void (*send_hci)(void * cookie, int idc, uint8_t const * data, size_t data_len),
void (*send_ll)(void * cookie, uint8_t const * data, size_t data_len, int phy, int tx_power),
void (*invalid_packet_handler)(void * cookie, int reason, char const * message,
uint8_t const * data, size_t data_len),
unsigned (*ranging_estimator)(void * cookie1, void * cookie2), void * cookie,
const uint8_t* proto_bytes, size_t proto_len) {
rootcanal::ControllerProperties properties;
if (proto_bytes != nullptr && proto_len > 0 ) {
rootcanal::configuration::Controller config;
if (config.ParseFromArray(proto_bytes, proto_len)) {
properties = rootcanal::ControllerProperties(config);
}
}
DualModeController* controller = new DualModeController(properties);
controller->SetAddress(
Address({address[0 ], address[1 ], address[2 ], address[3 ], address[4 ], address[5 ]}));
controller->RegisterEventChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(cookie, hci::Idc::EVT, data->data(), data->size());
});
controller->RegisterAclChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(cookie, hci::Idc::ACL, data->data(), data->size());
});
controller->RegisterScoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(cookie, hci::Idc::SCO, data->data(), data->size());
});
controller->RegisterIsoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(cookie, hci::Idc::ISO, data->data(), data->size());
});
controller->RegisterLinkLayerChannel(
[=](std::vector<uint8_t> const & data, Phy::Type phy, int8_t tx_power) {
send_ll(cookie, data.data(), data.size(), static_cast <int >(phy), tx_power);
});
if (invalid_packet_handler) {
controller->RegisterInvalidPacketHandler([=](uint32_t /*id*/, InvalidPacketReason reason,
std::string message,
std::vector<uint8_t> const & packet) {
invalid_packet_handler(cookie, static_cast <int >(reason), message.c_str(), packet.data(),
packet.size());
});
}
if (ranging_estimator) {
controller->RegisterRangingEstimator(
[=](void const * cookie1, void const * cookie2) {
return ranging_estimator(const_cast <void *>(cookie1), const_cast <void *>(cookie2));
});
}
return controller;
}
__attribute__((visibility("default" ))) void ffi_controller_delete(void * controller_) {
DualModeController* controller = reinterpret_cast <DualModeController*>(controller_);
delete controller;
}
__attribute__((visibility("default" ))) void ffi_controller_receive_hci(void * controller_, int idc,
uint8_t const * data,
size_t data_len) {
DualModeController* controller = reinterpret_cast <DualModeController*>(controller_);
std::shared_ptr<std::vector<uint8_t>> bytes =
std::make_shared<std::vector<uint8_t>>(data, data + data_len);
switch (idc) {
case hci::Idc::CMD:
controller->HandleCommand(bytes);
break ;
case hci::Idc::ACL:
controller->HandleAcl(bytes);
break ;
case hci::Idc::SCO:
controller->HandleSco(bytes);
break ;
case hci::Idc::ISO:
controller->HandleIso(bytes);
break ;
default :
std::cerr << "Dropping HCI packet with unknown type " << (int )idc << std::endl;
break ;
}
}
__attribute__((visibility("default" ))) void ffi_controller_receive_ll(void * controller_,
uint8_t const * data,
size_t data_len, int phy,
int rssi) {
DualModeController* controller = reinterpret_cast <DualModeController*>(controller_);
std::shared_ptr<std::vector<uint8_t>> bytes =
std::make_shared<std::vector<uint8_t>>(data, data + data_len);
model::packets::LinkLayerPacketView packet =
model::packets::LinkLayerPacketView::Create(pdl::packet::slice(bytes));
if (!packet.IsValid()) {
std::cerr << "Dropping malformed LL packet" << std::endl;
return ;
}
controller->ReceiveLinkLayerPacket(packet, Phy::Type(phy), rssi);
}
__attribute__((visibility("default" ))) void ffi_controller_tick(void * controller_) {
DualModeController* controller = reinterpret_cast <DualModeController*>(controller_);
controller->Tick();
}
__attribute__((visibility("default" ))) void ffi_generate_rpa(uint8_t const irk_[16 ],
uint8_t rpa[6 ]) {
std::array<uint8_t, LeController::kIrkSize> irk;
memcpy(irk.data(), irk_, LeController::kIrkSize);
Address address = LeController::generate_rpa(irk);
memcpy(rpa, address.data(), Address::kLength);
}
}; // extern "C"
Messung V0.5 in Prozent C=88 H=98 G=93
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-27)
¤
*© Formatika GbR, Deutschland