1 /*
2 * Copyright (C) 2023 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 <libminradio/modem/RadioModem.h>
18
19 #include <libminradio/debug.h>
20 #include <libminradio/response.h>
21
22 #define RADIO_MODULE "Modem"
23
24 namespace android::hardware::radio::minimal {
25
26 using namespace ::android::hardware::radio::minimal::binder_printing;
27 using ::aidl::android::hardware::radio::RadioIndicationType;
28 using ::ndk::ScopedAStatus;
29 namespace aidl = ::aidl::android::hardware::radio::modem;
30 namespace aidlRadio = ::aidl::android::hardware::radio;
31 constexpr auto ok = &ScopedAStatus::ok;
32
RadioModem(std::shared_ptr<SlotContext> context,std::vector<aidlRadio::RadioTechnology> rats)33 RadioModem::RadioModem(std::shared_ptr<SlotContext> context,
34 std::vector<aidlRadio::RadioTechnology> rats)
35 : RadioSlotBase(context) {
36 int32_t ratBitmap = 0;
37 for (auto rat : rats) {
38 CHECK(rat > aidlRadio::RadioTechnology::UNKNOWN) << "Invalid RadioTechnology: " << rat;
39 CHECK(rat <= aidlRadio::RadioTechnology::NR)
40 << ": " << rat << " not supported yet: "
41 << "please verify if RadioAccessFamily for this RadioTechnology is a bit-shifted 1";
42 ratBitmap |= 1 << static_cast<int32_t>(rat);
43 }
44 mRatBitmap = ratBitmap;
45 }
46
getModemUuid() const47 std::string RadioModem::getModemUuid() const {
48 // Assumes one modem per slot.
49 return std::format("com.android.minradio.modem{}", mContext->getSlotIndex());
50 }
51
getSimUuid() const52 std::string RadioModem::getSimUuid() const {
53 // Assumes one SIM per slot.
54 return std::format("com.android.minradio.sim{}", mContext->getSlotIndex());
55 }
56
enableModem(int32_t serial,bool on)57 ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
58 LOG_NOT_SUPPORTED << on;
59 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
60 }
61
getBasebandVersion(int32_t serial)62 ScopedAStatus RadioModem::getBasebandVersion(int32_t serial) {
63 LOG_CALL;
64 respond()->getBasebandVersionResponse( //
65 noError(serial), std::format("libminradio V{}", IRadioModem::version));
66 return ok();
67 }
68
getDeviceIdentity(int32_t serial)69 ScopedAStatus RadioModem::getDeviceIdentity(int32_t serial) {
70 LOG_AND_RETURN_DEPRECATED();
71 }
72
getHardwareConfig(int32_t serial)73 ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
74 LOG_CALL;
75
76 aidl::HardwareConfig modem1Config{
77 .type = aidl::HardwareConfig::TYPE_MODEM,
78 .uuid = getModemUuid(),
79 .state = aidl::HardwareConfig::STATE_ENABLED,
80 .modem = {{
81 .rilModel = 0, // 0=single (one-to-one relationship for hw and ril daemon)
82 .rat = static_cast<aidlRadio::RadioTechnology>(mRatBitmap),
83 .maxVoiceCalls = 0,
84 .maxDataCalls = 1,
85 .maxStandby = 1,
86 }},
87 };
88
89 aidl::HardwareConfig sim1Config{
90 .type = aidl::HardwareConfig::TYPE_SIM,
91 .uuid = getSimUuid(),
92 .state = aidl::HardwareConfig::STATE_ENABLED,
93 .sim = {{
94 .modemUuid = getModemUuid(),
95 }},
96 };
97
98 respond()->getHardwareConfigResponse(noError(serial), {modem1Config, sim1Config});
99 return ok();
100 }
101
getModemActivityInfo(int32_t serial)102 ScopedAStatus RadioModem::getModemActivityInfo(int32_t serial) {
103 LOG_CALL_IGNORED;
104 const aidl::ActivityStatsTechSpecificInfo generalActivityStats{
105 .txmModetimeMs = {0, 0, 0, 0, 0},
106 };
107 const aidl::ActivityStatsInfo info{
108 // idleModeTimeMs doesn't make sense for external modem, but the framework
109 // doesn't allow for ModemActivityInfo.isEmpty
110 .idleModeTimeMs = 1,
111 .techSpecificInfo = {generalActivityStats},
112 };
113 respond()->getModemActivityInfoResponse(noError(serial), info);
114 return ok();
115 }
116
getModemStackStatus(int32_t serial)117 ScopedAStatus RadioModem::getModemStackStatus(int32_t serial) {
118 LOG_CALL;
119 respond()->getModemStackStatusResponse(noError(serial), true);
120 return ok();
121 }
122
getRadioCapability(int32_t serial)123 ScopedAStatus RadioModem::getRadioCapability(int32_t serial) {
124 LOG_CALL;
125 aidl::RadioCapability cap{
126 .session = 0,
127 .phase = aidl::RadioCapability::PHASE_FINISH,
128 .raf = mRatBitmap, // rafs are nothing else than rat masks
129 .logicalModemUuid = getModemUuid(),
130 .status = aidl::RadioCapability::STATUS_SUCCESS,
131 };
132 respond()->getRadioCapabilityResponse(noError(serial), cap);
133 return ok();
134 }
135
nvReadItem(int32_t serial,aidl::NvItem)136 ScopedAStatus RadioModem::nvReadItem(int32_t serial, aidl::NvItem) {
137 LOG_AND_RETURN_DEPRECATED();
138 }
139
nvResetConfig(int32_t serial,aidl::ResetNvType resetType)140 ScopedAStatus RadioModem::nvResetConfig(int32_t serial, aidl::ResetNvType resetType) {
141 LOG_CALL << resetType; // RELOAD is the only non-deprecated argument
142 respond()->nvResetConfigResponse(notSupported(serial));
143 return ok();
144 }
145
nvWriteCdmaPrl(int32_t serial,const std::vector<uint8_t> &)146 ScopedAStatus RadioModem::nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>&) {
147 LOG_AND_RETURN_DEPRECATED();
148 }
149
nvWriteItem(int32_t serial,const aidl::NvWriteItem &)150 ScopedAStatus RadioModem::nvWriteItem(int32_t serial, const aidl::NvWriteItem&) {
151 LOG_AND_RETURN_DEPRECATED();
152 }
153
requestShutdown(int32_t serial)154 ScopedAStatus RadioModem::requestShutdown(int32_t serial) {
155 LOG_NOT_SUPPORTED;
156 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
157 }
158
responseAcknowledgement()159 ScopedAStatus RadioModem::responseAcknowledgement() {
160 LOG_CALL_NOSERIAL;
161 return ok();
162 }
163
sendDeviceState(int32_t serial,aidl::DeviceStateType type,bool state)164 ScopedAStatus RadioModem::sendDeviceState(int32_t serial, aidl::DeviceStateType type, bool state) {
165 LOG_CALL_IGNORED << type << ' ' << state;
166 respond()->sendDeviceStateResponse(noError(serial));
167 return ok();
168 }
169
setRadioCapability(int32_t serial,const aidl::RadioCapability & rc)170 ScopedAStatus RadioModem::setRadioCapability(int32_t serial, const aidl::RadioCapability& rc) {
171 LOG_NOT_SUPPORTED << rc;
172 respond()->setRadioCapabilityResponse(notSupported(serial), {});
173 return ok();
174 }
175
setRadioPower(int32_t serial,bool powerOn,bool forEmergencyCall,bool preferredForEmergencyCall)176 ScopedAStatus RadioModem::setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
177 bool preferredForEmergencyCall) {
178 LOG_CALL_IGNORED << powerOn << " " << forEmergencyCall << " " << preferredForEmergencyCall;
179 respond()->setRadioPowerResponse(noError(serial));
180 indicate()->radioStateChanged(RadioIndicationType::UNSOLICITED,
181 powerOn ? aidl::RadioState::ON : aidl::RadioState::OFF);
182 return ok();
183 }
184
setResponseFunctions(const std::shared_ptr<aidl::IRadioModemResponse> & response,const std::shared_ptr<aidl::IRadioModemIndication> & indication)185 ScopedAStatus RadioModem::setResponseFunctions(
186 const std::shared_ptr<aidl::IRadioModemResponse>& response,
187 const std::shared_ptr<aidl::IRadioModemIndication>& indication) {
188 LOG_CALL_NOSERIAL << response << ' ' << indication;
189 CHECK(response);
190 CHECK(indication);
191 respond = response;
192 indicate = indication;
193 setResponseFunctionsBase();
194 return ok();
195 }
196
onUpdatedResponseFunctions()197 void RadioModem::onUpdatedResponseFunctions() {
198 indicate()->rilConnected(RadioIndicationType::UNSOLICITED);
199 indicate()->radioStateChanged(RadioIndicationType::UNSOLICITED, aidl::RadioState::ON);
200 }
201
202 } // namespace android::hardware::radio::minimal
203