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