jerry_net.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. #include <rtdevice.h>
  2. #include <fcntl.h>
  3. #include "jerry_net.h"
  4. /* manage the pipe of socket */
  5. #ifdef RT_USING_LWIP
  6. #undef PIPE_BUFSZ
  7. #define PIPE_BUFSZ 512
  8. static rt_int32_t pipe_init(struct socket_info *thiz)
  9. {
  10. char dname[8];
  11. char dev_name[32];
  12. static int pipeno = 0;
  13. if (thiz == RT_NULL)
  14. {
  15. return -1;
  16. }
  17. snprintf(dname, sizeof(dname), "Socket%d", pipeno++);
  18. thiz->pipe = rt_pipe_create(dname, PIPE_BUFSZ);
  19. if (thiz->pipe == RT_NULL)
  20. {
  21. return -1;
  22. }
  23. snprintf(dev_name, sizeof(dev_name), "/dev/%s", dname);
  24. thiz->pipe_read_fd = open(dev_name, O_RDONLY, 0);
  25. if (thiz->pipe_read_fd < 0)
  26. {
  27. rt_kprintf("pipe_read_fd open failed\n");
  28. return -1;
  29. }
  30. thiz->pipe_write_fd = open(dev_name, O_WRONLY, 0);
  31. if (thiz->pipe_write_fd < 0)
  32. {
  33. close(thiz->pipe_read_fd);
  34. rt_kprintf("pipe_write_fd open failed\n");
  35. return -1;
  36. }
  37. return 0;
  38. }
  39. static rt_int32_t pipe_deinit(struct socket_info *thiz)
  40. {
  41. if (thiz == RT_NULL)
  42. {
  43. return -1;
  44. }
  45. close(thiz->pipe_read_fd);
  46. close(thiz->pipe_write_fd);
  47. rt_pipe_delete((const char *)thiz->pipe);
  48. return 0;
  49. }
  50. /* manage the socket_list */
  51. int get_socket_list_count(socket_list_t **l)
  52. {
  53. if (*l == RT_NULL)
  54. {
  55. return 0;
  56. }
  57. int count = 0;
  58. socket_list_t *start = *l;
  59. do
  60. {
  61. count++;
  62. *l = (*l)->next;
  63. }
  64. while ((*l) != start);
  65. return count;
  66. }
  67. void socket_list_init(socket_list_t **l, jerry_value_t socket)
  68. {
  69. (*l)->next = (*l)->prev = (*l);
  70. (*l)->js_socket = socket;
  71. }
  72. void socket_list_insert(socket_list_t **l, jerry_value_t socket)
  73. {
  74. if (*l == RT_NULL)
  75. {
  76. *l = (socket_list_t *)malloc(sizeof(socket_list_t));
  77. socket_list_init(l, socket);
  78. }
  79. else
  80. {
  81. socket_list_t *n = (socket_list_t *)malloc(sizeof(socket_list_t));
  82. socket_list_init(&n, socket);
  83. (*l)->next->prev = n;
  84. n->next = (*l)->next;
  85. (*l)->next = n;
  86. n->prev = (*l);
  87. }
  88. }
  89. void socket_list_remove(socket_list_t **n)
  90. {
  91. if ((*n)->next == (*n))
  92. {
  93. free((*n));
  94. (*n) = RT_NULL;
  95. }
  96. else
  97. {
  98. (*n)->next->prev = (*n)->prev;
  99. (*n)->prev->next = (*n)->next;
  100. (*n)->next = (*n)->prev = (*n);
  101. free(*n);
  102. (*n) = RT_NULL;
  103. }
  104. }
  105. bool socket_list_remove_by_socket(socket_list_t **l, jerry_value_t socket)
  106. {
  107. if ((*l) == RT_NULL || socket == RT_NULL)
  108. {
  109. return false;
  110. }
  111. socket_list_t *start = (*l);
  112. do
  113. {
  114. if ((*l)->js_socket == socket)
  115. {
  116. socket_list_t *toRemove = *l;
  117. (*l) = (*l)->next;
  118. if ((*l) != toRemove)
  119. {
  120. socket_list_remove(&toRemove);
  121. }
  122. else
  123. {
  124. socket_list_remove(l);
  125. }
  126. return true;
  127. }
  128. (*l) = (*l)->next;
  129. }
  130. while ((*l) != start);
  131. return false;
  132. }
  133. void socket_list_remove_all(socket_list_t **l)
  134. {
  135. if ((*l) == RT_NULL)
  136. {
  137. return;
  138. }
  139. socket_list_t *start = (*l);
  140. do
  141. {
  142. socket_list_t *toRemove = *l;
  143. (*l) = (*l)->next;
  144. if ((*l) != toRemove)
  145. {
  146. socket_list_remove(&toRemove);
  147. }
  148. else
  149. {
  150. socket_list_remove(l);
  151. }
  152. (*l) = (*l)->next;
  153. }
  154. while ((*l) != start);
  155. }
  156. /* the callbacks of Net Module */
  157. void get_net_info(void **info, jerry_value_t js_target)
  158. {
  159. jerry_value_t js_info = js_get_property(js_target, "info");
  160. jerry_get_object_native_pointer(js_info, info, NULL);
  161. jerry_release_value(js_info);
  162. }
  163. void net_event_callback_func(const void *args, uint32_t size)
  164. {
  165. net_event_info *cb_info = (net_event_info *)args;
  166. if (cb_info->js_return != RT_NULL)
  167. {
  168. js_emit_event(cb_info->js_target, cb_info->event_name, &cb_info->js_return, 1);
  169. }
  170. else
  171. {
  172. js_emit_event(cb_info->js_target, cb_info->event_name, NULL, 0);
  173. }
  174. if (cb_info->js_return != RT_NULL && cb_info->js_return != cb_info->js_target)//&& strcmp(cb_info->event_name, "connection") != 0 )
  175. {
  176. jerry_release_value(cb_info->js_return);
  177. }
  178. free(cb_info->event_name);
  179. free(cb_info);
  180. }
  181. void net_socket_callback_func(const void *args, uint32_t size)
  182. {
  183. net_funcInfo_t *cb_info = (net_funcInfo_t *)args;
  184. jerry_value_t ret = jerry_call_function(cb_info->js_run, cb_info->js_this, (jerry_value_t *)cb_info->args, cb_info->args_cnt);
  185. jerry_release_value(ret);
  186. free(cb_info);
  187. }
  188. void net_server_close(jerry_value_t js_server)
  189. {
  190. net_serverInfo_t *js_server_info = RT_NULL;
  191. get_net_info((void **)&js_server_info, js_server);
  192. /*emit 'close' event*/
  193. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  194. memset(event_info, 0, sizeof(net_event_info));
  195. event_info->event_name = strdup("close");
  196. event_info->js_target = js_server;
  197. event_info->js_return = RT_NULL;
  198. js_send_callback(js_server_info->event_callback, event_info, sizeof(net_event_info));
  199. free(event_info);
  200. /*do close callback of server*/
  201. net_closeInfo_t *close_info = (net_closeInfo_t *)malloc(sizeof(net_closeInfo_t));
  202. memset(close_info, 0, sizeof(net_closeInfo_t));
  203. close_info->js_server = js_server;
  204. close_info->js_socket = RT_NULL;
  205. js_send_callback(js_server_info->close_callback, close_info, sizeof(net_closeInfo_t));
  206. free(close_info);
  207. }
  208. void net_socket_callback_free(const void *args, uint32_t size)
  209. {
  210. net_closeInfo_t *close_info = (net_closeInfo_t *)args;
  211. struct socket_info *js_socket_info = RT_NULL;
  212. get_net_info((void **)&js_socket_info, close_info->js_socket);
  213. jerry_value_t js_server = js_socket_info->js_server;
  214. net_writeInfo_t write_info;
  215. memset(&write_info, 0, sizeof(net_writeInfo_t));
  216. if (js_socket_info->connect_thread != RT_NULL)
  217. {
  218. rt_thread_delete(js_socket_info->connect_thread);
  219. js_socket_info->connect_thread = RT_NULL;
  220. }
  221. if (js_socket_info->readData_thread != RT_NULL && !js_socket_info->isClosing)
  222. {
  223. /*Tell readThread to stop reading*/
  224. write_info.js_data = RT_NULL;
  225. write_info.js_callback = RT_NULL;
  226. write_info.stop_read = true;
  227. write_info.stop_sem = rt_sem_create("stop_read_sem", 1, RT_IPC_FLAG_FIFO);
  228. rt_sem_take(write_info.stop_sem, RT_WAITING_FOREVER);
  229. write(js_socket_info->pipe_write_fd, &write_info, sizeof(net_writeInfo_t));
  230. }
  231. if (write_info.stop_sem)
  232. {
  233. rt_sem_take(write_info.stop_sem, RT_WAITING_FOREVER);
  234. closesocket(js_socket_info->socket_id);
  235. rt_sem_release(write_info.stop_sem);
  236. rt_sem_delete(write_info.stop_sem);
  237. }
  238. else
  239. {
  240. closesocket(js_socket_info->socket_id);
  241. }
  242. rt_sem_release(js_socket_info->socket_sem);
  243. js_socket_info->socket_id = -1;
  244. js_remove_callback(js_socket_info->event_callback);
  245. js_remove_callback(js_socket_info->fun_callback);
  246. js_remove_callback(js_socket_info->close_callback);
  247. rt_sem_delete(js_socket_info->socket_sem);
  248. js_socket_info->socket_sem = RT_NULL;
  249. js_destroy_emitter(close_info->js_socket);
  250. if (close_info->js_server != RT_NULL)
  251. {
  252. /*get server info*/
  253. net_serverInfo_t *js_server_info = RT_NULL;
  254. get_net_info((void **)&js_server_info, js_server);
  255. rt_sem_take(js_server_info->server_sem, RT_WAITING_FOREVER);
  256. socket_list_remove_by_socket(&(js_server_info->socket_list), close_info->js_socket);
  257. rt_sem_release(js_server_info->server_sem);
  258. if (js_server_info->server_id == -1 && get_socket_list_count(&(js_server_info->socket_list)) == 0)
  259. {
  260. net_server_close(js_server);
  261. }
  262. }
  263. free(close_info);
  264. }
  265. void net_socket_free_callback(void *native_p)
  266. {
  267. struct socket_info *js_socket_info = (struct socket_info *)native_p;
  268. if (!js_socket_info)
  269. {
  270. return;
  271. }
  272. closesocket(js_socket_info->socket_id);
  273. js_socket_info->socket_id = -1;
  274. js_remove_callback(js_socket_info->event_callback);
  275. js_remove_callback(js_socket_info->fun_callback);
  276. js_remove_callback(js_socket_info->close_callback);
  277. pipe_deinit(js_socket_info);
  278. if (js_socket_info->socket_sem)
  279. {
  280. rt_sem_delete(js_socket_info->socket_sem);
  281. js_destroy_emitter(js_socket_info->this_value);
  282. if (js_socket_info->js_server != RT_NULL)
  283. {
  284. /*get server info*/
  285. net_serverInfo_t *js_server_info = RT_NULL;
  286. get_net_info((void **)&js_server_info, js_socket_info->js_server);
  287. rt_sem_take(js_server_info->server_sem, RT_WAITING_FOREVER);
  288. socket_list_remove_by_socket(&(js_server_info->socket_list), js_socket_info->this_value);
  289. rt_sem_release(js_server_info->server_sem);
  290. if (js_server_info->server_id == -1 && get_socket_list_count(&(js_server_info->socket_list)) == 0)
  291. {
  292. net_server_close(js_socket_info->js_server);
  293. }
  294. }
  295. }
  296. free(js_socket_info);
  297. }
  298. void net_server_callback_free(const void *args, uint32_t size)
  299. {
  300. net_closeInfo_t *close_info = (net_closeInfo_t *)args;
  301. net_serverInfo_t *js_server_info = RT_NULL;
  302. get_net_info((void **)&js_server_info, close_info->js_server);
  303. if (js_server_info->listen_thread != RT_NULL)
  304. {
  305. rt_thread_delete(js_server_info->listen_thread);
  306. js_server_info->listen_thread = RT_NULL;
  307. }
  308. if (js_server_info->server_id != -1)
  309. {
  310. closesocket(js_server_info->server_id);
  311. js_server_info->server_id = -1;
  312. }
  313. js_remove_callback(js_server_info->event_callback);
  314. js_remove_callback(js_server_info->close_callback);
  315. rt_sem_delete(js_server_info->server_sem);
  316. js_server_info->server_sem = RT_NULL;
  317. js_destroy_emitter(close_info->js_server);
  318. free(close_info);
  319. }
  320. void net_server_free_callback(void *native_p)
  321. {
  322. net_serverInfo_t *js_server_info = (net_serverInfo_t *)native_p;
  323. if (!js_server_info)
  324. {
  325. return;
  326. }
  327. if (js_server_info->listen_thread != RT_NULL)
  328. {
  329. rt_thread_delete(js_server_info->listen_thread);
  330. }
  331. if (js_server_info->server_id != -1)
  332. {
  333. closesocket(js_server_info->server_id);
  334. }
  335. js_remove_callback(js_server_info->event_callback);
  336. js_remove_callback(js_server_info->close_callback);
  337. if (js_server_info->server_sem != RT_NULL)
  338. {
  339. rt_sem_delete(js_server_info->server_sem);
  340. js_server_info->server_sem = RT_NULL;
  341. js_destroy_emitter(js_server_info->this_value);
  342. }
  343. free(js_server_info);
  344. }
  345. const static jerry_object_native_info_t net_server_info =
  346. {
  347. net_server_free_callback
  348. };
  349. const static jerry_object_native_info_t net_socket_info =
  350. {
  351. net_socket_free_callback
  352. };
  353. /* the method of socket */
  354. void net_socket_readData(jerry_value_t js_socket)
  355. {
  356. unsigned char buffer[BUFFER_SIZE];
  357. memset(&buffer, 0, BUFFER_SIZE);
  358. struct socket_info *js_socket_info = RT_NULL;
  359. get_net_info((void **)&js_socket_info, js_socket);
  360. int bytesRead = recv(js_socket_info->socket_id, buffer, BUFFER_SIZE + 1, 0);
  361. if (js_socket_info->isClosing)
  362. {
  363. return;
  364. }
  365. if (bytesRead <= 0)
  366. {
  367. js_socket_info->isClosing = true;
  368. /*emit 'end' event*/
  369. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  370. memset(event_info, 0, sizeof(net_event_info));
  371. event_info->event_name = strdup("end");
  372. event_info->js_target = js_socket;
  373. event_info->js_return = RT_NULL;
  374. js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
  375. free(event_info);
  376. /*do close callback*/
  377. net_closeInfo_t *close_info = (net_closeInfo_t *)malloc(sizeof(net_closeInfo_t));
  378. memset(close_info, 0, sizeof(net_closeInfo_t));
  379. close_info->js_server = js_socket_info->js_server;
  380. close_info->js_socket = js_socket;
  381. js_send_callback(js_socket_info->close_callback, close_info, sizeof(net_closeInfo_t));
  382. free(close_info);
  383. }
  384. else
  385. {
  386. /*set property: data*/
  387. js_buffer_t *js_buffer;
  388. jerry_value_t data_value = jerry_buffer_create(bytesRead, &js_buffer);
  389. if (js_buffer)
  390. {
  391. rt_memcpy(js_buffer->buffer, buffer, bytesRead);
  392. }
  393. /*emit 'data' event*/
  394. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  395. memset(event_info, 0, sizeof(net_event_info));
  396. event_info->event_name = strdup("data");
  397. event_info->js_target = js_socket;
  398. event_info->js_return = data_value;
  399. js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
  400. free(event_info);
  401. }
  402. }
  403. void net_socket_sendData(net_writeInfo_t *write_info, jerry_value_t js_socket)
  404. {
  405. int bytes;
  406. unsigned char buffer[BUFFER_SIZE];
  407. memset(&buffer, 0, BUFFER_SIZE);
  408. /*send the data*/
  409. int hasSent = 0;
  410. struct socket_info *js_socket_info = RT_NULL;
  411. get_net_info((void **)&js_socket_info, js_socket);
  412. js_buffer_t *js_buffer = jerry_buffer_find(write_info->js_data);
  413. if (js_buffer)
  414. {
  415. int i;
  416. for (i = 0, bytes = js_buffer->bufsize; bytes > 0; i++, bytes -= BUFFER_SIZE)
  417. {
  418. memset(&buffer, 0, BUFFER_SIZE);
  419. if (bytes > BUFFER_SIZE)
  420. {
  421. memcpy(buffer, js_buffer->buffer + i * BUFFER_SIZE, BUFFER_SIZE);
  422. hasSent += send(js_socket_info->socket_id, buffer, BUFFER_SIZE, 0);
  423. }
  424. else
  425. {
  426. memcpy(buffer, js_buffer->buffer + i * BUFFER_SIZE, bytes);
  427. hasSent += send(js_socket_info->socket_id, buffer, bytes, 0);
  428. }
  429. }
  430. }
  431. else if (jerry_value_is_string(write_info->js_data))
  432. {
  433. int i;
  434. char *js_str = js_value_to_string(write_info->js_data);
  435. for (i = 0, bytes = strlen(js_str); bytes > 0; i++, bytes -= BUFFER_SIZE)
  436. {
  437. memset(&buffer, 0, BUFFER_SIZE);
  438. if (bytes > BUFFER_SIZE)
  439. {
  440. memcpy(buffer, js_str + i * BUFFER_SIZE, BUFFER_SIZE);
  441. hasSent += send(js_socket_info->socket_id, buffer, BUFFER_SIZE, 0);
  442. }
  443. else
  444. {
  445. memcpy(buffer, js_str + i * BUFFER_SIZE, bytes);
  446. hasSent += send(js_socket_info->socket_id, buffer, bytes, 0);
  447. }
  448. }
  449. free(js_str);
  450. }
  451. /*do callback*/
  452. if (hasSent && write_info->js_callback != RT_NULL)
  453. {
  454. net_funcInfo_t *func_info = (net_funcInfo_t *)malloc(sizeof(net_funcInfo_t));
  455. memset(func_info, 0, sizeof(net_funcInfo_t));
  456. func_info->js_run = write_info->js_callback;
  457. func_info->js_this = js_socket;
  458. func_info->args = RT_NULL;
  459. func_info->args_cnt = 0;
  460. js_send_callback(js_socket_info->fun_callback, func_info, sizeof(net_funcInfo_t));
  461. free(func_info);
  462. }
  463. }
  464. void net_socket_readData_entry(void *p)
  465. {
  466. jerry_value_t js_socket = ((net_readInfo_t *)p)->js_socket;
  467. free(p);
  468. struct socket_info *js_socket_info = RT_NULL;
  469. get_net_info((void **)&js_socket_info, js_socket);
  470. int socket = js_socket_info->socket_id;
  471. int pipe_read_fd = js_socket_info->pipe_read_fd;
  472. int max_fd = 0;
  473. if (socket > pipe_read_fd)
  474. {
  475. max_fd = socket + 1;
  476. }
  477. else
  478. {
  479. max_fd = pipe_read_fd + 1;
  480. }
  481. fd_set readfds;
  482. while (1)
  483. {
  484. FD_ZERO(&readfds);
  485. FD_SET(socket, &readfds);
  486. FD_SET(pipe_read_fd, &readfds);
  487. if (js_socket_info->isClosing)
  488. {
  489. return;
  490. }
  491. if (js_socket_info->timeout.tv_sec == 0 && js_socket_info->timeout.tv_usec == 0)
  492. {
  493. select(max_fd, &readfds, 0, 0, 0);
  494. }
  495. else
  496. {
  497. if (select(max_fd, &readfds, 0, 0, &js_socket_info->timeout) == 0)
  498. {
  499. /*emit 'timeout' event*/
  500. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  501. memset(event_info, 0, sizeof(net_event_info));
  502. event_info->event_name = strdup("timeout");
  503. event_info->js_target = js_socket;
  504. event_info->js_return = RT_NULL;
  505. js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
  506. free(event_info);
  507. }
  508. }
  509. if (FD_ISSET(pipe_read_fd, &readfds))
  510. {
  511. //read from pipe
  512. static net_writeInfo_t write_info;
  513. rt_sem_take(js_socket_info->socket_sem, RT_WAITING_FOREVER);
  514. memset(&write_info, 0, sizeof(net_writeInfo_t));
  515. read(js_socket_info->pipe_read_fd, &write_info, sizeof(net_writeInfo_t));
  516. if (write_info.stop_read && write_info.stop_sem)
  517. {
  518. pipe_deinit(js_socket_info);
  519. rt_sem_release(write_info.stop_sem);
  520. break;
  521. }
  522. net_socket_sendData(&write_info, js_socket);
  523. rt_sem_release(js_socket_info->socket_sem);
  524. }
  525. if (FD_ISSET(socket, &readfds) && js_socket_info->readable == true)
  526. {
  527. net_socket_readData(js_socket);
  528. }
  529. }
  530. }
  531. /*start the read_thread of socket */
  532. void net_socket_startRead(jerry_value_t js_socket)
  533. {
  534. /*get socket_info*/
  535. struct socket_info *js_socket_info = RT_NULL;
  536. get_net_info((void **)&js_socket_info, js_socket);
  537. if (js_socket_info->socket_id < 0)
  538. {
  539. return;
  540. }
  541. /*create a thread to read data from server*/
  542. if (js_socket_info->allowHalfOpen == false)
  543. {
  544. net_readInfo_t *read_info = (net_readInfo_t *)malloc(sizeof(net_readInfo_t));
  545. memset(read_info, 0, sizeof(net_readInfo_t));
  546. read_info->js_socket = js_socket;
  547. js_socket_info->readData_thread = rt_thread_create("socket_Read", net_socket_readData_entry, read_info, 2048, 20, 5);
  548. rt_thread_startup(js_socket_info->readData_thread);
  549. }
  550. /*emit 'connect' event*/
  551. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  552. memset(event_info, 0, sizeof(net_event_info));
  553. event_info->event_name = strdup("connect");
  554. event_info->js_target = js_socket;
  555. event_info->js_return = RT_NULL;
  556. js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
  557. free(event_info);
  558. }
  559. /*update property : remoteAddress , remoteFamily, remotePort, localAddress and localPort*/
  560. int net_socket_updateProperty(jerry_value_t js_socket)
  561. {
  562. /*get socket_info*/
  563. struct socket_info *js_socket_info = RT_NULL;
  564. get_net_info((void **)&js_socket_info, js_socket);
  565. if (js_socket_info->socket_id < 0)
  566. {
  567. return 0;
  568. }
  569. struct sockaddr_in remote_name; //get the infomation of remote address
  570. socklen_t sin_size = sizeof(struct sockaddr_in);
  571. getpeername(js_socket_info->socket_id, (struct sockaddr *)&remote_name, &sin_size);
  572. jerry_value_t js_remoteFamily;
  573. if (remote_name.sin_family == AF_INET)
  574. {
  575. js_remoteFamily = jerry_create_string((const jerry_char_t *)"IPv4");
  576. }
  577. else
  578. {
  579. js_remoteFamily = jerry_create_string((const jerry_char_t *)"IPv6");
  580. }
  581. js_set_property(js_socket, "remoteFamily", js_remoteFamily);
  582. jerry_release_value(js_remoteFamily);
  583. jerry_value_t js_remotePort = jerry_create_number(ntohs(remote_name.sin_port));
  584. js_set_property(js_socket, "remotePort", js_remotePort);
  585. jerry_release_value(js_remotePort);
  586. jerry_value_t js_remoteAddress = jerry_create_string((jerry_char_t *)inet_ntoa(remote_name.sin_addr));
  587. js_set_property(js_socket, "remoteAddress", js_remoteAddress);
  588. jerry_release_value(js_remoteAddress);
  589. /*update property : localAddress and localPort*/
  590. struct sockaddr_in local_name; //get the infomation of local address
  591. getsockname(js_socket_info->socket_id, (struct sockaddr *)&local_name, &sin_size);
  592. jerry_value_t js_localAddress = jerry_create_string((jerry_char_t *)inet_ntoa(local_name.sin_addr));
  593. js_set_property(js_socket, "localAddress", js_localAddress);
  594. jerry_release_value(js_localAddress);
  595. jerry_value_t js_localPort = jerry_create_number(ntohs(local_name.sin_port));
  596. js_set_property(js_socket, "localPort", js_localPort);
  597. jerry_release_value(js_localPort);
  598. return 1;
  599. }
  600. void net_socket_connect_entry(void *connect_info)
  601. {
  602. net_connectInfo_t *info = (net_connectInfo_t *)connect_info;
  603. int ret = connect(info->socket_id, (struct sockaddr *)info->socket_fd, sizeof(struct sockaddr));
  604. if (ret >= 0)
  605. {
  606. if (net_socket_updateProperty(info->js_socket))
  607. {
  608. net_socket_startRead(info->js_socket);
  609. }
  610. }
  611. rt_free(info->socket_fd);
  612. rt_free(info);
  613. /*get socket_info*/
  614. struct socket_info *js_socket_info = RT_NULL;
  615. get_net_info((void **)&js_socket_info, info->js_socket);
  616. if (js_socket_info)
  617. {
  618. js_socket_info->connect_thread = RT_NULL;
  619. }
  620. }
  621. DECLARE_HANDLER(socket_connect)
  622. {
  623. if (args_cnt == 0 || args_cnt > 3)
  624. {
  625. return jerry_create_undefined();
  626. }
  627. /*relative informations*/
  628. int port = -1;
  629. char *host = RT_NULL;
  630. int family = 4;
  631. jerry_value_t js_connect_cb = RT_NULL;
  632. /*get socket_info*/
  633. struct socket_info *js_socket_info = RT_NULL;
  634. get_net_info((void **)&js_socket_info, this_value);
  635. if (jerry_value_is_object(args[0]))
  636. {
  637. jerry_value_t js_port = js_get_property(args[0], "port");
  638. if (jerry_value_is_number(js_port))
  639. {
  640. port = jerry_get_number_value(js_port);
  641. }
  642. jerry_release_value(js_port);
  643. jerry_value_t js_host = js_get_property(args[0], "host");
  644. if (jerry_value_is_string(js_host))
  645. {
  646. host = js_value_to_string(js_host);
  647. }
  648. jerry_release_value(js_host);
  649. jerry_value_t js_family = js_get_property(args[0], "family");
  650. if (jerry_value_is_number(js_family))
  651. {
  652. family = jerry_get_number_value(js_family);
  653. }
  654. jerry_release_value(js_family);
  655. }
  656. if (jerry_value_is_number(args[0]))
  657. {
  658. port = jerry_get_number_value(args[0]);
  659. }
  660. if (args_cnt > 1 && jerry_value_is_string(args[1]))
  661. {
  662. host = js_value_to_string(args[1]);
  663. }
  664. if (args_cnt > 1 && jerry_value_is_function(args[1]))
  665. {
  666. js_connect_cb = args[1];
  667. }
  668. else if (args_cnt > 2 && jerry_value_is_function(args[2]))
  669. {
  670. js_connect_cb = args[2];
  671. }
  672. /*add connect event listener*/
  673. if (js_connect_cb != RT_NULL)
  674. {
  675. js_add_event_listener(this_value, "connect", js_connect_cb);
  676. }
  677. /*create socket*/
  678. if (js_socket_info->socket_id == -1)
  679. {
  680. if (family == 4)
  681. {
  682. js_socket_info->socket_id = socket(PF_INET, SOCK_STREAM, 0);
  683. }
  684. #if LWIP_IPV6
  685. else if (family == 6)
  686. {
  687. js_socket_info->server_socket = socket(PF_INET6, SOCK_STREAM, 0);
  688. }
  689. #endif
  690. else
  691. {
  692. rt_kprintf("the paramater named 'family' is wrong\n");
  693. return jerry_create_undefined();
  694. }
  695. }
  696. else
  697. {
  698. if (net_socket_updateProperty(this_value))
  699. {
  700. net_socket_startRead(this_value);
  701. }
  702. }
  703. /*read to connect*/
  704. if (port > 0)
  705. {
  706. struct sockaddr_in *socket_fd = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
  707. memset(socket_fd, 0, sizeof(struct sockaddr_in));
  708. socket_fd->sin_family = AF_INET;
  709. #if LWIP_IPV6
  710. if (family == 6)
  711. socket_fd->sin_family = AF_INET6;
  712. #endif
  713. struct hostent *socket_host;
  714. socket_host = gethostbyname(host);
  715. socket_fd->sin_addr = *((struct in_addr *)socket_host->h_addr);
  716. socket_fd->sin_port = htons(port);
  717. rt_memset(&(socket_fd->sin_zero), 0, sizeof(socket_fd->sin_zero));
  718. net_connectInfo_t *connect_info = (net_connectInfo_t *)malloc(sizeof(net_connectInfo_t));
  719. memset(connect_info, 0, sizeof(net_connectInfo_t));
  720. connect_info->socket_fd = socket_fd;
  721. connect_info->socket_id = js_socket_info->socket_id;
  722. connect_info->js_socket = this_value;
  723. js_socket_info->connect_thread = rt_thread_create("socket_connect", net_socket_connect_entry, connect_info, 1024, 20, 5);
  724. rt_thread_startup(js_socket_info->connect_thread);
  725. }
  726. else
  727. {
  728. rt_kprintf("the paramater named 'port' is wrong\n");
  729. return jerry_create_undefined();
  730. }
  731. free(host);
  732. return jerry_acquire_value(this_value);
  733. }
  734. DECLARE_HANDLER(socket_destroy)
  735. {
  736. /*get socket_info*/
  737. struct socket_info *js_socket_info = RT_NULL;
  738. get_net_info((void **)&js_socket_info, this_value);
  739. if (js_socket_info->socket_id == -1)
  740. {
  741. return jerry_create_undefined();
  742. }
  743. /*emit 'end' event*/
  744. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  745. memset(event_info, 0, sizeof(net_event_info));
  746. event_info->event_name = strdup("end");
  747. event_info->js_target = this_value;
  748. event_info->js_return = RT_NULL;
  749. js_send_callback(js_socket_info->event_callback, event_info, sizeof(net_event_info));
  750. free(event_info);
  751. /*do close callback*/
  752. net_closeInfo_t *close_info = (net_closeInfo_t *)malloc(sizeof(net_closeInfo_t));
  753. memset(close_info, 0, sizeof(net_closeInfo_t));
  754. close_info->js_server = js_socket_info->js_server;
  755. close_info->js_socket = this_value;
  756. js_send_callback(js_socket_info->close_callback, close_info, sizeof(net_closeInfo_t));
  757. free(close_info);
  758. return jerry_create_undefined();
  759. }
  760. DECLARE_HANDLER(socket_end)
  761. {
  762. if (args_cnt == 0 || args_cnt > 2)
  763. {
  764. return jerry_create_undefined();
  765. }
  766. /*get socket_info*/
  767. struct socket_info *js_socket_info = RT_NULL;
  768. get_net_info((void **)&js_socket_info, this_value);
  769. if (js_socket_info->socket_id == -1)
  770. {
  771. return jerry_create_undefined();
  772. }
  773. /*get wirte andy destroy function*/
  774. jerry_value_t js_socket_write = js_get_property(this_value, "write");
  775. jerry_value_t js_socket_destroy = js_get_property(this_value, "destroy");
  776. if (jerry_value_is_function(js_socket_write) && jerry_value_is_function(js_socket_destroy))
  777. {
  778. jerry_call_function(js_socket_write, this_value, args, args_cnt);
  779. jerry_call_function(js_socket_destroy, this_value, NULL, 0);
  780. }
  781. jerry_release_value(js_socket_write);
  782. jerry_release_value(js_socket_destroy);
  783. return this_value;
  784. }
  785. DECLARE_HANDLER(socket_pause)
  786. {
  787. /*get socket_info*/
  788. struct socket_info *js_socket_info = RT_NULL;
  789. get_net_info((void **)&js_socket_info, this_value);
  790. if (js_socket_info->socket_id == -1)
  791. {
  792. return jerry_create_undefined();
  793. }
  794. if (js_socket_info->readData_thread != 0)
  795. {
  796. rt_thread_suspend(js_socket_info->readData_thread);
  797. }
  798. return jerry_create_undefined();
  799. }
  800. DECLARE_HANDLER(socket_resume)
  801. {
  802. /*get socket_info*/
  803. struct socket_info *js_socket_info = RT_NULL;
  804. get_net_info((void **)&js_socket_info, this_value);
  805. if (js_socket_info->socket_id == -1)
  806. {
  807. return jerry_create_undefined();
  808. }
  809. if (js_socket_info->readData_thread != 0)
  810. {
  811. rt_thread_resume(js_socket_info->readData_thread);
  812. }
  813. return jerry_create_undefined();
  814. }
  815. DECLARE_HANDLER(socket_setTimeout)
  816. {
  817. if (args_cnt == 0 || args_cnt > 2)
  818. {
  819. return jerry_create_undefined();
  820. }
  821. /*get socket_info*/
  822. struct socket_info *js_socket_info = RT_NULL;
  823. get_net_info((void **)&js_socket_info, this_value);
  824. if (js_socket_info->socket_id == -1)
  825. {
  826. return jerry_create_undefined();
  827. }
  828. int utime = 0 ;
  829. if (jerry_value_is_number(args[0]))
  830. {
  831. utime = jerry_get_number_value(args[0]);
  832. }
  833. if (utime < 0)
  834. {
  835. return jerry_create_undefined();
  836. }
  837. js_socket_info->timeout.tv_usec = utime * 1000;
  838. if (args_cnt == 2 && jerry_value_is_function(args[1]))
  839. {
  840. js_add_event_listener(this_value, "timeout", args[1]);
  841. }
  842. return jerry_create_undefined();
  843. }
  844. DECLARE_HANDLER(socket_write)
  845. {
  846. if (args_cnt == 0 || args_cnt > 2)
  847. {
  848. return jerry_create_undefined();
  849. }
  850. /*get socket_info*/
  851. struct socket_info *js_socket_info = RT_NULL;
  852. get_net_info((void **)&js_socket_info, this_value);
  853. if (js_socket_info->socket_id == -1)
  854. {
  855. return jerry_create_undefined();
  856. }
  857. if (js_socket_info->writable == true)
  858. {
  859. net_writeInfo_t write_info;
  860. memset(&write_info, 0, sizeof(net_writeInfo_t));
  861. write_info.js_data = args[0];
  862. if (args_cnt == 2 && jerry_value_is_function(args[1]))
  863. {
  864. write_info.js_callback = args[1];
  865. }
  866. else
  867. {
  868. write_info.js_callback = RT_NULL;
  869. }
  870. write_info.stop_read = false;
  871. write_info.stop_sem = RT_NULL;
  872. write(js_socket_info->pipe_write_fd, &write_info, sizeof(net_writeInfo_t));
  873. }
  874. return jerry_create_undefined();
  875. }
  876. jerry_value_t create_js_socket()
  877. {
  878. jerry_value_t js_socket = jerry_create_object();
  879. struct socket_info *js_socket_info = (struct socket_info *)malloc(sizeof(struct socket_info));
  880. memset(js_socket_info, 0, sizeof(struct socket_info));
  881. int ret = pipe_init(js_socket_info);
  882. if (ret == -1)
  883. {
  884. rt_kprintf("net module create pipe failed\n");
  885. free(js_socket_info);
  886. jerry_release_value(js_socket);
  887. return jerry_create_undefined();
  888. }
  889. js_socket_info->js_server = RT_NULL;
  890. js_socket_info->this_value = js_socket;
  891. /*set method*/
  892. REGISTER_METHOD_NAME(js_socket, "connect", socket_connect);
  893. REGISTER_METHOD_NAME(js_socket, "destroy", socket_destroy);
  894. REGISTER_METHOD_NAME(js_socket, "end", socket_end);
  895. REGISTER_METHOD_NAME(js_socket, "pause", socket_pause);
  896. REGISTER_METHOD_NAME(js_socket, "resume", socket_resume);
  897. REGISTER_METHOD_NAME(js_socket, "setTimeout", socket_setTimeout);
  898. REGISTER_METHOD_NAME(js_socket, "write", socket_write);
  899. /* set property*/
  900. if (js_socket_info)
  901. {
  902. jerry_value_t js_info = jerry_create_object();
  903. js_set_property(js_socket, "info", js_info);
  904. jerry_set_object_native_pointer(js_info, js_socket_info, &net_socket_info); // set native_pointer
  905. jerry_release_value(js_info);
  906. // initialize the socket_info
  907. js_socket_info->socket_id = -1;
  908. js_socket_info->allowHalfOpen = false;
  909. js_socket_info->writable = true;
  910. js_socket_info->readable = true;
  911. js_socket_info->isClosing = false;
  912. js_socket_info->event_callback = js_add_callback(net_event_callback_func);
  913. js_socket_info->fun_callback = js_add_callback(net_socket_callback_func);
  914. js_socket_info->close_callback = js_add_callback(net_socket_callback_free);
  915. js_socket_info->socket_sem = rt_sem_create("socket_sem", 1, RT_IPC_FLAG_FIFO);
  916. js_socket_info->timeout.tv_sec = 0;
  917. js_socket_info->timeout.tv_usec = 0;
  918. jerry_value_t js_localAddress = jerry_create_undefined();
  919. js_set_property(js_socket, "localAddress", js_localAddress);
  920. jerry_release_value(js_localAddress);
  921. jerry_value_t js_localPort = jerry_create_undefined();
  922. js_set_property(js_socket, "localPort", js_localPort);
  923. jerry_release_value(js_localPort);
  924. jerry_value_t js_remoteAddress = jerry_create_undefined();
  925. js_set_property(js_socket, "remoteAddress", js_remoteAddress);
  926. jerry_release_value(js_remoteAddress);
  927. jerry_value_t js_remoteFamily = jerry_create_undefined();
  928. js_set_property(js_socket, "remoteFamily", js_remoteFamily);
  929. jerry_release_value(js_remoteFamily);
  930. jerry_value_t js_remotePort = jerry_create_undefined();
  931. js_set_property(js_socket, "remotePort", js_remotePort);
  932. jerry_release_value(js_remotePort);
  933. }
  934. return js_socket;
  935. }
  936. DECLARE_HANDLER(net_Socket)
  937. {
  938. if (args_cnt > 1)
  939. return jerry_create_undefined();
  940. jerry_value_t js_socket = create_js_socket();
  941. if (jerry_value_is_undefined(js_socket))
  942. return jerry_create_undefined();
  943. /*get socket_info*/
  944. js_make_emitter(js_socket, jerry_create_undefined());
  945. struct socket_info *js_socket_info = RT_NULL;
  946. get_net_info((void **)&js_socket_info, js_socket);
  947. //get options value and set the paramaters
  948. if (args_cnt == 1 && jerry_value_is_object(args[0]))
  949. {
  950. jerry_value_t js_fd = js_get_property(args[0], "fd");
  951. if (jerry_value_is_number(js_fd))
  952. {
  953. js_socket_info->socket_id = jerry_get_number_value(js_fd);
  954. }
  955. jerry_release_value(js_fd);
  956. jerry_value_t js_allowHalfOpen = js_get_property(args[0], "allowHalfOpen");
  957. if (jerry_value_is_boolean(js_allowHalfOpen))
  958. {
  959. js_socket_info->allowHalfOpen = jerry_get_boolean_value(js_allowHalfOpen);
  960. }
  961. jerry_release_value(js_allowHalfOpen);
  962. jerry_value_t js_writable = js_get_property(args[0], "writable");
  963. if (jerry_value_is_boolean(js_writable))
  964. {
  965. js_socket_info->writable = jerry_get_boolean_value(js_writable);
  966. }
  967. jerry_release_value(js_writable);
  968. jerry_value_t js_readable = js_get_property(args[0], "readable");
  969. if (jerry_value_is_boolean(js_readable))
  970. {
  971. js_socket_info->writable = jerry_get_boolean_value(js_readable);
  972. }
  973. jerry_release_value(js_readable);
  974. }
  975. return (js_socket);
  976. }
  977. /* the method of server */
  978. static void net_server_listen_entry(void *listen_info)
  979. {
  980. jerry_value_t js_server = ((net_listenInfo_t *)listen_info)->js_server;
  981. int backlog = ((net_listenInfo_t *)listen_info)->backlog;
  982. free(listen_info);
  983. /*get socket_info*/
  984. net_serverInfo_t *js_server_info = RT_NULL;
  985. get_net_info((void **)&js_server_info, js_server);
  986. int server_id = js_server_info->server_id;
  987. rt_sem_t server_sem = js_server_info->server_sem;
  988. /*start listening and accepting*/
  989. if (socket > 0)
  990. {
  991. struct sockaddr_in client_addr;
  992. socklen_t addrlen = 1;
  993. listen(server_id, backlog); // start listen
  994. rt_kprintf("SERVER_MAX_CONNECTIONS : %d \n", backlog);
  995. while (1)
  996. {
  997. memset(&client_addr, 0, sizeof(struct sockaddr_in));
  998. int client_fd = accept(server_id, (struct sockaddr *)&client_addr, &addrlen); //accept ths client socket
  999. /*judge whether the new client are allow to connect*/
  1000. rt_sem_take(server_sem, RT_WAITING_FOREVER);
  1001. int client_count = get_socket_list_count(&js_server_info->socket_list);
  1002. rt_sem_release(server_sem);
  1003. if (client_fd && client_count < backlog)
  1004. {
  1005. /*set the option of new_socket func*/
  1006. jerry_value_t js_new_socket_option = jerry_create_object();
  1007. jerry_value_t js_socket_allowHalfOpen = jerry_create_boolean(js_server_info->allowHalfOpen);
  1008. js_set_property(js_new_socket_option, "allowHalfOpen", js_socket_allowHalfOpen);
  1009. jerry_release_value(js_socket_allowHalfOpen);
  1010. jerry_value_t js_socket_fd = jerry_create_number(client_fd);
  1011. js_set_property(js_new_socket_option, "fd", js_socket_fd);
  1012. jerry_release_value(js_socket_fd);
  1013. /*do new_socket func*/
  1014. jerry_value_t js_new_socket = jerry_create_external_function(net_Socket_handler);
  1015. jerry_value_t js_socket = jerry_call_function(js_new_socket, jerry_create_undefined(), &js_new_socket_option, 1);
  1016. jerry_release_value(js_new_socket_option);
  1017. jerry_release_value(js_new_socket);
  1018. if (jerry_value_is_undefined(js_socket))
  1019. {
  1020. jerry_release_value(js_socket);
  1021. closesocket(client_fd);
  1022. }
  1023. else
  1024. {
  1025. /*set the socket's server*/
  1026. struct socket_info *js_socket_info = RT_NULL;
  1027. get_net_info((void **)&js_socket_info, js_socket);
  1028. js_socket_info->js_server = js_server;
  1029. /*add js_socket to socket_list*/
  1030. rt_sem_take(server_sem, RT_WAITING_FOREVER);
  1031. socket_list_insert(&js_server_info->socket_list, js_socket);
  1032. client_count = get_socket_list_count(&js_server_info->socket_list);
  1033. if (net_socket_updateProperty(js_socket))
  1034. {
  1035. net_socket_startRead(js_socket);
  1036. }
  1037. rt_sem_release(server_sem);
  1038. /*emit 'connention' event*/
  1039. /*send the new socket to connection listener of js_server*/
  1040. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  1041. memset(event_info, 0, sizeof(net_event_info));
  1042. event_info->event_name = strdup("connection");
  1043. event_info->js_target = js_server;
  1044. event_info->js_return = js_socket;
  1045. js_send_callback(js_server_info->event_callback, event_info, sizeof(net_event_info));
  1046. free(event_info);
  1047. }
  1048. }
  1049. else
  1050. {
  1051. closesocket(client_fd);
  1052. }
  1053. }
  1054. }
  1055. }
  1056. DECLARE_HANDLER(server_close)
  1057. {
  1058. /*get server info*/
  1059. net_serverInfo_t *js_server_info = RT_NULL;
  1060. get_net_info((void **)&js_server_info, this_value);
  1061. if (!js_server_info)
  1062. {
  1063. js_destroy_emitter(this_value);
  1064. return jerry_create_undefined();
  1065. }
  1066. if (args_cnt > 1)
  1067. {
  1068. return jerry_create_undefined();
  1069. }
  1070. if (args_cnt > 0 && jerry_value_is_function(args[0]))
  1071. {
  1072. js_add_event_listener(this_value, "close", args[0]);
  1073. }
  1074. /*stop listening*/
  1075. if (js_server_info->listen_thread != RT_NULL)
  1076. {
  1077. rt_thread_delete(js_server_info->listen_thread);
  1078. js_server_info->listen_thread = RT_NULL;
  1079. }
  1080. if (js_server_info->server_id != -1)
  1081. {
  1082. closesocket(js_server_info->server_id);
  1083. js_server_info->server_id = -1;
  1084. }
  1085. if (get_socket_list_count(&(js_server_info->socket_list)) == 0)
  1086. {
  1087. net_server_close(this_value);
  1088. }
  1089. return jerry_create_undefined();
  1090. }
  1091. DECLARE_HANDLER(server_listen)
  1092. {
  1093. if (args_cnt == 0 || args_cnt > 4)
  1094. return jerry_create_undefined();
  1095. /*get server info*/
  1096. net_serverInfo_t *js_server_info = RT_NULL;
  1097. get_net_info((void **)&js_server_info, this_value);
  1098. /*end listen_thread*/
  1099. if (js_server_info->listen_thread)
  1100. {
  1101. rt_thread_delete(js_server_info->listen_thread);
  1102. js_server_info->listen_thread = RT_NULL;
  1103. }
  1104. /*the value of option*/
  1105. int port = -1;
  1106. char *host = RT_NULL;
  1107. int backlog = SERVER_MAX_CONNECTIONS;
  1108. int family = 4;
  1109. jerry_value_t js_listen_cb = RT_NULL;
  1110. #if LWIP_IPV6
  1111. family = 6;
  1112. #endif
  1113. if (jerry_value_is_object(args[0]))
  1114. {
  1115. jerry_value_t js_port = js_get_property(args[0], "port");
  1116. if (jerry_value_is_number(js_port))
  1117. {
  1118. port = jerry_get_number_value(js_port);
  1119. }
  1120. jerry_release_value(js_port);
  1121. jerry_value_t js_host = js_get_property(args[0], "host");
  1122. if (jerry_value_is_string(js_host))
  1123. {
  1124. host = js_value_to_string(js_host);
  1125. }
  1126. jerry_release_value(js_host);
  1127. jerry_value_t js_backlog = js_get_property(args[0], "backlog");
  1128. if (jerry_value_is_number(js_backlog))
  1129. {
  1130. int count = jerry_get_number_value(js_backlog);
  1131. if (count < backlog)
  1132. {
  1133. backlog = count;
  1134. }
  1135. }
  1136. jerry_release_value(js_backlog);
  1137. if (args_cnt == 2 && jerry_value_is_function(args[1]))
  1138. {
  1139. js_listen_cb = args[1];
  1140. }
  1141. }
  1142. else if (jerry_value_is_number(args[0]))
  1143. {
  1144. switch (args_cnt)
  1145. {
  1146. case 4 :
  1147. if (jerry_value_is_string(args[3]))
  1148. {
  1149. host = js_value_to_string(args[3]);
  1150. }
  1151. else if (jerry_value_is_number(args[3]))
  1152. {
  1153. backlog = jerry_get_number_value(args[3]);
  1154. }
  1155. else if (jerry_value_is_function(args[3]))
  1156. {
  1157. js_listen_cb = args[3];
  1158. }
  1159. case 3 :
  1160. if (jerry_value_is_string(args[2]))
  1161. {
  1162. host = js_value_to_string(args[2]);
  1163. }
  1164. else if (jerry_value_is_number(args[2]))
  1165. {
  1166. backlog = jerry_get_number_value(args[2]);
  1167. }
  1168. else if (jerry_value_is_function(args[2]))
  1169. {
  1170. js_listen_cb = args[2];
  1171. }
  1172. case 2 :
  1173. if (jerry_value_is_string(args[1]))
  1174. {
  1175. host = js_value_to_string(args[1]);
  1176. }
  1177. else if (jerry_value_is_number(args[1]))
  1178. {
  1179. backlog = jerry_get_number_value(args[1]);
  1180. }
  1181. else if (jerry_value_is_function(args[1]))
  1182. {
  1183. js_listen_cb = args[1];
  1184. }
  1185. case 1 :
  1186. port = jerry_get_number_value(args[0]);
  1187. default:
  1188. break;
  1189. }
  1190. }
  1191. if (port < 0)
  1192. {
  1193. goto __exit;
  1194. }
  1195. /*create socket and bind*/
  1196. if (family == 4)
  1197. {
  1198. js_server_info->server_id = socket(AF_INET, SOCK_STREAM, 0);
  1199. }
  1200. else if (family == 6)
  1201. {
  1202. js_server_info->server_id = socket(AF_INET6, SOCK_STREAM, 0);
  1203. }
  1204. if (js_server_info->server_id > 0)
  1205. {
  1206. struct sockaddr_in server_addr;
  1207. if (family == 4)
  1208. {
  1209. server_addr.sin_family = AF_INET;
  1210. }
  1211. else if (family == 6)
  1212. {
  1213. server_addr.sin_family = AF_INET6;
  1214. }
  1215. if (host)
  1216. {
  1217. server_addr.sin_addr.s_addr = inet_addr(host);
  1218. }
  1219. else
  1220. {
  1221. server_addr.sin_addr.s_addr = INADDR_ANY;
  1222. }
  1223. server_addr.sin_port = htons(port);
  1224. const int on = 1;
  1225. setsockopt(js_server_info->server_id, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  1226. int bind_ret = bind(js_server_info->server_id, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
  1227. if (bind_ret == 0)
  1228. {
  1229. net_listenInfo_t *listen_info = (net_listenInfo_t *)malloc(sizeof(net_listenInfo_t));
  1230. memset(listen_info, 0, sizeof(net_listenInfo_t));
  1231. listen_info->js_server = this_value;
  1232. listen_info->backlog = backlog;
  1233. net_serverInfo_t *js_server_info = RT_NULL;
  1234. get_net_info((void **)&js_server_info, this_value);
  1235. js_server_info->listen_thread = rt_thread_create("net_listen", net_server_listen_entry, listen_info, 2048, 20, 5);
  1236. rt_err_t thread_ret = rt_thread_startup(js_server_info->listen_thread);
  1237. if (thread_ret == RT_EOK)
  1238. {
  1239. /*emit 'listening' event*/
  1240. net_event_info *event_info = (net_event_info *)malloc(sizeof(net_event_info));
  1241. memset(event_info, 0, sizeof(net_event_info));
  1242. event_info->event_name = strdup("listening");
  1243. event_info->js_target = this_value;
  1244. event_info->js_return = RT_NULL;
  1245. js_send_callback(js_server_info->event_callback, event_info, sizeof(net_event_info));
  1246. free(event_info);
  1247. }
  1248. }
  1249. }
  1250. __exit:
  1251. free(host);
  1252. jerry_release_value(js_listen_cb);
  1253. return jerry_create_undefined();
  1254. }
  1255. /* the method of net */
  1256. DECLARE_HANDLER(net_connect)
  1257. {
  1258. if (args_cnt == 0 || args_cnt > 3)
  1259. {
  1260. return jerry_create_undefined();
  1261. }
  1262. /* create socket */
  1263. jerry_value_t js_new_socket = js_get_property(this_value, "Socket");
  1264. jerry_value_t js_socket = jerry_call_function(js_new_socket, this_value, NULL, 0);
  1265. jerry_release_value(js_new_socket);
  1266. if (jerry_value_is_undefined(js_socket))
  1267. {
  1268. jerry_release_value(js_socket);
  1269. return jerry_create_undefined();
  1270. }
  1271. /* do socket.connect */
  1272. jerry_value_t js_socket_connect = js_get_property(js_socket, "connect");
  1273. jerry_value_t js_ret = jerry_call_function(js_socket_connect, js_socket, args, args_cnt);
  1274. jerry_release_value(js_socket_connect);
  1275. if (jerry_value_is_undefined(js_ret))
  1276. {
  1277. jerry_release_value(js_ret);
  1278. return jerry_create_undefined();
  1279. }
  1280. jerry_release_value(js_ret);
  1281. return js_socket;
  1282. }
  1283. DECLARE_HANDLER(net_createServer)
  1284. {
  1285. jerry_value_t js_server = jerry_create_object();
  1286. /*add property of server*/
  1287. net_serverInfo_t *js_server_info = (net_serverInfo_t *)malloc(sizeof(net_serverInfo_t));
  1288. memset(js_server_info, 0, sizeof(net_serverInfo_t));
  1289. jerry_value_t js_info = jerry_create_object();
  1290. js_set_property(js_server, "info", js_info);
  1291. jerry_set_object_native_pointer(js_info, js_server_info, &net_server_info); // set native_pointer
  1292. jerry_release_value(js_info);
  1293. js_make_emitter(js_server, jerry_create_undefined());
  1294. js_server_info->allowHalfOpen = false;
  1295. js_server_info->server_id = -1;
  1296. js_server_info->event_callback = js_add_callback(net_event_callback_func);
  1297. js_server_info->close_callback = js_add_callback(net_server_callback_free);
  1298. js_server_info->socket_list = RT_NULL;
  1299. js_server_info->server_sem = rt_sem_create("server_sem", 1, RT_IPC_FLAG_FIFO);
  1300. js_server_info->this_value = js_server;
  1301. if (args_cnt > 0 && jerry_value_is_object(args[0]))
  1302. {
  1303. jerry_value_t js_allowHalfOpen = js_get_property(args[0], "allowHalfOpen");
  1304. if (jerry_value_is_boolean(js_allowHalfOpen))
  1305. {
  1306. js_server_info->allowHalfOpen = jerry_value_to_boolean(js_allowHalfOpen);
  1307. }
  1308. jerry_release_value(js_allowHalfOpen);
  1309. }
  1310. if (args_cnt > 0 && jerry_value_is_function(args[0]))
  1311. {
  1312. js_add_event_listener(js_server, "connection", args[0]);
  1313. }
  1314. if (args_cnt > 1 && jerry_value_is_function(args[1]))
  1315. {
  1316. js_add_event_listener(js_server, "connection", args[1]);
  1317. }
  1318. /*register method to server*/
  1319. REGISTER_METHOD_NAME(js_server, "listen", server_listen);
  1320. REGISTER_METHOD_NAME(js_server, "close", server_close);
  1321. return (js_server);
  1322. }
  1323. jerry_value_t jerry_net_init()
  1324. {
  1325. jerry_value_t js_net = jerry_create_object();
  1326. REGISTER_METHOD_NAME(js_net, "Socket", net_Socket);
  1327. REGISTER_METHOD_NAME(js_net, "connect", net_connect);
  1328. REGISTER_METHOD_NAME(js_net, "createConnection", net_connect);
  1329. REGISTER_METHOD_NAME(js_net, "createServer", net_createServer);
  1330. return (js_net);
  1331. }
  1332. JS_MODULE(net, jerry_net_init)
  1333. #endif