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