/*---------------------------------------------------------------------------*/
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);
}
Example #2
0
/*---------------------------------------------------------------------------*/
static PT_THREAD(send_part_of_file(struct httpd_state *s)) {
	PSOCK_BEGIN(&s->sout);
	
	PSOCK_SEND(&s->sout, s->file.data, s->len);
	
	PSOCK_END(&s->sout);
}
Example #3
0
static
PT_THREAD(send_file(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sout);
  char filename[HTTPD_PATHLEN];
  strcpy(filename, slip_config_www_root);
  strcat(filename, s->filename);
  strcpy(s->filename, filename);

  s->fd = open(s->filename, O_RDONLY);
  if (s-> fd > 0) {
    do {
      /* Read data from file system into buffer */
      s->len = read(s->fd, s->outputbuf, sizeof(s->outputbuf));

      /* If there is data in the buffer, send it */
      if(s->len > 0) {
        PSOCK_SEND(&s->sout, (uint8_t *)s->outputbuf, s->len);
      } else {
        break;
      }
    } while(s->len > 0);
  }
  close(s->fd);
  PSOCK_END(&s->sout);
}
/*
 * 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);
}
Example #5
0
// This function is going to use uIP's protosockets to handle the connection.
// This means it must return int, because of the way the protosockets work.
// In a nutshell, when a PSOCK_* macro needs to wait for something, it will
// return from handle_connection so that other work can take place.  When the
// event is triggered, uip_callback() will call this function again and the
// switch() statement (see below) will take care of resuming execution where
// it left off.  It *looks* like this function runs from start to finish, but
// that's just an illusion to make it easier to code :-)
int
UIPClient::handle_connection(uip_tcp_appstate_t *s)
{
  // All protosockets must start with this macro.  Its internal implementation
  // is that of a switch() statement, so all code between PSOCK_BEGIN and
  // PSOCK_END is actually inside a switch block.  (This means for example,
  // that you can't declare variables in the middle of it!)

  struct psock *p = &s->p;
  uip_userdata_t *u = (uip_userdata_t *) s->user;

  PSOCK_BEGIN(p);

    if (uip_newdata() && readyToReceive(s))
      {
        PSOCK_READBUF_LEN(p, 0); //TODO check what happens when there's more new data incoming than space left in UIPClients buffer (most likely this is just discarded, isn't it?)
        dataReceived(s);
      }

    if (readyToSend(s))
      {
        PSOCK_SEND(p, u->out_buffer, u->out_len);
        dataSent(s);
      }

    if (isClosed(s))
      {
        // Disconnect.
        PSOCK_CLOSE(p);
      }

    // All protosockets must end with this macro.  It closes the switch().
  PSOCK_END(p);
}
Example #6
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send(void))
{
  PSOCK_BEGIN(&s.sout);
  
  PSOCK_SEND(&s.sout, s.outputbuf, s.len);
  PSOCK_END(&s.sout);    
}
static PT_THREAD(handle_output(contiki_data_t *s))
{
	PSOCK_BEGIN(&s->p);
	if (s->state == WRITTING) {
		PSOCK_SEND(&s->p, s->out_buf, s->out_len);
		s->state = WRITE_END;
		process_post_synch(s->process, xively_event, s);
	}
	PSOCK_END(&s->p);
}
Example #8
0
static int handle_tcp_connection(struct psock *p, enum tcp_event_type type,
				 struct net_buf *buf)
{
	PSOCK_BEGIN(p);

	if (type == TCP_WRITE_EVENT) {
		NET_DBG("Trying to send %d bytes data\n", uip_appdatalen(buf));
		PSOCK_SEND(p, buf);
	}

	PSOCK_END(p);
}
Example #9
0
/*
 * A protosocket always requires a protothread. The protothread
 * contains the code that uses the protosocket. We define the
 * protothread here.
 */
