iwasm_main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef CONNECTION_UART
  6. #include <netdb.h>
  7. #include <netinet/in.h>
  8. #include <sys/socket.h>
  9. #include <arpa/inet.h>
  10. #else
  11. #include <termios.h>
  12. #endif
  13. #include <arpa/inet.h>
  14. #include <unistd.h>
  15. #include <getopt.h>
  16. #include <stdlib.h>
  17. #include <strings.h>
  18. #include <sys/types.h>
  19. #include <fcntl.h>
  20. #include <pthread.h>
  21. #include <signal.h>
  22. #include <unistd.h>
  23. #include <strings.h>
  24. #include "runtime_lib.h"
  25. #include "runtime_timer.h"
  26. #include "native_interface.h"
  27. #include "app_manager_export.h"
  28. #include "bh_platform.h"
  29. #include "runtime_sensor.h"
  30. #include "bi-inc/attr_container.h"
  31. #include "module_wasm_app.h"
  32. #include "wasm_export.h"
  33. #define MAX 2048
  34. #ifndef CONNECTION_UART
  35. #define SA struct sockaddr
  36. static char *host_address = "127.0.0.1";
  37. static int port = 8888;
  38. #else
  39. static char *uart_device = "/dev/ttyS2";
  40. static int baudrate = B115200;
  41. #endif
  42. extern bool
  43. init_sensor_framework();
  44. extern void
  45. exit_sensor_framework();
  46. extern void
  47. exit_connection_framework();
  48. extern int
  49. aee_host_msg_callback(void *msg, uint32_t msg_len);
  50. extern bool
  51. init_connection_framework();
  52. #ifndef CONNECTION_UART
  53. int listenfd = -1;
  54. int sockfd = -1;
  55. static pthread_mutex_t sock_lock = PTHREAD_MUTEX_INITIALIZER;
  56. #else
  57. int uartfd = -1;
  58. #endif
  59. #ifndef CONNECTION_UART
  60. static bool server_mode = false;
  61. // Function designed for chat between client and server.
  62. void *
  63. func(void *arg)
  64. {
  65. char buff[MAX];
  66. int n;
  67. struct sockaddr_in servaddr;
  68. while (1) {
  69. if (sockfd != -1)
  70. close(sockfd);
  71. // socket create and verification
  72. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  73. if (sockfd == -1) {
  74. printf("socket creation failed...\n");
  75. return NULL;
  76. }
  77. else
  78. printf("Socket successfully created..\n");
  79. bzero(&servaddr, sizeof(servaddr));
  80. // assign IP, PORT
  81. servaddr.sin_family = AF_INET;
  82. servaddr.sin_addr.s_addr = inet_addr(host_address);
  83. servaddr.sin_port = htons(port);
  84. // connect the client socket to server socket
  85. if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) != 0) {
  86. printf("connection with the server failed...\n");
  87. sleep(10);
  88. continue;
  89. }
  90. else {
  91. printf("connected to the server..\n");
  92. }
  93. // infinite loop for chat
  94. for (;;) {
  95. bzero(buff, MAX);
  96. // read the message from client and copy it in buffer
  97. n = read(sockfd, buff, sizeof(buff));
  98. // print buffer which contains the client contents
  99. // fprintf(stderr, "recieved %d bytes from host: %s", n, buff);
  100. // socket disconnected
  101. if (n <= 0)
  102. break;
  103. aee_host_msg_callback(buff, n);
  104. }
  105. }
  106. // After chatting close the socket
  107. close(sockfd);
  108. }
  109. static bool
  110. host_init()
  111. {
  112. return true;
  113. }
  114. int
  115. host_send(void *ctx, const char *buf, int size)
  116. {
  117. int ret;
  118. if (pthread_mutex_trylock(&sock_lock) == 0) {
  119. if (sockfd == -1) {
  120. pthread_mutex_unlock(&sock_lock);
  121. return 0;
  122. }
  123. ret = write(sockfd, buf, size);
  124. pthread_mutex_unlock(&sock_lock);
  125. return ret;
  126. }
  127. return -1;
  128. }
  129. void
  130. host_destroy()
  131. {
  132. if (server_mode)
  133. close(listenfd);
  134. pthread_mutex_lock(&sock_lock);
  135. close(sockfd);
  136. pthread_mutex_unlock(&sock_lock);
  137. }
  138. /* clang-format off */
  139. host_interface interface = {
  140. .init = host_init,
  141. .send = host_send,
  142. .destroy = host_destroy
  143. };
  144. /* clang-format on */
  145. /* Change it to 1 when fuzzing test */
  146. #define WASM_ENABLE_FUZZ_TEST 0
  147. void *
  148. func_server_mode(void *arg)
  149. {
  150. int clilent;
  151. struct sockaddr_in serv_addr, cli_addr;
  152. int n;
  153. char buff[MAX];
  154. struct sigaction sa;
  155. sa.sa_handler = SIG_IGN;
  156. sa.sa_flags = 0;
  157. sigemptyset(&sa.sa_mask);
  158. sigaction(SIGPIPE, &sa, 0);
  159. /* First call to socket() function */
  160. listenfd = socket(AF_INET, SOCK_STREAM, 0);
  161. if (listenfd < 0) {
  162. perror("ERROR opening socket");
  163. exit(1);
  164. }
  165. /* Initialize socket structure */
  166. bzero((char *)&serv_addr, sizeof(serv_addr));
  167. serv_addr.sin_family = AF_INET;
  168. serv_addr.sin_addr.s_addr = INADDR_ANY;
  169. serv_addr.sin_port = htons(port);
  170. /* Now bind the host address using bind() call.*/
  171. if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
  172. perror("ERROR on binding");
  173. exit(1);
  174. }
  175. listen(listenfd, 5);
  176. clilent = sizeof(cli_addr);
  177. while (1) {
  178. pthread_mutex_lock(&sock_lock);
  179. sockfd = accept(listenfd, (struct sockaddr *)&cli_addr, &clilent);
  180. pthread_mutex_unlock(&sock_lock);
  181. if (sockfd < 0) {
  182. perror("ERROR on accept");
  183. exit(1);
  184. }
  185. printf("connection established!\n");
  186. for (;;) {
  187. bzero(buff, MAX);
  188. // read the message from client and copy it in buffer
  189. n = read(sockfd, buff, sizeof(buff));
  190. // socket disconnected
  191. if (n <= 0) {
  192. pthread_mutex_lock(&sock_lock);
  193. close(sockfd);
  194. sockfd = -1;
  195. pthread_mutex_unlock(&sock_lock);
  196. sleep(1);
  197. break;
  198. }
  199. aee_host_msg_callback(buff, n);
  200. }
  201. #if WASM_ENABLE_FUZZ_TEST != 0
  202. /* Exit the process when host disconnect.
  203. This is helpful for reproducing failure case. */
  204. close(sockfd);
  205. exit(1);
  206. #endif
  207. }
  208. }
  209. #else
  210. static int
  211. parse_baudrate(int baud)
  212. {
  213. switch (baud) {
  214. case 9600:
  215. return B9600;
  216. case 19200:
  217. return B19200;
  218. case 38400:
  219. return B38400;
  220. case 57600:
  221. return B57600;
  222. case 115200:
  223. return B115200;
  224. case 230400:
  225. return B230400;
  226. case 460800:
  227. return B460800;
  228. case 500000:
  229. return B500000;
  230. case 576000:
  231. return B576000;
  232. case 921600:
  233. return B921600;
  234. case 1000000:
  235. return B1000000;
  236. case 1152000:
  237. return B1152000;
  238. case 1500000:
  239. return B1500000;
  240. case 2000000:
  241. return B2000000;
  242. case 2500000:
  243. return B2500000;
  244. case 3000000:
  245. return B3000000;
  246. case 3500000:
  247. return B3500000;
  248. case 4000000:
  249. return B4000000;
  250. default:
  251. return -1;
  252. }
  253. }
  254. static bool
  255. uart_init(const char *device, int baudrate, int *fd)
  256. {
  257. int uart_fd;
  258. struct termios uart_term;
  259. uart_fd = open(device, O_RDWR | O_NOCTTY);
  260. if (uart_fd <= 0)
  261. return false;
  262. memset(&uart_term, 0, sizeof(uart_term));
  263. uart_term.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
  264. uart_term.c_iflag = IGNPAR;
  265. uart_term.c_oflag = 0;
  266. /* set noncanonical mode */
  267. uart_term.c_lflag = 0;
  268. uart_term.c_cc[VTIME] = 30;
  269. uart_term.c_cc[VMIN] = 1;
  270. tcflush(uart_fd, TCIFLUSH);
  271. if (tcsetattr(uart_fd, TCSANOW, &uart_term) != 0) {
  272. close(uart_fd);
  273. return false;
  274. }
  275. *fd = uart_fd;
  276. return true;
  277. }
  278. static void *
  279. func_uart_mode(void *arg)
  280. {
  281. int n;
  282. char buff[MAX];
  283. if (!uart_init(uart_device, baudrate, &uartfd)) {
  284. printf("open uart fail! %s\n", uart_device);
  285. return NULL;
  286. }
  287. for (;;) {
  288. bzero(buff, MAX);
  289. n = read(uartfd, buff, sizeof(buff));
  290. if (n <= 0) {
  291. close(uartfd);
  292. uartfd = -1;
  293. break;
  294. }
  295. aee_host_msg_callback(buff, n);
  296. }
  297. return NULL;
  298. }
  299. static int
  300. uart_send(void *ctx, const char *buf, int size)
  301. {
  302. int ret;
  303. ret = write(uartfd, buf, size);
  304. return ret;
  305. }
  306. static void
  307. uart_destroy()
  308. {
  309. close(uartfd);
  310. }
  311. /* clang-format off */
  312. static host_interface interface = {
  313. .send = uart_send,
  314. .destroy = uart_destroy
  315. };
  316. /* clang-format on */
  317. #endif
  318. static attr_container_t *
  319. read_test_sensor(void *sensor)
  320. {
  321. attr_container_t *attr_obj = attr_container_create("read test sensor data");
  322. if (attr_obj) {
  323. bool ret =
  324. attr_container_set_string(&attr_obj, "name", "read test sensor");
  325. if (!ret) {
  326. attr_container_destroy(attr_obj);
  327. return NULL;
  328. }
  329. return attr_obj;
  330. }
  331. return NULL;
  332. }
  333. static bool
  334. config_test_sensor(void *s, void *config)
  335. {
  336. return false;
  337. }
  338. static char global_heap_buf[1024 * 1024] = { 0 };
  339. /* clang-format off */
  340. static void
  341. showUsage()
  342. {
  343. #ifndef CONNECTION_UART
  344. printf("Usage:\n");
  345. printf("\nWork as TCP server mode:\n");
  346. printf("\tsimple -s|--server_mode -p|--port <Port>\n");
  347. printf("where\n");
  348. printf("\t<Port> represents the port that would be listened on and the default is 8888\n");
  349. printf("\nWork as TCP client mode:\n");
  350. printf("\tsimple -a|--host_address <Host Address> -p|--port <Port>\n");
  351. printf("where\n");
  352. printf("\t<Host Address> represents the network address of host and the default is 127.0.0.1\n");
  353. printf("\t<Port> represents the listen port of host and the default is 8888\n");
  354. #else
  355. printf("Usage:\n");
  356. printf("\tsimple -u <Uart Device> -b <Baudrate>\n\n");
  357. printf("where\n");
  358. printf("\t<Uart Device> represents the UART device name and the default is /dev/ttyS2\n");
  359. printf("\t<Baudrate> represents the UART device baudrate and the default is 115200\n");
  360. #endif
  361. }
  362. /* clang-format on */
  363. static bool
  364. parse_args(int argc, char *argv[])
  365. {
  366. int c;
  367. while (1) {
  368. int optIndex = 0;
  369. static struct option longOpts[] = {
  370. #ifndef CONNECTION_UART
  371. { "server_mode", no_argument, NULL, 's' },
  372. { "host_address", required_argument, NULL, 'a' },
  373. { "port", required_argument, NULL, 'p' },
  374. #else
  375. { "uart", required_argument, NULL, 'u' },
  376. { "baudrate", required_argument, NULL, 'b' },
  377. #endif
  378. { "help", required_argument, NULL, 'h' },
  379. { 0, 0, 0, 0 }
  380. };
  381. c = getopt_long(argc, argv, "sa:p:u:b:w:h", longOpts, &optIndex);
  382. if (c == -1)
  383. break;
  384. switch (c) {
  385. #ifndef CONNECTION_UART
  386. case 's':
  387. server_mode = true;
  388. break;
  389. case 'a':
  390. host_address = optarg;
  391. printf("host address: %s\n", host_address);
  392. break;
  393. case 'p':
  394. port = atoi(optarg);
  395. printf("port: %d\n", port);
  396. break;
  397. #else
  398. case 'u':
  399. uart_device = optarg;
  400. printf("uart device: %s\n", uart_device);
  401. break;
  402. case 'b':
  403. baudrate = parse_baudrate(atoi(optarg));
  404. printf("uart baudrate: %s\n", optarg);
  405. break;
  406. #endif
  407. case 'h':
  408. showUsage();
  409. return false;
  410. default:
  411. showUsage();
  412. return false;
  413. }
  414. }
  415. return true;
  416. }
  417. // Driver function
  418. int
  419. iwasm_main(int argc, char *argv[])
  420. {
  421. RuntimeInitArgs init_args;
  422. korp_tid tid;
  423. if (!parse_args(argc, argv))
  424. return -1;
  425. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  426. #if USE_GLOBAL_HEAP_BUF != 0
  427. init_args.mem_alloc_type = Alloc_With_Pool;
  428. init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
  429. init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
  430. #else
  431. init_args.mem_alloc_type = Alloc_With_Allocator;
  432. init_args.mem_alloc_option.allocator.malloc_func = malloc;
  433. init_args.mem_alloc_option.allocator.realloc_func = realloc;
  434. init_args.mem_alloc_option.allocator.free_func = free;
  435. #endif
  436. /* initialize runtime environment */
  437. if (!wasm_runtime_full_init(&init_args)) {
  438. printf("Init runtime environment failed.\n");
  439. return -1;
  440. }
  441. /* connection framework */
  442. if (!init_connection_framework()) {
  443. goto fail1;
  444. }
  445. /* sensor framework */
  446. if (!init_sensor_framework()) {
  447. goto fail2;
  448. }
  449. /* timer manager */
  450. if (!init_wasm_timer()) {
  451. goto fail3;
  452. }
  453. /* add the sys sensor objects */
  454. add_sys_sensor("sensor_test1", "This is a sensor for test", 0, 1000,
  455. read_test_sensor, config_test_sensor);
  456. add_sys_sensor("sensor_test2", "This is a sensor for test", 0, 1000,
  457. read_test_sensor, config_test_sensor);
  458. start_sensor_framework();
  459. #ifndef CONNECTION_UART
  460. if (server_mode)
  461. os_thread_create(&tid, func_server_mode, NULL,
  462. BH_APPLET_PRESERVED_STACK_SIZE);
  463. else
  464. os_thread_create(&tid, func, NULL, BH_APPLET_PRESERVED_STACK_SIZE);
  465. #else
  466. os_thread_create(&tid, func_uart_mode, NULL,
  467. BH_APPLET_PRESERVED_STACK_SIZE);
  468. #endif
  469. app_manager_startup(&interface);
  470. exit_wasm_timer();
  471. fail3:
  472. exit_sensor_framework();
  473. fail2:
  474. exit_connection_framework();
  475. fail1:
  476. wasm_runtime_destroy();
  477. return -1;
  478. }