1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "hril_modem.h"
17
18#include "hril_notification.h"
19#include "hril_request.h"
20
21namespace OHOS {
22namespace Telephony {
23HRilModem::HRilModem(int32_t slotId) : HRilBase(slotId)
24{
25    AddHandlerToMap();
26}
27
28int32_t HRilModem::ShutDown(int32_t serialId)
29{
30    return RequestVendor(serialId, HREQ_MODEM_SHUT_DOWN, modemFuncs_, &HRilModemReq::ShutDown);
31}
32
33int32_t HRilModem::SetRadioState(int32_t serialId, int32_t fun, int32_t rst)
34{
35    return RequestVendor(serialId, HREQ_MODEM_SET_RADIO_STATUS, modemFuncs_, &HRilModemReq::SetRadioState, fun, rst);
36}
37
38int32_t HRilModem::GetRadioState(int32_t serialId)
39{
40    return RequestVendor(serialId, HREQ_MODEM_GET_RADIO_STATUS, modemFuncs_, &HRilModemReq::GetRadioState);
41}
42
43int32_t HRilModem::GetImei(int32_t serialId)
44{
45    return RequestVendor(serialId, HREQ_MODEM_GET_IMEI, modemFuncs_, &HRilModemReq::GetImei);
46}
47
48int32_t HRilModem::GetImeiSv(int32_t serialId)
49{
50    return RequestVendor(serialId, HREQ_MODEM_GET_IMEISV, modemFuncs_, &HRilModemReq::GetImeiSv);
51}
52
53int32_t HRilModem::GetMeid(int32_t serialId)
54{
55    return RequestVendor(serialId, HREQ_MODEM_GET_MEID, modemFuncs_, &HRilModemReq::GetMeid);
56}
57
58int32_t HRilModem::GetVoiceRadioTechnology(int32_t serialId)
59{
60    return RequestVendor(serialId, HREQ_MODEM_GET_VOICE_RADIO, modemFuncs_, &HRilModemReq::GetVoiceRadioTechnology);
61}
62
63int32_t HRilModem::GetBasebandVersion(int32_t serialId)
64{
65    return RequestVendor(serialId, HREQ_MODEM_GET_BASEBAND_VERSION, modemFuncs_, &HRilModemReq::GetBasebandVersion);
66}
67
68int32_t HRilModem::RadioStateUpdated(
69    const int32_t indType, const HRilErrNumber error, const void *response, size_t responseLen)
70{
71    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(int32_t)) != 0) {
72        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
73        return HRIL_ERR_INVALID_PARAMETER;
74    }
75    if (response == nullptr) {
76        TELEPHONY_LOGE("response is null");
77        return HRIL_ERR_NULL_POINT;
78    }
79    radioState_ = *(const int32_t *)response;
80    return Notify(indType, error, &HDI::Ril::V1_1::IRilCallback::RadioStateUpdated, radioState_);
81}
82
83int32_t HRilModem::VoiceRadioTechUpdated(
84    const int32_t indType, const HRilErrNumber error, const void *response, size_t responseLen)
85{
86    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(HRilVoiceRadioInfo)) != 0) {
87        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
88        return HRIL_ERR_INVALID_PARAMETER;
89    }
90    if (response == nullptr) {
91        TELEPHONY_LOGE("response is null");
92        return HRIL_ERR_NULL_POINT;
93    }
94    HDI::Ril::V1_1::VoiceRadioTechnology voiceRadioTech = {};
95    BuildIVoiceRadioTechnology(voiceRadioTech, *(const HRilVoiceRadioInfo *)response);
96    return Notify(indType, error, &HDI::Ril::V1_1::IRilCallback::VoiceRadioTechUpdated, voiceRadioTech);
97}
98
99int32_t HRilModem::DsdsModeUpdated(
100    const int32_t indType, const HRilErrNumber error, const void *response, size_t responseLen)
101{
102    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(int32_t)) != 0) {
103        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
104        return HRIL_ERR_INVALID_PARAMETER;
105    }
106    if (response == nullptr) {
107        TELEPHONY_LOGE("response is null");
108        return HRIL_ERR_NULL_POINT;
109    }
110    return Notify(
111        indType, error, &HDI::Ril::V1_1::IRilCallback::DsdsModeUpdated, *(static_cast<const int32_t *>(response)));
112}
113
114int32_t HRilModem::NcfgFinishedResult(
115    int32_t indType, HRilErrNumber error, const void *response, size_t responseLen)
116{
117    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(int32_t)) != 0) {
118        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
119        return HRIL_ERR_INVALID_PARAMETER;
120    }
121    if (response == nullptr) {
122        TELEPHONY_LOGE("response is null");
123        return HRIL_ERR_NULL_POINT;
124    }
125    return Notify(
126        indType, error, &HDI::Ril::V1_3::IRilCallback::NcfgFinishedResult, *(static_cast<const int32_t *>(response)));
127}
128
129int32_t HRilModem::RestartRildNvMatch(
130    int32_t indType, HRilErrNumber error, const void *response, size_t responseLen)
131{
132    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(int32_t)) != 0) {
133        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
134        return HRIL_ERR_INVALID_PARAMETER;
135    }
136    if (response == nullptr) {
137        TELEPHONY_LOGE("response is null");
138        return HRIL_ERR_NULL_POINT;
139    }
140    return Notify(
141        indType, error, &HDI::Ril::V1_3::IRilCallback::RestartRildNvMatch, *(static_cast<const int32_t *>(response)));
142}
143
144int32_t HRilModem::ShutDownResponse(
145    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
146{
147    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::ShutDownResponse);
148}
149
150int32_t HRilModem::SetRadioStateResponse(
151    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
152{
153    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::SetRadioStateResponse);
154}
155
156int32_t HRilModem::GetRadioStateResponse(
157    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
158{
159    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(int32_t)) != 0) {
160        TELEPHONY_LOGE("Invalid parameter, responseLen:%{public}zu", responseLen);
161        return HRIL_ERR_INVALID_PARAMETER;
162    }
163    if (response == nullptr) {
164        TELEPHONY_LOGE("response is null");
165        return HRIL_ERR_NULL_POINT;
166    }
167    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::GetRadioStateResponse, *(const int32_t *)response);
168}
169
170int32_t HRilModem::GetImeiResponse(
171    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
172{
173    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(char)) != 0) {
174        TELEPHONY_LOGE("GetImeiResponse:Invalid parameter, responseLen:%{public}zu", responseLen);
175        return HRIL_ERR_INVALID_PARAMETER;
176    }
177    if (response == nullptr) {
178        TELEPHONY_LOGE("response is null");
179        return HRIL_ERR_NULL_POINT;
180    }
181    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::GetImeiResponse, std::string((const char *)response));
182}
183
184int32_t HRilModem::GetImeiSvResponse(
185    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
186{
187    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(char)) != 0) {
188        TELEPHONY_LOGE("GetImeiSvResponse:Invalid parameter, responseLen:%{public}zu", responseLen);
189        return HRIL_ERR_INVALID_PARAMETER;
190    }
191    if (response == nullptr) {
192        TELEPHONY_LOGE("response is null");
193        return HRIL_ERR_NULL_POINT;
194    }
195    return Response(
196        responseInfo, &HDI::Ril::V1_3::IRilCallback::GetImeiSvResponse, std::string((const char *)response));
197}
198
199int32_t HRilModem::GetMeidResponse(
200    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
201{
202    std::string meidResponse = "";
203    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(char)) != 0) {
204        TELEPHONY_LOGE("GetMeidResponse:Invalid parameter, responseLen:%{public}zu", responseLen);
205        if (responseInfo.error == HDI::Ril::V1_1::RilErrType::NONE) {
206            responseInfo.error = HDI::Ril::V1_1::RilErrType::RIL_ERR_INVALID_RESPONSE;
207        }
208    }
209    if (response == nullptr) {
210        TELEPHONY_LOGE("response is null");
211        if (responseInfo.error == HDI::Ril::V1_1::RilErrType::NONE) {
212            responseInfo.error = HDI::Ril::V1_1::RilErrType::RIL_ERR_NULL_POINT;
213        }
214    } else {
215        meidResponse = std::string((const char *)response);
216    }
217    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::GetMeidResponse, meidResponse);
218}
219
220int32_t HRilModem::GetVoiceRadioTechnologyResponse(
221    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
222{
223    HDI::Ril::V1_1::VoiceRadioTechnology voiceRadioTech = {};
224    if (response == nullptr) {
225        TELEPHONY_LOGE("GetVoiceRadioTechnologyResponse Invalid response: nullptr");
226        if (responseInfo.error == HDI::Ril::V1_1::RilErrType::NONE) {
227            responseInfo.error = HDI::Ril::V1_1::RilErrType::RIL_ERR_INVALID_RESPONSE;
228        }
229    } else {
230        BuildIVoiceRadioTechnology(voiceRadioTech, *(const HRilVoiceRadioInfo *)response);
231    }
232    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::GetVoiceRadioTechnologyResponse, voiceRadioTech);
233}
234
235void HRilModem::BuildIVoiceRadioTechnology(
236    HDI::Ril::V1_1::VoiceRadioTechnology &voiceRadioTech, const HRilVoiceRadioInfo &hRiadioInfo)
237{
238    voiceRadioTech.srvStatus = static_cast<OHOS::HDI::Ril::V1_1::RilSrvStatus>(hRiadioInfo.srvStatus);
239    voiceRadioTech.srvDomain = static_cast<OHOS::HDI::Ril::V1_1::RilSrvDomain>(hRiadioInfo.srvDomain);
240    voiceRadioTech.roamStatus = static_cast<OHOS::HDI::Ril::V1_1::RilRoamStatus>(hRiadioInfo.roamStatus);
241    voiceRadioTech.simStatus = static_cast<OHOS::HDI::Ril::V1_1::RilSimStatus>(hRiadioInfo.simStatus);
242    voiceRadioTech.lockStatus = static_cast<OHOS::HDI::Ril::V1_1::RilSimLockStatus>(hRiadioInfo.lockStatus);
243    voiceRadioTech.sysMode = static_cast<OHOS::HDI::Ril::V1_1::RilSysMode>(hRiadioInfo.sysMode);
244    voiceRadioTech.sysModeName = (hRiadioInfo.sysModeName == nullptr) ? "" : hRiadioInfo.sysModeName;
245    voiceRadioTech.actType = static_cast<OHOS::HDI::Ril::V1_1::RilRadioTech>(hRiadioInfo.actType);
246    voiceRadioTech.actName = (hRiadioInfo.actName == nullptr) ? "" : hRiadioInfo.actName;
247}
248
249int32_t HRilModem::GetBasebandVersionResponse(
250    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
251{
252    if ((response == nullptr && responseLen != 0) || (responseLen % sizeof(char)) != 0) {
253        TELEPHONY_LOGE("GetBasebandVersionResponse:Invalid parameter, responseLen:%{public}zu", responseLen);
254        return HRIL_ERR_INVALID_PARAMETER;
255    }
256    if (response == nullptr) {
257        TELEPHONY_LOGE("response is null");
258        return HRIL_ERR_NULL_POINT;
259    }
260    return Response(
261        responseInfo, &HDI::Ril::V1_1::IRilCallback::GetBasebandVersionResponse, std::string((const char *)response));
262}
263
264bool HRilModem::IsModemResponse(uint32_t code)
265{
266    return ((code >= HREQ_COMMON_BASE) && (code <= HREQ_MODEM_GET_VOICE_RADIO));
267}
268
269bool HRilModem::IsModemNotification(uint32_t code)
270{
271    return ((code >= HNOTI_COMMON_BASE) && (code <= HNOTI_COMMON_END));
272}
273
274bool HRilModem::IsModemRespOrNotify(uint32_t code)
275{
276    return IsModemResponse(code) || IsModemNotification(code);
277}
278
279int32_t HRilModem::SetActiveSimResponse(
280    int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
281{
282    return Response(responseInfo, &HDI::Ril::V1_1::IRilCallback::SetActiveSimResponse);
283}
284
285void HRilModem::AddHandlerToMap()
286{
287    // indication
288    notiMemberFuncMap_[HNOTI_MODEM_RADIO_STATE_UPDATED] =
289        [this](int32_t notifyType, HRilErrNumber error, const void *response,
290        size_t responseLen) { return RadioStateUpdated(notifyType, error, response, responseLen); };
291    notiMemberFuncMap_[HNOTI_MODEM_VOICE_TECH_UPDATED] =
292        [this](int32_t notifyType, HRilErrNumber error, const void *response,
293        size_t responseLen) { return VoiceRadioTechUpdated(notifyType, error, response, responseLen); };
294    notiMemberFuncMap_[HNOTI_MODEM_DSDS_MODE_UPDATED] =
295        [this](int32_t notifyType, HRilErrNumber error, const void *response,
296        size_t responseLen) { return DsdsModeUpdated(notifyType, error, response, responseLen); };
297    notiMemberFuncMap_[HNOTI_MODEM_NCFG_FINISHED_RESULT] =
298        [this](int32_t notifyType, HRilErrNumber error, const void *response,
299        size_t responseLen) { return NcfgFinishedResult(notifyType, error, response, responseLen); };
300    notiMemberFuncMap_[HNOTI_MODEM_RESTART_RILD_NV_MATCH] =
301        [this](int32_t notifyType, HRilErrNumber error, const void *response,
302        size_t responseLen) { return RestartRildNvMatch(notifyType, error, response, responseLen); };
303    // response
304    respMemberFuncMap_[HREQ_MODEM_SHUT_DOWN] =
305        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
306        size_t responseLen) { return ShutDownResponse(requestNum, responseInfo, response, responseLen); };
307    respMemberFuncMap_[HREQ_MODEM_SET_RADIO_STATUS] =
308        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
309        size_t responseLen) { return SetRadioStateResponse(requestNum, responseInfo, response, responseLen); };
310    respMemberFuncMap_[HREQ_SIM_SET_ACTIVE_SIM] =
311        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
312        size_t responseLen) { return SetActiveSimResponse(requestNum, responseInfo, response, responseLen); };
313    respMemberFuncMap_[HREQ_MODEM_GET_RADIO_STATUS] =
314        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
315        size_t responseLen) { return GetRadioStateResponse(requestNum, responseInfo, response, responseLen); };
316    respMemberFuncMap_[HREQ_MODEM_GET_IMEI] =
317        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
318        size_t responseLen) { return GetImeiResponse(requestNum, responseInfo, response, responseLen); };
319    respMemberFuncMap_[HREQ_MODEM_GET_IMEISV] =
320        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
321        size_t responseLen) { return GetImeiSvResponse(requestNum, responseInfo, response, responseLen); };
322    respMemberFuncMap_[HREQ_MODEM_GET_MEID] =
323        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
324        size_t responseLen) { return GetMeidResponse(requestNum, responseInfo, response, responseLen); };
325    respMemberFuncMap_[HREQ_MODEM_GET_VOICE_RADIO] = [this](int32_t requestNum,
326        HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response, size_t responseLen) {
327        return GetVoiceRadioTechnologyResponse(requestNum, responseInfo, response, responseLen);
328    };
329    respMemberFuncMap_[HREQ_MODEM_GET_BASEBAND_VERSION] =
330        [this](int32_t requestNum, HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo, const void *response,
331        size_t responseLen) { return GetBasebandVersionResponse(requestNum, responseInfo, response, responseLen); };
332}
333
334void HRilModem::RegisterModemFuncs(const HRilModemReq *modemFuncs)
335{
336    modemFuncs_ = modemFuncs;
337}
338
339int32_t HRilModem::GetLastRadioState()
340{
341    return radioState_;
342}
343} // namespace Telephony
344} // namespace OHOS