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