Sample code
/*** @file rsimTest.c** This application implements a basic remote SIM server using the Legato remote SIM service.** No physical remote SIM card is connected or supported by this server and all SIM responses* are simulated. This application is therefore only used for sanity tests.** The remote SIM server does the following:* - Register a RSIM message handler* - Receive a SAP connection request, establish the connection and send the ATR* - Receive a first APDU request and respond with an APDU response error* - Receive a second APDU request and respond with a correct APDU response* - Receive a third APDU request and trigger a graceful SAP disconnection* - Exit** @note* - Ensure that your platform supports the remote SIM service before using it* - Select the remote SIM card and reboot before using it* - The application does not start automatically and should be started with "app start rsimTest"** <HR>** Copyright (C) Sierra Wireless Inc.*/#include "legato.h"#include "interfaces.h"#ifdef LE_CONFIG_LINUX#else#define exit(x) pthread_exit(x)#endif//--------------------------------------------------------------------------------------------------// Symbol and Enum definitions//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------/*** Memory pool size*///--------------------------------------------------------------------------------------------------#define RSIM_EVENTS_POOL_SIZE 2//--------------------------------------------------------------------------------------------------/*** SAP message identifiers (cf. SIM Access Profile specification)*///--------------------------------------------------------------------------------------------------#define SAP_MSGID_CONNECT_REQ 0x00#define SAP_MSGID_CONNECT_RESP 0x01#define SAP_MSGID_DISCONNECT_REQ 0x02#define SAP_MSGID_DISCONNECT_RESP 0x03#define SAP_MSGID_DISCONNECT_IND 0x04#define SAP_MSGID_TRANSFER_APDU_REQ 0x05#define SAP_MSGID_TRANSFER_APDU_RESP 0x06#define SAP_MSGID_TRANSFER_ATR_REQ 0x07#define SAP_MSGID_TRANSFER_ATR_RESP 0x08#define SAP_MSGID_POWER_SIM_OFF_REQ 0x09#define SAP_MSGID_POWER_SIM_OFF_RESP 0x0A#define SAP_MSGID_POWER_SIM_ON_REQ 0x0B#define SAP_MSGID_POWER_SIM_ON_RESP 0x0C#define SAP_MSGID_RESET_SIM_REQ 0x0D#define SAP_MSGID_RESET_SIM_RESP 0x0E#define SAP_MSGID_TRANSFER_CARD_READER_STATUS_REQ 0x0F#define SAP_MSGID_TRANSFER_CARD_READER_STATUS_RESP 0x10#define SAP_MSGID_STATUS_IND 0x11#define SAP_MSGID_ERROR_RESP 0x12#define SAP_MSGID_SET_TRANSPORT_PROTOCOL_REQ 0x13#define SAP_MSGID_SET_TRANSPORT_PROTOCOL_RESP 0x14//--------------------------------------------------------------------------------------------------/*** SAP parameters identifiers (cf. SIM Access Profile specification)*///--------------------------------------------------------------------------------------------------#define SAP_PARAMID_MAX_MSG_SIZE 0x00#define SAP_PARAMID_CONNECTION_STATUS 0x01#define SAP_PARAMID_RESULT_CODE 0x02#define SAP_PARAMID_DISCONNECTION_TYPE 0x03#define SAP_PARAMID_COMMAND_APDU 0x04#define SAP_PARAMID_COMMAND_APDU_7816 0x10#define SAP_PARAMID_RESPONSE_APDU 0x05#define SAP_PARAMID_ATR 0x06#define SAP_PARAMID_CARD_READER_STATUS 0x07#define SAP_PARAMID_STATUS_CHANGE 0x08#define SAP_PARAMID_TRANSPORT_PROTOCOL 0x09//--------------------------------------------------------------------------------------------------/*** Length in bytes of different parameters of SAP messages (cf. SIM Access Profile specification).* Only parameters with fixed lengths are listed here*///--------------------------------------------------------------------------------------------------#define SAP_LENGTH_SAP_HEADER 4 ///< 4 bytes header for SAP messages#define SAP_LENGTH_PARAM_HEADER 4 ///< 4 bytes header for each parameter#define SAP_LENGTH_MAX_MSG_SIZE 2#define SAP_LENGTH_CONNECTION_STATUS 1#define SAP_LENGTH_RESULT_CODE 1#define SAP_LENGTH_DISCONNECTION_TYPE 1#define SAP_LENGTH_CARD_READER_STATUS 1#define SAP_LENGTH_STATUS_CHANGE 1#define SAP_LENGTH_TRANSPORT_PROTOCOL 1#define SAP_LENGTH_PARAM_PAYLOAD 4 ///< Parameter payload is 4 bytes long with padding#define SAP_LENGTH_PARAM (SAP_LENGTH_PARAM_HEADER + SAP_LENGTH_PARAM_PAYLOAD)//--------------------------------------------------------------------------------------------------/*** SAP ConnectionStatus values (cf. SIM Access Profile specification section 5.2.2)*///--------------------------------------------------------------------------------------------------#define SAP_CONNSTATUS_OK 0x00 ///< OK, Server can fulfill requirements#define SAP_CONNSTATUS_SERVER_NOK 0x01 ///< Error, Server unable to establish connection#define SAP_CONNSTATUS_MAXMSGSIZE_NOK 0x02 ///< Error, Server does not support///< maximum message size#define SAP_CONNSTATUS_SMALL_MAXMSGSIZE 0x03 ///< Error, maximum message size///< by Client is too small#define SAP_CONNSTATUS_OK_ONGOING_CALL 0x04 ///< OK, ongoing call//--------------------------------------------------------------------------------------------------/*** SAP DisconnectionType values (cf. SIM Access Profile specification section 5.2.3)*///--------------------------------------------------------------------------------------------------#define SAP_DISCONNTYPE_GRACEFUL 0x00 ///< Graceful#define SAP_DISCONNTYPE_IMMEDIATE 0x01 ///< Immediate//--------------------------------------------------------------------------------------------------/*** SAP ResultCode values (cf. SIM Access Profile specification section 5.2.4)*///--------------------------------------------------------------------------------------------------#define SAP_RESULTCODE_OK 0x00 ///< OK, request processed correctly#define SAP_RESULTCODE_ERROR_NO_REASON 0x01 ///< Error, no reason defined#define SAP_RESULTCODE_ERROR_CARD_NOK 0x02 ///< Error, card not accessible#define SAP_RESULTCODE_ERROR_CARD_OFF 0x03 ///< Error, card (already) powered off#define SAP_RESULTCODE_ERROR_CARD_REMOVED 0x04 ///< Error, card removed#define SAP_RESULTCODE_ERROR_CARD_ON 0x05 ///< Error, card already powered on#define SAP_RESULTCODE_ERROR_NO_DATA 0x06 ///< Error, data not available#define SAP_RESULTCODE_ERROR_NOT_SUPPORTED 0x07 ///< Error, not supported//--------------------------------------------------------------------------------------------------/*** SAP StatusChange values (cf. SIM Access Profile specification section 5.2.8)*///--------------------------------------------------------------------------------------------------#define SAP_STATUSCHANGE_UNKNOWN_ERROR 0x00 ///< Unknown Error#define SAP_STATUSCHANGE_CARD_RESET 0x01 ///< Card reset#define SAP_STATUSCHANGE_CARD_NOK 0x02 ///< Card not accessible#define SAP_STATUSCHANGE_CARD_REMOVED 0x03 ///< Card removed#define SAP_STATUSCHANGE_CARD_INSERTED 0x04 ///< Card inserted#define SAP_STATUSCHANGE_CARD_RECOVERED 0x05 ///< Card recovered//--------------------------------------------------------------------------------------------------/*** Bit shift to access MSB byte*///--------------------------------------------------------------------------------------------------#define MSB_SHIFT 8//--------------------------------------------------------------------------------------------------// Data structures//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------/*** RSIM message sending structure*///--------------------------------------------------------------------------------------------------typedef struct{uint8_t message[LE_RSIM_MAX_MSG_SIZE]; ///< Messagesize_t messageSize; ///< Message sizele_rsim_CallbackHandlerFunc_t callbackPtr; ///< Callback responsevoid* context; ///< Associated context}RsimMessageSending_t;//--------------------------------------------------------------------------------------------------// Static declarations//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------/*** Memory pool used to transfer RSIM messages sending to the application thread*///--------------------------------------------------------------------------------------------------static le_mem_PoolRef_t RsimMessagesPool;//--------------------------------------------------------------------------------------------------/*** RSIM message handler reference*///--------------------------------------------------------------------------------------------------static le_rsim_MessageHandlerRef_t RsimMessageHandlerRef;//--------------------------------------------------------------------------------------------------/*** Semaphore used to synchronize the test*///--------------------------------------------------------------------------------------------------static le_sem_Ref_t AppSemaphore;//--------------------------------------------------------------------------------------------------/*** Application thread reference*///--------------------------------------------------------------------------------------------------static le_thread_Ref_t AppThreadRef;//--------------------------------------------------------------------------------------------------/*** Expected message identifier*///--------------------------------------------------------------------------------------------------static uint8_t ExpectedMessageId = 0;//--------------------------------------------------------------------------------------------------// Utility functions//--------------------------------------------------------------------------------------------------// -------------------------------------------------------------------------------------------------/*** Callback for RSIM messages sending result*/// -------------------------------------------------------------------------------------------------static void CallbackHandler(uint8_t messageId,le_result_t result,void* contextPtr){LE_DEBUG("Sending result: messageId=%d, result=%d, context=%p", messageId, result, contextPtr);// Check sending result against expected resultLE_ASSERT(result == (le_result_t)contextPtr);le_sem_Post(AppSemaphore);}//--------------------------------------------------------------------------------------------------/*** Send SAP message through application thread*///--------------------------------------------------------------------------------------------------static void SendSapMessage(void* param1Ptr,void* param2Ptr){RsimMessageSending_t* rsimSendingPtr = (RsimMessageSending_t*) param1Ptr;// Send messageLE_ASSERT_OK(le_rsim_SendMessage(rsimSendingPtr->message,rsimSendingPtr->messageSize,rsimSendingPtr->callbackPtr,rsimSendingPtr->context));// Release allocated memoryle_mem_Release(rsimSendingPtr);}//--------------------------------------------------------------------------------------------------/*** Send SAP CONNECT_RESP message*///--------------------------------------------------------------------------------------------------static void SendSapConnectResp(uint8_t connectionStatus,uint16_t maxMsgSize){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// ConnectionStatus 'Error, Server does not support maximum message size'if (SAP_CONNSTATUS_MAXMSGSIZE_NOK == connectionStatus){// SAP headermessage[0] = SAP_MSGID_CONNECT_RESP; // MsgId (CONNECT_RESP)message[1] = 0x02; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_CONNECTION_STATUS; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_CONNECTION_STATUS; // Parameter length (LSB)// Parameter value (ConnectionStatus)message[8] = connectionStatus; // ConnectionStatusmessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Parameter headermessage[12] = SAP_PARAMID_MAX_MSG_SIZE; // Parameter Idmessage[13] = 0x00; // Reservedmessage[14] = 0x00; // Parameter length (MSB)message[15] = SAP_LENGTH_MAX_MSG_SIZE; // Parameter length (LSB)// Parameter value (MaxMsgSize)message[16] = ((maxMsgSize & 0xFF00U) >> MSB_SHIFT);// MaxMsgSize (MSB)message[17] = (maxMsgSize & 0x00FF); // MaxMsgSize (LSB)message[18] = 0x00; // Paddingmessage[19] = 0x00; // Padding// Message sizemessageSize = 20;}else{// SAP headermessage[0] = SAP_MSGID_CONNECT_RESP; // MsgId (CONNECT_RESP)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_CONNECTION_STATUS; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_CONNECTION_STATUS; // Parameter length (LSB)// Parameter value (ConnectionStatus)message[8] = connectionStatus; // ConnectionStatusmessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;}LE_DEBUG("Send CONNECT_RESP message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP STATUS_IND message*///--------------------------------------------------------------------------------------------------static void SendSapStatusInd(uint8_t statusChange){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// SAP headermessage[0] = SAP_MSGID_STATUS_IND; // MsgId (STATUS_IND)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_STATUS_CHANGE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_STATUS_CHANGE; // Parameter length (LSB)// Parameter value (StatusChange)message[8] = statusChange; // StatusChangemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;LE_DEBUG("Send STATUS_IND message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP TRANSFER_ATR_RESP message*///--------------------------------------------------------------------------------------------------static void SendSapTransferAtrResp(uint8_t resultCode,uint8_t* atrPtr,uint16_t atrLen){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// ResultCode 'OK, request processed correctly'if (SAP_RESULTCODE_OK == resultCode){// SAP headermessage[0] = SAP_MSGID_TRANSFER_ATR_RESP; // MsgId (TRANSFER_ATR_RESP)message[1] = 0x02; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_RESULT_CODE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_RESULT_CODE; // Parameter length (LSB)// Parameter value (ResultCode)message[8] = resultCode; // ResultCodemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Parameter headermessage[12] = SAP_PARAMID_ATR; // Parameter Idmessage[13] = 0x00; // Reservedmessage[14] = ((atrLen & 0xFF00U) >> MSB_SHIFT);// Parameter length (MSB)message[15] = (atrLen & 0x00FF); // Parameter length (LSB)// Current message sizemessageSize = 16;// Parameter value (ATR)memcpy(&message[messageSize], atrPtr, atrLen);messageSize += atrLen;// Message size should be 4-byte alignedmessageSize += (4 - (messageSize % 4));}else{// SAP headermessage[0] = SAP_MSGID_TRANSFER_ATR_RESP; // MsgId (TRANSFER_ATR_RESP)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_RESULT_CODE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_RESULT_CODE; // Parameter length (LSB)// Parameter value (ResultCode)message[8] = resultCode; // ResultCodemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;}LE_DEBUG("Send TRANSFER_ATR_RESP message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP TRANSFER_APDU_RESP message*///--------------------------------------------------------------------------------------------------static void SendSapTransferApduResp(uint8_t resultCode,uint8_t* apduPtr,uint16_t apduLen){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// ResultCode 'OK, request processed correctly'if (SAP_RESULTCODE_OK == resultCode){// SAP headermessage[0] = SAP_MSGID_TRANSFER_APDU_RESP; // MsgId (TRANSFER_APDU_RESP)message[1] = 0x02; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_RESULT_CODE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_RESULT_CODE; // Parameter length (LSB)// Parameter value (ResultCode)message[8] = resultCode; // ResultCodemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Parameter headermessage[12] = SAP_PARAMID_COMMAND_APDU; // Parameter Idmessage[13] = 0x00; // Reservedmessage[14] = ((apduLen & 0xFF00U) >> MSB_SHIFT); // Parameter length (MSB)message[15] = (apduLen & 0x00FF); // Parameter length (LSB)// Current message sizemessageSize = 16;// Parameter value (APDU)memcpy(&message[messageSize], apduPtr, apduLen);messageSize += apduLen;// Message size should be 4-byte alignedmessageSize += (4 - (messageSize % 4));}else{// SAP headermessage[0] = SAP_MSGID_TRANSFER_APDU_RESP; // MsgId (TRANSFER_APDU_RESP)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_RESULT_CODE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_RESULT_CODE; // Parameter length (LSB)// Parameter value (ResultCode)message[8] = resultCode; // ResultCodemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;}LE_DEBUG("Send TRANSFER_APDU_RESP message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP POWER_SIM_ON_RESP message*///--------------------------------------------------------------------------------------------------static void SendSapPowerSimOnResp(uint8_t resultCode){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// SAP headermessage[0] = SAP_MSGID_POWER_SIM_ON_RESP; // MsgId (POWER_SIM_ON_RESP)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_RESULT_CODE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_RESULT_CODE; // Parameter length (LSB)// Parameter value (ResultCode)message[8] = resultCode; // ResultCodemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;LE_DEBUG("Send POWER_SIM_ON_RESP message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP DISCONNECT_IND message*///--------------------------------------------------------------------------------------------------static void SendSapDisconnectInd(uint8_t disconnectionType){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// SAP headermessage[0] = SAP_MSGID_DISCONNECT_IND; // MsgId (DISCONNECT_IND)message[1] = 0x01; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Parameter headermessage[4] = SAP_PARAMID_DISCONNECTION_TYPE; // Parameter Idmessage[5] = 0x00; // Reservedmessage[6] = 0x00; // Parameter length (MSB)message[7] = SAP_LENGTH_DISCONNECTION_TYPE; // Parameter length (LSB)// Parameter value (DisconnectionType)message[8] = disconnectionType; // DisconnectionTypemessage[9] = 0x00; // Paddingmessage[10] = 0x00; // Paddingmessage[11] = 0x00; // Padding// Message sizemessageSize = 12;LE_DEBUG("Send DISCONNECT_IND message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}//--------------------------------------------------------------------------------------------------/*** Send SAP DISCONNECT_RESP message*///--------------------------------------------------------------------------------------------------static void SendSapDisconnectResp(void){uint8_t message[LE_RSIM_MAX_MSG_SIZE];size_t messageSize = 0;memset(&message, 0, sizeof(message));// SAP headermessage[0] = SAP_MSGID_DISCONNECT_RESP; // MsgId (DISCONNECT_RESP)message[1] = 0x00; // Parameters numbermessage[2] = 0x00; // Reservedmessage[3] = 0x00; // Reserved// Message sizemessageSize = 4;LE_DEBUG("Send DISCONNECT_RESP message:");LE_DUMP(message, messageSize);// Send message with the application threadRsimMessageSending_t* rsimSendingPtr = le_mem_ForceAlloc(RsimMessagesPool);memcpy(rsimSendingPtr->message, message, messageSize);rsimSendingPtr->messageSize = messageSize;rsimSendingPtr->callbackPtr = CallbackHandler;rsimSendingPtr->context = (void*)LE_OK;le_event_QueueFunctionToThread(AppThreadRef, SendSapMessage, rsimSendingPtr, NULL);}// -------------------------------------------------------------------------------------------------/*** Event callback for RSIM messages notification*/// -------------------------------------------------------------------------------------------------static void MessageHandler(const uint8_t* messagePtr,size_t messageNumElements,void* contextPtr){LE_DEBUG("Received a RSIM message:");LE_DUMP(messagePtr, messageNumElements);uint8_t msgId = messagePtr[0];LE_DEBUG("Received MessageId %d, expected %d", msgId, ExpectedMessageId);LE_ASSERT(msgId == ExpectedMessageId);switch (msgId){case SAP_MSGID_CONNECT_REQ:LE_DEBUG("CONNECT_REQ received");break;case SAP_MSGID_DISCONNECT_REQ:LE_DEBUG("DISCONNECT_REQ received");break;case SAP_MSGID_TRANSFER_APDU_REQ:LE_DEBUG("TRANSFER_APDU_REQ received");break;case SAP_MSGID_TRANSFER_ATR_REQ:LE_DEBUG("TRANSFER_ATR_REQ received");break;case SAP_MSGID_POWER_SIM_OFF_REQ:LE_DEBUG("POWER_SIM_OFF_REQ received");break;case SAP_MSGID_POWER_SIM_ON_REQ:LE_DEBUG("POWER_SIM_ON_REQ received");break;case SAP_MSGID_RESET_SIM_REQ:LE_DEBUG("RESET_SIM_REQ received");break;case SAP_MSGID_TRANSFER_CARD_READER_STATUS_REQ:case SAP_MSGID_SET_TRANSPORT_PROTOCOL_REQ:LE_ERROR("Unsupported SAP message with id %d received", msgId);break;default:LE_ERROR("Unknown SAP message with id %d received", msgId);break;}// Semaphore is used to synchronize the task execution with the core testle_sem_Post(AppSemaphore);}//--------------------------------------------------------------------------------------------------/*** Synchronize test thread (i.e. main) and application thread*///--------------------------------------------------------------------------------------------------static void SynchronizeTest(void){le_clk_Time_t timeToWait = {5, 0};LE_ASSERT_OK(le_sem_WaitWithTimeOut(AppSemaphore, timeToWait));}//--------------------------------------------------------------------------------------------------/*** Thread used to register handler and to send/receive the RSIM messages*///--------------------------------------------------------------------------------------------------static void* AppHandler(void* ctxPtr){// Connect to the Remote SIM service// Register handler for RSIM messages notificationRsimMessageHandlerRef = le_rsim_AddMessageHandler(MessageHandler, NULL);LE_ASSERT(NULL != RsimMessageHandlerRef);LE_INFO("MessageHandler %p added", RsimMessageHandlerRef);// Semaphore is used to synchronize the task execution with the core testle_sem_Post(AppSemaphore);// Run the event loopreturn NULL;}//--------------------------------------------------------------------------------------------------/*** Remove Remote SIM message handler*///--------------------------------------------------------------------------------------------------static void AppRemoveHandler(void* param1Ptr,void* param2Ptr){// Unregister message handlerLE_INFO("Unregister MessageHandler %p", RsimMessageHandlerRef);le_rsim_RemoveMessageHandler(RsimMessageHandlerRef);// Semaphore is used to synchronize the task execution with the core testle_sem_Post(AppSemaphore);}//--------------------------------------------------------------------------------------------------// Test functions//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------/*** Initialize the test component.*///--------------------------------------------------------------------------------------------------{LE_INFO("Start RSIM test");// Simulated ATR responseuint8_t atrData[22] ={0x3B, 0x9F, 0x96, 0x80, 0x1F, 0xC7, 0x80, 0x31,0xE0, 0x73, 0xFE, 0x21, 0x13, 0x67, 0x93, 0x31,0x01, 0x08, 0x01, 0x01, 0x01, 0x72};size_t atrLength = 22;// Simulated APDU responseuint8_t apduData[2] ={0x61, 0x2C};size_t apduLength = 2;// Create and expand RSIM messages memory poolle_mem_ExpandPool(RsimMessagesPool, RSIM_EVENTS_POOL_SIZE);// Create a semaphore to synchronize the testAppSemaphore = le_sem_Create("AppSemaphore", 0);// Create a thread to send and receive Remote SIM messagesAppThreadRef = le_thread_Create("AppThread", AppHandler, NULL);le_thread_Start(AppThreadRef);// Wait for the thread initialization before continuing the testSynchronizeTest();// Wait for the remote SIM service connection requestExpectedMessageId = SAP_MSGID_CONNECT_REQ;SynchronizeTest();// Send a CONNECT_RESP message with 'OK, Server can fulfill requirements'SendSapConnectResp(SAP_CONNSTATUS_OK, 0);// Wait for message sending resultSynchronizeTest();// Send a STATUS_IND message with 'Card reset', triggering an ATR requestExpectedMessageId = SAP_MSGID_TRANSFER_ATR_REQ;SendSapStatusInd(SAP_STATUSCHANGE_CARD_RESET);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a TRANSFER_ATR_RESP message with 'OK, request processed correctly',// triggering an APDU requestExpectedMessageId = SAP_MSGID_TRANSFER_APDU_REQ;SendSapTransferAtrResp(SAP_RESULTCODE_OK, atrData, atrLength);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a TRANSFER_APDU_RESP message with 'Error, no reason defined',// triggering a POWER_SIM_ON requestExpectedMessageId = SAP_MSGID_POWER_SIM_ON_REQ;SendSapTransferApduResp(SAP_RESULTCODE_ERROR_NO_REASON, NULL, 0);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a POWER_SIM_ON_RESP message with 'OK, request processed correctly',// triggering an ATR requestExpectedMessageId = SAP_MSGID_TRANSFER_ATR_REQ;SendSapPowerSimOnResp(SAP_RESULTCODE_OK);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a TRANSFER_ATR_RESP message with 'OK, request processed correctly',// triggering an APDU requestExpectedMessageId = SAP_MSGID_TRANSFER_APDU_REQ;SendSapTransferAtrResp(SAP_RESULTCODE_OK, atrData, atrLength);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a TRANSFER_APDU_RESP message with 'OK, request processed correctly',// triggering a new APDU requestSendSapTransferApduResp(SAP_RESULTCODE_OK, apduData, apduLength);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a DISCONNECT_IND message with 'Graceful', triggering a disconnection requestExpectedMessageId = SAP_MSGID_DISCONNECT_REQ;SendSapDisconnectInd(SAP_DISCONNTYPE_GRACEFUL);// Wait for message sending resultSynchronizeTest();// Wait for the message receptionSynchronizeTest();// Send a DISCONNECT_RESP messageSendSapDisconnectResp();// Wait for message sending resultSynchronizeTest();// Remove the message handlerle_event_QueueFunctionToThread(AppThreadRef, AppRemoveHandler, NULL, NULL);SynchronizeTest();// Delete semaphorele_sem_Delete(AppSemaphore);// Stop the remote SIM service test applicationexit(EXIT_SUCCESS);}