📄 natinit.c
字号:
* Call this routine to remove an event from the message queue processed by * the 'tNAT' task. After calling this function, the event ID is no longer * valid.** RETURNS: OK, upon success; or ERROR, upon failure.**/STATUS natEvtRemove ( void * eventId /* From a successful event creation. */ ) { REMOVE_EVENT_DESC * pEvt; if ((pEvt = (REMOVE_EVENT_DESC *)malloc(sizeof(REMOVE_EVENT_DESC))) == NULL) { nat_printf(NAT_PRINTF_ERROR, "Fail to allocate the memory for removal event\n"); return ERROR; } pEvt->evtNode.msgId = TYPE_REMOVE_EVENT; pEvt->eventId = eventId; if (msgQSend(natDispatcher.msgQId,(char *)&pEvt,sizeof(void *), sysClkRateGet() >> 2, /*wait for 0.5 sec, not to hang forever in case */ MSG_PRI_NORMAL) != OK) { free((void *)pEvt); return ERROR; } return (OK); }/******************************************************************************* natTaskDelete - delete the 'tNAT' task and free associated resources** Call this routine to send a "delete" message to the message queue processed * by the 'tNAT' task. Upon processing this message, the task frees all * resources associated with its message queue and then shuts itself down. * * RETURNS: OK, upon success; or ERROR, upon failure.** NOMANUAL* */STATUS natTaskDelete (void) { SHUTDOWN_EVENT_DESC * pEvt; if ((pEvt = (SHUTDOWN_EVENT_DESC *)malloc(sizeof(SHUTDOWN_EVENT_DESC))) == NULL) { nat_printf(NAT_PRINTF_ERROR, "Fail to allocate the memory for shutdown event\n"); return ERROR; } pEvt->msgId = TYPE_SHUTDOWN_EVENT; /* send an shutdown event to let the NAT task delete itself and cleanup */ if (msgQSend(natDispatcher.msgQId,(char *)&pEvt,sizeof(void *), sysClkRateGet() >> 2, /*wait for 0.5 sec, not to hang forever in case */ MSG_PRI_URGENT) != OK) { free((void *)pEvt); return ERROR; } /* give NAT task some time to do the deletion job */ taskDelay(4); return (OK); }/******************************************************************************* natTimerResolutionSet - set the timer resolution in vxWorks ticks** Use this function to specify how often the NAT timer facility checks * for expired timers and events, such as a create timer event, a delete * timer event, or an activate timer event. The default resolution is * 5 ticks. * */int natTimerResolutionSet ( int ticks ) { if (ticks) natDispatcher.msgQTimeOutTicks = ticks; return (natDispatcher.msgQTimeOutTicks); }/******************************************************************************** dispatchTask - run as the dispatch task for NAT component** This function defines the event-processing loop for the message queue. * * NOMANUAL* */LOCAL void dispatchTask ( EVT_DISPATCHER_DESC * pDesc ) { EVT_NODE * pEvtNode; int numOfBytes; nat_task_initialize(NULL); /* record the last system tick */ pDesc->lastTick = tickGet(); for (;;) { numOfBytes = msgQReceive(pDesc->msgQId, (char *)&pEvtNode, sizeof(EVT_NODE *), pDesc->msgQTimeOutTicks); /* check if there is a message */ if ((numOfBytes != ERROR) && (numOfBytes >= sizeof(EVT_NODE *)) ) { /* handle the message */ switch (pEvtNode->msgId) { case TYPE_TIMER_EVENT: /* enqueue the timer event */ dllAdd(&pDesc->timerEvtList,&pEvtNode->node); break; case TYPE_ACTIVATE_EVENT: { ACTIVATE_EVENT_DESC *pEvt = (ACTIVATE_EVENT_DESC *)pEvtNode; /* retrive the event to be actiavated */ EVT_NODE * pEventIdNode = (EVT_NODE *)pEvt->eventId; if (pEventIdNode->msgId == TYPE_TIMER_EVENT) { /* locate the timer event in the list */ if (nodeSearch(&pDesc->timerEvtList, &pEventIdNode->node) == TRUE) { TIMER_EVENT_DESC * pTimerEvt; /* load the timer interval and turn it on */ pTimerEvt = (TIMER_EVENT_DESC *)pEventIdNode; pTimerEvt->state = TIMER_START; pTimerEvt->expireInterval = pTimerEvt->duration; } } free ((void *)pEvtNode); } break; case TYPE_REMOVE_EVENT: { DL_NODE * pNode = (DL_NODE *) (((REMOVE_EVENT_DESC *)pEvtNode)->eventId); if (nodeSearch(&pDesc->timerEvtList,pNode) == TRUE) { dllRemove(&pDesc->timerEvtList,pNode); free((void *)pNode); } free ((void *)pEvtNode); } break; case TYPE_SHUTDOWN_EVENT: /* terminate the NAT task itself and cleanup */ { EVT_NODE * pNextEvtNode; /* first dump and free all queued events */ while (msgQReceive (pDesc->msgQId, (char *)&pNextEvtNode, sizeof(EVT_NODE *), NO_WAIT) != ERROR) { free((void *)pNextEvtNode); } /* remove all events in the list */ dllFreeList(&pDesc->timerEvtList); /* free the current event */ free ((void *)pEvtNode); /* delete the message queue */ msgQDelete(pDesc->msgQId); /* Now delete the task ifself */ taskDelete(0); /* should never come to here, unreachable */ } break; default: break; } /* end switch statement */ } /* end if (numOfBytes) */ /* check if there is more message */ if (msgQNumMsgs(pDesc->msgQId) <= 0) { /* no more messages in the Q, check the timer */ timerUpdateAndEvtFuncExec(pDesc); } } }/******************************************************************************** timerUpdateAndEvtFuncExec - update timers and execute the event functions** This updates timers and executes the event functions.* * NOMANUAL*/LOCAL void timerUpdateAndEvtFuncExec ( EVT_DISPATCHER_DESC * pDesc ) { ULONG curTime; ULONG timeDelta; TIMER_EVENT_DESC * pTimeEvt; DL_NODE * pRmNode = NULL; /* the current system tick */ curTime = tickGet(); /* the time difference between now and the last recorded system tick */ timeDelta = curTime >= pDesc->lastTick? /* tick counter wrap around? */ curTime - pDesc->lastTick: /* no */ (UINT32)0xffffffff - pDesc->lastTick + curTime; /* yes */ /* update the last tick counter */ pDesc->lastTick = curTime; /* update the running timer interval */ pTimeEvt = (TIMER_EVENT_DESC *)DLL_FIRST(&pDesc->timerEvtList); while (pTimeEvt) { if (pTimeEvt->state == TIMER_START) { if (pTimeEvt->expireInterval > timeDelta) /* decrement the timer interval */ pTimeEvt->expireInterval -= timeDelta; else { /* timer expired, execute the event function */ pTimeEvt->pEvtFunc(pTimeEvt->evtFuncContext); if (pTimeEvt->option & OPTION_ONE_SHOT) { /* the node to be removed */ pRmNode = &pTimeEvt->evtNode.node; } else /* reload the timer duration contant */ pTimeEvt->expireInterval = pTimeEvt->duration; } } pTimeEvt = (TIMER_EVENT_DESC *)DLL_NEXT(&pTimeEvt->evtNode.node); if (pRmNode != NULL) { dllRemove(&pDesc->timerEvtList,pRmNode); free((void *)pRmNode); pRmNode = NULL; } } }/******************************************************************************** nodeSearch - Match the given node in the list** This function matches the given node against the list.* * NOMANUAL */LOCAL BOOL nodeSearch ( DL_LIST * pList, DL_NODE * pMatchNode ) { DL_NODE * pNode; pNode = DLL_FIRST(pList); while (pNode) { if (pNode == pMatchNode) return TRUE; pNode = DLL_NEXT(pNode); } return FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -