lws-plat-esp8266.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. #include "private-libwebsockets.h"
  2. #include "ip_addr.h"
  3. /* forced into this because new espconn accepted callbacks carry no context ptr */
  4. static struct lws_context *hacky_context;
  5. static unsigned int time_high, ot;
  6. /*
  7. * included from libwebsockets.c for esp8266 builds
  8. */
  9. unsigned long long time_in_microseconds(void)
  10. {
  11. unsigned int t = system_get_time();
  12. if (ot > t)
  13. time_high++;
  14. ot = t;
  15. return (((long long)time_high) << 32) | t;
  16. }
  17. int gettimeofday(struct timeval *tv, void *tz)
  18. {
  19. unsigned long long t = time_in_microseconds();
  20. tv->tv_sec = t / 1000000;
  21. tv->tv_usec = t % 1000000;
  22. return 0;
  23. }
  24. time_t time(time_t *tloc)
  25. {
  26. unsigned long long t = time_in_microseconds();
  27. if (tloc)
  28. *tloc = t / 1000000;
  29. return 0;
  30. }
  31. LWS_VISIBLE int
  32. lws_get_random(struct lws_context *context, void *buf, int len)
  33. {
  34. // return read(context->fd_random, (char *)buf, len);
  35. return 0;
  36. }
  37. LWS_VISIBLE int
  38. lws_send_pipe_choked(struct lws *wsi)
  39. {
  40. return wsi->pending_send_completion;
  41. }
  42. LWS_VISIBLE struct lws *
  43. wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
  44. {
  45. int n;
  46. for (n = 0; n < context->max_fds; n++)
  47. if (context->connpool[n] == fd)
  48. return (struct lws *)context->connpool[n + context->max_fds];
  49. return NULL;
  50. }
  51. LWS_VISIBLE int
  52. lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
  53. {
  54. //lwsl_notice("%s: wsi %p: len %d\n", __func__, wsi, len);
  55. wsi->pending_send_completion++;
  56. espconn_send(wsi->desc.sockfd, buf, len);
  57. return len;
  58. }
  59. void abort(void)
  60. {
  61. while(1) ;
  62. }
  63. void exit(int n)
  64. {
  65. abort();
  66. }
  67. void _sint(void *s)
  68. {
  69. }
  70. LWS_VISIBLE int
  71. insert_wsi(struct lws_context *context, struct lws *wsi)
  72. {
  73. (void)context;
  74. (void)wsi;
  75. return 0;
  76. }
  77. LWS_VISIBLE int
  78. delete_from_fd(struct lws_context *context, lws_sockfd_type fd)
  79. {
  80. (void)context;
  81. (void)fd;
  82. return 1;
  83. }
  84. struct tm *localtime(const time_t *timep)
  85. {
  86. return NULL;
  87. }
  88. struct tm *localtime_r(const time_t *timep, struct tm *t)
  89. {
  90. return NULL;
  91. }
  92. int atoi(const char *s)
  93. {
  94. int n = 0;
  95. while (*s && (*s >= '0' && *s <= '9'))
  96. n = (n * 10) + ((*s++) - '0');
  97. return n;
  98. }
  99. #undef isxdigit
  100. int isxdigit(int c)
  101. {
  102. if (c >= 'A' && c <= 'F')
  103. return 1;
  104. if (c >= 'a' && c <= 'f')
  105. return 1;
  106. if (c >= '0' && c <= '9')
  107. return 1;
  108. return 0;
  109. }
  110. int strcasecmp(const char *s1, const char *s2)
  111. {
  112. char a, b;
  113. while (*s1 && *s2) {
  114. a = *s1++;
  115. b = *s2++;
  116. if (a == b)
  117. continue;
  118. if (a >= 'a' && a <= 'z')
  119. a -= 'a' - 'A';
  120. if (b >= 'a' && b <= 'z')
  121. b -= 'a' - 'A';
  122. if (a != b)
  123. return 1;
  124. }
  125. return 0;
  126. }
  127. LWS_VISIBLE int
  128. lws_poll_listen_fd(struct lws_pollfd *fd)
  129. {
  130. return 0;
  131. }
  132. LWS_VISIBLE void
  133. lws_cancel_service_pt(struct lws *wsi)
  134. {
  135. }
  136. LWS_VISIBLE void
  137. lws_cancel_service(struct lws_context *context)
  138. {
  139. }
  140. LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
  141. {
  142. extern void output_redirect(const char *str);
  143. output_redirect(line);
  144. }
  145. LWS_VISIBLE LWS_EXTERN int
  146. _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
  147. {
  148. return 0;
  149. }
  150. LWS_VISIBLE int
  151. lws_plat_check_connection_error(struct lws *wsi)
  152. {
  153. return 0;
  154. }
  155. LWS_VISIBLE int
  156. lws_plat_service(struct lws_context *context, int timeout_ms)
  157. {
  158. // return _lws_plat_service_tsi(context, timeout_ms, 0);
  159. return 0;
  160. }
  161. static int
  162. esp8266_find_free_conn(struct lws_context *context)
  163. {
  164. int n;
  165. for (n = 0; n < context->max_fds; n++)
  166. if (!context->connpool[n]) {
  167. lwsl_info(" using connpool %d\n", n);
  168. return n;
  169. }
  170. lwsl_err("%s: no free conns\n", __func__);
  171. return -1;
  172. }
  173. lws_sockfd_type
  174. esp8266_create_tcp_listen_socket(struct lws_vhost *vh)
  175. {
  176. int n = esp8266_find_free_conn(vh->context);
  177. struct espconn *conn;
  178. if (n < 0)
  179. return NULL;
  180. conn = lws_zalloc(sizeof *conn);
  181. if (!conn)
  182. return NULL;
  183. vh->context->connpool[n] = conn;
  184. conn->type = ESPCONN_TCP;
  185. conn->state = ESPCONN_NONE;
  186. conn->proto.tcp = &vh->tcp;
  187. return conn;
  188. }
  189. const char *
  190. lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen)
  191. {
  192. unsigned char *p = wsi->desc.sockfd->proto.tcp->remote_ip;
  193. lws_snprintf(name, namelen, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
  194. return name;
  195. }
  196. LWS_VISIBLE int
  197. lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)
  198. {
  199. //lwsl_notice("%s\n", __func__);
  200. if (!wsi->context->rxd)
  201. return 0;
  202. if (len < wsi->context->rxd_len)
  203. lwsl_err("trunc read (%d vs %d)\n", len, wsi->context->rxd_len);
  204. else
  205. len = wsi->context->rxd_len;
  206. ets_memcpy(buf, wsi->context->rxd, len);
  207. wsi->context->rxd = NULL;
  208. return len;
  209. }
  210. static void
  211. cb_1Hz(void *arg)
  212. {
  213. struct lws_context *context = arg;
  214. struct lws_context_per_thread *pt = &context->pt[0];
  215. struct lws *wsi;
  216. struct lws_pollfd *pollfd;
  217. int n;
  218. /* Service any ah that has pending rx */
  219. for (n = 0; n < context->max_http_header_pool; n++)
  220. if (pt->ah_pool[n].rxpos != pt->ah_pool[n].rxlen) {
  221. wsi = pt->ah_pool[n].wsi;
  222. pollfd = &pt->fds[wsi->position_in_fds_table];
  223. if (pollfd->events & LWS_POLLIN) {
  224. pollfd->revents |= LWS_POLLIN;
  225. lws_service_fd(context, pollfd);
  226. }
  227. }
  228. /* handle timeouts */
  229. lws_service_fd(context, NULL);
  230. }
  231. static void
  232. esp8266_cb_rx(void *arg, char *data, unsigned short len)
  233. {
  234. struct espconn *conn = arg;
  235. struct lws *wsi = conn->reverse;
  236. struct lws_context_per_thread *pt = &wsi->context->pt[0];
  237. struct lws_pollfd pollfd;
  238. int n = 0;
  239. /*
  240. * if we're doing HTTP headers, and we have no ah, check if there is
  241. * a free ah, if not, have to buffer it
  242. */
  243. if (!wsi->hdr_parsing_completed && !wsi->u.hdr.ah) {
  244. for (n = 0; n < wsi->context->max_http_header_pool; n++)
  245. if (!pt->ah_pool[n].in_use)
  246. break;
  247. n = n == wsi->context->max_http_header_pool;
  248. }
  249. if (!(pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN) || n) {
  250. wsi->premature_rx = realloc(wsi->premature_rx,
  251. wsi->prem_rx_size + len);
  252. if (!wsi->premature_rx)
  253. return;
  254. os_memcpy((char *)wsi->premature_rx + wsi->prem_rx_size, data, len);
  255. wsi->prem_rx_size += len;
  256. // lwsl_notice("%s: wsi %p: len %d BUFFERING\n", __func__, wsi, len);
  257. if (n) /* we know it will fail, but we will get on the wait list */
  258. n = lws_header_table_attach(wsi, 0);
  259. (void)n;
  260. return;
  261. }
  262. //lwsl_err("%s: wsi %p. len %d\n", __func__, wsi, len);
  263. pollfd.fd = arg;
  264. pollfd.events = LWS_POLLIN;
  265. pollfd.revents = LWS_POLLIN;
  266. wsi->context->rxd = data;
  267. wsi->context->rxd_len = len;
  268. lws_service_fd(lws_get_context(wsi), &pollfd);
  269. }
  270. static void
  271. esp8266_cb_sent(void *arg)
  272. {
  273. struct espconn *conn = arg;
  274. struct lws *wsi = conn->reverse;
  275. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  276. // lwsl_err("%s: wsi %p (psc %d) wsi->position_in_fds_table=%d\n", __func__, wsi, wsi->pending_send_completion, wsi->position_in_fds_table);
  277. wsi->pending_send_completion--;
  278. if (wsi->close_is_pending_send_completion &&
  279. !wsi->pending_send_completion &&
  280. !lws_partial_buffered(wsi)) {
  281. lwsl_notice("doing delayed close\n");
  282. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  283. }
  284. if (pt->fds[wsi->position_in_fds_table].events & LWS_POLLOUT) {
  285. struct lws_pollfd pollfd;
  286. pollfd.fd = arg;
  287. pollfd.events = LWS_POLLOUT;
  288. pollfd.revents = LWS_POLLOUT;
  289. // lwsl_notice("informing POLLOUT\n");
  290. lws_service_fd(lws_get_context(wsi), &pollfd);
  291. }
  292. }
  293. static void
  294. esp8266_cb_disconnected(void *arg)
  295. {
  296. struct espconn *conn = arg;
  297. struct lws *wsi = conn->reverse;
  298. int n;
  299. lwsl_notice("%s: %p\n", __func__, wsi);
  300. for (n = 0; n < hacky_context->max_fds; n++)
  301. if (hacky_context->connpool[n] == arg) {
  302. hacky_context->connpool[n] = NULL;
  303. lwsl_info(" freed connpool %d\n", n);
  304. }
  305. if (wsi) {
  306. conn->reverse = NULL;
  307. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  308. lwsl_notice("closed ok\n");
  309. }
  310. }
  311. static void
  312. esp8266_cb_recon(void *arg, signed char err)
  313. {
  314. struct espconn *conn = arg;
  315. lwsl_err("%s: wsi %p. err %d\n", __func__, conn->reverse, err);
  316. conn->state = ESPCONN_CLOSE;
  317. esp8266_cb_disconnected(arg);
  318. }
  319. /*
  320. * there is no reliable indication of which listen socket we were accepted on.
  321. */
  322. static void
  323. esp8266_cb_connect(void *arg)
  324. {
  325. struct espconn *cs = arg;
  326. // struct ip_addr *ipa = (struct ip_addr *)cs->proto.tcp->remote_ip;
  327. struct lws_vhost *vh = hacky_context->vhost_list;
  328. // struct ip_info info;
  329. struct lws *wsi;
  330. int n;
  331. lwsl_notice("%s: (wsi coming): %p\n", __func__, cs->reverse);
  332. #if 0
  333. wifi_get_ip_info(0, &info);
  334. if (ip_addr_netcmp(ipa, &info.ip, &info.netmask)) {
  335. /* we are on the same subnet as the AP, ie, connected to AP */
  336. while (vh && strcmp(vh->name, "ap"))
  337. vh = vh->vhost_next;
  338. } else
  339. while (vh && !strcmp(vh->name, "ap"))
  340. vh = vh->vhost_next;
  341. if (!vh)
  342. goto bail;
  343. #endif
  344. n = esp8266_find_free_conn(hacky_context);
  345. if (n < 0)
  346. goto bail;
  347. hacky_context->connpool[n] = cs;
  348. espconn_recv_hold(cs);
  349. wsi = lws_adopt_socket_vhost(vh, cs);
  350. if (!wsi)
  351. goto bail;
  352. lwsl_err("%s: wsi %p (using free_conn %d): vh %s\n", __func__, wsi, n, vh->name);
  353. espconn_regist_recvcb(cs, esp8266_cb_rx);
  354. espconn_regist_reconcb(cs, esp8266_cb_recon);
  355. espconn_regist_disconcb(cs, esp8266_cb_disconnected);
  356. espconn_regist_sentcb(cs, esp8266_cb_sent);
  357. espconn_set_opt(cs, ESPCONN_NODELAY | ESPCONN_REUSEADDR);
  358. espconn_regist_time(cs, 7200, 1);
  359. return;
  360. bail:
  361. lwsl_err("%s: bailed]n", __func__);
  362. espconn_disconnect(cs);
  363. }
  364. void
  365. esp8266_tcp_stream_bind(lws_sockfd_type fd, int port, struct lws *wsi)
  366. {
  367. fd->proto.tcp->local_port = port;
  368. fd->reverse = wsi;
  369. hacky_context = wsi->context;
  370. espconn_regist_connectcb(fd, esp8266_cb_connect);
  371. /* hmmm it means, listen() + accept() */
  372. espconn_accept(fd);
  373. espconn_tcp_set_max_con_allow(fd, 10);
  374. }
  375. void
  376. esp8266_tcp_stream_accept(lws_sockfd_type fd, struct lws *wsi)
  377. {
  378. int n;
  379. fd->reverse = wsi;
  380. for (n = 0; n < wsi->context->max_fds ; n++)
  381. if (wsi->context->connpool[n] == wsi->desc.sockfd)
  382. wsi->position_in_fds_table = n;
  383. }
  384. LWS_VISIBLE int
  385. lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd)
  386. {
  387. return 0;
  388. }
  389. LWS_VISIBLE void
  390. lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
  391. {
  392. }
  393. LWS_VISIBLE int
  394. lws_plat_context_early_init(void)
  395. {
  396. espconn_tcp_set_max_con(12);
  397. return 0;
  398. }
  399. LWS_VISIBLE void
  400. lws_plat_context_early_destroy(struct lws_context *context)
  401. {
  402. }
  403. LWS_VISIBLE void
  404. lws_plat_context_late_destroy(struct lws_context *context)
  405. {
  406. #if 0
  407. struct lws_context_per_thread *pt = &context->pt[0];
  408. int m = context->count_threads;
  409. if (context->lws_lookup)
  410. lws_free(context->lws_lookup);
  411. while (m--) {
  412. close(pt->dummy_pipe_fds[0]);
  413. close(pt->dummy_pipe_fds[1]);
  414. pt++;
  415. }
  416. #endif
  417. // close(context->fd_random);
  418. }
  419. /* cast a struct sockaddr_in6 * into addr for ipv6 */
  420. LWS_VISIBLE int
  421. lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
  422. size_t addrlen)
  423. {
  424. return 0;
  425. }
  426. LWS_VISIBLE void
  427. lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
  428. {
  429. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  430. context->connpool[wsi->position_in_fds_table + context->max_fds] = (lws_sockfd_type)wsi;
  431. wsi->desc.sockfd->reverse = wsi;
  432. pt->fds_count++;
  433. }
  434. LWS_VISIBLE void
  435. lws_plat_delete_socket_from_fds(struct lws_context *context,
  436. struct lws *wsi, int m)
  437. {
  438. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  439. int n;
  440. for (n = 0; n < wsi->context->max_fds; n++)
  441. if (wsi->context->connpool[n] == wsi->desc.sockfd) {
  442. wsi->context->connpool[n] = NULL;
  443. wsi->context->connpool[n + wsi->context->max_fds] = NULL;
  444. lwsl_notice(" freed connpool %d\n", n);
  445. }
  446. wsi->desc.sockfd->reverse = NULL;
  447. pt->fds_count--;
  448. }
  449. LWS_VISIBLE void
  450. lws_plat_service_periodic(struct lws_context *context)
  451. {
  452. }
  453. LWS_VISIBLE int
  454. lws_plat_change_pollfd(struct lws_context *context,
  455. struct lws *wsi, struct lws_pollfd *pfd)
  456. {
  457. void *p;
  458. //lwsl_notice("%s: %p: wsi->pift=%d, events %d\n",
  459. // __func__, wsi, wsi->position_in_fds_table, pfd->events);
  460. if (pfd->events & LWS_POLLIN) {
  461. if (wsi->premature_rx) {
  462. lwsl_notice("replaying buffered rx: wsi %p\n", wsi);
  463. p = wsi->premature_rx;
  464. wsi->premature_rx = NULL;
  465. esp8266_cb_rx(wsi->desc.sockfd,
  466. (char *)p + wsi->prem_rx_pos,
  467. wsi->prem_rx_size - wsi->prem_rx_pos);
  468. wsi->prem_rx_size = 0;
  469. wsi->prem_rx_pos = 0;
  470. lws_free(p);
  471. }
  472. if (espconn_recv_unhold(wsi->desc.sockfd) < 0)
  473. return -1;
  474. } else
  475. if (espconn_recv_hold(wsi->desc.sockfd) < 0)
  476. return -1;
  477. if (!(pfd->events & LWS_POLLOUT))
  478. return 0;
  479. if (!wsi->pending_send_completion) {
  480. pfd->revents |= LWS_POLLOUT;
  481. // lwsl_notice("doing POLLOUT\n");
  482. lws_service_fd(lws_get_context(wsi), pfd);
  483. } //else
  484. //lwsl_notice("pending sc\n");
  485. return 0;
  486. }
  487. LWS_VISIBLE const char *
  488. lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
  489. {
  490. // return inet_ntop(af, src, dst, cnt);
  491. return 0;
  492. }
  493. LWS_VISIBLE int
  494. lws_plat_init(struct lws_context *context,
  495. struct lws_context_creation_info *info)
  496. {
  497. // struct lws_context_per_thread *pt = &context->pt[0];
  498. // int n = context->count_threads, fd;
  499. /* master context has the global fd lookup array */
  500. context->connpool = lws_zalloc(sizeof(struct espconn *) *
  501. context->max_fds * 2);
  502. if (context->connpool == NULL) {
  503. lwsl_err("OOM on lws_lookup array for %d connections\n",
  504. context->max_fds);
  505. return 1;
  506. }
  507. lwsl_notice(" mem: platform fd map: %5u bytes\n",
  508. sizeof(struct espconn *) * context->max_fds);
  509. // fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
  510. // context->fd_random = fd;
  511. // if (context->fd_random < 0) {
  512. // lwsl_err("Unable to open random device %s %d\n",
  513. // SYSTEM_RANDOM_FILEPATH, context->fd_random);
  514. // return 1;
  515. // }
  516. os_memset(&context->to_timer, 0, sizeof(os_timer_t));
  517. os_timer_disarm(&context->to_timer);
  518. os_timer_setfn(&context->to_timer, (os_timer_func_t *)cb_1Hz, context);
  519. os_timer_arm(&context->to_timer, 1000, 1);
  520. if (!lws_libev_init_fd_table(context) &&
  521. !lws_libuv_init_fd_table(context)) {
  522. /* otherwise libev handled it instead */
  523. #if 0
  524. while (n--) {
  525. if (pipe(pt->dummy_pipe_fds)) {
  526. lwsl_err("Unable to create pipe\n");
  527. return 1;
  528. }
  529. /* use the read end of pipe as first item */
  530. pt->fds[0].fd = pt->dummy_pipe_fds[0];
  531. pt->fds[0].events = LWS_POLLIN;
  532. pt->fds[0].revents = 0;
  533. pt->fds_count = 1;
  534. pt++;
  535. }
  536. #endif
  537. }
  538. #ifdef LWS_WITH_PLUGINS
  539. if (info->plugin_dirs)
  540. lws_plat_plugins_init(context, info->plugin_dirs);
  541. #endif
  542. return 0;
  543. }