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 RetVal=NFCSTATUS_FAILED; 198 } 199 200 } 201 else 202 { 203 RetVal=NFCSTATUS_BUSY; 204 } 205 } 206 return RetVal; 207 } 208 209 /** 210 * Check for target presence. 211 * Checks given target is present in RF filed or not 212 */ 213 NFCSTATUS phLibNfc_RemoteDev_CheckPresence( phLibNfc_Handle hTargetDev, 214 pphLibNfc_RspCb_t pPresenceChk_RspCb, 215 void* pRspCbCtx 216 ) 217 { 218 NFCSTATUS RetVal = NFCSTATUS_FAILED; 219 phHal_sRemoteDevInformation_t *ps_rem_dev_info = NULL; 220 /* Check for valid sate */ 221 if((NULL == gpphLibContext) || 222 (gpphLibContext->LibNfcState.cur_state 223 == eLibNfcHalStateShutdown)) 224 { 225 RetVal = NFCSTATUS_NOT_INITIALISED; 226 } 227 /* Check for valid parameters*/ 228 else if((NULL == pRspCbCtx) || (NULL == pPresenceChk_RspCb) 229 || (hTargetDev == 0) ) 230 { 231 RetVal= NFCSTATUS_INVALID_PARAMETER; 232 } 233 /* Check for DeInit call*/ 234 else if(gpphLibContext->LibNfcState.next_state 235 == eLibNfcHalStateShutdown) 236 { 237 RetVal = NFCSTATUS_SHUTDOWN; 238 } 239 /* Check target is connected or not */ 240 else if( gpphLibContext->Connected_handle == 0) 241 { 242 RetVal = NFCSTATUS_TARGET_NOT_CONNECTED; 243 } 244 /* Check given handle is valid or not*/ 245 else if(hTargetDev != gpphLibContext->Connected_handle) 246 { 247 RetVal = NFCSTATUS_INVALID_HANDLE; 248 } 249 #ifdef LLCP_TRANSACT_CHANGES 250 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) 251 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) 252 { 253 RetVal= NFCSTATUS_BUSY; 254 } 255 #endif /* #ifdef LLCP_TRANSACT_CHANGES */ 256 else 257 { 258 ps_rem_dev_info = (phHal_sRemoteDevInformation_t *) 259 gpphLibContext->Connected_handle; 260 if((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) 261 &&(0 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak) 262 &&(TRUE == gpphLibContext->LastTrancvSuccess)) 263 { 264 /* Call HAL4 API */ 265 RetVal = phHal4Nfc_Transceive( 266 gpphLibContext->psHwReference, 267 gpphLibContext->psBufferedAuth, 268 (phHal_sRemoteDevInformation_t *) 269 gpphLibContext->Connected_handle, 270 (pphHal4Nfc_TransceiveCallback_t ) 271 phLibNfc_ChkPresence_Trcv_Cb, 272 (void *)gpphLibContext 273 ); 274 275 } 276 else 277 { 278 /* Call lower layer PresenceCheck function */ 279 RetVal = phHal4Nfc_PresenceCheck(gpphLibContext->psHwReference, 280 phLibNfc_RemoteDev_CheckPresence_Cb, 281 (void *)gpphLibContext); 282 } 283 if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal)) 284 { 285 gpphLibContext->CBInfo.pClientPresChkCb = pPresenceChk_RspCb; 286 gpphLibContext->CBInfo.pClientPresChkCntx = pRspCbCtx; 287 /* Mark General callback pending status as TRUE*/ 288 gpphLibContext->status.GenCb_pending_status = TRUE; 289 290 /* Update the state machine*/ 291 gpphLibContext->LibNfcState.next_state = eLibNfcHalStatePresenceChk; 292 } 293 else /* If return value is internal error(other than pending ) return NFCSTATUS_FAILED*/ 294 { 295 RetVal = NFCSTATUS_FAILED; 296 } 297 } 298 return RetVal; 299 } 300 301 /** 302 * Response Callback for Remote device Presence Check. 303 */ 304 STATIC 305 void phLibNfc_RemoteDev_CheckPresence_Cb(void *context, 306 NFCSTATUS status) 307 { 308 void *pUpperLayerContext=NULL; 309 pphLibNfc_RspCb_t pClientCb=NULL; 310 311 /*check valid context is returned or not*/ 312 if((phLibNfc_LibContext_t *)context != gpphLibContext) 313 { 314 /*exception: wrong context pointer returned*/ 315 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 316 } 317 /* Mark general callback pending status as FALSE*/ 318 gpphLibContext->status.GenCb_pending_status = FALSE; 319 pClientCb =gpphLibContext->CBInfo.pClientPresChkCb ; 320 pUpperLayerContext = gpphLibContext->CBInfo.pClientPresChkCntx; 321 gpphLibContext->CBInfo.pClientPresChkCntx = NULL; 322 gpphLibContext->CBInfo.pClientPresChkCb =NULL; 323 /* Check DeInit call is called, if yes call pending 324 shutdown and return NFCSTATUS_SHUTDOWN */ 325 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 326 { 327 phLibNfc_Pending_Shutdown(); 328 status = NFCSTATUS_SHUTDOWN; 329 } 330 else 331 { 332 if (status != NFCSTATUS_SUCCESS) 333 { 334 /*If status is other than SUCCESS (Internal error) return 335 NFCSTATUS_TARGET_LOST */ 336 status= NFCSTATUS_TARGET_LOST; 337 } 338 else 339 { 340 status = NFCSTATUS_SUCCESS; 341 } 342 } 343 /* Update the current state */ 344 phLibNfc_UpdateCurState(status,gpphLibContext); 345 if(NULL != pClientCb) 346 { 347 /* call the upper layer callback */ 348 pClientCb(pUpperLayerContext,status); 349 } 350 return; 351 } 352 353 /**Used for presence chk incase of mifare std tags*/ 354 STATIC void phLibNfc_ChkPresence_Trcv_Cb( 355 void *context, 356 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 357 phNfc_sData_t *response, 358 NFCSTATUS status 359 ) 360 { 361 PHNFC_UNUSED_VARIABLE(psRemoteDevInfo); 362 PHNFC_UNUSED_VARIABLE(response); 363 phLibNfc_RemoteDev_CheckPresence_Cb(context,status); 364 return; 365 } 366 367 368 369