From b21d2494bc074731992c9c37374213b09b90b171 Mon Sep 17 00:00:00 2001 From: nifi Date: Tue, 8 Jun 2010 22:39:30 +0000 Subject: [PATCH] Added example using HTTP to control and be controlled. --- examples/ipv6/sky-websense/Makefile | 3 +- examples/ipv6/sky-websense/websense-remote.c | 174 ++++++++++++++++ examples/ipv6/sky-websense/wget.c | 201 +++++++++++++++++++ examples/ipv6/sky-websense/wget.h | 62 ++++++ 4 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 examples/ipv6/sky-websense/websense-remote.c create mode 100644 examples/ipv6/sky-websense/wget.c create mode 100644 examples/ipv6/sky-websense/wget.h diff --git a/examples/ipv6/sky-websense/Makefile b/examples/ipv6/sky-websense/Makefile index 19065ed43..2f5cd33b6 100644 --- a/examples/ipv6/sky-websense/Makefile +++ b/examples/ipv6/sky-websense/Makefile @@ -5,9 +5,10 @@ CONTIKI=../../.. WITH_UIP6=1 UIP_CONF_IPV6=1 -APPS += webserver +APPS += webserver webbrowser CFLAGS += -DPROJECT_CONF_H=\"project-rpl-web-conf.h\" +CONTIKI_SOURCEFILES += wget.c PROJECTDIRS += ../rpl-border-router PROJECT_SOURCEFILES += httpd-simple.c diff --git a/examples/ipv6/sky-websense/websense-remote.c b/examples/ipv6/sky-websense/websense-remote.c new file mode 100644 index 000000000..ca9d96b3c --- /dev/null +++ b/examples/ipv6/sky-websense/websense-remote.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: websense-remote.c,v 1.1 2010/06/08 22:39:30 nifi Exp $ + */ + +/** + * \file + * A simple example using HTTP to control and be controlled + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#include "contiki.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" +#include "wget.h" +#include "webserver-nogui.h" +#include "httpd-simple.h" +#include + +/* The address of the server to register the services for this node */ +#define SERVER "aaaa::1" + +/* This command registers two services (/0 and /1) to turn the leds on or off */ +#define REGISTER_COMMAND "/r?p=0&d=Turn%20off%20leds&p=1&d=Turn%20on%20leds" + +/* The address of the other node to control */ +#define OTHER_NODE "aaaa::212:7403:3:303" + +/* The commands to send to the other node */ +#define SET_LEDS_ON "/1" +#define SET_LEDS_OFF "/0" + +PROCESS(websense_remote_process, "Websense Remote"); + +AUTOSTART_PROCESSES(&websense_remote_process); + +/*---------------------------------------------------------------------------*/ +static const char *TOP = "Contiki Websense Remote\n"; +static const char *BOTTOM = "\n"; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_command(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, TOP); + + if(s->filename[1] == '0') { + /* Turn off leds */ + leds_off(LEDS_ALL); + SEND_STRING(&s->sout, "Turned off leds!"); + } else if(s->filename[1] == '1') { + /* Turn on leds */ + leds_on(LEDS_ALL); + SEND_STRING(&s->sout, "Turned on leds!"); + } else { + SEND_STRING(&s->sout, "Unknown command"); + } + + SEND_STRING(&s->sout, BOTTOM); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_simple_script_t +httpd_simple_get_script(const char *name) +{ + return handle_command; +} +/*---------------------------------------------------------------------------*/ +static void +wget_done(int status) +{ + switch(status) { + case WGET_OK: + printf("Command sent.\n"); + break; + case WGET_TIMEDOUT: + printf("Command timedout.\n"); + break; + case WGET_ABORTED: + printf("Connection aborted.\n"); + break; + case WGET_CONNECT_FAILED: + printf("Failed to connect.\n"); + break; + } +} +static const struct wget_callbacks callbacks = { + NULL, wget_done +}; +static void +send_command(const char *server, const char *command) +{ + int ret; + printf("Sending to [%s]: %s\n", server, command); + ret = wget(server, command, &callbacks); + if(ret != WGET_OK) { + if(ret == WGET_ALREADY_RUNNING) { + printf("Waiting for previous command to finish.\n"); + } else { + printf("Failed to send command: %u\n", ret); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(websense_remote_process, ev, data) +{ + static int mode; + static struct etimer timer; + + PROCESS_BEGIN(); + + mode = 0; + wget_init(); + process_start(&webserver_nogui_process, NULL); + + SENSORS_ACTIVATE(button_sensor); + + /* Give the node some time to join the network before registering + the available services. */ + etimer_set(&timer, CLOCK_SECOND * 30); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == sensors_event && data == &button_sensor) { + /* The button has been pressed. Send command to the other node. */ + if(mode) { + /* Turn on leds */ + send_command(OTHER_NODE, SET_LEDS_OFF); + } else { + send_command(OTHER_NODE, SET_LEDS_ON); + } + /* Alternate between the two commands */ + mode = !mode; + + } else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&timer)) { + printf("Registering services\n"); + send_command(SERVER, REGISTER_COMMAND); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/sky-websense/wget.c b/examples/ipv6/sky-websense/wget.c new file mode 100644 index 000000000..9f543ed85 --- /dev/null +++ b/examples/ipv6/sky-websense/wget.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: wget.c,v 1.1 2010/06/08 22:39:30 nifi Exp $ + */ + +/** + * \file + * A simple wget implementation + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#include "webclient.h" +#include "wget.h" +#include "dev/leds.h" + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +#define DEBUG_LEDS 0 +#undef LEDS_ON +#undef LEDS_OFF +#if DEBUG_LEDS +#define LEDS_ON(led) leds_on(led) +#define LEDS_OFF(led) leds_off(led) +#else +#define LEDS_ON(led) +#define LEDS_OFF(led) +#endif /* DEBUG */ + +static int fetch_running; + +#define STATS ((DEBUG) & DEBUG_PRINT) && 1 +#if STATS +static clock_time_t fetch_started; +static unsigned long fetch_counter; +#endif /* STATUS */ + +static const char *server; +static const char *file; +static const struct wget_callbacks *callbacks; + +PROCESS(wget_process, "wget"); + +/*---------------------------------------------------------------------------*/ +static void +call_done(int status) +{ + if(callbacks != NULL && callbacks->done != NULL) { + callbacks->done(status); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(wget_process, ev, data) +{ + PROCESS_BEGIN(); + + PRINTF("wget: fetching %s\n", file); +#if STATS + fetch_counter = 0; + fetch_started = clock_time(); +#endif /* STATS */ + LEDS_ON(LEDS_YELLOW); + if(webclient_get((char *)server, 80, (char *)file) == 0) { + PRINTF("wget: failed to connect\n"); + LEDS_OFF(LEDS_YELLOW); + fetch_running = 0; + call_done(WGET_CONNECT_FAILED); + } else { + while(fetch_running) { + PROCESS_WAIT_EVENT(); + if(ev == tcpip_event) { + webclient_appcall(data); + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +webclient_datahandler(char *data, u16_t len) +{ + if(len == 0) { +#if STATS + clock_time_t elapsed; + elapsed = clock_time() - fetch_started; + PRINTF("wget: recv %lu bytes during %lu sec (", + fetch_counter, (elapsed / CLOCK_SECOND)); +#if CLOCK_SECOND == 128 + PRINTF("%lu.%02lus, ", (unsigned long) elapsed >> 7, + (unsigned long)((elapsed & 127) * 100) / 128); + PRINTF("%lu byte/sec ", (fetch_counter * 128L) / elapsed); +#endif + PRINTF("%lu tick): ", (unsigned long) elapsed); + if(elapsed > CLOCK_SECOND) { + PRINTF("%lu", fetch_counter / (elapsed / CLOCK_SECOND)); + } else { + PRINTF("-"); + } + PRINTF(" byte/sec\n"); +#else /* STATS */ + PRINTF("wget: complete\n"); +#endif /* STATS */ + + fetch_running = 0; + call_done(WGET_OK); + LEDS_OFF(LEDS_RED|LEDS_YELLOW); + } else { +#if STATS + fetch_counter += len; +#endif /* STATS */ + if(callbacks != NULL && callbacks->data != NULL) { + /* Assume the buffer is large enough for ending zero */ + data[len] = '\0'; + callbacks->data(data, len); + } + } +} +/*---------------------------------------------------------------------------*/ +void +webclient_connected(void) +{ + LEDS_OFF(LEDS_YELLOW); + LEDS_ON(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +void +webclient_timedout(void) +{ + PRINTF("wget: timedout\n"); + LEDS_OFF(LEDS_RED|LEDS_YELLOW); + fetch_running = 0; + call_done(WGET_TIMEDOUT); +} +/*---------------------------------------------------------------------------*/ +void +webclient_aborted(void) +{ + PRINTF("wget: aborted\n"); + LEDS_OFF(LEDS_RED|LEDS_YELLOW); + fetch_running = 0; + call_done(WGET_ABORTED); +} +/*---------------------------------------------------------------------------*/ +void +webclient_closed(void) +{ + PRINTF("wget: closed\n"); + fetch_running = 0; + LEDS_OFF(LEDS_RED|LEDS_YELLOW); + call_done(WGET_CLOSED); +} +/*---------------------------------------------------------------------------*/ +void +wget_init(void) +{ + webclient_init(); +} +/*---------------------------------------------------------------------------*/ +int +wget(const char *s, const char *f, const struct wget_callbacks *c) +{ + if(fetch_running) { + return WGET_ALREADY_RUNNING; + } + fetch_running = 1; + server = s; + file = f; + callbacks = c; + process_start(&wget_process, NULL); + return WGET_OK; +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/sky-websense/wget.h b/examples/ipv6/sky-websense/wget.h new file mode 100644 index 000000000..9fb3c2f8f --- /dev/null +++ b/examples/ipv6/sky-websense/wget.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: wget.h,v 1.1 2010/06/08 22:39:30 nifi Exp $ + */ + +/** + * \file + * A simple wget implementation + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef __WGET_H__ +#define __WGET_H__ + +#include "contiki.h" + +struct wget_callbacks { + void (* data)(const char *data, uint16_t len); + void (* done)(int status); +}; + +void wget_init(void); +int wget(const char *server, const char *file, const struct wget_callbacks *c); + +enum { + WGET_OK, + WGET_ALREADY_RUNNING, + WGET_TIMEDOUT, + WGET_ABORTED, + WGET_CONNECT_FAILED, + WGET_CLOSED +}; + +#endif /* __WGET_H__ */