示例#1
0
// 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;
  }
  ////

}
示例#2
0
void httpd_init_state(chanend tcp_svr, 
                      xtcp_connection_t *conn)
{
  int i;

  for (i=0;i<NUM_HTTPD_CONNECTIONS;i++) {
    if (!connection_states[i].active) 
      break;    
  }
  
  if (i==NUM_HTTPD_CONNECTIONS) {
    printstr("Too many httpd connections!");
    xtcp_close(tcp_svr, conn);
  }
  else {
    //    printstr("open ");
    //printintln(i);
    connection_states[i].active = 1;
    connection_states[i].conn_id = conn->id;
    connection_states[i].pss.cmdptr = 0;
    connection_states[i].pss.dptr = 0;
    connection_states[i].pss.saved_dptr = 0;
    connection_states[i].pss.bfcount = 0;
    connection_states[i].saved_pss = connection_states[i].pss;


    xtcp_set_connection_appstate(tcp_svr, conn, (xtcp_appstate_t) &connection_states[i]);
  }
  return;
}
void demo_protocol_periodic(chanend tcp_svr, int t) {
	// timeout any inactive connections
	for (int i = 0; i < NUM_DEMO_PROTOCOL_CONNECTIONS; i++) {
		struct demo_protocol_state_t *st = &connection_states[i];
		xtcp_connection_t conn;
		if (st->active) {
			if ((t - st->last_used) > DEMO_PROTOCOL_CONN_TIMEOUT_TIMER_TICKS) {
				conn.id = st->conn_id;
				xtcp_close(tcp_svr, &conn);
			}
		}
	}
}
示例#4
0
void httpd_recv(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];
  int len; 

  len = xtcp_recv(tcp_svr, data);
  // this assumes that a request fits in one read!!
  if (hs == NULL || hs->pss.cmdptr != 0) 
    return;

  parse_http_request(hs, &data[0], len, page_svr, led_svr);
  if (hs->pss.cmdptr != 0)
    xtcp_init_send(tcp_svr, conn);
  else
    xtcp_close(tcp_svr, conn);
}
示例#5
0
// Parses a HTTP request for a GET
static void parse_telnet_stream(chanend tcp_svr,
                                xtcp_connection_t *conn,
                                telnetd_state_t *hs, 
                                char *data, 
                                int len)
{
  int i = 0;
  
  while (i<len) {
    switch (hs->parse_state) {
    case PARSING_CMD:
      switch (data[i]) 
        {        
        case SB:
          hs->parse_state = PARSING_OPTIONS;          
          break;
        case SE:
          hs->parse_state = PARSING_DATA;
          break;
        case WILL:
        case WONT:
          hs->parse_state = PARSING_REQUEST;
          break;
        case DO:
        case DONT:
          hs->parse_state = PARSING_NOTIFICATION;
          break;
        case IP:          
          xtcp_close(tcp_svr, conn);
          return;
        default:          
          // unsupported command - ignore
          hs->parse_state = PARSING_DATA;
          break;
        };   
      i++;
      break;
    case PARSING_NOTIFICATION:
      // just ignore everything the other side tells us for now
      hs->parse_state = PARSING_DATA;
      i++;
      break;
    case PARSING_REQUEST:
#if 0
      switch (data[i]) 
        {        
        case SUPPRESS_GA:
          hs->pending_cmd = DO;
          hs->pending_cmd_data = data[i];          
          break;
        default:
          hs->pending_cmd = DONT;
          hs->pending_cmd_data = data[i];          
          break;
        };   
      telnetd_init_send(tcp_svr, hs, conn);
#endif
      hs->parse_state = PARSING_DATA;
      i++;
      break;
    case PARSING_OPTIONS:
      if (data[i] == IAC) 
        hs->parse_state = PARSING_CMD;
      i++;
      break;
    case PARSING_DATA:
      switch (data[i]) 
        {
        case IAC:
          hs->parse_state = PARSING_CMD;
          break;
        case CR:
          hs->line_buf_in[hs->inptr] = NUL;
          hs->parse_state = PARSING_EOL;
          break;
        default:
          if (hs->inptr < TELNET_LINE_BUFFER_LEN && 
              data[i] != NUL &&
              !(data[i] & 0x80)) {
            hs->line_buf_in[hs->inptr] = data[i];
            hs->inptr++;
          }
          break;
        }
      i++;
      break;
    case PARSING_EOL:
      if (data[i] == LF) {
        telnetd_recv_line(tcp_svr, hs->index, hs->line_buf_in, hs->inptr);
        hs->inptr = 0;
        hs->parse_state = PARSING_DATA;
      }
      i++;
      break;
    }
  }

  if (hs->first_recv) {
    hs->first_recv = 0;
    telnetd_new_connection(tcp_svr,hs->index);
  }
}
示例#6
0
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;
  }

}
示例#8
0
static void process_xscope_data(chanend c_xtcp, xscope_protocol xscope_data)
{
    /* Custom protocol definition
     * Start with cmd_type, send end_token as 0 as last
     * Listen:    0-dc-inport-proto-dc
     * Connect:   1-dc-out_port-proto-host_ipconfig
     * Send:      2-1-local_port-dc-remote_addr
     * Close:     2-2-local_port-dc-remote_addr
     */
#define CONTROLLER_IP	{169, 254, 196, 179}
#if !defined(CONTROLLER_IP)
#warning No define of form CONTROLLER_IP
#error Rebuild the application with this define assigned to the host controller ip
#endif

    xtcp_ipaddr_t ipaddr = CONTROLLER_IP;
    /*ipaddr[0] = atoi(xscope_data.ip_addr_1);
    ipaddr[1] = atoi(xscope_data.ip_addr_2);
    ipaddr[2] = atoi(xscope_data.ip_addr_3);
    ipaddr[3] = atoi(xscope_data.ip_addr_4);*/

    switch (xscope_data.cmd_type) {
      case XSCOPE_CMD_LISTEN: //listen; for server type conn
        xtcp_listen(c_xtcp, xscope_data.port_no, xscope_data.protocol);
        printstr("Listening on port: ");
        printintln(xscope_data.port_no);
      break;
      case XSCOPE_CMD_CONNECT: //connect; for client type conn
        xtcp_connect(c_xtcp, xscope_data.port_no, ipaddr, xscope_data.protocol);
        printstr("Connected to host on port: ");
        printintln(xscope_data.port_no);
      break;
      case XSCOPE_CMD_SEND: { //Send data
        int conn_id;
        xtcp_connection_t conn;
    	if (PROTO_TCP == xscope_data.protocol)
          conn_id = get_tcp_conn_id(ipaddr,  xscope_data.port_no);
    	else if (PROTO_UDP == xscope_data.protocol)
          conn_id = get_udp_conn_id(ipaddr,  xscope_data.port_no);

        if (conn_id) {
       	  conn.id = conn_id;
          xtcp_init_send(c_xtcp, &conn);
       	  printstr("Sending data on the connection: ");
       	  printintln(conn_id);
        }
      }
      break;
      case XSCOPE_CMD_CLOSE: { //Close command
        int conn_id;
        xtcp_connection_t conn;
        if (PROTO_TCP == xscope_data.protocol)
          conn_id = get_tcp_conn_id(ipaddr,  xscope_data.port_no);
        else if (PROTO_UDP == xscope_data.protocol)
          conn_id = get_udp_conn_id(ipaddr,  xscope_data.port_no);

    	if (conn_id) {
       	  conn.id = conn_id;
       	  xtcp_close(c_xtcp, &conn);
       	  printstr("Closing the connection: ");
       	  printintln(conn_id);
        }
      }
      break;
      case XSCOPE_CMD_CTRLR_SEND: //this is a controller send command; do nothing
      break;
      default:
        printstrln("unknown command received");
      break;
    }
}