/*
 * Timesynch functionality
 */
static
PT_THREAD(timesynch(struct psock *p))
{
  PSOCK_BEGIN(p);
  printf("TIME: %d\n",clock_time());
  static TimesynchSRMsg time_pkt;
  memset(&time_pkt,0,sizeof(time_pkt));

  PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p));
  if(PSOCK_NEWDATA(p)){
    clock_time_t t2 = clock_time();
    PSOCK_READBUF(p);
    memcpy(&time_pkt,buffer,sizeof(time_pkt));
    
    time_pkt.t1 = time_pkt.t1;
    time_pkt.t2 = t2;
    time_pkt.t3 = clock_time();
    
    printf("Clock print: %u\n",clock_time());
    PSOCK_SEND(p,&time_pkt,sizeof(time_pkt));
    printf("Clock print: %u\n",clock_time());

    printf("T1: %u\n",time_pkt.t1);
    printf("T2: %u\n",time_pkt.t2);
    printf("T3: %u\n",time_pkt.t3);

  } else {
    printf("Timed out!\n");
    PSOCK_CLOSE_EXIT(p);
  }
  state = 4;
  PSOCK_END(p);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(create_test_session(struct psock *p))
{
  /*
   * A protosocket's protothread must start with a PSOCK_BEGIN(), with
   * the protosocket as argument.
   */
  PSOCK_BEGIN(p);

  /*
   * Here we define all the thread local variables that we need to
   * utilize.
   */
  static RequestSession request;
  static AcceptSession accept;
  
  PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p));
  if(PSOCK_NEWDATA(p)){
    /*
     * We read data from the buffer now that it has arrived.
     * Using memcpy we store it in our local variable.
     */
    PSOCK_READBUF(p);
    memcpy(&request,buffer,sizeof(request));

    TEST_AMOUNT = (int) request.NumOfPackets;
    UDP_SENDER_PORT = (int) request.SenderPort;
    UDP_RECEIVER_PORT = (int) request.RecieverPort;
    
    /*
     * Prints for debugging.
     */
    printf("Type: %"PRIu32"\n",request.Type);
    printf("SenderPort: %"PRIu32"\n",request.SenderPort);
    printf("ReceiverPort: %"PRIu32"\n",request.RecieverPort);
    printf("SenderAddress: %08x,%x\n",request.SenderAddress,request.SenderMBZ);
    printf("ReceiverAddress: %08x,%x\n",request.RecieverAddress,request.RecieverMBZ);
    printf("StartTime: %u\n",request.StartTime.Second);
    
    accept.Accept = 0;
    accept.Port = request.RecieverPort; 

    PSOCK_SEND(p, &accept, sizeof(accept));
    PSOCK_SEND(p, &accept, sizeof(accept));
  } else {
    printf("Timed out!\n");
  }  
  state = 3;
  PSOCK_END(p);
}
Пример #3
0
/*
 * In uip-server we have defined the UIP_APPCALL macro to
 * server_handle_connection so that this funcion is uIP's application
 * function. This function is called whenever an uIP event occurs
 * (e.g. when a new connection is established, new data arrives, sent
 * data is acknowledged, data needs to be retransmitted, etc.).
 */
void server_handle_connection()
{
	/*
	* The uip_conn structure has a field called "appstate" that holds
	* the application state of the connection. We make a pointer to
	* this to access it easier.
	*/
	uip_tcp_appstate_t* s = &(uip_conn->appstate);

	/*
	* If a new connection was just established, we should initialize
	* the protosocket in our applications' state structure.
	*/
	if (uip_connected())
	{
		PSOCK_INIT(&s->p, s->pwmRgb, sizeof(s->pwmRgb));
	}

	/*
	* Finally, we run the protosocket function that actually handles
	* the communication. We pass it a pointer to the application state
	* of the current connection.
	*/
	PSOCK_BEGIN(&s->p);

	while (1)
	{
		PSOCK_READBUF(&s->p);

		TIM4->CCR2 = s->pwmRgb[0];
		TIM4->CCR3 = s->pwmRgb[1];
		TIM4->CCR4 = s->pwmRgb[2];
	}

	PSOCK_CLOSE(&s->p);
	PSOCK_END(&s->p);
}
/*
 * A protosocket always requires a protothread. The protothread
 * contains the code that uses the protosocket. We define the
 * protothread here.
 */
