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