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 ChkLlcpMac_Cb(pContext,status); 108 } 109 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 if (LlcpMac->SendPending) 147 { 148 /* Reset Flag */ 149 LlcpMac->SendPending = FALSE; 150 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED); 151 } 152 153 if (LlcpMac->RecvPending) 154 { 155 /* Reset Flag */ 156 LlcpMac->RecvPending = FALSE; 157 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED); 158 } 159 160 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, 161 LlcpMac->LinkState, 162 NULL, 163 LlcpMac->PeerRemoteDevType); 164 } 165 166 return status; 167 } 168 169 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void *pContext, 170 NFCSTATUS Status) 171 { 172 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 173 174 #ifdef LLCP_CHANGES 175 if(gpphLibContext->LibNfcState.next_state 176 == eLibNfcHalStateShutdown) 177 { 178 phLibNfc_Pending_Shutdown(); 179 Status = NFCSTATUS_SHUTDOWN; 180 } 181 #endif /* #ifdef LLCP_CHANGES */ 182 183 /* Reset Send and Receive Flag */ 184 LlcpMac->SendPending = FALSE; 185 LlcpMac->RecvPending = FALSE; 186 187 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status); 188 189 } 190 191 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void *pContext, 192 NFCSTATUS Status) 193 { 194 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 195 #ifdef LLCP_CHANGES 196 197 phFriNfc_LlcpMac_Send_CB_t pfSendCB; 198 void *pSendContext; 199 200 201 if(gpphLibContext->LibNfcState.next_state 202 == eLibNfcHalStateShutdown) 203 { 204 phLibNfc_Pending_Shutdown(); 205 Status = NFCSTATUS_SHUTDOWN; 206 } 207 208 if (NFCSTATUS_SHUTDOWN == Status) 209 { 210 /* Save context in local variables */ 211 pfSendCB = LlcpMac->MacSend_Cb; 212 pSendContext = LlcpMac->MacSend_Context; 213 214 /* Reset the pointer to the Send Callback */ 215 LlcpMac->MacSend_Cb = NULL; 216 LlcpMac->MacSend_Context = NULL; 217 218 /* Reset Send and Receive Flag */ 219 LlcpMac->SendPending = FALSE; 220 LlcpMac->RecvPending = FALSE; 221 } 222 223 #endif /* #ifdef LLCP_CHANGES */ 224 225 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status); 226 227 #ifdef LLCP_CHANGES 228 229 if (NFCSTATUS_SHUTDOWN == Status) 230 { 231 if ((LlcpMac->SendPending) && (NULL != pfSendCB)) 232 { 233 pfSendCB(pSendContext, Status); 234 } 235 } 236 else 237 238 #endif /* #ifdef LLCP_CHANGES */ 239 { 240 /* Test if a send is pending */ 241 if(LlcpMac->SendPending) 242 { 243 Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context); 244 } 245 } 246 } 247 248 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void *pContext, 249 NFCSTATUS Status) 250 { 251 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 252 253 #ifdef LLCP_CHANGES 254 if(gpphLibContext->LibNfcState.next_state 255 == eLibNfcHalStateShutdown) 256 { 257 phLibNfc_Pending_Shutdown(); 258 Status = NFCSTATUS_SHUTDOWN; 259 } 260 #endif /* #ifdef LLCP_CHANGES */ 261 262 /* Reset Send and Receive Flag */ 263 LlcpMac->SendPending = FALSE; 264 LlcpMac->RecvPending = FALSE; 265 266 /* Call the callbacks */ 267 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status); 268 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status); 269 } 270 271 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac, 272 phNfc_sData_t *psData, 273 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb, 274 void *pContext) 275 { 276 NFCSTATUS status = NFCSTATUS_SUCCESS; 277 278 if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext) 279 { 280 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 281 } 282 else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator) 283 { 284 /*Previous callback is pending */ 285 status = NFCSTATUS_REJECTED; 286 } 287 else 288 { 289 /* Save the LlcpMacSend_Cb */ 290 LlcpMac->MacSend_Cb = LlcpMacSend_Cb; 291 LlcpMac->MacSend_Context = pContext; 292 293 switch(LlcpMac->PeerRemoteDevType) 294 { 295 case phFriNfc_LlcpMac_ePeerTypeInitiator: 296 { 297 if(LlcpMac->RecvPending) 298 { 299 /*set the completion routines for the LLCP Transceive function*/ 300 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 301 LlcpMac->MacCompletionInfo.Context = LlcpMac; 302 303 /* set the command type*/ 304 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 305 306 /* set the Additional Info*/ 307 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 308 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 309 LlcpMac->SendPending = TRUE; 310 311 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 312 &LlcpMac->MacCompletionInfo, 313 LlcpMac->psRemoteDevInfo, 314 LlcpMac->Cmd, 315 &LlcpMac->psDepAdditionalInfo, 316 psData->buffer, 317 (uint16_t)psData->length, 318 LlcpMac->psReceiveBuffer->buffer, 319 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 320 } 321 else 322 { 323 LlcpMac->SendPending = TRUE; 324 LlcpMac->psSendBuffer = psData; 325 return status = NFCSTATUS_PENDING; 326 } 327 }break; 328 case phFriNfc_LlcpMac_ePeerTypeTarget: 329 { 330 if(!LlcpMac->RecvPending) 331 { 332 LlcpMac->SendPending = TRUE; 333 LlcpMac->psSendBuffer = psData; 334 return status = NFCSTATUS_PENDING; 335 } 336 else 337 { 338 /*set the completion routines for the LLCP Send function*/ 339 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb; 340 LlcpMac->MacCompletionInfo.Context = LlcpMac; 341 status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice, 342 &LlcpMac->MacCompletionInfo, 343 LlcpMac->psRemoteDevInfo, 344 psData->buffer, 345 (uint16_t)psData->length); 346 } 347 }break; 348 default: 349 { 350 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE); 351 }break; 352 } 353 } 354 return status; 355 } 356 357 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t *LlcpMac, 358 phNfc_sData_t *psData, 359 phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb, 360 void *pContext) 361 { 362 NFCSTATUS status = NFCSTATUS_SUCCESS; 363 if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext) 364 { 365 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 366 } 367 else if(LlcpMac->MacReceive_Cb != NULL) 368 { 369 /*Previous callback is pending */ 370 status = NFCSTATUS_REJECTED; 371 } 372 else 373 { 374 /* Save the LlcpMacReceive_Cb */ 375 LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb; 376 LlcpMac->MacReceive_Context = pContext; 377 378 /* Save the pointer to the receive buffer */ 379 LlcpMac->psReceiveBuffer= psData; 380 381 switch(LlcpMac->PeerRemoteDevType) 382 { 383 case phFriNfc_LlcpMac_ePeerTypeInitiator: 384 { 385 if(LlcpMac->SendPending) 386 { 387 /*set the completion routines for the LLCP Transceive function*/ 388 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 389 LlcpMac->MacCompletionInfo.Context = LlcpMac; 390 /* set the command type*/ 391 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 392 /* set the Additional Info*/ 393 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 394 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 395 LlcpMac->RecvPending = TRUE; 396 397 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 398 &LlcpMac->MacCompletionInfo, 399 LlcpMac->psRemoteDevInfo, 400 LlcpMac->Cmd, 401 &LlcpMac->psDepAdditionalInfo, 402 LlcpMac->psSendBuffer->buffer, 403 (uint16_t)LlcpMac->psSendBuffer->length, 404 psData->buffer, 405 (uint16_t*)&psData->length); 406 } 407 else 408 { 409 LlcpMac->RecvPending = TRUE; 410 return status = NFCSTATUS_PENDING; 411 } 412 }break; 413 case phFriNfc_LlcpMac_ePeerTypeTarget: 414 { 415 /*set the completion routines for the LLCP Receive function*/ 416 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb; 417 /* save the context of LlcpMacNfcip */ 418 LlcpMac->MacCompletionInfo.Context = LlcpMac; 419 LlcpMac->RecvPending = TRUE; 420 421 status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice, 422 &LlcpMac->MacCompletionInfo, 423 LlcpMac->psRemoteDevInfo, 424 LlcpMac->psReceiveBuffer->buffer, 425 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 426 }break; 427 default: 428 { 429 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE); 430 }break; 431 } 432 } 433 return status; 434 } 435 436 437 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac) 438 { 439 NFCSTATUS status = NFCSTATUS_SUCCESS; 440 441 if(NULL != LlcpMac) 442 { 443 LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk; 444 LlcpMac->LlcpMacInterface.activate = phFriNfc_LlcpMac_Nfcip_Activate; 445 LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate; 446 LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send; 447 LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive; 448 449 return NFCSTATUS_SUCCESS; 450 } 451 else 452 { 453 return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); 454 } 455 } 456