//POSIX.1b Timer #include #include #include #include #include #include #include #include #include #include #include #include #include "../jni_log.h" #include "apptimer.h" #define MAX_TIMER 32 static struct { timer_t timerId; void (*func)(union sigval sig); int value; uint8_t *user_data; } AppTimer[MAX_TIMER]; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static int createTimer(timer_t *timerId, void (*func)(union sigval sig), int value, uint8_t *usr_data, int usr_data_length, uint8_t **usr_data_ptr) { struct sigevent sev; pthread_attr_t attr; // Register printMsg to SIGALRM pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached memset(&sev, 0, sizeof(sev)); sev.sigev_notify = SIGEV_THREAD; sev.sigev_notify_function = func; sev.sigev_notify_attributes = &attr; if (usr_data != NULL && usr_data_length != 0) { if ((sev.sigev_value.sival_ptr = malloc(usr_data_length)) != NULL) { *usr_data_ptr = (uint8_t *) sev.sigev_value.sival_ptr; memcpy(sev.sigev_value.sival_ptr, usr_data, usr_data_length); //Copy usr data sev.sigev_value.sival_int = usr_data_length; } else { return -1; } } else { sev.sigev_value.sival_int = value; } /* create timer */ if (timer_create(CLOCK_REALTIME, &sev, timerId) == -1) { return -1; } // LOGD("timer_create\n"); return 0; } static int setTimer(timer_t timerId, int timeMSec) { struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = timeMSec / 1000; its.it_value.tv_nsec = (timeMSec % 1000) * 1000000; its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0; if (timer_settime(timerId, 0, &its, NULL) == -1) { return -1; } // LOGD("timer_settime\n"); return 0; } void AppTimer_Init(void) { memset(AppTimer, 0, sizeof(AppTimer)); pthread_mutex_init(&mutex, NULL); } void AppTimer_add(void (*func)(union sigval), int timeMS) { int i; // LOGD("AppTimer_add\n"); pthread_mutex_lock(&mutex); for (i = 0; i < MAX_TIMER; i++) { if (AppTimer[i].func == NULL) { if (createTimer(&(AppTimer[i].timerId), func, 0, NULL, 0, &(AppTimer[i].user_data)) == 0) { AppTimer[i].func = func; if (setTimer(AppTimer[i].timerId, timeMS) != 0) { //Set timer fail, delele it timer_delete(AppTimer[i].timerId); if (AppTimer[i].user_data != NULL) { free(AppTimer[i].user_data); AppTimer[i].user_data = NULL; } AppTimer[i].func = NULL; } } break; } } pthread_mutex_unlock(&mutex); } void AppTimer_add(void (*func)(union sigval), int timeMS, uint8_t *data, int length) { int i; // LOGD("AppTimer_add\n"); pthread_mutex_lock(&mutex); for (i = 0; i < MAX_TIMER; i++) { if (AppTimer[i].func == NULL) { if (createTimer(&(AppTimer[i].timerId), func, 0, data, length, &(AppTimer[i].user_data)) == 0) { AppTimer[i].func = func; if (setTimer(AppTimer[i].timerId, timeMS) != 0) { //Set timer fail, delele it timer_delete(AppTimer[i].timerId); if (AppTimer[i].user_data != NULL) { free(AppTimer[i].user_data); AppTimer[i].user_data = NULL; } AppTimer[i].func = NULL; } } break; } } pthread_mutex_unlock(&mutex); } void AppTimer_add(void (*func)(union sigval), int timeMS, int value) { int i; // LOGD("AppTimer_add\n"); pthread_mutex_lock(&mutex); for (i = 0; i < MAX_TIMER; i++) { if (AppTimer[i].func == NULL) { if (createTimer(&(AppTimer[i].timerId), func, value, NULL, 0, &(AppTimer[i].user_data)) == 0) { AppTimer[i].func = func; if (setTimer(AppTimer[i].timerId, timeMS) != 0) { //Set timer fail, delele it timer_delete(AppTimer[i].timerId); if (AppTimer[i].user_data != NULL) { free(AppTimer[i].user_data); AppTimer[i].user_data = NULL; } AppTimer[i].func = NULL; } } break; } } pthread_mutex_unlock(&mutex); } void AppTimer_delete(void (*func)(union sigval)) { int i; // LOGD("AppTimer_delete\n"); pthread_mutex_lock(&mutex); for (i = 0; i < MAX_TIMER; i++) { if (AppTimer[i].func == func) { timer_delete(AppTimer[i].timerId); if (AppTimer[i].user_data != NULL) { free(AppTimer[i].user_data); AppTimer[i].user_data = NULL; } AppTimer[i].func = NULL; } } pthread_mutex_unlock(&mutex); } uint32_t AppTimer_GetTickCount(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); }