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 /** 19 * \file phFriNfc_LlcpMacNfcip.c 20 * \brief NFC LLCP MAC Mappings For Different RF Technologies. 21 * 22 * Project: NFC-FRI 23 * 24 */ 25 26 27 /*include files*/ 28 #include <phFriNfc_LlcpMac.h> 29 #include <phLibNfcStatus.h> 30 #include <phLibNfc.h> 31 #include <phLibNfc_Internal.h> 32 #include <stdio.h> 33 #include <string.h> 34 35 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac, 36 phNfc_sData_t *psData, 37 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb, 38 void *pContext); 39 40 41 static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t *LlcpMac, 42 NFCSTATUS status) 43 { 44 phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB; 45 void *pReceiveContext; 46 47 if (LlcpMac->MacReceive_Cb != NULL) 48 { 49 /* Save callback params */ 50 pfReceiveCB = LlcpMac->MacReceive_Cb; 51 pReceiveContext = LlcpMac->MacReceive_Context; 52 53 /* Reset the pointer to the Receive Callback and Context*/ 54 LlcpMac->MacReceive_Cb = NULL; 55 LlcpMac->MacReceive_Context = NULL; 56 57 /* Call the receive callback */ 58 pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer); 59 } 60 } 61 62 static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t *LlcpMac, 63 NFCSTATUS status) 64 { 65 phFriNfc_LlcpMac_Send_CB_t pfSendCB; 66 void *pSendContext; 67 68 if (LlcpMac->MacSend_Cb != NULL) 69 { 70 /* Save context in local variables */ 71 pfSendCB = LlcpMac->MacSend_Cb; 72 pSendContext = LlcpMac->MacSend_Context; 73 74 /* Reset the pointer to the Send Callback */ 75 LlcpMac->MacSend_Cb = NULL; 76 LlcpMac->MacSend_Context = NULL; 77 78 /* Call Send callback */ 79 pfSendCB(pSendContext, status); 80 } 81 } 82 83 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t *LlcpMac, 84 phFriNfc_LlcpMac_Chk_CB_t ChkLlcpMac_Cb, 85 void *pContext) 86 { 87 NFCSTATUS status = NFCSTATUS_SUCCESS; 88 uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D}; 89 90 if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext) 91 { 92 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 93 } 94 else 95 { 96 status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3); 97 if(!status) 98 { 99 LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ; 100 LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3); 101 status = NFCSTATUS_SUCCESS; 102 } 103 else 104 { 105 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); 106 } 107 } 108 109 ChkLlcpMac_Cb(pContext,status); 110 return status; 111 } 112 113 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t *LlcpMac) 114 { 115 NFCSTATUS status = NFCSTATUS_SUCCESS; 116 117 if(LlcpMac == NULL) 118 { 119 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 120 } 121 else 122 { 123 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated; 124 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, 125 LlcpMac->LinkState, 126 &LlcpMac->sConfigParam, 127 LlcpMac->PeerRemoteDevType); 128 } 129 130 return status; 131 } 132 133 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t *LlcpMac) 134 { 135 NFCSTATUS status = NFCSTATUS_SUCCESS; 136 137 if(NULL == LlcpMac) 138 { 139 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 140 } 141 else 142 { 143 /* Set the flag of LinkStatus to deactivate */ 144 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated; 145 } 146 147 if (LlcpMac->SendPending) 148 { 149 /* Reset Flag */ 150 LlcpMac->SendPending = FALSE; 151 152 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED); 153 } 154 155 if (LlcpMac->RecvPending) 156 { 157 /* Reset Flag */ 158 LlcpMac->RecvPending = FALSE; 159 160 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED); 161 } 162 163 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, 164 LlcpMac->LinkState, 165 NULL, 166 LlcpMac->PeerRemoteDevType); 167 168 return status; 169 } 170 171 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void *pContext, 172 NFCSTATUS Status) 173 { 174 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 175 176 #ifdef LLCP_CHANGES 177 if(gpphLibContext->LibNfcState.next_state 178 == eLibNfcHalStateShutdown) 179 { 180 phLibNfc_Pending_Shutdown(); 181 Status = NFCSTATUS_SHUTDOWN; 182 } 183 #endif /* #ifdef LLCP_CHANGES */ 184 185 /* Reset Send and Receive Flag */ 186 LlcpMac->SendPending = FALSE; 187 LlcpMac->RecvPending = FALSE; 188 189 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status); 190 191 } 192 193 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void *pContext, 194 NFCSTATUS Status) 195 { 196 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 197 #ifdef LLCP_CHANGES 198 199 phFriNfc_LlcpMac_Send_CB_t pfSendCB; 200 void *pSendContext; 201 202 203 if(gpphLibContext->LibNfcState.next_state 204 == eLibNfcHalStateShutdown) 205 { 206 phLibNfc_Pending_Shutdown(); 207 Status = NFCSTATUS_SHUTDOWN; 208 } 209 210 if (NFCSTATUS_SHUTDOWN == Status) 211 { 212 /* Save context in local variables */ 213 pfSendCB = LlcpMac->MacSend_Cb; 214 pSendContext = LlcpMac->MacSend_Context; 215 216 /* Reset the pointer to the Send Callback */ 217 LlcpMac->MacSend_Cb = NULL; 218 LlcpMac->MacSend_Context = NULL; 219 220 /* Reset Send and Receive Flag */ 221 LlcpMac->SendPending = FALSE; 222 LlcpMac->RecvPending = FALSE; 223 } 224 225 #endif /* #ifdef LLCP_CHANGES */ 226 227 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status); 228 229 #ifdef LLCP_CHANGES 230 231 if (NFCSTATUS_SHUTDOWN == Status) 232 { 233 if ((LlcpMac->SendPending) && (NULL != pfSendCB)) 234 { 235 pfSendCB(pSendContext, Status); 236 } 237 } 238 else 239 240 #endif /* #ifdef LLCP_CHANGES */ 241 { 242 /* Test if a send is pending */ 243 if(LlcpMac->SendPending) 244 { 245 Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context); 246 } 247 } 248 } 249 250 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void *pContext, 251 NFCSTATUS Status) 252 { 253 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 254 255 #ifdef LLCP_CHANGES 256 if(gpphLibContext->LibNfcState.next_state 257 == eLibNfcHalStateShutdown) 258 { 259 phLibNfc_Pending_Shutdown(); 260 Status = NFCSTATUS_SHUTDOWN; 261 } 262 #endif /* #ifdef LLCP_CHANGES */ 263 264 /* Reset Send and Receive Flag */ 265 LlcpMac->SendPending = FALSE; 266 LlcpMac->RecvPending = FALSE; 267 268 /* Call the callbacks */ 269 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status); 270 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status); 271 } 272 273 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac, 274 phNfc_sData_t *psData, 275 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb, 276 void *pContext) 277 { 278 NFCSTATUS status = NFCSTATUS_SUCCESS; 279 280 if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext) 281 { 282 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 283 } 284 else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator) 285 { 286 /*Previous callback is pending */ 287 status = NFCSTATUS_REJECTED; 288 } 289 else 290 { 291 /* Save the LlcpMacSend_Cb */ 292 LlcpMac->MacSend_Cb = LlcpMacSend_Cb; 293 LlcpMac->MacSend_Context = pContext; 294 295 switch(LlcpMac->PeerRemoteDevType) 296 { 297 case phFriNfc_LlcpMac_ePeerTypeInitiator: 298 { 299 if(LlcpMac->RecvPending) 300 { 301 /*set the completion routines for the LLCP Transceive function*/ 302 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 303 LlcpMac->MacCompletionInfo.Context = LlcpMac; 304 305 /* set the command type*/ 306 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 307 308 /* set the Additional Info*/ 309 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 310 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 311 LlcpMac->SendPending = TRUE; 312 313 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 314 &LlcpMac->MacCompletionInfo, 315 LlcpMac->psRemoteDevInfo, 316 LlcpMac->Cmd, 317 &LlcpMac->psDepAdditionalInfo, 318 psData->buffer, 319 (uint16_t)psData->length, 320 LlcpMac->psReceiveBuffer->buffer, 321 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 322 } 323 else 324 { 325 LlcpMac->SendPending = TRUE; 326 LlcpMac->psSendBuffer = psData; 327 return status = NFCSTATUS_PENDING; 328 } 329 }break; 330 case phFriNfc_LlcpMac_ePeerTypeTarget: 331 { 332 if(!LlcpMac->RecvPending) 333 { 334 LlcpMac->SendPending = TRUE; 335 LlcpMac->psSendBuffer = psData; 336 return status = NFCSTATUS_PENDING; 337 } 338 else 339 { 340 /*set the completion routines for the LLCP Send function*/ 341 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb; 342 LlcpMac->MacCompletionInfo.Context = LlcpMac; 343 status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice, 344 &LlcpMac->MacCompletionInfo, 345 LlcpMac->psRemoteDevInfo, 346 psData->buffer, 347 (uint16_t)psData->length); 348 } 349 }break; 350 default: 351 { 352 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE); 353 }break; 354 } 355 } 356 return status; 357 } 358 359 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t *LlcpMac, 360 phNfc_sData_t *psData, 361 phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb, 362 void *pContext) 363 { 364 NFCSTATUS status = NFCSTATUS_SUCCESS; 365 if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext) 366 { 367 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 368 } 369 else if(LlcpMac->MacReceive_Cb != NULL) 370 { 371 /*Previous callback is pending */ 372 status = NFCSTATUS_REJECTED; 373 } 374 else 375 { 376 /* Save the LlcpMacReceive_Cb */ 377 LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb; 378 LlcpMac->MacReceive_Context = pContext; 379 380 /* Save the pointer to the receive buffer */ 381 LlcpMac->psReceiveBuffer= psData; 382 383 switch(LlcpMac->PeerRemoteDevType) 384 { 385 case phFriNfc_LlcpMac_ePeerTypeInitiator: 386 { 387 if(LlcpMac->SendPending) 388 { 389 /*set the completion routines for the LLCP Transceive function*/ 390 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 391 LlcpMac->MacCompletionInfo.Context = LlcpMac; 392 /* set the command type*/ 393 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 394 /* set the Additional Info*/ 395 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 396 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 397 LlcpMac->RecvPending = TRUE; 398 399 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 400 &LlcpMac->MacCompletionInfo, 401 LlcpMac->psRemoteDevInfo, 402 LlcpMac->Cmd, 403 &LlcpMac->psDepAdditionalInfo, 404 LlcpMac->psSendBuffer->buffer, 405 (uint16_t)LlcpMac->psSendBuffer->length, 406 psData->buffer, 407 (uint16_t*)&psData->length); 408 } 409 else 410 { 411 LlcpMac->RecvPending = TRUE; 412 return status = NFCSTATUS_PENDING; 413 } 414 }break; 415 case phFriNfc_LlcpMac_ePeerTypeTarget: 416 { 417 /*set the completion routines for the LLCP Receive function*/ 418 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb; 419 /* save the context of LlcpMacNfcip */ 420 LlcpMac->MacCompletionInfo.Context = LlcpMac; 421 LlcpMac->RecvPending = TRUE; 422 423 status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice, 424 &LlcpMac->MacCompletionInfo, 425 LlcpMac->psRemoteDevInfo, 426 LlcpMac->psReceiveBuffer->buffer, 427 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 428 }break; 429 default: 430 { 431 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE); 432 }break; 433 } 434 } 435 return status; 436 } 437 438 439 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac) 440 { 441 NFCSTATUS status = NFCSTATUS_SUCCESS; 442 443 if(NULL != LlcpMac) 444 { 445 LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk; 446 LlcpMac->LlcpMacInterface.activate = phFriNfc_LlcpMac_Nfcip_Activate; 447 LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate; 448 LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send; 449 LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive; 450 451 return NFCSTATUS_SUCCESS; 452 } 453 else 454 { 455 return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); 456 } 457 } 458