1/* 2 * Copyright (C) 2010 NXP Semiconductors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/*! 18 * \file phFriNfc_OvrHal.c 19 * \brief Overlapped HAL 20 * 21 * Project: NFC-FRI 22 * Creator: Gerald Kersch 23 * 24 * $Date: Wed May 5 10:47:27 2010 $ 25 * Changed by: $Author: ing02260 $ 26 * $Revision: 1.37 $ 27 * $Aliases: NFC_FRI1.1_WK1017_R34_3,NFC_FRI1.1_WK1023_R35_1 $ 28 * 29 */ 30 31#include <phFriNfc_OvrHal.h> 32#include <phOsalNfc.h> 33#include <phFriNfc_NdefMap.h> 34#include <phFriNfc_SmtCrdFmt.h> 35 36 37#ifdef PHFRINFC_OVRHAL_MOCKUP /* */ 38//#include <phLibNfc_Gen.h> 39#endif /* PHFRINFC_OVRHAL_MOCKUP */ 40/* 41* 42 43*/ 44#define MAX_MIF_PACKET_LEN 0x0FU 45#define MIFARE_PLUS_UID_INDEX_TO_COPY 0x03U 46#define MIFARE_PLUS_UID_LENGTH 0x07U 47#define MIFARE_CLASSIC_UID_LENGTH 0x04U 48#define MIFARE_UID_LEN_TO_COPY 0x04U 49 50static void phFriNfc_OvrHal_CB_Send(void *context, 51 NFCSTATUS status); 52static void phFriNfc_OvrHal_CB_Receive(void *context, 53 phNfc_sData_t *pDataInfo, 54 NFCSTATUS status); 55static void phFriNfc_OvrHal_CB_Transceive(void *context, 56 phHal_sRemoteDevInformation_t *RemoteDevHandle, 57 phNfc_sData_t *pRecvdata, 58 NFCSTATUS status 59 ); 60static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context, 61 phHal_sRemoteDevInformation_t *RemoteDevHandle, 62 NFCSTATUS status 63 ); 64 65static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal, 66 phFriNfc_CplRt_t *CompletionInfo, 67 uint8_t Operation); 68 69NFCSTATUS phFriNfc_OvrHal_Transceive(phFriNfc_OvrHal_t *OvrHal, 70 phFriNfc_CplRt_t *CompletionInfo, 71 phHal_sRemoteDevInformation_t *RemoteDevInfo, 72 phHal_uCmdList_t Cmd, 73 phHal_sDepAdditionalInfo_t *DepAdditionalInfo, 74 uint8_t *SendBuf, 75 uint16_t SendLength, 76 uint8_t *RecvBuf, 77 uint16_t *RecvLength) 78{ 79 NFCSTATUS status = NFCSTATUS_PENDING; 80 uint8_t i = 0; 81 uint32_t length = SendLength; 82 83 /* To remove "warning (VS C4100) : unreferenced formal parameter" */ 84 PHNFC_UNUSED_VARIABLE(DepAdditionalInfo); 85 86 /* Check the Input Parameters */ 87 if ((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) 88 || (NULL == (void*)SendBuf) || (NULL == RecvBuf) || (NULL == RecvLength) 89 || ((phHal_eJewel_PICC != RemoteDevInfo->RemDevType) && (0 == SendLength))) 90 91 { 92 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL, NFCSTATUS_INVALID_PARAMETER); 93 } 94 else 95 { 96 /* 16 is the maximum data, that can be sent to the mifare standard */ 97 static uint8_t mif_send_buf[MAX_MIF_PACKET_LEN] = {0}; 98 /* Populate the Transfer info structure */ 99 OvrHal->TranceiveInfo.cmd = Cmd; 100 101 /* Populate the Send Buffer Info */ 102 if((phHal_eMifare_PICC == RemoteDevInfo->RemDevType) 103 || (phHal_eISO14443_3A_PICC == RemoteDevInfo->RemDevType)) 104 { 105 OvrHal->TranceiveInfo.addr = SendBuf[i++]; 106 length = (SendLength - i); 107 108 if ((phHal_eMifareAuthentA == Cmd.MfCmd) 109 || (phHal_eMifareAuthentB == Cmd.MfCmd)) 110 { 111 uint8_t uid_index = 0; 112 /* Authentication requires UID in the send buffer */ 113 uint8_t uid_len = 114 RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength; 115 OvrHal->TranceiveInfo.sSendData.buffer = mif_send_buf; 116 117 switch (uid_len) 118 { 119 case MIFARE_PLUS_UID_LENGTH: 120 { 121 uid_index = MIFARE_PLUS_UID_INDEX_TO_COPY; 122 uid_len = MIFARE_UID_LEN_TO_COPY; 123 break; 124 } 125 126 case MIFARE_CLASSIC_UID_LENGTH: 127 { 128 uid_index = 0; 129 break; 130 } 131 132 default: 133 { 134 status = PHNFCSTVAL (CID_FRI_NFC_OVR_HAL, 135 NFCSTATUS_READ_FAILED); 136 break; 137 } 138 } 139 140 if (NFCSTATUS_PENDING == status) 141 { 142 /* copy uid to the send buffer for the authentication */ 143 (void)memcpy ((void *)mif_send_buf, 144 (void *)&RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[uid_index], 145 uid_len); 146 147 (void)memcpy((mif_send_buf + uid_len), &(SendBuf[i]), length); 148 length += uid_len; 149 } 150 } 151 else 152 { 153 OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++]; 154 } 155 OvrHal->TranceiveInfo.sSendData.length = length; 156 } 157 else 158 { 159 OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++]; 160 OvrHal->TranceiveInfo.sSendData.length = length; 161 } 162 163 if (NFCSTATUS_PENDING == status) 164 { 165 /* Populate the Receive buffer */ 166 OvrHal->TranceiveInfo.sRecvData.buffer = RecvBuf; 167 OvrHal->TranceiveInfo.sRecvData.length = *RecvLength; 168 OvrHal->pndef_recv_length = RecvLength; 169 phFriNfc_OvrHal_SetComplInfo(OvrHal,CompletionInfo, PH_FRINFC_OVRHAL_TRX); 170 171 /* Call the HAL 4.0 Transceive Function */ 172 status = phHal4Nfc_Transceive (OvrHal->psHwReference, 173 &OvrHal->TranceiveInfo, RemoteDevInfo, 174 phFriNfc_OvrHal_CB_Transceive, (void *)OvrHal); 175 } 176 177 } 178 return status; 179 180} 181 182NFCSTATUS phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t *OvrHal, 183 phFriNfc_CplRt_t *CompletionInfo, 184 phHal_sRemoteDevInformation_t *RemoteDevInfo, 185 uint8_t *RecvBuf, 186 uint16_t *RecvLength) 187{ 188 NFCSTATUS status = NFCSTATUS_PENDING; 189 190 /* Check the Input Parameters */ 191 if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) 192 || (NULL==RecvBuf) || (NULL==RecvLength) ) 193 { 194 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); 195 } 196 else 197 { 198 /* Get the remote dev type */ 199 OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType; 200 /* Save the receive buffer for use in callback */ 201 OvrHal->sReceiveData.buffer = RecvBuf; 202 OvrHal->sReceiveData.length = *RecvLength; 203 204 OvrHal->pndef_recv_length = RecvLength; 205 206 /* Set the callback */ 207 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_RCV); 208 209 /* Call the HAL 4.0 Receive Function */ 210 status = phHal4Nfc_Receive( OvrHal->psHwReference, 211 &OvrHal->TransactInfo, 212 phFriNfc_OvrHal_CB_Receive, 213 (void *)OvrHal); 214 } 215 return status; 216} 217 218NFCSTATUS phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t *OvrHal, 219 phFriNfc_CplRt_t *CompletionInfo, 220 phHal_sRemoteDevInformation_t *RemoteDevInfo, 221 uint8_t *SendBuf, 222 uint16_t SendLength) 223{ 224 NFCSTATUS status = NFCSTATUS_PENDING; 225 226 /* Check the Input Parameters */ 227 if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==SendBuf) ) 228 { 229 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); 230 } 231 else 232 { 233 /* Get the remote dev type */ 234 OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType; 235 /* Save the receive buffer for use in callback */ 236 OvrHal->sSendData.buffer = SendBuf; 237 OvrHal->sSendData.length = SendLength; 238 239 /* Set the callback */ 240 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_SND); 241 242 /* Call the HAL 4.0 Receive Function */ 243 status = phHal4Nfc_Send( OvrHal->psHwReference, 244 &OvrHal->TransactInfo, 245 OvrHal->sSendData, 246 phFriNfc_OvrHal_CB_Send, 247 (void *)OvrHal); 248 } 249 return status; 250} 251 252#ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED 253 254 255NFCSTATUS phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t *OvrHal, 256 phFriNfc_CplRt_t *CompletionInfo, 257 phHal_sRemoteDevInformation_t *RemoteDevInfo) 258{ 259 NFCSTATUS status = NFCSTATUS_PENDING; 260 261 /* Check the Input Parameters */ 262 if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo)) 263 { 264 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); 265 } 266 else 267 { 268 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_DIS); 269 270 status = phHal4Nfc_Connect( 271 OvrHal->psHwReference, 272 RemoteDevInfo, 273 phFriNfc_OvrHal_CB_ConnectDisconnect, 274 (void *)OvrHal); 275 } 276 277 return status; 278} 279 280 281 282NFCSTATUS phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t *OvrHal, 283 phFriNfc_CplRt_t *CompletionInfo, 284 phHal_sRemoteDevInformation_t *RemoteDevInfo, 285 phHal_sDevInputParam_t *DevInputParam) 286{ 287 NFCSTATUS status = NFCSTATUS_PENDING; 288 289 /* Check the Input Parameters */ 290 if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) || 291 (NULL == DevInputParam)) 292 { 293 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); 294 } 295 else 296 { 297 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_CON); 298 299 status = phHal4Nfc_Connect( 300 OvrHal->psHwReference, 301 RemoteDevInfo, 302 phFriNfc_OvrHal_CB_ConnectDisconnect, 303 (void *)OvrHal 304 ); 305 } 306 307 return status; 308} 309 310#endif 311 312static void phFriNfc_OvrHal_CB_Transceive(void *context, 313 phHal_sRemoteDevInformation_t *RemoteDevHandle, 314 phNfc_sData_t *pRecvdata, 315 NFCSTATUS status 316 ) 317 318{ 319 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; 320 321 if (NULL != OvrHal) 322 { 323 if(NULL != pRecvdata && OvrHal->TranceiveInfo.sRecvData.buffer != NULL && pRecvdata->buffer != NULL) 324 { 325 /* Work-around for the NFCIP Tranceive API */ 326 if (OvrHal->TranceiveInfo.sRecvData.buffer != pRecvdata->buffer) 327 { 328 memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length); 329 } 330 if (OvrHal->pndef_recv_length != NULL) 331 { 332 *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length; 333 } 334 } 335 if(NULL != RemoteDevHandle) 336 { 337 /* Fix for Warning 4100 */ 338 RemoteDevHandle=RemoteDevHandle; 339 } 340 341 if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine) 342 { 343 OvrHal->TemporaryCompletionInfo.CompletionRoutine( 344 OvrHal->TemporaryCompletionInfo.Context, 345 status); 346 } 347 } 348} 349 350static void phFriNfc_OvrHal_CB_Send(void *context, 351 NFCSTATUS status) 352{ 353 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; 354 355 if (NULL != OvrHal) 356 { 357 if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine) 358 { 359 OvrHal->TemporarySndCompletionInfo.CompletionRoutine( 360 OvrHal->TemporarySndCompletionInfo.Context, 361 status); 362 } 363 } 364} 365 366static void phFriNfc_OvrHal_CB_Receive(void *context, 367 phNfc_sData_t *pDataInfo, 368 NFCSTATUS status) 369{ 370 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; 371 372 if (NULL != OvrHal) 373 { 374 /* Copy the received buffer */ 375 if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL) 376 { 377 memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length); 378 *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length; 379 } 380 381 if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine) 382 { 383 OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine( 384 OvrHal->TemporaryRcvCompletionInfo.Context, 385 status); 386 } 387 } 388} 389 390static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context, 391 phHal_sRemoteDevInformation_t *RemoteDevHandle, 392 NFCSTATUS status 393 ) 394 395{ 396 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; 397 398 if (NULL != OvrHal) 399 { 400 if (RemoteDevHandle != NULL) 401 { 402 /* Fix for Warning 4100 */ 403 RemoteDevHandle = RemoteDevHandle; 404 } 405 else 406 { 407 status = NFCSTATUS_FAILED; 408 } 409 410 OvrHal->TemporaryCompletionInfo.CompletionRoutine( 411 OvrHal->TemporaryCompletionInfo.Context, status); 412 } 413 414} 415 416static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal, 417 phFriNfc_CplRt_t *CompletionInfo, 418 uint8_t Operation) 419 420{ 421 OvrHal->Operation = Operation; 422 switch(Operation) 423 { 424 case PH_FRINFC_OVRHAL_RCV: 425 { 426 OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; 427 OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context; 428 break; 429 } 430 case PH_FRINFC_OVRHAL_SND: 431 { 432 OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; 433 OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context; 434 break; 435 } 436 default: 437 { 438 OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; 439 OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context; 440 break; 441 } 442 } 443} 444