1 /*
2 * Copyright (C) 2010-2014 NXP Semiconductors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * OSAL Implementation for Timers.
19 */
20
21 #include <signal.h>
22 #include <phNfcTypes.h>
23 #include <phOsalNfc_Timer.h>
24 #include <phNfcCommon.h>
25 #include <phNxpNciHal.h>
26 #include <phNxpLog.h>
27
28 #define PH_NFC_MAX_TIMER (5U)
29 static phOsalNfc_TimerHandle_t apTimerInfo[PH_NFC_MAX_TIMER];
30
31 extern phNxpNciHal_Control_t nxpncihal_ctrl;
32
33
34 /*
35 * Defines the base address for generating timerid.
36 */
37 #define PH_NFC_TIMER_BASE_ADDRESS (100U)
38
39 /*
40 * Defines the value for invalid timerid returned during timeSetEvent
41 */
42 #define PH_NFC_TIMER_ID_ZERO (0x00)
43
44
45 /*
46 * Invalid timer ID type. This ID used indicate timer creation is failed */
47 #define PH_NFC_TIMER_ID_INVALID (0xFFFF)
48
49 /* Forward declarations */
50 static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg);
51 static void phOsalNfc_DeferredCall (void *pParams);
52 static void phOsalNfc_Timer_Expired(union sigval sv);
53
54 /*
55 *************************** Function Definitions ******************************
56 */
57
58 /*******************************************************************************
59 **
60 ** Function phOsalNfc_Timer_Create
61 **
62 ** Description Creates a timer which shall call back the specified function when the timer expires
63 ** Fails if OSAL module is not initialized or timers are already occupied
64 **
65 ** Parameters None
66 **
67 ** Returns TimerId
68 ** TimerId value of PH_OSALNFC_TIMER_ID_INVALID indicates that timer is not created -
69 **
70 *******************************************************************************/
phOsalNfc_Timer_Create(void)71 uint32_t phOsalNfc_Timer_Create(void)
72 {
73 /* dwTimerId is also used as an index at which timer object can be stored */
74 uint32_t dwTimerId = PH_OSALNFC_TIMER_ID_INVALID;
75 static struct sigevent se;
76 phOsalNfc_TimerHandle_t *pTimerHandle;
77 /* Timer needs to be initialized for timer usage */
78
79 se.sigev_notify = SIGEV_THREAD;
80 se.sigev_notify_function = phOsalNfc_Timer_Expired;
81 se.sigev_notify_attributes = NULL;
82 dwTimerId = phUtilNfc_CheckForAvailableTimer();
83
84 /* Check whether timers are available, if yes create a timer handle structure */
85 if( (PH_NFC_TIMER_ID_ZERO != dwTimerId) && (dwTimerId <= PH_NFC_MAX_TIMER) )
86 {
87 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwTimerId-1];
88 /* Build the Timer Id to be returned to Caller Function */
89 dwTimerId += PH_NFC_TIMER_BASE_ADDRESS;
90 se.sigev_value.sival_int = (int)dwTimerId;
91 /* Create POSIX timer */
92 if(timer_create(CLOCK_REALTIME, &se, &(pTimerHandle->hTimerHandle)) == -1)
93 {
94 dwTimerId = PH_NFC_TIMER_ID_INVALID;
95 }
96 else
97 {
98 /* Set the state to indicate timer is ready */
99 pTimerHandle->eState = eTimerIdle;
100 /* Store the Timer Id which shall act as flag during check for timer availability */
101 pTimerHandle->TimerId = dwTimerId;
102 }
103 }
104 else
105 {
106 dwTimerId = PH_NFC_TIMER_ID_INVALID;
107 }
108
109 /* Timer ID invalid can be due to Uninitialized state,Non availability of Timer */
110 return dwTimerId;
111 }
112
113 /*******************************************************************************
114 **
115 ** Function phOsalNfc_Timer_Start
116 **
117 ** Description Starts the requested, already created, timer
118 ** If the timer is already running, timer stops and restarts with the new timeout value
119 ** and new callback function in case any ??????
120 ** Creates a timer which shall call back the specified function when the timer expires
121 **
122 ** Parameters dwTimerId - valid timer ID obtained during timer creation
123 ** dwRegTimeCnt - requested timeout in milliseconds
124 ** pApplication_callback - application callback interface to be called when timer expires
125 ** pContext - caller context, to be passed to the application callback function
126 **
127 ** Returns NFC status:
128 ** NFCSTATUS_SUCCESS - the operation was successful
129 ** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
130 ** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
131 ** PH_OSALNFC_TIMER_START_ERROR - timer could not be created due to system error
132 **
133 *******************************************************************************/
phOsalNfc_Timer_Start(uint32_t dwTimerId,uint32_t dwRegTimeCnt,pphOsalNfc_TimerCallbck_t pApplication_callback,void * pContext)134 NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, pphOsalNfc_TimerCallbck_t pApplication_callback, void *pContext)
135 {
136 NFCSTATUS wStartStatus= NFCSTATUS_SUCCESS;
137
138 struct itimerspec its;
139 uint32_t dwIndex;
140 phOsalNfc_TimerHandle_t *pTimerHandle;
141 /* Retrieve the index at which the timer handle structure is stored */
142 dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
143 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
144 /* OSAL Module needs to be initialized for timer usage */
145 /* Check whether the handle provided by user is valid */
146 if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
147 (NULL != pApplication_callback) )
148 {
149 its.it_interval.tv_sec = 0;
150 its.it_interval.tv_nsec = 0;
151 its.it_value.tv_sec = dwRegTimeCnt / 1000;
152 its.it_value.tv_nsec = 1000000 * (dwRegTimeCnt % 1000);
153 if(its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
154 {
155 /* This would inadvertently stop the timer*/
156 its.it_value.tv_nsec = 1;
157 }
158 pTimerHandle->Application_callback = pApplication_callback;
159 pTimerHandle->pContext = pContext;
160 pTimerHandle->eState = eTimerRunning;
161 /* Arm the timer */
162 if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
163 {
164 wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_START_ERROR);
165 }
166 }
167 else
168 {
169 wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
170 }
171
172 return wStartStatus;
173 }
174
175 /*******************************************************************************
176 **
177 ** Function phOsalNfc_Timer_Stop
178 **
179 ** Description Stops already started timer
180 ** Allows to stop running timer. In case timer is stopped, timer callback
181 ** will not be notified any more
182 **
183 ** Parameters dwTimerId - valid timer ID obtained during timer creation
184 **
185 ** Returns NFC status:
186 ** NFCSTATUS_SUCCESS - the operation was successful
187 ** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
188 ** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
189 ** PH_OSALNFC_TIMER_STOP_ERROR - timer could not be stopped due to system error
190 **
191 *******************************************************************************/
phOsalNfc_Timer_Stop(uint32_t dwTimerId)192 NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId)
193 {
194 NFCSTATUS wStopStatus=NFCSTATUS_SUCCESS;
195 static struct itimerspec its = {{0, 0}, {0, 0}};
196
197 uint32_t dwIndex;
198 phOsalNfc_TimerHandle_t *pTimerHandle;
199 dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
200 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
201 /* OSAL Module and Timer needs to be initialized for timer usage */
202 /* Check whether the TimerId provided by user is valid */
203 if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
204 (pTimerHandle->eState != eTimerIdle) )
205 {
206 /* Stop the timer only if the callback has not been invoked */
207 if(pTimerHandle->eState == eTimerRunning)
208 {
209 if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
210 {
211 wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_STOP_ERROR);
212 }
213 else
214 {
215 /* Change the state of timer to Stopped */
216 pTimerHandle->eState = eTimerStopped;
217 }
218 }
219 }
220 else
221 {
222 wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
223 }
224
225 return wStopStatus;
226 }
227
228 /*******************************************************************************
229 **
230 ** Function phOsalNfc_Timer_Delete
231 **
232 ** Description Deletes previously created timer
233 ** Allows to delete previously created timer. In case timer is running,
234 ** it is first stopped and then deleted
235 **
236 ** Parameters dwTimerId - valid timer ID obtained during timer creation
237 **
238 ** Returns NFC status:
239 ** NFCSTATUS_SUCCESS - the operation was successful
240 ** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
241 ** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
242 ** PH_OSALNFC_TIMER_DELETE_ERROR - timer could not be stopped due to system error
243 **
244 *******************************************************************************/
phOsalNfc_Timer_Delete(uint32_t dwTimerId)245 NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId)
246 {
247 NFCSTATUS wDeleteStatus = NFCSTATUS_SUCCESS;
248
249 uint32_t dwIndex;
250 phOsalNfc_TimerHandle_t *pTimerHandle;
251 dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
252 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
253 /* OSAL Module and Timer needs to be initialized for timer usage */
254
255 /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
256 if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId)
257 && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
258 )
259 {
260 /* Cancel the timer before deleting */
261 if(timer_delete(pTimerHandle->hTimerHandle) == -1)
262 {
263 wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_DELETE_ERROR);
264 }
265 /* Clear Timer structure used to store timer related data */
266 memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
267 }
268 else
269 {
270 wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
271 }
272 return wDeleteStatus;
273 }
274
275 /*******************************************************************************
276 **
277 ** Function phOsalNfc_Timer_Cleanup
278 **
279 ** Description Deletes all previously created timers
280 ** Allows to delete previously created timers. In case timer is running,
281 ** it is first stopped and then deleted
282 **
283 ** Parameters None
284 **
285 ** Returns None
286 **
287 *******************************************************************************/
phOsalNfc_Timer_Cleanup(void)288 void phOsalNfc_Timer_Cleanup(void)
289 {
290 /* Delete all timers */
291 uint32_t dwIndex;
292 phOsalNfc_TimerHandle_t *pTimerHandle;
293 for(dwIndex = 0; dwIndex < PH_NFC_MAX_TIMER; dwIndex++)
294 {
295 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
296 /* OSAL Module and Timer needs to be initialized for timer usage */
297
298 /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
299 if( (0x00 != pTimerHandle->TimerId)
300 && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
301 )
302 {
303 /* Cancel the timer before deleting */
304 if(timer_delete(pTimerHandle->hTimerHandle) == -1)
305 {
306 NXPLOG_TML_E("timer %d delete error!", dwIndex);
307 }
308 /* Clear Timer structure used to store timer related data */
309 memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
310 }
311 }
312
313 return;
314 }
315
316 /*******************************************************************************
317 **
318 ** Function phOsalNfc_DeferredCall
319 **
320 ** Description Invokes the timer callback function after timer expiration.
321 ** Shall invoke the callback function registered by the timer caller function
322 **
323 ** Parameters pParams - parameters indicating the ID of the timer
324 **
325 ** Returns None -
326 **
327 *******************************************************************************/
phOsalNfc_DeferredCall(void * pParams)328 static void phOsalNfc_DeferredCall (void *pParams)
329 {
330 /* Retrieve the timer id from the parameter */
331 uint32_t dwIndex;
332 phOsalNfc_TimerHandle_t *pTimerHandle;
333 if(NULL != pParams)
334 {
335 /* Retrieve the index at which the timer handle structure is stored */
336 dwIndex = (uintptr_t)pParams - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
337 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
338 if(pTimerHandle->Application_callback != NULL)
339 {
340 /* Invoke the callback function with osal Timer ID */
341 pTimerHandle->Application_callback((uintptr_t)pParams, pTimerHandle->pContext);
342 }
343 }
344
345 return;
346 }
347
348 /*******************************************************************************
349 **
350 ** Function phOsalNfc_PostTimerMsg
351 **
352 ** Description Posts message on the user thread
353 ** Shall be invoked upon expiration of a timer
354 ** Shall post message on user thread through which timer callback function shall be invoked
355 **
356 ** Parameters pMsg - pointer to the message structure posted on user thread
357 **
358 ** Returns None -
359 **
360 *******************************************************************************/
phOsalNfc_PostTimerMsg(phLibNfc_Message_t * pMsg)361 static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg)
362 {
363
364 (void)phDal4Nfc_msgsnd(nxpncihal_ctrl.gDrvCfg.nClientId/*gpphOsalNfc_Context->dwCallbackThreadID*/, pMsg,0);
365
366 return;
367 }
368
369 /*******************************************************************************
370 **
371 ** Function phOsalNfc_Timer_Expired
372 **
373 ** Description posts message upon expiration of timer
374 ** Shall be invoked when any one timer is expired
375 ** Shall post message on user thread to invoke respective
376 ** callback function provided by the caller of Timer function
377 **
378 ** Returns None
379 **
380 *******************************************************************************/
phOsalNfc_Timer_Expired(union sigval sv)381 static void phOsalNfc_Timer_Expired(union sigval sv)
382 {
383 uint32_t dwIndex;
384 phOsalNfc_TimerHandle_t *pTimerHandle;
385
386
387 dwIndex = ((uint32_t)(sv.sival_int)) - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
388 pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
389 /* Timer is stopped when callback function is invoked */
390 pTimerHandle->eState = eTimerStopped;
391
392 pTimerHandle->tDeferedCallInfo.pDeferedCall = &phOsalNfc_DeferredCall;
393 pTimerHandle->tDeferedCallInfo.pParam = (void *) ((intptr_t)(sv.sival_int));
394
395 pTimerHandle->tOsalMessage.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
396 pTimerHandle->tOsalMessage.pMsgData = (void *)&pTimerHandle->tDeferedCallInfo;
397
398
399 /* Post a message on the queue to invoke the function */
400 phOsalNfc_PostTimerMsg ((phLibNfc_Message_t *)&pTimerHandle->tOsalMessage);
401
402 return;
403 }
404
405
406 /*******************************************************************************
407 **
408 ** Function phUtilNfc_CheckForAvailableTimer
409 **
410 ** Description Find an available timer id
411 **
412 ** Parameters void
413 **
414 ** Returns Available timer id
415 **
416 *******************************************************************************/
phUtilNfc_CheckForAvailableTimer(void)417 uint32_t phUtilNfc_CheckForAvailableTimer(void)
418 {
419 /* Variable used to store the index at which the object structure details
420 can be stored. Initialize it as not available. */
421 uint32_t dwIndex = 0x00;
422 uint32_t dwRetval = 0x00;
423
424
425 /* Check whether Timer object can be created */
426 for(dwIndex = 0x00;
427 ( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 == dwRetval) ); dwIndex++)
428 {
429 if(!(apTimerInfo[dwIndex].TimerId))
430 {
431 dwRetval = (dwIndex + 0x01);
432 }
433 }
434
435 return (dwRetval);
436
437 }
438
439 /*******************************************************************************
440 **
441 ** Function phOsalNfc_CheckTimerPresence
442 **
443 ** Description Checks the requested timer is present or not
444 **
445 ** Parameters pObjectHandle - timer context
446 **
447 ** Returns NFCSTATUS_SUCCESS if found
448 ** Other value if not found
449 **
450 *******************************************************************************/
phOsalNfc_CheckTimerPresence(void * pObjectHandle)451 NFCSTATUS phOsalNfc_CheckTimerPresence(void *pObjectHandle)
452 {
453 uint32_t dwIndex;
454 NFCSTATUS wRegisterStatus = NFCSTATUS_INVALID_PARAMETER;
455
456 for(dwIndex = 0x00; ( (dwIndex < PH_NFC_MAX_TIMER) &&
457 (wRegisterStatus != NFCSTATUS_SUCCESS) ); dwIndex++)
458 {
459 /* For Timer, check whether the requested handle is present or not */
460 if( ((&apTimerInfo[dwIndex]) ==
461 (phOsalNfc_TimerHandle_t *)pObjectHandle) &&
462 (apTimerInfo[dwIndex].TimerId) )
463 {
464 wRegisterStatus = NFCSTATUS_SUCCESS;
465 }
466 }
467 return wRegisterStatus;
468
469 }
470