1 /******************************************************************************
2  *
3  *  Copyright 2018-2023 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 <ese_logs.h>
20 #include <log/log.h>
21 #include <phNxpEseProto7816_3.h>
22 
23 #include "phNxpEsePal.h"
24 
25 /**
26  * \addtogroup ISO7816-3_protocol_lib
27  *
28  * @{ */
29 
30 /**
31  * \ingroup ISO7816-3_protocol_lib
32  * \brief   This function is used to reset the 7816 protocol stack instance
33  *
34  *
35  */
36 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void);
37 
38 /**
39  * \ingroup ISO7816-3_protocol_lib
40  * \brief    This internal function is called send the data to ESE
41  *\param[in]     data_len - data len
42  *\param[in]     p_data  -address to raw data
43  *
44  */
45 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
46                                                 uint8_t* p_data);
47 
48 /**
49  * \ingroup ISO7816-3_protocol_lib
50  * \brief    This internal function is called read the data from the ESE
51  *\param[in]     data_len - data len
52  *\param[in]     pp_data  -address to raw data
53  *
54  */
55 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
56                                                uint8_t** pp_data);
57 
58 /**
59  * \ingroup ISO7816-3_protocol_lib
60  * \brief   This internal function is called compute the LRC
61  *\param[in]     p_buff - raw data
62  *\param[in]     offset  -address to raw data
63  *\param[in]     length - length of data.
64  *\retval LRC value.
65  *
66  */
67 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
68                                             uint32_t offset, uint32_t length);
69 
70 /**
71  * \ingroup ISO7816-3_protocol_lib
72  * \brief     This internal function is called compute and compare the
73  *                  received LRC of the received data
74  *\param[in]    data_len - raw data
75  *\param[in]    p_data  -address to raw data
76  *
77  */
78 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len, uint8_t* p_data);
79 
80 /**
81  * \ingroup ISO7816-3_protocol_lib
82  * \brief     This internal function is called to send S-frame with all
83  *                   updated 7816-3 headers
84  *\param[in]    sFrameData -S frame APDU
85  *
86  */
87 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData);
88 
89 /**
90  * \ingroup ISO7816-3_protocol_lib
91  * \brief      This internal function is called to send I-frame with all
92  *                   updated 7816-3 headers
93  *\param[in]    iFrameData -I frame APDU
94  *
95  */
96 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData);
97 
98 /**
99  * \ingroup ISO7816-3_protocol_lib
100  * \brief        This internal function is called to send R-frame with all
101  *updated 7816-3 headers
102  *\param[in]    rFrameType -R frame APDU
103  *
104  */
105 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType);
106 
107 /**
108  * \ingroup ISO7816-3_protocol_lib
109  * \brief      This internal function is called to set the context for first
110  *I-frame. Not applicable for the first I-frame of the transceive
111  *
112  */
113 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void);
114 
115 /**
116  * \ingroup ISO7816-3_protocol_lib
117  * \brief      This internal function is called to set the context for next
118  *I-frame. Not applicable for the first I-frame of the transceive
119  *
120  */
121 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void);
122 
123 /**
124  * \ingroup ISO7816-3_protocol_lib
125  * \brief      This internal function is called to push I-frame data to internal
126  *structure.
127  *\param[in]    p_data -raw data buffer
128  *\param[in]    data_len -data length
129  *
130  */
131 static ESESTATUS phNxpEseProto7816_SaveIframeData(uint8_t* p_data,
132                                                   uint32_t data_len);
133 
134 /**
135  * \ingroup ISO7816-3_protocol_lib
136  * \brief      This internal function is called to do reset the recovery
137  *parameters
138  *
139  */
140 static ESESTATUS phNxpEseProto7816_ResetRecovery(void);
141 
142 /**
143  * \ingroup ISO7816-3_protocol_lib
144  * \brief       This internal function is called when 7816-3 stack failed to
145  *recover after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has
146  *to be recovered
147  *
148  */
149 static ESESTATUS phNxpEseProto7816_RecoverySteps(void);
150 
151 /**
152  * \ingroup ISO7816-3_protocol_lib
153  * \brief        This internal function is used to
154  *                  1. Identify the received frame
155  *                  2. If the received frame is I-frame with expected sequence
156  number, store it or else send R-NACK
157                     3. If the received frame is R-frame,
158                        3.1 R-ACK with expected seq. number: Send the next
159  chained I-frame
160                        3.2 R-ACK with different sequence number: Send the R-Nack
161                        3.3 R-NACK: Re-send the last frame
162                     4. If the received frame is S-frame, send back the correct
163  S-frame response.
164  *\param[in]    p_data -address of data.
165  *\param[in]    data_len -length of the frame
166  *
167  */
168 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
169                                                uint32_t data_len);
170 
171 /**
172  * \ingroup ISO7816-3_protocol_lib
173  * \brief      This internal function is used to
174  *                  1. Check the LRC
175  *                  2. Initiate decoding of received frame of data.
176  *
177  */
178 static ESESTATUS phNxpEseProto7816_ProcessResponse(void);
179 
180 /**
181  * \ingroup ISO7816-3_protocol_lib
182  * \brief      This internal function is used to
183  *                  1. Send the raw data received from application after
184  *computing LRC
185  *                  2. Receive the response data from ESE, decode, process
186  *and
187  *                     store the data.
188  *
189  */
190 static ESESTATUS TransceiveProcess(void);
191 
192 /**
193  * \ingroup ISO7816-3_protocol_lib
194  * \brief       This function is used to send the spi hard reset command
195  *
196  */
197 static ESESTATUS phNxpEseProto7816_HardReset(void);
198 
199 /**
200  * \ingroup ISO7816-3_protocol_lib
201  * \brief      This internal function is to decode the secure timer.
202  *                  value from the payload
203  *\param[in]     frameOffset -To get the L of TLV
204  *\param[in]     secureTimer -V of TLV: Retrieve each byte(4 byte) and push it
205  *to get the secure timer value (unsigned long) \param[in]    p_data -pointer to
206  *data.
207  *
208  */
209 static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset,
210                                                 unsigned int* secureTimer,
211                                                 uint8_t* p_data);
212 
213 /**
214  * \ingroup ISO7816-3_protocol_lib
215  * \brief       This internal function is to decode S-frame payload.
216  *\param[in]    p_data -Raw Data IFS.
217  *
218  */
219 static void phNxpEseProto7816_DecodeSFrameIFSData(uint8_t* p_data);
220 
221 /**
222  * \ingroup ISO7816-3_protocol_lib
223  * \brief       This internal function is to decode S-frame (ATR) payload.
224  *\param[in]    p_data -ATR TLV.
225  *
226  */
227 static void phNxpEseProto7816_DecodeSFrameATRData(uint8_t* p_data);
228 
229 /**
230  * \ingroup ISO7816-3_protocol_lib
231  * \brief       This internal function is to decode S-frame (secure timer TLV)
232  *payload. \param[in]    p_data -raw data - secure timer  TLV.
233  *
234  */
235 static void phNxpEseProto7816_DecodeSFrameSecureTimerData(uint8_t* p_data);
236 
237 /**
238  * \ingroup ISO7816-3_protocol_lib
239  * \brief       This internal function is to notify either WTX_ONGOING ot
240  *WTX_END \param[in]    state - Either WTX_ONGOING/WTX_END
241  *
242  */
243 static void phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state);
244 
245 /**
246  * \ingroup ISO7816-3_protocol_lib
247  * \brief       This internal function to check Last sent frame is S-Frame
248  *              request and if received block is not S-Frame response
249  *              re-send Last S-frame request
250  */
251 static bool phNxpEseProto7816_ResendLastSFrameReq(void);
252 /*!
253  * \brief 7816_3 protocol stack parameter variable instance
254  */
255 static phNxpEseProto7816_t phNxpEseProto7816_3_Var;
256 
257 /*!
258  * \brief 7816_3 protocol stack instance - pointer variable
259  */
260 static phNxpEseProto7816_t phNxpEseProto7816_ptr[MAX_END_POINTS];
261 
262 /*!
263  * \brief  Prints  time taken(in microseconds) in cmd transfer and response
264  *         receive
265  */
266 static void printCmdRspTimeDuration(ESESTATUS status, uint32_t cmdLen,
267                                     uint32_t respLen);
268 
269 /******************************************************************************
270  * Function         phNxpEseProto7816_SendRawFrame
271  *
272  * Description      This internal function is called send the data to ESE
273  *
274  * Returns          On success return true or else false.
275  *
276  ******************************************************************************/
phNxpEseProto7816_SendRawFrame(uint32_t data_len,uint8_t * p_data)277 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
278                                                 uint8_t* p_data) {
279   ESESTATUS status = ESESTATUS_FAILED;
280   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
281   status = phNxpEse_WriteFrame(data_len, p_data);
282   if (ESESTATUS_SUCCESS != status) {
283     NXP_LOG_ESE_E("%s Error phNxpEse_WriteFrame\n", __FUNCTION__);
284   } else {
285     NXP_LOG_ESE_D("%s phNxpEse_WriteFrame Success \n", __FUNCTION__);
286   }
287   NXP_LOG_ESE_D("Exit %s with status %d", __FUNCTION__, status);
288   return status;
289 }
290 
291 /******************************************************************************
292  * Function         phNxpEseProto7816_GetRawFrame
293  *
294  * Description      This internal function is called read the data from the ESE
295  *
296  * Returns          On success return true or else false.
297  *
298  ******************************************************************************/
phNxpEseProto7816_GetRawFrame(uint32_t * data_len,uint8_t ** pp_data)299 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
300                                                uint8_t** pp_data) {
301   ESESTATUS status = ESESTATUS_FAILED;
302 
303   status = phNxpEse_read(data_len, pp_data);
304   if (ESESTATUS_SUCCESS != status) {
305     NXP_LOG_ESE_E("%s phNxpEse_read failed , status : 0x%x", __FUNCTION__,
306                   status);
307   }
308   return status;
309 }
310 
311 /******************************************************************************
312  * Function         phNxpEseProto7816_ComputeLRC
313  *
314  * Description      This internal function is called compute the LRC
315  *
316  * Returns          On success return true or else false.
317  *
318  ******************************************************************************/
phNxpEseProto7816_ComputeLRC(unsigned char * p_buff,uint32_t offset,uint32_t length)319 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
320                                             uint32_t offset, uint32_t length) {
321   uint32_t LRC = 0, i = 0;
322   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
323   for (i = offset; i < length; i++) {
324     LRC = LRC ^ p_buff[i];
325   }
326   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
327   return (uint8_t)LRC;
328 }
329 
330 /******************************************************************************
331  * Function         phNxpEseProto7816_CheckLRC
332  *
333  * Description      This internal function is called compute and compare the
334  *                  received LRC of the received data
335  *
336  * Returns          On success return true or else false.
337  *
338  ******************************************************************************/
phNxpEseProto7816_CheckLRC(uint32_t data_len,uint8_t * p_data)339 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len,
340                                             uint8_t* p_data) {
341   ESESTATUS status = ESESTATUS_SUCCESS;
342   uint8_t calc_crc = 0;
343   uint8_t recv_crc = 0;
344   NXP_LOG_ESE_D("Enter %s len %d", __FUNCTION__, data_len);
345   if (data_len > 0) {
346     recv_crc = p_data[data_len - 1];
347 
348     /* calculate the CRC after excluding CRC  */
349     calc_crc = phNxpEseProto7816_ComputeLRC(p_data, 1, (data_len - 1));
350     NXP_LOG_ESE_D("Received LRC:0x%x Calculated LRC:0x%x", recv_crc, calc_crc);
351     if (recv_crc != calc_crc) {
352       status = ESESTATUS_FAILED;
353       NXP_LOG_ESE_E("%s LRC failed", __FUNCTION__);
354     }
355   } else {
356     status = ESESTATUS_FAILED;
357     NXP_LOG_ESE_E("%s LRC failed length = 0", __FUNCTION__);
358   }
359   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
360   return status;
361 }
362 
363 /******************************************************************************
364  * Function         phNxpEseProto7816_SendSFrame
365  *
366  * Description      This internal function is called to send S-frame with all
367  *                   updated 7816-3 headers
368  *
369  * Returns          On success return true or else false.
370  *
371  ******************************************************************************/
phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData)372 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData) {
373   ESESTATUS status = ESESTATUS_FAILED;
374   uint32_t frame_len = 0;
375   uint8_t* p_framebuff = NULL;
376   uint8_t pcb_byte = 0;
377   uint8_t lenIFS = 0;
378   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
379   sFrameInfo_t sframeData = sFrameData;
380   /* This update is helpful in-case a R-NACK is transmitted from the MW */
381   phNxpEseProto7816_3_Var.lastSentNonErrorframeType = SFRAME;
382   switch (sframeData.sFrameType) {
383     case RESYNCH_REQ:
384       frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
385       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
386       if (NULL == p_framebuff) {
387         return ESESTATUS_FAILED;
388       }
389       p_framebuff[2] = 0;
390       p_framebuff[3] = 0x00;
391 
392       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
393       pcb_byte |= PH_PROTO_7816_S_RESYNCH;
394       break;
395     case IFS_REQ:
396       frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
397       lenIFS = 0;
398       if (IFSC_SIZE_SEND < phNxpEseProto7816_3_Var.currentIFSDSize) {
399         frame_len += 2;
400         lenIFS = 2;
401       } else {
402         frame_len += 1;
403         lenIFS = 1;
404       }
405 
406       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
407       if (NULL == p_framebuff) {
408         return ESESTATUS_FAILED;
409       }
410       p_framebuff[2] = lenIFS;
411       if (2 == lenIFS) {
412         p_framebuff[3] = (phNxpEseProto7816_3_Var.currentIFSDSize >> 8);
413         p_framebuff[4] =
414             (phNxpEseProto7816_3_Var.currentIFSDSize & EXTENDED_FRAME_MARKER);
415       } else {
416         p_framebuff[3] = phNxpEseProto7816_3_Var.currentIFSDSize;
417       }
418 
419       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
420       pcb_byte |= IFS_REQ;
421       break;
422     case INTF_RESET_REQ:
423       frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
424       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
425       if (NULL == p_framebuff) {
426         return ESESTATUS_FAILED;
427       }
428       p_framebuff[2] = 0;
429       p_framebuff[3] = 0x00;
430 
431       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
432       pcb_byte |= PH_PROTO_7816_S_RESET;
433       break;
434     case PROP_END_APDU_REQ:
435       frame_len =
436           (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN + sframeData.len);
437       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
438       if (NULL == p_framebuff) {
439         return ESESTATUS_FAILED;
440       }
441       p_framebuff[2] = sframeData.len;
442       if (!sframeData.len)
443         p_framebuff[3] = PH_PROTO_7816_VALUE_ZERO;
444       else
445         phNxpEse_memcpy(&(p_framebuff[3]), sframeData.p_data, sframeData.len);
446       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
447       pcb_byte |= PH_PROTO_7816_S_END_OF_APDU;
448       break;
449     case HARD_RESET_REQ:
450       frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
451       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
452       if (NULL == p_framebuff) {
453         return ESESTATUS_FAILED;
454       }
455       p_framebuff[2] = 0;
456       p_framebuff[3] = 0x00;
457 
458       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
459       pcb_byte |= PH_PROTO_7816_S_HRD_RST_CMD;
460       break;
461     case WTX_RSP:
462       frame_len = (PH_PROTO_7816_HEADER_LEN + 1 + PH_PROTO_7816_CRC_LEN);
463       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
464       if (NULL == p_framebuff) {
465         return ESESTATUS_FAILED;
466       }
467       p_framebuff[2] = 0x01;
468       p_framebuff[3] = 0x01;
469 
470       pcb_byte |= PH_PROTO_7816_S_BLOCK_RSP;
471       pcb_byte |= PH_PROTO_7816_S_WTX;
472       break;
473     case ATR_REQ:
474       frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
475       p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
476       if (NULL == p_framebuff) {
477         return ESESTATUS_FAILED;
478       }
479       p_framebuff[2] = 0;
480       p_framebuff[3] = 0x00;
481 
482       pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
483       pcb_byte |= ATR_REQ;
484       break;
485     default:
486       NXP_LOG_ESE_E("Invalid S-block");
487       break;
488   }
489   if (NULL != p_framebuff) {
490     /* frame the packet */
491     p_framebuff[0] = 0x00;     /* NAD Byte */
492     p_framebuff[1] = pcb_byte; /* PCB */
493 
494     p_framebuff[frame_len - 1] =
495         phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
496     NXP_LOG_ESE_D("S-Frame PCB: %x\n", p_framebuff[1]);
497     status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
498     phNxpEse_free(p_framebuff);
499     /*After S-Frame Tx 1 ms sleep before Rx*/
500     if ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) &&
501         (sframeData.sFrameType != PROP_END_APDU_REQ)) {
502       phNxpEse_Sleep(1 * 1000);
503     }
504   } else {
505     NXP_LOG_ESE_E("Invalid S-block or malloc for s-block failed");
506   }
507   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
508   return status;
509 }
510 
511 /******************************************************************************
512  * Function         phNxpEseProto7816_sendRframe
513  *
514  * Description      This internal function is called to send R-frame with all
515  *                   updated 7816-3 headers
516  *
517  * Returns          On success return true or else false.
518  *
519  ******************************************************************************/
phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType)520 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType) {
521   ESESTATUS status = ESESTATUS_FAILED;
522   uint8_t recv_ack[4] = {0x00, 0x80, 0x00, 0x00};
523   if (RNACK == rFrameType) /* R-NACK */
524   {
525     recv_ack[1] = 0x82;
526   } else /* R-ACK*/
527   {
528     /* This update is helpful in-case a R-NACK is transmitted from the MW */
529     phNxpEseProto7816_3_Var.lastSentNonErrorframeType = RFRAME;
530   }
531   recv_ack[1] |=
532       ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo ^ 1)
533        << 4);
534   NXP_LOG_ESE_D("%s recv_ack[1]:0x%x", __FUNCTION__, recv_ack[1]);
535   recv_ack[3] =
536       phNxpEseProto7816_ComputeLRC(recv_ack, 0x00, (sizeof(recv_ack) - 1));
537   status = phNxpEseProto7816_SendRawFrame(sizeof(recv_ack), recv_ack);
538   return status;
539 }
540 
541 /******************************************************************************
542  * Function         phNxpEseProto7816_SendIframe
543  *
544  * Description      This internal function is called to send I-frame with all
545  *                   updated 7816-3 headers
546  *
547  * Returns          On success return true or else false.
548  *
549  ******************************************************************************/
phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData)550 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData) {
551   ESESTATUS status = ESESTATUS_FAILED;
552   uint32_t frame_len = 0;
553   uint8_t* p_framebuff = NULL;
554   uint8_t pcb_byte = 0;
555   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
556   if (0 == iFrameData.sendDataLen) {
557     NXP_LOG_ESE_E("I frame Len is 0, INVALID");
558     return ESESTATUS_FAILED;
559   }
560   /* This update is helpful in-case a R-NACK is transmitted from the MW */
561   phNxpEseProto7816_3_Var.lastSentNonErrorframeType = IFRAME;
562   frame_len = (iFrameData.sendDataLen + PH_PROTO_7816_HEADER_LEN +
563                PH_PROTO_7816_CRC_LEN + 2);
564 
565   p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
566   if (NULL == p_framebuff) {
567     NXP_LOG_ESE_E("Heap allocation failed");
568     return ESESTATUS_FAILED;
569   }
570 
571   /* frame the packet */
572   p_framebuff[0] = 0x00; /* NAD Byte */
573 
574   if (iFrameData.isChained) {
575     /* make B6 (M) bit high */
576     pcb_byte |= PH_PROTO_7816_CHAINING;
577   }
578 
579   /* Update the send seq no */
580   pcb_byte |=
581       (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo << 6);
582 
583   /* store the pcb byte */
584   p_framebuff[1] = pcb_byte;
585   if (iFrameData.sendDataLen >
586       IFSC_SIZE_SEND) { /* Case for frame size > 254 bytes */
587     p_framebuff[2] = EXTENDED_FRAME_MARKER;
588     uint8_t mask = (iFrameData.sendDataLen) & EXTENDED_FRAME_MARKER;
589     p_framebuff[4] = mask;
590     mask = ((iFrameData.sendDataLen) >> 8) & EXTENDED_FRAME_MARKER;
591     p_framebuff[3] = mask;
592     /* store I frame */
593     phNxpEse_memcpy(&(p_framebuff[5]),
594                     iFrameData.p_data + iFrameData.dataOffset,
595                     iFrameData.sendDataLen);
596   } else { /* Case for frame size < 254 bytes */
597     /* store I frame length */
598     p_framebuff[2] = iFrameData.sendDataLen;
599     frame_len = frame_len - 2;
600     /* store I frame */
601     phNxpEse_memcpy(&(p_framebuff[3]),
602                     iFrameData.p_data + iFrameData.dataOffset,
603                     iFrameData.sendDataLen);
604   }
605 
606   p_framebuff[frame_len - 1] =
607       phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
608 
609   status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
610   if (iFrameData.isChained == false) {
611     NXP_LOG_ESE_I("All Iframes are sent");
612     phPalEse_stopTimer(phPalEse_getTimer()->tx_timer);
613 
614     phPalEse_startTimer(phPalEse_getTimer()->rx_timer);
615   }
616   phNxpEse_free(p_framebuff);
617   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
618   return status;
619 }
620 
621 /******************************************************************************
622  * Function         phNxpEseProto7816_SetNextIframeContxt
623  *
624  * Description      This internal function is called to set the context for next
625  *I-frame.
626  *                  Not applicable for the first I-frame of the transceive
627  *
628  * Returns          On success return true or else false.
629  *
630  ******************************************************************************/
phNxpEseProto7816_SetFirstIframeContxt(void)631 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void) {
632   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
633   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset = 0;
634   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
635   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
636       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
637   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
638   if (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen >
639       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
640           .currentDataLenIFS) {
641     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
642     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
643         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
644             .currentDataLenIFS;
645     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
646         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen -
647         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
648             .currentDataLenIFS;
649   } else {
650     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
651         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen;
652     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
653   }
654   NXP_LOG_ESE_D(
655       "I-Frame Data Len: %d Seq. no:%d",
656       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen,
657       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo);
658   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
659   return ESESTATUS_SUCCESS;
660 }
661 
662 /******************************************************************************
663  * Function         phNxpEseProto7816_SetNextIframeContxt
664  *
665  * Description      This internal function is called to set the context for next
666  *I-frame.
667  *                  Not applicable for the first I-frame of the transceive
668  *
669  * Returns          On success return true or else false.
670  *
671  ******************************************************************************/
phNxpEseProto7816_SetNextIframeContxt(void)672 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void) {
673   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
674   /* Expecting to reach here only after first of chained I-frame is sent and
675    * before the last chained is sent */
676   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
677   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
678 
679   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
680       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
681   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset =
682       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.dataOffset +
683       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS;
684   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data =
685       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data;
686   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
687       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS;
688 
689   // if  chained
690   if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen >
691       phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
692           .currentDataLenIFS) {
693     NXP_LOG_ESE_D("Process Chained Frame");
694     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
695     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
696         phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
697             .currentDataLenIFS;
698     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
699         phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen -
700         phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
701             .currentDataLenIFS;
702   } else {
703     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
704     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
705         phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen;
706   }
707   NXP_LOG_ESE_D(
708       "I-Frame Data Len: %d",
709       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen);
710   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
711   return ESESTATUS_SUCCESS;
712 }
713 
714 /******************************************************************************
715  * Function         phNxpEseProto7816_ResetRecovery
716  *
717  * Description      This internal function is called to do reset the recovery
718  *                  parameters
719  *
720  * Returns          On success return true or else false.
721  *
722  ******************************************************************************/
phNxpEseProto7816_SaveIframeData(uint8_t * p_data,uint32_t data_len)723 static ESESTATUS phNxpEseProto7816_SaveIframeData(uint8_t* p_data,
724                                                   uint32_t data_len) {
725   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
726   NXP_LOG_ESE_D("Data[0]=0x%x len=%d Data[%d]=0x%x", p_data[0], data_len,
727                 data_len - 1, p_data[data_len - 1]);
728   ESESTATUS status = phNxpEse_StoreDatainList(data_len, p_data);
729   if (ESESTATUS_SUCCESS != status) {
730     NXP_LOG_ESE_E("%s - Error storing chained data in list, status %d",
731                   __FUNCTION__, status);
732   }
733   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
734   return status;
735 }
736 
737 /******************************************************************************
738  * Function         phNxpEseProto7816_ResetRecovery
739  *
740  * Description      This internal function is called to do reset the recovery
741  *                  parameters
742  *
743  * Returns          On success return true or else false.
744  *
745  ******************************************************************************/
phNxpEseProto7816_ResetRecovery(void)746 static ESESTATUS phNxpEseProto7816_ResetRecovery(void) {
747   phNxpEseProto7816_3_Var.recoveryCounter = 0;
748   return ESESTATUS_SUCCESS;
749 }
750 
751 /******************************************************************************
752  * Function         phNxpEseProto7816_RecoverySteps
753  *
754  * Description      This internal function is called when 7816-3 stack failed to
755  *recover
756  *                  after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has
757  *to be
758  *                  recovered
759  * Returns          On success return true or else false.
760  *
761  ******************************************************************************/
phNxpEseProto7816_RecoverySteps(void)762 static ESESTATUS phNxpEseProto7816_RecoverySteps(void) {
763   if (phNxpEseProto7816_3_Var.recoveryCounter <= GET_FRAME_RETRY_COUNT()) {
764     phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
765         INTF_RESET_REQ;
766     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
767     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
768         INTF_RESET_REQ;
769     phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
770         SEND_S_INTF_RST;
771     phNxpEseProto7816_3_Var.reset_type = RESET_TYPE_RECOVERY;
772   } else { /* If recovery fails */
773     phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
774     NXP_LOG_ESE_E("%s Recovery failed", __FUNCTION__);
775   }
776   return ESESTATUS_SUCCESS;
777 }
778 
779 /******************************************************************************
780  * Function         phNxpEseProto7816_DecodeSecureTimer
781  *
782  * Description      This internal function is to decode the secure timer.
783  *                  value from the payload
784  * Returns          void
785  *
786  ******************************************************************************/
phNxpEseProto7816_DecodeSecureTimer(uint8_t * frameOffset,unsigned int * secureTimer,uint8_t * p_data)787 static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset,
788                                                 unsigned int* secureTimer,
789                                                 uint8_t* p_data) {
790   uint8_t byteCounter = 0;
791   uint8_t dataLength = p_data[++(*frameOffset)]; /* To get the L of TLV */
792   if (dataLength > 0) {
793     /* V of TLV: Retrieve each byte(4 byte) and push it to get the secure timer
794      * value (unsigned long) */
795     for (byteCounter = 1; byteCounter <= dataLength; byteCounter++) {
796       (*frameOffset)++;
797       *secureTimer = (*secureTimer) << 8;
798       *secureTimer |= p_data[(*frameOffset)];
799     }
800   } else {
801     (*frameOffset)++; /* Goto the end of current marker if length is zero */
802   }
803   return;
804 }
805 
806 /******************************************************************************
807  * Function         phNxpEseProto7816_DecodeSFrameIFSData
808  *
809  * Description      This internal function is to decode S-frame payload.
810  * Returns          void
811  *
812  ******************************************************************************/
phNxpEseProto7816_DecodeSFrameIFSData(uint8_t * p_data)813 static void phNxpEseProto7816_DecodeSFrameIFSData(uint8_t* p_data) {
814   uint16_t ifsd_data = 0;
815   if (p_data[2] == 1) {
816     ifsd_data = p_data[3];
817   } else if (p_data[2] == 2) {
818     ifsd_data = p_data[3];
819     ifsd_data <<= 8;
820     ifsd_data |= p_data[4];
821   }
822   if (ifsd_data == phNxpEseProto7816_3_Var.currentIFSDSize) {
823     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
824         phNxpEseProto7816_3_Var.currentIFSDSize;
825     NXP_LOG_ESE_D("%s IFS adjustment: Max DataLen=%d \n", __FUNCTION__,
826                   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
827                       .currentDataLenIFS);
828   } else {
829     NXP_LOG_ESE_E("%s ERROR IFS adjustment: Max DataLen=%d \n", __FUNCTION__,
830                   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
831                       .currentDataLenIFS);
832   }
833 }
834 
835 /******************************************************************************
836  * Function         phNxpEseProto7816_DecodeSFrameATRData
837  *
838  * Description      This internal function is to decode S-frame payload.
839  * Returns          void
840  *
841  ******************************************************************************/
phNxpEseProto7816_DecodeSFrameATRData(uint8_t * p_data)842 static void phNxpEseProto7816_DecodeSFrameATRData(uint8_t* p_data) {
843   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC = 0;
844   /* Default IFSC size */
845   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.defaultDataLenIFSC =
846       p_data[16];
847   // phNxpEse_memcpy(phNxpEseProto7816_3_Var.pAtrData, &p_data[3], p_data[2]);
848   /* Max IFSC size */
849   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
850       (p_data[18] << 8);
851   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC |=
852       (p_data[19]);
853   if (!p_data[2])
854     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
855         IFSC_SIZE_SEND;
856 
857   phNxpEse_memcpy(&phNxpEseProto7816_3_Var.atrInfo.len,
858                   &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET],
859                   sizeof(phNxpEseProto7816_ATR_Info_t));
860 
861   NXP_LOG_ESE_D(
862       "%s Max DataLen=%d Current DataLen=%d Default DataLen=%d \n",
863       __FUNCTION__,
864       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC,
865       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS,
866       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
867           .defaultDataLenIFSC);
868   NXP_LOG_ESE_D("ATR Data Follows");
869   NXP_LOG_ESE_D("======================");
870   NXP_LOG_ESE_D("ATR Length = %d", phNxpEseProto7816_3_Var.atrInfo.len);
871   NXP_LOG_ESE_D("Vendor ID = 0x%.2x%.2x%.2x%.2x%.2x",
872                 phNxpEseProto7816_3_Var.atrInfo.vendorID[0],
873                 phNxpEseProto7816_3_Var.atrInfo.vendorID[1],
874                 phNxpEseProto7816_3_Var.atrInfo.vendorID[2],
875                 phNxpEseProto7816_3_Var.atrInfo.vendorID[3],
876                 phNxpEseProto7816_3_Var.atrInfo.vendorID[4]);
877   NXP_LOG_ESE_D("DLL-IC = supports T%d",
878                 phNxpEseProto7816_3_Var.atrInfo.dll_IC);
879   NXP_LOG_ESE_D("BGT = %d ms", (phNxpEseProto7816_3_Var.atrInfo.bgt[0] << 8) |
880                                    (phNxpEseProto7816_3_Var.atrInfo.bgt[1]));
881   NXP_LOG_ESE_D("BWT = %d ms", phNxpEseProto7816_3_Var.atrInfo.bwt[0] << 8 |
882                                    phNxpEseProto7816_3_Var.atrInfo.bwt[1]);
883   NXP_LOG_ESE_D("Max supported frequency = %d KHz",
884                 phNxpEseProto7816_3_Var.atrInfo.maxFreq[0] << 8 |
885                     phNxpEseProto7816_3_Var.atrInfo.maxFreq[1]);
886   NXP_LOG_ESE_D("Checksum LRC(0)/CRC(1) supports = 0x%x",
887                 phNxpEseProto7816_3_Var.atrInfo.checksum);
888   NXP_LOG_ESE_D("DefaultIFSC = %d bytes",
889                 phNxpEseProto7816_3_Var.atrInfo.defaultIFSC);
890   NXP_LOG_ESE_D("Number of logical connections supported = %d",
891                 phNxpEseProto7816_3_Var.atrInfo.numChannels);
892   NXP_LOG_ESE_D("Max IFSC = %d bytes",
893                 phNxpEseProto7816_3_Var.atrInfo.maxIFSC[0] << 8 |
894                     phNxpEseProto7816_3_Var.atrInfo.maxIFSC[1]);
895   NXP_LOG_ESE_D("Capabilities = 0x%x",
896                 phNxpEseProto7816_3_Var.atrInfo.capabilities[0] << 8 |
897                     phNxpEseProto7816_3_Var.atrInfo.capabilities[1]);
898 
899   if (phNxpEseProto7816_3_Var.atrInfo.vendorID[4] >= PH_SE_OS_VERSION_11) {
900     phNxpEse_memcpy(&phNxpEseProto7816_3_Var.extndAtrInfo.channelNo,
901                     &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] +
902                         sizeof(phNxpEseProto7816_ATR_Info_t),
903                     sizeof(phNxpEseProto7816_ATR_Info2_t));
904     NXP_LOG_ESE_D("Channel Number = 0x%x",
905                   phNxpEseProto7816_3_Var.extndAtrInfo.channelNo);
906     NXP_LOG_ESE_D(
907         "OS Type = %s",
908         (phNxpEseProto7816_3_Var.extndAtrInfo.osType == 0x01 ? "JCOP Mode"
909                                                              : "OSU Mode"));
910   }
911   if (phNxpEseProto7816_3_Var.atrInfo.vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN -
912                                                1] >= PH_SE_OS_VERSION_30) {
913     phNxpEse_setOsVersion(OS_VERSION_8_9);
914   } else if (phNxpEseProto7816_3_Var.atrInfo
915                  .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] >=
916              PH_SE_OS_VERSION_21) {
917     phNxpEse_setOsVersion(OS_VERSION_6_3);
918   } else if (phNxpEseProto7816_3_Var.atrInfo
919                  .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] >=
920              PH_SE_OS_VERSION_20) {
921     phNxpEse_setOsVersion(OS_VERSION_6_2);
922   } else if (phNxpEseProto7816_3_Var.atrInfo
923                  .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] >=
924              PH_SE_OS_VERSION_11) {
925     phNxpEse_setOsVersion(OS_VERSION_5_2_2);
926   } else if (phNxpEseProto7816_3_Var.atrInfo
927                  .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] ==
928              PH_SE_OS_VERSION_10) {
929     phNxpEse_setOsVersion(OS_VERSION_5_2);
930   } else if (phNxpEseProto7816_3_Var.atrInfo
931                  .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] ==
932              PH_PROTO_7816_VALUE_ZERO) {
933     phNxpEse_setOsVersion(OS_VERSION_5_1);
934   }
935 
936   NXP_LOG_ESE_D("======================");
937 }
938 
939 /******************************************************************************
940  * Function         phNxpEseProto7816_DecodeSFrameData
941  *
942  * Description      This internal function is to decode S-frame payload.
943  * Returns          void
944  *
945  ******************************************************************************/
phNxpEseProto7816_DecodeSFrameSecureTimerData(uint8_t * p_data)946 static void phNxpEseProto7816_DecodeSFrameSecureTimerData(uint8_t* p_data) {
947   uint8_t maxSframeLen = 0, dataType = 0, frameOffset = 0;
948   frameOffset = PH_PROPTO_7816_FRAME_LENGTH_OFFSET;
949   maxSframeLen =
950       p_data[frameOffset] +
951       frameOffset; /* to be in sync with offset which starts from index 0 */
952 
953   /* Secure Timer specific parser */
954   while (maxSframeLen > frameOffset) {
955     frameOffset += 1; /* To get the Type (TLV) */
956     dataType = p_data[frameOffset];
957     NXP_LOG_ESE_D("%s frameoffset=%d value=0x%x\n", __FUNCTION__, frameOffset,
958                   p_data[frameOffset]);
959     switch (dataType) /* Type (TLV) */
960     {
961       case PH_PROPTO_7816_SFRAME_TIMER1:
962         phNxpEseProto7816_DecodeSecureTimer(
963             &frameOffset,
964             &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1, p_data);
965         break;
966       case PH_PROPTO_7816_SFRAME_TIMER2:
967         phNxpEseProto7816_DecodeSecureTimer(
968             &frameOffset,
969             &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2, p_data);
970         break;
971       case PH_PROPTO_7816_SFRAME_TIMER3:
972         phNxpEseProto7816_DecodeSecureTimer(
973             &frameOffset,
974             &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3, p_data);
975         break;
976       default:
977         frameOffset +=
978             p_data[frameOffset + 1]; /* Goto the end of current marker */
979         break;
980     }
981   }
982   NXP_LOG_ESE_D("secure timer t1 = 0x%x t2 = 0x%x t3 = 0x%x",
983                 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1,
984                 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2,
985                 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3);
986   return;
987 }
988 
989 /******************************************************************************
990  * Function         phNxpEseProto7816_SetTxstate
991  *
992  * Description      This internal function is used to set the Tranceive state
993  *                  of T=1 Proto stack. Accordingly, it will set the params
994  *                  for next transceive.
995  * Returns          void.
996  *
997  ******************************************************************************/
phNxpEseProto7816_SetTxstate(phNxpEseProto7816_TransceiveStates_t state)998 static void phNxpEseProto7816_SetTxstate(
999     phNxpEseProto7816_TransceiveStates_t state) {
1000   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1001   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = state;
1002   switch (state) {
1003     case SEND_S_IFS_ADJ:
1004       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1005           IFS_REQ;
1006       break;
1007     case SEND_S_ATR_REQ:
1008       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1009           ATR_REQ;
1010       break;
1011     default:
1012       NXP_LOG_ESE_E("%s: Wrong transceive state received ", __FUNCTION__);
1013       break;
1014   }
1015 }
1016 /******************************************************************************
1017  * Function         phNxpEseProto7816_DecodeAtrRsp
1018  *
1019  * Description      The function phNxpEseProto7816_DecodeFrame() shall call
1020  *                  this function up on receiving the ATR RSP
1021  *                  1. If Last sent frame is S-Frame then send back the correct
1022  *                    S-frame response.
1023  *                  2. If Last sent frame is I-Frame then trigger the recovery
1024  *                    RESET_TYPE_OS_RESET.
1025  * Returns          On success returns ESESTATUS_SUCCESS else ESESTATUS_FAILED.
1026  *
1027  ******************************************************************************/
phNxpEseProto7816_DecodeAtrRsp(uint8_t * p_data)1028 static ESESTATUS phNxpEseProto7816_DecodeAtrRsp(uint8_t* p_data) {
1029   ESESTATUS status = ESESTATUS_SUCCESS;
1030   // This is 4ms delay and delay of 1ms in also there in line 1401 before
1031   // next Tx
1032   phNxpEse_Sleep(HARD_RESET_RES_DELAY);
1033   if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == IFRAME) {
1034     // Applicable only for SN300
1035     phNxpEseProto7816_SetTxstate(SEND_S_ATR_REQ);
1036     phNxpEseProto7816_3_Var.reset_type = RESET_TYPE_OS_RESET;
1037   } else {
1038     if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1039       /*Response status either success/fail*/
1040       if (!p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1])
1041         status = ESESTATUS_FAILED;
1042       else
1043         status = ESESTATUS_SUCCESS;
1044     }
1045     phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1046     phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
1047   }
1048   phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1049       HARD_RESET_RSP;
1050   return status;
1051 }
1052 /******************************************************************************
1053  * Function         phNxpEseProto7816_DecodeFrame
1054  *
1055  * Description      This internal function is used to
1056  *                  1. Identify the received frame
1057  *                  2. If the received frame is I-frame with expected sequence
1058  *                     number, store it or else send R-NACK
1059  *                  3. If the received frame is R-frame,
1060  *                     3.1 R-ACK with expected seq. number: Send the next
1061  *                     chained I-frame
1062  *                     3.2 R-ACK with different sequence number: Send the R-Nack
1063  *                     3.3 R-NACK: Re-send the last frame
1064  *                   4. If the received frame is S-frame,
1065  *                     4.1 Last sent frame is S-Frame then send back the
1066  *                         correct S-frame response.
1067  *                     4.2 Last sent frame is I-Frame then trigger the recovery
1068  *                         RESET_TYPE_OS_RESET.
1069  * Returns          On success returns true else false.
1070  *
1071  ******************************************************************************/
phNxpEseProto7816_DecodeFrame(uint8_t * p_data,uint32_t data_len)1072 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
1073                                                uint32_t data_len) {
1074   ESESTATUS status = ESESTATUS_SUCCESS;
1075   uint8_t pcb;
1076   phNxpEseProto7816_PCB_bits_t pcb_bits;
1077   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
1078   NXP_LOG_ESE_D("Retry Counter = %d\n",
1079                 phNxpEseProto7816_3_Var.recoveryCounter);
1080   pcb = p_data[PH_PROPTO_7816_PCB_OFFSET];
1081   // memset(&phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.rcvPcbBits, 0x00,
1082   // sizeof(struct PCB_BITS));
1083   phNxpEse_memset(&pcb_bits, 0x00, sizeof(phNxpEseProto7816_PCB_bits_t));
1084   phNxpEse_memcpy(&pcb_bits, &pcb, sizeof(uint8_t));
1085 
1086   if (0x00 == pcb_bits.msb) /* I-FRAME decoded should come here */
1087   {
1088     if (!phNxpEseProto7816_ResendLastSFrameReq()) {
1089       NXP_LOG_ESE_D("%s I-Frame Received", __FUNCTION__);
1090       phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1091       phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = IFRAME;
1092       if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo !=
1093           pcb_bits.bit7)  //   != pcb_bits->bit7)
1094       {
1095         NXP_LOG_ESE_D("%s I-Frame lastRcvdIframeInfo.seqNo:0x%x", __FUNCTION__,
1096                       pcb_bits.bit7);
1097         phNxpEseProto7816_ResetRecovery();
1098         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo = 0x00;
1099         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo |=
1100             pcb_bits.bit7;
1101 
1102         if (pcb_bits.bit6) {
1103           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
1104               true;
1105           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1106           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1107               NO_ERROR;
1108           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1109               SEND_R_ACK;
1110           if (EXTENDED_FRAME_MARKER == p_data[2] &&
1111               (data_len > 6)) /* Checking for extended frame prologue */
1112           {
1113             status = phNxpEseProto7816_SaveIframeData(&p_data[5], data_len - 6);
1114           } else if (data_len > 4) {
1115             status = phNxpEseProto7816_SaveIframeData(&p_data[3], data_len - 4);
1116           } else {
1117             phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1118                 SEND_R_NACK;
1119             NXP_LOG_ESE_I("%s Invalid IframeData", __FUNCTION__);
1120           }
1121         } else {
1122           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
1123               false;
1124           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1125               IDLE_STATE;
1126           if (EXTENDED_FRAME_MARKER == p_data[2] &&
1127               (data_len > 6)) /* Checking for extended frame prologue */
1128           {
1129             status = phNxpEseProto7816_SaveIframeData(&p_data[5], data_len - 6);
1130           } else if (data_len > 4) {
1131             status = phNxpEseProto7816_SaveIframeData(&p_data[3], data_len - 4);
1132           } else {
1133             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1134             phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1135                 SEND_R_NACK;
1136             NXP_LOG_ESE_I("%s Invalid IframeData", __FUNCTION__);
1137           }
1138         }
1139       } else {
1140         phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1141         if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
1142           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1143           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1144               OTHER_ERROR;
1145           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1146               SEND_R_NACK;
1147           phNxpEseProto7816_3_Var.recoveryCounter++;
1148         } else {
1149           phNxpEseProto7816_RecoverySteps();
1150           phNxpEseProto7816_3_Var.recoveryCounter++;
1151         }
1152       }
1153     }
1154   } else if ((0x01 == pcb_bits.msb) &&
1155              (0x00 == pcb_bits.bit7)) /* R-FRAME decoded should come here */
1156   {
1157     NXP_LOG_ESE_D("%s R-Frame Received", __FUNCTION__);
1158     if (data_len == (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN)) {
1159       phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1160       phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = RFRAME;
1161       phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo =
1162           0;  // = 0;
1163       phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo |=
1164           pcb_bits.bit5;
1165 
1166       if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x00)) {
1167         if (!phNxpEseProto7816_ResendLastSFrameReq()) {
1168           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1169               NO_ERROR;
1170           phNxpEseProto7816_ResetRecovery();
1171           if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1172                   .seqNo !=
1173               phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) {
1174             status = phNxpEseProto7816_SetNextIframeContxt();
1175             phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1176                 SEND_IFRAME;
1177           } else {
1178             // error handling.
1179           }
1180         }
1181       } /* Error handling 1 : Parity error */
1182       else if (((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) ||
1183                /* Error handling 2: Other indicated error */
1184                ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) ||
1185                /* Error handling 3 : Frame Missing error */
1186                ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x01))) {
1187         phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1188         if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) {
1189           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1190               OTHER_ERROR;
1191         } else if ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) {
1192           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1193               PARITY_ERROR;
1194         } else {
1195           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1196               SOF_MISSED_ERROR;
1197         }
1198         if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
1199           if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == IFRAME) {
1200             /*Only for R-NACK other issue re sync*/
1201             if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) {
1202               if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1203                           .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
1204                                         .IframeInfo.seqNo &&
1205                   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
1206                           .isChained == false) {
1207                 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1208                     SEND_S_RSYNC;
1209                 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1210                 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo
1211                     .sFrameType = RESYNCH_REQ;
1212               } else {
1213                 /*If R-NACK with sequence no matching then also reissue frame*/
1214                 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1215                                 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1216                                 sizeof(phNxpEseProto7816_NextTx_Info_t));
1217                 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1218                     SEND_IFRAME;
1219                 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
1220               }
1221             } else {
1222               phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1223                               &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1224                               sizeof(phNxpEseProto7816_NextTx_Info_t));
1225               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1226                   SEND_IFRAME;
1227               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
1228             }
1229           } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
1230                      RFRAME) {
1231             /* Usecase to reach the below case:
1232             I-frame sent first, followed by R-NACK and we receive a R-NACK with
1233             last sent I-frame sequence number*/
1234             if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1235                      .seqNo == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
1236                                    .IframeInfo.seqNo) &&
1237                 (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == IFRAME)) {
1238               phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1239                               &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1240                               sizeof(phNxpEseProto7816_NextTx_Info_t));
1241               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1242                   SEND_IFRAME;
1243               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
1244             }
1245             /* Usecase to reach the below case:
1246             R-frame sent first, followed by R-NACK and we receive a R-NACK with
1247             next expected I-frame sequence number*/
1248             else if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1249                           .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
1250                                         .IframeInfo.seqNo) &&
1251                      (phNxpEseProto7816_3_Var.lastSentNonErrorframeType ==
1252                       RFRAME)) {
1253               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1254               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1255                   NO_ERROR;
1256               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1257                   SEND_R_ACK;
1258             }
1259             /* Usecase to reach the below case:
1260             I-frame sent first, followed by R-NACK and we receive a R-NACK with
1261             next expected I-frame sequence number + all the other unexpected
1262             scenarios */
1263             else {
1264               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1265               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1266                   OTHER_ERROR;
1267               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1268                   SEND_R_NACK;
1269             }
1270           } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
1271                      SFRAME) {
1272             /* Copy the last S frame sent */
1273             phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1274                             &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1275                             sizeof(phNxpEseProto7816_NextTx_Info_t));
1276           }
1277           phNxpEseProto7816_3_Var.recoveryCounter++;
1278         } else {
1279           phNxpEseProto7816_RecoverySteps();
1280           phNxpEseProto7816_3_Var.recoveryCounter++;
1281         }
1282         // resend previously send I frame
1283       } else /* Error handling 4 */
1284       {
1285         phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1286         if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
1287           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1288               UNDEFINED_ERROR;
1289           phNxpEseProto7816_3_Var.recoveryCounter++;
1290         } else {
1291           phNxpEseProto7816_RecoverySteps();
1292           phNxpEseProto7816_3_Var.recoveryCounter++;
1293         }
1294       }
1295     } else {
1296       NXP_LOG_ESE_E("%s Payload data is not expected in R-Frame, data_len %d",
1297                     __FUNCTION__, data_len);
1298       status = ESESTATUS_INVALID_RECEIVE_LENGTH;
1299     }
1300   } else if ((0x01 == pcb_bits.msb) &&
1301              (0x01 == pcb_bits.bit7)) /* S-FRAME decoded should come here */
1302   {
1303     NXP_LOG_ESE_D("%s S-Frame Received", __FUNCTION__);
1304     int32_t frameType = (int32_t)(pcb & 0x3F); /*discard upper 2 bits */
1305     phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME;
1306     if (frameType != WTX_REQ) {
1307       phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1308       phNxpEseProto7816_ResetRecovery();
1309     }
1310 
1311     switch (frameType) {
1312       case RESYNCH_REQ:
1313         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1314             RESYNCH_REQ;
1315         break;
1316       case RESYNCH_RSP:
1317         if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1318                 .errCode == OTHER_ERROR) {
1319           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1320               .sFrameType = RESYNCH_RSP;
1321           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1322               NO_ERROR;
1323           phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1324                           &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1325                           sizeof(phNxpEseProto7816_NextTx_Info_t));
1326           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1327               SEND_IFRAME;
1328           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
1329           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
1330               PH_PROTO_7816_VALUE_ZERO;
1331           /* Initialized the I-Frame sequence number as boot time,
1332             as R-SYNCH has reset the Jcop seq number */
1333           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
1334               PH_PROTO_7816_VALUE_ONE;
1335         } else {
1336           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1337               .sFrameType = RESYNCH_RSP;
1338           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1339           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1340               IDLE_STATE;
1341         }
1342         break;
1343       case IFS_REQ:
1344         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1345             IFS_REQ;
1346         break;
1347       case IFS_RES:
1348         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1349             IFS_RES;
1350         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
1351           phNxpEseProto7816_DecodeSFrameIFSData(p_data);
1352         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1353         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1354             IDLE_STATE;
1355         if (phNxpEseProto7816_3_Var.reset_type == RESET_TYPE_OS_RESET)
1356           status = ESESTATUS_FAILED;
1357         break;
1358       case ABORT_REQ:
1359         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1360             ABORT_REQ;
1361         break;
1362       case ABORT_RES:
1363         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1364             ABORT_RES;
1365         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1366         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1367             IDLE_STATE;
1368         break;
1369       case WTX_REQ:
1370         phNxpEseProto7816_3_Var.wtx_counter++;
1371         NXP_LOG_ESE_D("%s Wtx_counter value - %lu", __FUNCTION__,
1372                       phNxpEseProto7816_3_Var.wtx_counter);
1373         NXP_LOG_ESE_D("%s Wtx_counter wtx_counter_limit - %lu", __FUNCTION__,
1374                       phNxpEseProto7816_3_Var.wtx_counter_limit);
1375         /* Previous sent frame is some S-frame but not WTX response S-frame */
1376         if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0 &&
1377             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType !=
1378                 WTX_RSP &&
1379             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == SFRAME) {
1380           /* Goto recovery if it
1381           keep coming here for more than recovery counter max. value */
1382           if (phNxpEseProto7816_3_Var.recoveryCounter <
1383               GET_FRAME_RETRY_COUNT()) { /* Re-transmitting the previous
1384                                                   sent S-frame */
1385             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
1386                 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
1387             phNxpEseProto7816_3_Var.recoveryCounter++;
1388           } else {
1389             phNxpEseProto7816_RecoverySteps();
1390             phNxpEseProto7816_3_Var.recoveryCounter++;
1391           }
1392         } else {
1393           /* Checking for WTX counter with max. allowed WTX count */
1394           if (phNxpEseProto7816_3_Var.wtx_counter ==
1395               phNxpEseProto7816_3_Var.wtx_counter_limit) {
1396             phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1397             if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1398               NXP_LOG_ESE_D(
1399                   "%s Power cycle to eSE  max "
1400                   "WTX received",
1401                   __FUNCTION__);
1402               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1403                   IDLE_STATE;
1404               status = ESESTATUS_TRANSCEIVE_FAILED;
1405             } else {
1406               phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1407                   .sFrameType = INTF_RESET_REQ;
1408               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1409               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo
1410                   .sFrameType = INTF_RESET_REQ;
1411               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1412                   SEND_S_INTF_RST;
1413               NXP_LOG_ESE_D(
1414                   "%s Interface Reset to eSE wtx"
1415                   " count reached!!!",
1416                   __FUNCTION__);
1417             }
1418           } else {
1419             phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1420             phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1421                 .sFrameType = WTX_REQ;
1422             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1423             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1424                 WTX_RSP;
1425             phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1426                 SEND_S_WTX_RSP;
1427           }
1428         }
1429         break;
1430       case WTX_RSP:
1431         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1432             WTX_RSP;
1433         break;
1434       case INTF_RESET_REQ:
1435         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1436             INTF_RESET_REQ;
1437         break;
1438       case INTF_RESET_RSP:
1439         if (phNxpEseProto7816_3_Var.reset_type == RESET_TYPE_RECOVERY) {
1440           uint32_t tmpcurrentIFSDSize = phNxpEseProto7816_3_Var.currentIFSDSize;
1441           phNxpEseProto7816_ResetProtoParams();
1442           phNxpEseProto7816_3_Var.currentIFSDSize = tmpcurrentIFSDSize;
1443           phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1444               PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1445           phNxpEseProto7816_SetTxstate(SEND_S_IFS_ADJ);
1446         } else {
1447           phNxpEseProto7816_ResetProtoParams();
1448           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1449               .sFrameType = INTF_RESET_RSP;
1450           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1451           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1452               IDLE_STATE;
1453         }
1454         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1455           phNxpEseProto7816_DecodeSFrameATRData(p_data);
1456         } else {
1457           phNxpEse_setOsVersion(OS_VERSION_4_0);
1458         }
1459         break;
1460       case PROP_END_APDU_REQ:
1461         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1462             PROP_END_APDU_REQ;
1463         break;
1464       case PROP_END_APDU_RSP:
1465         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1466             PROP_END_APDU_RSP;
1467         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
1468           phNxpEseProto7816_DecodeSFrameSecureTimerData(p_data);
1469         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1470         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1471             IDLE_STATE;
1472         break;
1473       case HARD_RESET_REQ:
1474         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1475             HARD_RESET_REQ;
1476         break;
1477       case HARD_RESET_RSP:
1478         status = phNxpEseProto7816_DecodeAtrRsp(p_data);
1479         break;
1480       case ATR_RSP:
1481         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1482             ATR_RSP;
1483         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1484           phNxpEseProto7816_DecodeSFrameATRData(p_data);
1485           status = phNxpEse_StoreDatainList(
1486               p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET],
1487               &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1]);
1488         } else {
1489           phNxpEse_setOsVersion(OS_VERSION_4_0);
1490         }
1491         if (phNxpEseProto7816_3_Var.reset_type == RESET_TYPE_OS_RESET) {
1492           phNxpEseProto7816_SetTxstate(SEND_S_IFS_ADJ);
1493         } else {
1494           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1495           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1496               IDLE_STATE;
1497         }
1498         break;
1499       default:
1500         NXP_LOG_ESE_E("%s Wrong S-Frame Received", __FUNCTION__);
1501         break;
1502     }
1503     /*After S-Frame Rx 1 microsecond delay before next Tx*/
1504     if ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) &&
1505         (frameType != PROP_END_APDU_RSP)) {
1506       phNxpEse_Sleep(1000);
1507     }
1508   } else {
1509     NXP_LOG_ESE_D("%s Wrong-Frame Received", __FUNCTION__);
1510   }
1511   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
1512   return status;
1513 }
1514 
1515 /******************************************************************************
1516  * Function         phNxpEseProto7816_ProcessResponse
1517  *
1518  * Description      This internal function is used to
1519  *                  1. Check the LRC
1520  *                  2. Initiate decoding of received frame of data.
1521  * Returns          On success return true or else false.
1522  *
1523  ******************************************************************************/
phNxpEseProto7816_ProcessResponse(void)1524 static ESESTATUS phNxpEseProto7816_ProcessResponse(void) {
1525   uint32_t data_len = 0;
1526   uint8_t* p_data = NULL;
1527   ESESTATUS status = ESESTATUS_FAILED;
1528   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
1529   status = phNxpEseProto7816_GetRawFrame(&data_len, &p_data);
1530   NXP_LOG_ESE_D("%s p_data ----> %p len ----> 0x%x", __FUNCTION__, p_data,
1531                 data_len);
1532   if (ESESTATUS_SUCCESS == status) {
1533     /* Resetting the timeout counter */
1534     phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1535     /* LRC check followed */
1536     status = phNxpEseProto7816_CheckLRC(data_len, p_data);
1537     if (status == ESESTATUS_SUCCESS) {
1538       /* Resetting the RNACK retry counter */
1539       phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1540       status = phNxpEseProto7816_DecodeFrame(p_data, data_len);
1541     } else {
1542       NXP_LOG_ESE_E("%s LRC Check failed", __FUNCTION__);
1543       if (phNxpEseProto7816_3_Var.rnack_retry_counter <
1544           phNxpEseProto7816_3_Var.rnack_retry_limit) {
1545         /*If Last sent Non-error frame is S-Frame*/
1546         if (!phNxpEseProto7816_ResendLastSFrameReq()) {
1547           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1548           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1549           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1550               PARITY_ERROR;
1551           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
1552               (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo
1553                     .seqNo)
1554               << 4;
1555           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1556               SEND_R_NACK;
1557           if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1558             phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1559           }
1560         }
1561         phNxpEseProto7816_3_Var.rnack_retry_counter++;
1562       } else {
1563         phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1564         /* Re-transmission failed completely, Going to exit */
1565         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1566             IDLE_STATE;
1567         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1568       }
1569     }
1570   } else {
1571     NXP_LOG_ESE_I("%s phNxpEseProto7816_GetRawFrame failed", __FUNCTION__);
1572     if ((SFRAME == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType) &&
1573         ((WTX_RSP ==
1574           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) ||
1575          (RESYNCH_RSP ==
1576           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType))) {
1577       if (phNxpEseProto7816_3_Var.rnack_retry_counter <
1578           phNxpEseProto7816_3_Var.rnack_retry_limit) {
1579         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1580         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1581         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1582             OTHER_ERROR;
1583         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
1584             (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo)
1585             << 4;
1586         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1587             SEND_R_NACK;
1588         phNxpEseProto7816_3_Var.rnack_retry_counter++;
1589       } else {
1590         phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1591         /* Re-transmission failed completely, Going to exit */
1592         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1593             IDLE_STATE;
1594         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1595       }
1596     } else {
1597       phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1598       /* re transmit the frame */
1599       if (phNxpEseProto7816_3_Var.timeoutCounter <
1600           PH_PROTO_7816_TIMEOUT_RETRY_COUNT) {
1601         phNxpEseProto7816_3_Var.timeoutCounter++;
1602         NXP_LOG_ESE_D("%s re-transmitting the previous frame", __FUNCTION__);
1603         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
1604             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
1605       } else {
1606         /* Re-transmission failed completely, Going to exit */
1607         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1608             IDLE_STATE;
1609         if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1610           status = ESESTATUS_FAILED;
1611         }
1612         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1613         NXP_LOG_ESE_D("%s calling phNxpEse_StoreDatainList", __FUNCTION__);
1614         ESESTATUS storeDataStatus = phNxpEse_StoreDatainList(data_len, p_data);
1615         if (storeDataStatus != ESESTATUS_SUCCESS) {
1616           NXP_LOG_ESE_D("%s :phNxpEse_StoreDatainList failed. status = %x",
1617                         __FUNCTION__, storeDataStatus);
1618           status = storeDataStatus;
1619         }
1620       }
1621     }
1622   }
1623   NXP_LOG_ESE_D("Exit %s Status 0x%x", __FUNCTION__, status);
1624   return status;
1625 }
1626 
1627 /******************************************************************************
1628  * Function         TransceiveProcess
1629  *
1630  * Description      This internal function is used to
1631  *                  1. Send the raw data received from application after
1632  *computing LRC
1633  *                  2. Receive the response data from ESE, decode, process
1634  *and
1635  *                     store the data.
1636  * Returns          On success return true or else false.
1637  *
1638  ******************************************************************************/
TransceiveProcess(void)1639 static ESESTATUS TransceiveProcess(void) {
1640   ESESTATUS status = ESESTATUS_FAILED;
1641   sFrameInfo_t sFrameInfo;
1642   memset(&sFrameInfo, 0, sizeof(sFrameInfo_t));
1643 
1644   phNxpEse_FlushData();
1645   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
1646   while (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState !=
1647          IDLE_STATE) {
1648     NXP_LOG_ESE_D(
1649         "%s nextTransceiveState %x", __FUNCTION__,
1650         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState);
1651     switch (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState) {
1652       case SEND_IFRAME:
1653         status = phNxpEseProto7816_SendIframe(
1654             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo);
1655         break;
1656       case SEND_R_ACK:
1657         status = phNxpEseProto7816_sendRframe(RACK);
1658         break;
1659       case SEND_R_NACK:
1660         status = phNxpEseProto7816_sendRframe(RNACK);
1661         if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1662           phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1663         }
1664         break;
1665       case SEND_S_RSYNC:
1666         sFrameInfo.sFrameType = RESYNCH_REQ;
1667         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1668         break;
1669       case SEND_S_INTF_RST:
1670         sFrameInfo.sFrameType = INTF_RESET_REQ;
1671         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1672         break;
1673       case SEND_S_IFS_ADJ:
1674         sFrameInfo.sFrameType = IFS_REQ;
1675         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1676         break;
1677       case SEND_S_EOS:
1678         sFrameInfo.sFrameType = PROP_END_APDU_REQ;
1679         sFrameInfo.len =
1680             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len;
1681         sFrameInfo.p_data =
1682             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data;
1683         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1684         break;
1685       case SEND_S_WTX_RSP:
1686         sFrameInfo.sFrameType = WTX_RSP;
1687         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1688         phNxpEseProto7816_CheckAndNotifyWtx(WTX_ONGOING);
1689         break;
1690       case SEND_S_HRD_RST:
1691         sFrameInfo.sFrameType = HARD_RESET_REQ;
1692         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1693         break;
1694       case SEND_S_ATR_REQ:
1695         sFrameInfo.sFrameType = ATR_REQ;
1696         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1697         break;
1698       default:
1699         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1700             IDLE_STATE;
1701         break;
1702     }
1703     if (ESESTATUS_SUCCESS == status) {
1704       phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1705                       &phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1706                       sizeof(phNxpEseProto7816_NextTx_Info_t));
1707       status = phNxpEseProto7816_ProcessResponse();
1708       if (ESESTATUS_NOT_ENOUGH_MEMORY == status ||
1709           ESESTATUS_INVALID_RECEIVE_LENGTH == status) {
1710         NXP_LOG_ESE_E(
1711             "%s Processing response failed, shall retry in new session",
1712             __FUNCTION__);
1713         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1714             IDLE_STATE;
1715       }
1716     } else {
1717       NXP_LOG_ESE_E("%s Transceive send failed, going to recovery!",
1718                     __FUNCTION__);
1719       phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1720           IDLE_STATE;
1721     }
1722   }
1723   /*Timeout condition when previously WTX_ONGOING is notified
1724    *WTX_END shall be notified from here */
1725   phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1726   NXP_LOG_ESE_D("Exit %s Status 0x%x", __FUNCTION__, status);
1727   return status;
1728 }
1729 
1730 /******************************************************************************
1731  * Function         phNxpEseProto7816_CheckAndNotifyWtx
1732  *
1733  * Description      This function is used to
1734  *                  1. Check any WTX received previously
1735  *computing LRC
1736  *                  2. Check WTX_counter limit is reached wtx_ntf limit
1737  *and
1738  *                  3. Notify if wtx counter is greater than wtx_ntf
1739  *
1740  * Returns          None.
1741  *
1742  ******************************************************************************/
phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state)1743 static void phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state) {
1744   if (phNxpEseProto7816_3_Var.wtx_counter) {
1745     if (state == WTX_END) {
1746       if (phNxpEseProto7816_3_Var.wtx_counter >=
1747           phNxpEseProto7816_3_Var.wtx_ntf_limit) {
1748         phNxpEse_NotifySEWtxRequest(WTX_END);
1749       }
1750       phNxpEseProto7816_3_Var.wtx_counter = 0;
1751     } else if (state == WTX_ONGOING) {
1752       if (phNxpEseProto7816_3_Var.wtx_counter ==
1753           phNxpEseProto7816_3_Var.wtx_ntf_limit) {
1754         phNxpEse_NotifySEWtxRequest(WTX_ONGOING);
1755       }
1756     }
1757   }
1758 }
1759 
1760 /******************************************************************************
1761  * Function         phNxpEseProto7816_Transceive
1762  *
1763  * Description      This function is used to
1764  *                  1. Send the raw data received from application after
1765  *computing LRC
1766  *                  2. Receive the response data from ESE, decode, process
1767  *and
1768  *                     store the data.
1769  *                  3. Get the final complete data and sent back to application
1770  *
1771  * Returns          On success return true or else false.
1772  *
1773  ******************************************************************************/
phNxpEseProto7816_Transceive(phNxpEse_data * pCmd,phNxpEse_data * pRsp)1774 ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd,
1775                                        phNxpEse_data* pRsp) {
1776   ESESTATUS status = ESESTATUS_FAILED;
1777   ESESTATUS wStatus = ESESTATUS_FAILED;
1778   phNxpEse_data pRes;
1779   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
1780   if ((NULL == pCmd) || (NULL == pRsp) ||
1781       (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
1782        PH_NXP_ESE_PROTO_7816_IDLE))
1783     return status;
1784   phNxpEse_memset(&pRes, 0x00, sizeof(phNxpEse_data));
1785   /* Updating the transceive information to the protocol stack */
1786   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1787       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1788   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = pCmd->p_data;
1789   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
1790       pCmd->len;
1791   NXP_LOG_ESE_D("Transceive data ptr 0x%p len:%d", pCmd->p_data, pCmd->len);
1792   status = phNxpEseProto7816_SetFirstIframeContxt();
1793 
1794   phPalEse_startTimer(phPalEse_getTimer()->tx_timer);
1795 
1796   status = TransceiveProcess();
1797 
1798   phPalEse_stopTimer(phPalEse_getTimer()->rx_timer);
1799 
1800   if (ESESTATUS_FAILED == status || ESESTATUS_TRANSCEIVE_FAILED == status) {
1801     /* ESE hard reset to be done */
1802     NXP_LOG_ESE_E("Transceive failed, hard reset to proceed");
1803     wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1804     if (ESESTATUS_SUCCESS == wStatus) {
1805       NXP_LOG_ESE_D(
1806           "%s Data successfully received at 7816, packaging to "
1807           "send upper layers: DataLen = %d",
1808           __FUNCTION__, pRes.len);
1809     }
1810   } else {
1811     // fetch the data info and report to upper layer.
1812     wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1813     if (ESESTATUS_SUCCESS == wStatus) {
1814       NXP_LOG_ESE_D(
1815           "%s Data successfully received at 7816, packaging to "
1816           "send upper layers: DataLen = %d",
1817           __FUNCTION__, pRes.len);
1818     } else
1819       status = ESESTATUS_FAILED;
1820   }
1821   printCmdRspTimeDuration(status, pCmd->len, pRes.len);
1822   /* Copy the data to be read by the upper layer via transceive api */
1823   pRsp->len = pRes.len;
1824   pRsp->p_data = pRes.p_data;
1825 
1826   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1827       PH_NXP_ESE_PROTO_7816_IDLE;
1828   phNxpEseProto7816_3_Var.reset_type = RESET_TYPE_NONE;
1829   NXP_LOG_ESE_D("Exit %s Status 0x%x", __FUNCTION__, status);
1830   return status;
1831 }
1832 
1833 /******************************************************************************
1834  * Function         printCmdRspTimeDuration
1835  *
1836  * Description      Prints time taken(usecs) in sending C-Apdu and receiving
1837  *                  R-Apdu
1838  *                  Applicable only when KPI measurement config is enabled
1839  *
1840  * Returns          void
1841  *
1842  ******************************************************************************/
printCmdRspTimeDuration(ESESTATUS status,uint32_t cmdLen,uint32_t respLen)1843 static void printCmdRspTimeDuration(ESESTATUS status, uint32_t cmdLen,
1844                                     uint32_t respLen) {
1845   if (!phPalEse_getTimer()->is_enabled) return;
1846 
1847   if (status == ESESTATUS_SUCCESS) {
1848     NXP_LOG_ESE_I(
1849         "TX: Total time taken for sending C-Apdu of size: %d is %lu usecs",
1850         cmdLen, phPalEse_timerDuration(phPalEse_getTimer()->tx_timer));
1851     NXP_LOG_ESE_I(
1852         "RX: Total time taken for receiving R-Apdu of size: %d is %lu usecs",
1853         respLen, phPalEse_timerDuration(phPalEse_getTimer()->rx_timer));
1854   } else {
1855     phPalEse_resetTimer();
1856   }
1857 }
1858 
1859 /******************************************************************************
1860  * Function         phNxpEseProto7816_HardReset
1861  *
1862  * Description      This function is used to send the spi hard reset command
1863  *
1864  * Returns          On success return TRUE or else FALSE.
1865  *
1866  ******************************************************************************/
phNxpEseProto7816_HardReset(void)1867 static ESESTATUS phNxpEseProto7816_HardReset(void) {
1868   ESESTATUS status = ESESTATUS_FAILED;
1869 
1870   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1871       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1872   /* send the hard reset s-frame command*/
1873   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1874   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1875       HARD_RESET_REQ;
1876   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1877       SEND_S_HRD_RST;
1878   status = TransceiveProcess();
1879   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1880       PH_NXP_ESE_PROTO_7816_IDLE;
1881   return status;
1882 }
1883 
1884 /******************************************************************************
1885  * Function         phNxpEseProto7816_ResetProtoParams
1886  *
1887  * Description      This function is used to reset the 7816 protocol stack
1888  *instance
1889  *
1890  * Returns          On success return true or else false.
1891  *
1892  ******************************************************************************/
phNxpEseProto7816_ResetProtoParams(void)1893 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void) {
1894   unsigned long int tmpWTXCountlimit = PH_PROTO_7816_VALUE_ZERO;
1895   unsigned long int tmpRNACKCountlimit = PH_PROTO_7816_VALUE_ZERO;
1896   unsigned long int tmpWtxNtfCountlimit = PH_PROTO_7816_VALUE_ZERO;
1897   tmpWTXCountlimit = phNxpEseProto7816_3_Var.wtx_counter_limit;
1898   tmpRNACKCountlimit = phNxpEseProto7816_3_Var.rnack_retry_limit;
1899   tmpWtxNtfCountlimit = phNxpEseProto7816_3_Var.wtx_ntf_limit;
1900   phNxpEse_memset(&phNxpEseProto7816_3_Var, PH_PROTO_7816_VALUE_ZERO,
1901                   sizeof(phNxpEseProto7816_t));
1902   phNxpEseProto7816_3_Var.wtx_counter_limit = tmpWTXCountlimit;
1903   phNxpEseProto7816_3_Var.rnack_retry_limit = tmpRNACKCountlimit;
1904   phNxpEseProto7816_3_Var.wtx_ntf_limit = tmpWtxNtfCountlimit;
1905   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1906       PH_NXP_ESE_PROTO_7816_IDLE;
1907   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
1908   phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1909   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = INVALID;
1910   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
1911       IFSC_SIZE_SEND;
1912   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.defaultDataLenIFSC =
1913       IFSC_SIZE_SEND;
1914   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
1915       IFSC_SIZE_SEND;
1916   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = NULL;
1917   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType = INVALID;
1918   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLenIFSC =
1919       IFSC_SIZE_SEND;
1920   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.defaultDataLenIFSC =
1921       IFSC_SIZE_SEND;
1922   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS =
1923       IFSC_SIZE_SEND;
1924   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data = NULL;
1925   /* Initialized with sequence number of the last I-frame sent */
1926   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
1927       PH_PROTO_7816_VALUE_ONE;
1928   /* Initialized with sequence number of the last I-frame received */
1929   phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
1930       PH_PROTO_7816_VALUE_ONE;
1931   /* Initialized with sequence number of the last I-frame received */
1932   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo =
1933       PH_PROTO_7816_VALUE_ONE;
1934   phNxpEseProto7816_3_Var.recoveryCounter = PH_PROTO_7816_VALUE_ZERO;
1935   phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1936   phNxpEseProto7816_3_Var.wtx_counter = PH_PROTO_7816_VALUE_ZERO;
1937   /* This update is helpful in-case a R-NACK is transmitted from the MW */
1938   phNxpEseProto7816_3_Var.lastSentNonErrorframeType = UNKNOWN;
1939   phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1940   return ESESTATUS_SUCCESS;
1941 }
1942 
1943 /******************************************************************************
1944  * Function         phNxpEseProto7816_Reset
1945  *
1946  * Description      This function is used to reset the 7816 protocol stack
1947  *instance
1948  *
1949  * Returns          On success return true or else false.
1950  *
1951  ******************************************************************************/
phNxpEseProto7816_Reset(void)1952 ESESTATUS phNxpEseProto7816_Reset(void) {
1953   ESESTATUS status = ESESTATUS_FAILED;
1954   /* Resetting host protocol instance */
1955   phNxpEseProto7816_ResetProtoParams();
1956   status = phNxpEseProto7816_HardReset();
1957   if (status == ESESTATUS_SUCCESS) {
1958     /* Updating the ATR information(IFS,..) to 7816 stack */
1959     phNxpEse_data atrRsp;
1960     phNxpEseProto7816_getAtr(&atrRsp);
1961     phNxpEse_free(atrRsp.p_data);
1962   }
1963   return status;
1964 }
1965 
1966 /******************************************************************************
1967  * Function         phNxpEseProto7816_Open
1968  *
1969  * Description      This function is used to open the 7816 protocol stack
1970  *instance
1971  *
1972  * Returns          On success return true or else false.
1973  *
1974  ******************************************************************************/
phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam)1975 ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam) {
1976   ESESTATUS status = ESESTATUS_FAILED;
1977   status = phNxpEseProto7816_ResetProtoParams();
1978   NXP_LOG_ESE_D("%s: First open completed, Congratulations", __FUNCTION__);
1979   /* Update WTX max. limit */
1980   phNxpEseProto7816_3_Var.wtx_counter_limit = initParam.wtx_counter_limit;
1981   phNxpEseProto7816_3_Var.rnack_retry_limit = initParam.rnack_retry_limit;
1982   phNxpEseProto7816_3_Var.wtx_ntf_limit = initParam.wtx_ntf_limit;
1983   if (initParam.interfaceReset) /* Do interface reset */
1984   {
1985     status = phNxpEseProto7816_IntfReset(initParam.pSecureTimerParams);
1986     if (ESESTATUS_SUCCESS == status) {
1987       phNxpEse_memcpy(initParam.pSecureTimerParams,
1988                       &phNxpEseProto7816_3_Var.secureTimerParams,
1989                       sizeof(phNxpEseProto7816SecureTimer_t));
1990     }
1991   } else /* Initialisation condition to achieve usecases like JCOP download */
1992   {
1993     status = phNxpEseProto7816_HardReset();
1994     /* Updating the ATR information (Eg: IFS,..) to 7816 stack */
1995     if (status == ESESTATUS_SUCCESS) {
1996       phNxpEse_data atrRsp;
1997       phNxpEseProto7816_getAtr(&atrRsp);
1998       phNxpEse_free(atrRsp.p_data);
1999     }
2000   }
2001   return status;
2002 }
2003 
2004 /******************************************************************************
2005  * Function         phNxpEseProto7816_Close
2006  *
2007  * Description      This function is used to close the 7816 protocol stack
2008  *instance
2009  *
2010  * Returns          On success return true or else false.
2011  *
2012  ******************************************************************************/
phNxpEseProto7816_Close(phNxpEseProto7816SecureTimer_t * pSecureTimerParams)2013 ESESTATUS phNxpEseProto7816_Close(
2014     phNxpEseProto7816SecureTimer_t* pSecureTimerParams) {
2015   ESESTATUS status = ESESTATUS_FAILED;
2016   if (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
2017       PH_NXP_ESE_PROTO_7816_IDLE)
2018     return status;
2019   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2020       PH_NXP_ESE_PROTO_7816_DEINIT;
2021   phNxpEseProto7816_3_Var.recoveryCounter = 0;
2022   phNxpEseProto7816_3_Var.wtx_counter = 0;
2023   /* send the end of session s-frame */
2024   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2025   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
2026       PROP_END_APDU_REQ;
2027   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
2028       PH_PROTO_7816_VALUE_ZERO;
2029   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_EOS;
2030   status = TransceiveProcess();
2031   if (ESESTATUS_SUCCESS != status) {
2032     /* reset all the structures */
2033     NXP_LOG_ESE_E("%s TransceiveProcess failed ", __FUNCTION__);
2034     if (status == ESESTATUS_TRANSCEIVE_FAILED &&
2035         phNxpEseProto7816_3_Var.atrInfo.len > PH_PROTO_7816_VALUE_ZERO) {
2036       if (phNxpEseProto7816_3_Var.atrInfo
2037               .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] <
2038           PH_SE_OS_VERSION_10) {
2039         NXP_LOG_ESE_D("%s shall trigger recovery", __FUNCTION__);
2040         status = ESESTATUS_RESPONSE_TIMEOUT;
2041       }
2042     }
2043   }
2044   phNxpEse_memcpy(pSecureTimerParams,
2045                   &phNxpEseProto7816_3_Var.secureTimerParams,
2046                   sizeof(phNxpEseProto7816SecureTimer_t));
2047   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2048       PH_NXP_ESE_PROTO_7816_IDLE;
2049   return status;
2050 }
2051 
2052 /******************************************************************************
2053  * Function         phNxpEseProto7816_CloseAllSessions
2054  *
2055  * Description      This function is used to close the 7816 protocol stack
2056  *instance
2057  *
2058  * Returns          On success return true or else false.
2059  *
2060  ******************************************************************************/
phNxpEseProto7816_CloseAllSessions(void)2061 ESESTATUS phNxpEseProto7816_CloseAllSessions(void) {
2062   ESESTATUS status = ESESTATUS_FAILED;
2063 
2064   /*Note:- Below OS version check using ATR shall
2065    * be removed while integrating with TEE/REE as ATR
2066    * information is not available in REE case*/
2067 
2068   if (phNxpEseProto7816_3_Var.atrInfo.vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN -
2069                                                1] >= PH_SE_OS_VERSION_10) {
2070     uint8_t* buffer = (uint8_t*)phNxpEse_memalloc(sizeof(uint8_t));
2071     if (buffer != NULL) {
2072       buffer[PH_PROTO_7816_VALUE_ZERO] = PH_PROTO_CLOSE_ALL_SESSION_INF;
2073       /* send the end of session s-frame */
2074       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2075       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
2076           PROP_END_APDU_REQ;
2077       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data = buffer;
2078       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
2079           PH_PROTO_CLOSE_ALL_SESSION_LEN;
2080       phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
2081           SEND_S_EOS;
2082       status = TransceiveProcess();
2083       if (ESESTATUS_FAILED == status) {
2084         /* reset all the structures */
2085         NXP_LOG_ESE_D("%s EndOfSession failed ", __FUNCTION__);
2086       }
2087       phNxpEse_free(buffer);
2088       phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2089           PH_NXP_ESE_PROTO_7816_IDLE;
2090     }
2091   } else {
2092     NXP_LOG_ESE_D("%s Function not supported ", __FUNCTION__);
2093     status = ESESTATUS_SUCCESS;
2094   }
2095   return status;
2096 }
2097 
2098 /******************************************************************************
2099  * Function         phNxpEseProto7816_IntfReset
2100  *
2101  * Description      This function is used to reset just the current interface
2102  *
2103  * Returns          On success return true or else false.
2104  *
2105  ******************************************************************************/
phNxpEseProto7816_IntfReset(phNxpEseProto7816SecureTimer_t * pSecureTimerParam)2106 ESESTATUS phNxpEseProto7816_IntfReset(
2107     phNxpEseProto7816SecureTimer_t* pSecureTimerParam) {
2108   ESESTATUS status = ESESTATUS_FAILED;
2109   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
2110   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2111       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2112   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2113   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
2114       INTF_RESET_REQ;
2115   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
2116       SEND_S_INTF_RST;
2117   status = TransceiveProcess();
2118   if (ESESTATUS_FAILED == status) {
2119     /* reset all the structures */
2120     NXP_LOG_ESE_E("%s TransceiveProcess failed ", __FUNCTION__);
2121   }
2122   phNxpEse_memcpy(pSecureTimerParam, &phNxpEseProto7816_3_Var.secureTimerParams,
2123                   sizeof(phNxpEseProto7816SecureTimer_t));
2124   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2125       PH_NXP_ESE_PROTO_7816_IDLE;
2126   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
2127   return status;
2128 }
2129 
2130 /******************************************************************************
2131  * Function         phNxpEseProto7816_SetIfs
2132  *
2133  * Description      This function is used to set IFSD value to card
2134  *
2135  * Returns          On success return true or else false.
2136  *
2137  ******************************************************************************/
phNxpEseProto7816_SetIfs(uint16_t IFS_Size)2138 ESESTATUS phNxpEseProto7816_SetIfs(uint16_t IFS_Size) {
2139   // phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
2140   // IFSC_Size;
2141   ESESTATUS status = ESESTATUS_FAILED;
2142   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
2143   /* IFSD > IFSC not allowed, card will reject by R-NACK so not sending */
2144   if (IFS_Size >
2145       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC) {
2146     phNxpEseProto7816_3_Var.currentIFSDSize =
2147         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC;
2148     /* IFSD is greater than IFSC , set max IFSC as IFSD*/
2149     NXP_LOG_ESE_D("%s : IFSD greater than IFSC ,  set max IFSC as IFSD  ",
2150                   __FUNCTION__);
2151   } else {
2152     phNxpEseProto7816_3_Var.currentIFSDSize = IFS_Size;
2153   }
2154   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2155       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2156   phNxpEseProto7816_SetTxstate(SEND_S_IFS_ADJ);
2157   status = TransceiveProcess();
2158   if (ESESTATUS_FAILED == status) {
2159     /* reset all the structures */
2160     NXP_LOG_ESE_E("%s TransceiveProcess failed ", __FUNCTION__);
2161   }
2162   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2163       PH_NXP_ESE_PROTO_7816_IDLE;
2164   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
2165   return status;
2166 }
2167 
2168 /******************************************************************************
2169  * Function         phNxpEseProto7816_GetIfs
2170  *
2171  * Description      This function is used to get current IFS adjusted value wrt
2172  *card
2173  *
2174  * Returns          On success return true or else false.
2175  *
2176  ******************************************************************************/
phNxpEseProto7816_GetIfs(void)2177 uint16_t phNxpEseProto7816_GetIfs(void) {
2178   NXP_LOG_ESE_D(
2179       "Enter %s current IFSC = %d", __FUNCTION__,
2180       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS);
2181   return phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
2182       .currentDataLenIFS;
2183 }
2184 
2185 /******************************************************************************
2186  * Function         phNxpEseProto7816_GetOsMode
2187  *
2188  * Description      This function is used to get current OS Mode
2189  *
2190  * Returns          0x01 : JCOP_MODE
2191  *                  0x02 : OSU_MODE
2192  *
2193  ******************************************************************************/
phNxpEseProto7816_GetOsMode(void)2194 phNxpEseProto7816_OsType_t phNxpEseProto7816_GetOsMode(void) {
2195   phNxpEseProto7816_OsType_t mode = UNKNOWN_MODE;
2196   if (GET_CHIP_OS_VERSION() >= OS_VERSION_5_2_2) {
2197     if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_JCOP) {
2198       NXP_LOG_ESE_D("Enter %s OS Mode = %s", __FUNCTION__, "JCOP Mode");
2199       mode = JCOP_MODE;
2200     } else if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_OSU) {
2201       NXP_LOG_ESE_D("Enter %s OS Mode = %s", __FUNCTION__, "OSU Mode");
2202       mode = OSU_MODE;
2203     } else {
2204       NXP_LOG_ESE_D("Enter %s OS Mode = %s", __FUNCTION__, "UNKNOWN Mode");
2205       mode = UNKNOWN_MODE;
2206     }
2207   } else {
2208     NXP_LOG_ESE_E("%s function not supported", __FUNCTION__);
2209   }
2210   return mode;
2211 }
2212 
2213 /******************************************************************************
2214  * Function         phNxpEseProto7816_getAtr
2215  *
2216  * Description      This function is used to get the ATR data from ESE
2217  *
2218  * Returns          On success return true or else false
2219  *
2220  ******************************************************************************/
phNxpEseProto7816_getAtr(phNxpEse_data * pATRRsp)2221 ESESTATUS phNxpEseProto7816_getAtr(phNxpEse_data* pATRRsp) {
2222   ESESTATUS status = ESESTATUS_FAILED;
2223 
2224   NXP_LOG_ESE_D("Enter %s ", __FUNCTION__);
2225   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2226       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2227   phNxpEseProto7816_SetTxstate(SEND_S_ATR_REQ);
2228   status = TransceiveProcess();
2229   if (ESESTATUS_FAILED == status) {
2230     /* reset all the structures */
2231     NXP_LOG_ESE_D("%s TransceiveProcess failed ", __FUNCTION__);
2232   }
2233 
2234   status = phNxpEse_GetData(&(pATRRsp->len), &(pATRRsp->p_data));
2235   if (ESESTATUS_SUCCESS == status) {
2236     NXP_LOG_ESE_D(
2237         "%s Data successfully received at 7816, packaging to "
2238         "send upper layers: DataLen = %d",
2239         __FUNCTION__, pATRRsp->len);
2240   } else
2241     status = ESESTATUS_FAILED;
2242   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2243       PH_NXP_ESE_PROTO_7816_IDLE;
2244   NXP_LOG_ESE_D("Exit %s ", __FUNCTION__);
2245   return status;
2246 }
2247 
2248 /******************************************************************************
2249  * Function         phNxpEseProto7816_SetEndPoint
2250  *
2251  * Description      This function is used to set end point protocol context
2252  *
2253  * Returns          Always return TRUE (1).
2254  *
2255  ******************************************************************************/
phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint)2256 ESESTATUS phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint) {
2257   ESESTATUS status = ESESTATUS_FAILED;
2258   if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
2259     phNxpEseProto7816_3_Var = phNxpEseProto7816_ptr[uEndPoint];
2260     status = ESESTATUS_SUCCESS;
2261   } else {
2262     /*Do nothing return fail*/
2263   }
2264   return status;
2265 }
2266 
2267 /******************************************************************************
2268  * Function         phNxpEseProto7816_ResetEndPoint
2269  *
2270  * Description      This function is used to set end point protocol context
2271  *
2272  * Returns          Always return TRUE (1).
2273  *
2274  ******************************************************************************/
phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint)2275 ESESTATUS phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint) {
2276   ESESTATUS status = ESESTATUS_FAILED;
2277   if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
2278     phNxpEseProto7816_ptr[uEndPoint] = phNxpEseProto7816_3_Var;
2279     status = ESESTATUS_SUCCESS;
2280   } else {
2281     /*Do nothing return fail*/
2282   }
2283   return status;
2284 }
2285 
2286 /******************************************************************************
2287  * Function         phNxpEseProto7816_ResendLastSFrameReq
2288  *
2289  * Description      This function is used to Resend S-Frame on receiving
2290  *                  non S-Frame response
2291  *
2292  * Returns          If last sent Frame is S-Frame
2293  *                  return TRUE(S-Frame) otherwise FALSE(Non-S-Frame).
2294  *
2295  ******************************************************************************/
phNxpEseProto7816_ResendLastSFrameReq(void)2296 static bool phNxpEseProto7816_ResendLastSFrameReq(void) {
2297   bool isLastSFrameReq = false;
2298   if (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == SFRAME &&
2299       WTX_RSP !=
2300           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) {
2301     NXP_LOG_ESE_D("%s Unexpected Frame, re-transmitting the previous S-frame",
2302                   __FUNCTION__);
2303     phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
2304                     &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
2305                     sizeof(phNxpEseProto7816_NextTx_Info_t));
2306     isLastSFrameReq = true;
2307   }
2308   return isLastSFrameReq;
2309 }
2310 
2311 /** @} */
2312