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 phLibNfc_discovery.c 19 20 * Project: NFC FRI 1.1 21 * 22 * $Date: Mon Mar 1 19:02:41 2010 $ 23 * $Author: ing07385 $ 24 * $Revision: 1.36 $ 25 * $Aliases: NFC_FRI1.1_WK1008_SDK,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1007_SDK,NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $ 26 * 27 */ 28 29 /* 30 ************************* Header Files **************************************** 31 */ 32 33 #include <phLibNfcStatus.h> 34 #include <phLibNfc.h> 35 #include <phHal4Nfc.h> 36 #include <phOsalNfc.h> 37 #include <phLibNfc_Internal.h> 38 #include <phLibNfc_ndef_raw.h> 39 #include <phLibNfc_initiator.h> 40 #include <phLibNfc_discovery.h> 41 42 /* 43 *************************** Macro's **************************************** 44 */ 45 46 #ifndef STATIC_DISABLE 47 #define STATIC static 48 #else 49 #define STATIC 50 #endif 51 52 /* 53 *************************** Global Variables ********************************** 54 */ 55 56 57 58 /* 59 *************************** Static Function Declaration *********************** 60 */ 61 62 63 /*Remote device Presence check callback*/ 64 STATIC void phLibNfc_RemoteDev_CheckPresence_Cb(void *context, 65 NFCSTATUS status); 66 67 /**Used for presence chk incase of mifare std tags*/ 68 STATIC void phLibNfc_ChkPresence_Trcv_Cb( 69 void *context, 70 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 71 phNfc_sData_t *response, 72 NFCSTATUS status 73 ); 74 75 /* 76 *************************** Function Definitions ****************************** 77 */ 78 void phLibNfc_config_discovery_cb(void *context, 79 NFCSTATUS status) 80 { 81 82 if((phLibNfc_LibContext_t *)context == gpphLibContext) 83 { /*check for same context*/ 84 85 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 86 { 87 /*If shutdown called in between allow shutdown to happen*/ 88 phLibNfc_Pending_Shutdown(); 89 status = NFCSTATUS_SHUTDOWN; 90 } 91 else 92 { 93 gpphLibContext->status.GenCb_pending_status = FALSE; 94 gpphLibContext->status.DiscEnbl_status = FALSE; 95 phLibNfc_UpdateCurState(status,gpphLibContext); 96 #ifdef RESTART_CFG 97 if(gpphLibContext->status.Discovery_pending_status == TRUE) 98 { 99 NFCSTATUS RetStatus = NFCSTATUS_FAILED; 100 /* Application has called discovery before receiving this callback, 101 so NO notification to the upper layer, instead lower layer 102 discovery is called */ 103 gpphLibContext->status.Discovery_pending_status = FALSE; 104 RetStatus = phHal4Nfc_ConfigureDiscovery( 105 gpphLibContext->psHwReference, 106 gpphLibContext->eLibNfcCfgMode, 107 &gpphLibContext->sADDconfig, 108 (pphLibNfc_RspCb_t) 109 phLibNfc_config_discovery_cb, 110 (void *)gpphLibContext); 111 if (NFCSTATUS_PENDING == RetStatus) 112 { 113 (void)phLibNfc_UpdateNextState(gpphLibContext, 114 eLibNfcHalStateConfigReady); 115 gpphLibContext->status.GenCb_pending_status = TRUE; 116 gpphLibContext->status.DiscEnbl_status = TRUE; 117 } 118 else 119 { 120 status = NFCSTATUS_FAILED; 121 } 122 } 123 #endif /* #ifdef RESTART_CFG */ 124 } 125 } /*End of if-context check*/ 126 else 127 { /*exception: wrong context pointer returned*/ 128 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 129 status = NFCSTATUS_FAILED; 130 } 131 if(gpphLibContext->CBInfo.pClientDisConfigCb!=NULL) 132 { 133 gpphLibContext->CBInfo.pClientDisConfigCb(gpphLibContext->CBInfo.pClientDisCfgCntx,status); 134 gpphLibContext->CBInfo.pClientDisConfigCb=NULL; 135 } 136 return; 137 } 138 /** 139 * Configure Discovery Modes. 140 * This function is used to configure ,start and stop the discovery wheel. 141 */ 142 NFCSTATUS phLibNfc_Mgt_ConfigureDiscovery ( 143 phLibNfc_eDiscoveryConfigMode_t DiscoveryMode, 144 phLibNfc_sADD_Cfg_t sADDSetup, 145 pphLibNfc_RspCb_t pConfigDiscovery_RspCb, 146 void* pContext 147 ) 148 { 149 NFCSTATUS RetVal = NFCSTATUS_FAILED; 150 phHal_sADD_Cfg_t *psADDConfig; 151 psADDConfig = (phHal_sADD_Cfg_t *)&(sADDSetup); 152 153 154 if((NULL == gpphLibContext) || 155 (gpphLibContext->LibNfcState.cur_state 156 == eLibNfcHalStateShutdown)) 157 { 158 /*Lib Nfc not initialized*/ 159 RetVal = NFCSTATUS_NOT_INITIALISED; 160 } 161 /* Check for Valid parameters*/ 162 else if((NULL == pContext) || (NULL == pConfigDiscovery_RspCb)) 163 { 164 RetVal= NFCSTATUS_INVALID_PARAMETER; 165 } 166 else if(gpphLibContext->LibNfcState.next_state 167 == eLibNfcHalStateShutdown) 168 { 169 RetVal= NFCSTATUS_SHUTDOWN; 170 } 171 else 172 { 173 gpphLibContext->eLibNfcCfgMode =DiscoveryMode; 174 gpphLibContext->sADDconfig = sADDSetup; 175 if(gpphLibContext->status.DiscEnbl_status != TRUE) 176 { 177 178 /* call lower layer config API for the discovery 179 configuration sent by the application */ 180 RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference, 181 DiscoveryMode, 182 psADDConfig, 183 (pphLibNfc_RspCb_t) 184 phLibNfc_config_discovery_cb, 185 (void*)gpphLibContext); 186 if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING) 187 { 188 gpphLibContext->status.DiscEnbl_status = TRUE; 189 /* Copy discovery callback and its context */ 190 gpphLibContext->CBInfo.pClientDisConfigCb = pConfigDiscovery_RspCb; 191 gpphLibContext->CBInfo.pClientDisCfgCntx = pContext; 192 gpphLibContext->status.GenCb_pending_status = TRUE; 193 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConfigReady; 194 } 195 else 196 { 197 if (PHNFCSTATUS(RetVal) == NFCSTATUS_BUSY) 198 { 199 RetVal = NFCSTATUS_BUSY; 200 } 201 else 202 { 203 RetVal=NFCSTATUS_FAILED; 204 } 205 } 206 207 } 208 else 209 { 210 RetVal=NFCSTATUS_BUSY; 211 } 212 } 213 return RetVal; 214 } 215 216 /** 217 * Check for target presence. 218 * Checks given target is present in RF filed or not 219 */ 220 NFCSTATUS phLibNfc_RemoteDev_CheckPresence( phLibNfc_Handle hTargetDev, 221 pphLibNfc_RspCb_t pPresenceChk_RspCb, 222 void* pRspCbCtx 223 ) 224 { 225 NFCSTATUS RetVal = NFCSTATUS_FAILED; 226 phHal_sRemoteDevInformation_t *ps_rem_dev_info = NULL; 227 /* Check for valid sate */ 228 if((NULL == gpphLibContext) || 229 (gpphLibContext->LibNfcState.cur_state 230 == eLibNfcHalStateShutdown)) 231 { 232 RetVal = NFCSTATUS_NOT_INITIALISED; 233 } 234 /* Check for valid parameters*/ 235 else if((NULL == pRspCbCtx) || (NULL == pPresenceChk_RspCb) 236 || (hTargetDev == 0) ) 237 { 238 RetVal= NFCSTATUS_INVALID_PARAMETER; 239 } 240 /* Check for DeInit call*/ 241 else if(gpphLibContext->LibNfcState.next_state 242 == eLibNfcHalStateShutdown) 243 { 244 RetVal = NFCSTATUS_SHUTDOWN; 245 } 246 /* Check target is connected or not */ 247 else if( gpphLibContext->Connected_handle == 0) 248 { 249 RetVal = NFCSTATUS_TARGET_NOT_CONNECTED; 250 } 251 /* Check given handle is valid or not*/ 252 else if(hTargetDev != gpphLibContext->Connected_handle) 253 { 254 RetVal = NFCSTATUS_INVALID_HANDLE; 255 } 256 #ifdef LLCP_TRANSACT_CHANGES 257 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) 258 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) 259 { 260 RetVal= NFCSTATUS_BUSY; 261 } 262 #endif /* #ifdef LLCP_TRANSACT_CHANGES */ 263 else 264 { 265 ps_rem_dev_info = (phHal_sRemoteDevInformation_t *) 266 gpphLibContext->Connected_handle; 267 if((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) 268 &&(0 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak) 269 &&(TRUE == gpphLibContext->LastTrancvSuccess)) 270 { 271 /* Call HAL4 API */ 272 RetVal = phHal4Nfc_Transceive( 273 gpphLibContext->psHwReference, 274 gpphLibContext->psBufferedAuth, 275 (phHal_sRemoteDevInformation_t *) 276 gpphLibContext->Connected_handle, 277 (pphHal4Nfc_TransceiveCallback_t ) 278 phLibNfc_ChkPresence_Trcv_Cb, 279 (void *)gpphLibContext 280 ); 281 282 } 283 else 284 { 285 /* Call lower layer PresenceCheck function */ 286 RetVal = phHal4Nfc_PresenceCheck(gpphLibContext->psHwReference, 287 phLibNfc_RemoteDev_CheckPresence_Cb, 288 (void *)gpphLibContext); 289 } 290 if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal)) 291 { 292 gpphLibContext->CBInfo.pClientPresChkCb = pPresenceChk_RspCb; 293 gpphLibContext->CBInfo.pClientPresChkCntx = pRspCbCtx; 294 /* Mark General callback pending status as TRUE*/ 295 gpphLibContext->status.GenCb_pending_status = TRUE; 296 297 /* Update the state machine*/ 298 gpphLibContext->LibNfcState.next_state = eLibNfcHalStatePresenceChk; 299 } 300 else /* If return value is internal error(other than pending ) return NFCSTATUS_FAILED*/ 301 { 302 RetVal = NFCSTATUS_FAILED; 303 } 304 } 305 return RetVal; 306 } 307 308 /** 309 * Response Callback for Remote device Presence Check. 310 */ 311 STATIC 312 void phLibNfc_RemoteDev_CheckPresence_Cb(void *context, 313 NFCSTATUS status) 314 { 315 void *pUpperLayerContext=NULL; 316 pphLibNfc_RspCb_t pClientCb=NULL; 317 318 /*check valid context is returned or not*/ 319 if((phLibNfc_LibContext_t *)context != gpphLibContext) 320 { 321 /*exception: wrong context pointer returned*/ 322 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 323 } 324 /* Mark general callback pending status as FALSE*/ 325 gpphLibContext->status.GenCb_pending_status = FALSE; 326 pClientCb =gpphLibContext->CBInfo.pClientPresChkCb ; 327 pUpperLayerContext = gpphLibContext->CBInfo.pClientPresChkCntx; 328 gpphLibContext->CBInfo.pClientPresChkCntx = NULL; 329 gpphLibContext->CBInfo.pClientPresChkCb =NULL; 330 /* Check DeInit call is called, if yes call pending 331 shutdown and return NFCSTATUS_SHUTDOWN */ 332 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 333 { 334 phLibNfc_Pending_Shutdown(); 335 status = NFCSTATUS_SHUTDOWN; 336 } 337 else 338 { 339 if (status != NFCSTATUS_SUCCESS) 340 { 341 /*If status is other than SUCCESS (Internal error) return 342 NFCSTATUS_TARGET_LOST */ 343 status= NFCSTATUS_TARGET_LOST; 344 } 345 else 346 { 347 status = NFCSTATUS_SUCCESS; 348 } 349 } 350 /* Update the current state */ 351 phLibNfc_UpdateCurState(status,gpphLibContext); 352 if(NULL != pClientCb) 353 { 354 /* call the upper layer callback */ 355 pClientCb(pUpperLayerContext,status); 356 } 357 return; 358 } 359 360 /**Used for presence chk incase of mifare std tags*/ 361 STATIC void phLibNfc_ChkPresence_Trcv_Cb( 362 void *context, 363 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 364 phNfc_sData_t *response, 365 NFCSTATUS status 366 ) 367 { 368 PHNFC_UNUSED_VARIABLE(psRemoteDevInfo); 369 PHNFC_UNUSED_VARIABLE(response); 370 phLibNfc_RemoteDev_CheckPresence_Cb(context,status); 371 return; 372 } 373 374 375 376