void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { struct mg_ev_mgr_lwip_data *md = (struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data; while (md->sig_queue_len > 0) { mgos_lock(); int sig = md->sig_queue[md->start_index].sig; struct mg_connection *nc = md->sig_queue[md->start_index].nc; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN; md->sig_queue_len--; mgos_unlock(); if (nc->iface == NULL || nc->mgr == NULL) continue; switch (sig) { case MG_SIG_CONNECT_RESULT: { #if MG_ENABLE_SSL if (cs->err == 0 && (nc->flags & MG_F_SSL) && !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) { mg_lwip_ssl_do_hs(nc); } else #endif { mg_if_connect_cb(nc, cs->err); } break; } case MG_SIG_CLOSE_CONN: { nc->flags |= MG_F_SEND_AND_CLOSE; mg_close_conn(nc); break; } case MG_SIG_RECV: { cs->recv_pending = 0; if (nc->flags & MG_F_UDP) { mg_lwip_handle_recv_udp(nc); } else { mg_lwip_handle_recv_tcp(nc); } break; } case MG_SIG_TOMBSTONE: { break; } case MG_SIG_ACCEPT: { mg_lwip_handle_accept(nc); break; } } } }
static void mg_ssl_begin(struct mg_connection *nc) { int server_side = (nc->listener != NULL); enum mg_ssl_if_result res = mg_ssl_if_handshake(nc); DBG(("%p %d res %d", nc, server_side, res)); if (res == MG_SSL_OK) { nc->flags |= MG_F_SSL_HANDSHAKE_DONE; nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE); if (server_side) { union socket_address sa; socklen_t sa_len = sizeof(sa); (void) getpeername(nc->sock, &sa.sa, &sa_len); mg_if_accept_tcp_cb(nc, &sa, sa_len); } else { mg_if_connect_cb(nc, 0); } } else if (res != MG_SSL_WANT_READ && res != MG_SSL_WANT_WRITE) { if (!server_side) { mg_if_connect_cb(nc, res); } nc->flags |= MG_F_CLOSE_IMMEDIATELY; } }
static void mg_lwip_task(os_event_t *e) { struct mg_mgr *mgr = NULL; DBG(("sig %d", e->sig)); poll_scheduled = 0; switch ((enum mg_sig_type) e->sig) { case MG_SIG_TOMBSTONE: break; case MG_SIG_POLL: { mgr = (struct mg_mgr *) e->par; break; } case MG_SIG_CONNECT_RESULT: { struct mg_connection *nc = (struct mg_connection *) e->par; mgr = nc->mgr; mg_if_connect_cb(nc, nc->err); break; } case MG_SIG_CLOSE_CONN: { struct mg_connection *nc = (struct mg_connection *) e->par; mgr = nc->mgr; nc->flags |= MG_F_CLOSE_IMMEDIATELY; mg_close_conn(nc); break; } case MG_SIG_SENT_CB: { struct mg_connection *nc = (struct mg_connection *) e->par; mgr = nc->mgr; mg_if_sent_cb(nc, nc->err); break; } case MG_SIG_V7_CALLBACK: { #ifndef NO_V7 struct v7_callback_args *cba = (struct v7_callback_args *) e->par; _sj_invoke_cb(cba->v7, cba->func, cba->this_obj, cba->args); v7_disown(cba->v7, &cba->func); v7_disown(cba->v7, &cba->this_obj); v7_disown(cba->v7, &cba->args); free(cba); #endif break; } } if (mgr != NULL) { mg_mgr_poll(mgr, 0); } }
void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { struct mg_ev_mgr_lwip_data *md = (struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data; while (md->sig_queue_len > 0) { struct mg_connection *nc = md->sig_queue[md->start_index].nc; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; switch (md->sig_queue[md->start_index].sig) { case MG_SIG_CONNECT_RESULT: { #if MG_ENABLE_SSL if (cs->err == 0 && (nc->flags & MG_F_SSL) && !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) { mg_lwip_ssl_do_hs(nc); } else #endif { mg_if_connect_cb(nc, cs->err); } break; } case MG_SIG_CLOSE_CONN: { nc->flags |= MG_F_CLOSE_IMMEDIATELY; mg_close_conn(nc); break; } case MG_SIG_RECV: { mg_lwip_handle_recv(nc); break; } case MG_SIG_SENT_CB: { if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent); cs->num_sent = 0; break; } case MG_SIG_TOMBSTONE: { break; } } md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN; md->sig_queue_len--; } }
static void mg_lwip_task(os_event_t *e) { struct mg_mgr *mgr = NULL; poll_scheduled = 0; switch ((enum mg_sig_type) e->sig) { case MG_SIG_TOMBSTONE: break; case MG_SIG_POLL: { mgr = (struct mg_mgr *) e->par; break; } case MG_SIG_CONNECT_RESULT: { struct mg_connection *nc = (struct mg_connection *) e->par; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; mgr = nc->mgr; mg_if_connect_cb(nc, cs->err); break; } case MG_SIG_CLOSE_CONN: { struct mg_connection *nc = (struct mg_connection *) e->par; mgr = nc->mgr; nc->flags |= MG_F_CLOSE_IMMEDIATELY; mg_close_conn(nc); break; } case MG_SIG_SENT_CB: { struct mg_connection *nc = (struct mg_connection *) e->par; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; mgr = nc->mgr; if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent); cs->num_sent = 0; break; } case MG_SIG_V7_CALLBACK: { #ifndef NO_V7 struct v7_callback_args *cba = (struct v7_callback_args *) e->par; _sj_invoke_cb(cba->v7, cba->func, cba->this_obj, cba->args); v7_disown(cba->v7, &cba->func); v7_disown(cba->v7, &cba->this_obj); v7_disown(cba->v7, &cba->args); free(cba); #endif break; } } if (mgr != NULL) { mg_mgr_poll(mgr, 0); if (s_suspended) { int can_suspend = 1; struct mg_connection *nc; /* Looking for data to send and if there isn't any - suspending */ for (nc = mgr->active_connections; nc != NULL; nc = nc->next) { if (nc->send_mbuf.len > 0) { can_suspend = 0; break; } } if (can_suspend) { os_timer_disarm(&s_poll_tmr); #if MG_LWIP_REXMIT_INTERVAL_MS > 0 os_timer_disarm(&s_rexmit_tmr); #endif } } } }
void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) { int worth_logging = fd_flags != 0 || (nc->flags & (MG_F_WANT_READ | MG_F_WANT_WRITE)); if (worth_logging) { DBG(("%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, fd_flags, nc->flags, (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len)); } if (nc->flags & MG_F_CONNECTING) { if (fd_flags != 0) { int err = 0; #if !defined(MG_ESP8266) if (!(nc->flags & MG_F_UDP)) { socklen_t len = sizeof(err); int ret = getsockopt(nc->sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len); if (ret != 0) { err = 1; } else if (err == EAGAIN || err == EWOULDBLOCK) { err = 0; } } #else /* * On ESP8266 we use blocking connect. */ err = nc->err; #endif #if MG_ENABLE_SSL if ((nc->flags & MG_F_SSL) && err == 0) { mg_ssl_begin(nc); } else { mg_if_connect_cb(nc, err); } #else mg_if_connect_cb(nc, err); #endif } else if (nc->err != 0) { mg_if_connect_cb(nc, nc->err); } } if (fd_flags & _MG_F_FD_CAN_READ) { if (nc->flags & MG_F_UDP) { mg_handle_udp_read(nc); } else { if (nc->flags & MG_F_LISTENING) { /* * We're not looping here, and accepting just one connection at * a time. The reason is that eCos does not respect non-blocking * flag on a listening socket and hangs in a loop. */ mg_accept_conn(nc); } else { mg_handle_tcp_read(nc); } } } if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY)) { if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0) { mg_write_to_socket(nc); } mg_if_poll(nc, (time_t) now); mg_if_timer(nc, now); } if (worth_logging) { DBG(("%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, nc->flags, (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len)); } }