blob: 6e44f7c86d5a2cf258d6f29604a1123797a6d56b [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2014 Marvell International Ltd.
* All Rights Reserved
******************************************************************************/
/* -------------------------------------------------------------------------------------------------------------------
*
* Filename: mbim_util.c
*
* Authors: Adrian Zelezniak
*
* Description: all utiliy functions and macros needed for the MIBM translator
*
* HISTORY:
* Jan 7, 2014 - Initial Version
*
* Notes:
*
******************************************************************************/
#define LOG_TAG "MBIM"
/******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <uci.h>
#include "mbim_types.h"
#include "mbim_protocol.h"
#include "mbim_util.h"
#include "mbim_basic.h"
#include "mbim_sms.h"
#include "mbim_basic_extension.h"
#if defined MBIM_MTIL
#include "mbim_mtil.h"
#else
#include "mbim_ril.h"
#endif
/******************************************************************************
* Defines
******************************************************************************/
//#define LOG_BUF_SIZE 1024
/******************************************************************************
* Enums
******************************************************************************/
/******************************************************************************
* Macros
******************************************************************************/
#define UUID_COMPARE(a,b) memcmp(a,b,16)
#define UUID_COPY(a,b) memcpy(a,b,16)
/******************************************************************************
* External variables
******************************************************************************/
extern MBIM_DATABASE mbimDb;
/******************************************************************************
* Function prototypes
******************************************************************************/
static void trim(char *buffer);
#if defined MBIM_MTIL
extern int DeletePdp(P_MBIM_MESSAGE_CONTEXT pContext, int cid);
#endif
/******************************************************************************
* Code
******************************************************************************/
#if defined SYSLOG
extern int slogFd;
inline void __mbim_log_print(int prio, const char *tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
int write_length;
#if 0
FILE *fdbg;
if (!mbimDb.debug_enable)
return 0;
#endif
if (prio < ANDROID_LOG_VERBOSE)
{
return;
}
write_length = snprintf(buf,LOG_BUF_SIZE,"%s: ",tag);
if (write_length != 0)
{
va_start(ap, fmt);
write_length += vsnprintf(&buf[write_length], LOG_BUF_SIZE, fmt, ap);
va_end(ap);
buf[write_length++] = '\n';
buf[write_length++] = '\r';
#if 0
if ((fdbg = fopen("/tmp/mbimdebug", "r")) != NULL)
{
fclose(fdbg);
printf(buf);
}
else
syslog(0,buf);
#endif
if (slogFd < 0)
slogFd = open("/dev/kmsg", O_RDWR | O_SYNC);
if (slogFd >= 0)
write(slogFd, buf, write_length);
}
return;
}
#endif
/*******************************************************************************\
* Function: logReceivedMbimMsg
* Description: This function records the received command and Transaction Id
* Parameters: int commandNum - The type of MBIM message received
* int transId - This is the unique transaction ID for this command
*
* Returns:
\*******************************************************************************/
void logReceivedMbimMsg(UINT32 msgId, UINT32 transId)
{
char message[20];
switch(msgId)
{
case MBIM_OPEN_MSG_E:
sprintf(message, "OPEN");
break;
case MBIM_CLOSE_MSG_E:
sprintf(message, "CLOSE");
break;
case MBIM_COMMAND_MSG_E:
sprintf(message, "COMMAND");
break;
case MBIM_HOST_ERROR_MSG_E:
sprintf(message, "HOST ERROR");
break;
default:
sprintf(message, "UNKNOWN");
break;
}
MBIM_LOGD("Process %s message: MBIM State = %d, TransId = %d", message, mbimDb.open, transId);
}
/*******************************************************************************\
* Function: logSentMbimMsg
* Description: This function records the sent command and Transaction Id
* Parameters: char *msg --> Pointer to the MBIM Header
*
* Returns:
\*******************************************************************************/
void logSentMbimMsg(char *msg)
{
P_MBIM_MESSAGE_HEADER mbimHdr_p = (P_MBIM_MESSAGE_HEADER)msg;
P_MBIM_COMMAND_DONE commandDone_p = (P_MBIM_COMMAND_DONE)msg;
P_MBIM_INDICATION_STATUS_MSG indicationMsg_p = (P_MBIM_INDICATION_STATUS_MSG)msg;
char rsp[20];
if (msg != NULL)
{
switch(mbimHdr_p->messageType)
{
case MBIM_OPEN_DONE_E:
sprintf(rsp, "OPEN DONE");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
break;
case MBIM_CLOSE_DONE_E:
sprintf(rsp, "CLOSE DONE");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
break;
case MBIM_COMMAND_DONE_E:
sprintf(rsp, "COMMAND DONE");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d, CID = %d", rsp, mbimDb.open, mbimHdr_p->transactionId, commandDone_p->cid);
break;
case MBIM_FUNCTION_ERROR_MSG_E:
sprintf(rsp, "FUNCTION ERROR");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
break;
case MBIM_INDICATE_STATUS_MSG_E:
sprintf(rsp, "INDICATION STATUS");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d, CID = %d", rsp, mbimDb.open, mbimHdr_p->transactionId, indicationMsg_p->cid);
break;
default:
sprintf(rsp, "UNKNOWN");
MBIM_LOGD("Send %s message: MBIM State = %d, TransId = %d", rsp, mbimDb.open, mbimHdr_p->transactionId);
break;
}
}
else
MBIM_LOGE("Trying to send a NULL response to MBIM");
}
/*******************************************************************************\
* Function: UUID2Index
* Description: Convert UUID to index
* Parameters: P_MBIM_UUID uuid - This is a pointer to the 16 bytes UUID
* Returns: index
\*******************************************************************************/
//{a1a2a3a4-b1b2-c1c2-d1d2-e1e2e3e4e5e6} UUID indianess
int UUID2Index (P_MBIM_UUID uuid_p)
{
int index = -1;
if ( UUID_COMPARE(uuid_p, UUID_BASIC_CONNECT) == 0 )
index = UUID_BASIC_CONNECT_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_SMS) == 0 )
index = UUID_SMS_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_USSD) == 0 )
index = UUID_USSD_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_PHONEBOOK) == 0 )
index = UUID_PHONEBOOK_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_STK) == 0 )
index = UUID_STK_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_AUTH) == 0 )
index = UUID_AUTH_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_DSS) == 0 )
index = UUID_DSS_INDEX;
else if ( UUID_COMPARE(uuid_p, UUID_BASIC_CONNECT_EXTENSIONS) == 0 )
index = UUID_BASIC_CONNECT_EXTENSIONS_INDEX;
return index;
}
/*******************************************************************************\
* Function: Index2UUID
* Description: Convert index to UUID
* Parameters: P_MBIM_UUID uuid - This is a pointer to the 16 bytes UUID
* int uuidIndex - The index of the UUID in our code
* Returns: int - Error Value
\*******************************************************************************/
//{a1a2a3a4-b1b2-c1c2-d1d2-e1e2e3e4e5e6} UUID indianess
int Index2UUID (P_MBIM_UUID uuid_p, int uuidIndex)
{
int ret = MBIM_OK;
switch(uuidIndex)
{
case UUID_BASIC_CONNECT_INDEX:
UUID_COPY(uuid_p, UUID_BASIC_CONNECT);
break;
case UUID_SMS_INDEX:
UUID_COPY(uuid_p, UUID_SMS);
break;
case UUID_USSD_INDEX:
UUID_COPY(uuid_p, UUID_USSD);
break;
case UUID_PHONEBOOK_INDEX:
UUID_COPY(uuid_p, UUID_PHONEBOOK);
break;
case UUID_STK_INDEX:
UUID_COPY(uuid_p, UUID_STK);
break;
case UUID_AUTH_INDEX:
UUID_COPY(uuid_p, UUID_AUTH);
break;
case UUID_DSS_INDEX:
UUID_COPY(uuid_p, UUID_DSS);
break;
case UUID_BASIC_CONNECT_EXTENSIONS_INDEX:
UUID_COPY(uuid_p, UUID_BASIC_CONNECT_EXTENSIONS);
break;
case UUID_MS_UICC_LOW_LEVEL_INDEX:
UUID_COPY(uuid_p, UUID_MS_UICC_LOW_LEVEL);
break;
default:
ret = MBIM_UUID_UKNOWN_ERROR;
}
return ret;
}
/*******************************************************************************\
* Function: getNumOfFragments
* Description: Get number of fragments needed to transmit payload
* Parameters: int mbimMsgSize - The size of the message
* int bufLen - The size of the payload we want to send
* Returns: int - Number of fragments
\*******************************************************************************/
int getNumOfFragments(int mbimMsgSize, int bufLen)
{
int numOfFragments;
int fragmentPayloadSize;
int payloadLen = bufLen;
//Each fragment has mandatory MBIM header and MBIM fragment header (So we remove this from usable payload).
fragmentPayloadSize = mbimDb.maxControlTransfer - FRAGMENT_HDR_SIZE;
//We need to remove the MBIM header and frag header from calculation.
payloadLen = (mbimMsgSize + bufLen) - FRAGMENT_HDR_SIZE;
//Calculate now all available data / How much each framgent can carry (integer division, so
numOfFragments = ((payloadLen-1) / fragmentPayloadSize) + 1;
return numOfFragments;
}
void initSessionDb(int sessionId, char *apn, UINT32 ipType, P_MBIM_UUID contextType, int cid)
{
if (sessionId < MAX_NUM_OF_SESSIONS)
{
strncpy(mbimDb.session[sessionId].APN, apn, MBIM_ACCESSSTRING_MAXSIZE/2-1);
memcpy((char *)&mbimDb.session[sessionId].contextType, (char *)contextType, sizeof(MBIM_UUID));
mbimDb.session[sessionId].APN[MBIM_ACCESSSTRING_MAXSIZE/2] = 0;
mbimDb.session[sessionId].cid = cid;
mbimDb.session[sessionId].voiceCallState = MBIMVoiceCallStateNone; //Set to default value
mbimDb.session[sessionId].ipType = ipType;
mbimDb.session[sessionId].sessionState = MBIMActivationStateActivated;
MBIM_LOGD("CID CONNECT - Init Session: sessionId = %d, ipType = %d, APN=%s, Cid = %d", sessionId, ipType, apn, cid);
}
else
{
MBIM_LOGE("CID CONNECT - Init Session: sessionId = %d does not exist", MAX_NUM_OF_SESSIONS);
}
}
void resetSessionDb(int sessionId)
{
// int cid;
if (sessionId < MAX_NUM_OF_SESSIONS)
{
memset( mbimDb.session[sessionId].APN, 0, MBIM_ACCESSSTRING_MAXSIZE/2);
memset( &mbimDb.session[sessionId].contextType, 0, sizeof(MBIM_UUID));
// cid = mbimDb.session[sessionId].cid;
mbimDb.session[sessionId].cid = 0;
mbimDb.session[sessionId].voiceCallState = MBIMVoiceCallStateNone; //Set to default value
mbimDb.session[sessionId].ipType = 0;
mbimDb.session[sessionId].sessionState = MBIMActivationStateUnknown;
MBIM_LOGD("CID CONNECT - reset Session: sessionId = %d", sessionId);
//DeletePdp(NULL, cid);
}
else
{
MBIM_LOGE("CID CONNECT - reset Session: sessionId = %d does not exist", MAX_NUM_OF_SESSIONS);
}
}
int getRegisterTech(int dataClass)
{
int retVal = 0;
if ((dataClass & MBIMDataClassLTE) != 0 )
retVal = 7;
else if (((dataClass & MBIMDataClassHSUPA) != 0 ) &&
((dataClass & MBIMDataClassHSUPA) != 0 ) )
retVal = 6;
else if ((dataClass & MBIMDataClassHSUPA) != 0 )
retVal = 5;
else if ((dataClass & MBIMDataClassHSDPA) != 0 )
retVal = 4;
else if ((dataClass & MBIMDataClassUMTS) != 0 )
retVal = 3;
else if ((dataClass & MBIMDataClassEDGE) != 0 )
retVal = 2;
else if ((dataClass & MBIMDataClassGPRS) != 0 )
retVal = 1;
return retVal;
}
/*******************************************************************************\
* Function: CodeSignalStr2MbimCodedValue
* Description: converts from Measured RSSI to Coded Value used in MBIM_SIGANL_STATE_INFO.
* translation table can be found at Table 10-58 Errata 1
*
* Parameters: int signalStrength
* Returns: Coded signal Strength
\*******************************************************************************/
int CodeSignalStr2MbimCodedValue(int signalStrength)
{
int codedSignalStrength;
if ( signalStrength < (-113) )
codedSignalStrength = 0;
else if (signalStrength > (-51) )
codedSignalStrength = 31;
else
{
//convert to coded signal
codedSignalStrength = (signalStrength + 113)/2;
}
return codedSignalStrength;
}
/*******************************************************************************\
* Function: CodeBer2MbimCodedValue
* Description: converts from Measured BER to Coded Value used in MBIM_SIGANL_STATE_INFO.
* translation table can be found at Table 10-58 Errata 1
*
* Parameters: float - Bit error rate value
* Returns: Returns encoded BER.
\*******************************************************************************/
int CodeBer2MbimCodedValue(float ber)
{
int codedBer = 0, i;
int limit = 2;
ber *= 10;
//Go through all possible coded value, and check if BER is inside range
for (i=0 ; i<7 ; i++)
{
if (ber < (limit << i))
{
codedBer = i;
break;
}
}
return codedBer;
}
/*******************************************************************************\
* Function: CodeBer2MbimCodedValue
* Description: converts from Measured FER to Coded Value used in MBIM_SIGANL_STATE_INFO.
* translation table can be found at Table 10-58 Errata 1
*
* Parameters: float - Frame error rate value
* Returns: Returns encoded FER.
\*******************************************************************************/
int CodeFer2MbimCodedValue(float fer)
{
int codedFer;
fer *= 100;
if (fer < 1)
codedFer = 0;
else if (fer < 10)
codedFer = 1;
else if (fer < 50)
codedFer = 2;
else if (fer < 100)
codedFer = 3;
else if (fer < 200)
codedFer = 4;
else if (fer < 400)
codedFer = 5;
else if (fer < 800)
codedFer = 6;
else
codedFer = 7;
return codedFer;
}
/*******************************************************************************\
* Function: getIpv4MaskLength
* Description: Convert the IPv4 mask, into Mask legnth
* Parameters: UINT32 mask
* Returns: return the length of the mask
\*******************************************************************************/
int getIpv4MaskLength(UINT32 mask)
{
int index;
for (index=0; index < 32 ; index++)
{
if ((mask&0x1) == 1)
break;
//Update mask
mask = (mask>>1);
}
return (32-index);
}
/*******************************************************************************\
* Function: getIpv6MaskLength
* Description:
*
* Parameters: float - Frame error rate value
* Returns: Returns encoded FER.
\*******************************************************************************/
int getIpv6MaskLength(UINT32 *mask)
{
int index, charIndex;
UINT32 temp;
//Count how many UINT32 we have with mask enabled
for (charIndex = 0 ; charIndex < 16 ; charIndex++)
{
if (mask[charIndex] != 0xffffffff)
break;
}
//Search inside of this UINT32 where the Zero starts
temp = mask[charIndex];
for (index=0; index < 32 ; index++)
{
if ((temp&0x1) == 1)
break;
//Update mask
temp = (temp>>1);
}
return (charIndex*32+(32-index));
}
/*******************************************************************
* FUNCTION: checkForNumericOnlyChars
*
* DESCRIPTION: check the given string, validate it only contains numeric
*
* RETURNS: TRUE or FALSE
*
*******************************************************************/
BOOL checkForNumericOnlyChars(const CHAR * password)
{
INT16 passLen = 0;
INT8 count = 0;
BOOL result = TRUE;
passLen = (INT16) strlen((const char *)password);
if (passLen > 0) {
/* Chech each digit */
while ((result == TRUE) && (count < passLen)) {
if ((password[count] < '0') || (password[count] > '9')) {
result = FALSE;
}
count++;
}
}
return (result);
}
/*******************************************************************
* FUNCTION: copyStrToUtf16
*
* DESCRIPTION: Copy normal string into UTF-16 string.
*
* INPUT: char *dst - the destination target (this will be in format UTF-16)
* char *src - the source string (normal used string)
* int sizeOfStr - the size of the original string we are copying
* RETURNS: int - The size of the new string
*
*******************************************************************/
int copyStrToUtf16(char *dst, char*src, int sizeOfStr)
{
int index;
int utf16Index = 0;
//run over al the original string
for (index = 0; index < sizeOfStr ; index++)
{
if (isalnum(src[index])|| ispunct(src[index]) || isspace(src[index]))
{
dst[utf16Index] = src[index];
utf16Index++;
dst[utf16Index] = 0;
utf16Index++;
}
}
return utf16Index;
}
/*******************************************************************
* FUNCTION: copyStrToUtf16
*
* DESCRIPTION: Copy UTF-16 string into normal string.
*
* INPUT: char *dst - the destination target (8 bit string)
* char *src - the source string (this will be in format UTF-16)
* int sizeOfStr - the size of the original UTF-16 string we are copying
* RETURNS: int - The size of the new string
*
*******************************************************************/
int copyUtf16ToStr(char *dst, char*src, int sizeOfUtf16)
{
int index;
int strIndex = 0;
//run over al the UTF16 string and copy to 8bit string
for (index = 0; index < sizeOfUtf16 ; index+=2)
{
dst[strIndex] = src[index];
strIndex++;
}
dst[strIndex] = 0;
return strIndex;
}
/*******************************************************************************\
* Function: pinListFillPinDescriptor (Used on CID_PIN_LIST)
* Description: fill the pin descriptor
* Parameters: P_MBIM_PIN_DESC - Pointer to pin descriptor we want to fill
* ...
* Returns: void
\*******************************************************************************/
void pinListFillPinDescriptor( P_MBIM_PIN_DESC pPinDesc,
MBIM_PIN_MODE_ENUM pinMode,
MBIM_PIN_FORMAT_ENUM pinFormat,
UINT32 pinLengthMax,
UINT32 pinLengthMin)
{
pPinDesc->pinMode = pinMode;
pPinDesc->pinFormat = pinFormat;
pPinDesc->pinLengthMax = pinLengthMax;
pPinDesc->pinLengthMin = pinLengthMin;
}
/*******************************************************************************\
* Function: setRoutingTable (Used on CID_IP_CONFIGURATIONS)
* Description: Set Linux routing tables sodata can be sent after connect PDP
* Parameters: void
* Returns: void
\*******************************************************************************/
void setRoutingTable(int cid)
{
char cmd[200];
MBIM_LOGD("Set Routing Tables Cid = %d", cid);
if (1/*mbimDb.loopbackEnabled == FALSE*/)
{
//Set routing to wotk in Hostless mode
sprintf(cmd, "iptables -t nat -A POSTROUTING -o ccinet%d -j MASQUERADE", cid-1);
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd, "iptables -A FORWARD -i ccinet%d -o usb0 -m state --state RELATED,ESTABLISHED -j ACCEPT", cid-1);
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd, "iptables -A FORWARD -i usb0 -o ccinet%d -j ACCEPT", cid-1);
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd, "ip route del default");
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd,"ip route add default dev ccinet%d",cid-1);
system(cmd);
MBIM_LOGD(cmd);
}
else
{
//Set routing to wotk in Hostless mode
sprintf(cmd, "iptables -t nat -A POSTROUTING -o lo -j MASQUERADE");
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd, "iptables -A FORWARD -i lo -o usb0 -m state --state RELATED,ESTABLISHED -j ACCEPT");
system(cmd);
MBIM_LOGD(cmd);
sprintf(cmd, "iptables -A FORWARD -i usb0 -o lo -j ACCEPT");
system(cmd);
MBIM_LOGD(cmd);
}
}
int getSessionIdFromCid(int cid)
{
int sessionId = MAX_NUM_OF_SESSIONS;
int sessionIndex;
for (sessionIndex = 0 ; sessionIndex < MAX_NUM_OF_SESSIONS ; sessionIndex++)
{
if (mbimDb.session[sessionIndex].cid == cid)
{
sessionId = sessionIndex;
break;
}
}
return sessionId;
}
char hexToNum(char ch)
{
ch = (UINT8) toupper(ch);
if (isdigit(ch)) {
ch -= '0';
} else if (isxdigit(ch)) {
ch -= 'A';
ch += 0x0A;
}
return ch;
}
/*******************************************************************************\
* Function: getFreeSessionId
* Description: Get the first free session ID
* Parameters: void
* Returns: int - return Session ID. If not found return MAX_NUM_OF_SESSIONS
\*******************************************************************************/
int getFreeSessionId(void)
{
int sessionId = MAX_NUM_OF_SESSIONS;
int sessionIndex;
for (sessionIndex = 0 ; sessionIndex < MAX_NUM_OF_SESSIONS ; sessionIndex++)
{
if (mbimDb.session[sessionIndex].cid == 0)
{
sessionId = sessionIndex;
break;
}
}
return sessionId;
}
/*******************************************************************************\
* Function: ReadCOMCfgFileAndSearchValue
* Description: Read COMCfg and search for the value for a specific Token
* Parameters: char *token
* char *value
* Returns: int - 0 - OK, -1 fail
\*******************************************************************************/
int ReadCOMCfgFileAndSearchValue(char * token, char *value)
{
FILE* pComCFG = NULL;
char buffer[256];
size_t len_token;
size_t len_value;
len_token = strlen(token);
len_value = strlen(value);
if((pComCFG = fopen(NVM_DIR "/" COMCFG_FILE,"rt")) != NULL)
{
while(!feof(pComCFG))
{
if ( fgets (buffer , sizeof(buffer) , pComCFG) != NULL )
{
if(strlen(buffer)> 3) //not empty line
{
//remove space characters from string
trim(buffer);
if(strchr( buffer, ',') != NULL)
{
if(strncasecmp(buffer, token, len_token) == 0)
{
if(strncasecmp(buffer + len_token + 1, value, len_value) == 0)
{
fclose(pComCFG);
//The value is found
return 1;
}
}
}
}
}
}//while
fclose(pComCFG);
}
else
{
MBIM_LOGD("fopen %s failed ",NVM_DIR "/" COMCFG_FILE);
return -1;
}
return 0;
}
static void trim(char *buffer)
{
char *p1 = buffer;
char *p2 = buffer;
while (*p1 != 0) {
if ((*p1)<32) {
++p1;
} else
*p2++ = *p1++;
}
*p2 = 0;
}
#if defined USER_STRINGS_ARRAY_CLASS
/***************************************************
* Strings array functions
* A set of functions to handle a dynamic array
* of strings.
**************************************************/
static StringArrayClassS *StringArrayGrow(StringArrayClassS * stringArrayContainer)
{
char **newArray;
int i,j;
newArray = (char **)malloc((stringArrayContainer->allocCount + STRING_ARRAY_DEFAULT_GROW) * sizeof (char *));
if (newArray == NULL) {
StringArrayFree((StringArrayHandleT)stringArrayContainer);
return NULL;
} else {
for (i = 0 ; i < stringArrayContainer->stringsCount ; i++) {
newArray[i] = strdup(stringArrayContainer->stringsArray[i]);
if (newArray[i] == NULL) { // Cleanup in case of alloc fail
StringArrayFree((StringArrayHandleT)stringArrayContainer);
for (j = 0 ; j < i ; j++) {
free(newArray[j]);
}
return NULL;
} else { // free old string memory
free(stringArrayContainer->stringsArray[i]);
}
}
stringArrayContainer->allocCount += STRING_ARRAY_DEFAULT_GROW;
free(stringArrayContainer->stringsArray);
stringArrayContainer->stringsArray = newArray;
}
return stringArrayContainer;
}
StringArrayHandleT StringArrayInit (int count)
{
StringArrayClassS *stringsArrayContainer = NULL;
if (count == 0)
count = STRING_ARRAY_DEFAULT_COUNT;
stringsArrayContainer = (StringArrayClassS *)malloc (sizeof(StringArrayClass));
if (stringsArrayContainer) {
stringsArrayContainer->stringsArray = (char **)malloc(count * sizeof(char *));
if (stringsArrayContainer->stringsArray) {
stringsArrayContainer->stringsCount = 0;
stringsArrayContainer->allocCount = count;
} else {
free (stringsArrayContainer);
stringsArrayContainer = NULL;
}
}
return (StringArrayHandleT)stringsArrayContainer;
}
int StringArrayAddString(StringArrayHandleT handle, char *string)
{
StringArrayClassS *stringsArrayContainer = (StringArrayClassS *)handle;
if (stringsArrayContainer->stringsCount > stringsArrayContainer->allocCount) {
/*
* PRINT WARNING - USED MORE STRINGS THAN ALLOCATED
* CONSIDER ASSERT HERE
*/
StringArrayFree(stringsArrayContainer);
return -1;
}
if (stringsArrayContainer->stringsCount == stringsArrayContainer->allocCount) {
stringsArrayContainer = StringArrayGrow(stringsArrayContainer);
if (stringsArrayContainer == NULL) {
// StringArrayGrow will cleanup if allocation failed
return -1;
}
}
stringsArrayContainer->stringsArray[stringsArrayContainer->stringsCount] = strdup(string);
if (stringsArrayContainer->stringsArray[stringsArrayContainer->stringsCount]) {
stringsArrayContainer->stringsCount++;
} else {
StringArrayFree(stringsArrayContainer);
return -1;
}
return 0;
}
char ** StringArrayGetStrings(StringArrayHandleT handle)
{
return (((StringArrayClassS *)handle)->stringsArray);
}
int StringArrayGetCount(StringArrayHandleT handle)
{
return (((StringArrayClassS *)handle)->allocCount);
}
void StringArrayFree(StringArrayHandleT handle)
{
int i;
StringArrayClassS *stringsArrayContainer = (StringArrayClassS *)handle;
for (i = 0 ; i < stringsArrayContainer->allocCount ; i++) {
free(stringsArrayContainer->stringsArray[i]);
}
free(stringsArrayContainer);
}
#endif //USER_STRINGS_ARRAY_CLASS
#if defined MBIM_MTIL
/*******************************************************************************\
* Function: MtilSimStatus2MbimSubscriberReadyState
* Description: This function converts the received return code and pin code status to MBIM subscriber
* ready status.
* Parameters: ret_code - The ret-code status for the pin
* pin_code - The status of the pin_code
* Returns: int, returns the Mbim Subscriber ready State
\*******************************************************************************/
int MtilSimStatus2MbimSubscriberReadyState(int ret_code, int pin_code)
{
UINT32 subsState;
switch(ret_code)
{
case MTIL_CODE_AT_OK:
{
if (pin_code == MTIL_PIN_STATUS_READY)
{
subsState = MBIMSubscriberReadyStateInitialized;
}
else if (pin_code == MTIL_PIN_STATUS_SIM_REMOVED)
{
subsState = MBIMSubscriberReadyStateSimNotInserted;
}
else if (pin_code == MTIL_PIN_STATUS_NETWORK_REJECTED)
{
subsState = MBIMSubscriberReadyStateNotActivated;
}
else if (pin_code == MTIL_PIN_STATUS_UNKNOWN)
{
subsState = MBIMSubscriberReadyStateBadSim;
}
else
{
subsState = MBIMSubscriberReadyStateDeviceLocked;
}
}
break;
case MTIL_CODE_AT_ERR_SIM_FAILURE:
case MTIL_CODE_AT_ERR_SIM_WRONG:
case MTIL_CODE_AT_ERR_INCORRECT_PASS:
subsState = MBIMSubscriberReadyStateBadSim;
break;
case MTIL_CODE_AT_ERR_SIM_NOT_INSERTED:
subsState = MBIMSubscriberReadyStateSimNotInserted;
break;
case MTIL_CODE_AT_ERR_SIM_PIN_REQ:
case MTIL_CODE_AT_ERR_SIM_PUK_REQ:
case MTIL_CODE_AT_ERR_SIM_PIN2_REQ:
case MTIL_CODE_AT_ERR_SIM_PUK2_REQ:
subsState = MBIMSubscriberReadyStateDeviceLocked;
break;
default:
subsState = MBIMSubscriberReadyStateNotInitialized;
break;
}
return subsState;
}
/*******************************************************************************\
* Function: MtilCauseCodeForNwError2Mbim
* Description: converts from General NW error, to the MBIM NW error
* Parameters: UINT32 - Received the NW error sent by comm
*
* Returns: int - returns the MBIM NW error
\*******************************************************************************/
int MtilCauseCodeForNwError2Mbim(UINT32 result)
{
//This needs more considration (For now looks as match)
return (result%100);
}
/*******************************************************************************\
* Function: getMaxDataClassSupported
* Description: Retruns the supported data class technologies
* Parameters: Pointer to CNTI response message
* Returns: Returns a bitmap mask for the supported class technologies
\*******************************************************************************/
int getMaxDataClassSupported(P_MTIL_CNTI_STATUS_MSG pCnti)
{
UINT32 dataClass = 0;
//This needs more considration (For now looks as match)
if (pCnti->epsActive)
dataClass |= MBIMDataClassLTE;
if (pCnti->hsdpaActive)
dataClass |= MBIMDataClassHSDPA;
if (pCnti->hsupaActive)
dataClass |= MBIMDataClassHSUPA;
if (pCnti->act == MTIL_MM_ACT_UTRAN)
dataClass |= MBIMDataClassUMTS;
if (pCnti->egprsActive)
dataClass |= MBIMDataClassEDGE;
if (pCnti->gprsActive)
dataClass |= MBIMDataClassGPRS;
if (pCnti->act == MTIL_MM_ACT_GSM)
dataClass |= MBIMDataClassNone;
return dataClass;
}
/*******************************************************************************\
* Function: getMaxDataClassAvailable
* Description: Retruns the supported data class technologies
* Parameters: Pointer to CNTI response message
* Returns: Returns a bitmap mask for the supported class technologies
\*******************************************************************************/
int getMaxDataClassAvailable(P_MTIL_CNTI_STATUS_MSG pCnti, UINT64 *dlSpeed, UINT64 *ulSpeed)
{
UINT32 dataClass = MTIL_MM_NETWORK_MODE_REPORT_EUTRA_EPS;
//workaround for LTE (adrian)
if (pCnti->mode == 0)
pCnti->mode = MBIMDataClassLTE;
switch (pCnti->mode)
{
case MTIL_MM_NETWORK_MODE_REPORT_GSM:
dataClass = 0;
((UINT32 *)dlSpeed)[0] = 0;
((UINT32 *)ulSpeed)[0] = 0;
break;
case MTIL_MM_NETWORK_MODE_REPORT_UMTS:
dataClass = MBIMDataClassUMTS;
((UINT32 *)dlSpeed)[0] = 384000;
((UINT32 *)ulSpeed)[0] = 384000;
break;
case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSDPA:
dataClass = MBIMDataClassHSDPA;
((UINT32 *)dlSpeed)[0] = 42000000;
((UINT32 *)ulSpeed)[0] = 384000;
break;
case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSUPA:
dataClass = MBIMDataClassHSUPA;
((UINT32 *)dlSpeed)[0] = 384000;
((UINT32 *)ulSpeed)[0] = 5760000;
break;
case MTIL_MM_NETWORK_MODE_REPORT_UMTS_HSDPA_HSUPA:
dataClass = MBIMDataClassHSUPA | MBIMDataClassHSDPA;
((UINT32 *)dlSpeed)[0] = 42000000;
((UINT32 *)ulSpeed)[0] = 5760000;
break;
case MTIL_MM_NETWORK_MODE_REPORT_GSM_EGPRS:
dataClass = MBIMDataClassEDGE;
((UINT32 *)dlSpeed)[0] = 236800;
((UINT32 *)ulSpeed)[0] = 118400;
break;
case MTIL_MM_NETWORK_MODE_REPORT_GSM_GPRS:
dataClass = MBIMDataClassGPRS;
((UINT32 *)dlSpeed)[0] = 48000;
((UINT32 *)ulSpeed)[0] = 24000;
break;
case MTIL_MM_NETWORK_MODE_REPORT_EUTRA_EPS:
dataClass = MBIMDataClassLTE;
((UINT32 *)dlSpeed)[0] = 100000000;
((UINT32 *)ulSpeed)[0] = 50000000;
break;
default:
dataClass = MBIMDataClassLTE;
((UINT32 *)dlSpeed)[0] = 100000000;
((UINT32 *)ulSpeed)[0] = 50000000;
break;
}
((UINT32 *)dlSpeed)[1] = 0;
((UINT32 *)ulSpeed)[1] = 0;
return dataClass;
}
/*******************************************************************************\
* Function: transCregAct2Mbim
* Description: translate CregAct 2 Mbim
*
* Parameters: int ACT
* Returns: Technology in use
\*******************************************************************************/
int transCregAct2Mbim(int act)
{
int retVal = 0;
switch(act)
{
case 0: // GSM
retVal = MBIMDataClassNone;
break;
case 6: // GSM w/GPRS
retVal = MBIMDataClassGPRS;
break;
case 5: //GSM w/EGPRS
retVal = MBIMDataClassEDGE;
break;
case 1: // UTRAN
retVal = MBIMDataClassUMTS;
break;
case 2: //UTRAN w/HSDPA
retVal = MBIMDataClassHSDPA;
break;
case 3: //UTRAN w/HSUPA
retVal = MBIMDataClassHSUPA;
break;
case 4: //UTRAN w/HSDPA + HSUPA
retVal = MBIMDataClassHSUPA | MBIMDataClassHSDPA;
break;
case 7:
retVal = MBIMDataClassLTE;
break;
default:
return 0;// - Unknown
}
MBIM_LOGD("Data Class = %d", retVal);
return retVal;
}
/*******************************************************************
* FUNCTION: translateSimMsg2MbimSimMsg
*
* DESCRIPTION: Translate from COMM response about SIM to MBIM SIM MSG
*
* INPUT: int - The Sm Message received from MTIL server
* RETURNS: int - Represnting the MbimPinType
*
*******************************************************************/
int translateSimMsg2MbimSimMsg(int simMsg)
{
int retVal = MTIL_CODE_AT_ERR_UNKNOWN;
switch (simMsg)
{
case MTIL_PIN_STATUS_READY:
retVal = MBIMPinTypeNone;
break;
case MTIL_PIN_STATUS_SIM_PIN:
retVal = MBIMPinTypePin1;
break;
case MTIL_PIN_STATUS_SIM_PIN2:
retVal = MBIMPinTypePin2;
break;
case MTIL_PIN_STATUS_SIM_PUK:
retVal = MBIMPinTypePuk1;
break;
case MTIL_PIN_STATUS_SIM_PUK2:
retVal = MBIMPinTypePuk2;
break;
default:
retVal = MBIMPinTypeCustom;
break;
}
return retVal;
}
/*******************************************************************
* FUNCTION: translateCopsRegMode
*
* DESCRIPTION: Translate COPS registration mode to MBIM registration Mode
*
* INPUT: int regMode - COPS registration mode
* RETURNS: int - MBIM registration mode
*
*******************************************************************/
int translateCopsRegMode(int regMode)
{
int mbimRegMode;
switch (regMode)
{
case 0:
mbimRegMode = MBIMRegisterModeAutomatic;
break;
case 1:
mbimRegMode = MBIMRegisterModeManual;
break;
default:
mbimRegMode = MBIMRegisterModeUnknown;
break;
}
return mbimRegMode;
}
/*******************************************************************
* FUNCTION: translateCgattState
*
* DESCRIPTION: Translate CGATT state to MBIM State
*
* INPUT: int regMode - COPS registration mode
* RETURNS: int - MBIM registration mode
*
*******************************************************************/
int translateCgattState(int state)
{
int mbimState;
switch (state)
{
case 0:
mbimState = MBIMPacketServiceStateDetached;
break;
case 1:
mbimState = MBIMPacketServiceStateAttached;
break;
default:
mbimState = MBIMPacketServiceStateUnknown;
break;
}
return mbimState;
}
/*******************************************************************************\
* Function: setRoutingTable (Used on CID_IP_CONFIGURATIONS)
* Description: Translate from Cops Provider state to MBIM provider State
* Parameters: int - Cops Opt provider STAT
* Returns: int - Mbim provider STATE
\*******************************************************************************/
int translateCopsProvider2MbimProvider(int stat)
{
int mbimStat;
switch(stat)
{
case 0: //Unknown
mbimStat = MBIM_PROVIDER_STATE_UNKNOWN;
break;
case 1: //Avaiable
mbimStat = MBIM_PROVIDER_STATE_PREFERRED;
break;
case 2: //Current
mbimStat = MBIM_PROVIDER_STATE_REGISTERED;
break;
case 3: //forbidden
mbimStat = MBIM_PROVIDER_STATE_FORBIDDEN;
break;
default:
mbimStat = MBIM_PROVIDER_STATE_UNKNOWN;
break;
}
return mbimStat;
}
/*******************************************************************************\
* Function: translateMbimFlag2CmglStatus
* Description: Translate from MBIM Flag SMS read to CmglStat
* Parameters: int - Cops Opt provider STAT
* Returns: int - Mbim provider STATE
\*******************************************************************************/
int translateMbimFlag2CmglStat(int flag)
{
int stat = 0;
switch(flag)
{
case MBIMSmsFlagAll:
stat = MSG_MSG_STAT_ALL;
break;
case MBIMSmsFlagNew:
stat = MSG_MSG_STAT_REC_UNREAD;
break;
case MBIMSmsFlagOld:
stat = MSG_MSG_STAT_READ;
break;
case MBIMSmsFlagSent:
stat = MSG_MSG_STAT_STO_SENT;
break;
case MBIMSmsFlagDraft:
stat = MSG_MSG_STAT_STO_UNSENT;
break;
default:
stat = MSG_MSG_STAT_ALL;
break;
}
return stat;
}
/*******************************************************************************\
* Function: translateMbimFlag2CmglStatus
* Description: Translate from MBIM Flag SMS read to CmgrStat
* Parameters: int -
* Returns: int -
\*******************************************************************************/
int translateCmgrStat2MbimMessageStat(int status)
{
int stat = 0;
switch(status)
{
case MSG_MSG_STAT_REC_UNREAD:
stat = MBIMSmsStatusNew;
break;
case MSG_MSG_STAT_READ:
stat = MBIMSmsStatusOld;
break;
case MSG_MSG_STAT_STO_UNSENT:
stat = MBIMSmsStatusDraft;
break;
case MSG_MSG_STAT_STO_SENT:
stat = MBIMSmsStatusSent;
break;
default:
stat = MBIMSmsStatusNew;
break;
}
return stat;
}
/************************************************************************************
* F@: translateMbimFlag2CmgdFlag - Convert SMS delete flag
*
*/
/*******************************************************************************\
* Function: translateMbimFlag2CmgdFlag
* Description: Translate from MBIM flag to SMS flag
* Parameters: int - Mbim Flag
* Returns: int - Flag
\*******************************************************************************/
int translateMbimFlag2CmgdFlag(UINT8 mbimFlag)
{
int Flag;
switch (mbimFlag)
{
case MBIMSmsFlagIndex:
Flag = MSG_MSG_DELFLAG_INDEX;
break;
case MBIMSmsFlagOld:
Flag = MSG_MSG_DELFLAG_ALL_READ;
break;
case MBIMSmsFlagSent:
Flag = MSG_MSG_DELFLAG_ALL_READ_OR_SENT;
break;
case MBIMSmsFlagDraft:
Flag = MSG_MSG_DELFLAG_ALL_READ_OR_MO;
break;
case MBIMSmsFlagAll:
default:
Flag = MSG_MSG_DELFLAG_ALL;
break;
}
return Flag;
}
/*******************************************************************************\
* Function: translateSmsStatus2MbimSmsStatus
* Description: Translate from SMS status to MBIM SMS status
* Parameters: int - Cops Opt provider STAT
* Returns: int - Mbim provider STATE
\*******************************************************************************/
int translateSmsStatus2MbimSmsStatus(int smsStatus)
{
int mbimStatus = 0;
switch(smsStatus)
{
case MTIL_CODE_AT_ERR_SMS_INVALID_INDEX:
mbimStatus = MBIM_STATUS_INVALID_MEMORY_INDEX;
break;
case MTIL_CODE_AT_ERR_INVALID_PDU_MODE_PARAM:
case MTIL_CODE_AT_ERR_INVALID_TEXT_MODE_PARAM:
mbimStatus = MBIM_STATUS_SMS_FORMAT_NOT_SUPPORTED;
break;
case MTIL_CODE_AT_ERR_SMS_MEMORY_FAILURE:
mbimStatus = MBIM_STATUS_MEMORY_FAILURE;
break;
case MTIL_CODE_AT_ERR_SMS_OPER_NOT_SUPPORTED:
mbimStatus = MBIM_STATUS_FILTER_NOT_SUPPORTED;
break;
default:
mbimStatus = MBIM_STATUS_MEMORY_FAILURE;
break;
}
return mbimStatus;
}
int translateCregRegisterState2Mbim(int registerState)
{
int state;
switch(registerState)
{
case REGSTATUS_NOT_SEARCHING:
state = MBIMRegisterStateDeregistered;
break;
case REGSTATUS_HOME:
state = MBIMRegisterStateHome;
break;
case REGSTATUS_SEARCHING:
state = MBIMRegisterStateSearching;
break;
case REGSTATUS_DENIED:
state = MBIMRegisterStateDenied;
break;
case REGSTATUS_ROAMING:
state = MBIMRegisterStateRoaming;
break;
case REGSTATUS_EMERGENCY_ONLY_NOT_USED:
case REGSTATUS_EMERGENCY_ONLY:
state = MBIMRegisterStateUnknown;
break;
case REGSTATUS_UNKNOWN:
case REGSTATUS_SMS_ONLY_HOME:
case REGSTATUS_SMS_ONLY_ROAMING:
default:
state = MBIMRegisterStateUnknown;
break;
}
return state;
}
#endif //MBIM_MTIL
/*******************************************************************************\
* Function: translateMbimFlag2CmglStatus
* Description: Translate from MBIM Flag SMS read to CmglStat
* Parameters: int - Cops Opt provider STAT
* Returns: int - Mbim provider STATE
\*******************************************************************************/
int translateMbimFlag2CmglStat(int flag)
{
int stat = 0;
switch(flag)
{
case MBIMSmsFlagAll:
stat = MSG_MSG_STAT_ALL;
break;
case MBIMSmsFlagNew:
stat = MSG_MSG_STAT_REC_UNREAD;
break;
case MBIMSmsFlagOld:
stat = MSG_MSG_STAT_READ;
break;
case MBIMSmsFlagSent:
stat = MSG_MSG_STAT_STO_SENT;
break;
case MBIMSmsFlagDraft:
stat = MSG_MSG_STAT_STO_UNSENT;
break;
case MBIMSmsFlagIndex:
stat = MSG_MSG_STAT_REC_UNREAD;
break;
default:
stat = MSG_MSG_STAT_ALL;
break;
}
return stat;
}
/* AT Parser For MBIM Send AT. ------START----- */
/**
* Starts tokenizing an AT response string
* returns -1 if this is not a valid response string, 0 on success.
* updates *p_cur with current position
*/
int at_tok_start(char **p_cur)
{
if (*p_cur == NULL)
{
return -1;
}
// skip prefix
// consume "^[^:]:"
*p_cur = strchr(*p_cur, ':');
if (*p_cur == NULL)
{
return -1;
}
(*p_cur)++;
return 0;
}
static void skipWhiteSpace(char **p_cur)
{
if (*p_cur == NULL) return;
while (**p_cur != '\0' && isspace(**p_cur))
{
(*p_cur)++;
}
}
static void skipNextComma(char **p_cur)
{
if (*p_cur == NULL) return;
while (**p_cur != '\0' && **p_cur != ',')
{
(*p_cur)++;
}
if (**p_cur == ',')
{
(*p_cur)++;
}
}
static char * nextTok(char **p_cur)
{
char *ret = NULL;
skipWhiteSpace(p_cur);
if (*p_cur == NULL)
{
ret = NULL;
}
else if (**p_cur == '"')
{
(*p_cur)++;
ret = strsep(p_cur, "\"");
skipNextComma(p_cur);
}
else
{
ret = strsep(p_cur, ",");
}
return ret;
}
/**
* Parses the next integer in the AT response line and places it in *p_out
* returns 0 on success and -1 on fail
* updates *p_cur
* "base" is the same as the base param in strtol
*/
static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns)
{
char *ret;
if (*p_cur == NULL)
{
return -1;
}
ret = nextTok(p_cur);
if (ret == NULL)
{
return -1;
}
else
{
long l;
char *end;
if (uns)
l = strtoul(ret, &end, base);
else
l = strtol(ret, &end, base);
*p_out = (int)l;
}
return 0;
}
/**
* Parses the next base 10 integer in the AT response line
* and places it in *p_out
* returns 0 on success and -1 on fail
* updates *p_cur
*/
int at_tok_nextint(char **p_cur, int *p_out)
{
return at_tok_nextint_base(p_cur, p_out, 10, 0);
}
/**
* Parses the next base 16 integer in the AT response line
* and places it in *p_out
* returns 0 on success and -1 on fail
* updates *p_cur
*/
int at_tok_nexthexint(char **p_cur, int *p_out)
{
return at_tok_nextint_base(p_cur, p_out, 16, 1);
}
int at_tok_nextbool(char **p_cur, char *p_out)
{
int ret;
int result;
ret = at_tok_nextint(p_cur, &result);
if (ret < 0)
{
return -1;
}
// booleans should be 0 or 1
if (!(result == 0 || result == 1))
{
return -1;
}
if (p_out != NULL)
{
*p_out = (char)result;
}
return ret;
}
int at_tok_nextstr(char **p_cur, char **p_out)
{
if (*p_cur == NULL)
{
return -1;
}
*p_out = nextTok(p_cur);
return 0;
}
/** returns 1 on "has more tokens" and 0 if no */
int at_tok_hasmore(char **p_cur)
{
return !(*p_cur == NULL || **p_cur == '\0');
}
/* AT Parser For MBIM Send AT. ------END----- */
UINT32 mbim_htonl(UINT32 n)
{
return ((n & 0xFF) << 24) |
((n & 0xFF00) << 8) |
((n & 0xFF0000UL) >> 8) |
((n & 0xFF000000UL) >> 24);
}
UINT32 mbim_getTotalbitOne(UINT32 value)
{
UINT32 count = 0;
while(value) {
value = value & (value -1);
count ++;
}
return count;
}
UINT32 mbimipV4ToUINT(char *addr)
{
char *line = strdup(addr);
char *p = line;
char *linesave = line;
UINT8 ip[4] = {0};
int i = 0;
UINT32 ret = 0;
while((p = strsep(&line,"."))!=NULL)
{
ip[i] = atoi(p);
i++;
}
memcpy(&ret, ip, 4);
free(linesave);
return ret;
}
static UINT32 mbimaddrv6[4];
UINT32* mbimipV6ToUINT(char *addr)
{
char *line = strdup(addr);
char *p = line;
char *linesave = line;
short ip[8] = {0};
int i = 0;
memset(mbimaddrv6, 0, sizeof(mbimaddrv6));
if (strstr(addr, ":"))
{
while((p = strsep(&line,":"))!=NULL)
{
short tmp = strtoul(p, NULL, 16);
ip[i] = ((tmp&0xFF)<<8)+((tmp&0xFF00)>>8);
i++;
}
}
else if (strstr(addr, "."))
{
char *cip = (char *)ip;
while((p = strsep(&line,"."))!=NULL)
{
cip[i] = (char)strtoul(p, NULL, 10);
i++;
}
}
memcpy(mbimaddrv6, ip, 16);
free(linesave);
return mbimaddrv6;
}
int mbimisv6addrvalid(unsigned int *v6addr)
{
if (v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == 0 && v6addr[3] == 0)
return 0;
else
return 1;
}
int mbimrsrptorssi(int rsrp)
{
int rssi;
if (rsrp== 255){
rssi = 99;
mbimDb.signalState.rssiThreshold = 5;
}else if (rsrp == 1){
rssi = 1;
mbimDb.signalState.rssiThreshold = 1;
}else if (rsrp > 1 && rsrp <= 24){
rssi = rsrp/13 + 2; //rsrp:1 - 24 rsri:2-3
mbimDb.signalState.rssiThreshold = 1;
}else if (rsrp > 24 && rsrp <= 33){
rssi = (rsrp - 24)/4 + 4; //rsrp:24 - 33 rsri:4-6
mbimDb.signalState.rssiThreshold = 2;
}else if (rsrp > 33 && rsrp <= 42){
rssi = (rsrp - 33)/2 + 7; //rsrp:33 - 42 rsri:7-11
mbimDb.signalState.rssiThreshold = 2;
}else if (rsrp > 42 && rsrp <= 54){
rssi = (rsrp - 42)/3 + 12; //rsrp:42 - 54 rsri:12-16
mbimDb.signalState.rssiThreshold = 2;
}else if (rsrp > 54 && rsrp <= 97){
rssi = (rsrp - 54)/3 + 17; //rsrp:54 - 97 rsri:17-31
mbimDb.signalState.rssiThreshold = 5;
}else{
rssi = 99;
mbimDb.signalState.rssiThreshold = 5;
}
return rssi;
}
int mbimrsrptocodeval(int rsrp)
{
if (rsrp == 255)
{
mbimDb.signalState.rsrp5gThreshold = 5;
return 127;
}
else
{
mbimDb.signalState.rsrp5gThreshold = 2;
return rsrp;
}
}
UINT32 mbim_tlv_new(UINT8 *tlv, int tlv_type, const UINT8 *tlv_data, UINT32 tlv_data_length)
{
UINT32 tlv_size;
UINT32 padding_size;
if (tlv_type == MBIM_TLV_TYPE_INVALID)
return 0;
padding_size = (tlv_data_length % 4) ? (4 - (tlv_data_length % 4)) : 0;
tlv_size = 8 + tlv_data_length + padding_size;
MBIM_TLV_FIELD_TYPE (tlv) = tlv_type;
MBIM_TLV_FIELD_RESERVED (tlv) = 0;
MBIM_TLV_FIELD_PADDING_LENGTH (tlv) = padding_size;
MBIM_TLV_FIELD_DATA_LENGTH (tlv) = tlv_data_length;
if (tlv_data && tlv_data_length) {
memcpy (MBIM_TLV_FIELD_DATA (tlv), tlv_data, tlv_data_length);
if (padding_size)
memset (MBIM_TLV_FIELD_DATA (tlv) + tlv_data_length, 0, padding_size);
}
return tlv_size;
}
UINT32 mbim_tlv_new_str(UINT8 *tlv, UINT8 *str, int len)
{
UINT8 *p = (UINT8 *)MBIM_MALLOC(len*2);
if (!p)
return 0;
memset(p, 0, len*2);
int tmplen = copyStrToUtf16((char *)p, (char *)str, len);
UINT32 tlv_size = mbim_tlv_new(tlv, MBIM_TLV_TYPE_WCHAR_STR, p, tmplen);
if (p)
free(p);
return tlv_size;
}
UINT32 mbim_tlv_new_u16(UINT8 *tlv, UINT8 *array, int len)
{
UINT16 *p = (UINT16 *)MBIM_MALLOC(len*sizeof(UINT16));
if (!p)
return 0;
int i = 0;
UINT16 *ptmp = p;
for (i = 0; i < len; i++)
*ptmp++ = (UINT16)array[i];
UINT32 tlv_size = mbim_tlv_new(tlv, MBIM_TLV_TYPE_UINT16_TBL, (UINT8 *)p, len*2);
if (p)
free(p);
return tlv_size;
}
UINT32 mbim_tlv_new_precfg_dflt_cfg_nssai(UINT8 *tlv, int tlv_type, int acctype, UINT8 *nssaitlv, int nssaitlv_len)
{
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);
pinfo->AccessType = acctype;
memcpy((UINT8 *)pinfo+sizeof(MBIM_MS_PRE_DFLT_NSSAI_INFO), nssaitlv, nssaitlv_len);
int len = mbim_tlv_new(tlv, tlv_type, (UINT8*)pinfo, sizeof(MBIM_MS_PRE_DFLT_NSSAI_INFO) + nssaitlv_len);
MBIM_FREE(pinfo);
return len;
}
UINT8 * mbim_tlv_new_cfg_nssai(int tlv_type, P_MBIM_SNSSAI pNssai, int num, int *tlv_len)
{
int len = 0;
int i = 0;
P_MBIM_SNSSAI pns = pNssai;
for (i = 0; i < num; i++,pns++)
len += ((pns->length)+1);
UINT8 *data = (UINT8 *)MBIM_MALLOC(sizeof(UINT8)*len);
UINT8 *pdata = data;
pns = pNssai;
for (i = 0; i < num; i++, pns++)
{
*pdata++ = pns->length;
if (pns->length == 1)
*pdata++ = pns->SliceServiceType;
else if (pns->length == 2)
{
*pdata++ = pns->SliceServiceType;
*pdata++ = pns->MappedSst;
}
else if (pns->length == 4)
{
*pdata++ = pns->SliceServiceType;
*pdata++ = pns->sd[0];
*pdata++ = pns->sd[1];
*pdata++ = pns->sd[2];
}
else if (pns->length == 5)
{
*pdata++ = pns->SliceServiceType;
*pdata++ = pns->sd[0];
*pdata++ = pns->sd[1];
*pdata++ = pns->sd[2];
*pdata++ = pns->MappedSst;
}
else if (pns->length == 8)
{
*pdata++ = pns->SliceServiceType;
*pdata++ = pns->sd[0];
*pdata++ = pns->sd[1];
*pdata++ = pns->sd[2];
*pdata++ = pns->MappedSst;
*pdata++ = pns->MappedSd[0];
*pdata++ = pns->MappedSd[1];
*pdata++ = pns->MappedSd[2];
}
}
UINT8 *tlv = (UINT8 *)MBIM_MALLOC(8+len+4);
*tlv_len = mbim_tlv_new(tlv, tlv_type, data, len);
MBIM_FREE(data);
return tlv;
}
/*parse nassi,s-nassai formats:
sst
sst;mapped_sst
sst.sd
sst.sd;mapped_sst
sst.sd;mapped_sst.mapped_sd
*/
int mbim_parse_snssai(P_MBIM_SNSSAI info, char *snssai)
{
char *psnssai = strdup(snssai);
char *save = psnssai;
char *q = strsep(&psnssai, ";");
int val = 0;
if (q)
{
char *frg = strdup(q);
char *s = strtok(frg, ".");
if (s)
{
info->length += 1;
sscanf(s,"%02x", &val);
info->SliceServiceType = (UINT8)val;
s = strtok(NULL, ".");
if (s)
{
sscanf(s,"%02x",&val);
info->sd[0] = (UINT8)val;
sscanf(s+2,"%02x",&val);
info->sd[1] = (UINT8)val;
sscanf(s+4,"%02x",&val);
info->sd[2] = (UINT8)val;
info->length += 3;
}
}
free(frg);
q = strsep(&psnssai, ";");
if (q)
{
frg = strdup(q);
char *s = strtok(frg, ".");
if (s)
{
info->length += 1;
sscanf(s,"%02x",&val);
info->MappedSst = (UINT8)val;
s = strtok(NULL, ".");
if (s)
{
sscanf(s,"%02x", &val);
info->MappedSd[0] = (UINT8)val;
sscanf(s+2,"%02x", &val);
info->MappedSd[1] = (UINT8)val;
sscanf(s+4,"%02x", &val);
info->MappedSd[2] = (UINT8)val;
info->length += 3;
}
}
free(frg);
}
}
free(save);
return 0;
}
short int2bcd(int val)
{
char a[4] = { 0 };
memset(a, 0, sizeof(a));
int i = 0;
while (val)
{
a[i++] = val % 10;
val /= 10;
}
return ((a[3] & 0xFF) << 12) | ((a[2] & 0xFF) << 8) | ((a[1] & 0xFF) << 4) | ((a[0] & 0xFF) << 0);
}
char mbim_hexToNum(char ch)
{
ch = toupper(ch);
if (isdigit(ch))
{
ch -= '0';
}
else if (isxdigit(ch))
{
ch -= 'A';
ch += 0x0A;
}
else
{
MBIM_LOGE("%02x is not a hex digit", (UINT8)ch);
}
return ch;
}
int mbim_ConvertHexToNum(char *inData, int inLen, char *outData)
{
int i = 0, j = 0, dataLen = 0;
if (inLen > 0)
{
for (i = 0, j = 0; j < inLen - 1; i++, j = j + 2)
{
outData[i] = (mbim_hexToNum(inData[j]) << 4) + mbim_hexToNum(inData[j + 1]);
}
dataLen = i;
}
else
{
outData[0] = '\0';
dataLen = 0;
}
return dataLen;
}
void mbim_ConvertNumToHex(char *inData, int inLen, char *outData)
{
int i = 0;
char tmpBuf[10];
memset(tmpBuf, 0, sizeof(tmpBuf));
if (inLen > 0)
{
for (i = 0; i < inLen; i++)
{
sprintf(tmpBuf, "%02X", (UINT8)inData[i]);
strcat(outData, tmpBuf);
}
}
}
void mbim_disableAutoDial(void)
{
struct uci_context *_ctx = uci_alloc_context();
struct uci_ptr auto_apn_ptr = {
.package = "wan_default",
.section = "default",
.option = "auto_apn",
.value = "0",
};
struct uci_ptr connect_mode_ptr = {
.package = "wan_default",
.section = "default",
.option = "connect_mode",
.value = "0",
};
uci_set(_ctx, &auto_apn_ptr);
uci_commit(_ctx, &auto_apn_ptr.p, false);
uci_unload(_ctx, auto_apn_ptr.p);
uci_set(_ctx, &connect_mode_ptr);
uci_commit(_ctx, &connect_mode_ptr.p, false);
uci_unload(_ctx, connect_mode_ptr.p);
uci_free_context(_ctx);
}