static
PT_THREAD(handle_connection(struct psock *p))
{
  /*
   * A protosocket's protothread must start with a PSOCK_BEGIN(), with
   * the protosocket as argument.
   *
   * Remember that the same rules as for protothreads apply: do NOT
   * use local variables unless you are very sure what you are doing!
   * Local (stack) variables are not preserved when the protothread
   * blocks.
   */
  PSOCK_BEGIN(p);

  /*
   * We start by sending out a welcoming message. The message is sent
   * using the PSOCK_SEND_STR() function that sends a null-terminated
   * string.
   */
  PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");
  
  /*
   * Next, we use the PSOCK_READTO() function to read incoming data
   * from the TCP connection until we get a newline character. The
   * number of bytes that we actually keep is dependant of the length
   * of the input buffer that we use. Since we only have a 10 byte
   * buffer here (the buffer[] array), we can only remember the first
   * 10 bytes received. The rest of the line up to the newline simply
   * is discarded.
   */
  PSOCK_READTO(p, '\n');
  
  /*
   * And we send back the contents of the buffer. The PSOCK_DATALEN()
   * function provides us with the length of the data that we've
   * received. Note that this length will not be longer than the input
   * buffer we're using.
   */
  PSOCK_SEND_STR(p, "Got the following data: ");
  PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
  PSOCK_SEND_STR(p, "Good bye!\r\n");

  /*
   * We close the protosocket.
   */
  PSOCK_CLOSE(p);

  /*
   * And end the protosocket's protothread.
   */
  PSOCK_END(p);
}
Example #10
0
static PT_THREAD(SendData(struct httpd_state *s, int len, char* b)) {
	static int c = 0;
	
	PSOCK_BEGIN(&s->sout);
	f(7, "SendData___________________ ", &c);
	PSOCK_SEND(&s->sout, b, len);
	f(7, "SendData ", &c);
	
	if (s->state == STATE_OUTPUT) {
		s->state = STATE_WAITING;
	} else { // if == STATE_OUTPUT_READBACK
		s->state = STATE_READBACK;
	}
	PSOCK_END(&s->sout);
}
Example #11
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_file(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sout);
  
  do {
    /* Read data from file system into buffer */
    s->len = cfs_read(s->fd, s->outputbuf, sizeof(s->outputbuf));

    /* If there is data in the buffer, send it */
    if(s->len > 0) {
      PSOCK_SEND(&s->sout, (uint8_t *)s->outputbuf, s->len);
    } else {
      break;
    }
  } while(s->len > 0);
      
  PSOCK_END(&s->sout);
}
Example #12
0
/* -------------------------------------------------------------------------- */
static PT_THREAD(handle_connection(struct psock *p))
{
    // So, as always let's start
    PSOCK_BEGIN(p);

    // Let's send a hello world
    PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");

    // Let's block this thread untile a new line is received
    PSOCK_READTO(p, '\n');

    // And what we receive, we send it back, MUAHAHA
    PSOCK_SEND_STR(p, "Got the following data: ");
    PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
    PSOCK_SEND_STR(p, "Good bye!\r\n");

    // Finally close the socket
    PSOCK_CLOSE(p);

    // The End...
    PSOCK_END(p);
}
Example #13
0
static
PT_THREAD(send_data(connection_state_t* conn_state))
{
    uint16_t index;
    http_response_t* response;
    http_header_t* header;
    uint8_t* buffer;

    PSOCK_BEGIN(&(conn_state->sout));

    PRINTF("send_data -> \n");

    index = 0;
    response = &conn_state->response;
    header = response->headers;
    buffer = allocate_buffer(200);

    /*FIXME: what is the best solution here to send the data. Right now, if buffer is not allocated, no data is sent!*/
    if (buffer) {
        index += sprintf(buffer + index, "%s %d %s%s", httpv1_1, response->status_code, response->status_string, line_end);
        for (; header; header = header->next) {
            PRINTF("header %u \n", (uint16_t)header);
            index += sprintf(buffer + index, "%s%s%s%s", header->name, header_delimiter, header->value, line_end);
        }
        index += sprintf(buffer + index, "%s", line_end);

        memcpy(buffer + index, response->payload, response->payload_len);
        index += response->payload_len;

        PRINTF("Sending Data(size %d): %s \n", index, buffer);

        PSOCK_SEND(&(conn_state->sout), buffer, index);
    } else {
        PRINTF("BUFF ERROR: send_data!\n");
    }

    PSOCK_END(&(conn_state->sout));
}
Example #14
0
static PT_THREAD(handle_mqtt_connection(mqtt_state_t* state))
{
  static struct etimer keepalive_timer;

  uint8_t msg_type;
  uint8_t msg_qos;
  uint16_t msg_id;

  PSOCK_BEGIN(&state->ps);

  // Initialise and send CONNECT message
  mqtt_msg_init(&state->mqtt_connection, state->out_buffer, state->out_buffer_length);
  state->outbound_message =  mqtt_msg_connect(&state->mqtt_connection, state->connect_info);
  PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
  state->outbound_message = NULL;

  // Wait for CONACK message
  PSOCK_READBUF_LEN(&state->ps, 2);
  if(mqtt_get_type(state->in_buffer) != MQTT_MSG_TYPE_CONNACK)
    PSOCK_CLOSE_EXIT(&state->ps);
  
  // Tell the client we're connected
  mqtt_flags |= MQTT_FLAG_CONNECTED;
  complete_pending(state, MQTT_EVENT_TYPE_CONNECTED);

  // Setup the keep alive timer and enter main message processing loop
  etimer_set(&keepalive_timer, CLOCK_SECOND * state->connect_info->keepalive);
  while(1)
  {
    // Wait for something to happen: 
    //   new incoming data, 
    //   new outgoing data, 
    //   keep alive timer expired
    PSOCK_WAIT_UNTIL(&state->ps, PSOCK_NEWDATA(&state->ps) || 
                                 state->outbound_message != NULL ||
                                 etimer_expired(&keepalive_timer));

    // If there's a new message waiting to go out, then send it
    if(state->outbound_message != NULL)
    {
      PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
      state->outbound_message = NULL;

      // If it was a PUBLISH message with QoS-0 then tell the client it's done
      if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == 0)
        complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);

      // Reset the keepalive timer as we've just sent some data
      etimer_restart(&keepalive_timer);
      continue;
    }

    // If the keep-alive timer expired then prepare a ping for sending
    // and reset the timer
    if(etimer_expired(&keepalive_timer))
    {
      state->outbound_message = mqtt_msg_pingreq(&state->mqtt_connection);
      etimer_reset(&keepalive_timer);
      continue;
    }

    // If we get here we must have woken for new incoming data, 
    // read and process it.
    PSOCK_READBUF_LEN(&state->ps, 2);
    
    state->message_length_read = PSOCK_DATALEN(&state->ps);
    state->message_length = mqtt_get_total_length(state->in_buffer, state->message_length_read);

    msg_type = mqtt_get_type(state->in_buffer);
    msg_qos  = mqtt_get_qos(state->in_buffer);
    msg_id   = mqtt_get_id(state->in_buffer, state->in_buffer_length);
    switch(msg_type)
    {
      case MQTT_MSG_TYPE_SUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_SUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_UNSUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_UNSUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_PUBLISH:
        if(msg_qos == 1)
          state->outbound_message = mqtt_msg_puback(&state->mqtt_connection, msg_id);
        else if(msg_qos == 2)
          state->outbound_message = mqtt_msg_pubrec(&state->mqtt_connection, msg_id);

        deliver_publish(state, state->in_buffer, state->message_length_read);
        break;
      case MQTT_MSG_TYPE_PUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PUBREC:
        state->outbound_message = mqtt_msg_pubrel(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBREL:
        state->outbound_message = mqtt_msg_pubcomp(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBCOMP:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PINGREQ:
        state->outbound_message = mqtt_msg_pingresp(&state->mqtt_connection);
        break;
      case MQTT_MSG_TYPE_PINGRESP:
        // Ignore
        break;
    }

    // NOTE: this is done down here and not in the switch case above
    //       because the PSOCK_READBUF_LEN() won't work inside a switch
    //       statement due to the way protothreads resume.
    if(msg_type == MQTT_MSG_TYPE_PUBLISH)
    {
      uint16_t len;

      // adjust message_length and message_length_read so that
      // they only account for the publish data and not the rest of the 
      // message, this is done so that the offset passed with the
      // continuation event is the offset within the publish data and
      // not the offset within the message as a whole.
      len = state->message_length_read;
      mqtt_get_publish_data(state->in_buffer, &len);
      len = state->message_length_read - len;
      state->message_length -= len;
      state->message_length_read -= len;

      while(state->message_length_read < state->message_length)
      {
        PSOCK_READBUF_LEN(&state->ps, state->message_length - state->message_length_read);
        deliver_publish_continuation(state, state->message_length_read, state->in_buffer, PSOCK_DATALEN(&state->ps));
        state->message_length_read += PSOCK_DATALEN(&state->ps);
      }
    }
  }

  PSOCK_END(&state->ps);
}
Example #15
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(smtp_thread(void))
{
  PSOCK_BEGIN(&s.psock);

  PSOCK_READTO(&s.psock, ISO_nl);
   
  if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(2);
    PSOCK_EXIT(&s.psock);
  }
  
  PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
  PSOCK_SEND_STR(&s.psock, localhostname);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);

  PSOCK_READTO(&s.psock, ISO_nl);
  
  if(s.inputbuffer[0] != ISO_2) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(3);
    PSOCK_EXIT(&s.psock);
  }

  PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
  PSOCK_SEND_STR(&s.psock, s.from);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);

  PSOCK_READTO(&s.psock, ISO_nl);
  
  if(s.inputbuffer[0] != ISO_2) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(4);
    PSOCK_EXIT(&s.psock);
  }

  PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
  PSOCK_SEND_STR(&s.psock, s.to);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);

  PSOCK_READTO(&s.psock, ISO_nl);
  
  if(s.inputbuffer[0] != ISO_2) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(5);
    PSOCK_EXIT(&s.psock);
  }
  
  if(s.cc != 0) {
    PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
    PSOCK_SEND_STR(&s.psock, s.cc);
    PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);

    PSOCK_READTO(&s.psock, ISO_nl);
  
    if(s.inputbuffer[0] != ISO_2) {
      PSOCK_CLOSE(&s.psock);
      smtp_done(6);
      PSOCK_EXIT(&s.psock);
    }
  }
  
  PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
  
  PSOCK_READTO(&s.psock, ISO_nl);
  
  if(s.inputbuffer[0] != ISO_3) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(7);
    PSOCK_EXIT(&s.psock);
  }

  PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
  PSOCK_SEND_STR(&s.psock, s.to);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
  
  if(s.cc != 0) {
    PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
    PSOCK_SEND_STR(&s.psock, s.cc);
    PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
  }
  
  PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
  PSOCK_SEND_STR(&s.psock, s.from);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
  
  PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
  PSOCK_SEND_STR(&s.psock, s.subject);
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);

  PSOCK_SEND(&s.psock, s.msg, s.msglen);
  
  PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);

  PSOCK_READTO(&s.psock, ISO_nl);
  if(s.inputbuffer[0] != ISO_2) {
    PSOCK_CLOSE(&s.psock);
    smtp_done(8);
    PSOCK_EXIT(&s.psock);
  }

  PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
  smtp_done(SMTP_ERR_OK);
  PSOCK_END(&s.psock);
}
/*
 * 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);
}