blob: 6e44f7c86d5a2cf258d6f29604a1123797a6d56b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2*(C) Copyright 2014 Marvell International Ltd.
3* All Rights Reserved
4******************************************************************************/
5/* -------------------------------------------------------------------------------------------------------------------
6 *
7 * Filename: mbim_util.c
8 *
9 * Authors: Adrian Zelezniak
10 *
11 * Description: all utiliy functions and macros needed for the MIBM translator
12 *
13 * HISTORY:
14 * Jan 7, 2014 - Initial Version
15 *
16 * Notes:
17 *
18 ******************************************************************************/
19
20#define LOG_TAG "MBIM"
21
22/******************************************************************************
23 * Include files
24 ******************************************************************************/
25#include <stdio.h>
26#include <stdlib.h>
27#include <uci.h>
28
29#include "mbim_types.h"
30#include "mbim_protocol.h"
31#include "mbim_util.h"
32#include "mbim_basic.h"
33#include "mbim_sms.h"
34#include "mbim_basic_extension.h"
35#if defined MBIM_MTIL
36#include "mbim_mtil.h"
37#else
38#include "mbim_ril.h"
39#endif
40
41/******************************************************************************
42 * Defines
43 ******************************************************************************/
44//#define LOG_BUF_SIZE 1024
45
46/******************************************************************************
47 * Enums
48 ******************************************************************************/
49
50
51/******************************************************************************
52 * Macros
53 ******************************************************************************/
54
55#define UUID_COMPARE(a,b) memcmp(a,b,16)
56#define UUID_COPY(a,b) memcpy(a,b,16)
57
58
59
60/******************************************************************************
61 * External variables
62 ******************************************************************************/
63extern MBIM_DATABASE mbimDb;
64
65
66
67/******************************************************************************
68 * Function prototypes
69 ******************************************************************************/
70static void trim(char *buffer);
71
72#if defined MBIM_MTIL
73extern int DeletePdp(P_MBIM_MESSAGE_CONTEXT pContext, int cid);
74#endif
75
76/******************************************************************************
77 * Code
78 ******************************************************************************/
79
80#if defined SYSLOG
81extern int slogFd;
82inline void __mbim_log_print(int prio, const char *tag, const char *fmt, ...)
83{
84 va_list ap;
85 char buf[LOG_BUF_SIZE];
86 int write_length;
87
88#if 0
89 FILE *fdbg;
90
91 if (!mbimDb.debug_enable)
92 return 0;
93#endif
94 if (prio < ANDROID_LOG_VERBOSE)
95 {
96 return;
97 }
98
99 write_length = snprintf(buf,LOG_BUF_SIZE,"%s: ",tag);
100 if (write_length != 0)
101 {
102 va_start(ap, fmt);
103 write_length += vsnprintf(&buf[write_length], LOG_BUF_SIZE, fmt, ap);
104 va_end(ap);
105 buf[write_length++] = '\n';
106 buf[write_length++] = '\r';
107#if 0
108 if ((fdbg = fopen("/tmp/mbimdebug", "r")) != NULL)
109 {
110 fclose(fdbg);
111 printf(buf);
112 }
113 else
114 syslog(0,buf);
115#endif
116 if (slogFd < 0)
117 slogFd = open("/dev/kmsg", O_RDWR | O_SYNC);
118 if (slogFd >= 0)
119 write(slogFd, buf, write_length);
120 }
121
122 return;
123}
124#endif
125
126
127/*******************************************************************************\
128* Function: logReceivedMbimMsg
129* Description: This function records the received command and Transaction Id
130* Parameters: int commandNum - The type of MBIM message received
131* int transId - This is the unique transaction ID for this command
132*
133* Returns:
134\*******************************************************************************/
135void logReceivedMbimMsg(UINT32 msgId, UINT32 transId)
136{
137 char message[20];
138 switch(msgId)
139 {
140 case MBIM_OPEN_MSG_E:
141 sprintf(message, "OPEN");
142 break;
143 case MBIM_CLOSE_MSG_E:
144 sprintf(message, "CLOSE");
145 break;
146 case MBIM_COMMAND_MSG_E:
147 sprintf(message, "COMMAND");
148 break;
149 case MBIM_HOST_ERROR_MSG_E:
150 sprintf(message, "HOST ERROR");
151 break;
152 default:
153 sprintf(message, "UNKNOWN");
154 break;
155 }
156 MBIM_LOGD("Process %s message: MBIM State = %d, TransId = %d", message, mbimDb.open, transId);
157
158}
159
160/*******************************************************************************\
161* Function: logSentMbimMsg
162* Description: This function records the sent command and Transaction Id
163* Parameters: char *msg --> Pointer to the MBIM Header
164*
165* Returns:
166\*******************************************************************************/
167void logSentMbimMsg(char *msg)
168{
169 P_MBIM_MESSAGE_HEADER mbimHdr_p = (P_MBIM_MESSAGE_HEADER)msg;
170 P_MBIM_COMMAND_DONE commandDone_p = (P_MBIM_COMMAND_DONE)msg;
171 P_MBIM_INDICATION_STATUS_MSG indicationMsg_p = (P_MBIM_INDICATION_STATUS_MSG)msg;
172 char rsp[20];
173
174 if (msg != NULL)
175 {
176 switch(mbimHdr_p->messageType)
177 {
178 case MBIM_OPEN_DONE_E:
179 sprintf(rsp, "OPEN DONE");
180 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
181 break;
182 case MBIM_CLOSE_DONE_E:
183 sprintf(rsp, "CLOSE DONE");
184 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
185 break;
186 case MBIM_COMMAND_DONE_E:
187 sprintf(rsp, "COMMAND DONE");
188 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d, CID = %d", rsp, mbimDb.open, mbimHdr_p->transactionId, commandDone_p->cid);
189 break;
190 case MBIM_FUNCTION_ERROR_MSG_E:
191 sprintf(rsp, "FUNCTION ERROR");
192 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
193 break;
194 case MBIM_INDICATE_STATUS_MSG_E:
195 sprintf(rsp, "INDICATION STATUS");
196 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d, CID = %d", rsp, mbimDb.open, mbimHdr_p->transactionId, indicationMsg_p->cid);
197 break;
198 default:
199 sprintf(rsp, "UNKNOWN");
200 MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
201 break;
202 }
203
204 }
205 else
206 MBIM_LOGE("Trying to send a NULL response to MBIM");
207
208}
209
210
211
212/*******************************************************************************\
213* Function: UUID2Index
214* Description: Convert UUID to index
215* Parameters: P_MBIM_UUID uuid - This is a pointer to the 16 bytes UUID
216* Returns: index
217\*******************************************************************************/
218//{a1a2a3a4-b1b2-c1c2-d1d2-e1e2e3e4e5e6} UUID indianess
219int UUID2Index (P_MBIM_UUID uuid_p)
220{
221 int index = -1;
222
223 if ( UUID_COMPARE(uuid_p, UUID_BASIC_CONNECT) == 0 )
224 index = UUID_BASIC_CONNECT_INDEX;
225 else if ( UUID_COMPARE(uuid_p, UUID_SMS) == 0 )
226 index = UUID_SMS_INDEX;
227 else if ( UUID_COMPARE(uuid_p, UUID_USSD) == 0 )
228 index = UUID_USSD_INDEX;
229 else if ( UUID_COMPARE(uuid_p, UUID_PHONEBOOK) == 0 )
230 index = UUID_PHONEBOOK_INDEX;
231 else if ( UUID_COMPARE(uuid_p, UUID_STK) == 0 )
232 index = UUID_STK_INDEX;
233 else if ( UUID_COMPARE(uuid_p, UUID_AUTH) == 0 )
234 index = UUID_AUTH_INDEX;
235 else if ( UUID_COMPARE(uuid_p, UUID_DSS) == 0 )
236 index = UUID_DSS_INDEX;
237 else if ( UUID_COMPARE(uuid_p, UUID_BASIC_CONNECT_EXTENSIONS) == 0 )
238 index = UUID_BASIC_CONNECT_EXTENSIONS_INDEX;
239 return index;
240}
241
242
243
244/*******************************************************************************\
245* Function: Index2UUID
246* Description: Convert index to UUID
247* Parameters: P_MBIM_UUID uuid - This is a pointer to the 16 bytes UUID
248* int uuidIndex - The index of the UUID in our code
249* Returns: int - Error Value
250\*******************************************************************************/
251//{a1a2a3a4-b1b2-c1c2-d1d2-e1e2e3e4e5e6} UUID indianess
252int Index2UUID (P_MBIM_UUID uuid_p, int uuidIndex)
253{
254 int ret = MBIM_OK;
255
256 switch(uuidIndex)
257 {
258 case UUID_BASIC_CONNECT_INDEX:
259 UUID_COPY(uuid_p, UUID_BASIC_CONNECT);
260 break;
261 case UUID_SMS_INDEX:
262 UUID_COPY(uuid_p, UUID_SMS);
263 break;
264 case UUID_USSD_INDEX:
265 UUID_COPY(uuid_p, UUID_USSD);
266 break;
267 case UUID_PHONEBOOK_INDEX:
268 UUID_COPY(uuid_p, UUID_PHONEBOOK);
269 break;
270 case UUID_STK_INDEX:
271 UUID_COPY(uuid_p, UUID_STK);
272 break;
273 case UUID_AUTH_INDEX:
274 UUID_COPY(uuid_p, UUID_AUTH);
275 break;
276 case UUID_DSS_INDEX:
277 UUID_COPY(uuid_p, UUID_DSS);
278 break;
279 case UUID_BASIC_CONNECT_EXTENSIONS_INDEX:
280 UUID_COPY(uuid_p, UUID_BASIC_CONNECT_EXTENSIONS);
281 break;
282 case UUID_MS_UICC_LOW_LEVEL_INDEX:
283 UUID_COPY(uuid_p, UUID_MS_UICC_LOW_LEVEL);
284 break;
285 default:
286 ret = MBIM_UUID_UKNOWN_ERROR;
287 }
288
289 return ret;
290}
291
292/*******************************************************************************\
293* Function: getNumOfFragments
294* Description: Get number of fragments needed to transmit payload
295* Parameters: int mbimMsgSize - The size of the message
296* int bufLen - The size of the payload we want to send
297* Returns: int - Number of fragments
298\*******************************************************************************/
299int getNumOfFragments(int mbimMsgSize, int bufLen)
300{
301 int numOfFragments;
302 int fragmentPayloadSize;
303 int payloadLen = bufLen;
304
305 //Each fragment has mandatory MBIM header and MBIM fragment header (So we remove this from usable payload).
306 fragmentPayloadSize = mbimDb.maxControlTransfer - FRAGMENT_HDR_SIZE;
307
308 //We need to remove the MBIM header and frag header from calculation.
309 payloadLen = (mbimMsgSize + bufLen) - FRAGMENT_HDR_SIZE;
310
311 //Calculate now all available data / How much each framgent can carry (integer division, so
312 numOfFragments = ((payloadLen-1) / fragmentPayloadSize) + 1;
313
314 return numOfFragments;
315}
316
317
318void initSessionDb(int sessionId, char *apn, UINT32 ipType, P_MBIM_UUID contextType, int cid)
319{
320 if (sessionId < MAX_NUM_OF_SESSIONS)
321 {
322 strncpy(mbimDb.session[sessionId].APN, apn, MBIM_ACCESSSTRING_MAXSIZE/2-1);
323 memcpy((char *)&mbimDb.session[sessionId].contextType, (char *)contextType, sizeof(MBIM_UUID));
324
325 mbimDb.session[sessionId].APN[MBIM_ACCESSSTRING_MAXSIZE/2] = 0;
326 mbimDb.session[sessionId].cid = cid;
327 mbimDb.session[sessionId].voiceCallState = MBIMVoiceCallStateNone; //Set to default value
328 mbimDb.session[sessionId].ipType = ipType;
329 mbimDb.session[sessionId].sessionState = MBIMActivationStateActivated;
330
331 MBIM_LOGD("CID CONNECT - Init Session: sessionId = %d, ipType = %d, APN=%s, Cid = %d", sessionId, ipType, apn, cid);
332 }
333 else
334 {
335 MBIM_LOGE("CID CONNECT - Init Session: sessionId = %d does not exist", MAX_NUM_OF_SESSIONS);
336 }
337}
338
339
340void resetSessionDb(int sessionId)
341{
342// int cid;
343 if (sessionId < MAX_NUM_OF_SESSIONS)
344 {
345 memset( mbimDb.session[sessionId].APN, 0, MBIM_ACCESSSTRING_MAXSIZE/2);
346 memset( &mbimDb.session[sessionId].contextType, 0, sizeof(MBIM_UUID));
347
348// cid = mbimDb.session[sessionId].cid;
349 mbimDb.session[sessionId].cid = 0;
350 mbimDb.session[sessionId].voiceCallState = MBIMVoiceCallStateNone; //Set to default value
351 mbimDb.session[sessionId].ipType = 0;
352 mbimDb.session[sessionId].sessionState = MBIMActivationStateUnknown;
353
354 MBIM_LOGD("CID CONNECT - reset Session: sessionId = %d", sessionId);
355
356 //DeletePdp(NULL, cid);
357 }
358 else
359 {
360 MBIM_LOGE("CID CONNECT - reset Session: sessionId = %d does not exist", MAX_NUM_OF_SESSIONS);
361 }
362
363
364}
365
366
367int getRegisterTech(int dataClass)
368{
369 int retVal = 0;
370
371 if ((dataClass & MBIMDataClassLTE) != 0 )
372 retVal = 7;
373 else if (((dataClass & MBIMDataClassHSUPA) != 0 ) &&
374 ((dataClass & MBIMDataClassHSUPA) != 0 ) )
375 retVal = 6;
376 else if ((dataClass & MBIMDataClassHSUPA) != 0 )
377 retVal = 5;
378 else if ((dataClass & MBIMDataClassHSDPA) != 0 )
379 retVal = 4;
380 else if ((dataClass & MBIMDataClassUMTS) != 0 )
381 retVal = 3;
382 else if ((dataClass & MBIMDataClassEDGE) != 0 )
383 retVal = 2;
384 else if ((dataClass & MBIMDataClassGPRS) != 0 )
385 retVal = 1;
386
387 return retVal;
388
389}
390/*******************************************************************************\
391* Function: CodeSignalStr2MbimCodedValue
392* Description: converts from Measured RSSI to Coded Value used in MBIM_SIGANL_STATE_INFO.
393* translation table can be found at Table 10-58 Errata 1
394*
395* Parameters: int signalStrength
396* Returns: Coded signal Strength
397\*******************************************************************************/
398int CodeSignalStr2MbimCodedValue(int signalStrength)
399{
400 int codedSignalStrength;
401
402 if ( signalStrength < (-113) )
403 codedSignalStrength = 0;
404 else if (signalStrength > (-51) )
405 codedSignalStrength = 31;
406 else
407 {
408 //convert to coded signal
409 codedSignalStrength = (signalStrength + 113)/2;
410 }
411
412 return codedSignalStrength;
413}
414
415
416/*******************************************************************************\
417* Function: CodeBer2MbimCodedValue
418* Description: converts from Measured BER to Coded Value used in MBIM_SIGANL_STATE_INFO.
419* translation table can be found at Table 10-58 Errata 1
420*
421* Parameters: float - Bit error rate value
422* Returns: Returns encoded BER.
423\*******************************************************************************/
424int CodeBer2MbimCodedValue(float ber)
425{
426 int codedBer = 0, i;
427 int limit = 2;
428
429 ber *= 10;
430
431 //Go through all possible coded value, and check if BER is inside range
432 for (i=0 ; i<7 ; i++)
433 {
434 if (ber < (limit << i))
435 {
436 codedBer = i;
437 break;
438 }
439 }
440
441 return codedBer;
442}
443
444/*******************************************************************************\
445* Function: CodeBer2MbimCodedValue
446* Description: converts from Measured FER to Coded Value used in MBIM_SIGANL_STATE_INFO.
447* translation table can be found at Table 10-58 Errata 1
448*
449* Parameters: float - Frame error rate value
450* Returns: Returns encoded FER.
451\*******************************************************************************/
452int CodeFer2MbimCodedValue(float fer)
453{
454 int codedFer;
455 fer *= 100;
456
457 if (fer < 1)
458 codedFer = 0;
459 else if (fer < 10)
460 codedFer = 1;
461 else if (fer < 50)
462 codedFer = 2;
463 else if (fer < 100)
464 codedFer = 3;
465 else if (fer < 200)
466 codedFer = 4;
467 else if (fer < 400)
468 codedFer = 5;
469 else if (fer < 800)
470 codedFer = 6;
471 else
472 codedFer = 7;
473
474 return codedFer;
475}
476
477
478/*******************************************************************************\
479* Function: getIpv4MaskLength
480* Description: Convert the IPv4 mask, into Mask legnth
481* Parameters: UINT32 mask
482* Returns: return the length of the mask
483\*******************************************************************************/
484int getIpv4MaskLength(UINT32 mask)
485{
486 int index;
487 for (index=0; index < 32 ; index++)
488 {
489 if ((mask&0x1) == 1)
490 break;
491
492 //Update mask
493 mask = (mask>>1);
494 }
495
496 return (32-index);
497}
498
499
500/*******************************************************************************\
501* Function: getIpv6MaskLength
502* Description:
503*
504* Parameters: float - Frame error rate value
505* Returns: Returns encoded FER.
506\*******************************************************************************/
507int getIpv6MaskLength(UINT32 *mask)
508{
509 int index, charIndex;
510 UINT32 temp;
511
512 //Count how many UINT32 we have with mask enabled
513 for (charIndex = 0 ; charIndex < 16 ; charIndex++)
514 {
515 if (mask[charIndex] != 0xffffffff)
516 break;
517 }
518
519 //Search inside of this UINT32 where the Zero starts
520 temp = mask[charIndex];
521 for (index=0; index < 32 ; index++)
522 {
523 if ((temp&0x1) == 1)
524 break;
525
526 //Update mask
527 temp = (temp>>1);
528 }
529
530 return (charIndex*32+(32-index));
531}
532
533
534
535/*******************************************************************
536 * FUNCTION: checkForNumericOnlyChars
537 *
538 * DESCRIPTION: check the given string, validate it only contains numeric
539 *
540 * RETURNS: TRUE or FALSE
541 *
542 *******************************************************************/
543BOOL checkForNumericOnlyChars(const CHAR * password)
544{
545 INT16 passLen = 0;
546 INT8 count = 0;
547 BOOL result = TRUE;
548
549 passLen = (INT16) strlen((const char *)password);
550 if (passLen > 0) {
551 /* Chech each digit */
552 while ((result == TRUE) && (count < passLen)) {
553 if ((password[count] < '0') || (password[count] > '9')) {
554 result = FALSE;
555 }
556
557 count++;
558 }
559 }
560
561 return (result);
562}
563
564
565/*******************************************************************
566 * FUNCTION: copyStrToUtf16
567 *
568 * DESCRIPTION: Copy normal string into UTF-16 string.
569 *
570 * INPUT: char *dst - the destination target (this will be in format UTF-16)
571 * char *src - the source string (normal used string)
572 * int sizeOfStr - the size of the original string we are copying
573 * RETURNS: int - The size of the new string
574 *
575 *******************************************************************/
576int copyStrToUtf16(char *dst, char*src, int sizeOfStr)
577{
578 int index;
579 int utf16Index = 0;
580
581 //run over al the original string
582 for (index = 0; index < sizeOfStr ; index++)
583 {
584 if (isalnum(src[index])|| ispunct(src[index]) || isspace(src[index]))
585 {
586 dst[utf16Index] = src[index];
587 utf16Index++;
588 dst[utf16Index] = 0;
589 utf16Index++;
590 }
591 }
592
593 return utf16Index;
594}
595
596
597
598/*******************************************************************
599 * FUNCTION: copyStrToUtf16
600 *
601 * DESCRIPTION: Copy UTF-16 string into normal string.
602 *
603 * INPUT: char *dst - the destination target (8 bit string)
604 * char *src - the source string (this will be in format UTF-16)
605 * int sizeOfStr - the size of the original UTF-16 string we are copying
606 * RETURNS: int - The size of the new string
607 *
608 *******************************************************************/
609int copyUtf16ToStr(char *dst, char*src, int sizeOfUtf16)
610{
611 int index;
612 int strIndex = 0;
613
614 //run over al the UTF16 string and copy to 8bit string
615 for (index = 0; index < sizeOfUtf16 ; index+=2)
616 {
617 dst[strIndex] = src[index];
618 strIndex++;
619 }
620 dst[strIndex] = 0;
621
622 return strIndex;
623}
624
625
626/*******************************************************************************\
627* Function: pinListFillPinDescriptor (Used on CID_PIN_LIST)
628* Description: fill the pin descriptor
629* Parameters: P_MBIM_PIN_DESC - Pointer to pin descriptor we want to fill
630* ...
631* Returns: void
632\*******************************************************************************/
633void pinListFillPinDescriptor( P_MBIM_PIN_DESC pPinDesc,
634 MBIM_PIN_MODE_ENUM pinMode,
635 MBIM_PIN_FORMAT_ENUM pinFormat,
636 UINT32 pinLengthMax,
637 UINT32 pinLengthMin)
638{
639 pPinDesc->pinMode = pinMode;
640 pPinDesc->pinFormat = pinFormat;
641 pPinDesc->pinLengthMax = pinLengthMax;
642 pPinDesc->pinLengthMin = pinLengthMin;
643}
644
645/*******************************************************************************\
646* Function: setRoutingTable (Used on CID_IP_CONFIGURATIONS)
647* Description: Set Linux routing tables sodata can be sent after connect PDP
648* Parameters: void
649* Returns: void
650\*******************************************************************************/
651void setRoutingTable(int cid)
652{
653 char cmd[200];
654
655 MBIM_LOGD("Set Routing Tables Cid = %d", cid);
656
657 if (1/*mbimDb.loopbackEnabled == FALSE*/)
658 {
659 //Set routing to wotk in Hostless mode
660 sprintf(cmd, "iptables -t nat -A POSTROUTING -o ccinet%d -j MASQUERADE", cid-1);
661 system(cmd);
662 MBIM_LOGD(cmd);
663
664 sprintf(cmd, "iptables -A FORWARD -i ccinet%d -o usb0 -m state --state RELATED,ESTABLISHED -j ACCEPT", cid-1);
665 system(cmd);
666 MBIM_LOGD(cmd);
667
668 sprintf(cmd, "iptables -A FORWARD -i usb0 -o ccinet%d -j ACCEPT", cid-1);
669 system(cmd);
670 MBIM_LOGD(cmd);
671
672 sprintf(cmd, "ip route del default");
673 system(cmd);
674 MBIM_LOGD(cmd);
675
676 sprintf(cmd,"ip route add default dev ccinet%d",cid-1);
677 system(cmd);
678 MBIM_LOGD(cmd);
679
680 }
681 else
682 {
683 //Set routing to wotk in Hostless mode
684 sprintf(cmd, "iptables -t nat -A POSTROUTING -o lo -j MASQUERADE");
685 system(cmd);
686 MBIM_LOGD(cmd);
687
688 sprintf(cmd, "iptables -A FORWARD -i lo -o usb0 -m state --state RELATED,ESTABLISHED -j ACCEPT");
689 system(cmd);
690 MBIM_LOGD(cmd);
691
692 sprintf(cmd, "iptables -A FORWARD -i usb0 -o lo -j ACCEPT");
693 system(cmd);
694 MBIM_LOGD(cmd);
695 }
696}
697
698
699
700int getSessionIdFromCid(int cid)
701{
702 int sessionId = MAX_NUM_OF_SESSIONS;
703 int sessionIndex;
704
705 for (sessionIndex = 0 ; sessionIndex < MAX_NUM_OF_SESSIONS ; sessionIndex++)
706 {
707 if (mbimDb.session[sessionIndex].cid == cid)
708 {
709 sessionId = sessionIndex;
710 break;
711 }
712 }
713 return sessionId;
714}
715
716
717char hexToNum(char ch)
718{
719 ch = (UINT8) toupper(ch);
720
721 if (isdigit(ch)) {
722 ch -= '0';
723 } else if (isxdigit(ch)) {
724 ch -= 'A';
725 ch += 0x0A;
726 }
727
728 return ch;
729}
730
731
732/*******************************************************************************\
733* Function: getFreeSessionId
734* Description: Get the first free session ID
735* Parameters: void
736* Returns: int - return Session ID. If not found return MAX_NUM_OF_SESSIONS
737\*******************************************************************************/
738int getFreeSessionId(void)
739{
740 int sessionId = MAX_NUM_OF_SESSIONS;
741 int sessionIndex;
742
743 for (sessionIndex = 0 ; sessionIndex < MAX_NUM_OF_SESSIONS ; sessionIndex++)
744 {
745 if (mbimDb.session[sessionIndex].cid == 0)
746 {
747 sessionId = sessionIndex;
748 break;
749 }
750 }
751
752 return sessionId;
753}
754
755
756/*******************************************************************************\
757* Function: ReadCOMCfgFileAndSearchValue
758* Description: Read COMCfg and search for the value for a specific Token
759* Parameters: char *token
760* char *value
761* Returns: int - 0 - OK, -1 fail
762\*******************************************************************************/
763int ReadCOMCfgFileAndSearchValue(char * token, char *value)
764{
765 FILE* pComCFG = NULL;
766 char buffer[256];
767 size_t len_token;
768 size_t len_value;
769
770 len_token = strlen(token);
771 len_value = strlen(value);
772
773 if((pComCFG = fopen(NVM_DIR "/" COMCFG_FILE,"rt")) != NULL)
774 {
775 while(!feof(pComCFG))
776 {
777 if ( fgets (buffer , sizeof(buffer) , pComCFG) != NULL )
778 {
779 if(strlen(buffer)> 3) //not empty line
780 {
781 //remove space characters from string
782 trim(buffer);
783
784 if(strchr( buffer, ',') != NULL)
785 {
786 if(strncasecmp(buffer, token, len_token) == 0)
787 {
788 if(strncasecmp(buffer + len_token + 1, value, len_value) == 0)
789 {
790 fclose(pComCFG);
791
792 //The value is found
793 return 1;
794 }
795 }
796 }
797 }
798 }
799 }//while
800 fclose(pComCFG);
801 }
802 else
803 {
804 MBIM_LOGD("fopen %s failed ",NVM_DIR "/" COMCFG_FILE);
805 return -1;
806 }
807 return 0;
808}
809
810static void trim(char *buffer)
811{
812 char *p1 = buffer;
813 char *p2 = buffer;
814
815 while (*p1 != 0) {
816 if ((*p1)<32) {
817 ++p1;
818 } else
819 *p2++ = *p1++;
820 }
821 *p2 = 0;
822}
823
824#if defined USER_STRINGS_ARRAY_CLASS
825/***************************************************
826 * Strings array functions
827 * A set of functions to handle a dynamic array
828 * of strings.
829 **************************************************/
830static StringArrayClassS *StringArrayGrow(StringArrayClassS * stringArrayContainer)
831{
832 char **newArray;
833 int i,j;
834
835 newArray = (char **)malloc((stringArrayContainer->allocCount + STRING_ARRAY_DEFAULT_GROW) * sizeof (char *));
836
837 if (newArray == NULL) {
838 StringArrayFree((StringArrayHandleT)stringArrayContainer);
839 return NULL;
840 } else {
841 for (i = 0 ; i < stringArrayContainer->stringsCount ; i++) {
842 newArray[i] = strdup(stringArrayContainer->stringsArray[i]);
843
844 if (newArray[i] == NULL) { // Cleanup in case of alloc fail
845 StringArrayFree((StringArrayHandleT)stringArrayContainer);
846 for (j = 0 ; j < i ; j++) {
847 free(newArray[j]);
848 }
849 return NULL;
850 } else { // free old string memory
851 free(stringArrayContainer->stringsArray[i]);
852 }
853 }
854 stringArrayContainer->allocCount += STRING_ARRAY_DEFAULT_GROW;
855 free(stringArrayContainer->stringsArray);
856 stringArrayContainer->stringsArray = newArray;
857 }
858
859 return stringArrayContainer;
860}
861
862StringArrayHandleT StringArrayInit (int count)
863{
864 StringArrayClassS *stringsArrayContainer = NULL;
865
866 if (count == 0)
867 count = STRING_ARRAY_DEFAULT_COUNT;
868
869 stringsArrayContainer = (StringArrayClassS *)malloc (sizeof(StringArrayClass));
870 if (stringsArrayContainer) {
871 stringsArrayContainer->stringsArray = (char **)malloc(count * sizeof(char *));
872 if (stringsArrayContainer->stringsArray) {
873 stringsArrayContainer->stringsCount = 0;
874 stringsArrayContainer->allocCount = count;
875 } else {
876 free (stringsArrayContainer);
877 stringsArrayContainer = NULL;
878 }
879 }
880
881 return (StringArrayHandleT)stringsArrayContainer;
882
883}
884
885int StringArrayAddString(StringArrayHandleT handle, char *string)
886{
887 StringArrayClassS *stringsArrayContainer = (StringArrayClassS *)handle;
888
889 if (stringsArrayContainer->stringsCount > stringsArrayContainer->allocCount) {
890 /*
891 * PRINT WARNING - USED MORE STRINGS THAN ALLOCATED
892 * CONSIDER ASSERT HERE
893 */
894 StringArrayFree(stringsArrayContainer);
895 return -1;
896 }
897
898 if (stringsArrayContainer->stringsCount == stringsArrayContainer->allocCount) {
899 stringsArrayContainer = StringArrayGrow(stringsArrayContainer);
900 if (stringsArrayContainer == NULL) {
901 // StringArrayGrow will cleanup if allocation failed
902 return -1;
903 }
904 }
905 stringsArrayContainer->stringsArray[stringsArrayContainer->stringsCount] = strdup(string);
906
907 if (stringsArrayContainer->stringsArray[stringsArrayContainer->stringsCount]) {
908 stringsArrayContainer->stringsCount++;
909
910 } else {
911 StringArrayFree(stringsArrayContainer);
912 return -1;
913 }
914
915 return 0;
916}
917
918char ** StringArrayGetStrings(StringArrayHandleT handle)
919{
920 return (((StringArrayClassS *)handle)->stringsArray);
921}
922
923int StringArrayGetCount(StringArrayHandleT handle)
924{
925 return (((StringArrayClassS *)handle)->allocCount);
926}
927
928void StringArrayFree(StringArrayHandleT handle)
929{
930 int i;
931 StringArrayClassS *stringsArrayContainer = (StringArrayClassS *)handle;
932
933 for (i = 0 ; i < stringsArrayContainer->allocCount ; i++) {
934 free(stringsArrayContainer->stringsArray[i]);
935 }
936
937 free(stringsArrayContainer);
938}
939#endif //USER_STRINGS_ARRAY_CLASS
940
941#if defined MBIM_MTIL
942/*******************************************************************************\
943* Function: MtilSimStatus2MbimSubscriberReadyState
944* Description: This function converts the received return code and pin code status to MBIM subscriber
945* ready status.
946* Parameters: ret_code - The ret-code status for the pin
947* pin_code - The status of the pin_code
948* Returns: int, returns the Mbim Subscriber ready State
949\*******************************************************************************/
950int MtilSimStatus2MbimSubscriberReadyState(int ret_code, int pin_code)
951{
952 UINT32 subsState;
953
954 switch(ret_code)
955 {
956 case MTIL_CODE_AT_OK:
957 {
958 if (pin_code == MTIL_PIN_STATUS_READY)
959 {
960 subsState = MBIMSubscriberReadyStateInitialized;
961 }
962
963 else if (pin_code == MTIL_PIN_STATUS_SIM_REMOVED)
964 {
965 subsState = MBIMSubscriberReadyStateSimNotInserted;
966 }
967
968 else if (pin_code == MTIL_PIN_STATUS_NETWORK_REJECTED)
969 {
970 subsState = MBIMSubscriberReadyStateNotActivated;
971 }
972
973 else if (pin_code == MTIL_PIN_STATUS_UNKNOWN)
974 {
975 subsState = MBIMSubscriberReadyStateBadSim;
976 }
977 else
978 {
979 subsState = MBIMSubscriberReadyStateDeviceLocked;
980 }
981 }
982 break;
983
984 case MTIL_CODE_AT_ERR_SIM_FAILURE:
985 case MTIL_CODE_AT_ERR_SIM_WRONG:
986 case MTIL_CODE_AT_ERR_INCORRECT_PASS:
987 subsState = MBIMSubscriberReadyStateBadSim;
988 break;
989
990 case MTIL_CODE_AT_ERR_SIM_NOT_INSERTED:
991 subsState = MBIMSubscriberReadyStateSimNotInserted;
992 break;
993
994 case MTIL_CODE_AT_ERR_SIM_PIN_REQ:
995 case MTIL_CODE_AT_ERR_SIM_PUK_REQ:
996 case MTIL_CODE_AT_ERR_SIM_PIN2_REQ:
997 case MTIL_CODE_AT_ERR_SIM_PUK2_REQ:
998 subsState = MBIMSubscriberReadyStateDeviceLocked;
999 break;
1000
1001 default:
1002 subsState = MBIMSubscriberReadyStateNotInitialized;
1003 break;
1004 }
1005
1006 return subsState;
1007}
1008
1009
1010
1011
1012/*******************************************************************************\
1013* Function: MtilCauseCodeForNwError2Mbim
1014* Description: converts from General NW error, to the MBIM NW error
1015* Parameters: UINT32 - Received the NW error sent by comm
1016*
1017* Returns: int - returns the MBIM NW error
1018\*******************************************************************************/
1019int MtilCauseCodeForNwError2Mbim(UINT32 result)
1020{
1021 //This needs more considration (For now looks as match)
1022 return (result%100);
1023}
1024
1025
1026/*******************************************************************************\
1027* Function: getMaxDataClassSupported
1028* Description: Retruns the supported data class technologies
1029* Parameters: Pointer to CNTI response message
1030* Returns: Returns a bitmap mask for the supported class technologies
1031\*******************************************************************************/
1032int getMaxDataClassSupported(P_MTIL_CNTI_STATUS_MSG pCnti)
1033{
1034 UINT32 dataClass = 0;
1035 //This needs more considration (For now looks as match)
1036 if (pCnti->epsActive)
1037 dataClass |= MBIMDataClassLTE;
1038 if (pCnti->hsdpaActive)
1039 dataClass |= MBIMDataClassHSDPA;
1040 if (pCnti->hsupaActive)
1041 dataClass |= MBIMDataClassHSUPA;
1042 if (pCnti->act == MTIL_MM_ACT_UTRAN)
1043 dataClass |= MBIMDataClassUMTS;
1044 if (pCnti->egprsActive)
1045 dataClass |= MBIMDataClassEDGE;
1046 if (pCnti->gprsActive)
1047 dataClass |= MBIMDataClassGPRS;
1048 if (pCnti->act == MTIL_MM_ACT_GSM)
1049 dataClass |= MBIMDataClassNone;
1050
1051 return dataClass;
1052}
1053
1054
1055/*******************************************************************************\
1056* Function: getMaxDataClassAvailable
1057* Description: Retruns the supported data class technologies
1058* Parameters: Pointer to CNTI response message
1059* Returns: Returns a bitmap mask for the supported class technologies
1060\*******************************************************************************/
1061int getMaxDataClassAvailable(P_MTIL_CNTI_STATUS_MSG pCnti, UINT64 *dlSpeed, UINT64 *ulSpeed)
1062{
1063 UINT32 dataClass = MTIL_MM_NETWORK_MODE_REPORT_EUTRA_EPS;
1064
1065 //workaround for LTE (adrian)
1066 if (pCnti->mode == 0)
1067 pCnti->mode = MBIMDataClassLTE;
1068
1069 switch (pCnti->mode)
1070 {
1071 case MTIL_MM_NETWORK_MODE_REPORT_GSM:
1072 dataClass = 0;
1073 ((UINT32 *)dlSpeed)[0] = 0;
1074 ((UINT32 *)ulSpeed)[0] = 0;
1075 break;
1076 case MTIL_MM_NETWORK_MODE_REPORT_UMTS:
1077 dataClass = MBIMDataClassUMTS;
1078 ((UINT32 *)dlSpeed)[0] = 384000;
1079 ((UINT32 *)ulSpeed)[0] = 384000;
1080 break;
1081 case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSDPA:
1082 dataClass = MBIMDataClassHSDPA;
1083 ((UINT32 *)dlSpeed)[0] = 42000000;
1084 ((UINT32 *)ulSpeed)[0] = 384000;
1085 break;
1086 case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSUPA:
1087 dataClass = MBIMDataClassHSUPA;
1088 ((UINT32 *)dlSpeed)[0] = 384000;
1089 ((UINT32 *)ulSpeed)[0] = 5760000;
1090 break;
1091 case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSDPA_HSUPA:
1092 dataClass = MBIMDataClassHSUPA | MBIMDataClassHSDPA;
1093 ((UINT32 *)dlSpeed)[0] = 42000000;
1094 ((UINT32 *)ulSpeed)[0] = 5760000;
1095 break;
1096 case MTIL_MM_NETWORK_MODE_REPORT_GSM_EGPRS:
1097 dataClass = MBIMDataClassEDGE;
1098 ((UINT32 *)dlSpeed)[0] = 236800;
1099 ((UINT32 *)ulSpeed)[0] = 118400;
1100 break;
1101 case MTIL_MM_NETWORK_MODE_REPORT_GSM_GPRS:
1102 dataClass = MBIMDataClassGPRS;
1103 ((UINT32 *)dlSpeed)[0] = 48000;
1104 ((UINT32 *)ulSpeed)[0] = 24000;
1105 break;
1106 case MTIL_MM_NETWORK_MODE_REPORT_EUTRA_EPS:
1107 dataClass = MBIMDataClassLTE;
1108 ((UINT32 *)dlSpeed)[0] = 100000000;
1109 ((UINT32 *)ulSpeed)[0] = 50000000;
1110 break;
1111 default:
1112 dataClass = MBIMDataClassLTE;
1113 ((UINT32 *)dlSpeed)[0] = 100000000;
1114 ((UINT32 *)ulSpeed)[0] = 50000000;
1115 break;
1116 }
1117
1118 ((UINT32 *)dlSpeed)[1] = 0;
1119 ((UINT32 *)ulSpeed)[1] = 0;
1120
1121
1122 return dataClass;
1123}
1124
1125
1126
1127
1128
1129/*******************************************************************************\
1130* Function: transCregAct2Mbim
1131* Description: translate CregAct 2 Mbim
1132*
1133* Parameters: int ACT
1134* Returns: Technology in use
1135\*******************************************************************************/
1136int transCregAct2Mbim(int act)
1137{
1138 int retVal = 0;
1139
1140 switch(act)
1141 {
1142 case 0: // GSM
1143 retVal = MBIMDataClassNone;
1144 break;
1145
1146 case 6: // GSM w/GPRS
1147 retVal = MBIMDataClassGPRS;
1148 break;
1149
1150 case 5: //GSM w/EGPRS
1151 retVal = MBIMDataClassEDGE;
1152 break;
1153
1154 case 1: // UTRAN
1155 retVal = MBIMDataClassUMTS;
1156 break;
1157
1158 case 2: //UTRAN w/HSDPA
1159 retVal = MBIMDataClassHSDPA;
1160 break;
1161
1162 case 3: //UTRAN w/HSUPA
1163 retVal = MBIMDataClassHSUPA;
1164 break;
1165
1166 case 4: //UTRAN w/HSDPA + HSUPA
1167 retVal = MBIMDataClassHSUPA | MBIMDataClassHSDPA;
1168 break;
1169
1170 case 7:
1171 retVal = MBIMDataClassLTE;
1172 break;
1173 default:
1174 return 0;// - Unknown
1175 }
1176
1177 MBIM_LOGD("Data Class = %d", retVal);
1178
1179 return retVal;
1180}
1181
1182
1183
1184
1185
1186
1187/*******************************************************************
1188 * FUNCTION: translateSimMsg2MbimSimMsg
1189 *
1190 * DESCRIPTION: Translate from COMM response about SIM to MBIM SIM MSG
1191 *
1192 * INPUT: int - The Sm Message received from MTIL server
1193 * RETURNS: int - Represnting the MbimPinType
1194 *
1195 *******************************************************************/
1196int translateSimMsg2MbimSimMsg(int simMsg)
1197{
1198 int retVal = MTIL_CODE_AT_ERR_UNKNOWN;
1199
1200 switch (simMsg)
1201 {
1202 case MTIL_PIN_STATUS_READY:
1203 retVal = MBIMPinTypeNone;
1204 break;
1205
1206 case MTIL_PIN_STATUS_SIM_PIN:
1207 retVal = MBIMPinTypePin1;
1208 break;
1209
1210 case MTIL_PIN_STATUS_SIM_PIN2:
1211 retVal = MBIMPinTypePin2;
1212 break;
1213
1214 case MTIL_PIN_STATUS_SIM_PUK:
1215 retVal = MBIMPinTypePuk1;
1216 break;
1217
1218 case MTIL_PIN_STATUS_SIM_PUK2:
1219 retVal = MBIMPinTypePuk2;
1220 break;
1221
1222 default:
1223 retVal = MBIMPinTypeCustom;
1224 break;
1225 }
1226
1227 return retVal;
1228}
1229
1230
1231
1232
1233
1234
1235/*******************************************************************
1236 * FUNCTION: translateCopsRegMode
1237 *
1238 * DESCRIPTION: Translate COPS registration mode to MBIM registration Mode
1239 *
1240 * INPUT: int regMode - COPS registration mode
1241 * RETURNS: int - MBIM registration mode
1242 *
1243 *******************************************************************/
1244int translateCopsRegMode(int regMode)
1245{
1246 int mbimRegMode;
1247
1248 switch (regMode)
1249 {
1250 case 0:
1251 mbimRegMode = MBIMRegisterModeAutomatic;
1252 break;
1253 case 1:
1254 mbimRegMode = MBIMRegisterModeManual;
1255 break;
1256 default:
1257 mbimRegMode = MBIMRegisterModeUnknown;
1258 break;
1259 }
1260
1261 return mbimRegMode;
1262}
1263
1264
1265/*******************************************************************
1266 * FUNCTION: translateCgattState
1267 *
1268 * DESCRIPTION: Translate CGATT state to MBIM State
1269 *
1270 * INPUT: int regMode - COPS registration mode
1271 * RETURNS: int - MBIM registration mode
1272 *
1273 *******************************************************************/
1274int translateCgattState(int state)
1275{
1276 int mbimState;
1277
1278 switch (state)
1279 {
1280 case 0:
1281 mbimState = MBIMPacketServiceStateDetached;
1282 break;
1283 case 1:
1284 mbimState = MBIMPacketServiceStateAttached;
1285 break;
1286 default:
1287 mbimState = MBIMPacketServiceStateUnknown;
1288 break;
1289 }
1290
1291 return mbimState;
1292}
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302/*******************************************************************************\
1303* Function: setRoutingTable (Used on CID_IP_CONFIGURATIONS)
1304* Description: Translate from Cops Provider state to MBIM provider State
1305* Parameters: int - Cops Opt provider STAT
1306* Returns: int - Mbim provider STATE
1307\*******************************************************************************/
1308int translateCopsProvider2MbimProvider(int stat)
1309{
1310 int mbimStat;
1311
1312 switch(stat)
1313 {
1314 case 0: //Unknown
1315 mbimStat = MBIM_PROVIDER_STATE_UNKNOWN;
1316 break;
1317 case 1: //Avaiable
1318 mbimStat = MBIM_PROVIDER_STATE_PREFERRED;
1319 break;
1320
1321 case 2: //Current
1322 mbimStat = MBIM_PROVIDER_STATE_REGISTERED;
1323 break;
1324
1325 case 3: //forbidden
1326 mbimStat = MBIM_PROVIDER_STATE_FORBIDDEN;
1327 break;
1328
1329 default:
1330 mbimStat = MBIM_PROVIDER_STATE_UNKNOWN;
1331 break;
1332 }
1333
1334 return mbimStat;
1335}
1336
1337
1338
1339/*******************************************************************************\
1340* Function: translateMbimFlag2CmglStatus
1341* Description: Translate from MBIM Flag SMS read to CmglStat
1342* Parameters: int - Cops Opt provider STAT
1343* Returns: int - Mbim provider STATE
1344\*******************************************************************************/
1345int translateMbimFlag2CmglStat(int flag)
1346{
1347 int stat = 0;
1348
1349 switch(flag)
1350 {
1351 case MBIMSmsFlagAll:
1352 stat = MSG_MSG_STAT_ALL;
1353 break;
1354 case MBIMSmsFlagNew:
1355 stat = MSG_MSG_STAT_REC_UNREAD;
1356 break;
1357 case MBIMSmsFlagOld:
1358 stat = MSG_MSG_STAT_READ;
1359 break;
1360 case MBIMSmsFlagSent:
1361 stat = MSG_MSG_STAT_STO_SENT;
1362 break;
1363 case MBIMSmsFlagDraft:
1364 stat = MSG_MSG_STAT_STO_UNSENT;
1365 break;
1366 default:
1367 stat = MSG_MSG_STAT_ALL;
1368 break;
1369 }
1370
1371 return stat;
1372}
1373
1374
1375/*******************************************************************************\
1376* Function: translateMbimFlag2CmglStatus
1377* Description: Translate from MBIM Flag SMS read to CmgrStat
1378* Parameters: int -
1379* Returns: int -
1380\*******************************************************************************/
1381int translateCmgrStat2MbimMessageStat(int status)
1382{
1383 int stat = 0;
1384
1385 switch(status)
1386 {
1387 case MSG_MSG_STAT_REC_UNREAD:
1388 stat = MBIMSmsStatusNew;
1389 break;
1390
1391 case MSG_MSG_STAT_READ:
1392 stat = MBIMSmsStatusOld;
1393 break;
1394
1395 case MSG_MSG_STAT_STO_UNSENT:
1396 stat = MBIMSmsStatusDraft;
1397 break;
1398
1399 case MSG_MSG_STAT_STO_SENT:
1400 stat = MBIMSmsStatusSent;
1401 break;
1402
1403 default:
1404 stat = MBIMSmsStatusNew;
1405 break;
1406 }
1407
1408 return stat;
1409}
1410
1411
1412
1413/************************************************************************************
1414 * F@: translateMbimFlag2CmgdFlag - Convert SMS delete flag
1415 *
1416 */
1417/*******************************************************************************\
1418* Function: translateMbimFlag2CmgdFlag
1419* Description: Translate from MBIM flag to SMS flag
1420* Parameters: int - Mbim Flag
1421* Returns: int - Flag
1422\*******************************************************************************/
1423int translateMbimFlag2CmgdFlag(UINT8 mbimFlag)
1424{
1425 int Flag;
1426
1427 switch (mbimFlag)
1428 {
1429 case MBIMSmsFlagIndex:
1430 Flag = MSG_MSG_DELFLAG_INDEX;
1431 break;
1432
1433 case MBIMSmsFlagOld:
1434 Flag = MSG_MSG_DELFLAG_ALL_READ;
1435 break;
1436
1437 case MBIMSmsFlagSent:
1438 Flag = MSG_MSG_DELFLAG_ALL_READ_OR_SENT;
1439 break;
1440
1441 case MBIMSmsFlagDraft:
1442 Flag = MSG_MSG_DELFLAG_ALL_READ_OR_MO;
1443 break;
1444
1445 case MBIMSmsFlagAll:
1446 default:
1447 Flag = MSG_MSG_DELFLAG_ALL;
1448 break;
1449 }
1450
1451 return Flag;
1452}
1453
1454
1455
1456/*******************************************************************************\
1457* Function: translateSmsStatus2MbimSmsStatus
1458* Description: Translate from SMS status to MBIM SMS status
1459* Parameters: int - Cops Opt provider STAT
1460* Returns: int - Mbim provider STATE
1461\*******************************************************************************/
1462int translateSmsStatus2MbimSmsStatus(int smsStatus)
1463{
1464 int mbimStatus = 0;
1465
1466 switch(smsStatus)
1467 {
1468 case MTIL_CODE_AT_ERR_SMS_INVALID_INDEX:
1469 mbimStatus = MBIM_STATUS_INVALID_MEMORY_INDEX;
1470 break;
1471 case MTIL_CODE_AT_ERR_INVALID_PDU_MODE_PARAM:
1472 case MTIL_CODE_AT_ERR_INVALID_TEXT_MODE_PARAM:
1473 mbimStatus = MBIM_STATUS_SMS_FORMAT_NOT_SUPPORTED;
1474 break;
1475 case MTIL_CODE_AT_ERR_SMS_MEMORY_FAILURE:
1476 mbimStatus = MBIM_STATUS_MEMORY_FAILURE;
1477 break;
1478 case MTIL_CODE_AT_ERR_SMS_OPER_NOT_SUPPORTED:
1479 mbimStatus = MBIM_STATUS_FILTER_NOT_SUPPORTED;
1480 break;
1481 default:
1482 mbimStatus = MBIM_STATUS_MEMORY_FAILURE;
1483 break;
1484 }
1485 return mbimStatus;
1486
1487}
1488
1489
1490
1491int translateCregRegisterState2Mbim(int registerState)
1492{
1493 int state;
1494
1495 switch(registerState)
1496 {
1497 case REGSTATUS_NOT_SEARCHING:
1498 state = MBIMRegisterStateDeregistered;
1499 break;
1500
1501 case REGSTATUS_HOME:
1502 state = MBIMRegisterStateHome;
1503 break;
1504
1505 case REGSTATUS_SEARCHING:
1506 state = MBIMRegisterStateSearching;
1507 break;
1508
1509 case REGSTATUS_DENIED:
1510 state = MBIMRegisterStateDenied;
1511 break;
1512
1513 case REGSTATUS_ROAMING:
1514 state = MBIMRegisterStateRoaming;
1515 break;
1516
1517 case REGSTATUS_EMERGENCY_ONLY_NOT_USED:
1518 case REGSTATUS_EMERGENCY_ONLY:
1519 state = MBIMRegisterStateUnknown;
1520 break;
1521
1522 case REGSTATUS_UNKNOWN:
1523 case REGSTATUS_SMS_ONLY_HOME:
1524 case REGSTATUS_SMS_ONLY_ROAMING:
1525 default:
1526 state = MBIMRegisterStateUnknown;
1527 break;
1528 }
1529
1530 return state;
1531
1532
1533}
1534
1535#endif //MBIM_MTIL
1536
1537/*******************************************************************************\
1538* Function: translateMbimFlag2CmglStatus
1539* Description: Translate from MBIM Flag SMS read to CmglStat
1540* Parameters: int - Cops Opt provider STAT
1541* Returns: int - Mbim provider STATE
1542\*******************************************************************************/
1543int translateMbimFlag2CmglStat(int flag)
1544{
1545 int stat = 0;
1546
1547 switch(flag)
1548 {
1549 case MBIMSmsFlagAll:
1550 stat = MSG_MSG_STAT_ALL;
1551 break;
1552 case MBIMSmsFlagNew:
1553 stat = MSG_MSG_STAT_REC_UNREAD;
1554 break;
1555 case MBIMSmsFlagOld:
1556 stat = MSG_MSG_STAT_READ;
1557 break;
1558 case MBIMSmsFlagSent:
1559 stat = MSG_MSG_STAT_STO_SENT;
1560 break;
1561 case MBIMSmsFlagDraft:
1562 stat = MSG_MSG_STAT_STO_UNSENT;
1563 break;
1564 case MBIMSmsFlagIndex:
1565 stat = MSG_MSG_STAT_REC_UNREAD;
1566 break;
1567 default:
1568 stat = MSG_MSG_STAT_ALL;
1569 break;
1570 }
1571
1572 return stat;
1573}
1574
1575/* AT Parser For MBIM Send AT. ------START----- */
1576
1577
1578/**
1579 * Starts tokenizing an AT response string
1580 * returns -1 if this is not a valid response string, 0 on success.
1581 * updates *p_cur with current position
1582 */
1583int at_tok_start(char **p_cur)
1584{
1585 if (*p_cur == NULL)
1586 {
1587 return -1;
1588 }
1589
1590 // skip prefix
1591 // consume "^[^:]:"
1592
1593 *p_cur = strchr(*p_cur, ':');
1594
1595 if (*p_cur == NULL)
1596 {
1597 return -1;
1598 }
1599
1600 (*p_cur)++;
1601
1602 return 0;
1603}
1604
1605static void skipWhiteSpace(char **p_cur)
1606{
1607 if (*p_cur == NULL) return;
1608
1609 while (**p_cur != '\0' && isspace(**p_cur))
1610 {
1611 (*p_cur)++;
1612 }
1613}
1614
1615static void skipNextComma(char **p_cur)
1616{
1617 if (*p_cur == NULL) return;
1618
1619 while (**p_cur != '\0' && **p_cur != ',')
1620 {
1621 (*p_cur)++;
1622 }
1623
1624 if (**p_cur == ',')
1625 {
1626 (*p_cur)++;
1627 }
1628}
1629
1630static char * nextTok(char **p_cur)
1631{
1632 char *ret = NULL;
1633
1634 skipWhiteSpace(p_cur);
1635
1636 if (*p_cur == NULL)
1637 {
1638 ret = NULL;
1639 }
1640 else if (**p_cur == '"')
1641 {
1642 (*p_cur)++;
1643 ret = strsep(p_cur, "\"");
1644 skipNextComma(p_cur);
1645 }
1646 else
1647 {
1648 ret = strsep(p_cur, ",");
1649 }
1650
1651 return ret;
1652}
1653
1654
1655/**
1656 * Parses the next integer in the AT response line and places it in *p_out
1657 * returns 0 on success and -1 on fail
1658 * updates *p_cur
1659 * "base" is the same as the base param in strtol
1660 */
1661
1662static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns)
1663{
1664 char *ret;
1665
1666 if (*p_cur == NULL)
1667 {
1668 return -1;
1669 }
1670
1671 ret = nextTok(p_cur);
1672
1673 if (ret == NULL)
1674 {
1675 return -1;
1676 }
1677 else
1678 {
1679 long l;
1680 char *end;
1681
1682 if (uns)
1683 l = strtoul(ret, &end, base);
1684 else
1685 l = strtol(ret, &end, base);
1686
1687 *p_out = (int)l;
1688 }
1689
1690 return 0;
1691}
1692
1693/**
1694 * Parses the next base 10 integer in the AT response line
1695 * and places it in *p_out
1696 * returns 0 on success and -1 on fail
1697 * updates *p_cur
1698 */
1699int at_tok_nextint(char **p_cur, int *p_out)
1700{
1701 return at_tok_nextint_base(p_cur, p_out, 10, 0);
1702}
1703
1704/**
1705 * Parses the next base 16 integer in the AT response line
1706 * and places it in *p_out
1707 * returns 0 on success and -1 on fail
1708 * updates *p_cur
1709 */
1710int at_tok_nexthexint(char **p_cur, int *p_out)
1711{
1712 return at_tok_nextint_base(p_cur, p_out, 16, 1);
1713}
1714
1715int at_tok_nextbool(char **p_cur, char *p_out)
1716{
1717 int ret;
1718 int result;
1719
1720 ret = at_tok_nextint(p_cur, &result);
1721
1722 if (ret < 0)
1723 {
1724 return -1;
1725 }
1726
1727 // booleans should be 0 or 1
1728 if (!(result == 0 || result == 1))
1729 {
1730 return -1;
1731 }
1732
1733 if (p_out != NULL)
1734 {
1735 *p_out = (char)result;
1736 }
1737
1738 return ret;
1739}
1740
1741int at_tok_nextstr(char **p_cur, char **p_out)
1742{
1743 if (*p_cur == NULL)
1744 {
1745 return -1;
1746 }
1747
1748 *p_out = nextTok(p_cur);
1749
1750 return 0;
1751}
1752
1753/** returns 1 on "has more tokens" and 0 if no */
1754int at_tok_hasmore(char **p_cur)
1755{
1756 return !(*p_cur == NULL || **p_cur == '\0');
1757}
1758
1759/* AT Parser For MBIM Send AT. ------END----- */
1760
1761UINT32 mbim_htonl(UINT32 n)
1762{
1763 return ((n & 0xFF) << 24) |
1764 ((n & 0xFF00) << 8) |
1765 ((n & 0xFF0000UL) >> 8) |
1766 ((n & 0xFF000000UL) >> 24);
1767}
1768
1769
1770UINT32 mbim_getTotalbitOne(UINT32 value)
1771{
1772 UINT32 count = 0;
1773 while(value) {
1774 value = value & (value -1);
1775 count ++;
1776 }
1777
1778 return count;
1779}
1780
1781UINT32 mbimipV4ToUINT(char *addr)
1782{
1783 char *line = strdup(addr);
1784 char *p = line;
1785 char *linesave = line;
1786 UINT8 ip[4] = {0};
1787 int i = 0;
1788 UINT32 ret = 0;
1789
1790 while((p = strsep(&line,"."))!=NULL)
1791 {
1792 ip[i] = atoi(p);
1793 i++;
1794 }
1795
1796 memcpy(&ret, ip, 4);
1797 free(linesave);
1798
1799 return ret;
1800}
1801
1802static UINT32 mbimaddrv6[4];
1803
1804UINT32* mbimipV6ToUINT(char *addr)
1805{
1806 char *line = strdup(addr);
1807 char *p = line;
1808 char *linesave = line;
1809 short ip[8] = {0};
1810 int i = 0;
1811
1812 memset(mbimaddrv6, 0, sizeof(mbimaddrv6));
1813
1814 if (strstr(addr, ":"))
1815 {
1816 while((p = strsep(&line,":"))!=NULL)
1817 {
1818 short tmp = strtoul(p, NULL, 16);
1819 ip[i] = ((tmp&0xFF)<<8)+((tmp&0xFF00)>>8);
1820 i++;
1821 }
1822 }
1823 else if (strstr(addr, "."))
1824 {
1825 char *cip = (char *)ip;
1826 while((p = strsep(&line,"."))!=NULL)
1827 {
1828 cip[i] = (char)strtoul(p, NULL, 10);
1829 i++;
1830 }
1831 }
1832
1833 memcpy(mbimaddrv6, ip, 16);
1834 free(linesave);
1835
1836 return mbimaddrv6;
1837}
1838
1839
1840int mbimisv6addrvalid(unsigned int *v6addr)
1841{
1842 if (v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == 0 && v6addr[3] == 0)
1843 return 0;
1844 else
1845 return 1;
1846}
1847
1848
1849int mbimrsrptorssi(int rsrp)
1850{
1851 int rssi;
1852
1853 if (rsrp== 255){
1854 rssi = 99;
1855 mbimDb.signalState.rssiThreshold = 5;
1856 }else if (rsrp == 1){
1857 rssi = 1;
1858 mbimDb.signalState.rssiThreshold = 1;
1859 }else if (rsrp > 1 && rsrp <= 24){
1860 rssi = rsrp/13 + 2; //rsrp:1 - 24 rsri:2-3
1861 mbimDb.signalState.rssiThreshold = 1;
1862 }else if (rsrp > 24 && rsrp <= 33){
1863 rssi = (rsrp - 24)/4 + 4; //rsrp:24 - 33 rsri:4-6
1864 mbimDb.signalState.rssiThreshold = 2;
1865 }else if (rsrp > 33 && rsrp <= 42){
1866 rssi = (rsrp - 33)/2 + 7; //rsrp:33 - 42 rsri:7-11
1867 mbimDb.signalState.rssiThreshold = 2;
1868 }else if (rsrp > 42 && rsrp <= 54){
1869 rssi = (rsrp - 42)/3 + 12; //rsrp:42 - 54 rsri:12-16
1870 mbimDb.signalState.rssiThreshold = 2;
1871 }else if (rsrp > 54 && rsrp <= 97){
1872 rssi = (rsrp - 54)/3 + 17; //rsrp:54 - 97 rsri:17-31
1873 mbimDb.signalState.rssiThreshold = 5;
1874 }else{
1875 rssi = 99;
1876 mbimDb.signalState.rssiThreshold = 5;
1877 }
1878
1879 return rssi;
1880}
1881
1882int mbimrsrptocodeval(int rsrp)
1883{
1884 if (rsrp == 255)
1885 {
1886 mbimDb.signalState.rsrp5gThreshold = 5;
1887 return 127;
1888 }
1889 else
1890 {
1891 mbimDb.signalState.rsrp5gThreshold = 2;
1892 return rsrp;
1893 }
1894}
1895
1896UINT32 mbim_tlv_new(UINT8 *tlv, int tlv_type, const UINT8 *tlv_data, UINT32 tlv_data_length)
1897{
1898 UINT32 tlv_size;
1899 UINT32 padding_size;
1900
1901 if (tlv_type == MBIM_TLV_TYPE_INVALID)
1902 return 0;
1903
1904 padding_size = (tlv_data_length % 4) ? (4 - (tlv_data_length % 4)) : 0;
1905 tlv_size = 8 + tlv_data_length + padding_size;
1906
1907 MBIM_TLV_FIELD_TYPE (tlv) = tlv_type;
1908 MBIM_TLV_FIELD_RESERVED (tlv) = 0;
1909 MBIM_TLV_FIELD_PADDING_LENGTH (tlv) = padding_size;
1910 MBIM_TLV_FIELD_DATA_LENGTH (tlv) = tlv_data_length;
1911
1912 if (tlv_data && tlv_data_length) {
1913 memcpy (MBIM_TLV_FIELD_DATA (tlv), tlv_data, tlv_data_length);
1914 if (padding_size)
1915 memset (MBIM_TLV_FIELD_DATA (tlv) + tlv_data_length, 0, padding_size);
1916 }
1917
1918 return tlv_size;
1919}
1920
1921UINT32 mbim_tlv_new_str(UINT8 *tlv, UINT8 *str, int len)
1922{
1923 UINT8 *p = (UINT8 *)MBIM_MALLOC(len*2);
1924 if (!p)
1925 return 0;
1926
1927 memset(p, 0, len*2);
1928 int tmplen = copyStrToUtf16((char *)p, (char *)str, len);
1929 UINT32 tlv_size = mbim_tlv_new(tlv, MBIM_TLV_TYPE_WCHAR_STR, p, tmplen);
1930 if (p)
1931 free(p);
1932 return tlv_size;
1933}
1934
1935UINT32 mbim_tlv_new_u16(UINT8 *tlv, UINT8 *array, int len)
1936{
1937 UINT16 *p = (UINT16 *)MBIM_MALLOC(len*sizeof(UINT16));
1938 if (!p)
1939 return 0;
1940
1941 int i = 0;
1942 UINT16 *ptmp = p;
1943 for (i = 0; i < len; i++)
1944 *ptmp++ = (UINT16)array[i];
1945
1946 UINT32 tlv_size = mbim_tlv_new(tlv, MBIM_TLV_TYPE_UINT16_TBL, (UINT8 *)p, len*2);
1947
1948 if (p)
1949 free(p);
1950
1951 return tlv_size;
1952}
1953
1954UINT32 mbim_tlv_new_precfg_dflt_cfg_nssai(UINT8 *tlv, int tlv_type, int acctype, UINT8 *nssaitlv, int nssaitlv_len)
1955{
1956 P_MBIM_MS_PRE_DFLT_NSSAI_INFO pinfo = (P_MBIM_MS_PRE_DFLT_NSSAI_INFO)MBIM_MALLOC(sizeof(MBIM_MS_PRE_DFLT_NSSAI_INFO) + nssaitlv_len);
1957 pinfo->AccessType = acctype;
1958 memcpy((UINT8 *)pinfo+sizeof(MBIM_MS_PRE_DFLT_NSSAI_INFO), nssaitlv, nssaitlv_len);
1959
1960 int len = mbim_tlv_new(tlv, tlv_type, (UINT8*)pinfo, sizeof(MBIM_MS_PRE_DFLT_NSSAI_INFO) + nssaitlv_len);
1961 MBIM_FREE(pinfo);
1962 return len;
1963}
1964
1965UINT8 * mbim_tlv_new_cfg_nssai(int tlv_type, P_MBIM_SNSSAI pNssai, int num, int *tlv_len)
1966{
1967 int len = 0;
1968 int i = 0;
1969 P_MBIM_SNSSAI pns = pNssai;
1970 for (i = 0; i < num; i++,pns++)
1971 len += ((pns->length)+1);
1972
1973 UINT8 *data = (UINT8 *)MBIM_MALLOC(sizeof(UINT8)*len);
1974 UINT8 *pdata = data;
1975 pns = pNssai;
1976 for (i = 0; i < num; i++, pns++)
1977 {
1978 *pdata++ = pns->length;
1979 if (pns->length == 1)
1980 *pdata++ = pns->SliceServiceType;
1981 else if (pns->length == 2)
1982 {
1983 *pdata++ = pns->SliceServiceType;
1984 *pdata++ = pns->MappedSst;
1985 }
1986 else if (pns->length == 4)
1987 {
1988 *pdata++ = pns->SliceServiceType;
1989 *pdata++ = pns->sd[0];
1990 *pdata++ = pns->sd[1];
1991 *pdata++ = pns->sd[2];
1992 }
1993 else if (pns->length == 5)
1994 {
1995 *pdata++ = pns->SliceServiceType;
1996 *pdata++ = pns->sd[0];
1997 *pdata++ = pns->sd[1];
1998 *pdata++ = pns->sd[2];
1999 *pdata++ = pns->MappedSst;
2000 }
2001 else if (pns->length == 8)
2002 {
2003 *pdata++ = pns->SliceServiceType;
2004 *pdata++ = pns->sd[0];
2005 *pdata++ = pns->sd[1];
2006 *pdata++ = pns->sd[2];
2007 *pdata++ = pns->MappedSst;
2008 *pdata++ = pns->MappedSd[0];
2009 *pdata++ = pns->MappedSd[1];
2010 *pdata++ = pns->MappedSd[2];
2011 }
2012 }
2013
2014 UINT8 *tlv = (UINT8 *)MBIM_MALLOC(8+len+4);
2015 *tlv_len = mbim_tlv_new(tlv, tlv_type, data, len);
2016
2017 MBIM_FREE(data);
2018 return tlv;
2019}
2020
2021
2022/*parse nassi,s-nassai formats:
2023 sst
2024 sst;mapped_sst
2025 sst.sd
2026 sst.sd;mapped_sst
2027 sst.sd;mapped_sst.mapped_sd
2028*/
2029int mbim_parse_snssai(P_MBIM_SNSSAI info, char *snssai)
2030{
2031 char *psnssai = strdup(snssai);
2032 char *save = psnssai;
2033 char *q = strsep(&psnssai, ";");
2034 int val = 0;
2035
2036 if (q)
2037 {
2038 char *frg = strdup(q);
2039 char *s = strtok(frg, ".");
2040 if (s)
2041 {
2042 info->length += 1;
2043 sscanf(s,"%02x", &val);
2044 info->SliceServiceType = (UINT8)val;
2045 s = strtok(NULL, ".");
2046 if (s)
2047 {
2048 sscanf(s,"%02x",&val);
2049 info->sd[0] = (UINT8)val;
2050 sscanf(s+2,"%02x",&val);
2051 info->sd[1] = (UINT8)val;
2052 sscanf(s+4,"%02x",&val);
2053 info->sd[2] = (UINT8)val;
2054 info->length += 3;
2055 }
2056 }
2057 free(frg);
2058
2059 q = strsep(&psnssai, ";");
2060 if (q)
2061 {
2062 frg = strdup(q);
2063 char *s = strtok(frg, ".");
2064 if (s)
2065 {
2066 info->length += 1;
2067 sscanf(s,"%02x",&val);
2068 info->MappedSst = (UINT8)val;
2069 s = strtok(NULL, ".");
2070 if (s)
2071 {
2072 sscanf(s,"%02x", &val);
2073 info->MappedSd[0] = (UINT8)val;
2074 sscanf(s+2,"%02x", &val);
2075 info->MappedSd[1] = (UINT8)val;
2076 sscanf(s+4,"%02x", &val);
2077 info->MappedSd[2] = (UINT8)val;
2078 info->length += 3;
2079 }
2080 }
2081 free(frg);
2082 }
2083 }
2084
2085 free(save);
2086 return 0;
2087}
2088
2089short int2bcd(int val)
2090{
2091 char a[4] = { 0 };
2092 memset(a, 0, sizeof(a));
2093 int i = 0;
2094 while (val)
2095 {
2096 a[i++] = val % 10;
2097 val /= 10;
2098 }
2099
2100 return ((a[3] & 0xFF) << 12) | ((a[2] & 0xFF) << 8) | ((a[1] & 0xFF) << 4) | ((a[0] & 0xFF) << 0);
2101}
2102
2103char mbim_hexToNum(char ch)
2104{
2105 ch = toupper(ch);
2106
2107 if (isdigit(ch))
2108 {
2109 ch -= '0';
2110 }
2111 else if (isxdigit(ch))
2112 {
2113 ch -= 'A';
2114 ch += 0x0A;
2115 }
2116 else
2117 {
2118 MBIM_LOGE("%02x is not a hex digit", (UINT8)ch);
2119 }
2120
2121 return ch;
2122}
2123
2124int mbim_ConvertHexToNum(char *inData, int inLen, char *outData)
2125{
2126 int i = 0, j = 0, dataLen = 0;
2127 if (inLen > 0)
2128 {
2129 for (i = 0, j = 0; j < inLen - 1; i++, j = j + 2)
2130 {
2131 outData[i] = (mbim_hexToNum(inData[j]) << 4) + mbim_hexToNum(inData[j + 1]);
2132 }
2133 dataLen = i;
2134 }
2135 else
2136 {
2137 outData[0] = '\0';
2138 dataLen = 0;
2139 }
2140 return dataLen;
2141}
2142
2143void mbim_ConvertNumToHex(char *inData, int inLen, char *outData)
2144{
2145 int i = 0;
2146 char tmpBuf[10];
2147
2148 memset(tmpBuf, 0, sizeof(tmpBuf));
2149
2150 if (inLen > 0)
2151 {
2152 for (i = 0; i < inLen; i++)
2153 {
2154 sprintf(tmpBuf, "%02X", (UINT8)inData[i]);
2155 strcat(outData, tmpBuf);
2156 }
2157 }
2158}
2159
2160void mbim_disableAutoDial(void)
2161{
2162 struct uci_context *_ctx = uci_alloc_context();
2163 struct uci_ptr auto_apn_ptr = {
2164 .package = "wan_default",
2165 .section = "default",
2166 .option = "auto_apn",
2167 .value = "0",
2168 };
2169 struct uci_ptr connect_mode_ptr = {
2170 .package = "wan_default",
2171 .section = "default",
2172 .option = "connect_mode",
2173 .value = "0",
2174 };
2175
2176 uci_set(_ctx, &auto_apn_ptr);
2177 uci_commit(_ctx, &auto_apn_ptr.p, false);
2178 uci_unload(_ctx, auto_apn_ptr.p);
2179
2180 uci_set(_ctx, &connect_mode_ptr);
2181 uci_commit(_ctx, &connect_mode_ptr.p, false);
2182 uci_unload(_ctx, connect_mode_ptr.p);
2183
2184 uci_free_context(_ctx);
2185}