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