You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
8.2 KiB

2 years ago
  1. /******************************************************************************
  2. @file util.c
  3. @brief some utils for this QCM tool.
  4. DESCRIPTION
  5. Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
  6. INITIALIZATION AND SEQUENCING REQUIREMENTS
  7. None.
  8. ---------------------------------------------------------------------------
  9. Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
  10. Quectel Wireless Solution Proprietary and Confidential.
  11. ---------------------------------------------------------------------------
  12. ******************************************************************************/
  13. #include <sys/time.h>
  14. #if defined(__STDC__)
  15. #include <stdarg.h>
  16. #define __V(x) x
  17. #else
  18. #include <varargs.h>
  19. #define __V(x) (va_alist) va_dcl
  20. #define const
  21. #define volatile
  22. #endif
  23. #include <syslog.h>
  24. #include "QMIThread.h"
  25. static void setTimespecRelative(struct timespec *p_ts, long long msec)
  26. {
  27. struct timeval tv;
  28. gettimeofday(&tv, (struct timezone *) NULL);
  29. /* what's really funny about this is that I know
  30. pthread_cond_timedwait just turns around and makes this
  31. a relative time again */
  32. p_ts->tv_sec = tv.tv_sec + (msec / 1000);
  33. p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
  34. if (p_ts->tv_nsec >= 1000000000UL) {
  35. p_ts->tv_sec += 1;
  36. p_ts->tv_nsec -= 1000000000UL;
  37. }
  38. }
  39. int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, unsigned msecs) {
  40. if (msecs != 0) {
  41. unsigned i;
  42. unsigned t = msecs/4;
  43. int ret = 0;
  44. if (t == 0)
  45. t = 1;
  46. for (i = 0; i < msecs; i += t) {
  47. struct timespec ts;
  48. setTimespecRelative(&ts, t);
  49. ret = pthread_cond_timedwait(cond, mutex, &ts); //to advoid system time change
  50. if (ret != ETIMEDOUT) {
  51. if(ret) dbg_time("ret=%d, msecs=%u, t=%u", ret, msecs, t);
  52. break;
  53. }
  54. }
  55. return ret;
  56. } else {
  57. return pthread_cond_wait(cond, mutex);
  58. }
  59. }
  60. void cond_setclock_attr(pthread_cond_t *cond, clockid_t clock)
  61. {
  62. #if 0 //very old uclibc do not support pthread_condattr_setclock
  63. /* set relative time, for pthread_cond_timedwait */
  64. pthread_condattr_t attr;
  65. pthread_condattr_init (&attr);
  66. pthread_condattr_setclock(&attr, clock);
  67. pthread_cond_init(cond, &attr);
  68. pthread_condattr_destroy (&attr);
  69. #endif
  70. }
  71. const char * get_time(void) {
  72. static char time_buf[50];
  73. struct timeval tv;
  74. time_t time;
  75. suseconds_t millitm;
  76. struct tm *ti;
  77. gettimeofday (&tv, NULL);
  78. time= tv.tv_sec;
  79. millitm = (tv.tv_usec + 500) / 1000;
  80. if (millitm == 1000) {
  81. ++time;
  82. millitm = 0;
  83. }
  84. ti = localtime(&time);
  85. sprintf(time_buf, "%02d-%02d_%02d:%02d:%02d:%03d", ti->tm_mon+1, ti->tm_mday, ti->tm_hour, ti->tm_min, ti->tm_sec, (int)millitm);
  86. return time_buf;
  87. }
  88. unsigned long clock_msec(void)
  89. {
  90. struct timespec tm;
  91. clock_gettime( CLOCK_MONOTONIC, &tm);
  92. return (unsigned long)(tm.tv_sec*1000 + (tm.tv_nsec/1000000));
  93. }
  94. FILE *logfilefp = NULL;
  95. const int i = 1;
  96. #define is_bigendian() ( (*(char*)&i) == 0 )
  97. USHORT le16_to_cpu(USHORT v16) {
  98. USHORT tmp = v16;
  99. if (is_bigendian()) {
  100. unsigned char *s = (unsigned char *)(&v16);
  101. unsigned char *d = (unsigned char *)(&tmp);
  102. d[0] = s[1];
  103. d[1] = s[0];
  104. }
  105. return tmp;
  106. }
  107. UINT le32_to_cpu (UINT v32) {
  108. UINT tmp = v32;
  109. if (is_bigendian()) {
  110. unsigned char *s = (unsigned char *)(&v32);
  111. unsigned char *d = (unsigned char *)(&tmp);
  112. d[0] = s[3];
  113. d[1] = s[2];
  114. d[2] = s[1];
  115. d[3] = s[0];
  116. }
  117. return tmp;
  118. }
  119. UINT ql_swap32(UINT v32) {
  120. UINT tmp = v32;
  121. {
  122. unsigned char *s = (unsigned char *)(&v32);
  123. unsigned char *d = (unsigned char *)(&tmp);
  124. d[0] = s[3];
  125. d[1] = s[2];
  126. d[2] = s[1];
  127. d[3] = s[0];
  128. }
  129. return tmp;
  130. }
  131. USHORT cpu_to_le16(USHORT v16) {
  132. USHORT tmp = v16;
  133. if (is_bigendian()) {
  134. unsigned char *s = (unsigned char *)(&v16);
  135. unsigned char *d = (unsigned char *)(&tmp);
  136. d[0] = s[1];
  137. d[1] = s[0];
  138. }
  139. return tmp;
  140. }
  141. UINT cpu_to_le32 (UINT v32) {
  142. UINT tmp = v32;
  143. if (is_bigendian()) {
  144. unsigned char *s = (unsigned char *)(&v32);
  145. unsigned char *d = (unsigned char *)(&tmp);
  146. d[0] = s[3];
  147. d[1] = s[2];
  148. d[2] = s[1];
  149. d[3] = s[0];
  150. }
  151. return tmp;
  152. }
  153. void update_resolv_conf(int iptype, const char *ifname, const char *dns1, const char *dns2) {
  154. const char *dns_file = "/etc/resolv.conf";
  155. FILE *dns_fp;
  156. char dns_line[256];
  157. #define MAX_DNS 16
  158. char *dns_info[MAX_DNS];
  159. char dns_tag[64];
  160. int dns_match = 0;
  161. int i;
  162. snprintf(dns_tag, sizeof(dns_tag), "# IPV%d %s", iptype, ifname);
  163. for (i = 0; i < MAX_DNS; i++)
  164. dns_info[i] = NULL;
  165. dns_fp = fopen(dns_file, "r");
  166. if (dns_fp) {
  167. i = 0;
  168. dns_line[sizeof(dns_line)-1] = '\0';
  169. while((fgets(dns_line, sizeof(dns_line)-1, dns_fp)) != NULL) {
  170. if ((strlen(dns_line) > 1) && (dns_line[strlen(dns_line) - 1] == '\n'))
  171. dns_line[strlen(dns_line) - 1] = '\0';
  172. //dbg_time("%s", dns_line);
  173. if (strstr(dns_line, dns_tag)) {
  174. dns_match++;
  175. continue;
  176. }
  177. dns_info[i++] = strdup(dns_line);
  178. if (i == MAX_DNS)
  179. break;
  180. }
  181. fclose(dns_fp);
  182. }
  183. else if (errno != ENOENT) {
  184. dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
  185. return;
  186. }
  187. if (dns1 == NULL && dns_match == 0)
  188. return;
  189. dns_fp = fopen(dns_file, "w");
  190. if (dns_fp) {
  191. if (dns1)
  192. fprintf(dns_fp, "nameserver %s %s\n", dns1, dns_tag);
  193. if (dns2)
  194. fprintf(dns_fp, "nameserver %s %s\n", dns2, dns_tag);
  195. for (i = 0; i < MAX_DNS && dns_info[i]; i++)
  196. fprintf(dns_fp, "%s\n", dns_info[i]);
  197. fclose(dns_fp);
  198. }
  199. else {
  200. dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
  201. }
  202. for (i = 0; i < MAX_DNS && dns_info[i]; i++)
  203. free(dns_info[i]);
  204. }
  205. pid_t getpid_by_pdp(int pdp, const char* program_name)
  206. {
  207. glob_t gt;
  208. int ret;
  209. char filter[5] = {0};
  210. pid_t pid;
  211. sprintf(filter, "-n %d", pdp);
  212. ret = glob("/proc/*/cmdline", GLOB_NOSORT, NULL, &gt);
  213. if (ret != 0) {
  214. dbg_time("glob error, errno = %d(%s)", errno, strerror(errno));
  215. return -1;
  216. } else {
  217. int i = 0, fd = -1;
  218. size_t nreads;
  219. char cmdline[512] = {0};
  220. for (i = 0; i < gt.gl_pathc; i++) {
  221. fd = open(gt.gl_pathv[i], O_RDONLY);
  222. if (fd == -1) {
  223. dbg_time("open %s failed, errno = %d(%s)", gt.gl_pathv[i], errno, strerror(errno));
  224. globfree(&gt);
  225. return -1;
  226. }
  227. nreads = read(fd, cmdline, sizeof(cmdline));
  228. if (nreads > 0) {
  229. int pos = 0;
  230. while (pos < nreads-1) {
  231. if (cmdline[pos] == '\0')
  232. cmdline[pos] = ' '; // space
  233. pos++;
  234. }
  235. // printf("%s\n", cmdline);
  236. }
  237. if (strstr(cmdline, program_name) && strstr(cmdline, filter)) {
  238. char path[64] = {0};
  239. char pidstr[64] = {0};
  240. char *p;
  241. dbg_time("%s: %s", gt.gl_pathv[i], cmdline);
  242. strcpy(path, gt.gl_pathv[i]);
  243. p = strstr(gt.gl_pathv[i], "/cmdline");
  244. *p = '\0';
  245. while (*(--p) != '/') ;
  246. strcpy(pidstr, p+1);
  247. pid = atoi(pidstr);
  248. globfree(&gt);
  249. return pid;
  250. }
  251. }
  252. }
  253. globfree(&gt);
  254. return -1;
  255. }