// Setup a new connection void httpd_init_state(chanend tcp_svr, xtcp_connection_t *conn) { int i; // Try and find an empty connection slot for (i=0;i<NUM_HTTPD_CONNECTIONS;i++) { if (!connection_states[i].active) break; } // If no free connection slots were found, abort the connection if ( i == NUM_HTTPD_CONNECTIONS ) { xtcp_abort(tcp_svr, conn); } // Otherwise, assign the connection to a slot // else { connection_states[i].active = 1; connection_states[i].conn_id = conn->id; connection_states[i].dptr = NULL; xtcp_set_connection_appstate( tcp_svr, conn, (xtcp_appstate_t) &connection_states[i]); } }
/* * This associates some buffer state with a conenction. It uses three * API calls. * * xtcp_set_connection_appstate - for attaching a piece of user state * to a xtcp connection. * * xtcp_buffered_set_rx_buffer - to associate the rx memory buffer with a * buffered connection. * * xtcp_buffered_set_tx_buffer - to associate the tx memory buffer with a * buffered connection. */ static void demo_protocol_init_state(chanend tcp_svr, xtcp_connection_t *conn, int timestamp) { int i; for (i = 0; i < NUM_DEMO_PROTOCOL_CONNECTIONS; i++) { if (!connection_states[i].active) break; } if (i == NUM_DEMO_PROTOCOL_CONNECTIONS) xtcp_abort(tcp_svr, conn); else { connection_states[i].active = 1; connection_states[i].got_header = 0; connection_states[i].last_used = timestamp; connection_states[i].conn_id = conn->id; xtcp_set_connection_appstate(tcp_svr, conn, (xtcp_appstate_t) &connection_states[i]); xtcp_buffered_set_rx_buffer(tcp_svr, conn, &connection_states[i].bufinfo, connection_states[i].inbuf, DEMO_PROTOCOL_RXBUF_LEN); xtcp_buffered_set_tx_buffer(tcp_svr, conn, &connection_states[i].bufinfo, connection_states[i].outbuf, DEMO_PROTOCOL_TXBUF_LEN, DEMO_PROTOCOL_MAX_MSG_SIZE); } return; }
/* * The xtcp stack has sent a data received event: * * - use buffered receive until an entire packet has been read in * and processed. * */ void demo_protocol_recv(chanend tcp_svr, xtcp_connection_t *conn) { struct demo_protocol_state_t *st = (struct demo_protocol_state_t *) conn->appstate; int len = 0; // keep looping until we have received all of the data do { // if we have not already seen and processed the header then receive a header's worth // of data if (!st->got_header) { char *hdr; int overflow = 0; // read the header len = xtcp_buffered_recv(tcp_svr, conn, &st->bufinfo, &hdr, DEMO_PROTOCOL_HDR_SIZE, &overflow); if (overflow) { xtcp_abort(tcp_svr, conn); return; } if (len) { st->len = decode_demo_protocol_header(hdr); if (st->len <= 0 || st->len > DEMO_PROTOCOL_MAX_MSG_SIZE) { xtcp_abort(tcp_svr, conn); return; } st->got_header = 1; } } else { char *msg; int overflow = 0; len = xtcp_buffered_recv(tcp_svr, conn, &st->bufinfo, &msg, st->len, &overflow); if (overflow) { xtcp_abort(tcp_svr, conn); return; } if (len) { demo_protocol_process_message(tcp_svr, conn, st, msg); st->got_header = 0; } } } while (len); return; }
// xscope socket data handler void xtcp_handle_xscope_tcp_event(chanend c_xtcp, xtcp_connection_t *conn) { // Ignore events that are not directly relevant to tcp handler //printintln(conn->event); switch (conn->event) { case XTCP_IFUP: case XTCP_IFDOWN: conn_active = 0; return; case XTCP_ALREADY_HANDLED: return; default: break; } // Check if the connection is an client app connection if (conn->local_port == TCP_XSCOPE_PORT) { switch (conn->event) { case XTCP_NEW_CONNECTION: if (conn_active) { printstrln("a host connection is already active"); xtcp_abort(c_xtcp, conn); } else conn_active = 1; break; case XTCP_RECV_DATA: { xtcp_recv(c_xtcp, (char *) &xscope_data); process_xscope_data(c_xtcp, xscope_data); } break; case XTCP_SENT_DATA: case XTCP_REQUEST_DATA: case XTCP_RESEND_DATA: tcp_send(c_xtcp, conn); break; case XTCP_TIMED_OUT: case XTCP_ABORTED: case XTCP_CLOSED: conn_active = 0; break; default: // Ignore anything else break; } conn->event = XTCP_ALREADY_HANDLED; } return; }
// Setup a new connection void telnetd_init_state(chanend tcp_svr, xtcp_connection_t *conn) { int i; // Try and find an empty connection slot for (i=0;i<NUM_TELNETD_CONNECTIONS;i++) { if (!connection_states[i].active) break; } // If no free connection slots were found, abort the connection if ( i == NUM_TELNETD_CONNECTIONS ) { xtcp_abort(tcp_svr, conn); } else { // Otherwise, assign the connection to a slot connection_states[i].active = 1; connection_states[i].conn_id = conn->id; connection_states[i].parse_state = PARSING_DATA; connection_states[i].inptr = 0; connection_states[i].first_recv = 1; xtcp_buffered_set_tx_buffer(tcp_svr, conn, &connection_states[i].bufinfo, connection_states[i].outbuf, TELNET_LINE_BUFFER_LEN, (TELNET_LINE_BUFFER_LEN*1/4)); xtcp_set_connection_appstate(tcp_svr, conn, (xtcp_appstate_t) &connection_states[i]); } }
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; } }