1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "model/controller/ffi.h"
18 
19 #include <android-base/logging.h>
20 
21 #include <iostream>
22 
23 #include "model/controller/dual_mode_controller.h"
24 
25 using namespace rootcanal;
26 using bluetooth::hci::Address;
27 
28 namespace hci {
29 
30 enum Idc {
31   CMD = 1,
32   ACL,
33   SCO,
34   EVT,
35   ISO,
36 };
37 
ConfigureLogging()38 __attribute__((constructor)) static void ConfigureLogging() {
39   android::base::InitLogging({}, android::base::StdioLogger);
40 }
41 
42 }  // namespace hci
43 
44 extern "C" {
45 
ffi_controller_new(uint8_t const address[6],void (* send_hci)(int idc,uint8_t const * data,size_t data_len),void (* send_ll)(uint8_t const * data,size_t data_len,int phy,int tx_power))46 __attribute__((visibility("default"))) void* ffi_controller_new(
47         uint8_t const address[6], void (*send_hci)(int idc, uint8_t const* data, size_t data_len),
48         void (*send_ll)(uint8_t const* data, size_t data_len, int phy, int tx_power)) {
49   DualModeController* controller = new DualModeController();
50   controller->SetAddress(
51           Address({address[0], address[1], address[2], address[3], address[4], address[5]}));
52   controller->RegisterEventChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
53     send_hci(hci::Idc::EVT, data->data(), data->size());
54   });
55   controller->RegisterAclChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
56     send_hci(hci::Idc::ACL, data->data(), data->size());
57   });
58   controller->RegisterScoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
59     send_hci(hci::Idc::SCO, data->data(), data->size());
60   });
61   controller->RegisterIsoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
62     send_hci(hci::Idc::ISO, data->data(), data->size());
63   });
64   controller->RegisterLinkLayerChannel(
65           [=](std::vector<uint8_t> const& data, Phy::Type phy, int8_t tx_power) {
66             send_ll(data.data(), data.size(), static_cast<int>(phy), tx_power);
67           });
68 
69   return controller;
70 }
71 
ffi_controller_delete(void * controller_)72 __attribute__((visibility("default"))) void ffi_controller_delete(void* controller_) {
73   DualModeController* controller = reinterpret_cast<DualModeController*>(controller_);
74   delete controller;
75 }
76 
ffi_controller_receive_hci(void * controller_,int idc,uint8_t const * data,size_t data_len)77 __attribute__((visibility("default"))) void ffi_controller_receive_hci(void* controller_, int idc,
78                                                                        uint8_t const* data,
79                                                                        size_t data_len) {
80   DualModeController* controller = reinterpret_cast<DualModeController*>(controller_);
81   std::shared_ptr<std::vector<uint8_t>> bytes =
82           std::make_shared<std::vector<uint8_t>>(data, data + data_len);
83 
84   switch (idc) {
85     case hci::Idc::CMD:
86       controller->HandleCommand(bytes);
87       break;
88     case hci::Idc::ACL:
89       controller->HandleAcl(bytes);
90       break;
91     case hci::Idc::SCO:
92       controller->HandleSco(bytes);
93       break;
94     case hci::Idc::ISO:
95       controller->HandleIso(bytes);
96       break;
97     default:
98       std::cerr << "Dropping HCI packet with unknown type " << (int)idc << std::endl;
99       break;
100   }
101 }
102 
ffi_controller_receive_ll(void * controller_,uint8_t const * data,size_t data_len,int phy,int rssi)103 __attribute__((visibility("default"))) void ffi_controller_receive_ll(void* controller_,
104                                                                       uint8_t const* data,
105                                                                       size_t data_len, int phy,
106                                                                       int rssi) {
107   DualModeController* controller = reinterpret_cast<DualModeController*>(controller_);
108   std::shared_ptr<std::vector<uint8_t>> bytes =
109           std::make_shared<std::vector<uint8_t>>(data, data + data_len);
110   model::packets::LinkLayerPacketView packet =
111           model::packets::LinkLayerPacketView::Create(pdl::packet::slice(bytes));
112   if (!packet.IsValid()) {
113     std::cerr << "Dropping malformed LL packet" << std::endl;
114     return;
115   }
116   controller->ReceiveLinkLayerPacket(packet, Phy::Type(phy), rssi);
117 }
118 
ffi_controller_tick(void * controller_)119 __attribute__((visibility("default"))) void ffi_controller_tick(void* controller_) {
120   DualModeController* controller = reinterpret_cast<DualModeController*>(controller_);
121   controller->Tick();
122 }
123 
ffi_generate_rpa(uint8_t const irk_[16],uint8_t rpa[6])124 __attribute__((visibility("default"))) void ffi_generate_rpa(uint8_t const irk_[16],
125                                                              uint8_t rpa[6]) {
126   std::array<uint8_t, LinkLayerController::kIrkSize> irk;
127   memcpy(irk.data(), irk_, LinkLayerController::kIrkSize);
128   Address address = LinkLayerController::generate_rpa(irk);
129   memcpy(rpa, address.data(), Address::kLength);
130 }
131 
132 };  // extern "C"
133