1 /****************************************************************************** 2 * 3 * Copyright 2018 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 extern bool ese_debug_enabled; 23 24 /****************************************************************************** 25 \section Introduction Introduction 26 27 * This module provide the 7816-3 protocol level implementation for ESE 28 * 29 ******************************************************************************/ 30 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void); 31 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len, 32 uint8_t* p_data); 33 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len, 34 uint8_t** pp_data); 35 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff, 36 uint32_t offset, uint32_t length); 37 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len, uint8_t* p_data); 38 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData); 39 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData); 40 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType); 41 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void); 42 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void); 43 static ESESTATUS phNxpEseProro7816_SaveIframeData(uint8_t* p_data, 44 uint32_t data_len); 45 static ESESTATUS phNxpEseProto7816_ResetRecovery(void); 46 static ESESTATUS phNxpEseProto7816_RecoverySteps(void); 47 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data, 48 uint32_t data_len); 49 static ESESTATUS phNxpEseProto7816_ProcessResponse(void); 50 static ESESTATUS TransceiveProcess(void); 51 static ESESTATUS phNxpEseProto7816_RSync(void); 52 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void); 53 54 /****************************************************************************** 55 * Function phNxpEseProto7816_SendRawFrame 56 * 57 * Description This internal function is called send the data to ESE 58 * 59 * Returns On success return true or else false. 60 * 61 ******************************************************************************/ 62 static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len, 63 uint8_t* p_data) { 64 ESESTATUS status = ESESTATUS_FAILED; 65 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 66 status = phNxpEse_WriteFrame(data_len, p_data); 67 if (ESESTATUS_SUCCESS != status) { 68 ALOGE("%s Error phNxpEse_WriteFrame\n", __FUNCTION__); 69 } else { 70 ALOGD_IF(ese_debug_enabled, "%s phNxpEse_WriteFrame Success \n", 71 __FUNCTION__); 72 } 73 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 74 return status; 75 } 76 77 /****************************************************************************** 78 * Function phNxpEseProto7816_GetRawFrame 79 * 80 * Description This internal function is called read the data from the ESE 81 * 82 * Returns On success return true or else false. 83 * 84 ******************************************************************************/ 85 static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len, 86 uint8_t** pp_data) { 87 ESESTATUS status = ESESTATUS_FAILED; 88 89 status = phNxpEse_read(data_len, pp_data); 90 if (ESESTATUS_SUCCESS != status) { 91 ALOGE("%s phNxpEse_read failed , status : 0x%x", __FUNCTION__, status); 92 } 93 return status; 94 } 95 96 /****************************************************************************** 97 * Function phNxpEseProto7816_ComputeLRC 98 * 99 * Description This internal function is called compute the LRC 100 * 101 * Returns On success return true or else false. 102 * 103 ******************************************************************************/ 104 static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff, 105 uint32_t offset, uint32_t length) { 106 uint32_t LRC = 0, i = 0; 107 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 108 for (i = offset; i < length; i++) { 109 LRC = LRC ^ p_buff[i]; 110 } 111 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 112 return (uint8_t)LRC; 113 } 114 115 /****************************************************************************** 116 * Function phNxpEseProto7816_CheckLRC 117 * 118 * Description This internal function is called compute and compare the 119 * received LRC of the received data 120 * 121 * Returns On success return true or else false. 122 * 123 ******************************************************************************/ 124 static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len, 125 uint8_t* p_data) { 126 ESESTATUS status = ESESTATUS_SUCCESS; 127 uint8_t calc_crc = 0; 128 uint8_t recv_crc = 0; 129 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 130 recv_crc = p_data[data_len - 1]; 131 132 /* calculate the CRC after excluding CRC */ 133 calc_crc = phNxpEseProto7816_ComputeLRC(p_data, 1, (data_len - 1)); 134 ALOGD_IF(ese_debug_enabled, "Received LRC:0x%x Calculated LRC:0x%x", recv_crc, 135 calc_crc); 136 if (recv_crc != calc_crc) { 137 status = ESESTATUS_FAILED; 138 ALOGE("%s LRC failed", __FUNCTION__); 139 } 140 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 141 return status; 142 } 143 144 /****************************************************************************** 145 * Function phNxpEseProto7816_SendSFrame 146 * 147 * Description This internal function is called to send S-frame with all 148 * updated 7816-3 headers 149 * 150 * Returns On success return true or else false. 151 * 152 ******************************************************************************/ 153 static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData) { 154 ESESTATUS status = ESESTATUS_FAILED; 155 uint32_t frame_len = 0; 156 uint8_t* p_framebuff = NULL; 157 uint8_t pcb_byte = 0; 158 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 159 sFrameInfo_t sframeData = sFrameData; 160 /* This update is helpful in-case a R-NACK is transmitted from the MW */ 161 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = SFRAME; 162 switch (sframeData.sFrameType) { 163 case RESYNCH_REQ: 164 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN); 165 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t)); 166 if (NULL == p_framebuff) { 167 return ESESTATUS_FAILED; 168 } 169 p_framebuff[2] = 0; 170 p_framebuff[3] = 0x00; 171 172 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */ 173 pcb_byte |= PH_PROTO_7816_S_RESYNCH; 174 break; 175 case INTF_RESET_REQ: 176 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN); 177 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t)); 178 if (NULL == p_framebuff) { 179 return ESESTATUS_FAILED; 180 } 181 p_framebuff[2] = 0; 182 p_framebuff[3] = 0x00; 183 184 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */ 185 pcb_byte |= PH_PROTO_7816_S_RESET; 186 break; 187 case PROP_END_APDU_REQ: 188 frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN); 189 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t)); 190 if (NULL == p_framebuff) { 191 return ESESTATUS_FAILED; 192 } 193 p_framebuff[2] = 0; 194 p_framebuff[3] = 0x00; 195 196 pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */ 197 pcb_byte |= PH_PROTO_7816_S_END_OF_APDU; 198 break; 199 case WTX_RSP: 200 frame_len = (PH_PROTO_7816_HEADER_LEN + 1 + PH_PROTO_7816_CRC_LEN); 201 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t)); 202 if (NULL == p_framebuff) { 203 return ESESTATUS_FAILED; 204 } 205 p_framebuff[2] = 0x01; 206 p_framebuff[3] = 0x01; 207 208 pcb_byte |= PH_PROTO_7816_S_BLOCK_RSP; 209 pcb_byte |= PH_PROTO_7816_S_WTX; 210 break; 211 default: 212 ALOGE("Invalid S-block"); 213 break; 214 } 215 if (NULL != p_framebuff) { 216 /* frame the packet */ 217 p_framebuff[0] = 0x00; /* NAD Byte */ 218 p_framebuff[1] = pcb_byte; /* PCB */ 219 220 p_framebuff[frame_len - 1] = 221 phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1)); 222 ALOGD_IF(ese_debug_enabled, "S-Frame PCB: %x\n", p_framebuff[1]); 223 status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff); 224 phNxpEse_free(p_framebuff); 225 } else { 226 ALOGE("Invalid S-block or malloc for s-block failed"); 227 } 228 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 229 return status; 230 } 231 232 /****************************************************************************** 233 * Function phNxpEseProto7816_sendRframe 234 * 235 * Description This internal function is called to send R-frame with all 236 * updated 7816-3 headers 237 * 238 * Returns On success return true or else false. 239 * 240 ******************************************************************************/ 241 static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType) { 242 ESESTATUS status = ESESTATUS_FAILED; 243 uint8_t recv_ack[4] = {0x00, 0x80, 0x00, 0x00}; 244 if (RNACK == rFrameType) /* R-NACK */ 245 { 246 recv_ack[1] = 0x82; 247 } else /* R-ACK*/ 248 { 249 /* This update is helpful in-case a R-NACK is transmitted from the MW */ 250 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = RFRAME; 251 } 252 recv_ack[1] |= 253 ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo ^ 1) 254 << 4); 255 ALOGD_IF(ese_debug_enabled, "%s recv_ack[1]:0x%x", __FUNCTION__, recv_ack[1]); 256 recv_ack[3] = 257 phNxpEseProto7816_ComputeLRC(recv_ack, 0x00, (sizeof(recv_ack) - 1)); 258 status = phNxpEseProto7816_SendRawFrame(sizeof(recv_ack), recv_ack); 259 return status; 260 } 261 262 /****************************************************************************** 263 * Function phNxpEseProto7816_SendIframe 264 * 265 * Description This internal function is called to send I-frame with all 266 * updated 7816-3 headers 267 * 268 * Returns On success return true or else false. 269 * 270 ******************************************************************************/ 271 static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData) { 272 ESESTATUS status = ESESTATUS_FAILED; 273 uint32_t frame_len = 0; 274 uint8_t* p_framebuff = NULL; 275 uint8_t pcb_byte = 0; 276 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 277 if (0 == iFrameData.sendDataLen) { 278 ALOGE("I frame Len is 0, INVALID"); 279 return ESESTATUS_FAILED; 280 } 281 /* This update is helpful in-case a R-NACK is transmitted from the MW */ 282 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = IFRAME; 283 frame_len = (iFrameData.sendDataLen + PH_PROTO_7816_HEADER_LEN + 284 PH_PROTO_7816_CRC_LEN); 285 286 p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t)); 287 if (NULL == p_framebuff) { 288 ALOGE("Heap allocation failed"); 289 return ESESTATUS_FAILED; 290 } 291 292 /* frame the packet */ 293 p_framebuff[0] = 0x00; /* NAD Byte */ 294 295 if (iFrameData.isChained) { 296 /* make B6 (M) bit high */ 297 pcb_byte |= PH_PROTO_7816_CHAINING; 298 } 299 300 /* Update the send seq no */ 301 pcb_byte |= 302 (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo << 6); 303 304 /* store the pcb byte */ 305 p_framebuff[1] = pcb_byte; 306 /* store I frame length */ 307 p_framebuff[2] = iFrameData.sendDataLen; 308 /* store I frame */ 309 phNxpEse_memcpy(&(p_framebuff[3]), iFrameData.p_data + iFrameData.dataOffset, 310 iFrameData.sendDataLen); 311 312 p_framebuff[frame_len - 1] = 313 phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1)); 314 315 status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff); 316 317 phNxpEse_free(p_framebuff); 318 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 319 return status; 320 } 321 322 /****************************************************************************** 323 * Function phNxpEseProto7816_SetNextIframeContxt 324 * 325 * Description This internal function is called to set the context for next 326 *I-frame. 327 * Not applicable for the first I-frame of the transceive 328 * 329 * Returns On success return true or else false. 330 * 331 ******************************************************************************/ 332 static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void) { 333 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 334 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset = 0; 335 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME; 336 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo = 337 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1; 338 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME; 339 if (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen > 340 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen) { 341 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true; 342 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen = 343 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen; 344 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen = 345 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen - 346 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen; 347 } else { 348 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen = 349 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen; 350 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false; 351 } 352 ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d Seq. no:%d", 353 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen, 354 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo); 355 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 356 return ESESTATUS_SUCCESS; 357 } 358 359 /****************************************************************************** 360 * Function phNxpEseProto7816_SetNextIframeContxt 361 * 362 * Description This internal function is called to set the context for next 363 *I-frame. 364 * Not applicable for the first I-frame of the transceive 365 * 366 * Returns On success return true or else false. 367 * 368 ******************************************************************************/ 369 static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void) { 370 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 371 /* Expecting to reach here only after first of chained I-frame is sent and 372 * before the last chained is sent */ 373 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME; 374 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME; 375 376 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo = 377 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1; 378 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset = 379 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.dataOffset + 380 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen; 381 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = 382 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data; 383 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen = 384 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen; 385 386 // if chained 387 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen > 388 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen) { 389 ALOGD_IF(ese_debug_enabled, "Process Chained Frame"); 390 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true; 391 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen = 392 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen; 393 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen = 394 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen - 395 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen; 396 } else { 397 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false; 398 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen = 399 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen; 400 } 401 ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d", 402 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen); 403 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 404 return ESESTATUS_SUCCESS; 405 } 406 407 /****************************************************************************** 408 * Function phNxpEseProto7816_ResetRecovery 409 * 410 * Description This internal function is called to do reset the recovery 411 *pareameters 412 * 413 * Returns On success return true or else false. 414 * 415 ******************************************************************************/ 416 static ESESTATUS phNxpEseProro7816_SaveIframeData(uint8_t* p_data, 417 uint32_t data_len) { 418 ESESTATUS status = ESESTATUS_FAILED; 419 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 420 ALOGD_IF(ese_debug_enabled, "Data[0]=0x%x len=%d Data[%d]=0x%x", p_data[0], 421 data_len, data_len - 1, p_data[data_len - 1]); 422 if (ESESTATUS_SUCCESS != phNxpEse_StoreDatainList(data_len, p_data)) { 423 ALOGE("%s - Error storing chained data in list", __FUNCTION__); 424 } else { 425 status = ESESTATUS_SUCCESS; 426 } 427 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 428 return status; 429 } 430 431 /****************************************************************************** 432 * Function phNxpEseProto7816_ResetRecovery 433 * 434 * Description This internal function is called to do reset the recovery 435 *pareameters 436 * 437 * Returns On success return true or else false. 438 * 439 ******************************************************************************/ 440 static ESESTATUS phNxpEseProto7816_ResetRecovery(void) { 441 phNxpEseProto7816_3_Var.recoveryCounter = 0; 442 return ESESTATUS_SUCCESS; 443 } 444 445 /****************************************************************************** 446 * Function phNxpEseProto7816_RecoverySteps 447 * 448 * Description This internal function is called when 7816-3 stack failed to 449 *recover 450 * after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has 451 *to be 452 * recovered 453 * Returns On success return true or else false. 454 * 455 ******************************************************************************/ 456 static ESESTATUS phNxpEseProto7816_RecoverySteps(void) { 457 if (phNxpEseProto7816_3_Var.recoveryCounter <= 458 PH_PROTO_7816_FRAME_RETRY_COUNT) { 459 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 460 INTF_RESET_REQ; 461 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 462 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 463 INTF_RESET_REQ; 464 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 465 SEND_S_INTF_RST; 466 } else { /* If recovery fails */ 467 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE; 468 } 469 return ESESTATUS_SUCCESS; 470 } 471 472 /****************************************************************************** 473 * Function phNxpEseProto7816_DecodeSecureTimer 474 * 475 * Description This internal function is to decode the secure timer. 476 * value from the payload 477 * Returns void 478 * 479 ******************************************************************************/ 480 static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset, 481 unsigned int* secureTimer, 482 uint8_t* p_data) { 483 uint8_t byteCounter = 0; 484 uint8_t dataLength = p_data[++(*frameOffset)]; /* To get the L of TLV */ 485 if (dataLength > 0) { 486 /* V of TLV: Retrieve each byte(4 byte) and push it to get the secure timer 487 * value (unsigned long) */ 488 for (byteCounter = 1; byteCounter <= dataLength; byteCounter++) { 489 (*frameOffset)++; 490 *secureTimer = (*secureTimer) << 8; 491 *secureTimer |= p_data[(*frameOffset)]; 492 } 493 } else { 494 (*frameOffset)++; /* Goto the end of current marker if length is zero */ 495 } 496 return; 497 } 498 499 /****************************************************************************** 500 * Function phNxpEseProto7816_DecodeSFrameData 501 * 502 * Description This internal function is to decode S-frame payload. 503 * Returns void 504 * 505 ******************************************************************************/ 506 static void phNxpEseProto7816_DecodeSFrameData(uint8_t* p_data) { 507 uint8_t maxSframeLen = 0, dataType = 0, frameOffset = 0; 508 frameOffset = PH_PROPTO_7816_FRAME_LENGTH_OFFSET; 509 maxSframeLen = 510 p_data[frameOffset] + 511 frameOffset; /* to be in sync with offset which starts from index 0 */ 512 while (maxSframeLen > frameOffset) { 513 frameOffset += 1; /* To get the Type (TLV) */ 514 dataType = p_data[frameOffset]; 515 ALOGD_IF(ese_debug_enabled, "%s frameoffset=%d value=0x%x\n", __FUNCTION__, 516 frameOffset, p_data[frameOffset]); 517 switch (dataType) /* Type (TLV) */ 518 { 519 case PH_PROPTO_7816_SFRAME_TIMER1: 520 phNxpEseProto7816_DecodeSecureTimer( 521 &frameOffset, 522 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1, p_data); 523 break; 524 case PH_PROPTO_7816_SFRAME_TIMER2: 525 phNxpEseProto7816_DecodeSecureTimer( 526 &frameOffset, 527 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2, p_data); 528 break; 529 case PH_PROPTO_7816_SFRAME_TIMER3: 530 phNxpEseProto7816_DecodeSecureTimer( 531 &frameOffset, 532 &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3, p_data); 533 break; 534 default: 535 frameOffset += 536 p_data[frameOffset + 1]; /* Goto the end of current marker */ 537 break; 538 } 539 } 540 ALOGD_IF(ese_debug_enabled, "secure timer t1 = 0x%x t2 = 0x%x t3 = 0x%x", 541 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1, 542 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2, 543 phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3); 544 return; 545 } 546 547 /****************************************************************************** 548 * Function phNxpEseProto7816_DecodeFrame 549 * 550 * Description This internal function is used to 551 * 1. Identify the received frame 552 * 2. If the received frame is I-frame with expected sequence 553 number, store it or else send R-NACK 554 3. If the received frame is R-frame, 555 3.1 R-ACK with expected seq. number: Send the next 556 chained I-frame 557 3.2 R-ACK with different sequence number: Sebd the R-Nack 558 3.3 R-NACK: Re-send the last frame 559 4. If the received frame is S-frame, send back the correct 560 S-frame response. 561 * Returns On success return true or else false. 562 * 563 ******************************************************************************/ 564 static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data, 565 uint32_t data_len) { 566 ESESTATUS status = ESESTATUS_SUCCESS; 567 uint8_t pcb; 568 phNxpEseProto7816_PCB_bits_t pcb_bits; 569 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 570 ALOGD_IF(ese_debug_enabled, "Retry Counter = %d\n", 571 phNxpEseProto7816_3_Var.recoveryCounter); 572 pcb = p_data[PH_PROPTO_7816_PCB_OFFSET]; 573 // memset(&phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.rcvPcbBits, 0x00, 574 // sizeof(struct PCB_BITS)); 575 phNxpEse_memset(&pcb_bits, 0x00, sizeof(phNxpEseProto7816_PCB_bits_t)); 576 phNxpEse_memcpy(&pcb_bits, &pcb, sizeof(uint8_t)); 577 578 if (0x00 == pcb_bits.msb) /* I-FRAME decoded should come here */ 579 { 580 ALOGD_IF(ese_debug_enabled, "%s I-Frame Received", __FUNCTION__); 581 phNxpEseProto7816_3_Var.wtx_counter = 0; 582 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = IFRAME; 583 if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo != 584 pcb_bits.bit7) // != pcb_bits->bit7) 585 { 586 ALOGD_IF(ese_debug_enabled, "%s I-Frame lastRcvdIframeInfo.seqNo:0x%x", 587 __FUNCTION__, pcb_bits.bit7); 588 phNxpEseProto7816_ResetRecovery(); 589 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo = 0x00; 590 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo |= 591 pcb_bits.bit7; 592 593 if (pcb_bits.bit6) { 594 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained = 595 true; 596 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 597 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 598 NO_ERROR; 599 status = phNxpEseProro7816_SaveIframeData(&p_data[3], data_len - 4); 600 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 601 SEND_R_ACK; 602 } else { 603 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained = 604 false; 605 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 606 IDLE_STATE; 607 status = phNxpEseProro7816_SaveIframeData(&p_data[3], data_len - 4); 608 } 609 } else { 610 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 611 if (phNxpEseProto7816_3_Var.recoveryCounter < 612 PH_PROTO_7816_FRAME_RETRY_COUNT) { 613 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 614 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 615 OTHER_ERROR; 616 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 617 SEND_R_NACK; 618 phNxpEseProto7816_3_Var.recoveryCounter++; 619 } else { 620 phNxpEseProto7816_RecoverySteps(); 621 phNxpEseProto7816_3_Var.recoveryCounter++; 622 } 623 } 624 } else if ((0x01 == pcb_bits.msb) && 625 (0x00 == pcb_bits.bit7)) /* R-FRAME decoded should come here */ 626 { 627 ALOGD_IF(ese_debug_enabled, "%s R-Frame Received", __FUNCTION__); 628 phNxpEseProto7816_3_Var.wtx_counter = 0; 629 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = RFRAME; 630 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo = 631 0; // = 0; 632 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo |= 633 pcb_bits.bit5; 634 635 if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x00)) { 636 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode = 637 NO_ERROR; 638 phNxpEseProto7816_ResetRecovery(); 639 if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo != 640 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) { 641 status = phNxpEseProto7816_SetNextIframeContxt(); 642 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 643 SEND_IFRAME; 644 } else { 645 // error handling. 646 } 647 } /* Error handling 1 : Parity error */ 648 else if (((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) || 649 /* Error handling 2: Other indicated error */ 650 ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01))) { 651 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 652 if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) 653 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode = 654 OTHER_ERROR; 655 else 656 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode = 657 PARITY_ERROR; 658 if (phNxpEseProto7816_3_Var.recoveryCounter < 659 PH_PROTO_7816_FRAME_RETRY_COUNT) { 660 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == IFRAME) { 661 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx, 662 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx, 663 sizeof(phNxpEseProto7816_NextTx_Info_t)); 664 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 665 SEND_IFRAME; 666 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME; 667 } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == 668 RFRAME) { 669 /* Usecase to reach the below case: 670 I-frame sent first, followed by R-NACK and we receive a R-NACK with 671 last sent I-frame sequence number*/ 672 if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo 673 .seqNo == 674 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) && 675 (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == IFRAME)) { 676 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx, 677 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx, 678 sizeof(phNxpEseProto7816_NextTx_Info_t)); 679 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 680 SEND_IFRAME; 681 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME; 682 } 683 /* Usecase to reach the below case: 684 R-frame sent first, followed by R-NACK and we receive a R-NACK with 685 next expected I-frame sequence number*/ 686 else if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo 687 .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx 688 .IframeInfo.seqNo) && 689 (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == 690 RFRAME)) { 691 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 692 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 693 NO_ERROR; 694 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 695 SEND_R_ACK; 696 } 697 /* Usecase to reach the below case: 698 I-frame sent first, followed by R-NACK and we receive a R-NACK with 699 next expected I-frame sequence number + all the other unexpected 700 scenarios */ 701 else { 702 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 703 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 704 OTHER_ERROR; 705 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 706 SEND_R_NACK; 707 } 708 } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == 709 SFRAME) { 710 /* Copy the last S frame sent */ 711 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx, 712 &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx, 713 sizeof(phNxpEseProto7816_NextTx_Info_t)); 714 } 715 phNxpEseProto7816_3_Var.recoveryCounter++; 716 } else { 717 phNxpEseProto7816_RecoverySteps(); 718 phNxpEseProto7816_3_Var.recoveryCounter++; 719 } 720 // resend previously send I frame 721 } 722 /* Error handling 3 */ 723 else if ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x01)) { 724 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 725 if (phNxpEseProto7816_3_Var.recoveryCounter < 726 PH_PROTO_7816_FRAME_RETRY_COUNT) { 727 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode = 728 SOF_MISSED_ERROR; 729 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx = 730 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx; 731 phNxpEseProto7816_3_Var.recoveryCounter++; 732 } else { 733 phNxpEseProto7816_RecoverySteps(); 734 phNxpEseProto7816_3_Var.recoveryCounter++; 735 } 736 } else /* Error handling 4 */ 737 { 738 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 739 if (phNxpEseProto7816_3_Var.recoveryCounter < 740 PH_PROTO_7816_FRAME_RETRY_COUNT) { 741 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode = 742 UNDEFINED_ERROR; 743 phNxpEseProto7816_3_Var.recoveryCounter++; 744 } else { 745 phNxpEseProto7816_RecoverySteps(); 746 phNxpEseProto7816_3_Var.recoveryCounter++; 747 } 748 } 749 } else if ((0x01 == pcb_bits.msb) && 750 (0x01 == pcb_bits.bit7)) /* S-FRAME decoded should come here */ 751 { 752 ALOGD_IF(ese_debug_enabled, "%s S-Frame Received", __FUNCTION__); 753 int32_t frameType = (int32_t)(pcb & 0x3F); /*discard upper 2 bits */ 754 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME; 755 if (frameType != WTX_REQ) { 756 phNxpEseProto7816_3_Var.wtx_counter = 0; 757 } 758 switch (frameType) { 759 case RESYNCH_REQ: 760 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 761 RESYNCH_REQ; 762 break; 763 case RESYNCH_RSP: 764 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 765 RESYNCH_RSP; 766 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN; 767 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 768 IDLE_STATE; 769 break; 770 case IFSC_REQ: 771 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 772 IFSC_REQ; 773 break; 774 case IFSC_RES: 775 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 776 IFSC_RES; 777 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN; 778 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 779 IDLE_STATE; 780 break; 781 case ABORT_REQ: 782 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 783 ABORT_REQ; 784 break; 785 case ABORT_RES: 786 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 787 ABORT_RES; 788 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN; 789 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 790 IDLE_STATE; 791 break; 792 case WTX_REQ: 793 phNxpEseProto7816_3_Var.wtx_counter++; 794 ALOGD_IF(ese_debug_enabled, "%s Wtx_counter value - %lu", __FUNCTION__, 795 phNxpEseProto7816_3_Var.wtx_counter); 796 ALOGD_IF(ese_debug_enabled, "%s Wtx_counter wtx_counter_limit - %lu", 797 __FUNCTION__, phNxpEseProto7816_3_Var.wtx_counter_limit); 798 /* Previous sent frame is some S-frame but not WTX response S-frame */ 799 if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType != 800 WTX_RSP && 801 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == 802 SFRAME) { /* Goto recovery if it keep coming here for more than 803 recovery counter max. value */ 804 if (phNxpEseProto7816_3_Var.recoveryCounter < 805 PH_PROTO_7816_FRAME_RETRY_COUNT) { /* Re-transmitting the previous 806 sent S-frame */ 807 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx = 808 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx; 809 phNxpEseProto7816_3_Var.recoveryCounter++; 810 } else { 811 phNxpEseProto7816_RecoverySteps(); 812 phNxpEseProto7816_3_Var.recoveryCounter++; 813 } 814 } else { /* Checking for WTX counter with max. allowed WTX count */ 815 if (phNxpEseProto7816_3_Var.wtx_counter == 816 phNxpEseProto7816_3_Var.wtx_counter_limit) { 817 phNxpEseProto7816_3_Var.wtx_counter = 0; 818 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo 819 .sFrameType = INTF_RESET_REQ; 820 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 821 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 822 INTF_RESET_REQ; 823 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 824 SEND_S_INTF_RST; 825 ALOGE("%s Interface Reset to eSE wtx count reached!!!", 826 __FUNCTION__); 827 } else { 828 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 829 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo 830 .sFrameType = WTX_REQ; 831 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 832 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 833 WTX_RSP; 834 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 835 SEND_S_WTX_RSP; 836 } 837 } 838 break; 839 case WTX_RSP: 840 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 841 WTX_RSP; 842 break; 843 case INTF_RESET_REQ: 844 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 845 INTF_RESET_REQ; 846 break; 847 case INTF_RESET_RSP: 848 phNxpEseProto7816_ResetProtoParams(); 849 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 850 INTF_RESET_RSP; 851 if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) 852 phNxpEseProto7816_DecodeSFrameData(p_data); 853 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN; 854 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 855 IDLE_STATE; 856 break; 857 case PROP_END_APDU_REQ: 858 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 859 PROP_END_APDU_REQ; 860 break; 861 case PROP_END_APDU_RSP: 862 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = 863 PROP_END_APDU_RSP; 864 if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) 865 phNxpEseProto7816_DecodeSFrameData(p_data); 866 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN; 867 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 868 IDLE_STATE; 869 break; 870 default: 871 ALOGE("%s Wrong S-Frame Received", __FUNCTION__); 872 break; 873 } 874 } else { 875 ALOGE("%s Wrong-Frame Received", __FUNCTION__); 876 } 877 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 878 return status; 879 } 880 881 /****************************************************************************** 882 * Function phNxpEseProto7816_ProcessResponse 883 * 884 * Description This internal function is used to 885 * 1. Check the LRC 886 * 2. Initiate decoding of received frame of data. 887 * Returns On success return true or else false. 888 * 889 ******************************************************************************/ 890 static ESESTATUS phNxpEseProto7816_ProcessResponse(void) { 891 uint32_t data_len = 0; 892 uint8_t* p_data = NULL; 893 ESESTATUS status = ESESTATUS_FAILED; 894 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 895 status = phNxpEseProto7816_GetRawFrame(&data_len, &p_data); 896 ALOGD_IF(ese_debug_enabled, "%s p_data ----> %p len ----> 0x%x", __FUNCTION__, 897 p_data, data_len); 898 if (ESESTATUS_SUCCESS == status) { 899 /* Resetting the timeout counter */ 900 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO; 901 /* LRC check followed */ 902 status = phNxpEseProto7816_CheckLRC(data_len, p_data); 903 if (status == ESESTATUS_SUCCESS) { 904 /* Resetting the RNACK retry counter */ 905 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO; 906 phNxpEseProto7816_DecodeFrame(p_data, data_len); 907 } else { 908 ALOGE("%s LRC Check failed", __FUNCTION__); 909 if (phNxpEseProto7816_3_Var.rnack_retry_counter < 910 phNxpEseProto7816_3_Var.rnack_retry_limit) { 911 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID; 912 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 913 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 914 PARITY_ERROR; 915 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo = 916 (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo) 917 << 4; 918 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 919 SEND_R_NACK; 920 phNxpEseProto7816_3_Var.rnack_retry_counter++; 921 } else { 922 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO; 923 /* Re-transmission failed completely, Going to exit */ 924 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 925 IDLE_STATE; 926 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO; 927 } 928 } 929 } else { 930 ALOGE("%s phNxpEseProto7816_GetRawFrame failed", __FUNCTION__); 931 if ((SFRAME == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType) && 932 ((WTX_RSP == 933 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) || 934 (RESYNCH_RSP == 935 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType))) { 936 if (phNxpEseProto7816_3_Var.rnack_retry_counter < 937 phNxpEseProto7816_3_Var.rnack_retry_limit) { 938 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID; 939 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME; 940 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode = 941 OTHER_ERROR; 942 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo = 943 (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo) 944 << 4; 945 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 946 SEND_R_NACK; 947 phNxpEseProto7816_3_Var.rnack_retry_counter++; 948 } else { 949 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO; 950 /* Re-transmission failed completely, Going to exit */ 951 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 952 IDLE_STATE; 953 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO; 954 } 955 } else { 956 phNxpEse_Sleep(DELAY_ERROR_RECOVERY); 957 /* re transmit the frame */ 958 if (phNxpEseProto7816_3_Var.timeoutCounter < 959 PH_PROTO_7816_TIMEOUT_RETRY_COUNT) { 960 phNxpEseProto7816_3_Var.timeoutCounter++; 961 ALOGE("%s re-transmitting the previous frame", __FUNCTION__); 962 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx = 963 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx; 964 } else { 965 /* Re-transmission failed completely, Going to exit */ 966 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 967 IDLE_STATE; 968 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO; 969 ALOGE("%s calling phNxpEse_StoreDatainList", __FUNCTION__); 970 phNxpEse_StoreDatainList(data_len, p_data); 971 } 972 } 973 } 974 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status); 975 return status; 976 } 977 978 /****************************************************************************** 979 * Function TransceiveProcess 980 * 981 * Description This internal function is used to 982 * 1. Send the raw data received from application after 983 *computing LRC 984 * 2. Receive the the response data from ESE, decode, process 985 *and 986 * store the data. 987 * Returns On success return true or else false. 988 * 989 ******************************************************************************/ 990 static ESESTATUS TransceiveProcess(void) { 991 ESESTATUS status = ESESTATUS_FAILED; 992 sFrameInfo_t sFrameInfo; 993 994 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 995 while (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState != 996 IDLE_STATE) { 997 ALOGD_IF(ese_debug_enabled, "%s nextTransceiveState %x", __FUNCTION__, 998 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState); 999 switch (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState) { 1000 case SEND_IFRAME: 1001 status = phNxpEseProto7816_SendIframe( 1002 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo); 1003 break; 1004 case SEND_R_ACK: 1005 status = phNxpEseProto7816_sendRframe(RACK); 1006 break; 1007 case SEND_R_NACK: 1008 status = phNxpEseProto7816_sendRframe(RNACK); 1009 break; 1010 case SEND_S_RSYNC: 1011 sFrameInfo.sFrameType = RESYNCH_REQ; 1012 status = phNxpEseProto7816_SendSFrame(sFrameInfo); 1013 break; 1014 case SEND_S_INTF_RST: 1015 sFrameInfo.sFrameType = INTF_RESET_REQ; 1016 status = phNxpEseProto7816_SendSFrame(sFrameInfo); 1017 break; 1018 case SEND_S_EOS: 1019 sFrameInfo.sFrameType = PROP_END_APDU_REQ; 1020 status = phNxpEseProto7816_SendSFrame(sFrameInfo); 1021 break; 1022 case SEND_S_WTX_RSP: 1023 sFrameInfo.sFrameType = WTX_RSP; 1024 status = phNxpEseProto7816_SendSFrame(sFrameInfo); 1025 break; 1026 default: 1027 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 1028 IDLE_STATE; 1029 break; 1030 } 1031 if (ESESTATUS_SUCCESS == status) { 1032 phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx, 1033 &phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx, 1034 sizeof(phNxpEseProto7816_NextTx_Info_t)); 1035 status = phNxpEseProto7816_ProcessResponse(); 1036 } else { 1037 ALOGD_IF(ese_debug_enabled, 1038 "%s Transceive send failed, going to recovery!", __FUNCTION__); 1039 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 1040 IDLE_STATE; 1041 } 1042 }; 1043 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status); 1044 return status; 1045 } 1046 1047 /****************************************************************************** 1048 * Function phNxpEseProto7816_Transceive 1049 * 1050 * Description This function is used to 1051 * 1. Send the raw data received from application after 1052 *computing LRC 1053 * 2. Receive the the response data from ESE, decode, process 1054 *and 1055 * store the data. 1056 * 3. Get the final complete data and sent back to application 1057 * 1058 * Returns On success return true or else false. 1059 * 1060 ******************************************************************************/ 1061 ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd, 1062 phNxpEse_data* pRsp) { 1063 ESESTATUS status = ESESTATUS_FAILED; 1064 ESESTATUS wStatus = ESESTATUS_FAILED; 1065 phNxpEse_data pRes; 1066 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 1067 if ((NULL == pCmd) || (NULL == pRsp) || 1068 (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState != 1069 PH_NXP_ESE_PROTO_7816_IDLE)) 1070 return status; 1071 phNxpEse_memset(&pRes, 0x00, sizeof(phNxpEse_data)); 1072 /* Updating the transceive information to the protocol stack */ 1073 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1074 PH_NXP_ESE_PROTO_7816_TRANSCEIVE; 1075 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = pCmd->p_data; 1076 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen = 1077 pCmd->len; 1078 ALOGD_IF(ese_debug_enabled, "Transceive data ptr 0x%p len:%d", pCmd->p_data, 1079 pCmd->len); 1080 status = phNxpEseProto7816_SetFirstIframeContxt(); 1081 status = TransceiveProcess(); 1082 if (ESESTATUS_FAILED == status) { 1083 /* ESE hard reset to be done */ 1084 ALOGE("Transceive failed, hard reset to proceed"); 1085 wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data); 1086 if (ESESTATUS_SUCCESS == wStatus) { 1087 ALOGE( 1088 "%s Data successfully received at 7816, packaging to " 1089 "send upper layers: DataLen = %d", 1090 __FUNCTION__, pRes.len); 1091 /* Copy the data to be read by the upper layer via transceive api */ 1092 pRsp->len = pRes.len; 1093 pRsp->p_data = pRes.p_data; 1094 } 1095 } else { 1096 // fetch the data info and report to upper layer. 1097 wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data); 1098 if (ESESTATUS_SUCCESS == wStatus) { 1099 ALOGD_IF(ese_debug_enabled, 1100 "%s Data successfully received at 7816, packaging to " 1101 "send upper layers: DataLen = %d", 1102 __FUNCTION__, pRes.len); 1103 /* Copy the data to be read by the upper layer via transceive api */ 1104 pRsp->len = pRes.len; 1105 pRsp->p_data = pRes.p_data; 1106 } else 1107 status = ESESTATUS_FAILED; 1108 } 1109 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1110 PH_NXP_ESE_PROTO_7816_IDLE; 1111 ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status); 1112 return status; 1113 } 1114 1115 /****************************************************************************** 1116 * Function phNxpEseProto7816_RSync 1117 * 1118 * Description This function is used to send the RSync command 1119 * 1120 * Returns On success return true or else false. 1121 * 1122 ******************************************************************************/ 1123 static ESESTATUS phNxpEseProto7816_RSync(void) { 1124 ESESTATUS status = ESESTATUS_FAILED; 1125 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1126 PH_NXP_ESE_PROTO_7816_TRANSCEIVE; 1127 /* send the end of session s-frame */ 1128 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 1129 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 1130 RESYNCH_REQ; 1131 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_RSYNC; 1132 status = TransceiveProcess(); 1133 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1134 PH_NXP_ESE_PROTO_7816_IDLE; 1135 return status; 1136 } 1137 1138 /****************************************************************************** 1139 * Function phNxpEseProto7816_ResetProtoParams 1140 * 1141 * Description This function is used to reset the 7816 protocol stack 1142 *instance 1143 * 1144 * Returns On success return true or else false. 1145 * 1146 ******************************************************************************/ 1147 static ESESTATUS phNxpEseProto7816_ResetProtoParams(void) { 1148 unsigned long int tmpWTXCountlimit = PH_PROTO_7816_VALUE_ZERO; 1149 unsigned long int tmpRNACKCountlimit = PH_PROTO_7816_VALUE_ZERO; 1150 tmpWTXCountlimit = phNxpEseProto7816_3_Var.wtx_counter_limit; 1151 tmpRNACKCountlimit = phNxpEseProto7816_3_Var.rnack_retry_limit; 1152 phNxpEse_memset(&phNxpEseProto7816_3_Var, PH_PROTO_7816_VALUE_ZERO, 1153 sizeof(phNxpEseProto7816_t)); 1154 phNxpEseProto7816_3_Var.wtx_counter_limit = tmpWTXCountlimit; 1155 phNxpEseProto7816_3_Var.rnack_retry_limit = tmpRNACKCountlimit; 1156 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1157 PH_NXP_ESE_PROTO_7816_IDLE; 1158 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE; 1159 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID; 1160 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = INVALID; 1161 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen = 1162 IFSC_SIZE_SEND; 1163 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = NULL; 1164 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType = INVALID; 1165 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLen = 1166 IFSC_SIZE_SEND; 1167 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data = NULL; 1168 /* Initialized with sequence number of the last I-frame sent */ 1169 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo = 1170 PH_PROTO_7816_VALUE_ONE; 1171 /* Initialized with sequence number of the last I-frame received */ 1172 phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo = 1173 PH_PROTO_7816_VALUE_ONE; 1174 /* Initialized with sequence number of the last I-frame received */ 1175 phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo = 1176 PH_PROTO_7816_VALUE_ONE; 1177 phNxpEseProto7816_3_Var.recoveryCounter = PH_PROTO_7816_VALUE_ZERO; 1178 phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO; 1179 phNxpEseProto7816_3_Var.wtx_counter = PH_PROTO_7816_VALUE_ZERO; 1180 /* This update is helpful in-case a R-NACK is transmitted from the MW */ 1181 phNxpEseProto7816_3_Var.lastSentNonErrorframeType = UNKNOWN; 1182 phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO; 1183 return ESESTATUS_SUCCESS; 1184 } 1185 1186 /****************************************************************************** 1187 * Function phNxpEseProto7816_Reset 1188 * 1189 * Description This function is used to reset the 7816 protocol stack 1190 *instance 1191 * 1192 * Returns On success return true or else false. 1193 * 1194 ******************************************************************************/ 1195 ESESTATUS phNxpEseProto7816_Reset(void) { 1196 ESESTATUS status = ESESTATUS_FAILED; 1197 /* Resetting host protocol instance */ 1198 phNxpEseProto7816_ResetProtoParams(); 1199 /* Resynchronising ESE protocol instance */ 1200 status = phNxpEseProto7816_RSync(); 1201 return status; 1202 } 1203 1204 /****************************************************************************** 1205 * Function phNxpEseProto7816_Open 1206 * 1207 * Description This function is used to open the 7816 protocol stack 1208 *instance 1209 * 1210 * Returns On success return true or else false. 1211 * 1212 ******************************************************************************/ 1213 ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam) { 1214 ESESTATUS status = ESESTATUS_FAILED; 1215 status = phNxpEseProto7816_ResetProtoParams(); 1216 ALOGD_IF(ese_debug_enabled, "%s: First open completed, Congratulations", 1217 __FUNCTION__); 1218 /* Update WTX max. limit */ 1219 phNxpEseProto7816_3_Var.wtx_counter_limit = initParam.wtx_counter_limit; 1220 phNxpEseProto7816_3_Var.rnack_retry_limit = initParam.rnack_retry_limit; 1221 if (initParam.interfaceReset) /* Do interface reset */ 1222 { 1223 status = phNxpEseProto7816_IntfReset(initParam.pSecureTimerParams); 1224 if (ESESTATUS_SUCCESS == status) { 1225 phNxpEse_memcpy(initParam.pSecureTimerParams, 1226 &phNxpEseProto7816_3_Var.secureTimerParams, 1227 sizeof(phNxpEseProto7816SecureTimer_t)); 1228 } 1229 } else /* Do R-Sync */ 1230 { 1231 status = phNxpEseProto7816_RSync(); 1232 } 1233 return status; 1234 } 1235 1236 /****************************************************************************** 1237 * Function phNxpEseProto7816_Close 1238 * 1239 * Description This function is used to close the 7816 protocol stack 1240 *instance 1241 * 1242 * Returns On success return true or else false. 1243 * 1244 ******************************************************************************/ 1245 ESESTATUS phNxpEseProto7816_Close( 1246 phNxpEseProto7816SecureTimer_t* pSecureTimerParams) { 1247 ESESTATUS status = ESESTATUS_FAILED; 1248 if (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState != 1249 PH_NXP_ESE_PROTO_7816_IDLE) 1250 return status; 1251 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1252 PH_NXP_ESE_PROTO_7816_DEINIT; 1253 phNxpEseProto7816_3_Var.recoveryCounter = 0; 1254 phNxpEseProto7816_3_Var.wtx_counter = 0; 1255 /* send the end of session s-frame */ 1256 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 1257 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 1258 PROP_END_APDU_REQ; 1259 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_EOS; 1260 status = TransceiveProcess(); 1261 if (ESESTATUS_FAILED == status) { 1262 /* reset all the structures */ 1263 ALOGE("%s TransceiveProcess failed ", __FUNCTION__); 1264 } 1265 phNxpEse_memcpy(pSecureTimerParams, 1266 &phNxpEseProto7816_3_Var.secureTimerParams, 1267 sizeof(phNxpEseProto7816SecureTimer_t)); 1268 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1269 PH_NXP_ESE_PROTO_7816_IDLE; 1270 return status; 1271 } 1272 1273 /****************************************************************************** 1274 * Function phNxpEseProto7816_IntfReset 1275 * 1276 * Description This function is used to reset just the current interface 1277 * 1278 * Returns On success return true or else false. 1279 * 1280 ******************************************************************************/ 1281 ESESTATUS phNxpEseProto7816_IntfReset( 1282 phNxpEseProto7816SecureTimer_t* pSecureTimerParam) { 1283 ESESTATUS status = ESESTATUS_FAILED; 1284 ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__); 1285 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1286 PH_NXP_ESE_PROTO_7816_TRANSCEIVE; 1287 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME; 1288 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = 1289 INTF_RESET_REQ; 1290 phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = 1291 SEND_S_INTF_RST; 1292 status = TransceiveProcess(); 1293 if (ESESTATUS_FAILED == status) { 1294 /* reset all the structures */ 1295 ALOGE("%s TransceiveProcess failed ", __FUNCTION__); 1296 } 1297 phNxpEse_memcpy(pSecureTimerParam, &phNxpEseProto7816_3_Var.secureTimerParams, 1298 sizeof(phNxpEseProto7816SecureTimer_t)); 1299 phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState = 1300 PH_NXP_ESE_PROTO_7816_IDLE; 1301 ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__); 1302 return status; 1303 } 1304 1305 /****************************************************************************** 1306 * Function phNxpEseProto7816_SetIfscSize 1307 * 1308 * Description This function is used to set the max T=1 data send size 1309 * 1310 * Returns Always return true (1). 1311 * 1312 ******************************************************************************/ 1313 ESESTATUS phNxpEseProto7816_SetIfscSize(uint16_t IFSC_Size) { 1314 phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLen = IFSC_Size; 1315 return ESESTATUS_SUCCESS; 1316 } 1317 /** @} */ 1318