// Send some data back for a HTTP request void httpd_send(chanend tcp_svr, xtcp_connection_t *conn) { struct httpd_state_t *hs = (struct httpd_state_t *) conn->appstate; // Check if we need to resend previous data if (conn->event == XTCP_RESEND_DATA) { xtcp_send(tcp_svr, hs->prev_dptr, (hs->dptr - hs->prev_dptr)); return; } // Check if we have no data to send if (hs->dlen == 0 || hs->dptr == NULL) { // Terminates the send process xtcp_complete_send(tcp_svr); // Close the connection xtcp_close(tcp_svr, conn); } // We need to send some new data else { int len = hs->dlen; if (len > conn->mss) len = conn->mss; xtcp_send(tcp_svr, hs->dptr, len); hs->prev_dptr = hs->dptr; hs->dptr += len; hs->dlen -= len; } //// }
void httpd_handle_send_request(chanend tcp_svr, xtcp_connection_t *conn, chanend page_svr, chanend led_svr) { struct httpd_state_t *hs = (struct httpd_state_t *) conn->appstate; char data[XTCP_CLIENT_BUF_SIZE]; char *dptr = &data[0]; int len; int maxlen; if (hs->pss.cmdptr == 0) { xtcp_send(tcp_svr, data, 0); xtcp_close(tcp_svr, conn); return; } switch (conn->event) { case XTCP_REQUEST_DATA: break; case XTCP_SENT_DATA: break; case XTCP_RESEND_DATA: hs->pss = hs->saved_pss; break; default: break; } hs->saved_pss = hs->pss; maxlen = conn->mss; len = 0; // fill up the data buffer to maxlen while (len != maxlen && hs->pss.cmdptr != 0) { if (len + hs->pss.left <= maxlen) { page_server_get_data(page_svr, (char *) dptr, &(hs->pss), hs->pss.left); len += hs->pss.left; dptr += hs->pss.left; hs->pss.dptr += hs->pss.left; if (!page_server_eof(page_svr, &(hs->pss))) page_server_next_cmd(page_svr, &(hs->pss)); else hs->pss.cmdptr = 0; } else { int partial_len = maxlen - len; page_server_get_data(page_svr, (char *) dptr, &(hs->pss), partial_len); len += partial_len; hs->pss.left -= partial_len; hs->pss.dptr += partial_len; } } xtcp_send(tcp_svr, data, len); return; }
void telnet_config_event_handler(chanend c_xtcp, chanend c_uart_config, chanend c_flash_data, xtcp_connection_t *conn) { switch (conn->event) { case XTCP_IFUP: case XTCP_IFDOWN: case XTCP_ALREADY_HANDLED: return; default: break; } if (conn->local_port == S2E_TELNET_CONFIG_PORT) { connection_state_t *st = get_state_from_connection(conn); int close_request; int len; switch (conn->event) { case XTCP_NEW_CONNECTION: st = get_new_state(); if (!st) { xtcp_abort(c_xtcp, conn); break; } st->sending_welcome = 1; st->sending_ack = 0; st->err = NULL; st->conn_id = conn->id; init_telnet_parse_state(&st->telnet_parsing_state); reset_parsing_state(st); xtcp_init_send(c_xtcp, conn); break; case XTCP_RECV_DATA: len = xtcp_recv(c_xtcp, buf); if (!st || !st->active) break; len = parse_telnet_buffer(buf, len, &st->telnet_parsing_state, &close_request); parse_config(c_xtcp, c_uart_config, c_flash_data, conn, buf, len, st); if (close_request) xtcp_close(c_xtcp, conn); break; case XTCP_REQUEST_DATA: case XTCP_RESEND_DATA: if (!st || !st->active) { xtcp_complete_send(c_xtcp); break; } // When sending either st->sending_welcome is true, // st->sending_ack is true or st->err is non null. Depending on // whether the connection is sending a welcome message, ack or // error message if (st->sending_welcome) { xtcp_send(c_xtcp, welcome_msg, sizeof(welcome_msg)); } else if (st->sending_ack) { int len = construct_ack(st, buf); xtcp_send(c_xtcp, buf, len); } else if (st->err) { int len = strlen(st->err); strcpy(buf, st->err); buf[len] = '\n'; xtcp_send(c_xtcp, buf, len+1); } else { xtcp_complete_send(c_xtcp); } break; case XTCP_SENT_DATA: xtcp_complete_send(c_xtcp); if (st) { st->sending_ack = 0; st->sending_welcome = 0; st->err = NULL; } break; case XTCP_CLOSED: case XTCP_ABORTED: case XTCP_TIMED_OUT: if (st) { st->active = 0; } break; default: break; } conn->event = XTCP_ALREADY_HANDLED; } }