1 /******************************************************************************
2 *
3 * Copyright 2018 NXP
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #define LOG_TAG "NxpEseHal"
19 #include <log/log.h>
20 #include <phNxpEseProto7816_3.h>
21
22 extern bool ese_debug_enabled;
23
24 /******************************************************************************
25 \section Introduction Introduction
26
27 * This module provide the 7816-3 protocol level implementation for ESE
28 *
29 ******************************************************************************/
30 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void);
31 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
32 uint8_t* p_data);
33 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
34 uint8_t** pp_data);
35 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
36 uint32_t offset, uint32_t length);
37 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len, uint8_t* p_data);
38 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData);
39 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData);
40 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType);
41 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void);
42 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void);
43 static ESESTATUS phNxpEseProro7816_SaveIframeData(uint8_t* p_data,
44 uint32_t data_len);
45 static ESESTATUS phNxpEseProto7816_ResetRecovery(void);
46 static ESESTATUS phNxpEseProto7816_RecoverySteps(void);
47 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
48 uint32_t data_len);
49 static ESESTATUS phNxpEseProto7816_ProcessResponse(void);
50 static ESESTATUS TransceiveProcess(void);
51 static ESESTATUS phNxpEseProto7816_RSync(void);
52 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void);
53
54 /******************************************************************************
55 * Function phNxpEseProto7816_SendRawFrame
56 *
57 * Description This internal function is called send the data to ESE
58 *
59 * Returns On success return true or else false.
60 *
61 ******************************************************************************/
phNxpEseProto7816_SendRawFrame(uint32_t data_len,uint8_t * p_data)62 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
63 uint8_t* p_data) {
64 ESESTATUS status = ESESTATUS_FAILED;
65 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
66 status = phNxpEse_WriteFrame(data_len, p_data);
67 if (ESESTATUS_SUCCESS != status) {
68 ALOGE("%s Error phNxpEse_WriteFrame\n", __FUNCTION__);
69 } else {
70 ALOGD_IF(ese_debug_enabled, "%s phNxpEse_WriteFrame Success \n",
71 __FUNCTION__);
72 }
73 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
74 return status;
75 }
76
77 /******************************************************************************
78 * Function phNxpEseProto7816_GetRawFrame
79 *
80 * Description This internal function is called read the data from the ESE
81 *
82 * Returns On success return true or else false.
83 *
84 ******************************************************************************/
phNxpEseProto7816_GetRawFrame(uint32_t * data_len,uint8_t ** pp_data)85 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
86 uint8_t** pp_data) {
87 ESESTATUS status = ESESTATUS_FAILED;
88
89 status = phNxpEse_read(data_len, pp_data);
90 if (ESESTATUS_SUCCESS != status) {
91 ALOGE("%s phNxpEse_read failed , status : 0x%x", __FUNCTION__, status);
92 }
93 return status;
94 }
95
96 /******************************************************************************
97 * Function phNxpEseProto7816_ComputeLRC
98 *
99 * Description This internal function is called compute the LRC
100 *
101 * Returns On success return true or else false.
102 *
103 ******************************************************************************/
phNxpEseProto7816_ComputeLRC(unsigned char * p_buff,uint32_t offset,uint32_t length)104 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
105 uint32_t offset, uint32_t length) {
106 uint32_t LRC = 0, i = 0;
107 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
108 for (i = offset; i < length; i++) {
109 LRC = LRC ^ p_buff[i];
110 }
111 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
112 return (uint8_t)LRC;
113 }
114
115 /******************************************************************************
116 * Function phNxpEseProto7816_CheckLRC
117 *
118 * Description This internal function is called compute and compare the
119 * received LRC of the received data
120 *
121 * Returns On success return true or else false.
122 *
123 ******************************************************************************/
phNxpEseProto7816_CheckLRC(uint32_t data_len,uint8_t * p_data)124 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len,
125 uint8_t* p_data) {
126 ESESTATUS status = ESESTATUS_SUCCESS;
127 uint8_t calc_crc = 0;
128 uint8_t recv_crc = 0;
129 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
130 recv_crc = p_data[data_len - 1];
131
132 /* calculate the CRC after excluding CRC */
133 calc_crc = phNxpEseProto7816_ComputeLRC(p_data, 1, (data_len - 1));
134 ALOGD_IF(ese_debug_enabled, "Received LRC:0x%x Calculated LRC:0x%x", recv_crc,
135 calc_crc);
136 if (recv_crc != calc_crc) {
137 status = ESESTATUS_FAILED;
138 ALOGE("%s LRC failed", __FUNCTION__);
139 }
140 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
141 return status;
142 }
143
144 /******************************************************************************
145 * Function phNxpEseProto7816_SendSFrame
146 *
147 * Description This internal function is called to send S-frame with all
148 * updated 7816-3 headers
149 *
150 * Returns On success return true or else false.
151 *
152 ******************************************************************************/
phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData)153 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData) {
154 ESESTATUS status = ESESTATUS_FAILED;
155 uint32_t frame_len = 0;
156 uint8_t* p_framebuff = NULL;
157 uint8_t pcb_byte = 0;
158 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
159 sFrameInfo_t sframeData = sFrameData;
160 /* This update is helpful in-case a R-NACK is transmitted from the MW */
161 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = SFRAME;
162 switch (sframeData.sFrameType) {
163 case RESYNCH_REQ:
164 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
165 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
166 if (NULL == p_framebuff) {
167 return ESESTATUS_FAILED;
168 }
169 p_framebuff[2] = 0;
170 p_framebuff[3] = 0x00;
171
172 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
173 pcb_byte |= PH_PROTO_7816_S_RESYNCH;
174 break;
175 case INTF_RESET_REQ:
176 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
177 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
178 if (NULL == p_framebuff) {
179 return ESESTATUS_FAILED;
180 }
181 p_framebuff[2] = 0;
182 p_framebuff[3] = 0x00;
183
184 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
185 pcb_byte |= PH_PROTO_7816_S_RESET;
186 break;
187 case PROP_END_APDU_REQ:
188 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
189 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
190 if (NULL == p_framebuff) {
191 return ESESTATUS_FAILED;
192 }
193 p_framebuff[2] = 0;
194 p_framebuff[3] = 0x00;
195
196 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
197 pcb_byte |= PH_PROTO_7816_S_END_OF_APDU;
198 break;
199 case WTX_RSP:
200 frame_len = (PH_PROTO_7816_HEADER_LEN + 1 + PH_PROTO_7816_CRC_LEN);
201 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
202 if (NULL == p_framebuff) {
203 return ESESTATUS_FAILED;
204 }
205 p_framebuff[2] = 0x01;
206 p_framebuff[3] = 0x01;
207
208 pcb_byte |= PH_PROTO_7816_S_BLOCK_RSP;
209 pcb_byte |= PH_PROTO_7816_S_WTX;
210 break;
211 default:
212 ALOGE("Invalid S-block");
213 break;
214 }
215 if (NULL != p_framebuff) {
216 /* frame the packet */
217 p_framebuff[0] = 0x00; /* NAD Byte */
218 p_framebuff[1] = pcb_byte; /* PCB */
219
220 p_framebuff[frame_len - 1] =
221 phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
222 ALOGD_IF(ese_debug_enabled, "S-Frame PCB: %x\n", p_framebuff[1]);
223 status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
224 phNxpEse_free(p_framebuff);
225 } else {
226 ALOGE("Invalid S-block or malloc for s-block failed");
227 }
228 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
229 return status;
230 }
231
232 /******************************************************************************
233 * Function phNxpEseProto7816_sendRframe
234 *
235 * Description This internal function is called to send R-frame with all
236 * updated 7816-3 headers
237 *
238 * Returns On success return true or else false.
239 *
240 ******************************************************************************/
phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType)241 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType) {
242 ESESTATUS status = ESESTATUS_FAILED;
243 uint8_t recv_ack[4] = {0x00, 0x80, 0x00, 0x00};
244 if (RNACK == rFrameType) /* R-NACK */
245 {
246 recv_ack[1] = 0x82;
247 } else /* R-ACK*/
248 {
249 /* This update is helpful in-case a R-NACK is transmitted from the MW */
250 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = RFRAME;
251 }
252 recv_ack[1] |=
253 ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo ^ 1)
254 << 4);
255 ALOGD_IF(ese_debug_enabled, "%s recv_ack[1]:0x%x", __FUNCTION__, recv_ack[1]);
256 recv_ack[3] =
257 phNxpEseProto7816_ComputeLRC(recv_ack, 0x00, (sizeof(recv_ack) - 1));
258 status = phNxpEseProto7816_SendRawFrame(sizeof(recv_ack), recv_ack);
259 return status;
260 }
261
262 /******************************************************************************
263 * Function phNxpEseProto7816_SendIframe
264 *
265 * Description This internal function is called to send I-frame with all
266 * updated 7816-3 headers
267 *
268 * Returns On success return true or else false.
269 *
270 ******************************************************************************/
phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData)271 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData) {
272 ESESTATUS status = ESESTATUS_FAILED;
273 uint32_t frame_len = 0;
274 uint8_t* p_framebuff = NULL;
275 uint8_t pcb_byte = 0;
276 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
277 if (0 == iFrameData.sendDataLen) {
278 ALOGE("I frame Len is 0, INVALID");
279 return ESESTATUS_FAILED;
280 }
281 /* This update is helpful in-case a R-NACK is transmitted from the MW */
282 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = IFRAME;
283 frame_len = (iFrameData.sendDataLen + PH_PROTO_7816_HEADER_LEN +
284 PH_PROTO_7816_CRC_LEN);
285
286 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
287 if (NULL == p_framebuff) {
288 ALOGE("Heap allocation failed");
289 return ESESTATUS_FAILED;
290 }
291
292 /* frame the packet */
293 p_framebuff[0] = 0x00; /* NAD Byte */
294
295 if (iFrameData.isChained) {
296 /* make B6 (M) bit high */
297 pcb_byte |= PH_PROTO_7816_CHAINING;
298 }
299
300 /* Update the send seq no */
301 pcb_byte |=
302 (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo << 6);
303
304 /* store the pcb byte */
305 p_framebuff[1] = pcb_byte;
306 /* store I frame length */
307 p_framebuff[2] = iFrameData.sendDataLen;
308 /* store I frame */
309 phNxpEse_memcpy(&(p_framebuff[3]), iFrameData.p_data + iFrameData.dataOffset,
310 iFrameData.sendDataLen);
311
312 p_framebuff[frame_len - 1] =
313 phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
314
315 status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
316
317 phNxpEse_free(p_framebuff);
318 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
319 return status;
320 }
321
322 /******************************************************************************
323 * Function phNxpEseProto7816_SetNextIframeContxt
324 *
325 * Description This internal function is called to set the context for next
326 *I-frame.
327 * Not applicable for the first I-frame of the transceive
328 *
329 * Returns On success return true or else false.
330 *
331 ******************************************************************************/
phNxpEseProto7816_SetFirstIframeContxt(void)332 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void) {
333 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
334 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset = 0;
335 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
336 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
337 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
338 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
339 if (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen >
340 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen) {
341 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
342 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
343 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen;
344 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
345 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen -
346 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen;
347 } else {
348 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
349 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen;
350 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
351 }
352 ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d Seq. no:%d",
353 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen,
354 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo);
355 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
356 return ESESTATUS_SUCCESS;
357 }
358
359 /******************************************************************************
360 * Function phNxpEseProto7816_SetNextIframeContxt
361 *
362 * Description This internal function is called to set the context for next
363 *I-frame.
364 * Not applicable for the first I-frame of the transceive
365 *
366 * Returns On success return true or else false.
367 *
368 ******************************************************************************/
phNxpEseProto7816_SetNextIframeContxt(void)369 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void) {
370 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
371 /* Expecting to reach here only after first of chained I-frame is sent and
372 * before the last chained is sent */
373 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
374 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
375
376 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
377 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
378 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset =
379 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.dataOffset +
380 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen;
381 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data =
382 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data;
383 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen =
384 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen;
385
386 // if chained
387 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen >
388 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen) {
389 ALOGD_IF(ese_debug_enabled, "Process Chained Frame");
390 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
391 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
392 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen;
393 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
394 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen -
395 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen;
396 } else {
397 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
398 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
399 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen;
400 }
401 ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d",
402 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen);
403 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
404 return ESESTATUS_SUCCESS;
405 }
406
407 /******************************************************************************
408 * Function phNxpEseProto7816_ResetRecovery
409 *
410 * Description This internal function is called to do reset the recovery
411 *pareameters
412 *
413 * Returns On success return true or else false.
414 *
415 ******************************************************************************/
phNxpEseProro7816_SaveIframeData(uint8_t * p_data,uint32_t data_len)416 static ESESTATUS phNxpEseProro7816_SaveIframeData(uint8_t* p_data,
417 uint32_t data_len) {
418 ESESTATUS status = ESESTATUS_FAILED;
419 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
420 ALOGD_IF(ese_debug_enabled, "Data[0]=0x%x len=%d Data[%d]=0x%x", p_data[0],
421 data_len, data_len - 1, p_data[data_len - 1]);
422 if (ESESTATUS_SUCCESS != phNxpEse_StoreDatainList(data_len, p_data)) {
423 ALOGE("%s - Error storing chained data in list", __FUNCTION__);
424 } else {
425 status = ESESTATUS_SUCCESS;
426 }
427 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
428 return status;
429 }
430
431 /******************************************************************************
432 * Function phNxpEseProto7816_ResetRecovery
433 *
434 * Description This internal function is called to do reset the recovery
435 *pareameters
436 *
437 * Returns On success return true or else false.
438 *
439 ******************************************************************************/
phNxpEseProto7816_ResetRecovery(void)440 static ESESTATUS phNxpEseProto7816_ResetRecovery(void) {
441 phNxpEseProto7816_3_Var.recoveryCounter = 0;
442 return ESESTATUS_SUCCESS;
443 }
444
445 /******************************************************************************
446 * Function phNxpEseProto7816_RecoverySteps
447 *
448 * Description This internal function is called when 7816-3 stack failed to
449 *recover
450 * after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has
451 *to be
452 * recovered
453 * Returns On success return true or else false.
454 *
455 ******************************************************************************/
phNxpEseProto7816_RecoverySteps(void)456 static ESESTATUS phNxpEseProto7816_RecoverySteps(void) {
457 if (phNxpEseProto7816_3_Var.recoveryCounter <=
458 PH_PROTO_7816_FRAME_RETRY_COUNT) {
459 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
460 INTF_RESET_REQ;
461 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
462 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
463 INTF_RESET_REQ;
464 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
465 SEND_S_INTF_RST;
466 } else { /* If recovery fails */
467 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
468 }
469 return ESESTATUS_SUCCESS;
470 }
471
472 /******************************************************************************
473 * Function phNxpEseProto7816_DecodeSecureTimer
474 *
475 * Description This internal function is to decode the secure timer.
476 * value from the payload
477 * Returns void
478 *
479 ******************************************************************************/
phNxpEseProto7816_DecodeSecureTimer(uint8_t * frameOffset,unsigned int * secureTimer,uint8_t * p_data)480 static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset,
481 unsigned int* secureTimer,
482 uint8_t* p_data) {
483 uint8_t byteCounter = 0;
484 uint8_t dataLength = p_data[++(*frameOffset)]; /* To get the L of TLV */
485 if (dataLength > 0) {
486 /* V of TLV: Retrieve each byte(4 byte) and push it to get the secure timer
487 * value (unsigned long) */
488 for (byteCounter = 1; byteCounter <= dataLength; byteCounter++) {
489 (*frameOffset)++;
490 *secureTimer = (*secureTimer) << 8;
491 *secureTimer |= p_data[(*frameOffset)];
492 }
493 } else {
494 (*frameOffset)++; /* Goto the end of current marker if length is zero */
495 }
496 return;
497 }
498
499 /******************************************************************************
500 * Function phNxpEseProto7816_DecodeSFrameData
501 *
502 * Description This internal function is to decode S-frame payload.
503 * Returns void
504 *
505 ******************************************************************************/
phNxpEseProto7816_DecodeSFrameData(uint8_t * p_data)506 static void phNxpEseProto7816_DecodeSFrameData(uint8_t* p_data) {
507 uint8_t maxSframeLen = 0, dataType = 0, frameOffset = 0;
508 frameOffset = PH_PROPTO_7816_FRAME_LENGTH_OFFSET;
509 maxSframeLen =
510 p_data[frameOffset] +
511 frameOffset; /* to be in sync with offset which starts from index 0 */
512 while (maxSframeLen > frameOffset) {
513 frameOffset += 1; /* To get the Type (TLV) */
514 dataType = p_data[frameOffset];
515 ALOGD_IF(ese_debug_enabled, "%s frameoffset=%d value=0x%x\n", __FUNCTION__,
516 frameOffset, p_data[frameOffset]);
517 switch (dataType) /* Type (TLV) */
518 {
519 case PH_PROPTO_7816_SFRAME_TIMER1:
520 phNxpEseProto7816_DecodeSecureTimer(
521 &frameOffset,
522 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1, p_data);
523 break;
524 case PH_PROPTO_7816_SFRAME_TIMER2:
525 phNxpEseProto7816_DecodeSecureTimer(
526 &frameOffset,
527 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2, p_data);
528 break;
529 case PH_PROPTO_7816_SFRAME_TIMER3:
530 phNxpEseProto7816_DecodeSecureTimer(
531 &frameOffset,
532 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3, p_data);
533 break;
534 default:
535 frameOffset +=
536 p_data[frameOffset + 1]; /* Goto the end of current marker */
537 break;
538 }
539 }
540 ALOGD_IF(ese_debug_enabled, "secure timer t1 = 0x%x t2 = 0x%x t3 = 0x%x",
541 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1,
542 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2,
543 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3);
544 return;
545 }
546
547 /******************************************************************************
548 * Function phNxpEseProto7816_DecodeFrame
549 *
550 * Description This internal function is used to
551 * 1. Identify the received frame
552 * 2. If the received frame is I-frame with expected sequence
553 number, store it or else send R-NACK
554 3. If the received frame is R-frame,
555 3.1 R-ACK with expected seq. number: Send the next
556 chained I-frame
557 3.2 R-ACK with different sequence number: Sebd the R-Nack
558 3.3 R-NACK: Re-send the last frame
559 4. If the received frame is S-frame, send back the correct
560 S-frame response.
561 * Returns On success return true or else false.
562 *
563 ******************************************************************************/
phNxpEseProto7816_DecodeFrame(uint8_t * p_data,uint32_t data_len)564 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
565 uint32_t data_len) {
566 ESESTATUS status = ESESTATUS_SUCCESS;
567 uint8_t pcb;
568 phNxpEseProto7816_PCB_bits_t pcb_bits;
569 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
570 ALOGD_IF(ese_debug_enabled, "Retry Counter = %d\n",
571 phNxpEseProto7816_3_Var.recoveryCounter);
572 pcb = p_data[PH_PROPTO_7816_PCB_OFFSET];
573 // memset(&phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.rcvPcbBits, 0x00,
574 // sizeof(struct PCB_BITS));
575 phNxpEse_memset(&pcb_bits, 0x00, sizeof(phNxpEseProto7816_PCB_bits_t));
576 phNxpEse_memcpy(&pcb_bits, &pcb, sizeof(uint8_t));
577
578 if (0x00 == pcb_bits.msb) /* I-FRAME decoded should come here */
579 {
580 ALOGD_IF(ese_debug_enabled, "%s I-Frame Received", __FUNCTION__);
581 phNxpEseProto7816_3_Var.wtx_counter = 0;
582 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = IFRAME;
583 if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo !=
584 pcb_bits.bit7) // != pcb_bits->bit7)
585 {
586 ALOGD_IF(ese_debug_enabled, "%s I-Frame lastRcvdIframeInfo.seqNo:0x%x",
587 __FUNCTION__, pcb_bits.bit7);
588 phNxpEseProto7816_ResetRecovery();
589 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo = 0x00;
590 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo |=
591 pcb_bits.bit7;
592
593 if (pcb_bits.bit6) {
594 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
595 true;
596 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
597 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
598 NO_ERROR;
599 status = phNxpEseProro7816_SaveIframeData(&p_data[3], data_len - 4);
600 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
601 SEND_R_ACK;
602 } else {
603 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
604 false;
605 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
606 IDLE_STATE;
607 status = phNxpEseProro7816_SaveIframeData(&p_data[3], data_len - 4);
608 }
609 } else {
610 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
611 if (phNxpEseProto7816_3_Var.recoveryCounter <
612 PH_PROTO_7816_FRAME_RETRY_COUNT) {
613 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
614 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
615 OTHER_ERROR;
616 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
617 SEND_R_NACK;
618 phNxpEseProto7816_3_Var.recoveryCounter++;
619 } else {
620 phNxpEseProto7816_RecoverySteps();
621 phNxpEseProto7816_3_Var.recoveryCounter++;
622 }
623 }
624 } else if ((0x01 == pcb_bits.msb) &&
625 (0x00 == pcb_bits.bit7)) /* R-FRAME decoded should come here */
626 {
627 ALOGD_IF(ese_debug_enabled, "%s R-Frame Received", __FUNCTION__);
628 phNxpEseProto7816_3_Var.wtx_counter = 0;
629 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = RFRAME;
630 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo =
631 0; // = 0;
632 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo |=
633 pcb_bits.bit5;
634
635 if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x00)) {
636 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
637 NO_ERROR;
638 phNxpEseProto7816_ResetRecovery();
639 if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo !=
640 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) {
641 status = phNxpEseProto7816_SetNextIframeContxt();
642 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
643 SEND_IFRAME;
644 } else {
645 // error handling.
646 }
647 } /* Error handling 1 : Parity error */
648 else if (((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) ||
649 /* Error handling 2: Other indicated error */
650 ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01))) {
651 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
652 if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01))
653 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
654 OTHER_ERROR;
655 else
656 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
657 PARITY_ERROR;
658 if (phNxpEseProto7816_3_Var.recoveryCounter <
659 PH_PROTO_7816_FRAME_RETRY_COUNT) {
660 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == IFRAME) {
661 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
662 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
663 sizeof(phNxpEseProto7816_NextTx_Info_t));
664 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
665 SEND_IFRAME;
666 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
667 } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
668 RFRAME) {
669 /* Usecase to reach the below case:
670 I-frame sent first, followed by R-NACK and we receive a R-NACK with
671 last sent I-frame sequence number*/
672 if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
673 .seqNo ==
674 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) &&
675 (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == IFRAME)) {
676 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
677 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
678 sizeof(phNxpEseProto7816_NextTx_Info_t));
679 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
680 SEND_IFRAME;
681 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
682 }
683 /* Usecase to reach the below case:
684 R-frame sent first, followed by R-NACK and we receive a R-NACK with
685 next expected I-frame sequence number*/
686 else if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
687 .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
688 .IframeInfo.seqNo) &&
689 (phNxpEseProto7816_3_Var.lastSentNonErrorframeType ==
690 RFRAME)) {
691 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
692 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
693 NO_ERROR;
694 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
695 SEND_R_ACK;
696 }
697 /* Usecase to reach the below case:
698 I-frame sent first, followed by R-NACK and we receive a R-NACK with
699 next expected I-frame sequence number + all the other unexpected
700 scenarios */
701 else {
702 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
703 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
704 OTHER_ERROR;
705 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
706 SEND_R_NACK;
707 }
708 } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
709 SFRAME) {
710 /* Copy the last S frame sent */
711 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
712 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
713 sizeof(phNxpEseProto7816_NextTx_Info_t));
714 }
715 phNxpEseProto7816_3_Var.recoveryCounter++;
716 } else {
717 phNxpEseProto7816_RecoverySteps();
718 phNxpEseProto7816_3_Var.recoveryCounter++;
719 }
720 // resend previously send I frame
721 }
722 /* Error handling 3 */
723 else if ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x01)) {
724 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
725 if (phNxpEseProto7816_3_Var.recoveryCounter <
726 PH_PROTO_7816_FRAME_RETRY_COUNT) {
727 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
728 SOF_MISSED_ERROR;
729 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
730 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
731 phNxpEseProto7816_3_Var.recoveryCounter++;
732 } else {
733 phNxpEseProto7816_RecoverySteps();
734 phNxpEseProto7816_3_Var.recoveryCounter++;
735 }
736 } else /* Error handling 4 */
737 {
738 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
739 if (phNxpEseProto7816_3_Var.recoveryCounter <
740 PH_PROTO_7816_FRAME_RETRY_COUNT) {
741 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
742 UNDEFINED_ERROR;
743 phNxpEseProto7816_3_Var.recoveryCounter++;
744 } else {
745 phNxpEseProto7816_RecoverySteps();
746 phNxpEseProto7816_3_Var.recoveryCounter++;
747 }
748 }
749 } else if ((0x01 == pcb_bits.msb) &&
750 (0x01 == pcb_bits.bit7)) /* S-FRAME decoded should come here */
751 {
752 ALOGD_IF(ese_debug_enabled, "%s S-Frame Received", __FUNCTION__);
753 int32_t frameType = (int32_t)(pcb & 0x3F); /*discard upper 2 bits */
754 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME;
755 if (frameType != WTX_REQ) {
756 phNxpEseProto7816_3_Var.wtx_counter = 0;
757 }
758 switch (frameType) {
759 case RESYNCH_REQ:
760 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
761 RESYNCH_REQ;
762 break;
763 case RESYNCH_RSP:
764 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
765 RESYNCH_RSP;
766 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
767 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
768 IDLE_STATE;
769 break;
770 case IFSC_REQ:
771 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
772 IFSC_REQ;
773 break;
774 case IFSC_RES:
775 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
776 IFSC_RES;
777 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
778 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
779 IDLE_STATE;
780 break;
781 case ABORT_REQ:
782 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
783 ABORT_REQ;
784 break;
785 case ABORT_RES:
786 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
787 ABORT_RES;
788 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
789 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
790 IDLE_STATE;
791 break;
792 case WTX_REQ:
793 phNxpEseProto7816_3_Var.wtx_counter++;
794 ALOGD_IF(ese_debug_enabled, "%s Wtx_counter value - %lu", __FUNCTION__,
795 phNxpEseProto7816_3_Var.wtx_counter);
796 ALOGD_IF(ese_debug_enabled, "%s Wtx_counter wtx_counter_limit - %lu",
797 __FUNCTION__, phNxpEseProto7816_3_Var.wtx_counter_limit);
798 /* Previous sent frame is some S-frame but not WTX response S-frame */
799 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType !=
800 WTX_RSP &&
801 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
802 SFRAME) { /* Goto recovery if it keep coming here for more than
803 recovery counter max. value */
804 if (phNxpEseProto7816_3_Var.recoveryCounter <
805 PH_PROTO_7816_FRAME_RETRY_COUNT) { /* Re-transmitting the previous
806 sent S-frame */
807 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
808 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
809 phNxpEseProto7816_3_Var.recoveryCounter++;
810 } else {
811 phNxpEseProto7816_RecoverySteps();
812 phNxpEseProto7816_3_Var.recoveryCounter++;
813 }
814 } else { /* Checking for WTX counter with max. allowed WTX count */
815 if (phNxpEseProto7816_3_Var.wtx_counter ==
816 phNxpEseProto7816_3_Var.wtx_counter_limit) {
817 phNxpEseProto7816_3_Var.wtx_counter = 0;
818 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
819 .sFrameType = INTF_RESET_REQ;
820 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
821 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
822 INTF_RESET_REQ;
823 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
824 SEND_S_INTF_RST;
825 ALOGE("%s Interface Reset to eSE wtx count reached!!!",
826 __FUNCTION__);
827 } else {
828 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
829 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
830 .sFrameType = WTX_REQ;
831 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
832 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
833 WTX_RSP;
834 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
835 SEND_S_WTX_RSP;
836 }
837 }
838 break;
839 case WTX_RSP:
840 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
841 WTX_RSP;
842 break;
843 case INTF_RESET_REQ:
844 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
845 INTF_RESET_REQ;
846 break;
847 case INTF_RESET_RSP:
848 phNxpEseProto7816_ResetProtoParams();
849 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
850 INTF_RESET_RSP;
851 if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
852 phNxpEseProto7816_DecodeSFrameData(p_data);
853 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
854 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
855 IDLE_STATE;
856 break;
857 case PROP_END_APDU_REQ:
858 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
859 PROP_END_APDU_REQ;
860 break;
861 case PROP_END_APDU_RSP:
862 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
863 PROP_END_APDU_RSP;
864 if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
865 phNxpEseProto7816_DecodeSFrameData(p_data);
866 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
867 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
868 IDLE_STATE;
869 break;
870 default:
871 ALOGE("%s Wrong S-Frame Received", __FUNCTION__);
872 break;
873 }
874 } else {
875 ALOGE("%s Wrong-Frame Received", __FUNCTION__);
876 }
877 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
878 return status;
879 }
880
881 /******************************************************************************
882 * Function phNxpEseProto7816_ProcessResponse
883 *
884 * Description This internal function is used to
885 * 1. Check the LRC
886 * 2. Initiate decoding of received frame of data.
887 * Returns On success return true or else false.
888 *
889 ******************************************************************************/
phNxpEseProto7816_ProcessResponse(void)890 static ESESTATUS phNxpEseProto7816_ProcessResponse(void) {
891 uint32_t data_len = 0;
892 uint8_t* p_data = NULL;
893 ESESTATUS status = ESESTATUS_FAILED;
894 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
895 status = phNxpEseProto7816_GetRawFrame(&data_len, &p_data);
896 ALOGD_IF(ese_debug_enabled, "%s p_data ----> %p len ----> 0x%x", __FUNCTION__,
897 p_data, data_len);
898 if (ESESTATUS_SUCCESS == status) {
899 /* Resetting the timeout counter */
900 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
901 /* LRC check followed */
902 status = phNxpEseProto7816_CheckLRC(data_len, p_data);
903 if (status == ESESTATUS_SUCCESS) {
904 /* Resetting the RNACK retry counter */
905 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
906 phNxpEseProto7816_DecodeFrame(p_data, data_len);
907 } else {
908 ALOGE("%s LRC Check failed", __FUNCTION__);
909 if (phNxpEseProto7816_3_Var.rnack_retry_counter <
910 phNxpEseProto7816_3_Var.rnack_retry_limit) {
911 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
912 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
913 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
914 PARITY_ERROR;
915 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
916 (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo)
917 << 4;
918 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
919 SEND_R_NACK;
920 phNxpEseProto7816_3_Var.rnack_retry_counter++;
921 } else {
922 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
923 /* Re-transmission failed completely, Going to exit */
924 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
925 IDLE_STATE;
926 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
927 }
928 }
929 } else {
930 ALOGE("%s phNxpEseProto7816_GetRawFrame failed", __FUNCTION__);
931 if ((SFRAME == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType) &&
932 ((WTX_RSP ==
933 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) ||
934 (RESYNCH_RSP ==
935 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType))) {
936 if (phNxpEseProto7816_3_Var.rnack_retry_counter <
937 phNxpEseProto7816_3_Var.rnack_retry_limit) {
938 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
939 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
940 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
941 OTHER_ERROR;
942 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
943 (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo)
944 << 4;
945 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
946 SEND_R_NACK;
947 phNxpEseProto7816_3_Var.rnack_retry_counter++;
948 } else {
949 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
950 /* Re-transmission failed completely, Going to exit */
951 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
952 IDLE_STATE;
953 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
954 }
955 } else {
956 phNxpEse_Sleep(DELAY_ERROR_RECOVERY);
957 /* re transmit the frame */
958 if (phNxpEseProto7816_3_Var.timeoutCounter <
959 PH_PROTO_7816_TIMEOUT_RETRY_COUNT) {
960 phNxpEseProto7816_3_Var.timeoutCounter++;
961 ALOGE("%s re-transmitting the previous frame", __FUNCTION__);
962 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
963 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
964 } else {
965 /* Re-transmission failed completely, Going to exit */
966 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
967 IDLE_STATE;
968 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
969 ALOGE("%s calling phNxpEse_StoreDatainList", __FUNCTION__);
970 phNxpEse_StoreDatainList(data_len, p_data);
971 }
972 }
973 }
974 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
975 return status;
976 }
977
978 /******************************************************************************
979 * Function TransceiveProcess
980 *
981 * Description This internal function is used to
982 * 1. Send the raw data received from application after
983 *computing LRC
984 * 2. Receive the the response data from ESE, decode, process
985 *and
986 * store the data.
987 * Returns On success return true or else false.
988 *
989 ******************************************************************************/
TransceiveProcess(void)990 static ESESTATUS TransceiveProcess(void) {
991 ESESTATUS status = ESESTATUS_FAILED;
992 sFrameInfo_t sFrameInfo;
993
994 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
995 while (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState !=
996 IDLE_STATE) {
997 ALOGD_IF(ese_debug_enabled, "%s nextTransceiveState %x", __FUNCTION__,
998 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState);
999 switch (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState) {
1000 case SEND_IFRAME:
1001 status = phNxpEseProto7816_SendIframe(
1002 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo);
1003 break;
1004 case SEND_R_ACK:
1005 status = phNxpEseProto7816_sendRframe(RACK);
1006 break;
1007 case SEND_R_NACK:
1008 status = phNxpEseProto7816_sendRframe(RNACK);
1009 break;
1010 case SEND_S_RSYNC:
1011 sFrameInfo.sFrameType = RESYNCH_REQ;
1012 status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1013 break;
1014 case SEND_S_INTF_RST:
1015 sFrameInfo.sFrameType = INTF_RESET_REQ;
1016 status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1017 break;
1018 case SEND_S_EOS:
1019 sFrameInfo.sFrameType = PROP_END_APDU_REQ;
1020 status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1021 break;
1022 case SEND_S_WTX_RSP:
1023 sFrameInfo.sFrameType = WTX_RSP;
1024 status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1025 break;
1026 default:
1027 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1028 IDLE_STATE;
1029 break;
1030 }
1031 if (ESESTATUS_SUCCESS == status) {
1032 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1033 &phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1034 sizeof(phNxpEseProto7816_NextTx_Info_t));
1035 status = phNxpEseProto7816_ProcessResponse();
1036 } else {
1037 ALOGD_IF(ese_debug_enabled,
1038 "%s Transceive send failed, going to recovery!", __FUNCTION__);
1039 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1040 IDLE_STATE;
1041 }
1042 };
1043 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
1044 return status;
1045 }
1046
1047 /******************************************************************************
1048 * Function phNxpEseProto7816_Transceive
1049 *
1050 * Description This function is used to
1051 * 1. Send the raw data received from application after
1052 *computing LRC
1053 * 2. Receive the the response data from ESE, decode, process
1054 *and
1055 * store the data.
1056 * 3. Get the final complete data and sent back to application
1057 *
1058 * Returns On success return true or else false.
1059 *
1060 ******************************************************************************/
phNxpEseProto7816_Transceive(phNxpEse_data * pCmd,phNxpEse_data * pRsp)1061 ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd,
1062 phNxpEse_data* pRsp) {
1063 ESESTATUS status = ESESTATUS_FAILED;
1064 ESESTATUS wStatus = ESESTATUS_FAILED;
1065 phNxpEse_data pRes;
1066 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
1067 if ((NULL == pCmd) || (NULL == pRsp) ||
1068 (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
1069 PH_NXP_ESE_PROTO_7816_IDLE))
1070 return status;
1071 phNxpEse_memset(&pRes, 0x00, sizeof(phNxpEse_data));
1072 /* Updating the transceive information to the protocol stack */
1073 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1074 PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1075 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = pCmd->p_data;
1076 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
1077 pCmd->len;
1078 ALOGD_IF(ese_debug_enabled, "Transceive data ptr 0x%p len:%d", pCmd->p_data,
1079 pCmd->len);
1080 status = phNxpEseProto7816_SetFirstIframeContxt();
1081 status = TransceiveProcess();
1082 if (ESESTATUS_FAILED == status) {
1083 /* ESE hard reset to be done */
1084 ALOGE("Transceive failed, hard reset to proceed");
1085 wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1086 if (ESESTATUS_SUCCESS == wStatus) {
1087 ALOGE(
1088 "%s Data successfully received at 7816, packaging to "
1089 "send upper layers: DataLen = %d",
1090 __FUNCTION__, pRes.len);
1091 /* Copy the data to be read by the upper layer via transceive api */
1092 pRsp->len = pRes.len;
1093 pRsp->p_data = pRes.p_data;
1094 }
1095 } else {
1096 // fetch the data info and report to upper layer.
1097 wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1098 if (ESESTATUS_SUCCESS == wStatus) {
1099 ALOGD_IF(ese_debug_enabled,
1100 "%s Data successfully received at 7816, packaging to "
1101 "send upper layers: DataLen = %d",
1102 __FUNCTION__, pRes.len);
1103 /* Copy the data to be read by the upper layer via transceive api */
1104 pRsp->len = pRes.len;
1105 pRsp->p_data = pRes.p_data;
1106 } else
1107 status = ESESTATUS_FAILED;
1108 }
1109 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1110 PH_NXP_ESE_PROTO_7816_IDLE;
1111 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
1112 return status;
1113 }
1114
1115 /******************************************************************************
1116 * Function phNxpEseProto7816_RSync
1117 *
1118 * Description This function is used to send the RSync command
1119 *
1120 * Returns On success return true or else false.
1121 *
1122 ******************************************************************************/
phNxpEseProto7816_RSync(void)1123 static ESESTATUS phNxpEseProto7816_RSync(void) {
1124 ESESTATUS status = ESESTATUS_FAILED;
1125 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1126 PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1127 /* send the end of session s-frame */
1128 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1129 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1130 RESYNCH_REQ;
1131 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_RSYNC;
1132 status = TransceiveProcess();
1133 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1134 PH_NXP_ESE_PROTO_7816_IDLE;
1135 return status;
1136 }
1137
1138 /******************************************************************************
1139 * Function phNxpEseProto7816_ResetProtoParams
1140 *
1141 * Description This function is used to reset the 7816 protocol stack
1142 *instance
1143 *
1144 * Returns On success return true or else false.
1145 *
1146 ******************************************************************************/
phNxpEseProto7816_ResetProtoParams(void)1147 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void) {
1148 unsigned long int tmpWTXCountlimit = PH_PROTO_7816_VALUE_ZERO;
1149 unsigned long int tmpRNACKCountlimit = PH_PROTO_7816_VALUE_ZERO;
1150 tmpWTXCountlimit = phNxpEseProto7816_3_Var.wtx_counter_limit;
1151 tmpRNACKCountlimit = phNxpEseProto7816_3_Var.rnack_retry_limit;
1152 phNxpEse_memset(&phNxpEseProto7816_3_Var, PH_PROTO_7816_VALUE_ZERO,
1153 sizeof(phNxpEseProto7816_t));
1154 phNxpEseProto7816_3_Var.wtx_counter_limit = tmpWTXCountlimit;
1155 phNxpEseProto7816_3_Var.rnack_retry_limit = tmpRNACKCountlimit;
1156 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1157 PH_NXP_ESE_PROTO_7816_IDLE;
1158 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
1159 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1160 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = INVALID;
1161 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen =
1162 IFSC_SIZE_SEND;
1163 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = NULL;
1164 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType = INVALID;
1165 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen =
1166 IFSC_SIZE_SEND;
1167 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data = NULL;
1168 /* Initialized with sequence number of the last I-frame sent */
1169 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
1170 PH_PROTO_7816_VALUE_ONE;
1171 /* Initialized with sequence number of the last I-frame received */
1172 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
1173 PH_PROTO_7816_VALUE_ONE;
1174 /* Initialized with sequence number of the last I-frame received */
1175 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo =
1176 PH_PROTO_7816_VALUE_ONE;
1177 phNxpEseProto7816_3_Var.recoveryCounter = PH_PROTO_7816_VALUE_ZERO;
1178 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1179 phNxpEseProto7816_3_Var.wtx_counter = PH_PROTO_7816_VALUE_ZERO;
1180 /* This update is helpful in-case a R-NACK is transmitted from the MW */
1181 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = UNKNOWN;
1182 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1183 return ESESTATUS_SUCCESS;
1184 }
1185
1186 /******************************************************************************
1187 * Function phNxpEseProto7816_Reset
1188 *
1189 * Description This function is used to reset the 7816 protocol stack
1190 *instance
1191 *
1192 * Returns On success return true or else false.
1193 *
1194 ******************************************************************************/
phNxpEseProto7816_Reset(void)1195 ESESTATUS phNxpEseProto7816_Reset(void) {
1196 ESESTATUS status = ESESTATUS_FAILED;
1197 /* Resetting host protocol instance */
1198 phNxpEseProto7816_ResetProtoParams();
1199 /* Resynchronising ESE protocol instance */
1200 status = phNxpEseProto7816_RSync();
1201 return status;
1202 }
1203
1204 /******************************************************************************
1205 * Function phNxpEseProto7816_Open
1206 *
1207 * Description This function is used to open the 7816 protocol stack
1208 *instance
1209 *
1210 * Returns On success return true or else false.
1211 *
1212 ******************************************************************************/
phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam)1213 ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam) {
1214 ESESTATUS status = ESESTATUS_FAILED;
1215 status = phNxpEseProto7816_ResetProtoParams();
1216 ALOGD_IF(ese_debug_enabled, "%s: First open completed, Congratulations",
1217 __FUNCTION__);
1218 /* Update WTX max. limit */
1219 phNxpEseProto7816_3_Var.wtx_counter_limit = initParam.wtx_counter_limit;
1220 phNxpEseProto7816_3_Var.rnack_retry_limit = initParam.rnack_retry_limit;
1221 if (initParam.interfaceReset) /* Do interface reset */
1222 {
1223 status = phNxpEseProto7816_IntfReset(initParam.pSecureTimerParams);
1224 if (ESESTATUS_SUCCESS == status) {
1225 phNxpEse_memcpy(initParam.pSecureTimerParams,
1226 &phNxpEseProto7816_3_Var.secureTimerParams,
1227 sizeof(phNxpEseProto7816SecureTimer_t));
1228 }
1229 } else /* Do R-Sync */
1230 {
1231 status = phNxpEseProto7816_RSync();
1232 }
1233 return status;
1234 }
1235
1236 /******************************************************************************
1237 * Function phNxpEseProto7816_Close
1238 *
1239 * Description This function is used to close the 7816 protocol stack
1240 *instance
1241 *
1242 * Returns On success return true or else false.
1243 *
1244 ******************************************************************************/
phNxpEseProto7816_Close(phNxpEseProto7816SecureTimer_t * pSecureTimerParams)1245 ESESTATUS phNxpEseProto7816_Close(
1246 phNxpEseProto7816SecureTimer_t* pSecureTimerParams) {
1247 ESESTATUS status = ESESTATUS_FAILED;
1248 if (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
1249 PH_NXP_ESE_PROTO_7816_IDLE)
1250 return status;
1251 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1252 PH_NXP_ESE_PROTO_7816_DEINIT;
1253 phNxpEseProto7816_3_Var.recoveryCounter = 0;
1254 phNxpEseProto7816_3_Var.wtx_counter = 0;
1255 /* send the end of session s-frame */
1256 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1257 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1258 PROP_END_APDU_REQ;
1259 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_EOS;
1260 status = TransceiveProcess();
1261 if (ESESTATUS_FAILED == status) {
1262 /* reset all the structures */
1263 ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
1264 }
1265 phNxpEse_memcpy(pSecureTimerParams,
1266 &phNxpEseProto7816_3_Var.secureTimerParams,
1267 sizeof(phNxpEseProto7816SecureTimer_t));
1268 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1269 PH_NXP_ESE_PROTO_7816_IDLE;
1270 return status;
1271 }
1272
1273 /******************************************************************************
1274 * Function phNxpEseProto7816_IntfReset
1275 *
1276 * Description This function is used to reset just the current interface
1277 *
1278 * Returns On success return true or else false.
1279 *
1280 ******************************************************************************/
phNxpEseProto7816_IntfReset(phNxpEseProto7816SecureTimer_t * pSecureTimerParam)1281 ESESTATUS phNxpEseProto7816_IntfReset(
1282 phNxpEseProto7816SecureTimer_t* pSecureTimerParam) {
1283 ESESTATUS status = ESESTATUS_FAILED;
1284 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
1285 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1286 PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1287 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1288 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1289 INTF_RESET_REQ;
1290 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1291 SEND_S_INTF_RST;
1292 status = TransceiveProcess();
1293 if (ESESTATUS_FAILED == status) {
1294 /* reset all the structures */
1295 ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
1296 }
1297 phNxpEse_memcpy(pSecureTimerParam, &phNxpEseProto7816_3_Var.secureTimerParams,
1298 sizeof(phNxpEseProto7816SecureTimer_t));
1299 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1300 PH_NXP_ESE_PROTO_7816_IDLE;
1301 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
1302 return status;
1303 }
1304
1305 /******************************************************************************
1306 * Function phNxpEseProto7816_SetIfscSize
1307 *
1308 * Description This function is used to set the max T=1 data send size
1309 *
1310 * Returns Always return true (1).
1311 *
1312 ******************************************************************************/
phNxpEseProto7816_SetIfscSize(uint16_t IFSC_Size)1313 ESESTATUS phNxpEseProto7816_SetIfscSize(uint16_t IFSC_Size) {
1314 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen = IFSC_Size;
1315 return ESESTATUS_SUCCESS;
1316 }
1317 /** @} */
1318