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 36 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac, 37 phNfc_sData_t *psData, 38 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb, 39 void *pContext); 40 41 42 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t *LlcpMac, 43 phFriNfc_LlcpMac_Chk_CB_t ChkLlcpMac_Cb, 44 void *pContext) 45 { 46 NFCSTATUS status = NFCSTATUS_SUCCESS; 47 uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D}; 48 49 if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext) 50 { 51 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 52 } 53 else 54 { 55 status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3); 56 if(!status) 57 { 58 LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ; 59 LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3); 60 status = NFCSTATUS_SUCCESS; 61 } 62 else 63 { 64 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); 65 } 66 } 67 68 ChkLlcpMac_Cb(pContext,status); 69 return status; 70 } 71 72 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t *LlcpMac) 73 { 74 NFCSTATUS status = NFCSTATUS_SUCCESS; 75 76 if(LlcpMac == NULL) 77 { 78 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 79 } 80 else 81 { 82 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated; 83 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, 84 LlcpMac->LinkState, 85 &LlcpMac->sConfigParam, 86 LlcpMac->PeerRemoteDevType); 87 } 88 89 return status; 90 } 91 92 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t *LlcpMac) 93 { 94 NFCSTATUS status = NFCSTATUS_SUCCESS; 95 96 if(NULL == LlcpMac) 97 { 98 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 99 } 100 else 101 { 102 /* Set the flag of LinkStatus to deactivate */ 103 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated; 104 } 105 106 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, 107 LlcpMac->LinkState, 108 NULL, 109 LlcpMac->PeerRemoteDevType); 110 111 return status; 112 } 113 114 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void *pContext, 115 NFCSTATUS Status) 116 { 117 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 118 phFriNfc_LlcpMac_Send_CB_t pfSendCB; 119 void *pSendContext; 120 121 /* Reset Send and Receive Flag */ 122 LlcpMac->SendPending = FALSE; 123 LlcpMac->RecvPending = FALSE; 124 125 /* Save context in local variables */ 126 pfSendCB = LlcpMac->MacSend_Cb; 127 pSendContext = LlcpMac->MacSend_Context; 128 129 /* Reset the pointer to the Send Callback */ 130 LlcpMac->MacSend_Cb = NULL; 131 LlcpMac->MacSend_Context = NULL; 132 133 /* Call Send callback */ 134 pfSendCB(pSendContext, Status); 135 } 136 137 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void *pContext, 138 NFCSTATUS Status) 139 { 140 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 141 phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB; 142 void *pReceiveContext; 143 144 /* Save callback params */ 145 pfReceiveCB = LlcpMac->MacReceive_Cb; 146 pReceiveContext = LlcpMac->MacReceive_Context; 147 148 /* Reset the pointer to the Receive Callback and Context*/ 149 LlcpMac->MacReceive_Cb = NULL; 150 LlcpMac->MacReceive_Context = NULL; 151 152 /* Call the receive callback */ 153 pfReceiveCB(pReceiveContext, Status, LlcpMac->psReceiveBuffer); 154 155 /* Test if a send is pending */ 156 if(LlcpMac->SendPending) 157 { 158 Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacReceive_Context); 159 } 160 } 161 162 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void *pContext, 163 NFCSTATUS Status) 164 { 165 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext; 166 phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB; 167 void *pReceiveContext; 168 phFriNfc_LlcpMac_Send_CB_t pfSendCB; 169 void *pSendContext; 170 171 /* Save context in local variables */ 172 pfReceiveCB = LlcpMac->MacReceive_Cb; 173 pReceiveContext = LlcpMac->MacReceive_Context; 174 pfSendCB = LlcpMac->MacSend_Cb; 175 pSendContext = LlcpMac->MacSend_Context; 176 177 /* Reset the poniters to the Receive and Send Callback */ 178 LlcpMac->MacReceive_Cb = NULL; 179 LlcpMac->MacReceive_Context = NULL; 180 LlcpMac->MacSend_Cb = NULL; 181 LlcpMac->MacSend_Context = NULL; 182 183 /* Reset Send and Receive Flag */ 184 LlcpMac->SendPending = FALSE; 185 LlcpMac->RecvPending = FALSE; 186 187 /* Call the callbacks */ 188 pfSendCB(pSendContext, Status); 189 pfReceiveCB(pReceiveContext, Status, LlcpMac->psReceiveBuffer); 190 } 191 192 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac, 193 phNfc_sData_t *psData, 194 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb, 195 void *pContext) 196 { 197 NFCSTATUS status = NFCSTATUS_SUCCESS; 198 199 if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext) 200 { 201 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 202 } 203 else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator) 204 { 205 /*Previous callback is pending */ 206 status = NFCSTATUS_REJECTED; 207 } 208 else 209 { 210 /* Save the LlcpMacSend_Cb */ 211 LlcpMac->MacSend_Cb = LlcpMacSend_Cb; 212 LlcpMac->MacSend_Context = pContext; 213 214 switch(LlcpMac->PeerRemoteDevType) 215 { 216 case phFriNfc_LlcpMac_ePeerTypeInitiator: 217 { 218 if(LlcpMac->RecvPending) 219 { 220 /*set the completion routines for the LLCP Transceive function*/ 221 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 222 LlcpMac->MacCompletionInfo.Context = LlcpMac; 223 224 /* set the command type*/ 225 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 226 227 /* set the Additional Info*/ 228 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 229 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 230 LlcpMac->SendPending = TRUE; 231 232 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 233 &LlcpMac->MacCompletionInfo, 234 LlcpMac->psRemoteDevInfo, 235 LlcpMac->Cmd, 236 &LlcpMac->psDepAdditionalInfo, 237 psData->buffer, 238 (uint16_t)psData->length, 239 LlcpMac->psReceiveBuffer->buffer, 240 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 241 } 242 else 243 { 244 LlcpMac->SendPending = TRUE; 245 LlcpMac->psSendBuffer = psData; 246 return status = NFCSTATUS_PENDING; 247 } 248 }break; 249 case phFriNfc_LlcpMac_ePeerTypeTarget: 250 { 251 if(!LlcpMac->RecvPending) 252 { 253 LlcpMac->SendPending = TRUE; 254 LlcpMac->psSendBuffer = psData; 255 return status = NFCSTATUS_PENDING; 256 } 257 else 258 { 259 /*set the completion routines for the LLCP Send function*/ 260 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb; 261 LlcpMac->MacCompletionInfo.Context = LlcpMac; 262 status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice, 263 &LlcpMac->MacCompletionInfo, 264 LlcpMac->psRemoteDevInfo, 265 psData->buffer, 266 (uint16_t)psData->length); 267 } 268 }break; 269 default: 270 { 271 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE); 272 }break; 273 } 274 } 275 return status; 276 } 277 278 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t *LlcpMac, 279 phNfc_sData_t *psData, 280 phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb, 281 void *pContext) 282 { 283 NFCSTATUS status = NFCSTATUS_SUCCESS; 284 if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext) 285 { 286 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER); 287 } 288 else if(LlcpMac->MacReceive_Cb != NULL) 289 { 290 /*Previous callback is pending */ 291 status = NFCSTATUS_REJECTED; 292 } 293 else 294 { 295 /* Save the LlcpMacReceive_Cb */ 296 LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb; 297 LlcpMac->MacReceive_Context = pContext; 298 299 /* Save the pointer to the receive buffer */ 300 LlcpMac->psReceiveBuffer= psData; 301 302 switch(LlcpMac->PeerRemoteDevType) 303 { 304 case phFriNfc_LlcpMac_ePeerTypeInitiator: 305 { 306 if(LlcpMac->SendPending) 307 { 308 /*set the completion routines for the LLCP Transceive function*/ 309 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb; 310 LlcpMac->MacCompletionInfo.Context = LlcpMac; 311 /* set the command type*/ 312 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw; 313 /* set the Additional Info*/ 314 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 315 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0; 316 LlcpMac->RecvPending = TRUE; 317 318 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice, 319 &LlcpMac->MacCompletionInfo, 320 LlcpMac->psRemoteDevInfo, 321 LlcpMac->Cmd, 322 &LlcpMac->psDepAdditionalInfo, 323 LlcpMac->psSendBuffer->buffer, 324 (uint16_t)LlcpMac->psSendBuffer->length, 325 psData->buffer, 326 (uint16_t*)&psData->length); 327 } 328 else 329 { 330 LlcpMac->RecvPending = TRUE; 331 return status = NFCSTATUS_PENDING; 332 } 333 }break; 334 case phFriNfc_LlcpMac_ePeerTypeTarget: 335 { 336 /*set the completion routines for the LLCP Receive function*/ 337 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb; 338 /* save the context of LlcpMacNfcip */ 339 LlcpMac->MacCompletionInfo.Context = LlcpMac; 340 LlcpMac->RecvPending = TRUE; 341 342 status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice, 343 &LlcpMac->MacCompletionInfo, 344 LlcpMac->psRemoteDevInfo, 345 LlcpMac->psReceiveBuffer->buffer, 346 (uint16_t*)&LlcpMac->psReceiveBuffer->length); 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 358 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac) 359 { 360 NFCSTATUS status = NFCSTATUS_SUCCESS; 361 362 if(NULL != LlcpMac) 363 { 364 LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk; 365 LlcpMac->LlcpMacInterface.activate = phFriNfc_LlcpMac_Nfcip_Activate; 366 LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate; 367 LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send; 368 LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive; 369 370 return NFCSTATUS_SUCCESS; 371 } 372 else 373 { 374 return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); 375 } 376 } 377