2 * Copyright (C) 2010 NXP Semiconductors
3 * Copyright (C) 2012 Samsung Elevtronics Co., Ltd
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * \brief DAL Implementation for linux
22 * Project: Trusted NFC Linux Lignt
25 * $Author: Jonathan roux
36 #include <linux/ipc.h>
40 #include <semaphore.h>
41 #include <phDal4Nfc.h>
42 #include <phOsalNfc.h>
43 #include <phNfcStatus.h>
44 #include <phDal4Nfc_DeferredCall.h>
45 #include <phDal4Nfc_debug.h>
46 #include <phDal4Nfc_uart.h>
47 #include <phDal4Nfc_i2c.h>
48 #include <phDal4Nfc_link.h>
49 #include <phDal4Nfc_messageQueueLib.h>
50 #include <phDal4Nfc_message_glib.h>
56 /*-----------------------------------------------------------------------------------
58 ------------------------------------------------------------------------------------*/
59 #define DEFAULT_LINK_TYPE PN544_LINK_TYPE_I2C
61 /*-----------------------------------------------------------------------------------
63 ------------------------------------------------------------------------------------*/
64 /*structure holds members related for both read and write operations*/
65 typedef struct Dal_RdWr_st
68 pthread_t nReadThread; /* Read thread Hanlde */
69 uint8_t * pReadBuffer; /* Read local buffer */
70 uint8_t * pReadBufferTmp; /* Read local buffer (to read on I2C in once)*/
71 int nNbOfBytesToRead; /* Number of bytes to read */
72 int nNbOfBytesRead; /* Number of read bytes */
73 int nNbOfBytesReadTmp; /* Number of read bytes (to read on I2C in once)*/
74 char nReadBusy; /* Read state machine */
75 char nReadThreadAlive; /* Read state machine */
76 char nWaitingOnRead; /* Read state machine */
78 /* Read wait members */
79 uint8_t * pReadWaitBuffer; /* Read wait local Buffer */
80 int nNbOfBytesToReadWait; /* Number of bytes to read */
81 int nNbOfBytesReadWait; /* Number of read bytes */
82 char nReadWaitBusy; /* Read state machine */
83 char nWaitingOnReadWait; /* Read state machine */
84 char nCancelReadWait; /* Read state machine */
87 pthread_t nWriteThread; /* Write thread Hanlde */
88 uint8_t * pWriteBuffer; /* Write local buffer */
89 uint8_t * pTempWriteBuffer; /* Temp Write local buffer */
90 int nNbOfBytesToWrite; /* Number of bytes to write */
91 int nNbOfBytesWritten; /* Number of bytes written */
92 char nWaitingOnWrite; /* Write state machine */
93 char nWriteThreadAlive; /* Write state machine */
94 char nWriteBusy; /* Write state machine */
97 typedef void (*pphDal4Nfc_DeferFuncPointer_t) (void * );
98 typedef void * (*pphDal4Nfc_thread_handler_t) (void * pParam);
101 /*-----------------------------------------------------------------------------------
103 ------------------------------------------------------------------------------------*/
104 static phDal4Nfc_RdWr_t gReadWriteContext;
105 static phDal4Nfc_SContext_t gDalContext;
106 static pphDal4Nfc_SContext_t pgDalContext;
107 static phHal_sHwReference_t * pgDalHwContext;
108 static sem_t nfc_read_sem;
109 static int low_level_traces;
110 #ifdef USE_MQ_MESSAGE_QUEUE
111 static phDal4Nfc_DeferredCall_Msg_t nDeferedMessage;
112 static mqd_t nDeferedCallMessageQueueId;
115 int nDeferedCallMessageQueueId = 0;
117 static phDal4Nfc_link_cbk_interface_t gLinkFunc;
118 /*-----------------------------------------------------------------------------------
120 ------------------------------------------------------------------------------------*/
121 static void phDal4Nfc_DeferredCb (void *params);
122 static NFCSTATUS phDal4Nfc_StartThreads (void);
123 static void phDal4Nfc_FillMsg (phDal4Nfc_Message_t *pDalMsg, phOsalNfc_Message_t *pOsalMsg);
125 /*-----------------------------------------------------------------------------------
126 DAL API IMPLEMENTATION
127 ------------------------------------------------------------------------------------*/
129 static void refresh_low_level_traces() {
130 #ifdef LOW_LEVEL_TRACES
131 low_level_traces = 1;
136 char value[PROPERTY_VALUE_MAX];
138 property_get("ro.debuggable", value, "");
139 if (!value[0] || !atoi(value)) {
140 low_level_traces = 0; // user build, do not allow debug
144 property_get("debug.nfc.LOW_LEVEL_TRACES", value, "0");
146 low_level_traces = atoi(value);
150 low_level_traces = 0;
154 /*-----------------------------------------------------------------------------
156 FUNCTION: phDal4Nfc_Register
158 PURPOSE: DAL register function.
160 -----------------------------------------------------------------------------*/
161 NFCSTATUS phDal4Nfc_Register( phNfcIF_sReference_t *psRefer,
162 phNfcIF_sCallBack_t if_cb, void *psIFConf )
164 NFCSTATUS result = NFCSTATUS_SUCCESS;
166 if ((NULL != psRefer) &&
167 (NULL != psRefer->plower_if) &&
168 (NULL != if_cb.receive_complete) &&
169 (NULL != if_cb.send_complete)
172 /* Register the LLC functions to the upper layer */
173 psRefer->plower_if->init = phDal4Nfc_Init;
174 psRefer->plower_if->release = phDal4Nfc_Shutdown;
175 psRefer->plower_if->send = phDal4Nfc_Write;
176 psRefer->plower_if->receive = phDal4Nfc_Read;
177 psRefer->plower_if->receive_wait = phDal4Nfc_ReadWait;
178 psRefer->plower_if->transact_abort = phDal4Nfc_ReadWaitCancel;
179 psRefer->plower_if->unregister = phDal4Nfc_Unregister;
182 if (NULL != pgDalContext)
184 /* Copy the DAL context to the upper layer */
185 psRefer->plower_if->pcontext = pgDalContext;
186 /* Register the callback function from the upper layer */
187 pgDalContext->cb_if.receive_complete = if_cb.receive_complete;
188 pgDalContext->cb_if.send_complete = if_cb.send_complete;
189 pgDalContext->cb_if.notify = if_cb.notify;
190 /* Get the upper layer context */
191 pgDalContext->cb_if.pif_ctxt = if_cb.pif_ctxt;
192 /* Update the error state */
193 result = NFCSTATUS_SUCCESS;
197 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_NOT_INITIALISED);
200 else /*Input parameters invalid*/
202 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_PARAMETER);
207 /*-----------------------------------------------------------------------------
209 FUNCTION: phDal4Nfc_Unregister
211 PURPOSE: DAL unregister function.
213 -----------------------------------------------------------------------------*/
214 NFCSTATUS phDal4Nfc_Unregister(void *pContext, void *pHwRef )
216 NFCSTATUS result = NFCSTATUS_SUCCESS;
218 if ((NULL == pContext) && (NULL == pHwRef))
220 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_PARAMETER);
224 if (NULL != pgDalContext)
226 /* Register the callback function from the upper layer */
227 pgDalContext->cb_if.receive_complete = NULL;
228 pgDalContext->cb_if.send_complete = NULL ;
229 pgDalContext->cb_if.notify = NULL ;
230 /* Get the upper layer context */
231 pgDalContext->cb_if.pif_ctxt = NULL ;
236 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_NOT_INITIALISED);
242 /*-----------------------------------------------------------------------------
244 FUNCTION: phDal4Nfc_Init
246 PURPOSE: DAL Init function.
248 -----------------------------------------------------------------------------*/
249 NFCSTATUS phDal4Nfc_Init(void *pContext, void *pHwRef )
251 NFCSTATUS result = NFCSTATUS_SUCCESS;
253 // refresh_low_level_traces();
255 if ((NULL != pContext) && (NULL != pHwRef))
257 pContext = pgDalContext;
258 pgDalHwContext = (phHal_sHwReference_t *)pHwRef;
260 if ( gDalContext.hw_valid == TRUE )
262 /* The link has been opened from the application interface */
263 gLinkFunc.open_from_handle(pgDalHwContext);
265 if (!gLinkFunc.is_opened())
267 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
271 /* Clear link buffers */
277 static phDal4Nfc_sConfig_t hw_config;
278 hw_config.deviceNode = NULL;
279 result = phDal4Nfc_Config(&hw_config, pHwRef );
282 else /*Input parametrs invalid*/
284 result = NFCSTATUS_INVALID_PARAMETER;
290 /*-----------------------------------------------------------------------------
292 FUNCTION: phDal4Nfc_Shutdown
294 PURPOSE: DAL Shutdown function.
296 -----------------------------------------------------------------------------*/
298 NFCSTATUS phDal4Nfc_Shutdown( void *pContext, void *pHwRef)
300 NFCSTATUS result = NFCSTATUS_SUCCESS;
301 // void * pThreadReturn;
303 // if (pContext == NULL)
304 // return NFCSTATUS_INVALID_PARAMETER;
306 if (gDalContext.hw_valid == TRUE)
311 /* Close the message queue */
312 #ifdef USE_MQ_MESSAGE_QUEUE
313 mq_close(nDeferedCallMessageQueueId);
321 NFCSTATUS phDal4Nfc_ConfigRelease(void *pHwRef)
324 NFCSTATUS result = NFCSTATUS_SUCCESS;
325 void * pThreadReturn;
327 DAL_PRINT("phDal4Nfc_ConfigRelease ");
329 if (gDalContext.hw_valid == TRUE)
331 /* Kill the read and write threads */
332 gReadWriteContext.nReadThreadAlive = 0;
333 gReadWriteContext.nWriteThreadAlive = 0;
335 DAL_PRINT("Release Read Semaphore");
336 sem_post(&nfc_read_sem);
341 // hyogil.kim :: lock issue is found
342 pthread_kill(gReadWriteContext.nReadThread, SIGTERM);
344 if (pthread_join(gReadWriteContext.nReadThread, &pThreadReturn) != 0)
346 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED);
347 DAL_PRINT("phDal4Nfc_ConfigRelease KO");
350 /* Close the message queue */
351 #ifdef USE_MQ_MESSAGE_QUEUE
352 mq_close(nDeferedCallMessageQueueId);
355 /* Shutdown NFC Chip */
359 // gLinkFunc.close();
361 /* Reset the Read Writer context to NULL */
362 memset((void *)&gReadWriteContext,0,sizeof(gReadWriteContext));
363 /* Reset the DAL context values to NULL */
364 memset((void *)&gDalContext,0,sizeof(gDalContext));
367 sem_destroy(&nfc_read_sem);
370 gDalContext.hw_valid = FALSE;
372 DAL_DEBUG("phDal4Nfc_ConfigRelease(): %04x\n", result);
378 /*-----------------------------------------------------------------------------
380 FUNCTION: phDal4Nfc_Write
382 PURPOSE: DAL Write function.
384 -----------------------------------------------------------------------------*/
386 NFCSTATUS phDal4Nfc_Write( void *pContext, void *pHwRef,uint8_t *pBuffer, uint16_t length)
388 NFCSTATUS result = NFCSTATUS_SUCCESS;
389 static int MsgType= PHDAL4NFC_WRITE_MESSAGE;
390 int * pmsgType=&MsgType;
391 phDal4Nfc_Message_t sMsg;
392 phOsalNfc_Message_t OsalMsg;
394 if ((NULL != pContext) && (NULL != pHwRef)&&
395 (NULL != pBuffer) && (0 != length))
397 if( gDalContext.hw_valid== TRUE)
399 if((!gReadWriteContext.nWriteBusy)&&
400 (!gReadWriteContext.nWaitingOnWrite))
402 DAL_PRINT("phDal4Nfc_Write() : Temporary buffer !! \n");
403 gReadWriteContext.pTempWriteBuffer = (uint8_t*)malloc(length * sizeof(uint8_t));
404 /* Make a copy of the passed arguments */
405 memcpy(gReadWriteContext.pTempWriteBuffer,pBuffer,length);
406 DAL_DEBUG("phDal4Nfc_Write(): %d\n", length);
407 gReadWriteContext.pWriteBuffer = gReadWriteContext.pTempWriteBuffer;
408 gReadWriteContext.nNbOfBytesToWrite = length;
409 /* Change the write state so that thread can take over the write */
410 gReadWriteContext.nWriteBusy = TRUE;
411 /* Just set variable here. This is the trigger for the Write thread */
412 gReadWriteContext.nWaitingOnWrite = TRUE;
413 /* Update the error state */
414 result = NFCSTATUS_PENDING;
415 /* Send Message and perform physical write in the DefferedCallback */
416 /* read completed immediately */
417 sMsg.eMsgType= PHDAL4NFC_WRITE_MESSAGE;
418 /* Update the state */
419 phDal4Nfc_FillMsg(&sMsg,&OsalMsg);
420 phDal4Nfc_DeferredCall((pphDal4Nfc_DeferFuncPointer_t)phDal4Nfc_DeferredCb,(void *)pmsgType);
421 memset(&sMsg,0,sizeof(phDal4Nfc_Message_t));
422 memset(&OsalMsg,0,sizeof(phOsalNfc_Message_t));
426 /* Driver is BUSY with previous Write */
427 DAL_PRINT("phDal4Nfc_Write() : Busy \n");
428 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_BUSY) ;
433 /* TBD :Additional error code : NOT_INITIALISED */
434 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
437 }/*end if-Input parametrs valid-check*/
440 result = NFCSTATUS_INVALID_PARAMETER;
445 /*-----------------------------------------------------------------------------
447 FUNCTION: phDal4Nfc_Read
449 PURPOSE: DAL Read function.
451 -----------------------------------------------------------------------------*/
453 NFCSTATUS phDal4Nfc_Read( void *pContext, void *pHwRef,uint8_t *pBuffer, uint16_t length)
455 NFCSTATUS result = NFCSTATUS_SUCCESS;
457 if ((NULL != pContext) && (NULL != pHwRef)&&
458 (NULL != pBuffer) && (0 != length))
460 if ( gDalContext.hw_valid== TRUE)
462 if((!gReadWriteContext.nReadBusy)&&
463 (!gReadWriteContext.nWaitingOnRead))
465 DAL_DEBUG("*****DAl Read called length : %d\n", length);
467 /* Make a copy of the passed arguments */
468 gReadWriteContext.pReadBuffer = pBuffer;
469 gReadWriteContext.nNbOfBytesToRead = length;
470 /* Change the Read state so that thread can take over the read */
471 gReadWriteContext.nReadBusy = TRUE;
472 /* Just set variable here. This is the trigger for the Reader thread */
473 gReadWriteContext.nWaitingOnRead = TRUE;
474 /* Update the return state */
475 result = NFCSTATUS_PENDING;
476 /* unlock reader thread */
477 sem_post(&nfc_read_sem);
481 /* Driver is BUSY with prev Read */
482 DAL_PRINT("DAL BUSY\n");
483 /* Make a copy of the passed arguments */
484 gReadWriteContext.pReadBuffer = pBuffer;
485 gReadWriteContext.nNbOfBytesToRead = length;
486 result = NFCSTATUS_PENDING;
491 /* TBD :Additional error code : NOT_INITIALISED */
492 result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
494 }/*end if-Input parametrs valid-check*/
497 result = NFCSTATUS_INVALID_PARAMETER;
499 DAL_DEBUG("*****DAl Read called result : %x\n", result);
504 /*-----------------------------------------------------------------------------
506 FUNCTION: phDal4Nfc_ReadWait
508 PURPOSE: DAL Read wait function.
510 -----------------------------------------------------------------------------*/
512 NFCSTATUS phDal4Nfc_ReadWait(void *pContext, void *pHwRef,uint8_t *pBuffer, uint16_t length)
515 DAL_PRINT("phDal4Nfc_ReadWait");
518 /*-----------------------------------------------------------------------------
520 FUNCTION: phDal4Nfc_ReadWaitCancel
522 PURPOSE: Cancel the Read wait function.
524 -----------------------------------------------------------------------------*/
526 NFCSTATUS phDal4Nfc_ReadWaitCancel( void *pContext, void *pHwRef)
528 DAL_PRINT("phDal4Nfc_ReadWaitCancel");
530 /* unlock read semaphore */
531 sem_post(&nfc_read_sem);
536 /*-----------------------------------------------------------------------------
538 FUNCTION: phDal4Nfc_Config
540 PURPOSE: Configure the serial port.
542 -----------------------------------------------------------------------------*/
543 NFCSTATUS phDal4Nfc_Config(pphDal4Nfc_sConfig_t config,void **phwref)
545 NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
546 // const hw_module_t* hw_module;
547 // nfc_pn544_device_t* pn544_dev;
548 uint8_t num_eeprom_settings;
549 uint8_t* eeprom_settings;
553 config->deviceNode = "/dev/pn544";
556 /* Retrieve the hw module from the Android NFC HAL */
557 ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module);
559 LOGE("hw_get_module() failed");
560 return NFCSTATUS_FAILED;
562 ret = nfc_pn544_open(hw_module, &pn544_dev);
564 LOGE("Could not open pn544 hw_module");
565 return NFCSTATUS_FAILED;
567 config->deviceNode = pn544_dev->device_node;
568 if (config->deviceNode == NULL) {
569 LOGE("deviceNode NULL");
570 return NFCSTATUS_FAILED;
573 DAL_PRINT("phDal4Nfc_Config");
575 if ((config == NULL) || (phwref == NULL) || (config->nClientId == -1))
576 return NFCSTATUS_INVALID_PARAMETER;
579 /* Register the link callbacks */
580 memset(&gLinkFunc, 0, sizeof(phDal4Nfc_link_cbk_interface_t));
582 switch(PN544_LINK_TYPE_I2C)
584 case PN544_LINK_TYPE_UART:
585 case PN544_LINK_TYPE_USB:
587 DAL_PRINT("UART link Config");
588 /* Uart link interface */
589 gLinkFunc.init = phDal4Nfc_uart_initialize;
590 gLinkFunc.open_from_handle = phDal4Nfc_uart_set_open_from_handle;
591 gLinkFunc.is_opened = phDal4Nfc_uart_is_opened;
592 gLinkFunc.flush = phDal4Nfc_uart_flush;
593 gLinkFunc.close = phDal4Nfc_uart_close;
594 gLinkFunc.open_and_configure = phDal4Nfc_uart_open_and_configure;
595 gLinkFunc.read = phDal4Nfc_uart_read;
596 gLinkFunc.write = phDal4Nfc_uart_write;
597 gLinkFunc.reset = phDal4Nfc_uart_reset;
601 case PN544_LINK_TYPE_I2C:
605 DAL_PRINT("I2C link Config");
606 /* i2c link interface */
607 gLinkFunc.init = phDal4Nfc_i2c_initialize;
608 gLinkFunc.open_from_handle = phDal4Nfc_i2c_set_open_from_handle;
609 gLinkFunc.is_opened = phDal4Nfc_i2c_is_opened;
610 gLinkFunc.flush = phDal4Nfc_i2c_flush;
611 gLinkFunc.close = phDal4Nfc_i2c_close;
612 gLinkFunc.open_and_configure = phDal4Nfc_i2c_open_and_configure;
613 gLinkFunc.read = phDal4Nfc_i2c_read;
614 gLinkFunc.write = phDal4Nfc_i2c_write;
615 gLinkFunc.reset = phDal4Nfc_i2c_reset;
621 /* Shound not happen : Bad parameter */
622 return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_PARAMETER);
627 gLinkFunc.init(); /* So that link interface can initialize its internal state */
628 retstatus = gLinkFunc.open_and_configure(config, phwref);
629 if (retstatus != NFCSTATUS_SUCCESS)
632 /* Iniatilize the DAL context */
633 (void)memset(&gDalContext,0,sizeof(phDal4Nfc_SContext_t));
634 pgDalContext = &gDalContext;
636 /* Reset the Reader Thread values to NULL */
637 memset((void *)&gReadWriteContext,0,sizeof(gReadWriteContext));
638 gReadWriteContext.nReadThreadAlive = TRUE;
639 gReadWriteContext.nWriteBusy = FALSE;
640 gReadWriteContext.nWaitingOnWrite = FALSE;
642 /* Prepare the message queue for the defered calls */
643 #ifdef USE_MQ_MESSAGE_QUEUE
644 nDeferedCallMessageQueueId = mq_open(MQ_NAME_IDENTIFIER, O_CREAT|O_RDWR, 0666, &MQ_QUEUE_ATTRIBUTES);
646 nDeferedCallMessageQueueId = config->nClientId;
649 // gDalContext.pDev = pn544_dev;
651 /* Start Read and Write Threads */
652 if(NFCSTATUS_SUCCESS != phDal4Nfc_StartThreads())
654 return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED);
657 gDalContext.hw_valid = TRUE;
662 return NFCSTATUS_SUCCESS;
665 /*-----------------------------------------------------------------------------
667 FUNCTION: phDal4Nfc_Reset
669 PURPOSE: Reset the PN544, using the VEN pin
671 -----------------------------------------------------------------------------*/
672 NFCSTATUS phDal4Nfc_Reset(long level)
674 NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
676 DAL_DEBUG("phDal4Nfc_Reset: VEN to %ld",level);
678 retstatus = gLinkFunc.reset(level);
683 /*-----------------------------------------------------------------------------
685 FUNCTION: phDal4Nfc_Download
687 PURPOSE: Put the PN544 in download mode, using the GPIO4 pin
689 -----------------------------------------------------------------------------*/
690 NFCSTATUS phDal4Nfc_Download()
692 NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
694 DAL_DEBUG("phDal4Nfc_Download: GPIO4 to %d",1);
697 retstatus = phDal4Nfc_Reset(2);
704 /*-----------------------------------------------------------------------------------
705 DAL INTERNAL IMPLEMENTATION
706 ------------------------------------------------------------------------------------*/
711 * \ingroup grp_nfc_dal
713 * \brief DAL Reader thread handler
714 * This function manages the reads from the link interface. The reads are done from
715 * this thread to create the asynchronous mecanism. When calling the synchronous
716 * function phDal4Nfc_Read, the nWaitingOnRead mutex is unlocked and the read
717 * can be done. Then a client callback is called to send the result.
719 * \param[in] pArg A custom argument that can be passed to the thread (not used)
721 * \retval TRUE Thread exiting.
725 static void thread_sig_handler(int signo)
727 DAL_PRINT("Read Thread got signal for exit!!\n");
728 pthread_exit((void *)NULL);
729 DAL_PRINT("exit the read thread!!\n");
732 int phDal4Nfc_ReaderThread(void * pArg)
735 // NFCSTATUS result = NFCSTATUS_SUCCESS;
736 // uint8_t retry_cnt=0;
739 static int MsgType = PHDAL4NFC_READ_MESSAGE;
740 int *pmsgType = &MsgType;
742 phDal4Nfc_Message_t sMsg;
743 phOsalNfc_Message_t OsalMsg;
746 // pthread_setname_np(pthread_self(), "reader"); // our compiler does not support this
748 /* Create the overlapped event. Must be closed before exiting
749 to avoid a handle leak. This event is used READ API and the Reader thread*/
751 DAL_PRINT("RX Thread \n");
752 DAL_DEBUG("\nRX Thread nReadThreadAlive = %d",gReadWriteContext.nReadThreadAlive);
753 DAL_DEBUG("\nRX Thread nWaitingOnRead = %d",gReadWriteContext.nWaitingOnRead);
755 struct sigaction act;
756 act.sa_handler = thread_sig_handler;
757 sigaction(SIGTERM, &act, NULL);
760 sigemptyset(&newmask);
761 sigaddset(&newmask, SIGTERM);
762 pthread_sigmask(SIG_UNBLOCK, &newmask, NULL);
764 while (gReadWriteContext.nReadThreadAlive) /* Thread Loop */
766 /* Check for the read request from user */
767 DAL_PRINT("RX Thread Sem Lock\n");
769 sem_wait(&nfc_read_sem);
770 DAL_PRINT("RX Thread Sem UnLock\n");
772 /* Issue read operation.*/
773 gReadWriteContext.nNbOfBytesRead = 0;
774 DAL_DEBUG("\n*New *** *****Request Length = %d",gReadWriteContext.nNbOfBytesToRead);
775 memsetRet = memset(gReadWriteContext.pReadBuffer, 0, gReadWriteContext.nNbOfBytesToRead);
777 if (gReadWriteContext.nReadThreadAlive == 0)
779 DAL_DEBUG("Break Point 1 gReadWriteContext.nReadThreadAlive [%d]\n" , gReadWriteContext.nReadThreadAlive);
783 gReadWriteContext.nNbOfBytesRead = gLinkFunc.read(gReadWriteContext.pReadBuffer, gReadWriteContext.nNbOfBytesToRead);
785 DAL_DEBUG("Read ok. nbToRead=%d\n", gReadWriteContext.nNbOfBytesToRead);
786 DAL_DEBUG("NbReallyRead=%d\n", gReadWriteContext.nNbOfBytesRead);
787 DAL_PRINT("ReadBuff[]={ ");
789 for (i = 0; i < gReadWriteContext.nNbOfBytesRead; i++)
791 if(gReadWriteContext.pReadBuffer != NULL)
793 DAL_DEBUG("0x%x ", gReadWriteContext.pReadBuffer[i]);
800 /* read completed immediately */
801 sMsg.eMsgType = PHDAL4NFC_READ_MESSAGE;
802 /* Update the state */
803 phDal4Nfc_FillMsg(&sMsg, &OsalMsg);
805 if (gReadWriteContext.nReadThreadAlive == 0)
807 DAL_DEBUG("Break Point 2 gReadWriteContext.nReadThreadAlive [%d]\n" , gReadWriteContext.nReadThreadAlive);
811 phDal4Nfc_DeferredCall((pphDal4Nfc_DeferFuncPointer_t)phDal4Nfc_DeferredCb, (void *)pmsgType);
812 memsetRet = memset(&sMsg, 0, sizeof(phDal4Nfc_Message_t));
813 memsetRet = memset(&OsalMsg, 0, sizeof(phOsalNfc_Message_t));
814 } /* End of thread Loop*/
815 DAL_PRINT("Read Thread pthread_exit!!!!\n");
816 pthread_exit((void *)NULL);
824 * \ingroup grp_nfc_dal
826 * \brief DAL Start threads function
827 * This function is called from phDal4Nfc_Config and is responsible of creating the
830 * \retval NFCSTATUS_SUCCESS If success.
831 * \retval NFCSTATUS_FAILED Can not create thread or retreive its attributes
833 NFCSTATUS phDal4Nfc_StartThreads(void)
835 // pthread_attr_t nReadThreadAttributes;
836 // pthread_attr_t nWriteThreadAttributes;
839 if(sem_init(&nfc_read_sem, 0, 0) == -1)
841 DAL_PRINT("NFC Init Semaphore creation Error");
845 ret = pthread_create(&gReadWriteContext.nReadThread, NULL, (pphDal4Nfc_thread_handler_t)phDal4Nfc_ReaderThread, (void*) "dal_read_thread");
847 return(PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED));
849 return NFCSTATUS_SUCCESS;
853 * \ingroup grp_nfc_dal
855 * \brief DAL fill message function
856 * Internal messages management. This function fills message structure
857 * depending on message types.
859 * \param[in, out] pDalMsg DAL message to fill
860 * \param[in, out] pOsalMsg OSAL message to fill
863 void phDal4Nfc_FillMsg(phDal4Nfc_Message_t *pDalMsg,phOsalNfc_Message_t *pOsalMsg)
865 if(NULL != pgDalHwContext)
867 if(pDalMsg->eMsgType == PHDAL4NFC_WRITE_MESSAGE)
869 pDalMsg->transactInfo.length = (uint8_t)gReadWriteContext.nNbOfBytesWritten;
870 pDalMsg->transactInfo.buffer = NULL;
871 pDalMsg->transactInfo.status = NFCSTATUS_SUCCESS;
872 pDalMsg->pHwRef = pgDalHwContext;
873 pDalMsg->writeCbPtr = pgDalContext->cb_if.send_complete;
874 pOsalMsg->eMsgType = PH_DAL4NFC_MESSAGE_BASE;
875 pOsalMsg->pMsgData = pDalMsg;
878 else if(pDalMsg->eMsgType == PHDAL4NFC_READ_MESSAGE)
880 pDalMsg->transactInfo.length = (uint8_t)gReadWriteContext.nNbOfBytesRead;
881 pDalMsg->transactInfo.buffer = gReadWriteContext.pReadBuffer;
882 pDalMsg->pContext= pgDalContext->cb_if.pif_ctxt;
886 pDalMsg->transactInfo.length = (uint8_t)gReadWriteContext.nNbOfBytesReadWait;
887 pDalMsg->transactInfo.buffer = gReadWriteContext.pReadWaitBuffer;
888 pDalMsg->pContext= pgDalContext;
890 pDalMsg->transactInfo.status = NFCSTATUS_SUCCESS;
891 pDalMsg->pHwRef = pgDalHwContext;
892 pDalMsg->readCbPtr = pgDalContext->cb_if.receive_complete;
893 /*map to OSAL msg format*/
894 pOsalMsg->eMsgType = PH_DAL4NFC_MESSAGE_BASE;
895 pOsalMsg->pMsgData = pDalMsg;
901 * \ingroup grp_nfc_dal
903 * \brief DAL deferred callback function
904 * Generic handler function called by a client thread when reading a message from the queue.
905 * Will function will directly call the client function (same context). See phDal4Nfc_DeferredCall
907 * \param[in] params Parameter that will be passed to the client function.
910 void phDal4Nfc_DeferredCb (void *params)
914 phNfc_sTransactionInfo_t TransactionInfo;
920 case PHDAL4NFC_READ_MESSAGE:
921 DAL_PRINT(" Dal deferred read called \n");
922 TransactionInfo.buffer=gReadWriteContext.pReadBuffer;
923 TransactionInfo.length=(uint16_t)gReadWriteContext.nNbOfBytesRead;
924 TransactionInfo.status=NFCSTATUS_SUCCESS;
925 gReadWriteContext.nReadBusy = FALSE;
928 /* Reset flag so that another opertion can be issued.*/
929 gReadWriteContext.nWaitingOnRead = FALSE;
930 if ((NULL != pgDalContext) && (NULL != pgDalContext->cb_if.receive_complete))
932 pgDalContext->cb_if.receive_complete(pgDalContext->cb_if.pif_ctxt,
933 pgDalHwContext,&TransactionInfo);
937 case PHDAL4NFC_WRITE_MESSAGE:
938 DAL_PRINT(" Dal deferred write called \n");
942 phOsalNfc_PrintData("SEND", (uint16_t)gReadWriteContext.nNbOfBytesToWrite,
943 gReadWriteContext.pWriteBuffer, low_level_traces);
946 /* DAL_DEBUG("dalMsg->transactInfo.length : %d\n", dalMsg->transactInfo.length); */
947 /* Make a Physical WRITE */
948 /* NOTE: need to usleep(3000) here if the write is for SWP */
949 usleep(500); /* NXP advise 500us sleep required between I2C writes */
950 gReadWriteContext.nNbOfBytesWritten = gLinkFunc.write(gReadWriteContext.pWriteBuffer, gReadWriteContext.nNbOfBytesToWrite);
951 if (gReadWriteContext.nNbOfBytesWritten != gReadWriteContext.nNbOfBytesToWrite)
953 /* controller may be in standby. do it again! */
954 usleep(10000); /* wait 10 ms */
955 gReadWriteContext.nNbOfBytesWritten = gLinkFunc.write(gReadWriteContext.pWriteBuffer, gReadWriteContext.nNbOfBytesToWrite);
957 if (gReadWriteContext.nNbOfBytesWritten != gReadWriteContext.nNbOfBytesToWrite)
959 /* Report write failure or timeout */
960 DAL_PRINT(" Physical Write Error !!! \n");
961 TransactionInfo.length=(uint16_t)gReadWriteContext.nNbOfBytesWritten;
962 TransactionInfo.status = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_BOARD_COMMUNICATION_ERROR);
966 DAL_PRINT(" Physical Write Success \n");
967 TransactionInfo.length=(uint16_t)gReadWriteContext.nNbOfBytesWritten;
968 TransactionInfo.status=NFCSTATUS_SUCCESS;
969 DAL_PRINT("WriteBuff[]={ ");
970 for (i = 0; i < gReadWriteContext.nNbOfBytesWritten; i++)
972 DAL_DEBUG("0x%x ", gReadWriteContext.pWriteBuffer[i]);
976 // Free TempWriteBuffer
977 if(gReadWriteContext.pTempWriteBuffer != NULL)
979 free(gReadWriteContext.pTempWriteBuffer);
982 /* Reset Write context */
983 gReadWriteContext.nWriteBusy = FALSE;
984 gReadWriteContext.nWaitingOnWrite = FALSE;
986 /* call LLC callback */
987 if ((NULL != pgDalContext) && (NULL != pgDalContext->cb_if.send_complete))
989 pgDalContext->cb_if.send_complete(pgDalContext->cb_if.pif_ctxt,
990 pgDalHwContext,&TransactionInfo);
999 * \ingroup grp_nfc_dal
1001 * \brief DAL deferred call function
1002 * This function will enable to call the callback client asyncronously and in the client context.
1003 * It will post a message in a queue that will be processed by a client thread.
1005 * \param[in] func The function to call when message is read from the queue
1006 * \param[in] param Parameter that will be passed to the 'func' function.
1009 void phDal4Nfc_DeferredCall(pphDal4Nfc_DeferFuncPointer_t func, void *param)
1012 phDal4Nfc_Message_Wrapper_t nDeferedMessageWrapper;
1013 phDal4Nfc_DeferredCall_Msg_t *pDeferedMessage;
1014 static phDal4Nfc_DeferredCall_Msg_t nDeferedMessageRead;
1015 static phDal4Nfc_DeferredCall_Msg_t nDeferedMessageWrite;
1017 #ifdef USE_MQ_MESSAGE_QUEUE
1018 nDeferedMessage.eMsgType = PH_DAL4NFC_MESSAGE_BASE;
1019 nDeferedMessage.def_call = func;
1020 nDeferedMessage.params = param;
1021 retvalue = (int)mq_send(nDeferedCallMessageQueueId, (char *)&nDeferedMessage, sizeof(phDal4Nfc_DeferredCall_Msg_t), 0);
1023 if(PHDAL4NFC_READ_MESSAGE==(* (int*)param))
1025 pDeferedMessage = &nDeferedMessageRead;
1029 pDeferedMessage = &nDeferedMessageWrite;
1031 nDeferedMessageWrapper.mtype = 1;
1032 nDeferedMessageWrapper.msg.eMsgType = PH_DAL4NFC_MESSAGE_BASE;
1033 pDeferedMessage->pCallback = func;
1034 pDeferedMessage->pParameter = param;
1035 nDeferedMessageWrapper.msg.pMsgData = pDeferedMessage;
1036 nDeferedMessageWrapper.msg.Size = sizeof(phDal4Nfc_DeferredCall_Msg_t);
1037 #ifndef G_IDLE_ADD_MSGQ
1038 phDal4Nfc_msgsnd(nDeferedCallMessageQueueId, (struct msgbuf *)&nDeferedMessageWrapper, sizeof(phLibNfc_Message_t), 0);
1040 PostMessage((struct msgbuf *)&nDeferedMessageWrapper, sizeof(phLibNfc_Message_t), 0);