1 /******************************************************************************
2  *
3  *  Copyright (C) 2018 ST Microelectronics S.A.
4  *  Copyright 2018 NXP
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 #define LOG_TAG "StEse_HalApi"
20 
21 #include <pthread.h>
22 #include "StEseApi.h"
23 #include "SpiLayerComm.h"
24 #include <cutils/properties.h>
25 #include <ese_config.h>
26 #include "T1protocol.h"
27 #include "android_logmsg.h"
28 
29 /*********************** Global Variables *************************************/
30 
31 /* ESE Context structure */
32 ese_Context_t ese_ctxt;
33 
34 const char* halVersion = "ST54-SE HAL1.0 Version 1.0.20";
35 
36 pthread_mutex_t mutex;
37 
38 /******************************************************************************
39  * Function         StEseLog_InitializeLogLevel
40  *
41  * Description      This function is called during StEse_init to initialize
42  *                  debug log level.
43  *
44  * Returns          None
45  *
46  ******************************************************************************/
47 
StEseLog_InitializeLogLevel()48 void StEseLog_InitializeLogLevel() { InitializeSTLogLevel(); }
49 
50 /******************************************************************************
51  * Function         StEse_init
52  *
53  * Description      This function is called by Jni during the
54  *                  initialization of the ESE. It opens the physical connection
55  *                  with ESE and creates required client thread for
56  *                  operation.
57  * Returns          This function return ESESTATUS_SUCCES (0) in case of success
58  *                  In case of failure returns other failure value.
59  *
60  ******************************************************************************/
StEse_init()61 ESESTATUS StEse_init() {
62   SpiDriver_config_t tSpiDriver;
63   ESESTATUS wConfigStatus = ESESTATUS_SUCCESS;
64   int ret;
65 
66   char ese_dev_node[64];
67   std::string ese_node;
68 
69   STLOG_HAL_D("%s : SteSE_open Enter halVersion = %s ", __func__, halVersion);
70   /*When spi channel is already opened return status as FAILED*/
71   if (ese_ctxt.EseLibStatus != ESE_STATUS_CLOSE) {
72     STLOG_HAL_D("already opened\n");
73     return ESESTATUS_BUSY;
74   }
75 
76   memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
77   memset(&tSpiDriver, 0x00, sizeof(tSpiDriver));
78 
79   /* initialize trace level */
80   StEseLog_InitializeLogLevel();
81 
82   /*Read device node path*/
83   ese_node = EseConfig::getString(NAME_ST_ESE_DEV_NODE, "/dev/st54j");
84   strcpy(ese_dev_node, ese_node.c_str());
85   tSpiDriver.pDevName = ese_dev_node;
86 
87   /* Initialize SPI Driver layer */
88   if (T1protocol_init(&tSpiDriver) != ESESTATUS_SUCCESS) {
89     STLOG_HAL_E("T1protocol_init Failed");
90     if (intptr_t(tSpiDriver.pDevHandle) > 0) {
91       ese_ctxt.pDevHandle = tSpiDriver.pDevHandle;
92     }
93     goto clean_and_return;
94   }
95   /* Copying device handle to ESE Lib context*/
96   ese_ctxt.pDevHandle = tSpiDriver.pDevHandle;
97 
98   ret = pthread_mutex_init(&mutex, NULL);
99   if (ret != 0) {
100     STLOG_HAL_E("HAL: %s pthread_mutex_init failed", __func__);
101   }
102 
103   STLOG_HAL_D("wConfigStatus %x", wConfigStatus);
104   ese_ctxt.EseLibStatus = ESE_STATUS_OPEN;
105   return wConfigStatus;
106 
107 clean_and_return:
108   if (NULL != ese_ctxt.pDevHandle) {
109     SpiLayerInterface_close(ese_ctxt.pDevHandle);
110     memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
111   }
112   ese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
113   return ESESTATUS_FAILED;
114 }
115 
116 /******************************************************************************
117  * Function         StEseApi_isOpen
118  *
119  * \brief           Check if the hal is opened
120  *
121  * \retval return false if it is close, otherwise true.
122  *
123  ******************************************************************************/
StEseApi_isOpen()124 bool StEseApi_isOpen() {
125   STLOG_HAL_D(" %s  status 0x%x \n", __FUNCTION__, ese_ctxt.EseLibStatus);
126   return ese_ctxt.EseLibStatus != ESE_STATUS_CLOSE;
127 }
128 
129 /******************************************************************************
130  * Function         StEse_Transceive
131  *
132  * Description      This function update the len and provided buffer
133  *
134  * Returns          On Success ESESTATUS_SUCCESS else proper error code
135  *
136  ******************************************************************************/
StEse_Transceive(StEse_data * pCmd,StEse_data * pRsp)137 ESESTATUS StEse_Transceive(StEse_data* pCmd, StEse_data* pRsp) {
138   ESESTATUS status = ESESTATUS_SUCCESS;
139   static int pTxBlock_len = 0;
140   uint16_t pCmdlen = pCmd->len;
141 
142   STLOG_HAL_D("%s : Enter EseLibStatus = %d ", __func__, ese_ctxt.EseLibStatus);
143 
144   if ((NULL == pCmd) || (NULL == pRsp)) return ESESTATUS_INVALID_PARAMETER;
145 
146   if ((pCmd->len == 0) || pCmd->p_data == NULL) {
147     STLOG_HAL_E(" StEse_Transceive - Invalid Parameter no data\n");
148     return ESESTATUS_INVALID_PARAMETER;
149   } else if ((ESE_STATUS_CLOSE == ese_ctxt.EseLibStatus)) {
150     STLOG_HAL_E(" %s ESE Not Initialized \n", __FUNCTION__);
151     return ESESTATUS_NOT_INITIALISED;
152   }
153 
154   STLOG_HAL_D(" %s ESE - No access, waiting \n", __FUNCTION__);
155   pthread_mutex_lock(&mutex);
156 
157   STLOG_HAL_D(" %s ESE - Access granted, processing \n", __FUNCTION__);
158 
159   uint8_t* CmdPart = pCmd->p_data;
160 
161   while (pCmdlen > ATP.ifsc) {
162     pTxBlock_len = ATP.ifsc;
163 
164     int rc = T1protocol_transcieveApduPart(CmdPart, pTxBlock_len, false,
165                                            (StEse_data*) pRsp);
166     if (rc < 0) {
167       STLOG_HAL_E(" %s ESE - Error, release access \n", __FUNCTION__);
168       status = ESESTATUS_FAILED;
169 
170       pthread_mutex_unlock(&mutex);
171 
172       return status;
173     }
174     pCmdlen -= pTxBlock_len;
175     CmdPart = CmdPart + pTxBlock_len;
176     if (ESESTATUS_SUCCESS != status) {
177       STLOG_HAL_E(" %s T1protocol_transcieveApduPart- Failed \n", __FUNCTION__);
178     }
179   }
180   int rc = T1protocol_transcieveApduPart(CmdPart, pCmdlen, true,
181                                          (StEse_data*) pRsp);
182   if (rc < 0) status = ESESTATUS_FAILED;
183 
184   if (ESESTATUS_SUCCESS != status) {
185     STLOG_HAL_E(" %s T1protocol_transcieveApduPart- Failed \n", __FUNCTION__);
186   }
187 
188   STLOG_HAL_D(" %s ESE - Processing complete, release access \n", __FUNCTION__);
189 
190   pthread_mutex_unlock(&mutex);
191 
192   STLOG_HAL_D(" %s Exit status 0x%x \n", __FUNCTION__, status);
193 
194   return status;
195 }
196 
197 /******************************************************************************
198  * Function         StEse_close
199  *
200  * Description      This function close the ESE interface and free all
201  *                  resources.
202  *
203  * Returns          Always return ESESTATUS_SUCCESS (0).
204  *
205  ******************************************************************************/
StEse_close(void)206 ESESTATUS StEse_close(void) {
207   ESESTATUS status = ESESTATUS_SUCCESS;
208 
209   if ((ESE_STATUS_CLOSE == ese_ctxt.EseLibStatus)) {
210     STLOG_HAL_E(" %s ESE Not Initialized \n", __FUNCTION__);
211     return ESESTATUS_NOT_INITIALISED;
212   }
213 
214   if (NULL != ese_ctxt.pDevHandle) {
215     SpiLayerInterface_close(ese_ctxt.pDevHandle);
216     memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
217     STLOG_HAL_D("StEse_close - ESE Context deinit completed");
218     ese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
219   }
220 
221   pthread_mutex_destroy(&mutex);
222   /* Return success always */
223   return status;
224 }
225 
226 /******************************************************************************
227  * Function         StEse_getAtr
228  *
229  * Description      This function get the last ATR received.
230  *
231  * Returns          pointer to the ATR array.
232  *
233  ******************************************************************************/
StEse_getAtr(void)234 uint8_t* StEse_getAtr(void) {
235   STLOG_HAL_D("%s : Enter", __func__);
236   // The ATR is not supported by SPI in the secure element
237   return nullptr;
238 }
239 
240 /******************************************************************************
241  * Function         StEse_Reset
242  *
243  * Description      This function resets the eSE SPI interface by sending a
244  *                  SE reset and negotiating the ifs.
245  *
246  * Returns          ESESTATUS_SUCCESS is successful, ESESTATUS_SUCCESS otherwise
247  *
248  ******************************************************************************/
StEse_Reset(void)249 ESESTATUS StEse_Reset(void) {
250   STLOG_HAL_D("%s : Enter", __func__);
251   if (SpiLayerInterface_setup() != 0) {
252     return ESESTATUS_FAILED;
253   }
254 
255   return ESESTATUS_SUCCESS;
256 }
257