[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/ccapp/soft_timer.c b/ap/app/ccapp/soft_timer.c
new file mode 100644
index 0000000..5032f2f
--- /dev/null
+++ b/ap/app/ccapp/soft_timer.c
@@ -0,0 +1,493 @@
+/************************************************************************
+* °æÈ¨ËùÓÐ (C)2008, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+* 
+* ÎļþÃû³Æ£º soft_timer.c
+* Îļþ±êʶ£º 
+* ÄÚÈÝÕªÒª£º ¶¨ÒåͨÓõÄÈí¼þ¶¨Ê±Æ÷Ï߳̿â
+* ÆäËü˵Ã÷£º 
+* µ±Ç°°æ±¾£º V1.0
+* ×÷    Õߣº Ö£ÓñæÃ
+* Íê³ÉÈÕÆÚ£º 2010-09-02
+* 
+* Ð޸ļǼ1£º
+*    ÐÞ¸ÄÈÕÆÚ£º2010-09-02
+*    °æ ±¾ ºÅ£ºV1.0
+*    ÐÞ ¸Ä ÈË£ºÖ£ÓñæÃ
+*    ÐÞ¸ÄÄÚÈÝ£º³õʼ°æ±¾
+************************************************************************/
+#include  <stdio.h>
+#include  <stdlib.h>
+#include  <signal.h>
+#include  <sys/time.h>
+#include  <syslog.h>
+#include <fcntl.h>
+#include  <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include  "soft_timer.h"
+
+/*
+#define SOFT_TIMER_DEBUG 1
+*/
+/********************************************
+ * Macro declaration
+ *******************************************/
+#define NEW_TIMER_STEP 10
+#define MAX_TIMER_POOL_NUM  33
+
+/********************************************
+ * static variables
+ *******************************************/
+static SOFT_TIMER g_timer_pool[MAX_TIMER_POOL_NUM] = {0};
+static SOFT_TIMER *g_pTimerHeader = NULL;
+static int g_timer_initialized = 0;
+
+pthread_mutex_t g_timer_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void* SoftTimer_Loop(void *args);
+
+/********************************************
+ * SoftTimer_Init
+ * initialize global variables
+ *******************************************/
+static int SoftTimer_Init(void)
+{
+    int  result = 0;
+    pthread_attr_t attribute;
+    pthread_t stHandle;
+
+    if(0 == g_timer_initialized)
+    {
+        g_timer_initialized = 1;
+
+        pthread_attr_init(&attribute);
+        pthread_attr_setstacksize(&attribute, 32*1024);
+
+		#ifdef SOFT_TIMER_DEBUG
+        printf("Create soft timer first time, must create a thread now!\n");
+		#endif
+        result = pthread_create(&stHandle, &attribute, SoftTimer_Loop, NULL);
+        if(0 != result)
+        {
+		    #ifdef SOFT_TIMER_DEBUG
+            printf("StartSoftTimer failed, create thread fail %d!\n", result);
+			#endif
+            return ERROR;
+        }
+
+        g_pTimerHeader = &g_timer_pool[0];
+        g_pTimerHeader->next = g_pTimerHeader;
+        g_pTimerHeader->prev = g_pTimerHeader;
+        g_pTimerHeader->used = 1;
+    }
+
+    return OK;
+}
+
+/********************************************
+ * SetBasicTimerEx
+ * call [setitimer] to set basic timer
+ *******************************************/
+static void SetBasicTimerEx(int value)
+{
+    struct itimerval stTimer = {0};
+    struct itimerval oldTimer = {0};
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SetBasicTimerEx: value=%d\n", value);
+	#endif
+
+    stTimer.it_value.tv_sec = value / 1000;
+    stTimer.it_value.tv_usec = (value * 1000) % 1000000;
+
+    //stTimer.it_interval.tv_sec = stTimer.it_value.tv_sec;
+    //stTimer.it_interval.tv_usec = stTimer.it_value.tv_usec;
+
+    setitimer(ITIMER_REAL, &stTimer, &oldTimer);
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SetBasicTimerEx: tv_sec=%d, tv_usec=%d\n", stTimer.it_value.tv_sec, stTimer.it_value.tv_usec);
+    printf("SetBasicTimerEx:oldTimer tv_sec=%d, tv_usec=%d\n", oldTimer.it_value.tv_sec, oldTimer.it_value.tv_usec);
+	#endif
+}
+
+/********************************************
+ * SoftTimer_Add
+ * add a soft timer to double linked list
+ *******************************************/
+static int SoftTimer_Add(SOFT_TIMER *pHeader, SOFT_TIMER *pItem)
+{
+    SOFT_TIMER *pTmp = pHeader;
+
+    if(NULL == pHeader || NULL == pItem)
+    {
+        return -1;
+    }
+
+    do
+    {
+        if(pTmp->timerValue <= pItem->timerValue)
+        {
+            pTmp = pTmp->next;
+        }
+        else
+        {
+            break;
+        }
+    } while(pTmp != pHeader);
+
+    if(pTmp != pHeader)
+    {
+        pItem->next = pTmp;
+        pItem->prev = pTmp->prev;
+        pTmp->prev->next = pItem;
+        pTmp->prev = pItem;
+    }
+    else
+    {
+        pItem->next = pTmp;
+        pItem->prev = pTmp->prev;
+        pTmp->prev->next = pItem;
+        pTmp->prev = pItem;
+    }
+
+    return 0;
+}
+
+/********************************************
+ * SoftTimer_Delete
+ * delete a soft timer from double linked list
+ *******************************************/
+static int SoftTimer_Delete(SOFT_TIMER *pHeader, SOFT_TIMER *pItem)
+{
+    if(NULL == pHeader || NULL == pItem)
+    {
+        return -1;
+    }
+
+    if(pItem == pHeader)
+    {
+        return 0;
+    }
+
+    pItem->prev->next = pItem->next;
+    pItem->next->prev = pItem->prev;
+
+    return 0;
+}
+
+/********************************************
+ * SoftTimer_GetSize
+ * get total size of double linked list
+ *******************************************/
+static int SoftTimer_GetSize(SOFT_TIMER *pHeader)
+{
+    int size = 0;
+    SOFT_TIMER *pTmp = pHeader->next;
+
+    while(pTmp != pHeader)
+    {
+        size++;
+        pTmp = pTmp->next;
+    }
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SoftTimer_GetSize: size=%d\n", size);
+	#endif
+    return size;
+}
+
+/********************************************
+ * SoftTimer_Adjust
+ * adjust soft-timer's value in the double linked list
+ *******************************************/
+static int SoftTimer_AdjustTimerValue(SOFT_TIMER *pHeader, int value)
+{
+    SOFT_TIMER *pTmp = pHeader->next;
+
+    while(pTmp != pHeader)
+    {
+        pTmp->timerValue -= value;
+        pTmp = pTmp->next;
+    }
+    return 0;
+}
+
+/********************************************
+ * SoftTimer_Handler
+ * handler of soft-timer
+ *******************************************/
+static void SoftTimer_Handler(void)
+{
+    int index;
+    SOFT_TIMER *pHeader = g_pTimerHeader;
+    SOFT_TIMER *pTmp = pHeader->next;
+    unsigned int curTime = 0;
+
+    curTime = (pTmp != pHeader?pTmp->timerValue:0);
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SoftTimer_Ops: curTime=%d\n", curTime);
+	#endif
+
+    pthread_mutex_lock(&g_timer_mutex);
+
+    while(pTmp != pHeader)
+    {
+        pTmp->timerValue -= curTime;
+        if(pTmp->timerValue <= 0)
+        {
+            pTmp->procCallBack(pTmp->args);
+
+            if(TIMER_FLAG_RESTART == pTmp->ucFlag)
+            {
+                pTmp->timerValue = pTmp->ulNextInterval;
+            }
+            else
+            {
+                pTmp->timerValue = -1;
+            }
+            pTmp->done = 1;
+        }
+        pTmp = pTmp->next;
+    }
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SoftTimer_Ops:[1] %d\n", SoftTimer_GetSize(pHeader));
+	#endif
+
+    for(index = 1; index < MAX_TIMER_POOL_NUM; index++)
+    {
+        if(g_timer_pool[index].used && g_timer_pool[index].done)
+        {
+            g_timer_pool[index].done = 0;
+
+            SoftTimer_Delete(pHeader, &g_timer_pool[index]);
+
+            if(g_timer_pool[index].timerValue > 0)
+            {
+                SoftTimer_Add(pHeader, &g_timer_pool[index]);
+            }
+            else
+            {
+                memset(&g_timer_pool[index], 0, sizeof(SOFT_TIMER));
+            }
+        }
+    }
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SoftTimer_Ops:[2] %d\n", SoftTimer_GetSize(pHeader));
+	#endif
+
+    SetBasicTimerEx(pHeader->next->timerValue);
+
+    pthread_mutex_unlock(&g_timer_mutex);
+
+	#ifdef SOFT_TIMER_DEBUG
+    printf("SoftTimer_Ops: nextTime=%d\n", pHeader->next->timerValue);
+    #endif
+
+    return;
+}
+
+/********************************************
+ * SoftTimer_Loop
+ * A thread entry for soft-timer!
+ *******************************************/
+static void* SoftTimer_Loop(void *args)
+{
+    struct sigaction act;
+
+    act.sa_handler =(void*) SoftTimer_Handler;
+    act.sa_flags = 0;
+    sigemptyset(&act.sa_mask);
+    sigaction(SIGALRM, &act, NULL);
+
+    while(1)
+    {
+        pause();
+    }
+}
+
+static void SoftTimer_Process(int freeIndex)
+{
+    ULONG ulResidue = 0;
+    ULONG ulQuotient = 0;
+    int oldTimeValue = 0;
+    int leftTimeValue = 0;
+
+    struct itimerval stTimer = {0};
+
+    if(0 == SoftTimer_GetSize(g_pTimerHeader))
+    {
+        SoftTimer_Add(g_pTimerHeader, &( g_timer_pool[freeIndex]));
+        SetBasicTimerEx(g_pTimerHeader->next->timerValue);
+    }
+    else
+    {
+        oldTimeValue = g_pTimerHeader->next->timerValue;
+        if(oldTimeValue > 0)
+        {
+		    #ifdef SOFT_TIMER_DEBUG
+            printf("CreateSoftTimer: oldTimeValue=%d\n", oldTimeValue);
+			#endif
+            getitimer(ITIMER_REAL, &stTimer);
+			#ifdef SOFT_TIMER_DEBUG
+            printf("CreateSoftTimer: tv_sec=%d, tv_usec=%d\n", stTimer.it_value.tv_sec, stTimer.it_value.tv_usec);
+            #endif
+            leftTimeValue = stTimer.it_value.tv_sec * 1000 + (stTimer.it_value.tv_usec/1000);
+
+            ulResidue = leftTimeValue % NEW_TIMER_STEP;
+            if (0 != ulResidue)
+            {
+                ulQuotient = leftTimeValue / NEW_TIMER_STEP;
+                leftTimeValue = (ulQuotient + 1) * NEW_TIMER_STEP;
+            }
+            #ifdef SOFT_TIMER_DEBUG
+            printf("CreateSoftTimer: oldTimeValue=%d, leftTimeValue=%d\n", oldTimeValue, leftTimeValue);
+            #endif
+            if(oldTimeValue - leftTimeValue >=  NEW_TIMER_STEP)
+            {
+                SoftTimer_AdjustTimerValue(g_pTimerHeader, oldTimeValue - leftTimeValue);
+            }
+
+            SoftTimer_Add(g_pTimerHeader, &( g_timer_pool[freeIndex]));
+            SetBasicTimerEx(g_pTimerHeader->next->timerValue);
+        }
+    }
+}
+
+/********************************************
+ * CreateSoftTimer
+ * create a new soft-timer!
+ *******************************************/
+LONG CreateSoftTimer(USHORT usTimerID,
+                     UCHAR ucFlag,
+                     ULONG ulInterval,
+                     void * (*procCallBack)(void *),
+                     void *args)
+{
+    int ucIndex = 0;
+    int freeIndex = 0;
+
+    ULONG ulResidue = 0;
+    ULONG ulQuotient = 0;
+
+    if (NULL == procCallBack)
+    {
+	    #ifdef SOFT_TIMER_DEBUG
+        printf("CreateSoftTimer failed, procCallBack is NULL!\n");
+		#endif
+        return ERROR;
+    }
+
+    pthread_mutex_lock(&g_timer_mutex);
+
+    if(OK != SoftTimer_Init())
+    {
+        pthread_mutex_unlock(&g_timer_mutex);
+        return ERROR;
+    }
+
+    for(ucIndex = 1, freeIndex = 0; ucIndex < MAX_TIMER_POOL_NUM; ucIndex++)
+    {
+        /*same timer id exist, warning, return error*/
+        if (g_timer_pool[ucIndex].used && (usTimerID == g_timer_pool[ucIndex].usTimerID))
+        {
+		    #ifdef SOFT_TIMER_DEBUG
+            printf("Same timer id 0x%04x exist!\n", usTimerID);
+			#endif
+            pthread_mutex_unlock(&g_timer_mutex);
+            return ERROR;
+        }
+        if ((0 == g_timer_pool[ucIndex].used) && (0 == freeIndex))
+        {
+            freeIndex = ucIndex;
+        }
+    }
+
+    /* No empty timer left */
+    if (0 == freeIndex)
+    {
+	    #ifdef SOFT_TIMER_DEBUG
+        printf("StartSoftTimer 0x%04x failed, queue full!\n", usTimerID);
+		#endif
+        pthread_mutex_unlock(&g_timer_mutex);
+        return ERROR;
+    }
+
+    /* Adjust interval value, it must multiple of 10 */
+    ulResidue = ulInterval % NEW_TIMER_STEP;
+    if (0 != ulResidue)
+    {
+        ulQuotient = ulInterval / NEW_TIMER_STEP;
+        ulInterval = (ulQuotient + 1) * NEW_TIMER_STEP;
+    }
+
+    g_timer_pool[freeIndex].used = 1;
+    g_timer_pool[freeIndex].usTimerID = usTimerID;
+    g_timer_pool[freeIndex].ucFlag = ucFlag;
+    g_timer_pool[freeIndex].ulCurInterval = ulInterval;
+    g_timer_pool[freeIndex].ulNextInterval = ulInterval;
+    g_timer_pool[freeIndex].procCallBack = procCallBack;
+    g_timer_pool[freeIndex].args = args;
+    g_timer_pool[freeIndex].timerValue = ulInterval;
+
+    SoftTimer_Process(freeIndex);
+    #ifdef SOFT_TIMER_DEBUG
+    printf("CreateSoftTimer index %d success: \n"
+           "usTimerID = %d, \n"
+           "ucFlag = %d, \n"
+           "ulCurInterval = %ld, \n"
+           "ulNextInterval = %ld, \n"
+           "procCallBack = %p, \n"
+           "args =  %p. \n",
+           freeIndex,
+           usTimerID,
+           ucFlag,
+           ulInterval,
+           ulInterval,
+           procCallBack,
+           args);
+    #endif
+    pthread_mutex_unlock(&g_timer_mutex);
+
+    return OK;
+}
+
+/********************************************
+ * DeleteSoftTimer
+ * delete a soft-timer!
+ *******************************************/
+LONG DeleteSoftTimer(USHORT usTimerID)
+{
+    UCHAR ucIndex = 0;
+
+    pthread_mutex_lock(&g_timer_mutex);
+
+    for(ucIndex = 1; ucIndex < MAX_TIMER_POOL_NUM; ucIndex++)
+    {
+        if(g_timer_pool[ucIndex].used && (usTimerID == g_timer_pool[ucIndex].usTimerID))
+        {
+            break;
+        }
+    }
+
+    if (ucIndex >= MAX_TIMER_POOL_NUM)
+    {
+	    #ifdef SOFT_TIMER_DEBUG
+        printf("DeleteSoftTimer 0x%04x failed, not exist!\n", usTimerID);
+		#endif
+        pthread_mutex_unlock(&g_timer_mutex);
+        return ERROR;
+    }
+
+    SoftTimer_Delete(g_pTimerHeader, &( g_timer_pool[ucIndex]));
+    memset(&g_timer_pool[ucIndex], 0, sizeof(SOFT_TIMER));
+    #ifdef SOFT_TIMER_DEBUG
+    printf("DeleteSoftTimer 0x%04x success!\n", usTimerID);
+    #endif
+    pthread_mutex_unlock(&g_timer_mutex);
+    return OK;
+}