// 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;
}
Exemple #5
0
// 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;
  }

}