blob: 0d1aec4993cc469cd35d549bbb56cad96453372c [file] [log] [blame]
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/ioctl.h>
#include <dlfcn.h>
#include <stdint.h>
#include <sys/time.h>
#include "gsw_pm_interface.h"
#ifndef LOG_ERR_LEVEL
#define LOG_ERR_LEVEL 3 /* error conditions */
#endif
#ifndef LOG_WARN_LEVEL
#define LOG_WARN_LEVEL 4 /* warning conditions */
#endif
#ifndef LOG_INFO_LEVEL
#define LOG_INFO_LEVEL 6 /* informational */
#endif
#ifndef LOG_DEBUG_LEVEL
#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
#endif
#ifndef LOG_VERBOSE_LEVEL
#define LOG_VERBOSE_LEVEL 8
#endif
#define GSW_PM "[HAL][GSW_PM]"
#define GSW_WAKELOCK_NAME "gsw_app_wakelock"
#define LOGV(fmt, args ...) \
do{ \
char *file_ptr_1001 = __FILE__; \
char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
char line_1001[10] = {0}; \
sprintf(line_1001, "%d", __LINE__); \
while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
if(*ptr_1001 == '/') \
break; \
ptr_1001--; \
} \
fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
} while(0)
#define LOGI(fmt, args...) \
do{ \
char *file_ptr_1001 = __FILE__; \
char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
char line_1001[10] = {0}; \
sprintf(line_1001, "%d", __LINE__); \
while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
if(*ptr_1001 == '/') \
break; \
ptr_1001--; \
} \
fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
} while(0)
#define LOGD(fmt, args...) \
do{ \
char *file_ptr_1001 = __FILE__; \
char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
char line_1001[10] = {0}; \
sprintf(line_1001, "%d", __LINE__); \
while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
if(*ptr_1001 == '/') \
break; \
ptr_1001--; \
} \
fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
} while(0)
#define LOGW(fmt, args...) \
do{ \
char *file_ptr_1001 = __FILE__; \
char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
char line_1001[10] = {0}; \
sprintf(line_1001, "%d", __LINE__); \
while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
if(*ptr_1001 == '/') \
break; \
ptr_1001--; \
} \
fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
} while(0)
#define LOGE(fmt, args...) \
do{ \
char *file_ptr_1001 = __FILE__; \
char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
char line_1001[10] = {0}; \
sprintf(line_1001, "%d", __LINE__); \
while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
if(*ptr_1001 == '/') \
break; \
ptr_1001--; \
} \
fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
} while(0)
#define LOCK_MAX_SIZE 129
#define SDK_READY_CMD "uci get persist.mbtk.sdk__state"
#define CHECK_SYSTEM(cmd) do { \
int _ret = system(cmd); \
if (_ret == -1) perror("system error"); \
} while(0)
typedef void (*GSW_PM_WAKEUPCALLBACK)(int32_t wakeup_in);
typedef void (*mbtk_lpm_handler_t)(int32_t wakeup_in);
typedef void (*mbtk_log)(int level, const char *format,...);
int (*mbtk_autosuspend_enable)(char);
int (*mbtk_wakelock_create)(const char* name , size_t);
int (*mbtk_wakelock_lock)(int);
int (*mbtk_wakelock_unlock)(int);
int (*mbtk_wakelock_destroy)(int);
int (*mbtk_lpm_init)(mbtk_lpm_handler_t );
int lock_fd = -1;
typedef struct
{
int fd;
char *name;
} mbtk_lock_name_s;
static mbtk_lock_name_s lock_name[LOCK_MAX_SIZE]={0};
static mbtk_log fun_ptr_log = NULL;
static void *dlHandle_sleep = NULL;
char *lynqLib_sleep = "/lib/libmbtk_lib.so";
//0 success,1 timeout,the timeout is 60s
static int wait_sdk_ready()
{
char buffer[8] = {0};
int sdk_value = -1;
int timeout = 0;
const char *s_kmsg = "echo \"check_sdk_ready ready\" > /dev/kmsg";
const char *f_kmsg = "echo \"check_sdk_ready timeout\" > /dev/kmsg";
while(timeout < 500) // ~= 60s
{
timeout++;
FILE *fp = popen(SDK_READY_CMD, "r");
if(NULL == fp)
{
continue;
}
memset(buffer,0,sizeof(buffer));
if(fgets(buffer, sizeof(buffer), fp) == NULL)
{
pclose(fp);
perror("fgets failed:");
continue;
}
pclose(fp);
printf("gsw wait_sdk_ready:%s",buffer);
sdk_value = atoi(buffer);
if(sdk_value == 0) //sdk ready
{
CHECK_SYSTEM(s_kmsg);
return 0;
}
usleep(1000*100);//100ms
}
CHECK_SYSTEM(f_kmsg);
return 1;
}
/**
* @brief Enable autosleep
* @param void
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
static int handle()
{
if(dlHandle_sleep == NULL || fun_ptr_log == NULL)
{
dlHandle_sleep = dlopen(lynqLib_sleep, RTLD_NOW);
fun_ptr_log = (mbtk_log)dlsym(dlHandle_sleep, "mbtk_log");
if(fun_ptr_log == NULL || dlHandle_sleep == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
return GSW_HAL_SUCCESS;
}
int32_t gsw_autosleep_enable(void)
{
int ret;
if (handle())
return GSW_HAL_NORMAL_FAIL;
mbtk_autosuspend_enable=(int(*)(char))dlsym(dlHandle_sleep, "mbtk_autosuspend_enable");
ret = mbtk_autosuspend_enable(1);
if(ret < 0)
{
LOGE("mbtk_autosuspend_enable FAIL.\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief Disable autosleep
* @param void
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_autosleep_disenable(void)
{
int ret;
if (handle())
return GSW_HAL_NORMAL_FAIL;
mbtk_autosuspend_enable=(int(*)(char))dlsym(dlHandle_sleep, "mbtk_autosuspend_enable");
ret = mbtk_autosuspend_enable(0);
if(ret < 0)
{
LOGE("mbtk_autosuspend_enable FAIL.\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief Init power manager module
* @param [in]GSW_PM_WAKEUPCALLBACKHandler wakeup_callback
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_pm_sdk_init(GSW_PM_WAKEUPCALLBACK wakeup_callback)
{
int ret = 0;
ret = wait_sdk_ready(); //Continue to execute even if timed out
printf("wait_sdk_ready ret:%d\n",ret); //due to the LOG* can not use
if (handle())
return GSW_HAL_NORMAL_FAIL;
mbtk_lpm_init=(int(*)(mbtk_lpm_handler_t))dlsym(dlHandle_sleep, "mbtk_lpm_init");
ret = mbtk_lpm_init((mbtk_lpm_handler_t)wakeup_callback);
if(ret < 0)
{
LOGE("mbtk_lpm_init FAIL.\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief Release wake lock, enter sleep
* @param [in]int32_t wakeup_in
* @retval int
*/
int32_t gsw_pm_enter_sleep(const char *gsw_wakelock_name)
{
int ret;
int i;
if (handle())
return GSW_HAL_NORMAL_FAIL;
if (gsw_wakelock_name == NULL)
return GSW_HAL_NORMAL_FAIL;
for(i=0 ;i<LOCK_MAX_SIZE;i++)
{
if(lock_name[i].name != NULL && strcmp(lock_name[i].name, gsw_wakelock_name) == 0)
{
lock_fd = lock_name[i].fd;
break;
}
}
if (i >= LOCK_MAX_SIZE)
{
LOGE("mbtk_wakelock_lock not create.\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_wakelock_unlock=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_unlock");
ret = mbtk_wakelock_unlock(lock_fd);
if(ret < 0)
{
LOGE("mbtk_wakelock_unlock FAIL.\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_wakelock_destroy=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_destroy");
ret = mbtk_wakelock_destroy(lock_fd);
if(ret < 0)
{
LOGE("mbtk_wakelock_destroy FAIL.\n");
return GSW_HAL_NORMAL_FAIL;
}
if (lock_name[i].name != NULL)
{
free(lock_name[i].name);
lock_name[i].name = NULL;
lock_name[i].fd = -1;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief Creat wakeup lock
* @param [in]int32_t wakeup_in
* @retval int
*/
int32_t gsw_pm_exit_sleep(const char *gsw_wakelock_name)
{
int ret;
int i;
if (handle())
return GSW_HAL_NORMAL_FAIL;
if (gsw_wakelock_name == NULL)
return GSW_HAL_NORMAL_FAIL;
mbtk_wakelock_create=(int(*)(const char* name , size_t))dlsym(dlHandle_sleep, "mbtk_wakelock_create");
lock_fd = mbtk_wakelock_create(gsw_wakelock_name, strlen(gsw_wakelock_name));
if(lock_fd < 0)
{
LOGE("mbtk_wakelock_create FAIL.\n");
ret = GSW_HAL_NORMAL_FAIL;
goto end;
}
mbtk_wakelock_lock=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_lock");
ret = mbtk_wakelock_lock(lock_fd);
if(ret < 0)
{
LOGE("mbtk_wakelock_lock FAIL.\n");
ret = GSW_HAL_NORMAL_FAIL;
goto end;
}
for(i=0 ;i<LOCK_MAX_SIZE;i++)
{
if(lock_name[i].name == NULL)
break;
}
if(i == LOCK_MAX_SIZE)
{
LOGE("mbtk_wakelock_lock not space FAIL.\n");
ret = GSW_HAL_NORMAL_FAIL;
goto end;
}
lock_name[i].name = malloc(strlen(gsw_wakelock_name)+1);
if (lock_name[i].name == NULL)
{
LOGE("mbtk_wakelock_lock remeber FAIL.\n");
ret = GSW_HAL_NORMAL_FAIL;
goto end;
}
memcpy(lock_name[i].name, gsw_wakelock_name, strlen(gsw_wakelock_name)+1);
lock_name[i].fd = lock_fd;
ret = GSW_HAL_SUCCESS;
end:
return ret;
}
/**
* @brief Module log disk drop, used when restarting or hibernating
* @param [in]void
* @retval void
*/
void gsw_modem_log_sync(void)
{
FILE *fp;
char command[256];
char buffer[256];
int pid = -1;
const char *process_name = "mbtk_logd";
snprintf(command, sizeof(command), "pgrep %s", process_name);
fp = popen(command, "r");
if (fp == NULL)
{
perror("error comman");
return;
}
if (fgets(buffer, sizeof(buffer), fp) != NULL)
{
pid = atoi(buffer);
}
pclose(fp);
if (pid != -1)
{
if (kill(pid, SIGTERM) == -1)
{
perror("send SIGTERM signal failed");
return;
}
}
return;
}
/**
* @brief enable autosleep
* @return int : 0 is success , other failed
*/
int gswAutoSleepEnable(void)
{
return gsw_autosleep_enable();
}
/**
* @brief disenable autosleep
* @return int : 0 is success , other failed
*/
int gswAutoSleepDisable(void)
{
return gsw_autosleep_disenable();
}
/**
* @brief modem relase wakeuplock
* @return void
*/
void gswPMStartSleep(void)
{
gsw_pm_enter_sleep(GSW_WAKELOCK_NAME);
}
/**
* @brief modem add wakeuplock
* @return int : 0 is success , other failed
*/
int gswPMStopSleep(void)
{
return gsw_pm_exit_sleep(GSW_WAKELOCK_NAME);
}
int gswPmSDKInit(gsw_pm_wakeup_handler gswPmCallBack)
{
return gsw_pm_sdk_init(gswPmCallBack);
}