| /****************************************************************************** |
| *(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; |
| } |