• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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->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 
ReqGetMeid(const ReqDataInfo * requestInfo)168 void ReqGetMeid(const ReqDataInfo *requestInfo)
169 {
170     if (requestInfo == NULL) {
171         return;
172     }
173     int32_t err = HRIL_ERR_SUCCESS;
174     ResponseInfo *responseInfo = NULL;
175     TELEPHONY_LOGD("enter to [%{public}s]:%{public}d", __func__, __LINE__);
176     int32_t ret = SendCommandLock("AT+MEID", NULL, DEFAULT_TIMEOUT, &responseInfo);
177     struct ResponseAck respDataAck = { responseInfo, NULL, 0 };
178     if (responseInfo == NULL) {
179         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_NULL_POINT, &respDataAck);
180         return;
181     }
182     respDataAck.responseInfo = responseInfo;
183     if (ret != 0 || !responseInfo->success) {
184         err = GetResponseErrorCode(responseInfo);
185         TELEPHONY_LOGE("send AT CMD failed!");
186         ResponseModemReport(requestInfo->slotId, requestInfo, err, &respDataAck);
187         return;
188     }
189     if (responseInfo->head == NULL) {
190         TELEPHONY_LOGE("no data!");
191         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
192         return;
193     }
194     char *meidSn = responseInfo->head->data;
195     if ((meidSn == NULL) || (strlen(meidSn) == 0)) {
196         ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_INVALID_RESPONSE, &respDataAck);
197         return;
198     }
199     respDataAck.respDataPointer = (uint8_t *)meidSn;
200     respDataAck.respDataLen = strlen(meidSn);
201     ResponseModemReport(requestInfo->slotId, requestInfo, HRIL_ERR_SUCCESS, &respDataAck);
202 }
203 
ConvertVoiceTechToRadioTech(HRilVoiceSubMode subMode)204 static HRilRadioTech ConvertVoiceTechToRadioTech(HRilVoiceSubMode subMode)
205 {
206     switch (subMode) {
207         case HRIL_ACT_GSM:
208         case HRIL_ACT_GPRS:
209         case HRIL_ACT_EDGE:
210             return RADIO_TECHNOLOGY_GSM;
211         case HRIL_ACT_HSPA:
212         case HRIL_ACT_HSDPA:
213         case HRIL_ACT_HSUPA:
214             return RADIO_TECHNOLOGY_HSPA;
215         case HRIL_ACT_HSPAP:
216         case HRIL_ACT_DC_HSPAP:
217             return RADIO_TECHNOLOGY_HSPAP;
218         case HRIL_ACT_WCDMA:
219             return RADIO_TECHNOLOGY_WCDMA;
220         case HRIL_ACT_LTE:
221             return RADIO_TECHNOLOGY_LTE;
222         case HRIL_ACT_IS95A:
223         case HRIL_ACT_IS95B:
224         case HRIL_ACT_CDMA2000_1X:
225         case HRIL_ACT_HYBRID_CDMA2000_1X:
226             return RADIO_TECHNOLOGY_1XRTT;
227         case HRIL_ACT_EVDO_REL0:
228         case HRIL_ACT_EVDO_RELA:
229         case HRIL_ACT_EVDO_RELB:
230         case HRIL_ACT_HYBRID_EVDO_REL0:
231         case HRIL_ACT_HYBRID_EVDO_RELA:
232         case HRIL_ACT_HYBRID_EVDO_RELB:
233             return RADIO_TECHNOLOGY_EVDO;
234         case HRIL_ACT_TDSCDMA:
235             return RADIO_TECHNOLOGY_TD_SCDMA;
236         case HRIL_ACT_LTE_CA:
237             return RADIO_TECHNOLOGY_LTE_CA;
238         case HRIL_ACT_802_16E:
239             return RADIO_TECHNOLOGY_IWLAN;
240         case HRIL_ACT_NR:
241             return RADIO_TECHNOLOGY_NR;
242         default:
243             return RADIO_TECHNOLOGY_UNKNOWN;
244     }
245 }
246 
ProcessVoiceRadioInfo(const char * s,const HRilVoiceRadioInfo * hrilVoiceRadioInfo)247 int32_t ProcessVoiceRadioInfo(const char *s, const HRilVoiceRadioInfo *hrilVoiceRadioInfo)
248 {
249     int32_t srvStatus = 0;
250     int32_t srvDomain = 0;
251     int32_t roamStatus = 0;
252     int32_t simStatus = 0;
253     int32_t lockStatus = 0;
254     int32_t sysMode = 0;
255     int32_t actType = 0;
256     char *str = (char *)s;
257     HRilVoiceRadioInfo *voiceRadioInfo = (HRilVoiceRadioInfo *)hrilVoiceRadioInfo;
258     if ((str == NULL) || (voiceRadioInfo == NULL)) {
259         TELEPHONY_LOGE("ProcessVoiceRadioInfo s or voiceRadioInfo param is null");
260         return HRIL_ERR_NULL_POINT;
261     } else {
262         (void)memset_s(voiceRadioInfo, sizeof(HRilVoiceRadioInfo), 0, sizeof(HRilVoiceRadioInfo));
263         TELEPHONY_LOGD("result: %{public}s", str);
264         int32_t err = SkipATPrefix(&str);
265         if (err < 0) {
266             TELEPHONY_LOGE("skip failed: [%{public}s]", str);
267             return HRIL_ERR_INVALID_RESPONSE;
268         }
269         int32_t commaNum = FindCommaCharNum(str);
270         const int32_t VOICE_COMMA_NUM = 8;
271         if (commaNum != VOICE_COMMA_NUM) {
272             TELEPHONY_LOGE("ProcessVoiceRadioInfo failed commaNum: [%{public}d]", commaNum);
273             return HRIL_ERR_INVALID_RESPONSE;
274         }
275         NextIntNotSkipNextComma(&str, &srvStatus);
276         voiceRadioInfo->srvStatus = srvStatus;
277         NextIntNotSkipNextComma(&str, &srvDomain);
278         voiceRadioInfo->srvDomain = srvDomain;
279         NextIntNotSkipNextComma(&str, &roamStatus);
280         voiceRadioInfo->roamStatus = roamStatus;
281         NextIntNotSkipNextComma(&str, &simStatus);
282         voiceRadioInfo->simStatus = simStatus;
283         if (NextIntNotSkipNextComma(&str, &lockStatus) < 0) {
284             voiceRadioInfo->lockStatus = 0;
285         } else {
286             voiceRadioInfo->lockStatus = lockStatus;
287         }
288         NextIntNotSkipNextComma(&str, &sysMode);
289         voiceRadioInfo->sysMode = sysMode;
290         NextStr(&str, &(voiceRadioInfo->sysModeName));
291         NextIntNotSkipNextComma(&str, &actType);
292         voiceRadioInfo->actType = ConvertVoiceTechToRadioTech((HRilVoiceSubMode)actType);
293         NextStr(&str, &(voiceRadioInfo->actName));
294         return HRIL_ERR_SUCCESS;
295     }
296 }
297 
ReqGetVoiceRadioTechnology(const ReqDataInfo * requestInfo)298 void ReqGetVoiceRadioTechnology(const ReqDataInfo *requestInfo)
299 {
300     if (requestInfo == NULL) {
301         return;
302     }
303     int32_t err = HRIL_ERR_SUCCESS;
304     struct ReportInfo reportInfo;
305     ResponseInfo *responseInfo = NULL;
306     char *result = NULL;
307     int32_t ret = SendCommandLock("AT^SYSINFOEX", "^SYSINFOEX:", DEFAULT_TIMEOUT, &responseInfo);
308     if (responseInfo == NULL) {
309         TELEPHONY_LOGE("responseInfo is nullptr!");
310         reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_NULL_POINT, HRIL_RESPONSE, 0);
311         OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
312         return;
313     }
314     if (ret != 0 || !responseInfo->success) {
315         err = GetResponseErrorCode(responseInfo);
316         TELEPHONY_LOGE("send AT CMD failed!");
317     }
318     HRilVoiceRadioInfo voiceRadioInfo = {0};
319     if (responseInfo->head != NULL) {
320         result = responseInfo->head->data;
321     }
322     ret = ProcessVoiceRadioInfo(result, &voiceRadioInfo);
323     if (ret != 0) {
324         TELEPHONY_LOGE("ProcessVoiceRadioInfo format  unexpected: %{public}s", result);
325         reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_INVALID_RESPONSE, HRIL_RESPONSE, 0);
326         OnModemReport(requestInfo->slotId, reportInfo, NULL, 0);
327         FreeResponseInfo(responseInfo);
328         return;
329     }
330     reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
331     OnModemReport(requestInfo->slotId, reportInfo, (const uint8_t *)&voiceRadioInfo, sizeof(HRilVoiceRadioInfo));
332     FreeResponseInfo(responseInfo);
333 }
334