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 0x01: // 1K Classic
472 case 0x09: // Mini
473 case 0x08: // 1K
474 case 0x18: // 4K
475 case 0x88: // Infineon 1K
476 case 0x98: // Pro 4K
477 case 0xB8: // Pro 4K
478 case 0x28: // 1K emulation
479 case 0x38: // 4K emulation
480 aRemoteDevTypes[Count] = phHal_eMifare_PICC;
481 Count++;
482 break;
483 }
484 if((0 == Sak)&& (0 == Count))
485 {
486 /*Mifare check*/
487 if((NXP_UID ==
488 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0])
489 &&(NXP_MIN_UID_LEN <=
490 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength))
491 {
492 aRemoteDevTypes[Count] = phHal_eMifare_PICC;
493 Count++;
494 }
495 }
496 // Always add a separate 3A target on a separate
497 // handle, so the upper layers can connect to it.
498 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
499 Count++;
500 }
501 /*Check for P2P target passive*/
502 if((Sak & NFCIP_BITMASK) &&
503 (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&&
504 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
505 & phHal_ePassive106))
506 {
507 if( Sak == 0x53 // Fudan card incompatible to ISO18092
508 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04
509 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00
510 )
511 {
512 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
513 Count++;
514 }
515 else
516 {
517 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
518 Count++;
519 }
520 }
521 }/*case phHal_eISO14443_A_PICC:*/
522 break;
523 case phHal_eNfcIP1_Target:/*P2P target detected*/
524 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
525 Count++;
526 break;
527 case phHal_eISO14443_B_PICC: /*TYPE_B*/
528 #ifdef TYPE_B
529 aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC;
530 Count++;
531 break;
532 #endif
533 case phHal_eFelica_PICC: /*Felica*/
534 #ifdef TYPE_FELICA
535 {
536 /*nfc_id is used to differentiate between Felica and NfcIp target
537 discovered in Type F*/
538 nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0])
539 << BYTE_SIZE) |
540 psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1];
541 /*check for NfcIp target*/
542 if(NXP_NFCIP_NFCID2_ID == nfc_id)
543 {
544 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
545 &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
546 & phHal_ePassive212) ||
547 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
548 & phHal_ePassive424)))
549 {
550 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
551 Count++;
552 }
553 }
554 else/*Felica*/
555 {
556 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212
557 || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424)
558 {
559 aRemoteDevTypes[Count] = phHal_eFelica_PICC;
560 Count++;
561 }
562 }
563 break;
564 }
565 #endif
566 case phHal_eJewel_PICC: /*Jewel*/
567 #ifdef TYPE_JEWEL
568 {
569 /*Report Jewel tags only if TYPE A is enabled*/
570 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A)
571 {
572 aRemoteDevTypes[Count] = phHal_eJewel_PICC;
573 Count++;
574 }
575 break;
576 }
577 #endif
578 #ifdef TYPE_ISO15693
579 case phHal_eISO15693_PICC: /*ISO15693*/
580 {
581 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693)
582 {
583 aRemoteDevTypes[Count] = phHal_eISO15693_PICC;
584 Count++;
585 }
586 break;
587 }
588 #endif /* #ifdef TYPE_ISO15693 */
589 /*Types currently not supported*/
590 case phHal_eISO14443_BPrime_PICC:
591 default:
592 PHDBG_WARNING("Hal4:Notification for Not supported types");
593 break;
594 }/*End of switch*/
595 /*Update status code to success if atleast one device info is available*/
596 status = (((NFCSTATUS_SUCCESS != status)
597 && (NFCSTATUS_MULTIPLE_TAGS != status))
598 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
599 NFCSTATUS_SUCCESS:status;
600
601 /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this
602 is first discovery notification from Hci*/
603 status = ((NFCSTATUS_SUCCESS == status)
604 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
605 &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status);
606 /*If multiple protocols are supported ,allocate separate remote device
607 information for each protocol supported*/
608 /*Allocate and copy Remote device info into Hal4 Context*/
609 while(Count)
610 {
611 PHDBG_INFO("Hal4:Count is not zero");
612 --Count;
613 /*Allocate memory for each of Count number of
614 devices*/
615 if(NULL == Hal4Ctxt->rem_dev_list[
616 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
617 {
618 Hal4Ctxt->rem_dev_list[
619 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]
620 = (phHal_sRemoteDevInformation_t *)
621 phOsalNfc_GetMemory(
622 (uint32_t)(
623 sizeof(phHal_sRemoteDevInformation_t))
624 );
625 }
626 if(NULL == Hal4Ctxt->rem_dev_list[
627 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
628 {
629 status = PHNFCSTVAL(CID_NFC_HAL,
630 NFCSTATUS_INSUFFICIENT_RESOURCES);
631 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
632 break;
633 }
634 else
635 {
636 (void)memcpy(
637 (void *)Hal4Ctxt->rem_dev_list[
638 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices],
639 (void *)psRemoteDevInfo,
640 sizeof(phHal_sRemoteDevInformation_t)
641 );
642 /*Now copy appropriate device type from aRemoteDevTypes array*/
643 Hal4Ctxt->rem_dev_list[
644 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType
645 = aRemoteDevTypes[Count];
646 /*Increment number of devices*/
647 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++;
648 }/*End of else*/
649 }/*End of while*/
650
651 /*If Upper layer is interested only in P2P notifications*/
652 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
653 &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
654 &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType))
655 ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification))
656 )
657 {
658 PHDBG_INFO("Hal4:Trying to notify P2P Listener");
659 /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/
660 if((NFCSTATUS_SUCCESS == status)
661 ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status))
662 {
663 /*Pick only the P2P target device info from the list*/
664 for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
665 Count > 0;--Count)
666 {
667 /*Only one P2P target can be detected in one discovery*/
668 if(phHal_eNfcIP1_Target ==
669 Hal4Ctxt->rem_dev_list[Count-1]->RemDevType)
670 {
671 if (Count != 1)
672 {
673 (void)memcpy(
674 (void *)Hal4Ctxt->rem_dev_list[0],
675 (void *)Hal4Ctxt->rem_dev_list[Count-1],
676 sizeof(phHal_sRemoteDevInformation_t)
677 );
678 }
679 NfcIpDeviceCount = 1;
680 break;
681 }
682 }
683 /*If any P2p devices are discovered free other device info*/
684 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount)
685 {
686 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
687 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
688 Hal4Ctxt->rem_dev_list[
689 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
690 }
691 /*Issue P2P notification*/
692 if(NfcIpDeviceCount == 1)
693 {
694 sDiscoveryInfo.NumberOfDevices
695 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
696 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
697 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
698 PHDBG_INFO("Hal4:Calling P2P listener");
699 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)(
700 (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt),
701 NFC_DISCOVERY_NOTIFICATION,
702 uNotificationInfo,
703 NFCSTATUS_SUCCESS
704 );
705 }
706 else/*Restart Discovery wheel*/
707 {
708 PHDBG_INFO("Hal4:No P2P device in list");
709 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
710 PHDBG_INFO("Hal4:Restart discovery1");
711 status = phHciNfc_Restart_Discovery (
712 (void *)Hal4Ctxt->psHciHandle,
713 (void *)gpphHal4Nfc_Hwref,
714 FALSE
715 );
716 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
717 eHal4StateConfiguring:
718 Hal4Ctxt->Hal4NextState);
719 }
720 }
721 /*More discovery info available ,get next info from HCI*/
722 else if((NFCSTATUS_MULTIPLE_TAGS == status)
723 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices
724 < MAX_REMOTE_DEVICES))
725 {
726 status = phHciNfc_Select_Next_Target (
727 Hal4Ctxt->psHciHandle,
728 (void *)gpphHal4Nfc_Hwref
729 );
730 }
731 else/*Failed discovery ,restart discovery*/
732 {
733 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
734 PHDBG_INFO("Hal4:Restart discovery2");
735 status = phHciNfc_Restart_Discovery (
736 (void *)Hal4Ctxt->psHciHandle,
737 (void *)gpphHal4Nfc_Hwref,
738 FALSE
739 );/*Restart Discovery wheel*/
740 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
741 eHal4StateConfiguring:
742 Hal4Ctxt->Hal4NextState);
743 }
744 }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/
745 /*Notify if Upper layer is interested in tag notifications,also notify
746 P2p if its in the list with other tags*/
747 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
748 {
749 PHDBG_INFO("Hal4:Trying to notify Tag notification");
750 /*Multiple tags in field, get discovery info a second time for the
751 other devices*/
752 if((NFCSTATUS_MULTIPLE_TAGS == status)
753 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES))
754 {
755 PHDBG_INFO("Hal4:select next target1");
756 status = phHciNfc_Select_Next_Target (
757 Hal4Ctxt->psHciHandle,
758 (void *)gpphHal4Nfc_Hwref
759 );
760 }
761 /*Single tag multiple protocols scenario,Notify Multiple Protocols
762 status to upper layer*/
763 else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
764 {
765 PHDBG_INFO("Hal4:Multiple Tags or protocols");
766 sDiscoveryInfo.NumberOfDevices
767 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
768 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
769 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
770 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
771 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
772 NFC_DISCOVERY_NOTIFICATION,
773 uNotificationInfo,
774 status
775 );
776 }
777 else /*NFCSTATUS_SUCCESS*/
778 {
779 if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
780 &&(phHal_eNfcIP1_Target
781 == Hal4Ctxt->rem_dev_list[0]->RemDevType))
782 ||(NFCSTATUS_SUCCESS != status)
783 || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
784 )/*device detected but upper layer is not interested
785 in the type(P2P) or activate next failed*/
786 {
787 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0)
788 {
789 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
790 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
791 Hal4Ctxt->rem_dev_list[
792 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
793 }
794 PHDBG_INFO("Hal4:Restart discovery3");
795 status = phHciNfc_Restart_Discovery (
796 (void *)Hal4Ctxt->psHciHandle,
797 (void *)gpphHal4Nfc_Hwref,
798 FALSE
799 );/*Restart Discovery wheel*/
800 Hal4Ctxt->Hal4NextState = (
801 NFCSTATUS_PENDING == status?eHal4StateConfiguring
802 :Hal4Ctxt->Hal4NextState
803 );
804 }
805 else/*All remote device info available.Notify to upper layer*/
806 {
807 /*Update status for MULTIPLE_TAGS here*/
808 status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1?
809 NFCSTATUS_MULTIPLE_TAGS:status);
810 /*If listener is registered ,call it*/
811 sDiscoveryInfo.NumberOfDevices
812 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
813 sDiscoveryInfo.ppRemoteDevInfo
814 = Hal4Ctxt->rem_dev_list;
815 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
816 PHDBG_INFO("Hal4:Calling Discovery Handler1");
817 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
818 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
819 NFC_DISCOVERY_NOTIFICATION,
820 uNotificationInfo,
821 status
822 );
823 }
824 }
825 } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/
826 else/*listener not registered ,Restart Discovery wheel*/
827 {
828 PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery \
829 Notification");
830 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
831 PHDBG_INFO("Hal4:Restart discovery4");
832 status = phHciNfc_Restart_Discovery (
833 (void *)Hal4Ctxt->psHciHandle,
834 (void *)gpphHal4Nfc_Hwref,
835 FALSE
836 );
837 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
838 eHal4StateConfiguring:
839 Hal4Ctxt->Hal4NextState);
840 }
841 }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/
842 else/*NULL info received*/
843 {
844 sDiscoveryInfo.NumberOfDevices
845 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
846 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
847 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
848 /*If Discovery info is available from previous notifications try to
849 notify that to the upper layer*/
850 if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
851 #ifdef NFC_RF_NOISE_SW
852 &&((NFCSTATUS_SUCCESS == status)
853 || (NFCSTATUS_MULTIPLE_TAGS == status))
854 #endif /* #ifdef NFC_RF_NOISE_SW */
855 )
856 {
857 #ifndef NFC_RF_NOISE_SW
858 status = (((NFCSTATUS_SUCCESS != status)
859 && (NFCSTATUS_MULTIPLE_TAGS != status))
860 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
861 NFCSTATUS_SUCCESS:status;
862 #endif/*#ifndef NFC_RF_NOISE_SW*/
863 PHDBG_INFO("Hal4:Calling Discovery Handler2");
864 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
865 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
866 NFC_DISCOVERY_NOTIFICATION,
867 uNotificationInfo,
868 status
869 );
870 }
871 else/*Restart Discovery wheel*/
872 {
873 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
874 PHDBG_INFO("Hal4:Restart discovery5");
875 status = phHciNfc_Restart_Discovery (
876 (void *)Hal4Ctxt->psHciHandle,
877 (void *)gpphHal4Nfc_Hwref,
878 FALSE
879 );
880 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
881 eHal4StateConfiguring:Hal4Ctxt->Hal4NextState);
882 }
883 }/*else*/
884 return;
885 }
886
887
888 /**Register Notification handlers*/
phHal4Nfc_RegisterNotification(phHal_sHwReference_t * psHwReference,phHal4Nfc_RegisterType_t eRegisterType,pphHal4Nfc_Notification_t pNotificationHandler,void * Context)889 NFCSTATUS phHal4Nfc_RegisterNotification(
890 phHal_sHwReference_t *psHwReference,
891 phHal4Nfc_RegisterType_t eRegisterType,
892 pphHal4Nfc_Notification_t pNotificationHandler,
893 void *Context
894 )
895 {
896 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
897 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
898 if(NULL == pNotificationHandler || NULL == psHwReference)
899 {
900 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
901 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
902 }
903 else if((NULL == psHwReference->hal_context)
904 || (((phHal4Nfc_Hal4Ctxt_t *)
905 psHwReference->hal_context)->Hal4CurrentState
906 < eHal4StateOpenAndReady)
907 || (((phHal4Nfc_Hal4Ctxt_t *)
908 psHwReference->hal_context)->Hal4NextState
909 == eHal4StateClosed))
910 {
911 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
912 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
913 }
914 else
915 {
916 /*Extract context from hardware reference*/
917 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
918 switch(eRegisterType)
919 {
920 case eRegisterTagDiscovery:
921 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context;
922 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification
923 = pNotificationHandler; /*Register the tag Notification*/
924 break;
925 case eRegisterP2PDiscovery:
926 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context;
927 Hal4Ctxt->sUpperLayerInfo.pP2PNotification
928 = pNotificationHandler; /*Register the P2P Notification*/
929 break;
930 case eRegisterHostCardEmulation:
931 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
932 break;
933 case eRegisterSecureElement:
934 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context;
935 Hal4Ctxt->sUpperLayerInfo.pEventNotification
936 = pNotificationHandler; /*Register the Se Notification*/
937 break;
938 default:
939 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context;
940 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler
941 = pNotificationHandler; /*Register the default Notification*/
942 break;
943 }
944 PHDBG_INFO("Hal4:listener registered");
945 }
946 return RetStatus;
947 }
948
949
950 /**Unregister Notification handlers*/
phHal4Nfc_UnregisterNotification(phHal_sHwReference_t * psHwReference,phHal4Nfc_RegisterType_t eRegisterType,void * Context)951 NFCSTATUS phHal4Nfc_UnregisterNotification(
952 phHal_sHwReference_t *psHwReference,
953 phHal4Nfc_RegisterType_t eRegisterType,
954 void *Context
955 )
956 {
957 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
958 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
959 if(psHwReference == NULL)
960 {
961 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
962 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
963 }
964 else if((NULL == psHwReference->hal_context)
965 || (((phHal4Nfc_Hal4Ctxt_t *)
966 psHwReference->hal_context)->Hal4CurrentState
967 < eHal4StateOpenAndReady)
968 || (((phHal4Nfc_Hal4Ctxt_t *)
969 psHwReference->hal_context)->Hal4NextState
970 == eHal4StateClosed))
971 {
972 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
973 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
974 }
975 else
976 {
977 /*Extract context from hardware reference*/
978 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
979 switch(eRegisterType)
980 {
981 case eRegisterTagDiscovery:
982 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context;
983 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL;
984 /*UnRegister the tag Notification*/
985 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
986 PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered");
987 break;
988 case eRegisterP2PDiscovery:
989 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL;
990 /*UnRegister the p2p Notification*/
991 Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL;
992 PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered");
993 break;
994 case eRegisterHostCardEmulation:/*RFU*/
995 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
996 break;
997 /*UnRegister the Se Notification*/
998 case eRegisterSecureElement:
999 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL;
1000 Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL;
1001 PHDBG_INFO("Hal4:SE Listener Unregistered");
1002 break;
1003 default:
1004 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL;
1005 /*UnRegister the default Notification*/
1006 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL;
1007 PHDBG_INFO("Hal4:Default Listener Unregistered");
1008 break;
1009 }
1010 }
1011 return RetStatus;
1012 }
1013
1014
1015