• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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