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 * \file phHal4Nfc_ADD.c
18 * \brief Hal4Nfc_ADD source.
19 *
20 * Project: NFC-FRI 1.1
21 *
22 * $Date: Mon May 31 11:43:42 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.151 $
25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
26 *
27 */
28
29 /* ---------------------------Include files ----------------------------------*/
30 #include <phHciNfc.h>
31 #include <phHal4Nfc.h>
32 #include <phHal4Nfc_Internal.h>
33 #include <phOsalNfc.h>
34
35 /* ------------------------------- Macros ------------------------------------*/
36 #define NFCIP_ACTIVE_SHIFT 0x03U
37 #define NXP_UID 0x04U
38 #define NXP_MIN_UID_LEN 0x07U
39 /* --------------------Structures and enumerations --------------------------*/
40
phHal4Nfc_ConfigParameters(phHal_sHwReference_t * psHwReference,phHal_eConfigType_t CfgType,phHal_uConfig_t * puConfig,pphHal4Nfc_GenCallback_t pConfigCallback,void * pContext)41 NFCSTATUS phHal4Nfc_ConfigParameters(
42 phHal_sHwReference_t *psHwReference,
43 phHal_eConfigType_t CfgType,
44 phHal_uConfig_t *puConfig,
45 pphHal4Nfc_GenCallback_t pConfigCallback,
46 void *pContext
47 )
48 {
49 NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS;
50 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
51 /*NULL checks*/
52 if(NULL == psHwReference
53 || NULL == pConfigCallback
54 || NULL == puConfig
55 )
56 {
57 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
58 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
59 }
60 /*Check if initialised*/
61 else if((NULL == psHwReference->hal_context)
62 || (((phHal4Nfc_Hal4Ctxt_t *)
63 psHwReference->hal_context)->Hal4CurrentState
64 < eHal4StateOpenAndReady)
65 || (((phHal4Nfc_Hal4Ctxt_t *)
66 psHwReference->hal_context)->Hal4NextState
67 == eHal4StateClosed))
68 {
69 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
70 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
71 }
72 else
73 {
74 Hal4Ctxt = psHwReference->hal_context;
75 /*If previous Configuration request has not completed,do not allow new
76 configuration*/
77 if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
78 {
79 PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy");
80 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
81 }
82 else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
83 {
84 /*Allocate ADD context*/
85 if (NULL == Hal4Ctxt->psADDCtxtInfo)
86 {
87 Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
88 phOsalNfc_GetMemory((uint32_t)
89 (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
90 if(NULL != Hal4Ctxt->psADDCtxtInfo)
91 {
92 (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
93 sizeof(phHal4Nfc_ADDCtxtInfo_t)
94 );
95 }
96 }
97 if(NULL == Hal4Ctxt->psADDCtxtInfo)
98 {
99 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
100 CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
101 NFCSTATUS_INSUFFICIENT_RESOURCES);
102 }
103 else
104 {
105 /*Register Upper layer context*/
106 #ifdef LLCP_DISCON_CHANGES
107 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext;
108 #else /* #ifdef LLCP_DISCON_CHANGES */
109 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
110 #endif /* #ifdef LLCP_DISCON_CHANGES */
111 switch(CfgType)
112 {
113 /*NFC_EMULATION_CONFIG*/
114 case NFC_EMULATION_CONFIG:
115 {
116 (void)memcpy((void *)&Hal4Ctxt->uConfig,
117 (void *)puConfig,
118 sizeof(phHal_uConfig_t)
119 );
120 break;
121 }
122 /*P2P Configuration*/
123 case NFC_P2P_CONFIG:
124 {
125 /*If general bytes are not provided by above layer copy zeros
126 in general bytes*/
127 if(puConfig->nfcIPConfig.generalBytesLength == 0)
128 {
129 Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength = 0x00;
130 (void)memset(Hal4Ctxt->uConfig.nfcIPConfig.generalBytes,
131 0,Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength
132 );
133 }
134 else
135 {
136 (void)memcpy((void *)&Hal4Ctxt->uConfig,
137 (void *)puConfig,
138 sizeof(phHal_uConfig_t)
139 );
140 }
141 break;
142 }
143 /*Protection config*/
144 case NFC_SE_PROTECTION_CONFIG:
145 {
146 #ifdef IGNORE_EVT_PROTECTED
147 Hal4Ctxt->Ignore_Event_Protected = FALSE;
148 #endif/*#ifdef IGNORE_EVT_PROTECTED*/
149 (void)memcpy((void *)&Hal4Ctxt->uConfig,
150 (void *)puConfig,
151 sizeof(phHal_uConfig_t)
152 );
153 break;
154 }
155 default:
156 CfgStatus = NFCSTATUS_FAILED;
157 break;
158 }
159 if ( NFCSTATUS_SUCCESS == CfgStatus )
160 {
161 /*Issue configure with given configuration*/
162 CfgStatus = phHciNfc_Configure(
163 (void *)Hal4Ctxt->psHciHandle,
164 (void *)psHwReference,
165 CfgType,
166 &Hal4Ctxt->uConfig
167 );
168 /* Change the State of the HAL only if status is Pending */
169 if ( NFCSTATUS_PENDING == CfgStatus )
170 {
171 Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
172 Hal4Ctxt->sUpperLayerInfo.pConfigCallback
173 = pConfigCallback;
174 }
175 }
176 }
177 }
178 else
179 {
180 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
181 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
182 }
183 }
184 return CfgStatus;
185 }
186
187
188 /**Configure the discovery*/
phHal4Nfc_ConfigureDiscovery(phHal_sHwReference_t * psHwReference,phHal_eDiscoveryConfigMode_t discoveryMode,phHal_sADD_Cfg_t * discoveryCfg,pphHal4Nfc_GenCallback_t pConfigCallback,void * pContext)189 NFCSTATUS phHal4Nfc_ConfigureDiscovery(
190 phHal_sHwReference_t *psHwReference,
191 phHal_eDiscoveryConfigMode_t discoveryMode,
192 phHal_sADD_Cfg_t *discoveryCfg,
193 pphHal4Nfc_GenCallback_t pConfigCallback,
194 void *pContext
195 )
196 {
197 NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS;
198 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
199 if(NULL == psHwReference
200 || NULL == pConfigCallback
201 || NULL == discoveryCfg
202 )
203 {
204 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
205 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
206 }
207 else if((NULL == psHwReference->hal_context)
208 || (((phHal4Nfc_Hal4Ctxt_t *)
209 psHwReference->hal_context)->Hal4CurrentState
210 < eHal4StateOpenAndReady)
211 || (((phHal4Nfc_Hal4Ctxt_t *)
212 psHwReference->hal_context)->Hal4NextState
213 == eHal4StateClosed))
214 {
215 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
216 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
217 }
218 else
219 {
220 Hal4Ctxt = psHwReference->hal_context;
221 /*If previous Configuration request has not completed ,do not allow
222 new configuration*/
223 if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
224 {
225 PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy");
226 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
227 }
228 else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
229 {
230 if (NULL == Hal4Ctxt->psADDCtxtInfo)
231 {
232 Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
233 phOsalNfc_GetMemory((uint32_t)
234 (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
235 if(NULL != Hal4Ctxt->psADDCtxtInfo)
236 {
237 (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
238 sizeof(phHal4Nfc_ADDCtxtInfo_t)
239 );
240 }
241 }
242 if(NULL == Hal4Ctxt->psADDCtxtInfo)
243 {
244 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
245 CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
246 NFCSTATUS_INSUFFICIENT_RESOURCES);
247 }
248 else
249 {
250 /*Register Upper layer context*/
251 #ifdef LLCP_DISCON_CHANGES
252 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext;
253 #else /* #ifdef LLCP_DISCON_CHANGES */
254 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
255 #endif /* #ifdef LLCP_DISCON_CHANGES */
256 switch(discoveryMode)
257 {
258 case NFC_DISCOVERY_START:
259 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_START");
260 break;
261 case NFC_DISCOVERY_CONFIG:
262 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_CONFIG");
263 /*Since sADDCfg is allocated in stack ,copy the ADD
264 configuration structure to HAL4 context*/
265 (void)memcpy((void *)
266 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg),
267 (void *)discoveryCfg,
268 sizeof(phHal_sADD_Cfg_t)
269 );
270 PHDBG_INFO("Hal4:Finished copying sADDCfg");
271 Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE;
272 #ifdef UPDATE_NFC_ACTIVE
273 Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo.EnableNfcActive
274 = ( 0 == Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode?
275 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode:
276 NXP_NFCIP_ACTIVE_DEFAULT);
277 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode = ((
278 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode <<
279 (NXP_NFCIP_ACTIVE_DEFAULT * NFCIP_ACTIVE_SHIFT))
280 | Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode);
281 #endif/*#ifdef UPDATE_NFC_ACTIVE*/
282 /* information system_code(Felica) and
283 AFI(ReaderB) to be populated later */
284
285 CfgStatus = phHciNfc_Config_Discovery(
286 (void *)Hal4Ctxt->psHciHandle,
287 (void *)psHwReference,
288 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
289 );/*Configure HCI Discovery*/
290 break;
291 case NFC_DISCOVERY_STOP:
292 break;
293 /*Restart Discovery wheel*/
294 case NFC_DISCOVERY_RESUME:
295 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_RESUME");
296 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
297 CfgStatus = phHciNfc_Restart_Discovery (
298 (void *)Hal4Ctxt->psHciHandle,
299 (void *)psHwReference,
300 FALSE
301 );
302 break;
303 default:
304 break;
305 }
306 /* Change the State of the HAL only if HCI Configure
307 Returns status as Pending */
308 if ( NFCSTATUS_PENDING == CfgStatus )
309 {
310 (void)memcpy((void *)
311 &(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig),
312 (void *)&(discoveryCfg->PollDevInfo.PollCfgInfo),
313 sizeof(phHal_sPollDevInfo_t)
314 );
315 PHDBG_INFO("Hal4:Finished copying PollCfgInfo");
316 PHDBG_INFO("Hal4:Configure returned NFCSTATUS_PENDING");
317 Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
318 Hal4Ctxt->sUpperLayerInfo.pConfigCallback
319 = pConfigCallback;
320 }
321 else/*Configure failed.Restore old poll dev info*/
322 {
323 (void)memcpy((void *)
324 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo),
325 (void *)&(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig),
326 sizeof(phHal_sPollDevInfo_t)
327 );
328 }
329 }
330 }
331 else
332 {
333 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
334 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
335 }
336 }
337 return CfgStatus;
338 }
339
340
341 /*Configuration completion handler*/
phHal4Nfc_ConfigureComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo,uint8_t type)342 void phHal4Nfc_ConfigureComplete(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
343 void *pInfo,
344 uint8_t type
345 )
346 {
347 pphHal4Nfc_GenCallback_t pConfigCallback
348 = Hal4Ctxt->sUpperLayerInfo.pConfigCallback;
349 pphHal4Nfc_ConnectCallback_t pUpperConnectCb
350 = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb;
351 NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
352 if((type == NFC_NOTIFY_POLL_ENABLED) ||(type == NFC_NOTIFY_POLL_RESTARTED))
353 {
354 Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = TRUE;
355 PHDBG_INFO("Hal4:Poll Config Complete");
356 }
357 else
358 {
359 Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = FALSE;
360 PHDBG_WARNING("Hal4:Poll disabled,config success or config error");
361 }
362 if(NULL != Hal4Ctxt->sUpperLayerInfo.pConfigCallback)
363 {
364 #ifdef MERGE_SAK_SW2
365 if((NFC_UICC_EMULATION == Hal4Ctxt->uConfig.emuConfig.emuType)&&
366 (FALSE ==
367 Hal4Ctxt->uConfig.emuConfig.config.uiccEmuCfg.enableUicc))
368 {
369 Status = phHciNfc_System_Configure (
370 Hal4Ctxt->psHciHandle,
371 (void *)gpphHal4Nfc_Hwref,
372 PH_HAL4NFC_TGT_MERGE_ADDRESS,
373 PH_HAL4NFC_TGT_MERGE_SAK /*config value*/
374 );
375 }
376 if(NFCSTATUS_PENDING != Status)
377 {
378 #endif/*#ifdef MERGE_SAK_SW2*/
379 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
380 Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL;
381 (*pConfigCallback)(
382 #ifdef LLCP_DISCON_CHANGES
383 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt,
384 #else /* #ifdef LLCP_DISCON_CHANGES */
385 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
386 #endif /* #ifdef LLCP_DISCON_CHANGES */
387 Status
388 );
389 #ifdef MERGE_SAK_SW2
390 }
391 #endif/*#ifdef MERGE_SAK_SW2*/
392 }
393 /**if connect failed and discovery wheel was restarted*/
394 else if(Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
395 {
396 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
397 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
398 /*Notify to the upper layer*/
399 (*pUpperConnectCb)(
400 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
401 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
402 NFCSTATUS_FAILED
403 );
404 }
405 else
406 {
407 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
408 /**if disconnect failed and discovery wheel was restarted*/
409 if ( NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb)
410 {
411 ((phNfc_sCompletionInfo_t *)pInfo)->status = NFCSTATUS_SUCCESS;
412 phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
413 }
414 }
415 }
416
417
418 /**Handler for Target discovery completion for all remote device types*/
phHal4Nfc_TargetDiscoveryComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)419 void phHal4Nfc_TargetDiscoveryComplete(
420 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
421 void *pInfo
422 )
423 {
424 static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo;
425 NFCSTATUS status = NFCSTATUS_SUCCESS;
426 /**SAK byte*/
427 uint8_t Sak = 0;
428 /*Union type to encapsulate and return the discovery info*/
429 phHal4Nfc_NotificationInfo_t uNotificationInfo;
430 /*All the following types will be discovered as type A ,and differentiation
431 will have to be done within this module based on SAK byte and UID info*/
432 phHal_eRemDevType_t aRemoteDevTypes[3] = {
433 phHal_eISO14443_A_PICC,
434 phHal_eNfcIP1_Target,
435 phHal_eMifare_PICC
436 };
437 /*Count is used to add multiple info into remote dvice list for devices that
438 support multiple protocols*/
439 uint8_t Count = 0,
440 NfcIpDeviceCount = 0;/**<Number of NfcIp devices discovered*/
441 uint16_t nfc_id = 0;
442 /*remote device info*/
443 phHal_sRemoteDevInformation_t *psRemoteDevInfo = NULL;
444 status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
445 /*Update Hal4 state*/
446 Hal4Ctxt->Hal4CurrentState = eHal4StateTargetDiscovered;
447 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
448 PHDBG_INFO("Hal4:Remotedevice Discovered");
449 if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)
450 {
451 /*Extract Remote device Info*/
452 psRemoteDevInfo = (phHal_sRemoteDevInformation_t *)
453 ((phNfc_sCompletionInfo_t *)pInfo)->info;
454
455 switch(psRemoteDevInfo->RemDevType)
456 {
457 case phHal_eISO14443_A_PICC:/*for TYPE A*/
458 {
459 Sak = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
460 if((Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A)
461 || (TRUE == Hal4Ctxt->psADDCtxtInfo->smx_discovery))
462 {
463 /*Check if Iso is Supported*/
464 if(Sak & ISO_14443_BITMASK)
465 {
466 Count++;
467 }
468 /*Check for Mifare Supported*/
469 switch( Sak )
470 {
471 case 0x09: // Mini
472 case 0x08: // 1K
473 case 0x18: // 4K
474 case 0x88: // Infineon 1K
475 case 0x98: // Pro 4K
476 case 0xB8: // Pro 4K
477 case 0x28: // 1K emulation
478 case 0x38: // 4K emulation
479 aRemoteDevTypes[Count] = phHal_eMifare_PICC;
480 Count++;
481 break;
482 }
483 if((0 == Sak)&& (0 == Count))
484 {
485 /*Mifare check*/
486 if((NXP_UID ==
487 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0])
488 &&(NXP_MIN_UID_LEN <=
489 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength))
490 {
491 aRemoteDevTypes[Count] = phHal_eMifare_PICC;
492
493 }
494 else/*TYPE 3A*/
495 {
496 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
497 }
498 Count++;
499 }
500 else if ( !(Sak & ISO_14443_BITMASK) &&
501 !(Sak & NFCIP_BITMASK) && (0 == Count))
502 {
503 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
504 Count++;
505 }
506 }
507 /*Check for P2P target passive*/
508 if((Sak & NFCIP_BITMASK) &&
509 (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&&
510 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
511 & phHal_ePassive106))
512 {
513 if( Sak == 0x53 // Fudan card incompatible to ISO18092
514 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04
515 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00
516 )
517 {
518 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
519 Count++;
520 }
521 else
522 {
523 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
524 Count++;
525 }
526 }
527 }/*case phHal_eISO14443_A_PICC:*/
528 break;
529 case phHal_eNfcIP1_Target:/*P2P target detected*/
530 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
531 Count++;
532 break;
533 case phHal_eISO14443_B_PICC: /*TYPE_B*/
534 #ifdef TYPE_B
535 aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC;
536 Count++;
537 break;
538 #endif
539 case phHal_eFelica_PICC: /*Felica*/
540 #ifdef TYPE_FELICA
541 {
542 /*nfc_id is used to differentiate between Felica and NfcIp target
543 discovered in Type F*/
544 nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0])
545 << BYTE_SIZE) |
546 psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1];
547 /*check for NfcIp target*/
548 if(NXP_NFCIP_NFCID2_ID == nfc_id)
549 {
550 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
551 &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
552 & phHal_ePassive212) ||
553 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
554 & phHal_ePassive424)))
555 {
556 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
557 Count++;
558 }
559 }
560 else/*Felica*/
561 {
562 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212
563 || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424)
564 {
565 aRemoteDevTypes[Count] = phHal_eFelica_PICC;
566 Count++;
567 }
568 }
569 break;
570 }
571 #endif
572 case phHal_eJewel_PICC: /*Jewel*/
573 #ifdef TYPE_JEWEL
574 {
575 /*Report Jewel tags only if TYPE A is enabled*/
576 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A)
577 {
578 aRemoteDevTypes[Count] = phHal_eJewel_PICC;
579 Count++;
580 }
581 break;
582 }
583 #endif
584 #ifdef TYPE_ISO15693
585 case phHal_eISO15693_PICC: /*ISO15693*/
586 {
587 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693)
588 {
589 aRemoteDevTypes[Count] = phHal_eISO15693_PICC;
590 Count++;
591 }
592 break;
593 }
594 #endif /* #ifdef TYPE_ISO15693 */
595 /*Types currently not supported*/
596 case phHal_eISO14443_BPrime_PICC:
597 default:
598 PHDBG_WARNING("Hal4:Notification for Not supported types");
599 break;
600 }/*End of switch*/
601 /*Update status code to success if atleast one device info is available*/
602 status = (((NFCSTATUS_SUCCESS != status)
603 && (NFCSTATUS_MULTIPLE_TAGS != status))
604 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
605 NFCSTATUS_SUCCESS:status;
606
607 /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this
608 is first discovery notification from Hci*/
609 status = ((NFCSTATUS_SUCCESS == status)
610 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
611 &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status);
612 /*If multiple protocols are supported ,allocate separate remote device
613 information for each protocol supported*/
614 /*Allocate and copy Remote device info into Hal4 Context*/
615 while(Count)
616 {
617 PHDBG_INFO("Hal4:Count is not zero");
618 --Count;
619 /*Allocate memory for each of Count number of
620 devices*/
621 if(NULL == Hal4Ctxt->rem_dev_list[
622 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
623 {
624 Hal4Ctxt->rem_dev_list[
625 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]
626 = (phHal_sRemoteDevInformation_t *)
627 phOsalNfc_GetMemory(
628 (uint32_t)(
629 sizeof(phHal_sRemoteDevInformation_t))
630 );
631 }
632 if(NULL == Hal4Ctxt->rem_dev_list[
633 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
634 {
635 status = PHNFCSTVAL(CID_NFC_HAL,
636 NFCSTATUS_INSUFFICIENT_RESOURCES);
637 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
638 break;
639 }
640 else
641 {
642 (void)memcpy(
643 (void *)Hal4Ctxt->rem_dev_list[
644 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices],
645 (void *)psRemoteDevInfo,
646 sizeof(phHal_sRemoteDevInformation_t)
647 );
648 /*Now copy appropriate device type from aRemoteDevTypes array*/
649 Hal4Ctxt->rem_dev_list[
650 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType
651 = aRemoteDevTypes[Count];
652 /*Increment number of devices*/
653 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++;
654 }/*End of else*/
655 }/*End of while*/
656
657 /*If Upper layer is interested only in P2P notifications*/
658 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
659 &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
660 &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType))
661 ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification))
662 )
663 {
664 PHDBG_INFO("Hal4:Trying to notify P2P Listener");
665 /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/
666 if((NFCSTATUS_SUCCESS == status)
667 ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status))
668 {
669 /*Pick only the P2P target device info from the list*/
670 for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
671 Count > 0;--Count)
672 {
673 /*Only one P2P target can be detected in one discovery*/
674 if(phHal_eNfcIP1_Target ==
675 Hal4Ctxt->rem_dev_list[Count-1]->RemDevType)
676 {
677 (void)memcpy(
678 (void *)Hal4Ctxt->rem_dev_list[0],
679 (void *)Hal4Ctxt->rem_dev_list[Count-1],
680 sizeof(phHal_sRemoteDevInformation_t)
681 );
682 NfcIpDeviceCount = 1;
683 break;
684 }
685 }
686 /*If any P2p devices are discovered free other device info*/
687 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount)
688 {
689 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
690 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
691 Hal4Ctxt->rem_dev_list[
692 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
693 }
694 /*Issue P2P notification*/
695 if(NfcIpDeviceCount == 1)
696 {
697 sDiscoveryInfo.NumberOfDevices
698 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
699 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
700 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
701 PHDBG_INFO("Hal4:Calling P2P listener");
702 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)(
703 (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt),
704 NFC_DISCOVERY_NOTIFICATION,
705 uNotificationInfo,
706 NFCSTATUS_SUCCESS
707 );
708 }
709 else/*Restart Discovery wheel*/
710 {
711 PHDBG_INFO("Hal4:No P2P device in list");
712 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
713 PHDBG_INFO("Hal4:Restart discovery1");
714 status = phHciNfc_Restart_Discovery (
715 (void *)Hal4Ctxt->psHciHandle,
716 (void *)gpphHal4Nfc_Hwref,
717 FALSE
718 );
719 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
720 eHal4StateConfiguring:
721 Hal4Ctxt->Hal4NextState);
722 }
723 }
724 /*More discovery info available ,get next info from HCI*/
725 else if((NFCSTATUS_MULTIPLE_TAGS == status)
726 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices
727 < MAX_REMOTE_DEVICES))
728 {
729 status = phHciNfc_Select_Next_Target (
730 Hal4Ctxt->psHciHandle,
731 (void *)gpphHal4Nfc_Hwref
732 );
733 }
734 else/*Failed discovery ,restart discovery*/
735 {
736 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
737 PHDBG_INFO("Hal4:Restart discovery2");
738 status = phHciNfc_Restart_Discovery (
739 (void *)Hal4Ctxt->psHciHandle,
740 (void *)gpphHal4Nfc_Hwref,
741 FALSE
742 );/*Restart Discovery wheel*/
743 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
744 eHal4StateConfiguring:
745 Hal4Ctxt->Hal4NextState);
746 }
747 }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/
748 /*Notify if Upper layer is interested in tag notifications,also notify
749 P2p if its in the list with other tags*/
750 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
751 {
752 PHDBG_INFO("Hal4:Trying to notify Tag notification");
753 /*Multiple tags in field, get discovery info a second time for the
754 other devices*/
755 if((NFCSTATUS_MULTIPLE_TAGS == status)
756 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES))
757 {
758 PHDBG_INFO("Hal4:select next target1");
759 status = phHciNfc_Select_Next_Target (
760 Hal4Ctxt->psHciHandle,
761 (void *)gpphHal4Nfc_Hwref
762 );
763 }
764 /*Single tag multiple protocols scenario,Notify Multiple Protocols
765 status to upper layer*/
766 else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
767 {
768 PHDBG_INFO("Hal4:Multiple Tags or protocols");
769 sDiscoveryInfo.NumberOfDevices
770 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
771 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
772 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
773 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
774 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
775 NFC_DISCOVERY_NOTIFICATION,
776 uNotificationInfo,
777 status
778 );
779 }
780 else /*NFCSTATUS_SUCCESS*/
781 {
782 if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
783 &&(phHal_eNfcIP1_Target
784 == Hal4Ctxt->rem_dev_list[0]->RemDevType))
785 ||(NFCSTATUS_SUCCESS != status)
786 || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
787 )/*device detected but upper layer is not interested
788 in the type(P2P) or activate next failed*/
789 {
790 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0)
791 {
792 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
793 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
794 Hal4Ctxt->rem_dev_list[
795 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
796 }
797 PHDBG_INFO("Hal4:Restart discovery3");
798 status = phHciNfc_Restart_Discovery (
799 (void *)Hal4Ctxt->psHciHandle,
800 (void *)gpphHal4Nfc_Hwref,
801 FALSE
802 );/*Restart Discovery wheel*/
803 Hal4Ctxt->Hal4NextState = (
804 NFCSTATUS_PENDING == status?eHal4StateConfiguring
805 :Hal4Ctxt->Hal4NextState
806 );
807 }
808 else/*All remote device info available.Notify to upper layer*/
809 {
810 /*Update status for MULTIPLE_TAGS here*/
811 status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1?
812 NFCSTATUS_MULTIPLE_TAGS:status);
813 /*If listener is registered ,call it*/
814 sDiscoveryInfo.NumberOfDevices
815 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
816 sDiscoveryInfo.ppRemoteDevInfo
817 = Hal4Ctxt->rem_dev_list;
818 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
819 PHDBG_INFO("Hal4:Calling Discovery Handler1");
820 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
821 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
822 NFC_DISCOVERY_NOTIFICATION,
823 uNotificationInfo,
824 status
825 );
826 }
827 }
828 } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/
829 else/*listener not registered ,Restart Discovery wheel*/
830 {
831 PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery \
832 Notification");
833 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
834 PHDBG_INFO("Hal4:Restart discovery4");
835 status = phHciNfc_Restart_Discovery (
836 (void *)Hal4Ctxt->psHciHandle,
837 (void *)gpphHal4Nfc_Hwref,
838 FALSE
839 );
840 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
841 eHal4StateConfiguring:
842 Hal4Ctxt->Hal4NextState);
843 }
844 }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/
845 else/*NULL info received*/
846 {
847 sDiscoveryInfo.NumberOfDevices
848 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
849 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
850 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
851 /*If Discovery info is available from previous notifications try to
852 notify that to the upper layer*/
853 if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
854 #ifdef NFC_RF_NOISE_SW
855 &&((NFCSTATUS_SUCCESS == status)
856 || (NFCSTATUS_MULTIPLE_TAGS == status))
857 #endif /* #ifdef NFC_RF_NOISE_SW */
858 )
859 {
860 #ifndef NFC_RF_NOISE_SW
861 status = (((NFCSTATUS_SUCCESS != status)
862 && (NFCSTATUS_MULTIPLE_TAGS != status))
863 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
864 NFCSTATUS_SUCCESS:status;
865 #endif/*#ifndef NFC_RF_NOISE_SW*/
866 PHDBG_INFO("Hal4:Calling Discovery Handler2");
867 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
868 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
869 NFC_DISCOVERY_NOTIFICATION,
870 uNotificationInfo,
871 status
872 );
873 }
874 else/*Restart Discovery wheel*/
875 {
876 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
877 PHDBG_INFO("Hal4:Restart discovery5");
878 status = phHciNfc_Restart_Discovery (
879 (void *)Hal4Ctxt->psHciHandle,
880 (void *)gpphHal4Nfc_Hwref,
881 FALSE
882 );
883 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
884 eHal4StateConfiguring:Hal4Ctxt->Hal4NextState);
885 }
886 }/*else*/
887 return;
888 }
889
890
891 /**Register Notification handlers*/
phHal4Nfc_RegisterNotification(phHal_sHwReference_t * psHwReference,phHal4Nfc_RegisterType_t eRegisterType,pphHal4Nfc_Notification_t pNotificationHandler,void * Context)892 NFCSTATUS phHal4Nfc_RegisterNotification(
893 phHal_sHwReference_t *psHwReference,
894 phHal4Nfc_RegisterType_t eRegisterType,
895 pphHal4Nfc_Notification_t pNotificationHandler,
896 void *Context
897 )
898 {
899 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
900 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
901 if(NULL == pNotificationHandler || NULL == psHwReference)
902 {
903 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
904 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
905 }
906 else if((NULL == psHwReference->hal_context)
907 || (((phHal4Nfc_Hal4Ctxt_t *)
908 psHwReference->hal_context)->Hal4CurrentState
909 < eHal4StateOpenAndReady)
910 || (((phHal4Nfc_Hal4Ctxt_t *)
911 psHwReference->hal_context)->Hal4NextState
912 == eHal4StateClosed))
913 {
914 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
915 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
916 }
917 else
918 {
919 /*Extract context from hardware reference*/
920 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
921 switch(eRegisterType)
922 {
923 case eRegisterTagDiscovery:
924 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context;
925 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification
926 = pNotificationHandler; /*Register the tag Notification*/
927 break;
928 case eRegisterP2PDiscovery:
929 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context;
930 Hal4Ctxt->sUpperLayerInfo.pP2PNotification
931 = pNotificationHandler; /*Register the P2P Notification*/
932 break;
933 case eRegisterHostCardEmulation:
934 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
935 break;
936 case eRegisterSecureElement:
937 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context;
938 Hal4Ctxt->sUpperLayerInfo.pEventNotification
939 = pNotificationHandler; /*Register the Se Notification*/
940 break;
941 default:
942 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context;
943 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler
944 = pNotificationHandler; /*Register the default Notification*/
945 break;
946 }
947 PHDBG_INFO("Hal4:listener registered");
948 }
949 return RetStatus;
950 }
951
952
953 /**Unregister Notification handlers*/
phHal4Nfc_UnregisterNotification(phHal_sHwReference_t * psHwReference,phHal4Nfc_RegisterType_t eRegisterType,void * Context)954 NFCSTATUS phHal4Nfc_UnregisterNotification(
955 phHal_sHwReference_t *psHwReference,
956 phHal4Nfc_RegisterType_t eRegisterType,
957 void *Context
958 )
959 {
960 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
961 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
962 if(psHwReference == NULL)
963 {
964 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
965 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
966 }
967 else if((NULL == psHwReference->hal_context)
968 || (((phHal4Nfc_Hal4Ctxt_t *)
969 psHwReference->hal_context)->Hal4CurrentState
970 < eHal4StateOpenAndReady)
971 || (((phHal4Nfc_Hal4Ctxt_t *)
972 psHwReference->hal_context)->Hal4NextState
973 == eHal4StateClosed))
974 {
975 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
976 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
977 }
978 else
979 {
980 /*Extract context from hardware reference*/
981 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
982 switch(eRegisterType)
983 {
984 case eRegisterTagDiscovery:
985 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context;
986 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL;
987 /*UnRegister the tag Notification*/
988 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
989 PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered");
990 break;
991 case eRegisterP2PDiscovery:
992 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL;
993 /*UnRegister the p2p Notification*/
994 Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL;
995 PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered");
996 break;
997 case eRegisterHostCardEmulation:/*RFU*/
998 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
999 break;
1000 /*UnRegister the Se Notification*/
1001 case eRegisterSecureElement:
1002 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL;
1003 Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL;
1004 PHDBG_INFO("Hal4:SE Listener Unregistered");
1005 break;
1006 default:
1007 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL;
1008 /*UnRegister the default Notification*/
1009 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL;
1010 PHDBG_INFO("Hal4:Default Listener Unregistered");
1011 break;
1012 }
1013 }
1014 return RetStatus;
1015 }
1016
1017
1018