blob: 0d1aec4993cc469cd35d549bbb56cad96453372c [file] [log] [blame]
b.liu68a94c92025-05-24 12:53:41 +08001#include <stdio.h>
2#include <string.h>
3#include <strings.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <termios.h>
7#include <fcntl.h>
8#include <signal.h>
9#include <sys/types.h>
10#include <unistd.h>
11#include <pthread.h>
12#include <time.h>
13#include <sys/ioctl.h>
14#include <dlfcn.h>
15#include <stdint.h>
hong.liufa3dc0a2025-06-30 17:30:59 +080016#include <sys/time.h>
hong.liucd370792025-05-28 06:29:19 -070017#include "gsw_pm_interface.h"
b.liu68a94c92025-05-24 12:53:41 +080018
19#ifndef LOG_ERR_LEVEL
20#define LOG_ERR_LEVEL 3 /* error conditions */
21#endif
22#ifndef LOG_WARN_LEVEL
23#define LOG_WARN_LEVEL 4 /* warning conditions */
24#endif
25#ifndef LOG_INFO_LEVEL
26#define LOG_INFO_LEVEL 6 /* informational */
27#endif
28#ifndef LOG_DEBUG_LEVEL
29#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
30#endif
31#ifndef LOG_VERBOSE_LEVEL
32#define LOG_VERBOSE_LEVEL 8
33#endif
34
l.yang6a42e4d2025-05-28 01:04:20 -070035#define GSW_PM "[HAL][GSW_PM]"
hong.liud2417072025-06-27 07:10:37 -070036#define GSW_WAKELOCK_NAME "gsw_app_wakelock"
b.liu68a94c92025-05-24 12:53:41 +080037#define LOGV(fmt, args ...) \
38 do{ \
39 char *file_ptr_1001 = __FILE__; \
40 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
41 char line_1001[10] = {0}; \
42 sprintf(line_1001, "%d", __LINE__); \
43 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
44 if(*ptr_1001 == '/') \
45 break; \
46 ptr_1001--; \
47 } \
l.yang6a42e4d2025-05-28 01:04:20 -070048 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080049 } while(0)
50
51#define LOGI(fmt, args...) \
52 do{ \
53 char *file_ptr_1001 = __FILE__; \
54 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
55 char line_1001[10] = {0}; \
56 sprintf(line_1001, "%d", __LINE__); \
57 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
58 if(*ptr_1001 == '/') \
59 break; \
60 ptr_1001--; \
61 } \
l.yang6a42e4d2025-05-28 01:04:20 -070062 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080063 } while(0)
64
65#define LOGD(fmt, args...) \
66 do{ \
67 char *file_ptr_1001 = __FILE__; \
68 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
69 char line_1001[10] = {0}; \
70 sprintf(line_1001, "%d", __LINE__); \
71 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
72 if(*ptr_1001 == '/') \
73 break; \
74 ptr_1001--; \
75 } \
l.yang6a42e4d2025-05-28 01:04:20 -070076 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080077 } while(0)
78
79#define LOGW(fmt, args...) \
80 do{ \
81 char *file_ptr_1001 = __FILE__; \
82 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
83 char line_1001[10] = {0}; \
84 sprintf(line_1001, "%d", __LINE__); \
85 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
86 if(*ptr_1001 == '/') \
87 break; \
88 ptr_1001--; \
89 } \
l.yang6a42e4d2025-05-28 01:04:20 -070090 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080091 } while(0)
92
93#define LOGE(fmt, args...) \
94 do{ \
95 char *file_ptr_1001 = __FILE__; \
96 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
97 char line_1001[10] = {0}; \
98 sprintf(line_1001, "%d", __LINE__); \
99 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
100 if(*ptr_1001 == '/') \
101 break; \
102 ptr_1001--; \
103 } \
l.yang6a42e4d2025-05-28 01:04:20 -0700104 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_PM"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +0800105 } while(0)
106
107
b.liu68a94c92025-05-24 12:53:41 +0800108#define LOCK_MAX_SIZE 129
hong.liufa3dc0a2025-06-30 17:30:59 +0800109#define SDK_READY_CMD "uci get persist.mbtk.sdk__state"
110#define CHECK_SYSTEM(cmd) do { \
111 int _ret = system(cmd); \
112 if (_ret == -1) perror("system error"); \
113} while(0)
hong.liucd370792025-05-28 06:29:19 -0700114typedef void (*GSW_PM_WAKEUPCALLBACK)(int32_t wakeup_in);
b.liu68a94c92025-05-24 12:53:41 +0800115typedef void (*mbtk_lpm_handler_t)(int32_t wakeup_in);
116typedef void (*mbtk_log)(int level, const char *format,...);
117
118int (*mbtk_autosuspend_enable)(char);
119int (*mbtk_wakelock_create)(const char* name , size_t);
120int (*mbtk_wakelock_lock)(int);
121int (*mbtk_wakelock_unlock)(int);
122int (*mbtk_wakelock_destroy)(int);
123int (*mbtk_lpm_init)(mbtk_lpm_handler_t );
124int lock_fd = -1;
125
126typedef struct
127{
128 int fd;
129 char *name;
130} mbtk_lock_name_s;
131static mbtk_lock_name_s lock_name[LOCK_MAX_SIZE]={0};
132
133static mbtk_log fun_ptr_log = NULL;
lichengzhangea38e902025-06-14 11:53:03 +0800134static void *dlHandle_sleep = NULL;
b.liu68a94c92025-05-24 12:53:41 +0800135char *lynqLib_sleep = "/lib/libmbtk_lib.so";
136
hong.liufa3dc0a2025-06-30 17:30:59 +0800137//0 success,1 timeout,the timeout is 60s
138static int wait_sdk_ready()
139{
140 char buffer[8] = {0};
141 int sdk_value = -1;
142 int timeout = 0;
143 const char *s_kmsg = "echo \"check_sdk_ready ready\" > /dev/kmsg";
144 const char *f_kmsg = "echo \"check_sdk_ready timeout\" > /dev/kmsg";
145 while(timeout < 500) // ~= 60s
146 {
147 timeout++;
148 FILE *fp = popen(SDK_READY_CMD, "r");
149 if(NULL == fp)
150 {
151 continue;
152 }
153 memset(buffer,0,sizeof(buffer));
154 if(fgets(buffer, sizeof(buffer), fp) == NULL)
155 {
156 pclose(fp);
157 perror("fgets failed:");
158 continue;
159 }
160 pclose(fp);
161 printf("gsw wait_sdk_ready:%s",buffer);
162 sdk_value = atoi(buffer);
163 if(sdk_value == 0) //sdk ready
164 {
165 CHECK_SYSTEM(s_kmsg);
166 return 0;
167 }
168 usleep(1000*100);//100ms
169 }
170 CHECK_SYSTEM(f_kmsg);
171 return 1;
172}
b.liu68a94c92025-05-24 12:53:41 +0800173
174/**
175* @brief Enable autosleep
176* @param void
hong.liucd370792025-05-28 06:29:19 -0700177* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
b.liu68a94c92025-05-24 12:53:41 +0800178*/
179
180static int handle()
181{
182 if(dlHandle_sleep == NULL || fun_ptr_log == NULL)
183 {
184 dlHandle_sleep = dlopen(lynqLib_sleep, RTLD_NOW);
185 fun_ptr_log = (mbtk_log)dlsym(dlHandle_sleep, "mbtk_log");
186 if(fun_ptr_log == NULL || dlHandle_sleep == NULL)
187 {
hong.liucd370792025-05-28 06:29:19 -0700188 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800189 }
190 }
191 return GSW_HAL_SUCCESS;
192}
193
194int32_t gsw_autosleep_enable(void)
195{
196 int ret;
197 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700198 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800199 mbtk_autosuspend_enable=(int(*)(char))dlsym(dlHandle_sleep, "mbtk_autosuspend_enable");
200 ret = mbtk_autosuspend_enable(1);
201 if(ret < 0)
202 {
203 LOGE("mbtk_autosuspend_enable FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700204 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800205 }
b.liu68a94c92025-05-24 12:53:41 +0800206 return GSW_HAL_SUCCESS;
207}
208
209/**
210* @brief Disable autosleep
211* @param void
hong.liucd370792025-05-28 06:29:19 -0700212* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
b.liu68a94c92025-05-24 12:53:41 +0800213*/
214int32_t gsw_autosleep_disenable(void)
215{
216 int ret;
217 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700218 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800219 mbtk_autosuspend_enable=(int(*)(char))dlsym(dlHandle_sleep, "mbtk_autosuspend_enable");
220 ret = mbtk_autosuspend_enable(0);
221 if(ret < 0)
222 {
223 LOGE("mbtk_autosuspend_enable FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700224 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800225 }
b.liu68a94c92025-05-24 12:53:41 +0800226 return GSW_HAL_SUCCESS;
227}
228
229/**
230* @brief Init power manager module
231* @param [in]GSW_PM_WAKEUPCALLBACKHandler wakeup_callback
hong.liucd370792025-05-28 06:29:19 -0700232* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
b.liu68a94c92025-05-24 12:53:41 +0800233*/
234int32_t gsw_pm_sdk_init(GSW_PM_WAKEUPCALLBACK wakeup_callback)
235{
hong.liufa3dc0a2025-06-30 17:30:59 +0800236 int ret = 0;
237 ret = wait_sdk_ready(); //Continue to execute even if timed out
238 printf("wait_sdk_ready ret:%d\n",ret); //due to the LOG* can not use
b.liu68a94c92025-05-24 12:53:41 +0800239 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700240 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800241 mbtk_lpm_init=(int(*)(mbtk_lpm_handler_t))dlsym(dlHandle_sleep, "mbtk_lpm_init");
242 ret = mbtk_lpm_init((mbtk_lpm_handler_t)wakeup_callback);
243 if(ret < 0)
244 {
245 LOGE("mbtk_lpm_init FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700246 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800247 }
248 return GSW_HAL_SUCCESS;
249}
250
251/**
252* @brief Release wake lock, enter sleep
253* @param [in]int32_t wakeup_in
254* @retval int
255*/
256int32_t gsw_pm_enter_sleep(const char *gsw_wakelock_name)
257{
258 int ret;
259 int i;
260 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700261 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800262 if (gsw_wakelock_name == NULL)
hong.liucd370792025-05-28 06:29:19 -0700263 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800264 for(i=0 ;i<LOCK_MAX_SIZE;i++)
265 {
266 if(lock_name[i].name != NULL && strcmp(lock_name[i].name, gsw_wakelock_name) == 0)
267 {
268 lock_fd = lock_name[i].fd;
269 break;
270 }
271 }
272 if (i >= LOCK_MAX_SIZE)
273 {
274 LOGE("mbtk_wakelock_lock not create.\n");
hong.liucd370792025-05-28 06:29:19 -0700275 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800276 }
277
278 mbtk_wakelock_unlock=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_unlock");
279 ret = mbtk_wakelock_unlock(lock_fd);
280 if(ret < 0)
281 {
282 LOGE("mbtk_wakelock_unlock FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700283 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800284 }
285
286 mbtk_wakelock_destroy=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_destroy");
287 ret = mbtk_wakelock_destroy(lock_fd);
288 if(ret < 0)
289 {
290 LOGE("mbtk_wakelock_destroy FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700291 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800292 }
293 if (lock_name[i].name != NULL)
294 {
295 free(lock_name[i].name);
296 lock_name[i].name = NULL;
297 lock_name[i].fd = -1;
298 }
b.liu68a94c92025-05-24 12:53:41 +0800299 return GSW_HAL_SUCCESS;
300}
301
302/**
303* @brief Creat wakeup lock
304* @param [in]int32_t wakeup_in
305* @retval int
306*/
307int32_t gsw_pm_exit_sleep(const char *gsw_wakelock_name)
308{
309 int ret;
310 int i;
311 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700312 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800313 if (gsw_wakelock_name == NULL)
hong.liucd370792025-05-28 06:29:19 -0700314 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800315 mbtk_wakelock_create=(int(*)(const char* name , size_t))dlsym(dlHandle_sleep, "mbtk_wakelock_create");
316 lock_fd = mbtk_wakelock_create(gsw_wakelock_name, strlen(gsw_wakelock_name));
317 if(lock_fd < 0)
318 {
319 LOGE("mbtk_wakelock_create FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700320 ret = GSW_HAL_NORMAL_FAIL;
321 goto end;
b.liu68a94c92025-05-24 12:53:41 +0800322 }
323 mbtk_wakelock_lock=(int(*)(int))dlsym(dlHandle_sleep, "mbtk_wakelock_lock");
324
325 ret = mbtk_wakelock_lock(lock_fd);
326 if(ret < 0)
327 {
328 LOGE("mbtk_wakelock_lock FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700329 ret = GSW_HAL_NORMAL_FAIL;
330 goto end;
b.liu68a94c92025-05-24 12:53:41 +0800331 }
332 for(i=0 ;i<LOCK_MAX_SIZE;i++)
333 {
334 if(lock_name[i].name == NULL)
335 break;
336 }
hong.liucd370792025-05-28 06:29:19 -0700337 if(i == LOCK_MAX_SIZE)
338 {
339 LOGE("mbtk_wakelock_lock not space FAIL.\n");
340 ret = GSW_HAL_NORMAL_FAIL;
341 goto end;
342 }
b.liu68a94c92025-05-24 12:53:41 +0800343 lock_name[i].name = malloc(strlen(gsw_wakelock_name)+1);
344 if (lock_name[i].name == NULL)
345 {
346 LOGE("mbtk_wakelock_lock remeber FAIL.\n");
hong.liucd370792025-05-28 06:29:19 -0700347 ret = GSW_HAL_NORMAL_FAIL;
348 goto end;
b.liu68a94c92025-05-24 12:53:41 +0800349 }
350 memcpy(lock_name[i].name, gsw_wakelock_name, strlen(gsw_wakelock_name)+1);
351 lock_name[i].fd = lock_fd;
hong.liucd370792025-05-28 06:29:19 -0700352 ret = GSW_HAL_SUCCESS;
353end:
hong.liucd370792025-05-28 06:29:19 -0700354 return ret;
b.liu68a94c92025-05-24 12:53:41 +0800355}
356
357/**
358* @brief Module log disk drop, used when restarting or hibernating
359* @param [in]void
360* @retval void
361*/
362void gsw_modem_log_sync(void)
363{
364 FILE *fp;
365 char command[256];
366 char buffer[256];
367 int pid = -1;
368 const char *process_name = "mbtk_logd";
369
370 snprintf(command, sizeof(command), "pgrep %s", process_name);
371 fp = popen(command, "r");
372 if (fp == NULL)
373 {
374 perror("error comman");
375 return;
376 }
377
378 if (fgets(buffer, sizeof(buffer), fp) != NULL)
379 {
380 pid = atoi(buffer);
381 }
382 pclose(fp);
383
384 if (pid != -1)
385 {
386 if (kill(pid, SIGTERM) == -1)
387 {
388 perror("send SIGTERM signal failed");
389 return;
390 }
391 }
392 return;
hong.liud2417072025-06-27 07:10:37 -0700393}
394/**
395 * @brief enable autosleep
396 * @return int : 0 is success , other failed
397 */
398int gswAutoSleepEnable(void)
399{
400 return gsw_autosleep_enable();
401}
402
403/**
404 * @brief disenable autosleep
405 * @return int : 0 is success , other failed
406 */
407int gswAutoSleepDisable(void)
408{
409 return gsw_autosleep_disenable();
410}
411
412/**
413 * @brief modem relase wakeuplock
414 * @return void
415 */
416void gswPMStartSleep(void)
417{
418 gsw_pm_enter_sleep(GSW_WAKELOCK_NAME);
419}
420
421/**
422 * @brief modem add wakeuplock
423 * @return int : 0 is success , other failed
424 */
425int gswPMStopSleep(void)
426{
427 return gsw_pm_exit_sleep(GSW_WAKELOCK_NAME);
428}
429
430int gswPmSDKInit(gsw_pm_wakeup_handler gswPmCallBack)
431{
432 return gsw_pm_sdk_init(gswPmCallBack);
433}