blob: ab9aa7c47f9e36adb8fdd80a241d3e6d6f6b3dd8 [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2018 ASR Microelectronics
* All Rights Reserved
******************************************************************************/
/* ----------------------------------------------------------------------------
*
* Filename: mbim_uicc.c
*
*
* Description: Microsoft Low-Level UICC Access
*
*
* Notes:
*
******************************************************************************/
#define LOG_TAG "MBIM"
/******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "mbim_types.h"
#include "mbim_util.h"
#include "mbim_uicc.h"
#include "mbim_ril.h"
#if defined MBIM_MTIL
#include "mbim_mtil.h"
#include "MtilAPI.h"
#endif
#ifndef MBIM_UICC_UNUSEDPARAM
#define MBIM_UICC_UNUSEDPARAM() ((void) cid);((void) transactionId);((void) commandType);((void) infoBufLen);((void) infoBuf_p)
#endif
extern MBIM_DATABASE mbimDb;
/******************************************************************************
* Macros
******************************************************************************/
#define CREATE_UICC_CONTEXT(pContext, mBuf) \
pContext = (P_MBIM_MESSAGE_CONTEXT)MBIM_MALLOC(sizeof(MBIM_MESSAGE_CONTEXT)); \
if (pContext != NULL) { \
pContext->hdr.cid = cid; \
pContext->hdr.transId = transactionId; \
pContext->hdr.uuidIndex = UUID_MS_UICC_LOW_LEVEL_INDEX; \
pContext->hdr.indication= MBIM_REQUEST; \
pContext->body = mBuf; \
pContext->cmd = NULL; \
} \
else { \
if (mBuf != NULL) \
MBIM_FREE(mBuf); \
MBIM_LOGE("UICC UUID: OUT OF MEMORY CID %d (TransactionId = %d, Cmd Type = %d)", cid, transactionId, commandType); \
return MbimSendFunctionErrorMsg(transactionId, MBIM_ERROR_UNKNOWN); \
}
#define ALLOCATE_RESPONSE_BUFFER(mBuf_p, mSize) \
mBuf_p = (char *)MBIM_MALLOC(mSize); \
if (mBuf_p == NULL) { \
MBIM_LOGE("UICC UUID: OUT OF MEMORY CID %d (TransactionId = %d, Cmd Type = %d)", cid, transactionId, commandType); \
return MbimSendFunctionErrorMsg(transactionId, MBIM_ERROR_UNKNOWN); \
}
#define ALLOCATE_CMD_BUFFER(context_p, mBuf_p, mSize) \
mBuf_p = (char *)MBIM_MALLOC(mSize); \
if (mBuf_p == NULL) { \
if (context_p->body != NULL) \
MBIM_FREE(context_p->body); \
if (context_p != NULL) \
MBIM_FREE(context_p); \
MBIM_LOGE("UICC UUID: OUT OF MEMORY CID %d (TransactionId = %d, Cmd Type = %d)", cid, transactionId, commandType); \
return MbimSendFunctionErrorMsg(transactionId, MBIM_ERROR_UNKNOWN); \
} else { \
memset(mBuf_p, 0, mSize); \
context_p->cmd = mBuf_p; \
}
/******************************************************************************
* #defines
******************************************************************************/
#define DEFAULT_CONTEXT_ALLOC_SIZE (4000)
/******************************************************************************
* Global Variables
******************************************************************************/
/******************************************************************************
* Function prototypes
******************************************************************************/
int CID_UICC_NotSupported(UICC_CID_PARAMS);
int CID_UICC_ATR(UICC_CID_PARAMS);
int CID_UICC_OPENCHANNEL(UICC_CID_PARAMS);
int CID_UICC_CLOSECHANNEL(UICC_CID_PARAMS);
int CID_UICC_APDU(UICC_CID_PARAMS);
int CID_UICC_TERMINAL_CAPABILITY(UICC_CID_PARAMS);
int CID_UICC_RESET(UICC_CID_PARAMS);
/******************************************************************************
* External variables
******************************************************************************/
UiccUuidProcessors uiccCidProcessor[UUID_CID_MS_UICC_MAX] = {
CID_UICC_NotSupported, //0
CID_UICC_ATR,
CID_UICC_OPENCHANNEL,
CID_UICC_CLOSECHANNEL,
CID_UICC_APDU,
CID_UICC_TERMINAL_CAPABILITY,
CID_UICC_RESET,
};
/******************************************************************************
* Local variables
******************************************************************************/
const int MBIM_MAXLENGTH_APPID = 32;
const int MBIM_MAXLENGTH_APPNAME = 256;
const int MBIM_MAXNUM_PINREF = 8;
/******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************\
* Function: CID_UICC_NotSupported
* Description: This function sends Error to HOST when a unknown command is received
* Parameters: dataBuf - String
*
* Returns: 0=OK, <0=Error Code
\*******************************************************************************/
int CID_UICC_NotSupported(UICC_CID_PARAMS)
{
int rc = MBIM_OK;
//Added for compilation of unused parameters on Codeline
MBIM_UICC_UNUSEDPARAM();
MBIM_LOGE("UICC UUID: Command %d not supported (TransactionId = %d, Cmd Type = %d)", cid, transactionId, commandType);
rc = MbimSendCommandDone(transactionId, UUID_MS_UICC_LOW_LEVEL_INDEX,
cid, MBIM_STATUS_NO_DEVICE_SUPPORT, 0, NULL);
return rc;
}
int CID_UICC_ATR(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
if (commandType != MBIM_QUERY_COMMAND)
{
return CID_UICC_NotSupported(UICC_CID_PARAMS_USAGE);
}
//Allocate buffer for response
ALLOCATE_RESPONSE_BUFFER(buf, DEFAULT_CONTEXT_ALLOC_SIZE);
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
MbimTelRequestATR(mContext);
return rc;
}
int CID_UICC_RESET(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
P_MBIM_SET_MS_UICC_RESET pSet = NULL;
//Allocate buffer for response
ALLOCATE_RESPONSE_BUFFER(buf, DEFAULT_CONTEXT_ALLOC_SIZE);
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
if (commandType == MBIM_SET_COMMAND)
{
pSet = (P_MBIM_SET_MS_UICC_RESET)infoBuf_p;
MbimTelRequestSetUICCReset(mContext, pSet->PassThroughAction);
}
else
MbimTelRequestQueryUICCReset(mContext);
return rc;
}
int CID_UICC_OPENCHANNEL(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
if (commandType != MBIM_SET_COMMAND)
{
return CID_UICC_NotSupported(UICC_CID_PARAMS_USAGE);
}
//Allocate buffer for response
ALLOCATE_RESPONSE_BUFFER(buf, DEFAULT_CONTEXT_ALLOC_SIZE);
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
//copy cmd
ALLOCATE_CMD_BUFFER(mContext, mContext->cmd, infoBufLen);
memcpy(mContext->cmd, (char *)infoBuf_p, infoBufLen);
MbimTelRequestOPENCHNL(mContext);
return rc;
}
int CID_UICC_CLOSECHANNEL(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
if (commandType != MBIM_SET_COMMAND)
{
return CID_UICC_NotSupported(UICC_CID_PARAMS_USAGE);
}
//Allocate buffer for response
ALLOCATE_RESPONSE_BUFFER(buf, DEFAULT_CONTEXT_ALLOC_SIZE);
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
//copy cmd
ALLOCATE_CMD_BUFFER(mContext, mContext->cmd, infoBufLen);
memcpy(mContext->cmd, (char *)infoBuf_p, infoBufLen);
MbimTelRequestCLOSECHNL(mContext);
return rc;
}
int CID_UICC_APDU(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
if (commandType != MBIM_SET_COMMAND)
{
return CID_UICC_NotSupported(UICC_CID_PARAMS_USAGE);
}
//Allocate buffer for response
ALLOCATE_RESPONSE_BUFFER(buf, DEFAULT_CONTEXT_ALLOC_SIZE);
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
//copy cmd
ALLOCATE_CMD_BUFFER(mContext, mContext->cmd, infoBufLen);
memcpy(mContext->cmd, (char *)infoBuf_p, infoBufLen);
MbimTelRequestAPDU(mContext);
return rc;
}
int CID_UICC_TERMINAL_CAPABILITY(UICC_CID_PARAMS)
{
char *buf = NULL;
P_MBIM_MESSAGE_CONTEXT mContext = NULL;
int rc = MBIM_STATUS_SUCCESS;
if (commandType == MBIM_QUERY_COMMAND)
{
//get from local
if (mbimDb.uiccTermCapLen)
{
MbimSendCommandDone(transactionId, UUID_MS_UICC_LOW_LEVEL_INDEX, cid, MBIM_STATUS_SUCCESS, mbimDb.uiccTermCapLen, mbimDb.uiccTermCap);
}
else
{
MBIM_MS_SET_UICC_TERMINAL_CAPABILITY cap;
cap.ElementCount = 0;
MbimSendCommandDone(transactionId, UUID_MS_UICC_LOW_LEVEL_INDEX, cid, MBIM_STATUS_SUCCESS, sizeof(MBIM_MS_SET_UICC_TERMINAL_CAPABILITY), (char *)&cap);
}
}
else
{
//Create the context for this command
CREATE_UICC_CONTEXT(mContext, buf);
//copy cmd
ALLOCATE_CMD_BUFFER(mContext, mContext->cmd, infoBufLen);
memcpy(mContext->cmd, (char *)infoBuf_p, infoBufLen);
int ret = MbimTelRequestTermCap(mContext);
if (!ret)
{
//save
MBIM_FREE(mbimDb.uiccTermCap);
mbimDb.uiccTermCap = (char *)malloc(infoBufLen);
memcpy(mbimDb.uiccTermCap, infoBuf_p, infoBufLen);
mbimDb.uiccTermCapLen = infoBufLen;
}
MbimSendCommandDone(transactionId, UUID_MS_UICC_LOW_LEVEL_INDEX, cid, (ret? MBIM_STATUS_FAILURE: MBIM_STATUS_SUCCESS), infoBufLen, infoBuf_p);
}
return rc;
}