• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2024 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 "at_modem.h"
17 #include "vendor_adapter.h"
18 #include "vendor_report.h"
19 #include "vendor_util.h"
20 
21 struct ResponseAck {
22     ResponseInfo *responseInfo;
23     uint8_t *respDataPointer;
24     int32_t respDataLen;
25 };
26 
ResponseModemReport(int32_t slotId,const ReqDataInfo * requestInfo,int32_t err,struct ResponseAck * respDataAck)27 static int32_t ResponseModemReport(
28     int32_t slotId, const ReqDataInfo *requestInfo, int32_t err, struct ResponseAck *respDataAck)
29 {
30     if (requestInfo == NULL) {
31         TELEPHONY_LOGE("requestInfo is nullptr!");
32         return HRIL_ERR_GENERIC_FAILURE;
33     }
34     if (respDataAck == NULL) {
35         TELEPHONY_LOGE("respDataAck is nullptr!");
36         return HRIL_ERR_GENERIC_FAILURE;
37     }
38     struct ReportInfo reportInfo;
39     reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
40     OnModemReport(slotId, reportInfo, (const uint8_t *)(respDataAck->respDataPointer), respDataAck->respDataLen);
41     if (respDataAck->responseInfo != NULL) {
42         FreeResponseInfo(respDataAck->responseInfo);
43     }
44     return err;
45 }
46 
GetResponseErrorCode(ResponseInfo * pResponseInfo)47 static int32_t GetResponseErrorCode(ResponseInfo *pResponseInfo)
48 {
49     char *pLine = NULL;
50     int32_t ret = HRIL_ERR_GENERIC_FAILURE;
51     if (pResponseInfo && pResponseInfo->result) {
52         pLine = pResponseInfo->result;
53         SkipATPrefix(&pLine);
54         NextInt(&pLine, &ret);
55     }
56 
57     if (ret == -1) {
58         ret = HRIL_ERR_INVALID_RESPONSE;
59     }
60     TELEPHONY_LOGD("modem response error code: %{public}d", ret);
61     return ret;
62 }
63 
ReqSetRadioState(const ReqDataInfo * requestInfo,int32_t function,int32_t reset)64 void ReqSetRadioState(const ReqDataInfo *requestInfo, int32_t function, int32_t reset)
65 {
66     if (requestInfo == NULL) {
67         return;
68     }
69     struct ReportInfo reportInfo;
70     int32_t ret = SetRadioState(function, reset);
71     if (ret == HRIL_ERR_SUCCESS) {
72         reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_SUCCESS, HRIL_RESPONSE, 0);
73     } else {
74         TELEPHONY_LOGE("ReqSetRadioState failed");
75         if (ret == HRIL_ERR_REPEAT_STATUS) {
76             reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_REPEAT_STATUS, HRIL_RESPONSE, 0);
77         } else {
78             reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_GENERIC_FAILURE, HRIL_RESPONSE, 0);
79         }
80     }
81     OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
82 }
83 
ErrorHandler(const ReqDataInfo * requestInfo,ResponseInfo * pResponse)84 static void ErrorHandler(const ReqDataInfo *requestInfo, ResponseInfo *pResponse)
85 {
86     if (requestInfo == NULL) {
87         return;
88     }
89     struct ReportInfo reportInfo;
90     reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_GENERIC_FAILURE, HRIL_RESPONSE, 0);
91     OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
92     FreeResponseInfo(pResponse);
93 }
94 
ReqGetRadioState(const ReqDataInfo * requestInfo)95 void ReqGetRadioState(const ReqDataInfo *requestInfo)
96 {
97     if (requestInfo == NULL) {
98         return;
99     }
100     const long long timeOut = DEFAULT_TIMEOUT;
101     char *pLine = NULL;
102     int32_t radioState = -1;
103     ResponseInfo *pResponse = NULL;
104     struct ReportInfo reportInfo;
105 
106     int32_t ret = SendCommandLock("AT+CFUN?", "+CFUN", timeOut, &pResponse);
107     if (ret != 0 || pResponse == NULL || !pResponse->success) {
108         TELEPHONY_LOGE("AT+CFUN send failed");
109         return ErrorHandler(requestInfo, pResponse);
110     }
111     if (pResponse->head != NULL) {
112         pLine = pResponse->head->data;
113     }
114 
115     ret = SkipATPrefix(&pLine);
116     if (ret != 0) {
117         return ErrorHandler(requestInfo, pResponse);
118     }
119     ret = NextInt(&pLine, &radioState);
120     if (ret != 0) {
121         return ErrorHandler(requestInfo, pResponse);
122     }
123 
124     reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_SUCCESS, HRIL_RESPONSE, 0);
125     OnModemReport(requestInfo->slotId, reportInfo, (const uint8_t *)&radioState, sizeof(int32_t));
126     FreeResponseInfo(pResponse);
127     return;
128 }
129 
ReqGetImei(const ReqDataInfo * requestInfo)130 void ReqGetImei(const ReqDataInfo *requestInfo)
131 {
132     if (requestInfo == NULL) {
133         return;
134     }
135     int32_t err = HRIL_ERR_SUCCESS;
136     ResponseInfo *responseInfo = NULL;
137     TELEPHONY_LOGD("enter to [%{public}s]:%{public}d", __func__, __LINE__);
138     int32_t ret = SendCommandLock("AT+CGSN", NULL, DEFAULT_TIMEOUT, &responseInfo);
139     struct ResponseAck respDataAck = { responseInfo, NULL, 0 };
140     if (responseInfo == NULL) {
141         TELEPHONY_LOGE("responseInfo is null");
142         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_NULL_POINT, &respDataAck);
143         return;
144     }
145     respDataAck.responseInfo = responseInfo;
146     if (ret != 0 || !responseInfo->success) {
147         err = GetResponseErrorCode(responseInfo);
148         TELEPHONY_LOGE("send AT CMD failed!");
149         ResponseModemReport(requestInfo->slotId, requestInfo, err, &respDataAck);
150         return;
151     }
152     if (responseInfo->head == NULL) {
153         TELEPHONY_LOGE("no data!");
154         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
155         return;
156     }
157     char *imeiSn = responseInfo->head->data;
158     if ((imeiSn == NULL) || (strlen(imeiSn) == 0)) {
159         TELEPHONY_LOGE("ReqGetImei: ResponseInfo is Invalid!");
160         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
161         return;
162     }
163     respDataAck.respDataPointer = (uint8_t *)imeiSn;
164     respDataAck.respDataLen = strlen(imeiSn);
165     ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_SUCCESS, &respDataAck);
166 }
167 
ReqGetImeiSv(const ReqDataInfo * requestInfo)168 void ReqGetImeiSv(const ReqDataInfo *requestInfo)
169 {
170     if (requestInfo == NULL) {
171         return;
172     }
173     ResponseInfo *responseInfo = NULL;
174     struct ReportInfo reportInfo;
175     reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_SUCCESS, HRIL_RESPONSE, 0);
176     OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
177     FreeResponseInfo(responseInfo);
178 }
179 
ReqGetMeid(const ReqDataInfo * requestInfo)180 void ReqGetMeid(const ReqDataInfo *requestInfo)
181 {
182     if (requestInfo == NULL) {
183         return;
184     }
185     int32_t err = HRIL_ERR_SUCCESS;
186     ResponseInfo *responseInfo = NULL;
187     TELEPHONY_LOGD("enter to [%{public}s]:%{public}d", __func__, __LINE__);
188     int32_t ret = SendCommandLock("AT+MEID", NULL, DEFAULT_TIMEOUT, &responseInfo);
189     struct ResponseAck respDataAck = { responseInfo, NULL, 0 };
190     if (responseInfo == NULL) {
191         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_NULL_POINT, &respDataAck);
192         return;
193     }
194     respDataAck.responseInfo = responseInfo;
195     if (ret != 0 || !responseInfo->success) {
196         err = GetResponseErrorCode(responseInfo);
197         TELEPHONY_LOGE("send AT CMD failed!");
198         ResponseModemReport(requestInfo->slotId, requestInfo, err, &respDataAck);
199         return;
200     }
201     if (responseInfo->head == NULL) {
202         TELEPHONY_LOGE("no data!");
203         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
204         return;
205     }
206     char *meidSn = responseInfo->head->data;
207     if ((meidSn == NULL) || (strlen(meidSn) == 0)) {
208         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
209         return;
210     }
211     respDataAck.respDataPointer = (uint8_t *)meidSn;
212     respDataAck.respDataLen = strlen(meidSn);
213     ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_SUCCESS, &respDataAck);
214 }
215 
ConvertVoiceTechToRadioTech(HRilVoiceSubMode subMode)216 static HRilRadioTech ConvertVoiceTechToRadioTech(HRilVoiceSubMode subMode)
217 {
218     switch (subMode) {
219         case HRIL_ACT_GSM:
220         case HRIL_ACT_GPRS:
221         case HRIL_ACT_EDGE:
222             return RADIO_TECHNOLOGY_GSM;
223         case HRIL_ACT_HSPA:
224         case HRIL_ACT_HSDPA:
225         case HRIL_ACT_HSUPA:
226             return RADIO_TECHNOLOGY_HSPA;
227         case HRIL_ACT_HSPAP:
228         case HRIL_ACT_DC_HSPAP:
229             return RADIO_TECHNOLOGY_HSPAP;
230         case HRIL_ACT_WCDMA:
231             return RADIO_TECHNOLOGY_WCDMA;
232         case HRIL_ACT_LTE:
233             return RADIO_TECHNOLOGY_LTE;
234         case HRIL_ACT_IS95A:
235         case HRIL_ACT_IS95B:
236         case HRIL_ACT_CDMA2000_1X:
237         case HRIL_ACT_HYBRID_CDMA2000_1X:
238             return RADIO_TECHNOLOGY_1XRTT;
239         case HRIL_ACT_EVDO_REL0:
240         case HRIL_ACT_EVDO_RELA:
241         case HRIL_ACT_EVDO_RELB:
242         case HRIL_ACT_HYBRID_EVDO_REL0:
243         case HRIL_ACT_HYBRID_EVDO_RELA:
244         case HRIL_ACT_HYBRID_EVDO_RELB:
245             return RADIO_TECHNOLOGY_EVDO;
246         case HRIL_ACT_TDSCDMA:
247             return RADIO_TECHNOLOGY_TD_SCDMA;
248         case HRIL_ACT_LTE_CA:
249             return RADIO_TECHNOLOGY_LTE_CA;
250         case HRIL_ACT_802_16E:
251             return RADIO_TECHNOLOGY_IWLAN;
252         case HRIL_ACT_NR:
253             return RADIO_TECHNOLOGY_NR;
254         default:
255             return RADIO_TECHNOLOGY_UNKNOWN;
256     }
257 }
258 
ProcessVoiceRadioInfo(const char * s,const HRilVoiceRadioInfo * hrilVoiceRadioInfo)259 int32_t ProcessVoiceRadioInfo(const char *s, const HRilVoiceRadioInfo *hrilVoiceRadioInfo)
260 {
261     int32_t srvStatus = 0;
262     int32_t srvDomain = 0;
263     int32_t roamStatus = 0;
264     int32_t simStatus = 0;
265     int32_t lockStatus = 0;
266     int32_t sysMode = 0;
267     int32_t actType = 0;
268     char *str = (char *)s;
269     HRilVoiceRadioInfo *voiceRadioInfo = (HRilVoiceRadioInfo *)hrilVoiceRadioInfo;
270     if ((str == NULL) || (voiceRadioInfo == NULL)) {
271         TELEPHONY_LOGE("ProcessVoiceRadioInfo s or voiceRadioInfo param is null");
272         return HRIL_ERR_NULL_POINT;
273     } else {
274         (void)memset_s(voiceRadioInfo, sizeof(HRilVoiceRadioInfo), 0, sizeof(HRilVoiceRadioInfo));
275         TELEPHONY_LOGD("result: %{public}s", str);
276         int32_t err = SkipATPrefix(&str);
277         if (err < 0) {
278             TELEPHONY_LOGE("skip failed: [%{public}s]", str);
279             return HRIL_ERR_INVALID_RESPONSE;
280         }
281         int32_t commaNum = FindCommaCharNum(str);
282         const int32_t VOICE_COMMA_NUM = 8;
283         if (commaNum != VOICE_COMMA_NUM) {
284             TELEPHONY_LOGE("ProcessVoiceRadioInfo failed commaNum: [%{public}d]", commaNum);
285             return HRIL_ERR_INVALID_RESPONSE;
286         }
287         NextIntNotSkipNextComma(&str, &srvStatus);
288         voiceRadioInfo->srvStatus = srvStatus;
289         NextIntNotSkipNextComma(&str, &srvDomain);
290         voiceRadioInfo->srvDomain = srvDomain;
291         NextIntNotSkipNextComma(&str, &roamStatus);
292         voiceRadioInfo->roamStatus = roamStatus;
293         NextIntNotSkipNextComma(&str, &simStatus);
294         voiceRadioInfo->simStatus = simStatus;
295         if (NextIntNotSkipNextComma(&str, &lockStatus) < 0) {
296             voiceRadioInfo->lockStatus = 0;
297         } else {
298             voiceRadioInfo->lockStatus = lockStatus;
299         }
300         NextIntNotSkipNextComma(&str, &sysMode);
301         voiceRadioInfo->sysMode = sysMode;
302         NextStr(&str, &(voiceRadioInfo->sysModeName));
303         NextIntNotSkipNextComma(&str, &actType);
304         voiceRadioInfo->actType = ConvertVoiceTechToRadioTech((HRilVoiceSubMode)actType);
305         NextStr(&str, &(voiceRadioInfo->actName));
306         return HRIL_ERR_SUCCESS;
307     }
308 }
309 
ReqGetVoiceRadioTechnology(const ReqDataInfo * requestInfo)310 void ReqGetVoiceRadioTechnology(const ReqDataInfo *requestInfo)
311 {
312     if (requestInfo == NULL) {
313         return;
314     }
315     int32_t err = HRIL_ERR_SUCCESS;
316     struct ReportInfo reportInfo;
317     ResponseInfo *responseInfo = NULL;
318     char *result = NULL;
319     int32_t ret = SendCommandLock("AT^SYSINFOEX", "^SYSINFOEX:", DEFAULT_TIMEOUT, &responseInfo);
320     if (responseInfo == NULL) {
321         TELEPHONY_LOGE("responseInfo is nullptr!");
322         reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_NULL_POINT, HRIL_RESPONSE, 0);
323         OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
324         return;
325     }
326     if (ret != 0 || !responseInfo->success) {
327         err = GetResponseErrorCode(responseInfo);
328         TELEPHONY_LOGE("send AT CMD failed!");
329     }
330     HRilVoiceRadioInfo voiceRadioInfo = {0};
331     if (responseInfo->head != NULL) {
332         result = responseInfo->head->data;
333     }
334     ret = ProcessVoiceRadioInfo(result, &voiceRadioInfo);
335     if (ret != 0) {
336         TELEPHONY_LOGE("ProcessVoiceRadioInfo format  unexpected: %{public}s", result);
337         reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_INVALID_RESPONSE, HRIL_RESPONSE, 0);
338         OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
339         FreeResponseInfo(responseInfo);
340         return;
341     }
342     reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
343     OnModemReport(requestInfo->slotId, reportInfo, (const uint8_t *)&voiceRadioInfo, sizeof(HRilVoiceRadioInfo));
344     FreeResponseInfo(responseInfo);
345 }
346