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