1 /*
2 * Copyright 2010-2021 NXP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * TML Implementation.
19 */
20
21 #include <phDal4Nfc_messageQueueLib.h>
22 #include <phNxpConfig.h>
23 #include <phNxpLog.h>
24 #include <phNxpNciHal_utils.h>
25 #include <phOsalNfc_Timer.h>
26 #include <phTmlNfc.h>
27 #include "NfccTransportFactory.h"
28
29 /*
30 * Duration of Timer to wait after sending an Nci packet
31 */
32 #define PHTMLNFC_MAXTIME_RETRANSMIT (200U)
33 #define MAX_WRITE_RETRY_COUNT 0x03
34 #define MAX_READ_RETRY_DELAY_IN_MILLISEC (150U)
35 /* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
36 static uint8_t bCurrentRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
37
38 /* Value to reset variables of TML */
39 #define PH_TMLNFC_RESET_VALUE (0x00)
40
41 /* Indicates a Initial or offset value */
42 #define PH_TMLNFC_VALUE_ONE (0x01)
43
44 spTransport gpTransportObj;
45 extern bool_t gsIsFirstHalMinOpen;
46
47 /* Initialize Context structure pointer used to access context structure */
48 phTmlNfc_Context_t* gpphTmlNfc_Context = NULL;
49 /* Local Function prototypes */
50 static NFCSTATUS phTmlNfc_StartThread(void);
51 static void phTmlNfc_ReadDeferredCb(void* pParams);
52 static void phTmlNfc_WriteDeferredCb(void* pParams);
53 static void* phTmlNfc_TmlThread(void* pParam);
54 static void* phTmlNfc_TmlWriterThread(void* pParam);
55 static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void* pContext);
56 static NFCSTATUS phTmlNfc_InitiateTimer(void);
57 static void phTmlNfc_SignalWriteComplete(void);
58 static int phTmlNfc_WaitReadInit(void);
59
60 /* Function definitions */
61
62 /*******************************************************************************
63 **
64 ** Function phTmlNfc_Init
65 **
66 ** Description Provides initialization of TML layer and hardware interface
67 ** Configures given hardware interface and sends handle to the
68 ** caller
69 **
70 ** Parameters pConfig - TML configuration details as provided by the upper
71 ** layer
72 **
73 ** Returns NFC status:
74 ** NFCSTATUS_SUCCESS - initialization successful
75 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
76 ** invalid
77 ** NFCSTATUS_FAILED - initialization failed (for example,
78 ** unable to open hardware interface)
79 ** NFCSTATUS_INVALID_DEVICE - device has not been opened or has
80 ** been disconnected
81 **
82 *******************************************************************************/
phTmlNfc_Init(pphTmlNfc_Config_t pConfig)83 NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig) {
84 NFCSTATUS wInitStatus = NFCSTATUS_SUCCESS;
85
86 /* Check if TML layer is already Initialized */
87 if (NULL != gpphTmlNfc_Context) {
88 /* TML initialization is already completed */
89 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_ALREADY_INITIALISED);
90 }
91 /* Validate Input parameters */
92 else if ((NULL == pConfig) ||
93 (PH_TMLNFC_RESET_VALUE == pConfig->dwGetMsgThreadId)) {
94 /*Parameters passed to TML init are wrong */
95 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
96 } else {
97 /* Allocate memory for TML context */
98 gpphTmlNfc_Context =
99 (phTmlNfc_Context_t*)malloc(sizeof(phTmlNfc_Context_t));
100
101 if (NULL == gpphTmlNfc_Context) {
102 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
103 } else {
104 /*Configure transport layer for communication*/
105 if ((gpTransportObj == NULL) &&
106 (NFCSTATUS_SUCCESS != phTmlNfc_ConfigTransport()))
107 return NFCSTATUS_FAILED;
108
109 if (gsIsFirstHalMinOpen) {
110 if (!gpTransportObj->Flushdata(pConfig)) {
111 NXPLOG_NCIHAL_E("Flushdata Failed");
112 }
113 }
114 /* Initialise all the internal TML variables */
115 memset(gpphTmlNfc_Context, PH_TMLNFC_RESET_VALUE,
116 sizeof(phTmlNfc_Context_t));
117 /* Make sure that the thread runs once it is created */
118 gpphTmlNfc_Context->bThreadDone = 1;
119 /* Open the device file to which data is read/written */
120 wInitStatus = gpTransportObj->OpenAndConfigure(
121 pConfig, &(gpphTmlNfc_Context->pDevHandle));
122
123 if (NFCSTATUS_SUCCESS != wInitStatus) {
124 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_DEVICE);
125 gpphTmlNfc_Context->pDevHandle = NULL;
126 } else {
127 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
128 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
129 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
130 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
131 gpphTmlNfc_Context->fragment_len = pConfig->fragment_len;
132
133 if (0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0)) {
134 wInitStatus = NFCSTATUS_FAILED;
135 } else if (0 != phTmlNfc_WaitReadInit()) {
136 wInitStatus = NFCSTATUS_FAILED;
137 } else if (0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0)) {
138 wInitStatus = NFCSTATUS_FAILED;
139 } else if (0 != sem_init(&gpphTmlNfc_Context->postMsgSemaphore, 0, 0)) {
140 wInitStatus = NFCSTATUS_FAILED;
141 } else {
142 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
143 /* Start TML thread (to handle write and read operations) */
144 if (NFCSTATUS_SUCCESS != phTmlNfc_StartThread()) {
145 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
146 } else {
147 /* Create Timer used for Retransmission of NCI packets */
148 gpphTmlNfc_Context->dwTimerId = phOsalNfc_Timer_Create();
149 if (PH_OSALNFC_TIMER_ID_INVALID != gpphTmlNfc_Context->dwTimerId) {
150 /* Store the Thread Identifier to which Message is to be posted */
151 gpphTmlNfc_Context->dwCallbackThreadId =
152 pConfig->dwGetMsgThreadId;
153 /* Enable retransmission of Nci packet & set retry count to
154 * default */
155 gpphTmlNfc_Context->eConfig = phTmlNfc_e_DisableRetrans;
156 /* Retry Count = Standby Recovery time of NFCC / Retransmission
157 * time + 1 */
158 gpphTmlNfc_Context->bRetryCount =
159 (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
160 gpphTmlNfc_Context->bWriteCbInvoked = false;
161 } else {
162 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
163 }
164 }
165 }
166 }
167 }
168 }
169 /* Clean up all the TML resources if any error */
170 if (NFCSTATUS_SUCCESS != wInitStatus) {
171 /* Clear all handles and memory locations initialized during init */
172 phTmlNfc_Shutdown_CleanUp();
173 }
174
175 return wInitStatus;
176 }
177
178 /*******************************************************************************
179 **
180 ** Function phTmlNfc_ConfigTransport
181 **
182 ** Description Configure Transport channel based on transport type provided
183 ** in config file
184 **
185 ** Returns NFCSTATUS_SUCCESS If transport channel is configured
186 ** NFCSTATUS_FAILED If transport channel configuration failed
187 **
188 *******************************************************************************/
phTmlNfc_ConfigTransport()189 NFCSTATUS phTmlNfc_ConfigTransport() {
190 unsigned long transportType = UNKNOWN;
191 unsigned long value = 0;
192 int isfound = GetNxpNumValue(NAME_NXP_TRANSPORT, &value, sizeof(value));
193 if (isfound > 0) {
194 transportType = value;
195 }
196 gpTransportObj = transportFactory.getTransport((transportIntf)transportType);
197 if (gpTransportObj == nullptr) {
198 NXPLOG_TML_E("No Transport channel available \n");
199 return NFCSTATUS_FAILED;
200 }
201 return NFCSTATUS_SUCCESS;
202 }
203 /*******************************************************************************
204 **
205 ** Function phTmlNfc_ConfigNciPktReTx
206 **
207 ** Description Provides Enable/Disable Retransmission of NCI packets
208 ** Needed in case of Timeout between Transmission and Reception
209 ** of NCI packets. Retransmission can be enabled only if
210 ** standby mode is enabled
211 **
212 ** Parameters eConfig - values from phTmlNfc_ConfigRetrans_t
213 ** bRetryCount - Number of times Nci packets shall be
214 ** retransmitted (default = 3)
215 **
216 ** Returns None
217 **
218 *******************************************************************************/
phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration,uint8_t bRetryCounter)219 void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration,
220 uint8_t bRetryCounter) {
221 /* Enable/Disable Retransmission */
222
223 gpphTmlNfc_Context->eConfig = eConfiguration;
224 if (phTmlNfc_e_EnableRetrans == eConfiguration) {
225 /* Check whether Retry counter passed is valid */
226 if (0 != bRetryCounter) {
227 gpphTmlNfc_Context->bRetryCount = bRetryCounter;
228 }
229 /* Set retry counter to its default value */
230 else {
231 /* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1
232 */
233 gpphTmlNfc_Context->bRetryCount =
234 (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
235 }
236 }
237
238 return;
239 }
240
241 /*******************************************************************************
242 **
243 ** Function phTmlNfc_StartThread
244 **
245 ** Description Initializes comport, reader and writer threads
246 **
247 ** Parameters None
248 **
249 ** Returns NFC status:
250 ** NFCSTATUS_SUCCESS - threads initialized successfully
251 ** NFCSTATUS_FAILED - initialization failed due to system error
252 **
253 *******************************************************************************/
phTmlNfc_StartThread(void)254 static NFCSTATUS phTmlNfc_StartThread(void) {
255 NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS;
256 void* h_threadsEvent = 0x00;
257 int pthread_create_status = 0;
258
259 /* Create Reader and Writer threads */
260 pthread_create_status =
261 pthread_create(&gpphTmlNfc_Context->readerThread, NULL,
262 &phTmlNfc_TmlThread, (void*)h_threadsEvent);
263 if (0 != pthread_create_status) {
264 wStartStatus = NFCSTATUS_FAILED;
265 } else {
266 /*Start Writer Thread*/
267 pthread_create_status =
268 pthread_create(&gpphTmlNfc_Context->writerThread, NULL,
269 &phTmlNfc_TmlWriterThread, (void*)h_threadsEvent);
270 if (0 != pthread_create_status) {
271 wStartStatus = NFCSTATUS_FAILED;
272 }
273 }
274
275 return wStartStatus;
276 }
277
278 /*******************************************************************************
279 **
280 ** Function phTmlNfc_ReTxTimerCb
281 **
282 ** Description This is the timer callback function after timer expiration.
283 **
284 ** Parameters dwThreadId - id of the thread posting message
285 ** pContext - context provided by upper layer
286 **
287 ** Returns None
288 **
289 *******************************************************************************/
phTmlNfc_ReTxTimerCb(uint32_t dwTimerId,void * pContext)290 static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void* pContext) {
291 if ((gpphTmlNfc_Context->dwTimerId == dwTimerId) && (NULL == pContext)) {
292 /* If Retry Count has reached its limit,Retransmit Nci
293 packet */
294 if (0 == bCurrentRetryCount) {
295 /* Since the count has reached its limit,return from timer callback
296 Upper layer Timeout would have happened */
297 } else {
298 bCurrentRetryCount--;
299 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true;
300 gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
301 }
302 sem_post(&gpphTmlNfc_Context->txSemaphore);
303 }
304
305 return;
306 }
307
308 /*******************************************************************************
309 **
310 ** Function phTmlNfc_InitiateTimer
311 **
312 ** Description Start a timer for Tx and Rx thread.
313 **
314 ** Parameters void
315 **
316 ** Returns NFC status
317 **
318 *******************************************************************************/
phTmlNfc_InitiateTimer(void)319 static NFCSTATUS phTmlNfc_InitiateTimer(void) {
320 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
321
322 /* Start Timer once Nci packet is sent */
323 wStatus = phOsalNfc_Timer_Start(gpphTmlNfc_Context->dwTimerId,
324 (uint32_t)PHTMLNFC_MAXTIME_RETRANSMIT,
325 phTmlNfc_ReTxTimerCb, NULL);
326
327 return wStatus;
328 }
329
330 /*******************************************************************************
331 **
332 ** Function phTmlNfc_TmlThread
333 **
334 ** Description Read the data from the lower layer driver
335 **
336 ** Parameters pParam - parameters for Writer thread function
337 **
338 ** Returns None
339 **
340 *******************************************************************************/
phTmlNfc_TmlThread(void * pParam)341 static void* phTmlNfc_TmlThread(void* pParam) {
342 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
343 int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
344 uint8_t temp[260];
345 uint8_t readRetryDelay = 0;
346 /* Transaction info buffer to be passed to Callback Thread */
347 static phTmlNfc_TransactInfo_t tTransactionInfo;
348 /* Structure containing Tml callback function and parameters to be invoked
349 by the callback thread */
350 static phLibNfc_DeferredCall_t tDeferredInfo;
351 /* Initialize Message structure to post message onto Callback Thread */
352 static phLibNfc_Message_t tMsg;
353 UNUSED_PROP(pParam);
354 NXPLOG_TML_D("PN54X - Tml Reader Thread Started................\n");
355
356 /* Reader thread loop shall be running till shutdown is invoked */
357 while (gpphTmlNfc_Context->bThreadDone) {
358 /* If Tml read is requested */
359 /* Set the variable to success initially */
360 wStatus = NFCSTATUS_SUCCESS;
361 if (-1 == sem_wait(&gpphTmlNfc_Context->rxSemaphore)) {
362 NXPLOG_TML_E("sem_wait didn't return success \n");
363 }
364
365 /* If Tml read is requested */
366 if (1 == gpphTmlNfc_Context->tReadInfo.bEnable) {
367 NXPLOG_TML_D("PN54X - Read requested.....\n");
368 /* Set the variable to success initially */
369 wStatus = NFCSTATUS_SUCCESS;
370
371 /* Variable to fetch the actual number of bytes read */
372 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
373
374 /* Read the data from the file onto the buffer */
375 if (NULL != gpphTmlNfc_Context->pDevHandle) {
376 NXPLOG_TML_D("PN54X - Invoking I2C Read.....\n");
377 dwNoBytesWrRd =
378 gpTransportObj->Read(gpphTmlNfc_Context->pDevHandle, temp, 260);
379
380 if (-1 == dwNoBytesWrRd) {
381 NXPLOG_TML_E("PN54X - Error in I2C Read.....\n");
382 if (readRetryDelay < MAX_READ_RETRY_DELAY_IN_MILLISEC) {
383 /*sleep for 30/60/90/120/150 msec between each read trial incase of
384 * read error*/
385 readRetryDelay += 30;
386 }
387 usleep(readRetryDelay * 1000);
388 sem_post(&gpphTmlNfc_Context->rxSemaphore);
389 } else if (dwNoBytesWrRd > 260) {
390 NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n");
391 readRetryDelay = 0;
392 sem_post(&gpphTmlNfc_Context->rxSemaphore);
393 } else {
394 memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
395 readRetryDelay = 0;
396
397 NXPLOG_TML_D("PN54X - I2C Read successful.....\n");
398 /* This has to be reset only after a successful read */
399 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
400 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
401 (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0))) {
402 NXPLOG_TML_D("PN54X - Retransmission timer stopped.....\n");
403 /* Stop Timer to prevent Retransmission */
404 uint32_t timerStatus =
405 phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId);
406 if (NFCSTATUS_SUCCESS != timerStatus) {
407 NXPLOG_TML_E("PN54X - timer stopped returned failure.....\n");
408 } else {
409 gpphTmlNfc_Context->bWriteCbInvoked = false;
410 }
411 }
412 /* Update the actual number of bytes read including header */
413 gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t)(dwNoBytesWrRd);
414 phNxpNciHal_print_packet("RECV",
415 gpphTmlNfc_Context->tReadInfo.pBuffer,
416 gpphTmlNfc_Context->tReadInfo.wLength);
417
418 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
419
420 /* Fill the Transaction info structure to be passed to Callback
421 * Function */
422 tTransactionInfo.wStatus = wStatus;
423 tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
424 /* Actual number of bytes read is filled in the structure */
425 tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
426
427 /* Read operation completed successfully. Post a Message onto Callback
428 * Thread*/
429 /* Prepare the message to be posted on User thread */
430 tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb;
431 tDeferredInfo.pParameter = &tTransactionInfo;
432 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
433 tMsg.pMsgData = &tDeferredInfo;
434 tMsg.Size = sizeof(tDeferredInfo);
435 NXPLOG_TML_D("PN54X - Posting read message.....\n");
436 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
437 }
438 } else {
439 NXPLOG_TML_D("PN54X -gpphTmlNfc_Context->pDevHandle is NULL");
440 }
441 } else {
442 NXPLOG_TML_D("PN54X - read request NOT enabled");
443 usleep(10 * 1000);
444 }
445 } /* End of While loop */
446
447 return NULL;
448 }
449
450 /*******************************************************************************
451 **
452 ** Function phTmlNfc_TmlWriterThread
453 **
454 ** Description Writes the requested data onto the lower layer driver
455 **
456 ** Parameters pParam - context provided by upper layer
457 **
458 ** Returns None
459 **
460 *******************************************************************************/
phTmlNfc_TmlWriterThread(void * pParam)461 static void* phTmlNfc_TmlWriterThread(void* pParam) {
462 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
463 int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
464 /* Transaction info buffer to be passed to Callback Thread */
465 static phTmlNfc_TransactInfo_t tTransactionInfo;
466 /* Structure containing Tml callback function and parameters to be invoked
467 by the callback thread */
468 static phLibNfc_DeferredCall_t tDeferredInfo;
469 /* Initialize Message structure to post message onto Callback Thread */
470 static phLibNfc_Message_t tMsg;
471 /* In case of I2C Write Retry */
472 static uint16_t retry_cnt;
473 UNUSED_PROP(pParam);
474 NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n");
475
476 /* Writer thread loop shall be running till shutdown is invoked */
477 while (gpphTmlNfc_Context->bThreadDone) {
478 NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n");
479 if (-1 == sem_wait(&gpphTmlNfc_Context->txSemaphore)) {
480 NXPLOG_TML_E("sem_wait didn't return success \n");
481 }
482 /* If Tml write is requested */
483 if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable) {
484 NXPLOG_TML_D("PN54X - Write requested.....\n");
485 /* Set the variable to success initially */
486 wStatus = NFCSTATUS_SUCCESS;
487 if (NULL != gpphTmlNfc_Context->pDevHandle) {
488 retry:
489 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
490 /* Variable to fetch the actual number of bytes written */
491 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
492 /* Write the data in the buffer onto the file */
493 NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n");
494 /* TML reader writer callback synchronization mutex lock --- START */
495 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
496 gpphTmlNfc_Context->gWriterCbflag = false;
497 dwNoBytesWrRd =
498 gpTransportObj->Write(gpphTmlNfc_Context->pDevHandle,
499 gpphTmlNfc_Context->tWriteInfo.pBuffer,
500 gpphTmlNfc_Context->tWriteInfo.wLength);
501 /* TML reader writer callback synchronization mutex lock --- END */
502 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
503
504 /* Try I2C Write Five Times, if it fails : Raju */
505 if (-1 == dwNoBytesWrRd) {
506 if (gpTransportObj->IsFwDnldModeEnabled()) {
507 if (retry_cnt++ < MAX_WRITE_RETRY_COUNT) {
508 NXPLOG_TML_D("PN54X - Error in I2C Write - Retry 0x%x",
509 retry_cnt);
510 // Add a 10 ms delay to ensure NFCC is not still in stand by mode.
511 usleep(10 * 1000);
512 goto retry;
513 }
514 }
515 NXPLOG_TML_D("PN54X - Error in I2C Write.....\n");
516 wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
517 } else {
518 phNxpNciHal_print_packet("SEND",
519 gpphTmlNfc_Context->tWriteInfo.pBuffer,
520 gpphTmlNfc_Context->tWriteInfo.wLength);
521 }
522 retry_cnt = 0;
523 if (NFCSTATUS_SUCCESS == wStatus) {
524 NXPLOG_TML_D("PN54X - I2C Write successful.....\n");
525 dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE;
526 }
527 /* Fill the Transaction info structure to be passed to Callback Function
528 */
529 tTransactionInfo.wStatus = wStatus;
530 tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer;
531 /* Actual number of bytes written is filled in the structure */
532 tTransactionInfo.wLength = (uint16_t)dwNoBytesWrRd;
533
534 /* Prepare the message to be posted on the User thread */
535 tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb;
536 tDeferredInfo.pParameter = &tTransactionInfo;
537 /* Write operation completed successfully. Post a Message onto Callback
538 * Thread*/
539 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
540 tMsg.pMsgData = &tDeferredInfo;
541 tMsg.Size = sizeof(tDeferredInfo);
542
543 /* Check whether Retransmission needs to be started,
544 * If yes, Post message only if
545 * case 1. Message is not posted &&
546 * case 11. Write status is success ||
547 * case 12. Last retry of write is also failure
548 */
549 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
550 (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) {
551 if (gpphTmlNfc_Context->bWriteCbInvoked == false) {
552 if ((NFCSTATUS_SUCCESS == wStatus) || (bCurrentRetryCount == 0)) {
553 NXPLOG_TML_D("PN54X - Posting Write message.....\n");
554 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
555 &tMsg);
556 gpphTmlNfc_Context->bWriteCbInvoked = true;
557 }
558 }
559 } else {
560 NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n");
561 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
562 if (NFCSTATUS_SUCCESS == wStatus) {
563 /*TML reader writer thread callback synchronization---START*/
564 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
565 gpphTmlNfc_Context->gWriterCbflag = true;
566 phTmlNfc_SignalWriteComplete();
567 /*TML reader writer thread callback synchronization---END*/
568 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
569 }
570 }
571 } else {
572 NXPLOG_TML_D("PN54X - gpphTmlNfc_Context->pDevHandle is NULL");
573 }
574
575 /* If Data packet is sent, then NO retransmission */
576 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
577 (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) {
578 NXPLOG_TML_D("PN54X - Starting timer for Retransmission case");
579 wStatus = phTmlNfc_InitiateTimer();
580 if (NFCSTATUS_SUCCESS != wStatus) {
581 /* Reset Variables used for Retransmission */
582 NXPLOG_TML_D("PN54X - Retransmission timer initiate failed");
583 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
584 bCurrentRetryCount = 0;
585 }
586 }
587 } else {
588 NXPLOG_TML_D("PN54X - Write request NOT enabled");
589 usleep(10000);
590 }
591
592 } /* End of While loop */
593
594 return NULL;
595 }
596
597 /*******************************************************************************
598 **
599 ** Function phTmlNfc_CleanUp
600 **
601 ** Description Clears all handles opened during TML initialization
602 **
603 ** Parameters None
604 **
605 ** Returns None
606 **
607 *******************************************************************************/
phTmlNfc_CleanUp(void)608 void phTmlNfc_CleanUp(void) {
609 if (NULL == gpphTmlNfc_Context) {
610 return;
611 }
612 sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
613 sem_destroy(&gpphTmlNfc_Context->txSemaphore);
614 sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
615 pthread_mutex_destroy(&gpphTmlNfc_Context->wait_busy_lock);
616 pthread_cond_destroy(&gpphTmlNfc_Context->wait_busy_condition);
617 gpTransportObj = NULL;
618 /* Clear memory allocated for storing Context variables */
619 free((void*)gpphTmlNfc_Context);
620 /* Set the pointer to NULL to indicate De-Initialization */
621 gpphTmlNfc_Context = NULL;
622
623 return;
624 }
625
626 /*******************************************************************************
627 **
628 ** Function phTmlNfc_Shutdown
629 **
630 ** Description Uninitializes TML layer and hardware interface
631 **
632 ** Parameters None
633 **
634 ** Returns NFC status:
635 ** NFCSTATUS_SUCCESS - TML configuration released successfully
636 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
637 ** invalid
638 ** NFCSTATUS_FAILED - un-initialization failed (example: unable
639 ** to close interface)
640 **
641 *******************************************************************************/
phTmlNfc_Shutdown(void)642 NFCSTATUS phTmlNfc_Shutdown(void) {
643 NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS;
644
645 /* Check whether TML is Initialized */
646 if (NULL != gpphTmlNfc_Context) {
647 /* Reset thread variable to terminate the thread */
648 gpphTmlNfc_Context->bThreadDone = 0;
649 usleep(1000);
650 /* Clear All the resources allocated during initialization */
651 sem_post(&gpphTmlNfc_Context->rxSemaphore);
652 usleep(1000);
653 sem_post(&gpphTmlNfc_Context->txSemaphore);
654 usleep(1000);
655 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
656 usleep(1000);
657 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
658 usleep(1000);
659
660 if (nfcFL.chipType < sn100u) {
661 (void)gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
662 MODE_POWER_OFF);
663 }
664
665 gpTransportObj->Close(gpphTmlNfc_Context->pDevHandle);
666 gpphTmlNfc_Context->pDevHandle = NULL;
667 if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL)) {
668 NXPLOG_TML_E("Fail to kill reader thread!");
669 }
670 if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL)) {
671 NXPLOG_TML_E("Fail to kill writer thread!");
672 }
673 NXPLOG_TML_D("bThreadDone == 0");
674
675 } else {
676 wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
677 }
678
679 return wShutdownStatus;
680 }
681
682 /*******************************************************************************
683 **
684 ** Function phTmlNfc_Write
685 **
686 ** Description Asynchronously writes given data block to hardware
687 ** interface/driver. Enables writer thread if there are no
688 ** write requests pending. Returns successfully once writer
689 ** thread completes write operation. Notifies upper layer using
690 ** callback mechanism.
691 **
692 ** NOTE:
693 ** * it is important to post a message with id
694 ** PH_TMLNFC_WRITE_MESSAGE to IntegrationThread after data
695 ** has been written to PN54X
696 ** * if CRC needs to be computed, then input buffer should be
697 ** capable to store two more bytes apart from length of
698 ** packet
699 **
700 ** Parameters pBuffer - data to be sent
701 ** wLength - length of data buffer
702 ** pTmlWriteComplete - pointer to the function to be invoked
703 ** upon completion
704 ** pContext - context provided by upper layer
705 **
706 ** Returns NFC status:
707 ** NFCSTATUS_PENDING - command is yet to be processed
708 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
709 ** invalid
710 ** NFCSTATUS_BUSY - write request is already in progress
711 **
712 *******************************************************************************/
phTmlNfc_Write(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,void * pContext)713 NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength,
714 pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,
715 void* pContext) {
716 NFCSTATUS wWriteStatus;
717
718 /* Check whether TML is Initialized */
719
720 if (NULL != gpphTmlNfc_Context) {
721 if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) &&
722 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete)) {
723 if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy) {
724 /* Setting the flag marks beginning of a Write Operation */
725 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true;
726 /* Copy the buffer, length and Callback function,
727 This shall be utilized while invoking the Callback function in thread
728 */
729 gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer;
730 gpphTmlNfc_Context->tWriteInfo.wLength = wLength;
731 gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete;
732 gpphTmlNfc_Context->tWriteInfo.pContext = pContext;
733
734 wWriteStatus = NFCSTATUS_PENDING;
735 // FIXME: If retry is going on. Stop the retry thread/timer
736 if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) {
737 /* Set retry count to default value */
738 // FIXME: If the timer expired there, and meanwhile we have created
739 // a new request. The expired timer will think that retry is still
740 // ongoing.
741 bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount;
742 gpphTmlNfc_Context->bWriteCbInvoked = false;
743 }
744 /* Set event to invoke Writer Thread */
745 gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
746 sem_post(&gpphTmlNfc_Context->txSemaphore);
747 } else {
748 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
749 }
750 } else {
751 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
752 }
753 } else {
754 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
755 }
756
757 return wWriteStatus;
758 }
759
760 /*******************************************************************************
761 **
762 ** Function phTmlNfc_Read
763 **
764 ** Description Asynchronously reads data from the driver
765 ** Number of bytes to be read and buffer are passed by upper
766 ** layer.
767 ** Enables reader thread if there are no read requests pending
768 ** Returns successfully once read operation is completed
769 ** Notifies upper layer using callback mechanism
770 **
771 ** Parameters pBuffer - location to send read data to the upper layer via
772 ** callback
773 ** wLength - length of read data buffer passed by upper layer
774 ** pTmlReadComplete - pointer to the function to be invoked
775 ** upon completion of read operation
776 ** pContext - context provided by upper layer
777 **
778 ** Returns NFC status:
779 ** NFCSTATUS_PENDING - command is yet to be processed
780 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
781 ** invalid
782 ** NFCSTATUS_BUSY - read request is already in progress
783 **
784 *******************************************************************************/
phTmlNfc_Read(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,void * pContext)785 NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
786 pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,
787 void* pContext) {
788 NFCSTATUS wReadStatus;
789 int rxSemVal = 0, ret = 0;
790
791 /* Check whether TML is Initialized */
792 if (NULL != gpphTmlNfc_Context) {
793 if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
794 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete)) {
795 if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy) {
796 /* Setting the flag marks beginning of a Read Operation */
797 gpphTmlNfc_Context->tReadInfo.bThreadBusy = true;
798 /* Copy the buffer, length and Callback function,
799 This shall be utilized while invoking the Callback function in thread
800 */
801 gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer;
802 gpphTmlNfc_Context->tReadInfo.wLength = wLength;
803 gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
804 gpphTmlNfc_Context->tReadInfo.pContext = pContext;
805 wReadStatus = NFCSTATUS_PENDING;
806
807 /* Set event to invoke Reader Thread */
808 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
809 ret = sem_getvalue(&gpphTmlNfc_Context->rxSemaphore, &rxSemVal);
810 /* Post rxSemaphore either if sem_getvalue() is failed or rxSemVal is 0
811 */
812 if (ret || !rxSemVal) {
813 sem_post(&gpphTmlNfc_Context->rxSemaphore);
814 } else {
815 NXPLOG_TML_D(
816 "%s: skip reader thread scheduling, ret=%x, rxSemaVal=%x",
817 __func__, ret, rxSemVal);
818 }
819 } else {
820 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
821 }
822 } else {
823 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
824 }
825 } else {
826 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
827 }
828
829 return wReadStatus;
830 }
831
832 /*******************************************************************************
833 **
834 ** Function phTmlNfc_ReadAbort
835 **
836 ** Description Aborts pending read request (if any)
837 **
838 ** Parameters None
839 **
840 ** Returns NFC status:
841 ** NFCSTATUS_SUCCESS - ongoing read operation aborted
842 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
843 ** invalid
844 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
845 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel read
846 ** operation
847 **
848 *******************************************************************************/
phTmlNfc_ReadAbort(void)849 NFCSTATUS phTmlNfc_ReadAbort(void) {
850 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
851 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
852
853 /*Reset the flag to accept another Read Request */
854 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
855 wStatus = NFCSTATUS_SUCCESS;
856
857 return wStatus;
858 }
859
860 /*******************************************************************************
861 **
862 ** Function phTmlNfc_WriteAbort
863 **
864 ** Description Aborts pending write request (if any)
865 **
866 ** Parameters None
867 **
868 ** Returns NFC status:
869 ** NFCSTATUS_SUCCESS - ongoing write operation aborted
870 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
871 ** invalid
872 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
873 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel write
874 ** operation
875 **
876 *******************************************************************************/
phTmlNfc_WriteAbort(void)877 NFCSTATUS phTmlNfc_WriteAbort(void) {
878 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
879
880 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
881 /* Stop if any retransmission is in progress */
882 bCurrentRetryCount = 0;
883
884 /* Reset the flag to accept another Write Request */
885 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
886 wStatus = NFCSTATUS_SUCCESS;
887
888 return wStatus;
889 }
890
891 /*******************************************************************************
892 **
893 ** Function phTmlNfc_IoCtl
894 **
895 ** Description Resets device when insisted by upper layer
896 ** Number of bytes to be read and buffer are passed by upper
897 ** layer
898 ** Enables reader thread if there are no read requests pending
899 ** Returns successfully once read operation is completed
900 ** Notifies upper layer using callback mechanism
901 **
902 ** Parameters eControlCode - control code for a specific operation
903 **
904 ** Returns NFC status:
905 ** NFCSTATUS_SUCCESS - ioctl command completed successfully
906 ** NFCSTATUS_FAILED - ioctl command request failed
907 **
908 *******************************************************************************/
phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)909 NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode) {
910 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
911
912 if (NULL == gpphTmlNfc_Context) {
913 wStatus = NFCSTATUS_FAILED;
914 } else {
915 uint8_t read_flag = (gpphTmlNfc_Context->tReadInfo.bEnable > 0);
916
917 switch (eControlCode) {
918 case phTmlNfc_e_PowerReset: {
919 if (nfcFL.chipType >= sn100u) {
920 /*VEN_RESET*/
921 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
922 MODE_POWER_RESET);
923 } else {
924 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
925 MODE_POWER_ON);
926 usleep(100 * 1000);
927 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
928 MODE_POWER_OFF);
929 usleep(100 * 1000);
930 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
931 MODE_POWER_ON);
932 }
933 break;
934 }
935 case phTmlNfc_e_EnableVen: {
936 if (nfcFL.chipType < sn100u) {
937 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
938 MODE_POWER_ON);
939 usleep(100 * 1000);
940 }
941 break;
942 }
943 case phTmlNfc_e_ResetDevice:
944
945 {
946 #if (NXP_EXTNS == TRUE)
947 if (nfcFL.chipType < sn100u) {
948 #endif
949 /*Reset PN54X*/
950 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
951 MODE_POWER_ON);
952 usleep(100 * 1000);
953 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
954 MODE_POWER_OFF);
955 usleep(100 * 1000);
956 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
957 MODE_POWER_ON);
958 #if (NXP_EXTNS == TRUE)
959 }
960 #endif
961 break;
962 }
963 case phTmlNfc_e_EnableNormalMode: {
964 /*Reset PN54X*/
965 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
966 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
967 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with VEN RESET ");
968 if (nfcFL.chipType < sn100u) {
969 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
970 MODE_POWER_OFF);
971 usleep(10 * 1000);
972 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
973 MODE_POWER_ON);
974 usleep(100 * 1000);
975 } else {
976 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
977 MODE_FW_GPIO_LOW);
978 }
979 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
980 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with NCI CMD ");
981 if (nfcFL.chipType < sn100u) {
982 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
983 MODE_POWER_ON);
984 } else {
985 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
986 MODE_FW_GPIO_LOW);
987 }
988 }
989 break;
990 }
991 case phTmlNfc_e_EnableDownloadMode: {
992 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
993 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
994 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
995 NXPLOG_TML_D(
996 " phTmlNfc_e_EnableDownloadMode complete with VEN RESET ");
997 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
998 MODE_FW_DWNLD_WITH_VEN);
999 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
1000 NXPLOG_TML_D(" phTmlNfc_e_EnableDownloadMode complete with NCI CMD ");
1001 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
1002 MODE_FW_DWND_HIGH);
1003 }
1004 break;
1005 }
1006 case phTmlNfc_e_EnableDownloadModeWithVenRst: {
1007 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
1008 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
1009 NXPLOG_TML_D(
1010 " phTmlNfc_e_EnableDownloadModewithVenRst complete with "
1011 "VEN RESET ");
1012 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
1013 MODE_FW_DWNLD_WITH_VEN);
1014 break;
1015 }
1016 case phTmlNfc_e_setFragmentSize: {
1017 if (nfcFL.chipType != pn557) {
1018 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
1019 NXPLOG_TML_D("phTmlNfc_e_setFragmentSize 0x22A");
1020 } else {
1021 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_PN557;
1022 NXPLOG_TML_D("phTmlNfc_e_setFragmentSize 0x100");
1023 }
1024 break;
1025 }
1026 default: {
1027 wStatus = NFCSTATUS_INVALID_PARAMETER;
1028 break;
1029 }
1030 }
1031 if (read_flag && (gpphTmlNfc_Context->tReadInfo.bEnable == 0x00)) {
1032 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
1033 sem_post(&gpphTmlNfc_Context->rxSemaphore);
1034 }
1035 }
1036
1037 return wStatus;
1038 }
1039
1040 /*******************************************************************************
1041 **
1042 ** Function phTmlNfc_DeferredCall
1043 **
1044 ** Description Posts message on upper layer thread
1045 ** upon successful read or write operation
1046 **
1047 ** Parameters dwThreadId - id of the thread posting message
1048 ** ptWorkerMsg - message to be posted
1049 **
1050 ** Returns None
1051 **
1052 *******************************************************************************/
phTmlNfc_DeferredCall(uintptr_t dwThreadId,phLibNfc_Message_t * ptWorkerMsg)1053 void phTmlNfc_DeferredCall(uintptr_t dwThreadId,
1054 phLibNfc_Message_t* ptWorkerMsg) {
1055 intptr_t bPostStatus;
1056 UNUSED_PROP(dwThreadId);
1057 /* Post message on the user thread to invoke the callback function */
1058 if (-1 == sem_wait(&gpphTmlNfc_Context->postMsgSemaphore)) {
1059 NXPLOG_TML_E("sem_wait didn't return success \n");
1060 }
1061 bPostStatus =
1062 phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId, ptWorkerMsg, 0);
1063 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
1064 }
1065
1066 /*******************************************************************************
1067 **
1068 ** Function phTmlNfc_ReadDeferredCb
1069 **
1070 ** Description Read thread call back function
1071 **
1072 ** Parameters pParams - context provided by upper layer
1073 **
1074 ** Returns None
1075 **
1076 *******************************************************************************/
phTmlNfc_ReadDeferredCb(void * pParams)1077 static void phTmlNfc_ReadDeferredCb(void* pParams) {
1078 /* Transaction info buffer to be passed to Callback Function */
1079 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1080
1081 /* Reset the flag to accept another Read Request */
1082 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
1083 gpphTmlNfc_Context->tReadInfo.pThread_Callback(
1084 gpphTmlNfc_Context->tReadInfo.pContext, pTransactionInfo);
1085
1086 return;
1087 }
1088
1089 /*******************************************************************************
1090 **
1091 ** Function phTmlNfc_WriteDeferredCb
1092 **
1093 ** Description Write thread call back function
1094 **
1095 ** Parameters pParams - context provided by upper layer
1096 **
1097 ** Returns None
1098 **
1099 *******************************************************************************/
phTmlNfc_WriteDeferredCb(void * pParams)1100 static void phTmlNfc_WriteDeferredCb(void* pParams) {
1101 /* Transaction info buffer to be passed to Callback Function */
1102 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1103
1104 /* Reset the flag to accept another Write Request */
1105 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
1106 gpphTmlNfc_Context->tWriteInfo.pThread_Callback(
1107 gpphTmlNfc_Context->tWriteInfo.pContext, pTransactionInfo);
1108
1109 return;
1110 }
1111
phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result)1112 void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result) {
1113 fragmentation_enabled = result;
1114 }
1115
phTmlNfc_get_fragmentation_enabled()1116 phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled() {
1117 return fragmentation_enabled;
1118 }
1119
1120 /*******************************************************************************
1121 **
1122 ** Function phTmlNfc_SignalWriteComplete
1123 **
1124 ** Description function to invoke reader thread
1125 **
1126 ** Parameters None
1127 **
1128 ** Returns None
1129 **
1130 *******************************************************************************/
phTmlNfc_SignalWriteComplete(void)1131 static void phTmlNfc_SignalWriteComplete(void) {
1132 int ret = -1;
1133 if (gpphTmlNfc_Context->wait_busy_flag == true) {
1134 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - enter");
1135 gpphTmlNfc_Context->wait_busy_flag = false;
1136
1137 ret = pthread_cond_signal(&gpphTmlNfc_Context->wait_busy_condition);
1138 if (ret) {
1139 NXPLOG_TML_E(" phTmlNfc_SignalWriteComplete failed, error = 0x%X", ret);
1140 }
1141 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - exit");
1142 }
1143 }
1144
1145 /*******************************************************************************
1146 **
1147 ** Function phTmlNfc_WaitReadInit
1148 **
1149 ** Description init function for reader thread
1150 **
1151 ** Parameters None
1152 **
1153 ** Returns int
1154 **
1155 *******************************************************************************/
phTmlNfc_WaitReadInit(void)1156 static int phTmlNfc_WaitReadInit(void) {
1157 int ret = -1;
1158 pthread_condattr_t attr;
1159 pthread_condattr_init(&attr);
1160 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1161 memset(&gpphTmlNfc_Context->wait_busy_condition, 0,
1162 sizeof(gpphTmlNfc_Context->wait_busy_condition));
1163 pthread_mutex_init(&gpphTmlNfc_Context->wait_busy_lock, NULL);
1164 ret = pthread_cond_init(&gpphTmlNfc_Context->wait_busy_condition, &attr);
1165 if (ret) {
1166 NXPLOG_TML_E(" phTphTmlNfc_WaitReadInit failed, error = 0x%X", ret);
1167 }
1168 return ret;
1169 }
1170
1171 /*******************************************************************************
1172 **
1173 ** Function phTmlNfc_EnableFwDnldMode
1174 **
1175 ** Description wrapper function for enabling/disabling FW download mode
1176 **
1177 ** Parameters True/False
1178 **
1179 ** Returns NFCSTATUS
1180 **
1181 *******************************************************************************/
phTmlNfc_EnableFwDnldMode(bool mode)1182 void phTmlNfc_EnableFwDnldMode(bool mode) {
1183 gpTransportObj->EnableFwDnldMode(mode);
1184 }
1185
1186 /*******************************************************************************
1187 **
1188 ** Function phTmlNfc_IsFwDnldModeEnabled
1189 **
1190 ** Description wrapper function to get the FW download flag
1191 **
1192 ** Parameters None
1193 **
1194 ** Returns True/False status of FW download flag
1195 **
1196 *******************************************************************************/
phTmlNfc_IsFwDnldModeEnabled(void)1197 bool phTmlNfc_IsFwDnldModeEnabled(void) {
1198 return gpTransportObj->IsFwDnldModeEnabled();
1199 }
1200
1201 /*******************************************************************************
1202 **
1203 ** Function phTmlNfc_Shutdown_CleanUp
1204 **
1205 ** Description wrapper function for shutdown and cleanup of resources
1206 **
1207 ** Parameters None
1208 **
1209 ** Returns NFCSTATUS
1210 **
1211 *******************************************************************************/
phTmlNfc_Shutdown_CleanUp()1212 NFCSTATUS phTmlNfc_Shutdown_CleanUp() {
1213 NFCSTATUS wShutdownStatus = phTmlNfc_Shutdown();
1214 phTmlNfc_CleanUp();
1215 return wShutdownStatus;
1216 }
1217