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 client
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     }
1230     phNxpEseProto7816_ResetRecovery();
1231     switch (frameType) {
1232       case RESYNCH_REQ:
1233         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1234             RESYNCH_REQ;
1235         break;
1236       case RESYNCH_RSP:
1237         if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
1238                 .errCode == OTHER_ERROR) {
1239           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1240               .sFrameType = RESYNCH_RSP;
1241           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
1242               NO_ERROR;
1243           phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1244                           &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1245                           sizeof(phNxpEseProto7816_NextTx_Info_t));
1246           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1247               SEND_IFRAME;
1248           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
1249           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
1250               PH_PROTO_7816_VALUE_ZERO;
1251           /* Initialized the I-Frame sequence number as boot time,
1252             as R-SYNCH has reset the Jcop seq number */
1253           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
1254               PH_PROTO_7816_VALUE_ONE;
1255         } else {
1256           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1257               .sFrameType = RESYNCH_RSP;
1258           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1259           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1260               IDLE_STATE;
1261         }
1262         break;
1263       case IFS_REQ:
1264         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1265             IFS_REQ;
1266         break;
1267       case IFS_RES:
1268         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1269             IFS_RES;
1270         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
1271           phNxpEseProto7816_DecodeSFrameIFSData(p_data);
1272         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1273         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1274             IDLE_STATE;
1275         break;
1276       case ABORT_REQ:
1277         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1278             ABORT_REQ;
1279         break;
1280       case ABORT_RES:
1281         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1282             ABORT_RES;
1283         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1284         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1285             IDLE_STATE;
1286         break;
1287       case WTX_REQ:
1288         phNxpEseProto7816_3_Var.wtx_counter++;
1289         ALOGD_IF(ese_debug_enabled, "%s Wtx_counter value - %lu", __FUNCTION__,
1290                  phNxpEseProto7816_3_Var.wtx_counter);
1291         ALOGD_IF(ese_debug_enabled, "%s Wtx_counter wtx_counter_limit - %lu",
1292                  __FUNCTION__, phNxpEseProto7816_3_Var.wtx_counter_limit);
1293         /* Previous sent frame is some S-frame but not WTX response S-frame */
1294         if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0 &&
1295             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType !=
1296                 WTX_RSP &&
1297             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == SFRAME) {
1298           /* Goto recovery if it
1299           keep coming here for more than recovery counter max. value */
1300           if (phNxpEseProto7816_3_Var.recoveryCounter <
1301               GET_FRAME_RETRY_COUNT()) { /* Re-transmitting the previous
1302                                                   sent S-frame */
1303             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
1304                 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
1305             phNxpEseProto7816_3_Var.recoveryCounter++;
1306           } else {
1307             phNxpEseProto7816_RecoverySteps();
1308             phNxpEseProto7816_3_Var.recoveryCounter++;
1309           }
1310         } else {
1311           /* Checking for WTX counter with max. allowed WTX count */
1312           if (phNxpEseProto7816_3_Var.wtx_counter ==
1313               phNxpEseProto7816_3_Var.wtx_counter_limit) {
1314             phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1315             if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1316               ALOGD_IF(ese_debug_enabled,
1317                        "%s Power cycle to eSE  max "
1318                        "WTX received",
1319                        __FUNCTION__);
1320               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1321                   IDLE_STATE;
1322               status = ESESTATUS_TRANSCEIVE_FAILED;
1323             } else {
1324               phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1325                   .sFrameType = INTF_RESET_REQ;
1326               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1327               phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo
1328                   .sFrameType = INTF_RESET_REQ;
1329               phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1330                   SEND_S_INTF_RST;
1331               ALOGD_IF(ese_debug_enabled,
1332                        "%s Interface Reset to eSE wtx"
1333                        " count reached!!!",
1334                        __FUNCTION__);
1335             }
1336           } else {
1337             phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1338             phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
1339                 .sFrameType = WTX_REQ;
1340             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1341             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1342                 WTX_RSP;
1343             phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1344                 SEND_S_WTX_RSP;
1345           }
1346         }
1347         break;
1348       case WTX_RSP:
1349         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1350             WTX_RSP;
1351         break;
1352       case INTF_RESET_REQ:
1353         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1354             INTF_RESET_REQ;
1355         break;
1356       case INTF_RESET_RSP:
1357         phNxpEseProto7816_ResetProtoParams();
1358         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1359             INTF_RESET_RSP;
1360         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1361           phNxpEseProto7816_DecodeSFrameATRData(p_data);
1362         } else {
1363           phNxpEse_setOsVersion(OS_VERSION_4_0);
1364         }
1365         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1366         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1367             IDLE_STATE;
1368         break;
1369       case PROP_END_APDU_REQ:
1370         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1371             PROP_END_APDU_REQ;
1372         break;
1373       case PROP_END_APDU_RSP:
1374         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1375             PROP_END_APDU_RSP;
1376         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
1377           phNxpEseProto7816_DecodeSFrameSecureTimerData(p_data);
1378         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1379         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1380             IDLE_STATE;
1381         break;
1382       case HARD_RESET_REQ:
1383         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1384             HARD_RESET_REQ;
1385         break;
1386       case HARD_RESET_RSP:
1387         // This is 4ms delay and delay of 1ms in also there in line 1401 before
1388         // next Tx
1389         phNxpEse_Sleep(HARD_RESET_RES_DELAY);
1390         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1391             HARD_RESET_RSP;
1392         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1393           /*Response status either success/fail*/
1394           if (!p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1])
1395             status = ESESTATUS_FAILED;
1396           else
1397             status = ESESTATUS_SUCCESS;
1398         }
1399         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1400         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1401             IDLE_STATE;
1402         break;
1403       case ATR_RSP:
1404         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
1405             ATR_RSP;
1406         if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
1407           phNxpEseProto7816_DecodeSFrameATRData(p_data);
1408           phNxpEse_StoreDatainList(
1409               p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET],
1410               &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1]);
1411         } else {
1412           phNxpEse_setOsVersion(OS_VERSION_4_0);
1413         }
1414         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
1415         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1416             IDLE_STATE;
1417         break;
1418       default:
1419         ALOGE("%s Wrong S-Frame Received", __FUNCTION__);
1420         break;
1421     }
1422     /*After S-Frame Rx 1 msec delay before next Tx*/
1423     if ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) &&
1424         (frameType != PROP_END_APDU_RSP)) {
1425       phNxpEse_Sleep(1000);
1426     }
1427   } else {
1428     ALOGD_IF(ese_debug_enabled, "%s Wrong-Frame Received", __FUNCTION__);
1429   }
1430   ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
1431   return status;
1432 }
1433 
1434 /******************************************************************************
1435  * Function         phNxpEseProto7816_ProcessResponse
1436  *
1437  * Description      This internal function is used to
1438  *                  1. Check the LRC
1439  *                  2. Initiate decoding of received frame of data.
1440  * Returns          On success return true or else false.
1441  *
1442  ******************************************************************************/
phNxpEseProto7816_ProcessResponse(void)1443 static ESESTATUS phNxpEseProto7816_ProcessResponse(void) {
1444   uint32_t data_len = 0;
1445   uint8_t* p_data = NULL;
1446   ESESTATUS status = ESESTATUS_FAILED;
1447   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
1448   status = phNxpEseProto7816_GetRawFrame(&data_len, &p_data);
1449   ALOGD_IF(ese_debug_enabled, "%s p_data ----> %p len ----> 0x%x", __FUNCTION__,
1450            p_data, data_len);
1451   if (ESESTATUS_SUCCESS == status) {
1452     /* Resetting the timeout counter */
1453     phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1454     /* LRC check followed */
1455     status = phNxpEseProto7816_CheckLRC(data_len, p_data);
1456     if (status == ESESTATUS_SUCCESS) {
1457       /* Resetting the RNACK retry counter */
1458       phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1459       status = phNxpEseProto7816_DecodeFrame(p_data, data_len);
1460     } else {
1461       ALOGE("%s LRC Check failed", __FUNCTION__);
1462       if (phNxpEseProto7816_3_Var.rnack_retry_counter <
1463           phNxpEseProto7816_3_Var.rnack_retry_limit) {
1464         /*If Last sent Non-error frame is S-Frame*/
1465         if (!phNxpEseProto7816_ResendLastSFrameReq()) {
1466           phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1467           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1468           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1469               PARITY_ERROR;
1470           phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
1471               (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo
1472                     .seqNo)
1473               << 4;
1474           phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1475               SEND_R_NACK;
1476           if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1477             phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1478           }
1479         }
1480         phNxpEseProto7816_3_Var.rnack_retry_counter++;
1481       } else {
1482         phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1483         /* Re-transmission failed completely, Going to exit */
1484         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1485             IDLE_STATE;
1486         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1487       }
1488     }
1489   } else {
1490     ALOGD_IF(ese_debug_enabled, "%s phNxpEseProto7816_GetRawFrame failed",
1491              __FUNCTION__);
1492     if ((SFRAME == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType) &&
1493         ((WTX_RSP ==
1494           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) ||
1495          (RESYNCH_RSP ==
1496           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType))) {
1497       if (phNxpEseProto7816_3_Var.rnack_retry_counter <
1498           phNxpEseProto7816_3_Var.rnack_retry_limit) {
1499         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1500         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
1501         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
1502             OTHER_ERROR;
1503         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
1504             (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo)
1505             << 4;
1506         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1507             SEND_R_NACK;
1508         phNxpEseProto7816_3_Var.rnack_retry_counter++;
1509       } else {
1510         phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1511         /* Re-transmission failed completely, Going to exit */
1512         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1513             IDLE_STATE;
1514         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1515       }
1516     } else {
1517       phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1518       /* re transmit the frame */
1519       if (phNxpEseProto7816_3_Var.timeoutCounter <
1520           PH_PROTO_7816_TIMEOUT_RETRY_COUNT) {
1521         phNxpEseProto7816_3_Var.timeoutCounter++;
1522         ALOGD_IF(ese_debug_enabled, "%s re-transmitting the previous frame",
1523                  __FUNCTION__);
1524         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
1525             phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
1526       } else {
1527         /* Re-transmission failed completely, Going to exit */
1528         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1529             IDLE_STATE;
1530         if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1531           status = ESESTATUS_FAILED;
1532         }
1533         phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1534         ALOGD_IF(ese_debug_enabled, "%s calling phNxpEse_StoreDatainList",
1535                  __FUNCTION__);
1536         phNxpEse_StoreDatainList(data_len, p_data);
1537       }
1538     }
1539   }
1540   ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
1541   return status;
1542 }
1543 
1544 /******************************************************************************
1545  * Function         TransceiveProcess
1546  *
1547  * Description      This internal function is used to
1548  *                  1. Send the raw data received from application after
1549  *computing LRC
1550  *                  2. Receive the response data from ESE, decode, process
1551  *and
1552  *                     store the data.
1553  * Returns          On success return true or else false.
1554  *
1555  ******************************************************************************/
TransceiveProcess(void)1556 static ESESTATUS TransceiveProcess(void) {
1557   ESESTATUS status = ESESTATUS_FAILED;
1558   sFrameInfo_t sFrameInfo;
1559   memset(&sFrameInfo, 0, sizeof(sFrameInfo_t));
1560 
1561   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
1562   while (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState !=
1563          IDLE_STATE) {
1564     ALOGD_IF(ese_debug_enabled, "%s nextTransceiveState %x", __FUNCTION__,
1565              phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState);
1566     switch (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState) {
1567       case SEND_IFRAME:
1568         status = phNxpEseProto7816_SendIframe(
1569             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo);
1570         break;
1571       case SEND_R_ACK:
1572         status = phNxpEseProto7816_sendRframe(RACK);
1573         break;
1574       case SEND_R_NACK:
1575         status = phNxpEseProto7816_sendRframe(RNACK);
1576         if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1577           phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
1578         }
1579         break;
1580       case SEND_S_RSYNC:
1581         sFrameInfo.sFrameType = RESYNCH_REQ;
1582         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1583         break;
1584       case SEND_S_INTF_RST:
1585         sFrameInfo.sFrameType = INTF_RESET_REQ;
1586         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1587         break;
1588       case SEND_S_IFS_ADJ:
1589         sFrameInfo.sFrameType = IFS_REQ;
1590         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1591         break;
1592       case SEND_S_EOS:
1593         sFrameInfo.sFrameType = PROP_END_APDU_REQ;
1594         sFrameInfo.len =
1595             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len;
1596         sFrameInfo.p_data =
1597             phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data;
1598         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1599         break;
1600       case SEND_S_WTX_RSP:
1601         sFrameInfo.sFrameType = WTX_RSP;
1602         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1603         phNxpEseProto7816_CheckAndNotifyWtx(WTX_ONGOING);
1604         break;
1605       case SEND_S_HRD_RST:
1606         sFrameInfo.sFrameType = HARD_RESET_REQ;
1607         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1608         break;
1609       case SEND_S_ATR_REQ:
1610         sFrameInfo.sFrameType = ATR_REQ;
1611         status = phNxpEseProto7816_SendSFrame(sFrameInfo);
1612         break;
1613       default:
1614         phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1615             IDLE_STATE;
1616         break;
1617     }
1618     if (ESESTATUS_SUCCESS == status) {
1619       phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
1620                       &phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
1621                       sizeof(phNxpEseProto7816_NextTx_Info_t));
1622       status = phNxpEseProto7816_ProcessResponse();
1623     } else {
1624       ALOGE("%s Transceive send failed, going to recovery!", __FUNCTION__);
1625       phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1626           IDLE_STATE;
1627     }
1628   };
1629   /*Timeout condition when previously WTX_ONGOING is notified
1630    *WTX_END shall be notified from here */
1631   phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
1632   ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
1633   return status;
1634 }
1635 
1636 /******************************************************************************
1637  * Function         phNxpEseProto7816_CheckAndNotifyWtx
1638  *
1639  * Description      This function is used to
1640  *                  1. Check any WTX received previously
1641  *computing LRC
1642  *                  2. Check WTX_counter limit is reached wtx_ntf limit
1643  *and
1644  *                  3. Notify if wtx counter is greater than wtx_ntf
1645  *
1646  * Returns          None.
1647  *
1648  ******************************************************************************/
phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state)1649 static void phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state) {
1650   if (phNxpEseProto7816_3_Var.wtx_counter) {
1651     if (state == WTX_END) {
1652       if (phNxpEseProto7816_3_Var.wtx_counter >=
1653           phNxpEseProto7816_3_Var.wtx_ntf_limit) {
1654         phNxpEse_NotifySEWtxRequest(WTX_END);
1655       }
1656       phNxpEseProto7816_3_Var.wtx_counter = 0;
1657     } else if (state == WTX_ONGOING) {
1658       if (phNxpEseProto7816_3_Var.wtx_counter ==
1659           phNxpEseProto7816_3_Var.wtx_ntf_limit) {
1660         phNxpEse_NotifySEWtxRequest(WTX_ONGOING);
1661       }
1662     }
1663   }
1664 }
1665 
1666 /******************************************************************************
1667  * Function         phNxpEseProto7816_Transceive
1668  *
1669  * Description      This function is used to
1670  *                  1. Send the raw data received from application after
1671  *computing LRC
1672  *                  2. Receive the response data from ESE, decode, process
1673  *and
1674  *                     store the data.
1675  *                  3. Get the final complete data and sent back to application
1676  *
1677  * Returns          On success return true or else false.
1678  *
1679  ******************************************************************************/
phNxpEseProto7816_Transceive(phNxpEse_data * pCmd,phNxpEse_data * pRsp)1680 ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd,
1681                                        phNxpEse_data* pRsp) {
1682   ESESTATUS status = ESESTATUS_FAILED;
1683   ESESTATUS wStatus = ESESTATUS_FAILED;
1684   phNxpEse_data pRes;
1685   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
1686   if ((NULL == pCmd) || (NULL == pRsp) ||
1687       (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
1688        PH_NXP_ESE_PROTO_7816_IDLE))
1689     return status;
1690   phNxpEse_memset(&pRes, 0x00, sizeof(phNxpEse_data));
1691   /* Updating the transceive information to the protocol stack */
1692   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1693       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1694   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = pCmd->p_data;
1695   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
1696       pCmd->len;
1697   ALOGD_IF(ese_debug_enabled, "Transceive data ptr 0x%p len:%d", pCmd->p_data,
1698            pCmd->len);
1699   status = phNxpEseProto7816_SetFirstIframeContxt();
1700   status = TransceiveProcess();
1701   if (ESESTATUS_FAILED == status || ESESTATUS_TRANSCEIVE_FAILED == status) {
1702     /* ESE hard reset to be done */
1703     ALOGE("Transceive failed, hard reset to proceed");
1704     wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1705     if (ESESTATUS_SUCCESS == wStatus) {
1706       ALOGD_IF(ese_debug_enabled,
1707                "%s Data successfully received at 7816, packaging to "
1708                "send upper layers: DataLen = %d",
1709                __FUNCTION__, pRes.len);
1710     }
1711   } else {
1712     // fetch the data info and report to upper layer.
1713     wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
1714     if (ESESTATUS_SUCCESS == wStatus) {
1715       ALOGD_IF(ese_debug_enabled,
1716                "%s Data successfully received at 7816, packaging to "
1717                "send upper layers: DataLen = %d",
1718                __FUNCTION__, pRes.len);
1719     } else
1720       status = ESESTATUS_FAILED;
1721   }
1722 
1723   /* Copy the data to be read by the upper layer via transceive api */
1724   pRsp->len = pRes.len;
1725   pRsp->p_data = pRes.p_data;
1726 
1727   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1728       PH_NXP_ESE_PROTO_7816_IDLE;
1729   phNxpEseProto7816_3_Var.reset_type = RESET_TYPE_NONE;
1730   ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
1731   return status;
1732 }
1733 
1734 /******************************************************************************
1735  * Function         phNxpEseProto7816_RSync
1736  *
1737  * Description      This function is used to send the RSync command
1738  *
1739  * Returns          On success return true or else false.
1740  *
1741  ******************************************************************************/
phNxpEseProto7816_RSync(void)1742 static ESESTATUS phNxpEseProto7816_RSync(void) {
1743   ESESTATUS status = ESESTATUS_FAILED;
1744   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1745       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1746   /* send the end of session s-frame */
1747   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1748   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1749       RESYNCH_REQ;
1750   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_RSYNC;
1751   status = TransceiveProcess();
1752   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1753       PH_NXP_ESE_PROTO_7816_IDLE;
1754   return status;
1755 }
1756 
1757 /******************************************************************************
1758  * Function         phNxpEseProto7816_HardReset
1759  *
1760  * Description      This function is used to send the spi hard reset command
1761  *
1762  * Returns          On success return TRUE or else FALSE.
1763  *
1764  ******************************************************************************/
phNxpEseProto7816_HardReset(void)1765 static ESESTATUS phNxpEseProto7816_HardReset(void) {
1766   ESESTATUS status = ESESTATUS_FAILED;
1767 
1768   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1769       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
1770   /* send the hard reset s-frame command*/
1771   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1772   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1773       HARD_RESET_REQ;
1774   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1775       SEND_S_HRD_RST;
1776   status = TransceiveProcess();
1777   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1778       PH_NXP_ESE_PROTO_7816_IDLE;
1779   return status;
1780 }
1781 
1782 /******************************************************************************
1783  * Function         phNxpEseProto7816_ResetProtoParams
1784  *
1785  * Description      This function is used to reset the 7816 protocol stack
1786  *instance
1787  *
1788  * Returns          On success return true or else false.
1789  *
1790  ******************************************************************************/
phNxpEseProto7816_ResetProtoParams(void)1791 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void) {
1792   unsigned long int tmpWTXCountlimit = PH_PROTO_7816_VALUE_ZERO;
1793   unsigned long int tmpRNACKCountlimit = PH_PROTO_7816_VALUE_ZERO;
1794   unsigned long int tmpWtxNtfCountlimit = PH_PROTO_7816_VALUE_ZERO;
1795   tmpWTXCountlimit = phNxpEseProto7816_3_Var.wtx_counter_limit;
1796   tmpRNACKCountlimit = phNxpEseProto7816_3_Var.rnack_retry_limit;
1797   tmpWtxNtfCountlimit = phNxpEseProto7816_3_Var.wtx_ntf_limit;
1798   phNxpEse_memset(&phNxpEseProto7816_3_Var, PH_PROTO_7816_VALUE_ZERO,
1799                   sizeof(phNxpEseProto7816_t));
1800   phNxpEseProto7816_3_Var.wtx_counter_limit = tmpWTXCountlimit;
1801   phNxpEseProto7816_3_Var.rnack_retry_limit = tmpRNACKCountlimit;
1802   phNxpEseProto7816_3_Var.wtx_ntf_limit = tmpWtxNtfCountlimit;
1803   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1804       PH_NXP_ESE_PROTO_7816_IDLE;
1805   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
1806   phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
1807   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = INVALID;
1808   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
1809       IFSC_SIZE_SEND;
1810   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.defaultDataLenIFSC =
1811       IFSC_SIZE_SEND;
1812   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
1813       IFSC_SIZE_SEND;
1814   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = NULL;
1815   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType = INVALID;
1816   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLenIFSC =
1817       IFSC_SIZE_SEND;
1818   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.defaultDataLenIFSC =
1819       IFSC_SIZE_SEND;
1820   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS =
1821       IFSC_SIZE_SEND;
1822   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data = NULL;
1823   /* Initialized with sequence number of the last I-frame sent */
1824   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
1825       PH_PROTO_7816_VALUE_ONE;
1826   /* Initialized with sequence number of the last I-frame received */
1827   phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
1828       PH_PROTO_7816_VALUE_ONE;
1829   /* Initialized with sequence number of the last I-frame received */
1830   phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo =
1831       PH_PROTO_7816_VALUE_ONE;
1832   phNxpEseProto7816_3_Var.recoveryCounter = PH_PROTO_7816_VALUE_ZERO;
1833   phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
1834   phNxpEseProto7816_3_Var.wtx_counter = PH_PROTO_7816_VALUE_ZERO;
1835   /* This update is helpful in-case a R-NACK is transmitted from the MW */
1836   phNxpEseProto7816_3_Var.lastSentNonErrorframeType = UNKNOWN;
1837   phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
1838   return ESESTATUS_SUCCESS;
1839 }
1840 
1841 /******************************************************************************
1842  * Function         phNxpEseProto7816_Reset
1843  *
1844  * Description      This function is used to reset the 7816 protocol stack
1845  *instance
1846  *
1847  * Returns          On success return true or else false.
1848  *
1849  ******************************************************************************/
phNxpEseProto7816_Reset(void)1850 ESESTATUS phNxpEseProto7816_Reset(void) {
1851   ESESTATUS status = ESESTATUS_FAILED;
1852   /* Resetting host protocol instance */
1853   phNxpEseProto7816_ResetProtoParams();
1854   if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1855     status = phNxpEseProto7816_HardReset();
1856     if (status == ESESTATUS_SUCCESS) {
1857       /* Updating the ATR information(IFS,..) to 7816 stack */
1858       phNxpEse_data atrRsp;
1859       phNxpEseProto7816_getAtr(&atrRsp);
1860       phNxpEse_free(atrRsp.p_data);
1861     }
1862   } else {
1863     /* Resynchronising ESE protocol instance */
1864     status = phNxpEseProto7816_RSync();
1865   }
1866   return status;
1867 }
1868 
1869 /******************************************************************************
1870  * Function         phNxpEseProto7816_Open
1871  *
1872  * Description      This function is used to open the 7816 protocol stack
1873  *instance
1874  *
1875  * Returns          On success return true or else false.
1876  *
1877  ******************************************************************************/
phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam)1878 ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam) {
1879   ESESTATUS status = ESESTATUS_FAILED;
1880   status = phNxpEseProto7816_ResetProtoParams();
1881   ALOGD_IF(ese_debug_enabled, "%s: First open completed, Congratulations",
1882            __FUNCTION__);
1883   /* Update WTX max. limit */
1884   phNxpEseProto7816_3_Var.wtx_counter_limit = initParam.wtx_counter_limit;
1885   phNxpEseProto7816_3_Var.rnack_retry_limit = initParam.rnack_retry_limit;
1886   phNxpEseProto7816_3_Var.wtx_ntf_limit = initParam.wtx_ntf_limit;
1887   if (initParam.interfaceReset) /* Do interface reset */
1888   {
1889     status = phNxpEseProto7816_IntfReset(initParam.pSecureTimerParams);
1890     if (ESESTATUS_SUCCESS == status) {
1891       phNxpEse_memcpy(initParam.pSecureTimerParams,
1892                       &phNxpEseProto7816_3_Var.secureTimerParams,
1893                       sizeof(phNxpEseProto7816SecureTimer_t));
1894     }
1895   } else /* Initialisation condition to achieve usecases like JCOP download */
1896   {
1897     if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
1898       status = phNxpEseProto7816_HardReset();
1899       /* Updating the ATR information (Eg: IFS,..) to 7816 stack */
1900       if (status == ESESTATUS_SUCCESS) {
1901         phNxpEse_data atrRsp;
1902         phNxpEseProto7816_getAtr(&atrRsp);
1903         phNxpEse_free(atrRsp.p_data);
1904       }
1905     } else {
1906       status = phNxpEseProto7816_RSync();
1907     }
1908   }
1909   return status;
1910 }
1911 
1912 /******************************************************************************
1913  * Function         phNxpEseProto7816_Close
1914  *
1915  * Description      This function is used to close the 7816 protocol stack
1916  *instance
1917  *
1918  * Returns          On success return true or else false.
1919  *
1920  ******************************************************************************/
phNxpEseProto7816_Close(phNxpEseProto7816SecureTimer_t * pSecureTimerParams)1921 ESESTATUS phNxpEseProto7816_Close(
1922     phNxpEseProto7816SecureTimer_t* pSecureTimerParams) {
1923   ESESTATUS status = ESESTATUS_FAILED;
1924   if (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
1925       PH_NXP_ESE_PROTO_7816_IDLE)
1926     return status;
1927   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1928       PH_NXP_ESE_PROTO_7816_DEINIT;
1929   phNxpEseProto7816_3_Var.recoveryCounter = 0;
1930   phNxpEseProto7816_3_Var.wtx_counter = 0;
1931   /* send the end of session s-frame */
1932   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1933   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1934       PROP_END_APDU_REQ;
1935   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
1936       PH_PROTO_7816_VALUE_ZERO;
1937   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_EOS;
1938   status = TransceiveProcess();
1939   if (ESESTATUS_SUCCESS != status) {
1940     /* reset all the structures */
1941     ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
1942     if (status == ESESTATUS_TRANSCEIVE_FAILED &&
1943         phNxpEseProto7816_3_Var.atrInfo.len > PH_PROTO_7816_VALUE_ZERO) {
1944       if (phNxpEseProto7816_3_Var.atrInfo
1945               .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] <
1946           PH_SE_OS_VERSION_10) {
1947         ALOGD_IF(ese_debug_enabled, "%s shall trigger recovery", __FUNCTION__);
1948         status = ESESTATUS_RESPONSE_TIMEOUT;
1949       }
1950     }
1951   }
1952   phNxpEse_memcpy(pSecureTimerParams,
1953                   &phNxpEseProto7816_3_Var.secureTimerParams,
1954                   sizeof(phNxpEseProto7816SecureTimer_t));
1955   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1956       PH_NXP_ESE_PROTO_7816_IDLE;
1957   return status;
1958 }
1959 
1960 /******************************************************************************
1961  * Function         phNxpEseProto7816_CloseAllSessions
1962  *
1963  * Description      This function is used to close the 7816 protocol stack
1964  *instance
1965  *
1966  * Returns          On success return true or else false.
1967  *
1968  ******************************************************************************/
phNxpEseProto7816_CloseAllSessions(void)1969 ESESTATUS phNxpEseProto7816_CloseAllSessions(void) {
1970   ESESTATUS status = ESESTATUS_FAILED;
1971 
1972   /*Note:- Below OS version check using ATR shall
1973    * be removed while integrating with TEE/REE as ATR
1974    * information is not available in REE case*/
1975 
1976   if (phNxpEseProto7816_3_Var.atrInfo.vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN -
1977                                                1] >= PH_SE_OS_VERSION_10) {
1978     uint8_t* buffer = (uint8_t*)phNxpEse_memalloc(sizeof(uint8_t));
1979     if (buffer != NULL) {
1980       buffer[PH_PROTO_7816_VALUE_ZERO] = PH_PROTO_CLOSE_ALL_SESSION_INF;
1981       /* send the end of session s-frame */
1982       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
1983       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
1984           PROP_END_APDU_REQ;
1985       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data = buffer;
1986       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
1987           PH_PROTO_CLOSE_ALL_SESSION_LEN;
1988       phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
1989           SEND_S_EOS;
1990       status = TransceiveProcess();
1991       if (ESESTATUS_FAILED == status) {
1992         /* reset all the structures */
1993         ALOGD_IF(ese_debug_enabled, "%s EndOfSession failed ", __FUNCTION__);
1994       }
1995       phNxpEse_free(buffer);
1996       phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
1997           PH_NXP_ESE_PROTO_7816_IDLE;
1998     }
1999   } else {
2000     ALOGD_IF(ese_debug_enabled, "%s Function not supported ", __FUNCTION__);
2001     status = ESESTATUS_SUCCESS;
2002   }
2003   return status;
2004 }
2005 
2006 /******************************************************************************
2007  * Function         phNxpEseProto7816_IntfReset
2008  *
2009  * Description      This function is used to reset just the current interface
2010  *
2011  * Returns          On success return true or else false.
2012  *
2013  ******************************************************************************/
phNxpEseProto7816_IntfReset(phNxpEseProto7816SecureTimer_t * pSecureTimerParam)2014 ESESTATUS phNxpEseProto7816_IntfReset(
2015     phNxpEseProto7816SecureTimer_t* pSecureTimerParam) {
2016   ESESTATUS status = ESESTATUS_FAILED;
2017   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
2018   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2019       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2020   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2021   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
2022       INTF_RESET_REQ;
2023   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
2024       SEND_S_INTF_RST;
2025   status = TransceiveProcess();
2026   if (ESESTATUS_FAILED == status) {
2027     /* reset all the structures */
2028     ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
2029   }
2030   phNxpEse_memcpy(pSecureTimerParam, &phNxpEseProto7816_3_Var.secureTimerParams,
2031                   sizeof(phNxpEseProto7816SecureTimer_t));
2032   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2033       PH_NXP_ESE_PROTO_7816_IDLE;
2034   ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
2035   return status;
2036 }
2037 
2038 /******************************************************************************
2039  * Function         phNxpEseProto7816_SetIfs
2040  *
2041  * Description      This function is used to set IFSD value to card
2042  *
2043  * Returns          On success return true or else false.
2044  *
2045  ******************************************************************************/
phNxpEseProto7816_SetIfs(uint16_t IFS_Size)2046 ESESTATUS phNxpEseProto7816_SetIfs(uint16_t IFS_Size) {
2047   // phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
2048   // IFSC_Size;
2049   ESESTATUS status = ESESTATUS_FAILED;
2050   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
2051   /* IFSD > IFSC not allowed, card will reject by R-NACK so not sending */
2052   if (IFS_Size >
2053       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC) {
2054     phNxpEseProto7816_3_Var.currentIFSDSize =
2055         phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC;
2056     /* IFSD is greater than IFSC , set max IFSC as IFSD*/
2057     ALOGD_IF(ese_debug_enabled,
2058              "%s : IFSD greater than IFSC ,  set max IFSC as IFSD  ",
2059              __FUNCTION__);
2060   } else {
2061     phNxpEseProto7816_3_Var.currentIFSDSize = IFS_Size;
2062   }
2063   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2064       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2065   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2066   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = IFS_REQ;
2067   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
2068       SEND_S_IFS_ADJ;
2069   status = TransceiveProcess();
2070   if (ESESTATUS_FAILED == status) {
2071     /* reset all the structures */
2072     ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
2073   }
2074   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2075       PH_NXP_ESE_PROTO_7816_IDLE;
2076   ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
2077   return status;
2078 }
2079 
2080 /******************************************************************************
2081  * Function         phNxpEseProto7816_GetIfs
2082  *
2083  * Description      This function is used to get current IFS adjusted value wrt
2084  *card
2085  *
2086  * Returns          On success return true or else false.
2087  *
2088  ******************************************************************************/
phNxpEseProto7816_GetIfs(void)2089 uint16_t phNxpEseProto7816_GetIfs(void) {
2090   ALOGD_IF(
2091       ese_debug_enabled, "Enter %s current IFSC = %d", __FUNCTION__,
2092       phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS);
2093   return phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
2094       .currentDataLenIFS;
2095 }
2096 
2097 /******************************************************************************
2098  * Function         phNxpEseProto7816_GetOsMode
2099  *
2100  * Description      This function is used to get current OS Mode
2101  *
2102  * Returns          0x01 : JCOP_MODE
2103  *                  0x02 : OSU_MODE
2104  *
2105  ******************************************************************************/
phNxpEseProto7816_GetOsMode(void)2106 phNxpEseProto7816_OsType_t phNxpEseProto7816_GetOsMode(void) {
2107   phNxpEseProto7816_OsType_t mode = UNKNOWN_MODE;
2108   if (GET_CHIP_OS_VERSION() >= OS_VERSION_5_2_2) {
2109     if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_JCOP) {
2110       ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
2111                "JCOP Mode");
2112       mode = JCOP_MODE;
2113     } else if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_OSU) {
2114       ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
2115                "OSU Mode");
2116       mode = OSU_MODE;
2117     } else {
2118       ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
2119                "UNKNOWN Mode");
2120       mode = UNKNOWN_MODE;
2121     }
2122   } else {
2123     ALOGE("%s function not supported", __FUNCTION__);
2124   }
2125   return mode;
2126 }
2127 
2128 /******************************************************************************
2129  * Function         phNxpEseProto7816_getAtr
2130  *
2131  * Description      This function is used to get the ATR data from ESE
2132  *
2133  * Returns          On success return true or else false
2134  *
2135  ******************************************************************************/
phNxpEseProto7816_getAtr(phNxpEse_data * pATRRsp)2136 ESESTATUS phNxpEseProto7816_getAtr(phNxpEse_data* pATRRsp) {
2137   ESESTATUS status = ESESTATUS_FAILED;
2138 
2139   ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
2140   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2141       PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
2142   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
2143 
2144   phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = ATR_REQ;
2145   phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
2146       SEND_S_ATR_REQ;
2147   status = TransceiveProcess();
2148   if (ESESTATUS_FAILED == status) {
2149     /* reset all the structures */
2150     ALOGD_IF(ese_debug_enabled, "%s TransceiveProcess failed ", __FUNCTION__);
2151   }
2152 
2153   status = phNxpEse_GetData(&(pATRRsp->len), &(pATRRsp->p_data));
2154   if (ESESTATUS_SUCCESS == status) {
2155     ALOGD_IF(ese_debug_enabled,
2156              "%s Data successfully received at 7816, packaging to "
2157              "send upper layers: DataLen = %d",
2158              __FUNCTION__, pATRRsp->len);
2159   } else
2160     status = ESESTATUS_FAILED;
2161   phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
2162       PH_NXP_ESE_PROTO_7816_IDLE;
2163   ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
2164   return status;
2165 }
2166 
2167 /******************************************************************************
2168  * Function         phNxpEseProto7816_SetEndPoint
2169  *
2170  * Description      This function is used to set end point protocol context
2171  *
2172  * Returns          Always return TRUE (1).
2173  *
2174  ******************************************************************************/
phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint)2175 ESESTATUS phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint) {
2176   ESESTATUS status = ESESTATUS_FAILED;
2177   if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
2178     phNxpEseProto7816_3_Var = phNxpEseProto7816_ptr[uEndPoint];
2179     status = ESESTATUS_SUCCESS;
2180   } else {
2181     /*Do nothing return fail*/
2182   }
2183   return status;
2184 }
2185 
2186 /******************************************************************************
2187  * Function         phNxpEseProto7816_ResetEndPoint
2188  *
2189  * Description      This function is used to set end point protocol context
2190  *
2191  * Returns          Always return TRUE (1).
2192  *
2193  ******************************************************************************/
phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint)2194 ESESTATUS phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint) {
2195   ESESTATUS status = ESESTATUS_FAILED;
2196   if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
2197     phNxpEseProto7816_ptr[uEndPoint] = phNxpEseProto7816_3_Var;
2198     status = ESESTATUS_SUCCESS;
2199   } else {
2200     /*Do nothing return fail*/
2201   }
2202   return status;
2203 }
2204 
2205 /******************************************************************************
2206  * Function         phNxpEseProto7816_ResendLastSFrameReq
2207  *
2208  * Description      This function is used to Resend S-Frame on receiving
2209  *                  non S-Frame response
2210  *
2211  * Returns          If last sent Frame is S-Frame
2212  *                  return TRUE(S-Frame) otherwise FALSE(Non-S-Frame).
2213  *
2214  ******************************************************************************/
phNxpEseProto7816_ResendLastSFrameReq(void)2215 static bool phNxpEseProto7816_ResendLastSFrameReq(void) {
2216   bool isLastSFrameReq = false;
2217   if (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == SFRAME &&
2218       WTX_RSP !=
2219           phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) {
2220     ALOGD_IF(ese_debug_enabled,
2221              "%s Unexpected Frame, re-transmitting the previous S-frame",
2222              __FUNCTION__);
2223     phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
2224                     &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
2225                     sizeof(phNxpEseProto7816_NextTx_Info_t));
2226     isLastSFrameReq = true;
2227   }
2228   return isLastSFrameReq;
2229 }
2230 
2231 /** @} */
2232