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 "StEseApi.h"
22 #include <cutils/properties.h>
23 #include <ese_config.h>
24 #include <pthread.h>
25 #include "SpiLayerComm.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.22";
35
36 pthread_mutex_t mutex;
37
38 bool ConfRead = 0;
39 unsigned int PollInt_confvalue = 1000;
40 unsigned int BGT_confvalue = 1000;
41
42 /******************************************************************************
43 * Function StEseLog_InitializeLogLevel
44 *
45 * Description This function is called during StEse_init to initialize
46 * debug log level.
47 *
48 * Returns None
49 *
50 ******************************************************************************/
51
StEseLog_InitializeLogLevel()52 void StEseLog_InitializeLogLevel() { InitializeSTLogLevel(); }
53
54 /******************************************************************************
55 * Function StEse_init
56 *
57 * Description This function is called by Jni during the
58 * initialization of the ESE. It opens the physical connection
59 * with ESE and creates required client thread for
60 * operation.
61 * Returns This function return ESESTATUS_SUCCES (0) in case of success
62 * In case of failure returns other failure value.
63 *
64 ******************************************************************************/
StEse_init()65 ESESTATUS StEse_init() {
66 SpiDriver_config_t tSpiDriver;
67 ESESTATUS wConfigStatus = ESESTATUS_SUCCESS;
68 int ret;
69
70 char ese_dev_node[64];
71 std::string ese_node;
72
73 STLOG_HAL_D("%s : SteSE_open Enter halVersion = %s ", __func__, halVersion);
74 /*When spi channel is already opened return status as FAILED*/
75 if (ese_ctxt.EseLibStatus != ESE_STATUS_CLOSE) {
76 STLOG_HAL_D("already opened\n");
77 return ESESTATUS_BUSY;
78 }
79
80 memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
81 memset(&tSpiDriver, 0x00, sizeof(tSpiDriver));
82
83 /* initialize trace level */
84 StEseLog_InitializeLogLevel();
85
86 /*Read device node path*/
87 ese_node = EseConfig::getString(NAME_ST_ESE_DEV_NODE, "/dev/st54j");
88 strcpy(ese_dev_node, ese_node.c_str());
89 tSpiDriver.pDevName = ese_dev_node;
90
91 if (!ConfRead) {
92 PollInt_confvalue =
93 EseConfig::getUnsigned(NAME_ST_ESE_DEV_POLLING_INTERVAL, 1000);
94 BGT_confvalue = EseConfig::getUnsigned(NAME_ST_ESE_DEV_BGT, 1000);
95 ConfRead = true;
96 }
97
98 tSpiDriver.polling_interval = PollInt_confvalue;
99 tSpiDriver.bgt = BGT_confvalue;
100
101 /* Initialize SPI Driver layer */
102 if (T1protocol_init(&tSpiDriver) != ESESTATUS_SUCCESS) {
103 STLOG_HAL_E("T1protocol_init Failed");
104 if (intptr_t(tSpiDriver.pDevHandle) > 0) {
105 ese_ctxt.pDevHandle = tSpiDriver.pDevHandle;
106 }
107 goto clean_and_return;
108 }
109 /* Copying device handle to ESE Lib context*/
110 ese_ctxt.pDevHandle = tSpiDriver.pDevHandle;
111
112 ret = pthread_mutex_init(&mutex, NULL);
113 if (ret != 0) {
114 STLOG_HAL_E("HAL: %s pthread_mutex_init failed", __func__);
115 }
116
117 STLOG_HAL_D("wConfigStatus %x", wConfigStatus);
118 ese_ctxt.EseLibStatus = ESE_STATUS_OPEN;
119 return wConfigStatus;
120
121 clean_and_return:
122 if (NULL != ese_ctxt.pDevHandle) {
123 SpiLayerInterface_close(ese_ctxt.pDevHandle);
124 memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
125 }
126 ese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
127 return ESESTATUS_FAILED;
128 }
129
130 /******************************************************************************
131 * Function StEseApi_isOpen
132 *
133 * \brief Check if the hal is opened
134 *
135 * \retval return false if it is close, otherwise true.
136 *
137 ******************************************************************************/
StEseApi_isOpen()138 bool StEseApi_isOpen() {
139 STLOG_HAL_D(" %s status 0x%x \n", __FUNCTION__, ese_ctxt.EseLibStatus);
140 return ese_ctxt.EseLibStatus != ESE_STATUS_CLOSE;
141 }
142
143 /******************************************************************************
144 * Function StEse_Transceive
145 *
146 * Description This function update the len and provided buffer
147 *
148 * Returns On Success ESESTATUS_SUCCESS else proper error code
149 *
150 ******************************************************************************/
StEse_Transceive(StEse_data * pCmd,StEse_data * pRsp)151 ESESTATUS StEse_Transceive(StEse_data* pCmd, StEse_data* pRsp) {
152 ESESTATUS status = ESESTATUS_SUCCESS;
153 static int pTxBlock_len = 0;
154 int retry_count = 0;
155 uint16_t pCmdlen = pCmd->len;
156
157 STLOG_HAL_D("%s : Enter EseLibStatus = %d ", __func__, ese_ctxt.EseLibStatus);
158
159 if ((NULL == pCmd) || (NULL == pRsp)) return ESESTATUS_INVALID_PARAMETER;
160
161 if ((pCmd->len == 0) || pCmd->p_data == NULL) {
162 STLOG_HAL_E(" StEse_Transceive - Invalid Parameter no data\n");
163 return ESESTATUS_INVALID_PARAMETER;
164 } else if ((ESE_STATUS_CLOSE == ese_ctxt.EseLibStatus)) {
165 STLOG_HAL_E(" %s ESE Not Initialized \n", __FUNCTION__);
166 return ESESTATUS_NOT_INITIALISED;
167 }
168
169 STLOG_HAL_D(" %s ESE - No access, waiting \n", __FUNCTION__);
170 pthread_mutex_lock(&mutex);
171
172 STLOG_HAL_D(" %s ESE - Access granted, processing \n", __FUNCTION__);
173
174 uint8_t* CmdPart = pCmd->p_data;
175
176 retry:
177 while (pCmdlen > ATP.ifsc) {
178 pTxBlock_len = ATP.ifsc;
179
180 int rc = T1protocol_transcieveApduPart(CmdPart, pTxBlock_len, false,
181 (StEse_data*)pRsp, I_block);
182
183 if ((rc == -2) && (retry_count < 3)) {
184 retry_count++;
185 STLOG_HAL_E(" %s ESE - resync was needed, resend the whole frame retry"
186 " = %d\n", __FUNCTION__, retry_count);
187 pCmdlen = pCmd->len;
188 CmdPart = pCmd->p_data;
189 goto retry;
190 } else if (rc < 0) {
191 STLOG_HAL_E(" %s ESE - Error, release access \n", __FUNCTION__);
192 status = ESESTATUS_FAILED;
193 retry_count = 0;
194 pthread_mutex_unlock(&mutex);
195
196 return status;
197 } else {
198 retry_count = 0;
199 }
200
201 pCmdlen -= pTxBlock_len;
202 CmdPart = CmdPart + pTxBlock_len;
203 }
204
205 int rc = T1protocol_transcieveApduPart(CmdPart, pCmdlen, true,
206 (StEse_data*)pRsp, I_block);
207 if ((rc == -2) && (retry_count < 3)) {
208 retry_count++;
209 STLOG_HAL_E(" %s ESE - resync was needed, resend retry = %d\n",
210 __FUNCTION__, retry_count);
211 pCmdlen = pCmd->len;
212 CmdPart = pCmd->p_data;
213 goto retry;
214 } else if (rc < 0)
215 status = ESESTATUS_FAILED;
216
217 if (ESESTATUS_SUCCESS != status) {
218 STLOG_HAL_E(" %s T1protocol_transcieveApduPart- Failed \n", __FUNCTION__);
219 }
220 retry_count = 0;
221 STLOG_HAL_D(" %s ESE - Processing complete, release access \n", __FUNCTION__);
222
223 pthread_mutex_unlock(&mutex);
224
225 STLOG_HAL_D(" %s Exit status 0x%x \n", __FUNCTION__, status);
226
227 return status;
228 }
229
230 /******************************************************************************
231 * Function StEse_close
232 *
233 * Description This function close the ESE interface and free all
234 * resources.
235 *
236 * Returns Always return ESESTATUS_SUCCESS (0).
237 *
238 ******************************************************************************/
StEse_close(void)239 ESESTATUS StEse_close(void) {
240 ESESTATUS status = ESESTATUS_SUCCESS;
241
242 if ((ESE_STATUS_CLOSE == ese_ctxt.EseLibStatus)) {
243 STLOG_HAL_E(" %s ESE Not Initialized \n", __FUNCTION__);
244 return ESESTATUS_NOT_INITIALISED;
245 }
246
247 if (NULL != ese_ctxt.pDevHandle) {
248 SpiLayerInterface_close(ese_ctxt.pDevHandle);
249 memset(&ese_ctxt, 0x00, sizeof(ese_ctxt));
250 STLOG_HAL_D("StEse_close - ESE Context deinit completed");
251 ese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
252 }
253
254 pthread_mutex_destroy(&mutex);
255 /* Return success always */
256 return status;
257 }
258
259 /******************************************************************************
260 * Function StEse_getAtr
261 *
262 * Description This function get the last ATR received.
263 *
264 * Returns pointer to the ATR array.
265 *
266 ******************************************************************************/
StEse_getAtr(void)267 uint8_t* StEse_getAtr(void) {
268 STLOG_HAL_D("%s : Enter", __func__);
269 // The ATR is not supported by SPI in the secure element
270 return nullptr;
271 }
272
273 /******************************************************************************
274 * Function StEse_Reset
275 *
276 * Description This function resets the eSE SPI interface by sending a
277 * SE reset and negotiating the ifs.
278 *
279 * Returns ESESTATUS_SUCCESS is successful, ESESTATUS_SUCCESS otherwise
280 *
281 ******************************************************************************/
StEse_Reset(void)282 ESESTATUS StEse_Reset(void) {
283 STLOG_HAL_D("%s : Enter", __func__);
284 if (SpiLayerInterface_setup() != 0) {
285 return ESESTATUS_FAILED;
286 }
287
288 return ESESTATUS_SUCCESS;
289 }
290