All pastes #410570 Raw Edit

Anonymous

public c v1 · immutable
#410570 ·published 2007-03-26 14:28 UTC
rendered paste body
/* * This is a small example of how to write a TCP server using * Contiki's protosockets. It is a simple server that accepts one line * of text from the TCP connection, and echoes back the first 10 bytes * of the string, and then closes the connection. * * The server only handles one connection at a time. * */#include <string.h>/* * We include "contiki-net.h" to get all network definitions and * declarations. */#include "contiki-net.h"/* We copy all the include statements from the other file and hope for the best * because we don't know what we are doing */#include "contiki.h"#include "net/rime/trickle.h"#include "dev/button-sensor.h"#include "dev/leds.h"#include <stdio.h>/* * We define one protosocket since we've decided to only handle one * connection at a time. If we want to be able to handle more than one * connection at a time, each parallell connection needs its own * protosocket. */static struct psock ps;static int leds_inited_r = 0;static voidtrickle_recv(struct trickle_conn *c){  char *msg = (char*) rimebuf_dataptr();  printf("trickle message received '%s'\n", msg);  if(!leds_inited_r) { // hmmmm	  leds_init();	  leds_inited_r = 1;  }  int len = strlen(msg);  if(len>5) {	  msg+=4;	 if(strcmp("red", msg)==0)		 leds_toggle(LEDS_RED);	 else if(strcmp("blue", msg)==0)		 leds_toggle(LEDS_BLUE);	 else if(strcmp("green", msg)==0)		 leds_toggle(LEDS_GREEN);		   }  else if(strcmp("led", msg)==0) {	  leds_toggle(LEDS_ALL);  }}const static struct trickle_callbacks trickle_call = {trickle_recv};static struct trickle_conn trickle;/* * We must have somewhere to put incoming data, and we use a 10 byte * buffer for this purpose. */static char buffer[10];/*---------------------------------------------------------------------------*//* * A protosocket always requires a protothread. The protothread * contains the code that uses the protosocket. We define the * protothread here. */staticPT_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));  buffer[strlen(buffer)-1] = '\0';  rimebuf_copyfrom(buffer, PSOCK_DATALEN(p));  trickle_send(&trickle, TRICKLE_SECOND / 4);  PSOCK_SEND_STR(p, "Good bye!\r\n");  /*   * We close the protosocket.   */  PSOCK_CLOSE(p);  /*   * And end the protosocket's protothread.   */  PSOCK_END(p);}/*---------------------------------------------------------------------------*//* * We declare the process. */PROCESS(example_psock_server_process, "Example protosocket server");AUTOSTART_PROCESSES(&example_psock_server_process);//PROCESS(test_trickle_process, "TRICKLE test");/*---------------------------------------------------------------------------*//* * The definition of the process. */PROCESS_THREAD(example_psock_server_process, ev, data){  /*   * The process begins here.   */  PROCESS_BEGIN();  /*   * We start with setting up a listening TCP port. Note how we're   * using the HTONS() macro to convert the port number (1010) to   * network byte order as required by the tcp_listen() function.   */  tcp_listen(HTONS(1010));  trickle_open(&trickle, 128, &trickle_call);  /*   * We loop for ever, accepting new connections.   */  while(1) {    /*     * We wait until we get the first TCP/IP event, which probably     * comes because someone connected to us.     */    PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);    /*     * If a peer connected with us, we'll initialize the protosocket     * with PSOCK_INIT().     */    if(uip_connected()) {            /*       * The PSOCK_INIT() function initializes the protosocket and       * binds the input buffer to the protosocket.       */      PSOCK_INIT(&ps, buffer, sizeof(buffer));      /*       * We loop until the connection is aborted, closed, or times out.       */      while(!(uip_aborted() || uip_closed() || uip_timedout())) {	/*	 * We wait until we get a TCP/IP event. Remember that we	 * always need to wait for events inside a process, to let	 * other processes run while we are waiting.	 */	PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);	/*	 * Here is where the real work is taking place: we call the	 * handle_connection() protothread that we defined above. This	 * protothread uses the protosocket to receive the data that	 * we want it to.	 */	handle_connection(&ps);      }    }  }    trickle_close(&trickle);  /*   * We must always declare the end of a process.   */  PROCESS_END();}/*---------------------------------------------------------------------------*/