HAL_OS_linux.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /*
  2. * Copyright (C) 2015-2018 Alibaba Group Holding Limited
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7. #include <memory.h>
  8. #include <pthread.h>
  9. #include <unistd.h>
  10. #include <sys/prctl.h>
  11. #include <sys/time.h>
  12. #include <semaphore.h>
  13. #include <errno.h>
  14. #include <assert.h>
  15. #include <net/if.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <sys/ioctl.h>
  20. #include <sys/reboot.h>
  21. #include <sys/time.h>
  22. #include <time.h>
  23. #include <signal.h>
  24. #include "infra_config.h"
  25. #include "infra_compat.h"
  26. #include "infra_defs.h"
  27. #include "wrappers_defs.h"
  28. #define PLATFORM_WAIT_INFINITE (~0)
  29. #ifdef DYNAMIC_REGISTER
  30. char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1ZETBPbycq";
  31. char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "L68wCVXYUaNg1Ey9";
  32. char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "example1";
  33. char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "";
  34. #else
  35. #ifdef DEVICE_MODEL_ENABLED
  36. char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1RIsMLz2BJ";
  37. char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "fSAF0hle6xL0oRWd";
  38. char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "example1";
  39. char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "RDXf67itLqZCwdMCRrw0N5FHbv5D7jrE";
  40. #else
  41. char _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1MZxOdcBnO";
  42. char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "h4I4dneEFp7EImTv";
  43. char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "test_01";
  44. char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "t9GmMf2jb3LgWfXBaZD2r3aJrfVWBv56";
  45. #endif
  46. #endif
  47. char _firmware_version[IOTX_FIRMWARE_VER_LEN] = "app-1.0.0-20180101.1000";
  48. void *HAL_Malloc(uint32_t size)
  49. {
  50. return malloc(size);
  51. }
  52. void *HAL_Realloc(void *ptr, uint32_t size)
  53. {
  54. return realloc(ptr, size);
  55. }
  56. void HAL_Free(void *ptr)
  57. {
  58. free(ptr);
  59. }
  60. uint64_t HAL_UptimeMs(void)
  61. {
  62. uint64_t time_ms;
  63. struct timespec ts;
  64. clock_gettime(CLOCK_MONOTONIC, &ts);
  65. time_ms = ((uint64_t)ts.tv_sec * (uint64_t)1000) + (ts.tv_nsec / 1000 / 1000);
  66. return time_ms;
  67. }
  68. void HAL_SleepMs(uint32_t ms)
  69. {
  70. usleep(1000 * ms);
  71. }
  72. void HAL_Srandom(uint32_t seed)
  73. {
  74. srandom(seed);
  75. }
  76. uint32_t HAL_Random(uint32_t region)
  77. {
  78. FILE *handle;
  79. ssize_t ret = 0;
  80. uint32_t output = 0;
  81. handle = fopen("/dev/urandom", "r");
  82. if (handle == NULL) {
  83. printf("open /dev/urandom failed\n");
  84. return 0;
  85. }
  86. ret = fread(&output, sizeof(uint32_t), 1, handle);
  87. if (ret != 1) {
  88. printf("fread error: %d\n", (int)ret);
  89. fclose(handle);
  90. return 0;
  91. }
  92. fclose(handle);
  93. return (region > 0) ? (output % region) : 0;
  94. }
  95. int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
  96. {
  97. va_list args;
  98. int rc;
  99. va_start(args, fmt);
  100. rc = vsnprintf(str, len, fmt, args);
  101. va_end(args);
  102. return rc;
  103. }
  104. int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap)
  105. {
  106. return vsnprintf(str, len, format, ap);
  107. }
  108. void HAL_Printf(const char *fmt, ...)
  109. {
  110. va_list args;
  111. va_start(args, fmt);
  112. vprintf(fmt, args);
  113. va_end(args);
  114. fflush(stdout);
  115. }
  116. int HAL_GetPartnerID(char *pid_str)
  117. {
  118. memset(pid_str, 0x0, IOTX_PARTNER_ID_LEN);
  119. strcpy(pid_str, "c-sdk-2.3.0-pid");
  120. return strlen(pid_str);
  121. }
  122. int HAL_GetModuleID(char *mid_str)
  123. {
  124. memset(mid_str, 0x0, IOTX_MODULE_ID_LEN);
  125. strcpy(mid_str, "c-sdk-2.3.0-mid");
  126. return strlen(mid_str);
  127. }
  128. int HAL_SetProductKey(char *product_key)
  129. {
  130. int len = strlen(product_key);
  131. if (len > IOTX_PRODUCT_KEY_LEN) {
  132. return -1;
  133. }
  134. memset(_product_key, 0x0, IOTX_PRODUCT_KEY_LEN + 1);
  135. strncpy(_product_key, product_key, len);
  136. return len;
  137. }
  138. int HAL_SetDeviceName(char *device_name)
  139. {
  140. int len = strlen(device_name);
  141. if (len > IOTX_DEVICE_NAME_LEN) {
  142. return -1;
  143. }
  144. memset(_device_name, 0x0, IOTX_DEVICE_NAME_LEN + 1);
  145. strncpy(_device_name, device_name, len);
  146. return len;
  147. }
  148. int HAL_SetProductSecret(char *product_secret)
  149. {
  150. int len = strlen(product_secret);
  151. if (len > IOTX_PRODUCT_SECRET_LEN) {
  152. return -1;
  153. }
  154. memset(_product_secret, 0x0, IOTX_PRODUCT_SECRET_LEN + 1);
  155. strncpy(_product_secret, product_secret, len);
  156. return len;
  157. }
  158. int HAL_SetDeviceSecret(char *device_secret)
  159. {
  160. int len = strlen(device_secret);
  161. if (len > IOTX_DEVICE_SECRET_LEN) {
  162. return -1;
  163. }
  164. memset(_device_secret, 0x0, IOTX_DEVICE_SECRET_LEN + 1);
  165. strncpy(_device_secret, device_secret, len);
  166. return len;
  167. }
  168. int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1])
  169. {
  170. int len = strlen(_product_key);
  171. memset(product_key, 0x0, IOTX_PRODUCT_KEY_LEN + 1);
  172. strncpy(product_key, _product_key, len);
  173. return len;
  174. }
  175. int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1])
  176. {
  177. int len = strlen(_product_secret);
  178. memset(product_secret, 0x0, IOTX_PRODUCT_SECRET_LEN + 1);
  179. strncpy(product_secret, _product_secret, len);
  180. return len;
  181. }
  182. int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1])
  183. {
  184. int len = strlen(_device_name);
  185. memset(device_name, 0x0, IOTX_DEVICE_NAME_LEN + 1);
  186. strncpy(device_name, _device_name, len);
  187. return strlen(device_name);
  188. }
  189. int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1])
  190. {
  191. int len = strlen(_device_secret);
  192. memset(device_secret, 0x0, IOTX_DEVICE_SECRET_LEN + 1);
  193. strncpy(device_secret, _device_secret, len);
  194. return len;
  195. }
  196. void HAL_Reboot(void)
  197. {
  198. if (system("reboot")) {
  199. perror("HAL_Reboot failed");
  200. }
  201. }
  202. #define ROUTER_INFO_PATH "/proc/net/route"
  203. #define ROUTER_RECORD_SIZE 256
  204. char *_get_default_routing_ifname(char *ifname, int ifname_size)
  205. {
  206. FILE *fp = NULL;
  207. char line[ROUTER_RECORD_SIZE] = {0};
  208. char iface[IFNAMSIZ] = {0};
  209. char *result = NULL;
  210. unsigned int destination, gateway, flags, mask;
  211. unsigned int refCnt, use, metric, mtu, window, irtt;
  212. char *buff = NULL;
  213. fp = fopen(ROUTER_INFO_PATH, "r");
  214. if (fp == NULL) {
  215. perror("fopen");
  216. return result;
  217. }
  218. buff = fgets(line, sizeof(line), fp);
  219. if (buff == NULL) {
  220. perror("fgets");
  221. goto out;
  222. }
  223. while (fgets(line, sizeof(line), fp)) {
  224. if (11 !=
  225. sscanf(line, "%s %08x %08x %x %u %u %u %08x %u %u %u",
  226. iface, &destination, &gateway, &flags, &refCnt, &use,
  227. &metric, &mask, &mtu, &window, &irtt)) {
  228. perror("sscanf");
  229. continue;
  230. }
  231. /*default route */
  232. if ((destination == 0) && (mask == 0)) {
  233. strncpy(ifname, iface, ifname_size - 1);
  234. result = ifname;
  235. break;
  236. }
  237. }
  238. out:
  239. if (fp) {
  240. fclose(fp);
  241. }
  242. return result;
  243. }
  244. uint32_t HAL_Wifi_Get_IP(char ip_str[NETWORK_ADDR_LEN], const char *ifname)
  245. {
  246. struct ifreq ifreq;
  247. int sock = -1;
  248. char ifname_buff[IFNAMSIZ] = {0};
  249. if ((NULL == ifname || strlen(ifname) == 0) &&
  250. NULL == (ifname = _get_default_routing_ifname(ifname_buff, sizeof(ifname_buff)))) {
  251. perror("get default routeing ifname");
  252. return -1;
  253. }
  254. if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  255. perror("socket");
  256. return -1;
  257. }
  258. ifreq.ifr_addr.sa_family = AF_INET;
  259. strncpy(ifreq.ifr_name, ifname, IFNAMSIZ - 1);
  260. if (ioctl(sock, SIOCGIFADDR, &ifreq) < 0) {
  261. close(sock);
  262. perror("ioctl");
  263. return -1;
  264. }
  265. close(sock);
  266. strncpy(ip_str,
  267. inet_ntoa(((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr),
  268. NETWORK_ADDR_LEN);
  269. return ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
  270. }
  271. int HAL_GetFirmwareVersion(char *version)
  272. {
  273. char *ver = "app-1.0.0-20180101.1000";
  274. int len = strlen(ver);
  275. memset(version, 0x0, IOTX_FIRMWARE_VER_LEN);
  276. strncpy(version, ver, IOTX_FIRMWARE_VER_LEN);
  277. version[len] = '\0';
  278. return strlen(version);
  279. }
  280. void *HAL_SemaphoreCreate(void)
  281. {
  282. sem_t *sem = (sem_t *)malloc(sizeof(sem_t));
  283. if (NULL == sem) {
  284. return NULL;
  285. }
  286. if (0 != sem_init(sem, 0, 0)) {
  287. free(sem);
  288. return NULL;
  289. }
  290. return sem;
  291. }
  292. void HAL_SemaphoreDestroy(void *sem)
  293. {
  294. sem_destroy((sem_t *)sem);
  295. free(sem);
  296. }
  297. void HAL_SemaphorePost(void *sem)
  298. {
  299. sem_post((sem_t *)sem);
  300. }
  301. int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
  302. {
  303. if (PLATFORM_WAIT_INFINITE == timeout_ms) {
  304. sem_wait(sem);
  305. return 0;
  306. } else {
  307. struct timespec ts;
  308. int s;
  309. /* Restart if interrupted by handler */
  310. do {
  311. if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
  312. return -1;
  313. }
  314. s = 0;
  315. ts.tv_nsec += (timeout_ms % 1000) * 1000000;
  316. if (ts.tv_nsec >= 1000000000) {
  317. ts.tv_nsec -= 1000000000;
  318. s = 1;
  319. }
  320. ts.tv_sec += timeout_ms / 1000 + s;
  321. } while (((s = sem_timedwait(sem, &ts)) != 0) && errno == EINTR);
  322. return (s == 0) ? 0 : -1;
  323. }
  324. }
  325. int HAL_ThreadCreate(
  326. void **thread_handle,
  327. void *(*work_routine)(void *),
  328. void *arg,
  329. hal_os_thread_param_t *hal_os_thread_param,
  330. int *stack_used)
  331. {
  332. int ret = -1;
  333. if (stack_used) {
  334. *stack_used = 0;
  335. }
  336. ret = pthread_create((pthread_t *)thread_handle, NULL, work_routine, arg);
  337. return ret;
  338. }
  339. void HAL_ThreadDetach(void *thread_handle)
  340. {
  341. pthread_detach((pthread_t)thread_handle);
  342. }
  343. void HAL_ThreadDelete(void *thread_handle)
  344. {
  345. if (NULL == thread_handle) {
  346. pthread_exit(0);
  347. } else {
  348. /*main thread delete child thread*/
  349. pthread_cancel((pthread_t)thread_handle);
  350. pthread_join((pthread_t)thread_handle, 0);
  351. }
  352. }
  353. static FILE *fp;
  354. #define otafilename "/tmp/alinkota.bin"
  355. void HAL_Firmware_Persistence_Start(void)
  356. {
  357. fp = fopen(otafilename, "w");
  358. return;
  359. }
  360. int HAL_Firmware_Persistence_Write(char *buffer, uint32_t length)
  361. {
  362. unsigned int written_len = 0;
  363. written_len = fwrite(buffer, 1, length, fp);
  364. if (written_len != length) {
  365. return -1;
  366. }
  367. return 0;
  368. }
  369. int HAL_Firmware_Persistence_Stop(void)
  370. {
  371. if (fp != NULL) {
  372. fclose(fp);
  373. }
  374. /* check file md5, and burning it to flash ... finally reboot system */
  375. return 0;
  376. }
  377. void *HAL_MutexCreate(void)
  378. {
  379. int err_num;
  380. pthread_mutex_t *mutex = (pthread_mutex_t *)HAL_Malloc(sizeof(pthread_mutex_t));
  381. if (NULL == mutex) {
  382. return NULL;
  383. }
  384. if (0 != (err_num = pthread_mutex_init(mutex, NULL))) {
  385. printf("create mutex failed\n");
  386. HAL_Free(mutex);
  387. return NULL;
  388. }
  389. return mutex;
  390. }
  391. void HAL_MutexDestroy(void *mutex)
  392. {
  393. int err_num;
  394. if (!mutex) {
  395. printf("mutex want to destroy is NULL!\n");
  396. return;
  397. }
  398. if (0 != (err_num = pthread_mutex_destroy((pthread_mutex_t *)mutex))) {
  399. printf("destroy mutex failed\n");
  400. }
  401. HAL_Free(mutex);
  402. }
  403. void HAL_MutexLock(void *mutex)
  404. {
  405. int err_num;
  406. if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)mutex))) {
  407. printf("lock mutex failed: - '%s' (%d)\n", strerror(err_num), err_num);
  408. }
  409. }
  410. void HAL_MutexUnlock(void *mutex)
  411. {
  412. int err_num;
  413. if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)mutex))) {
  414. printf("unlock mutex failed - '%s' (%d)\n", strerror(err_num), err_num);
  415. }
  416. }
  417. void *HAL_Timer_Create(const char *name, void (*func)(void *), void *user_data)
  418. {
  419. timer_t *timer = NULL;
  420. struct sigevent ent;
  421. /* check parameter */
  422. if (func == NULL) {
  423. return NULL;
  424. }
  425. timer = (timer_t *)malloc(sizeof(time_t));
  426. if (timer == NULL) {
  427. return NULL;
  428. }
  429. /* Init */
  430. memset(&ent, 0x00, sizeof(struct sigevent));
  431. /* create a timer */
  432. ent.sigev_notify = SIGEV_THREAD;
  433. ent.sigev_notify_function = (void (*)(union sigval))func;
  434. ent.sigev_value.sival_ptr = user_data;
  435. printf("HAL_Timer_Create\n");
  436. if (timer_create(CLOCK_MONOTONIC, &ent, timer) != 0) {
  437. free(timer);
  438. return NULL;
  439. }
  440. return (void *)timer;
  441. }
  442. int HAL_Timer_Start(void *timer, int ms)
  443. {
  444. struct itimerspec ts;
  445. /* check parameter */
  446. if (timer == NULL) {
  447. return -1;
  448. }
  449. /* it_interval=0: timer run only once */
  450. ts.it_interval.tv_sec = 0;
  451. ts.it_interval.tv_nsec = 0;
  452. /* it_value=0: stop timer */
  453. ts.it_value.tv_sec = ms / 1000;
  454. ts.it_value.tv_nsec = (ms % 1000) * 1000000;
  455. return timer_settime(*(timer_t *)timer, 0, &ts, NULL);
  456. }
  457. int HAL_Timer_Stop(void *timer)
  458. {
  459. struct itimerspec ts;
  460. /* check parameter */
  461. if (timer == NULL) {
  462. return -1;
  463. }
  464. /* it_interval=0: timer run only once */
  465. ts.it_interval.tv_sec = 0;
  466. ts.it_interval.tv_nsec = 0;
  467. /* it_value=0: stop timer */
  468. ts.it_value.tv_sec = 0;
  469. ts.it_value.tv_nsec = 0;
  470. return timer_settime(*(timer_t *)timer, 0, &ts, NULL);
  471. }
  472. int HAL_Timer_Delete(void *timer)
  473. {
  474. int ret = 0;
  475. /* check parameter */
  476. if (timer == NULL) {
  477. return -1;
  478. }
  479. ret = timer_delete(*(timer_t *)timer);
  480. free(timer);
  481. return ret;
  482. }
  483. int HAL_GetNetifInfo(char *nif_str)
  484. {
  485. const char *net_info = "WiFi|03ACDEFF0032";
  486. memset(nif_str, 0x0, IOTX_NETWORK_IF_LEN);
  487. /* if the device have only WIFI, then list as follow, note that the len MUST NOT exceed NIF_STRLEN_MAX */
  488. strncpy(nif_str, net_info, IOTX_NETWORK_IF_LEN);
  489. /* if the device have ETH, WIFI, GSM connections, then list all of them as follow, note that the len MUST NOT exceed NIF_STRLEN_MAX */
  490. /* const char *multi_net_info = "ETH|0123456789abcde|WiFi|03ACDEFF0032|Cellular|imei_0123456789abcde|iccid_0123456789abcdef01234|imsi_0123456789abcde|msisdn_86123456789ab"); */
  491. /* strncpy(nif_str, multi_net_info, strlen(multi_net_info)); */
  492. return strlen(nif_str);
  493. }