xref: /aosp_15_r20/system/nfc/src/rust/hal/ffi/hidl.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
1*7eba2f3bSAndroid Build Coastguard Worker #include "hal/ffi/hidl.h"
2*7eba2f3bSAndroid Build Coastguard Worker 
3*7eba2f3bSAndroid Build Coastguard Worker #include <log/log.h>
4*7eba2f3bSAndroid Build Coastguard Worker #include <stdlib.h>
5*7eba2f3bSAndroid Build Coastguard Worker 
6*7eba2f3bSAndroid Build Coastguard Worker using ::android::wp;
7*7eba2f3bSAndroid Build Coastguard Worker using ::android::hardware::hidl_death_recipient;
8*7eba2f3bSAndroid Build Coastguard Worker using ::android::hidl::base::V1_0::IBase;
9*7eba2f3bSAndroid Build Coastguard Worker 
10*7eba2f3bSAndroid Build Coastguard Worker using android::OK;
11*7eba2f3bSAndroid Build Coastguard Worker using android::sp;
12*7eba2f3bSAndroid Build Coastguard Worker using android::status_t;
13*7eba2f3bSAndroid Build Coastguard Worker 
14*7eba2f3bSAndroid Build Coastguard Worker using ::android::hardware::hidl_vec;
15*7eba2f3bSAndroid Build Coastguard Worker using ::android::hardware::Return;
16*7eba2f3bSAndroid Build Coastguard Worker using ::android::hardware::Void;
17*7eba2f3bSAndroid Build Coastguard Worker using android::hardware::nfc::V1_0::INfc;
18*7eba2f3bSAndroid Build Coastguard Worker using INfcV1_1 = android::hardware::nfc::V1_1::INfc;
19*7eba2f3bSAndroid Build Coastguard Worker using INfcV1_2 = android::hardware::nfc::V1_2::INfc;
20*7eba2f3bSAndroid Build Coastguard Worker using android::hardware::nfc::V1_1::INfcClientCallback;
21*7eba2f3bSAndroid Build Coastguard Worker 
22*7eba2f3bSAndroid Build Coastguard Worker namespace nfc {
23*7eba2f3bSAndroid Build Coastguard Worker namespace hal {
24*7eba2f3bSAndroid Build Coastguard Worker namespace {
25*7eba2f3bSAndroid Build Coastguard Worker 
26*7eba2f3bSAndroid Build Coastguard Worker class NfcHalDeathRecipient : public hidl_death_recipient {
27*7eba2f3bSAndroid Build Coastguard Worker  public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)28*7eba2f3bSAndroid Build Coastguard Worker   virtual void serviceDied(
29*7eba2f3bSAndroid Build Coastguard Worker       uint64_t /*cookie*/,
30*7eba2f3bSAndroid Build Coastguard Worker       const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
31*7eba2f3bSAndroid Build Coastguard Worker     LOG_FATAL("Nfc HAL service died!");
32*7eba2f3bSAndroid Build Coastguard Worker     abort();
33*7eba2f3bSAndroid Build Coastguard Worker   }
34*7eba2f3bSAndroid Build Coastguard Worker };
35*7eba2f3bSAndroid Build Coastguard Worker 
36*7eba2f3bSAndroid Build Coastguard Worker class NfcCallbackTrampoline : public INfcClientCallback {
37*7eba2f3bSAndroid Build Coastguard Worker  public:
NfcCallbackTrampoline()38*7eba2f3bSAndroid Build Coastguard Worker   NfcCallbackTrampoline() {}
39*7eba2f3bSAndroid Build Coastguard Worker 
sendEvent_1_1(::android::hardware::nfc::V1_1::NfcEvent event,::android::hardware::nfc::V1_0::NfcStatus event_status)40*7eba2f3bSAndroid Build Coastguard Worker   Return<void> sendEvent_1_1(
41*7eba2f3bSAndroid Build Coastguard Worker       ::android::hardware::nfc::V1_1::NfcEvent event,
42*7eba2f3bSAndroid Build Coastguard Worker       ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
43*7eba2f3bSAndroid Build Coastguard Worker     on_event(event, event_status);
44*7eba2f3bSAndroid Build Coastguard Worker     return Void();
45*7eba2f3bSAndroid Build Coastguard Worker   }
sendEvent(::android::hardware::nfc::V1_0::NfcEvent event,::android::hardware::nfc::V1_0::NfcStatus event_status)46*7eba2f3bSAndroid Build Coastguard Worker   Return<void> sendEvent(
47*7eba2f3bSAndroid Build Coastguard Worker       ::android::hardware::nfc::V1_0::NfcEvent event,
48*7eba2f3bSAndroid Build Coastguard Worker       ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
49*7eba2f3bSAndroid Build Coastguard Worker     on_event((::android::hardware::nfc::V1_1::NfcEvent)event, event_status);
50*7eba2f3bSAndroid Build Coastguard Worker     return Void();
51*7eba2f3bSAndroid Build Coastguard Worker   }
52*7eba2f3bSAndroid Build Coastguard Worker 
sendData(const::android::hardware::nfc::V1_0::NfcData & data)53*7eba2f3bSAndroid Build Coastguard Worker   Return<void> sendData(const ::android::hardware::nfc::V1_0::NfcData& data) {
54*7eba2f3bSAndroid Build Coastguard Worker     on_data(rust::Slice(&data[0], data.size()));
55*7eba2f3bSAndroid Build Coastguard Worker     return Void();
56*7eba2f3bSAndroid Build Coastguard Worker   }
57*7eba2f3bSAndroid Build Coastguard Worker };
58*7eba2f3bSAndroid Build Coastguard Worker 
59*7eba2f3bSAndroid Build Coastguard Worker android::sp<NfcHalDeathRecipient> nfc_death_recipient_;
60*7eba2f3bSAndroid Build Coastguard Worker android::sp<INfc> nci_;
61*7eba2f3bSAndroid Build Coastguard Worker android::sp<INfcV1_1> nci_1_1_;
62*7eba2f3bSAndroid Build Coastguard Worker android::sp<INfcV1_2> nci_1_2_;
63*7eba2f3bSAndroid Build Coastguard Worker android::sp<NfcCallbackTrampoline> trampoline_;
64*7eba2f3bSAndroid Build Coastguard Worker 
65*7eba2f3bSAndroid Build Coastguard Worker }  // namespace
66*7eba2f3bSAndroid Build Coastguard Worker 
start_hal()67*7eba2f3bSAndroid Build Coastguard Worker void start_hal() {
68*7eba2f3bSAndroid Build Coastguard Worker   ALOG_ASSERT(nci_ != nullptr, "Stale value of the NCI port");
69*7eba2f3bSAndroid Build Coastguard Worker 
70*7eba2f3bSAndroid Build Coastguard Worker   nci_ = nci_1_1_ = nci_1_2_ = INfcV1_2::getService();
71*7eba2f3bSAndroid Build Coastguard Worker   if (nci_1_2_ == nullptr) {
72*7eba2f3bSAndroid Build Coastguard Worker     nci_ = nci_1_1_ = INfcV1_1::getService();
73*7eba2f3bSAndroid Build Coastguard Worker     if (nci_1_1_ == nullptr) {
74*7eba2f3bSAndroid Build Coastguard Worker       nci_ = INfc::getService();
75*7eba2f3bSAndroid Build Coastguard Worker     }
76*7eba2f3bSAndroid Build Coastguard Worker   }
77*7eba2f3bSAndroid Build Coastguard Worker   LOG_FATAL_IF(nci_ == nullptr, "Failed to retrieve the NFC HAL!");
78*7eba2f3bSAndroid Build Coastguard Worker   ALOGI("%s: INfc::getService() returned %p (%s)", __func__, nci_.get(),
79*7eba2f3bSAndroid Build Coastguard Worker         (nci_->isRemote() ? "remote" : "local"));
80*7eba2f3bSAndroid Build Coastguard Worker   if (nci_) {
81*7eba2f3bSAndroid Build Coastguard Worker     nfc_death_recipient_ = new NfcHalDeathRecipient();
82*7eba2f3bSAndroid Build Coastguard Worker     auto death_link = nci_->linkToDeath(nfc_death_recipient_, 0);
83*7eba2f3bSAndroid Build Coastguard Worker     ALOG_ASSERT(death_link.isOk(),
84*7eba2f3bSAndroid Build Coastguard Worker                 "Unable to set the death recipient for the Nfc HAL");
85*7eba2f3bSAndroid Build Coastguard Worker   }
86*7eba2f3bSAndroid Build Coastguard Worker 
87*7eba2f3bSAndroid Build Coastguard Worker   trampoline_ = new NfcCallbackTrampoline();
88*7eba2f3bSAndroid Build Coastguard Worker   if (nci_1_1_ != nullptr) {
89*7eba2f3bSAndroid Build Coastguard Worker     nci_1_1_->open_1_1(trampoline_);
90*7eba2f3bSAndroid Build Coastguard Worker   } else {
91*7eba2f3bSAndroid Build Coastguard Worker     nci_->open(trampoline_);
92*7eba2f3bSAndroid Build Coastguard Worker   }
93*7eba2f3bSAndroid Build Coastguard Worker }
94*7eba2f3bSAndroid Build Coastguard Worker 
stop_hal()95*7eba2f3bSAndroid Build Coastguard Worker void stop_hal() {
96*7eba2f3bSAndroid Build Coastguard Worker   ALOG_ASSERT(nci_ == nullptr, "The NCI communication was already closed");
97*7eba2f3bSAndroid Build Coastguard Worker 
98*7eba2f3bSAndroid Build Coastguard Worker   auto death_unlink = nci_->unlinkToDeath(nfc_death_recipient_);
99*7eba2f3bSAndroid Build Coastguard Worker   if (!death_unlink.isOk()) {
100*7eba2f3bSAndroid Build Coastguard Worker     ALOGE("Error unlinking death recipient from the Bluetooth HAL");
101*7eba2f3bSAndroid Build Coastguard Worker   }
102*7eba2f3bSAndroid Build Coastguard Worker   nci_->close();
103*7eba2f3bSAndroid Build Coastguard Worker   nci_ = nullptr;
104*7eba2f3bSAndroid Build Coastguard Worker   nci_1_1_ = nullptr;
105*7eba2f3bSAndroid Build Coastguard Worker   nci_1_2_ = nullptr;
106*7eba2f3bSAndroid Build Coastguard Worker   trampoline_ = nullptr;
107*7eba2f3bSAndroid Build Coastguard Worker }
108*7eba2f3bSAndroid Build Coastguard Worker 
send_command(rust::Slice<const uint8_t> data)109*7eba2f3bSAndroid Build Coastguard Worker void send_command(rust::Slice<const uint8_t> data) {
110*7eba2f3bSAndroid Build Coastguard Worker   ALOG_ASSERT(nci_ == nullptr, "The NCI communication was already closed");
111*7eba2f3bSAndroid Build Coastguard Worker   nci_->write(hidl_vec<uint8_t>(data.data(), data.data() + data.length()));
112*7eba2f3bSAndroid Build Coastguard Worker }
113*7eba2f3bSAndroid Build Coastguard Worker 
114*7eba2f3bSAndroid Build Coastguard Worker }  // namespace hal
115*7eba2f3bSAndroid Build Coastguard Worker }  // namespace nfc
116