• 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 "vendor_util.h"
17 
18 #include <stdlib.h>
19 
20 #include "parameter.h"
21 
22 #define NS_PER_S 1000000000
23 #define COUNT 1000
24 
25 #define SUPPORT_SLOT_ID "persist.sys.support.slotid"
26 #define DEFAULT_SLOT_COUNT "1"
27 #define TEL_SIM_SLOT_COUNT "const.telephony.slotCount"
28 
29 const int32_t G_RESP_ERRORS = 7;
30 const int32_t G_RESP_SUCCESS = 2;
31 const int32_t G_RESP_SMS_NOTIFY = 3;
32 const int32_t G_CHAR_TO_INT = 10;
33 static const char *g_respErrors[G_RESP_ERRORS] = {
34     "ERROR", "NO ANSWER", "+CME ERROR:", "NO CARRIER", "NO DIALTONE", "+CMS ERROR:", "COMMAND NOT SUPPORT"};
35 
36 static const char *g_respSuccess[G_RESP_SUCCESS] = {"OK", "CONNECT"};
37 
38 static const char *g_respSmsNotify[G_RESP_SMS_NOTIFY] = {"+CMT:", "+CDS:", "+CBM:"};
39 
40 enum CommonNumber {
41     HRIL_DEC = 10,
42     HRIL_HEX = 16,
43 };
44 
GenerateCommand(char * buffer,size_t bufferLen,const char * fmt,...)45 int32_t GenerateCommand(char *buffer, size_t bufferLen, const char *fmt, ...)
46 {
47     int32_t ret;
48     va_list va;
49 
50     va_start(va, fmt);
51     ret = vsprintf_s(buffer, bufferLen, fmt, va);
52     va_end(va);
53 
54     return ret;
55 }
56 
ReportStrWith(const char * s,const char * prefix)57 int32_t ReportStrWith(const char *s, const char *prefix)
58 {
59     const char *source = s;
60     const char *dest = prefix;
61     if (prefix == NULL || s == NULL) {
62         TELEPHONY_LOGE("str or prefix parameter is null.");
63         return 0;
64     }
65     for (; *source != '\0' && *dest != '\0'; source++, dest++) {
66         if (*source != *dest) {
67             return 0;
68         }
69     }
70     return *dest == '\0';
71 }
72 
IsResponseSuccess(const char * s)73 int32_t IsResponseSuccess(const char *s)
74 {
75     size_t i;
76     for (i = 0; i < G_RESP_SUCCESS; i++) {
77         if (ReportStrWith(s, g_respSuccess[i])) {
78             return 1;
79         }
80     }
81     return 0;
82 }
83 
IsResponseError(const char * s)84 int32_t IsResponseError(const char *s)
85 {
86     size_t i;
87     for (i = 0; i < G_RESP_ERRORS; i++) {
88         if (ReportStrWith(s, g_respErrors[i])) {
89             return 1;
90         }
91     }
92     return 0;
93 }
94 
IsSms(const char * s)95 int32_t IsSms(const char *s)
96 {
97     if (s[0] == '>') {
98         return 1;
99     }
100     return 0;
101 }
102 
IsSmsNotify(const char * s)103 int32_t IsSmsNotify(const char *s)
104 {
105     size_t i;
106     for (i = 0; i < G_RESP_SMS_NOTIFY; i++) {
107         if (ReportStrWith(s, g_respSmsNotify[i])) {
108             return 1;
109         }
110     }
111     return 0;
112 }
113 
SetWaitTimeout(struct timespec * time,long long msec)114 void SetWaitTimeout(struct timespec *time, long long msec)
115 {
116     struct timeval now;
117     long def = 1000L;
118     gettimeofday(&now, (struct timezone *)NULL);
119     time->tv_nsec = (now.tv_usec + (msec % COUNT) * def) * def;
120     time->tv_sec = now.tv_sec + (msec / COUNT);
121     if (time->tv_nsec >= NS_PER_S) {
122         time->tv_nsec -= NS_PER_S;
123         time->tv_sec++;
124     }
125 }
126 
SkipATPrefix(char ** s)127 int32_t SkipATPrefix(char **s)
128 {
129     if (*s == NULL) {
130         TELEPHONY_LOGE("str parameter is null.");
131         return -1;
132     }
133     *s = strchr(*s, ':');
134     if (*s == NULL) {
135         TELEPHONY_LOGE("str parameter is null.");
136         return -1;
137     }
138     (*s)++;
139     return 0;
140 }
141 
SkipSpace(char ** s)142 void SkipSpace(char **s)
143 {
144     if (*s == NULL) {
145         TELEPHONY_LOGE("str parameter is null.");
146         return;
147     }
148     while (**s != '\0' && **s == ' ') {
149         (*s)++;
150     }
151 }
152 
NextInt(char ** s,int32_t * out)153 int32_t NextInt(char **s, int32_t *out)
154 {
155     char *ret = NULL;
156     char *end = NULL;
157     if (*s == NULL) {
158         TELEPHONY_LOGE("str parameter is null.");
159         return -1;
160     }
161     SkipSpace(s);
162     if (*s == NULL) {
163         TELEPHONY_LOGE("str parameter is null, after skip space.");
164         return -1;
165     }
166     ret = strsep(s, ",");
167     while (*s != NULL && **s == ',') {
168         (*s)++;
169     }
170     *out = (int32_t)strtol(ret, &end, HRIL_DEC);
171     if (ret == end) {
172         TELEPHONY_LOGE("strtol is fail, err:%{public}d", *out);
173         return -1;
174     }
175     return 0;
176 }
177 
NextInt64(char ** s,int64_t * out)178 int64_t NextInt64(char **s, int64_t *out)
179 {
180     char *ret = NULL;
181     char *end = NULL;
182     if (*s == NULL) {
183         TELEPHONY_LOGE("str parameter is null.");
184         return -1;
185     }
186     SkipSpace(s);
187     if (*s == NULL) {
188         TELEPHONY_LOGE("str parameter is null, after skip space.");
189         return -1;
190     }
191     ret = strsep(s, ",");
192     while (*s != NULL && **s == ',') {
193         (*s)++;
194     }
195     *out = (int64_t)strtoll(ret, &end, HRIL_DEC);
196     if (ret == end) {
197         TELEPHONY_LOGE("NextInt64 strtoll is fail");
198         return -1;
199     }
200     return 0;
201 }
202 
NextIntNotSkipNextComma(char ** s,int32_t * out)203 int32_t NextIntNotSkipNextComma(char **s, int32_t *out)
204 {
205     char *ret = NULL;
206     char *end = NULL;
207     if (*s == NULL) {
208         TELEPHONY_LOGE("str parameter is null.");
209         return -1;
210     }
211     SkipSpace(s);
212     if (*s == NULL) {
213         TELEPHONY_LOGE("str parameter is null, after skip space.");
214         return -1;
215     }
216     ret = strsep(s, ",");
217     *out = (int32_t)strtol(ret, &end, HRIL_DEC);
218     if (ret == end) {
219         TELEPHONY_LOGE("strtol is fail, err:%{public}d", *out);
220         return -1;
221     }
222     return 0;
223 }
224 
NextIntByRightBracket(char ** s,int32_t * out)225 int32_t NextIntByRightBracket(char **s, int32_t *out)
226 {
227     char *ret = NULL;
228     char *end = NULL;
229     if (*s == NULL) {
230         TELEPHONY_LOGE("str parameter is null.");
231         return -1;
232     }
233     SkipSpace(s);
234     if (*s == NULL) {
235         TELEPHONY_LOGE("str parameter is null, after skip space.");
236         return -1;
237     }
238     ret = strsep(s, ")");
239     while (*s != NULL && **s == ')') {
240         (*s)++;
241     }
242     *out = (int32_t)strtol(ret, &end, HRIL_DEC);
243     if (ret == end) {
244         TELEPHONY_LOGE("strtol is fail, err:%{public}d", *out);
245         return -1;
246     }
247     return 0;
248 }
249 
SkipNextComma(char ** s)250 void SkipNextComma(char **s)
251 {
252     if (*s == NULL) {
253         TELEPHONY_LOGE("str parameter is null.");
254         return;
255     }
256     while (**s != '\0' && **s != ',') {
257         (*s)++;
258     }
259     if (**s == ',') {
260         (*s)++;
261     }
262 }
263 
NextIntFromHex(char ** s,int32_t * out)264 int32_t NextIntFromHex(char **s, int32_t *out)
265 {
266     char *ret = NULL;
267     char *end = NULL;
268     if (*s == NULL) {
269         TELEPHONY_LOGE("str parameter is null.");
270         return -1;
271     }
272     SkipSpace(s);
273     if (*s == NULL) {
274         TELEPHONY_LOGE("str parameter is null, after skip space.");
275         return -1;
276     } else if (**s == '"') {
277         (*s)++;
278         ret = strsep(s, "\"");
279         SkipNextComma(s);
280     } else {
281         ret = strsep(s, ",");
282     }
283     *out = (int32_t)strtol(ret, &end, HRIL_HEX);
284     if (ret == end) {
285         TELEPHONY_LOGE("strtol is fail, err:%{public}d", *out);
286         return -1;
287     }
288     return 0;
289 }
290 
NextULongFromHex(char ** s,uint64_t * out)291 uint64_t NextULongFromHex(char **s, uint64_t *out)
292 {
293     char *ret = NULL;
294     char *end = NULL;
295     if (*s == NULL) {
296         TELEPHONY_LOGE("str parameter is null.");
297         return -1;
298     }
299     SkipSpace(s);
300     if (*s == NULL) {
301         TELEPHONY_LOGE("str parameter is null, after skip space.");
302         return -1;
303     } else if (**s == '"') {
304         (*s)++;
305         ret = strsep(s, "\"");
306         SkipNextComma(s);
307     } else {
308         ret = strsep(s, ",");
309     }
310     *out = (uint64_t)strtoul(ret, &end, HRIL_HEX);
311     if (ret == end) {
312         TELEPHONY_LOGE("strtoul is fail");
313         return -1;
314     }
315     return 0;
316 }
317 
NextStr(char ** s,char ** out)318 int32_t NextStr(char **s, char **out)
319 {
320     if (*s == NULL) {
321         TELEPHONY_LOGE("str parameter is null.");
322         return -1;
323     }
324     SkipSpace(s);
325     if (*s == NULL) {
326         TELEPHONY_LOGE("str parameter is null, after skip space.");
327         return -1;
328     } else if (**s == '"') {
329         (*s)++;
330         *out = strsep(s, "\"");
331         SkipNextComma(s);
332     } else {
333         *out = strsep(s, ",");
334     }
335     return 0;
336 }
337 
338 /* +CRING: GPRS "IP","00.00.00.00",,"abc.com"
339  * get GPRS
340  */
NextTxtStr(char ** s,char ** out)341 int32_t NextTxtStr(char **s, char **out)
342 {
343     if (*s == NULL) {
344         TELEPHONY_LOGE("str parameter is null.");
345         return -1;
346     }
347     SkipSpace(s);
348     if (*s == NULL) {
349         TELEPHONY_LOGE("str parameter is null, after skip space.");
350         return -1;
351     } else {
352         *out = strsep(s, " ");
353     }
354     return 0;
355 }
356 
NextBool(char ** s,char * out)357 int32_t NextBool(char **s, char *out)
358 {
359     int32_t ret;
360     int32_t result;
361 
362     if (*s == NULL) {
363         TELEPHONY_LOGE("str parameter is null.");
364         return -1;
365     }
366     ret = NextInt(s, &result);
367     if (ret < 0) {
368         TELEPHONY_LOGE("NextInt is fail, ret:%{public}d", ret);
369         return -1;
370     }
371     // booleans should be 0 or 1
372     if (!(result == 0 || result == 1)) {
373         TELEPHONY_LOGE("booleans should be 0 or 1, result:%{public}d", result);
374         return -1;
375     }
376     if (out != NULL) {
377         *out = (char)result;
378     }
379     return ret;
380 }
381 
ParseReportError(char * str)382 int32_t ParseReportError(char *str)
383 {
384     int32_t ret = VENDOR_FAIL;
385     char *pStr = str;
386 
387     if (pStr == NULL) {
388         TELEPHONY_LOGE("str parameter is null.");
389         return ret;
390     }
391     if (!SkipATPrefix(&pStr)) {
392         NextInt(&pStr, &ret);
393     }
394     return ret;
395 }
396 
GetReportErrorInfo(const ResponseInfo * response)397 ModemReportErrorInfo GetReportErrorInfo(const ResponseInfo *response)
398 {
399     int32_t ret = VENDOR_FAIL;
400     ModemReportErrorInfo errInfo;
401 
402     errInfo.errType = HRIL_REPORT_ERR_TYPE_GENERIC;
403     errInfo.errorNo = HRIL_ERR_GENERIC_FAILURE;
404     if ((response != NULL) && (!response->success)) {
405         char *pStr = response->result;
406         if (ReportStrWith(pStr, "+CME ERROR:")) {
407             errInfo.errType = HRIL_REPORT_ERR_TYPE_CME;
408         } else if (ReportStrWith(pStr, "+CMS ERROR:")) {
409             errInfo.errType = HRIL_REPORT_ERR_TYPE_CMS;
410         } else {
411             return errInfo;
412         }
413         ret = ParseReportError(pStr);
414         if (ret > 0) {
415             errInfo.errorNo = ret;
416         }
417     }
418     return errInfo;
419 }
420 
InitModemReportErrorInfo(void)421 ModemReportErrorInfo InitModemReportErrorInfo(void)
422 {
423     ModemReportErrorInfo errInfo;
424 
425     errInfo.errorNo = HRIL_ERR_SUCCESS;
426     errInfo.errType = HRIL_REPORT_ERR_TYPE_NONE;
427     return errInfo;
428 }
429 
ConvertCharToInt32(const char * s)430 int32_t ConvertCharToInt32(const char *s)
431 {
432     char *str = (char *)s;
433     int32_t ret = 0;
434     char firstChar = *str;
435     if ((firstChar == '+') || (firstChar == '-')) {
436         ++str;
437     }
438     while (*str == '0') {
439         ++str;
440     }
441     while (*str) {
442         char tmp = *str;
443         if ((*str < '0') || (*str > '9')) {
444             return ret;
445         } else {
446             int32_t val = (int32_t)(tmp - '0');
447             ret = (ret * G_CHAR_TO_INT) + val;
448         }
449         str++;
450     }
451     if (firstChar == '-') {
452         ret = -ret;
453     }
454     return ret;
455 }
456 
FindCommaCharNum(const char * srcStr)457 int32_t FindCommaCharNum(const char *srcStr)
458 {
459     char *str = (char *)srcStr;
460     if (str == NULL) {
461         TELEPHONY_LOGE("srcStr parameter is null.");
462         return -1;
463     }
464     if (*str == '\0') {
465         return -1;
466     }
467     int32_t charNum = 0;
468     while (*str != '\0') {
469         if (*str == ',') {
470             charNum++;
471         }
472         str++;
473     }
474     return charNum;
475 }
476 
GetSimSlotCount(void)477 int32_t GetSimSlotCount(void)
478 {
479     char simSlotCount[PARAMETER_SIZE] = {0};
480     GetParameter(TEL_SIM_SLOT_COUNT, DEFAULT_SLOT_COUNT, simSlotCount, PARAMETER_SIZE);
481     return atoi(simSlotCount);
482 }
483 
GetSlotId(const ReqDataInfo * requestInfo)484 int32_t GetSlotId(const ReqDataInfo *requestInfo)
485 {
486     int32_t slotId = HRIL_SIM_SLOT_0;
487     char strSlotId[PARAMETER_SIZE] = {0};
488 
489     if (requestInfo != NULL) {
490         slotId = requestInfo->slotId;
491     } else { // proactive notification
492         if (GetParameter(SUPPORT_SLOT_ID, "", strSlotId, PARAMETER_SIZE) > 0) {
493             slotId = atoi(strSlotId);
494         }
495     }
496     if (slotId >= GetSimSlotCount()) {
497         slotId = HRIL_SIM_SLOT_0;
498         TELEPHONY_LOGE("slotId is invalid, slotId0 will be used. slotId:%{public}d", slotId);
499     }
500     return slotId;
501 }