static
PT_THREAD(connection_setup(struct psock *p))
{
  /*
   * A protosocket's protothread must start with a PSOCK_BEGIN(), with
   * the protosocket as argument.
   */
  PSOCK_BEGIN(p);
  printf("TIME: %d\n",clock_time());

  /*
   * Here we define all the thread local variables that we need to
   * utilize.
   */
  static ServerGreeting greet;
  static SetupResponseUAuth setup;
  static ServerStartMsg start;
  static int i;
  static int acceptedMode = 1;

  /* 
   * We configure the Server-Greeting that we want to send. Setting
   * the accepted modes to those we accept. The following modes are 
   * meaningful:
   * 1 - Unauthenticated
   * 2 - Authenticated
   * 3 - Encrypted
   * 0 - Do not wish to communicate.
   */
  memset(&greet, 0, sizeof(greet));
  greet.Modes = 1;
  /*
   * We generate random sequence of octects for the challenge and
   * salt. 
   */
  for (i = 0; i < 16; i++){
      greet.Challenge[i] = rand() % 16;
      }
  for (i = 0; i < 16; i++){
      greet.Salt[i] = rand() % 16;
      }
  /*
   * Count must be a power of 2 and be at least 1024.
   */
  //greet.Count = (1 << 12);
  /*
   * We set the MBZ octets to zero.
   */
  for (i = 0; i < 12; i++){
    greet.MBZ[i] = 0;
  }

  /*
   * Using PSOCK_SEND() we send the Server-Greeting to the connected
   * client.
   */
  PSOCK_SEND(p, &greet, sizeof(greet));

  /* 
   * We wait until we receive a server greeting from the server.
   * PSOCK_NEWDATA(p) returns 1 when new data has arrived in 
   * the protosocket.  
   */
  PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p));
  if(PSOCK_NEWDATA(p)){
    /*
     * We read data from the buffer now that it has arrived.
     * Using memcpy we store it in our local variable.
     */
    PSOCK_READBUF(p);
    memcpy(&setup,buffer,sizeof(setup));
    if(setup.Modes != acceptedMode){
      printf("Client did not match our modes!\n");
      PSOCK_CLOSE_EXIT(p);
    } else{
      /*
       * We have agreed upon the mode. Now we send the Server-Start
       * message.
       */
      memset(&start,0,sizeof(start));
      /* 
       * We set the MBZ octets to zero.
       */
      for (i = 0; i < 15; i++){
        start.MBZ1[i] = 0;
      }
      for (i = 0; i < 8; i++){
        start.MBZ2[i] = 0;
      }
      /*
       * The accept field is set to zero if the server wishes to continue
       * communicating. A non-zero value is defined as in RFC 4656.
       */
      start.Accept = 0;
      /*
       * Timestamp is set to the time the Server started.
       */
      double temp;
      start.timestamp.Second = clock_seconds();
      temp = (double) clock_time()/CLOCK_SECOND - start.timestamp.Second;
      start.timestamp.Fraction = temp*1000;
      /*
       * Using PSOCK_SEND() we send the Server-Start to the connected
       * client.
       */
      PSOCK_SEND(p, &start, sizeof(start));
      printf("Client agreed to mode: %d\n",setup.Modes);
    }
  } else {
    printf("Timed out!\n");
  }
  state = 2;
  
  PSOCK_END(p);
}
Пример #5
0
static
PT_THREAD(handle_request(connection_state_t* conn_state))
{
    static int error;
    const char* content_len;

    PSOCK_BEGIN(&(conn_state->sin));

    content_len = NULL;

    error = HTTP_NO_ERROR; /*always reinit static variables due to protothreads*/

    PRINTF("Request--->\n");

    //read method
    PSOCK_READTO(&(conn_state->sin), ' ');

    if (!is_method_handled(conn_state, conn_state->inputbuf)) {
        /*method not handled*/
        http_set_status(&conn_state->response, SERVICE_UNAVAILABLE_503);
        conn_state->state = STATE_OUTPUT;
    } else {
        /*read until the end of url*/
        PSOCK_READTO(&(conn_state->sin), ' ');

        /*-1 is needed since it also includes space char*/
        if (conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] != ' ' ) {
            error = HTTP_URL_TOO_LONG;
        }

        conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0;

        PRINTF("Read URL:%s\n", conn_state->inputbuf);

        if (error == HTTP_NO_ERROR) {
            error = parse_url(conn_state, conn_state->inputbuf);
        }

        if (error != HTTP_NO_ERROR) {
            if (error == HTTP_URL_TOO_LONG) {
                http_set_status(&conn_state->response, REQUEST_URI_TOO_LONG_414);
            } else {
                http_set_status(&conn_state->response, BAD_REQUEST_400);
            }

            conn_state->state = STATE_OUTPUT;
        } else {
            /*read until the end of HTTP version - not used yet*/
            PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR);

            PRINTF("After URL:%s\n", conn_state->inputbuf);

            /*FIXME : PSOCK_READTO takes just a single delimiter so I read till the end of line
            but now it may not fit in the buffer. If PSOCK_READTO would take two delimiters,
            we would have read until : and <CR> so it would not be blocked.*/

            /*Read the headers and store the necessary ones*/
            do {
                /*read the next line*/
                PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR);
                conn_state->inputbuf[ PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0;

                /*if headers finished then stop the infinite loop*/
                if (conn_state->inputbuf[0] == CARRIAGE_RETURN_CHAR || conn_state->inputbuf[0] == 0) {
                    PRINTF("Finished Headers!\n\n");
                    break;
                }

                parse_header(conn_state, conn_state->inputbuf);
            }
            while(1);

            content_len = get_header(conn_state->request.headers, HTTP_HEADER_NAME_CONTENT_LENGTH);
            if (content_len) {
                conn_state->request.payload_len = atoi(content_len);

                PRINTF("Post Data Size string: %s int: %d\n", content_len, conn_state->request.payload_len);
            }

            if (conn_state->request.payload_len) {
                static uint16_t read_bytes = 0;
                /*init the static variable again*/
                read_bytes = 0;

                conn_state->request.payload = allocate_buffer(conn_state->request.payload_len + 1);

                if (conn_state->request.payload) {
                    do {
                        PSOCK_READBUF(&(conn_state->sin));
                        /*null terminate the buffer in case it is a string.*/
                        conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin))] = 0;

                        memcpy(conn_state->request.payload + read_bytes, conn_state->inputbuf, PSOCK_DATALEN(&(conn_state->sin)));

                        read_bytes += PSOCK_DATALEN(&(conn_state->sin));

                    } while (read_bytes < conn_state->request.payload_len);

                    conn_state->request.payload[read_bytes++] = 0;

                    PRINTF("PostData => %s \n", conn_state->request.payload);
                } else {
                    error = HTTP_MEMORY_ALLOC_ERR;
                }
            }

            if (error == HTTP_NO_ERROR) {
                if (service_cbk) {
                    service_cbk(&conn_state->request, &conn_state->response);
                }
            } else {
                PRINTF("Error:%d\n",error);
                http_set_status(&conn_state->response, INTERNAL_SERVER_ERROR_500);
            }

            conn_state->state = STATE_OUTPUT;
        }
    }

    PSOCK_END(&(conn_state->sin));
}