Remove the JSON-WS example

Does not seem to build for any platforms.
This commit is contained in:
George Oikonomou 2017-10-28 19:57:21 +01:00
parent 0fdd1015e2
commit f50671ce37
9 changed files with 0 additions and 1421 deletions

View File

@ -1,24 +0,0 @@
CONTIKI=../../..
PROJECT_SOURCEFILES += json-ws.c
ifdef WITH_COSM
CFLAGS += -DWITH_COSM=1
endif
ifdef WITH_UDP
CFLAGS += -DWITH_UDP=1
PROJECT_SOURCEFILES += json-ws-udp.c
endif
MODULES += os/lib/json os/net/app-layer/httpd-ws
ifeq ($(TARGET),)
-include Makefile.target
endif
ifneq ($(TARGET),)
all: websense-$(TARGET)
endif
include $(CONTIKI)/Makefile.include

View File

@ -1,109 +0,0 @@
JSON ws
=======
Short description on how to set-up a sensor network for global IPv6 addresses.
NOTE: this assumes that you do not have a native IPv6 connection.
You will need:
- PC with Ubuntu (Linux) - 11 or 12 versions
- A node for the RPL-Border-Router (examples/ipv6/rpl-border-router)
- A node for the json webservice (examples/ipv6/json-ws)
Set-up IPv6 tunnel and Border Router
------------------------------------
1. Ensure that you have gogo6c installed.
sudo apt-get install gogoc
2. Register an account at gogo6 and Freenet6 (http://www.gogo6.com).
The account at Freenet6 is needed by the gogo6c client.
3. Edit the gogoc.conf and set your own Freenet6 user and password by
changing the lines with "userid" and "passwd".
4. Start gogoc at command line
cd contiki/examples/ipv6/json-ws
sudo gogoc -f gogoc.conf -n
This will print your prefix - TSP_PREFIX. In my case
TSP_PREFIX=2001:05c0:1517:e400 (prefixlen is 56).
5. Connect one of the nodes to the PC (via USB or serial) and program
it with the RPL-border-router (assumes Z1 node).
cd contiki/examples/ipv6/rpl-border-router
make DEFINES=DEFINES=NETSTACK_RDC=nullrdc_driver,CSMA_CONF_802154_AUTOACK=1 TARGET=z1 border-router.upload
6. Run tunslip6 which will forward IP from the RPL network to the IPv6 tunnel
(and to the Internet).
cd contiki/examples/ipv6/rpl-border-router
make connect-router PREFIX=<TSP_PREFIX>::1/64
When you start this you should get a printout from the border-router
which give you the IPv6 address of it.
Server IPv6 addresses:
2001:05c0:1517:e400:c30c::10a
fe80::c30c:0:0:10a
7. Browse using Mozilla Firefox (or any other browser) to the IPv6 address
given by the border router. This will show you the list of other nodes
connected to the RPL network.
http://[2001:05c0:1517:e400:c30c::10a]/
NOTE: this is a global IPv6 address so it should also be reachable from
any machine on the Internet.
Configuration of COSM submission
--------------------------------
1. Register a COSM account at https://cosm.com/
Set-up a feed and create an API key for the feed.
2. Program the sensor node with (assumes Z1)
cd contiki/examples/ipv6/json-ws
make websense-z1.upload WITH_COSM=1 TARGET=z1
3. Check the IPv6 address of the node via the RPL-border router or by looking
at printouts when booting (make login TARGET=z1)
4. You need to configure the node to push data to the COSM feed and this can be
done in several ways. For convenience a Python script is included that
pushes the configuration to the nodes.
Edit the file 'setcosm.py' and replace "<your-key>" and "<your-feed>" with
your COSM API key and COSM feed id. You can then use this Python script to
configure your nodes.
This is an example that configures the node with IP address
2001:05c0:1517:e400:c30c::10b to push data to the COSM feed with stream 1:
cd contiki/examples/ipv6/json-ws
./setcosm.py [2001:05c0:1517:e400:c30c::10b] 1
Another way to configure the nodes is to use a REST add-on for the web
browser to post a COSM configuration to the node. "REST Client" for Mozilla
Firefox is an example of such add-on.
POST a JSON expression to your node with the following data: This assumes
that you have the feed with id 55180 and want to post to stream 1 in that
feed. The field 'appdata' should be set to the API key you created at the
COSM web site for the feed.
{
"host":"[2001:470:1f10:333::2]",
"port":80,
"path":"/v2/feeds/55180/datastreams/1",
"appdata":"<insert your COSM API key>",
"interval":120,
"proto":"cosm"
}
This will configure the node to periodically push temperature data every
other minute. You can use GET to retrieve the data to se that the node has
been successfully configured (the COSM API key will be visualized as a
number of stars).

View File

@ -1,351 +0,0 @@
#-----------------------------------------------------------------------------
# $Id: gogoc.conf.in,v 1.1 2009/11/20 16:53:12 jasminko Exp $
#-----------------------------------------------------------------------------
########################## READ ME! ################################
#
# Welcome to the gogoCLIENT configuration file.
# In order to use the client, you need to modify the 'userid', 'passwd' and
# 'server' parameters below depending on which of these situations applies:
#
# 1. If you created a Freenet6 account, enter your userid and password below.
# Change the server name to "broker.freenet6.net" and auth_method to 'any'.
# 2. If you would like to use Freenet6 without creating an account,
# do not make any modifications and close this file.
# 3. If this software was provided by your ISP, enter the userid, password and
# server name provided by your ISP below.
#
########################## BASIC CONFIGURATION ################################
#
# User Identification and Password:
# Specify your user name and password as provided by your ISP or Freenet6.
# If you plan to connect anonymously, leave these values empty.
# NOTE: Change auth_method option if you are using a username/password.
#
# userid=<your_userid>
# passwd=<your_password>
#
userid=<change to your userid>
passwd=<change to your password>
#
# gogoSERVER:
# Specify a gogoSERVER name or IP address (provided by your ISP or
# Freenet6). An optional port number can be added; the default port number
# is 3653.
#
# Examples:
# server=hostname # FQDN
# server=A.B.C.D # IPv4 address
# server=[X:X::X:X] # IPv6 address
# server=hostname:port_number
# server=A.B.C.D:port_number
# server=[X:X::X:X]:port_number
#
# Freenet6 account holders should enter authenticated.freenet6.net,
# otherwise use anonymous.freenet6.net.
# Your ISP may provide you with a different server name.
#
#server=anonymous.freenet6.net
#server=authenticated.freenet6.net
server=amsterdam.freenet6.net
#
# Authentication Method:
#
# auth_method=<{anonymous}|{any|passdss-3des-1|digest-md5|plain}>
#
# anonymous: Sends no username or password
#
# any: The most secure method will be used.
# passdss-3des-1: The password is sent encrypted.
# digest-md5: The password is sent encrypted.
# plain: Both username and password are sent as plain text.
#
# Recommended values:
# - any: If you are authenticating a username / password.
# - anonymous: If you are connecting anonymously.
#
#auth_method=anonymous
auth_method=any
########################## ROUTING CONFIGURATION ##############################
# Use these parameters when you wish the client to act as a router and provide
# IPv6 connectivity to IPv6-capable devices on your network.
#
# Local Host Type:
# Change this value to 'router' to enable IPv6 advertisements.
#
# host_type=<host|router>
#
host_type=router
#host
#
# Prefix Length:
# Length of the requested prefix. Valid values range between 0 and 64 when
# using V6*V4 tunnel modes, and between 0 and 32 when using V4V6 tunnel mode.
#
# prefixlen=<integer>
#
prefixlen=64
#
# Advertisement Interface Prefix:
# Name of the interface that will be configured to send router advertisements.
# This is an interface index on Windows (ex: 4) and a name on Linux
# and BSD (ex: eth1 or fxp1).
#
# if_prefix=<interface name>
#
if_prefix=tun0
#
# DNS Server:
# A DNS server list to which the reverse prefix will be delegated. Servers
# are separated by the colon(:) delimiter.
#
# Example: dns_server=ns1.domain:ns2.domain:ns3.domain
#
dns_server=
######################### ADVANCED CONFIGURATION ##############################
#
# gogoCLIENT Installation Directory:
# Directory where the gogoCLIENT will be installed. This value has been
# set during installation.
#
gogoc_dir=
#
# Auto-Retry Connect, Retry Delay and Max Retry Delay:
# When auto_retry_connect=yes, the gogoCLIENT will attempt to reconnect
# after a disconnection occurred. The time to wait is 'retry_delay' and that
# delay is doubled at every 3 failed consecutive reconnection attempt.
# However, the wait delay will never exceed retry_delay_max.
#
#
# auto_retry_connect=<yes|no>
# retry_delay=<integer: 0..3600>
# retry_delay_max=<integer: 0..3600>
#
# Recommended values: "yes", 30, 300
#
auto_retry_connect=yes
retry_delay=30
retry_delay_max=300
#
# Keepalive Feature and Message Interval:
# Indicates if and how often the client will send data to keep the tunnel
# active.
#
# keepalive=<yes|no>
# keepalive_interval=<integer>
#
# Recommended values: "yes" and 30
#
keepalive=yes
keepalive_interval=30
#
# Tunnel Encapsulation Mode:
# v6v4: IPv6-in-IPv4 tunnel.
# v6udpv4: IPv6-in-UDP-in-IPv4 tunnel (for clients behind a NAT).
# v6anyv4: Lets the broker choose the best mode for IPv6 tunnel.
# v4v6: IPv4-in-IPv6 tunnel.
#
# Recommended value: v6anyv4
#
tunnel_mode=v6anyv4
#
# Tunnel Interface Name:
# The interface name assigned to the tunnel. This value is O/S dependent.
#
# if_tunnel_v6v4 is the tunnel interface name for v6v4 encapsulation mode
# if_tunnel_v6udpv4 is the tunnel interface name for v6udpv4 encapsulate mode
# if_tunnel_v4v6 is the tunnel interface name for v4v6 encapsulation mode
#
# Default values are set during installation.
#
if_tunnel_v6v4=sit1
if_tunnel_v6udpv4=sit
if_tunnel_v4v6=sit0
#
# Local IP Address of the Client:
# Allows you to set a specific address as the local tunnel endpoint.
#
# client_v4=<auto|A.B.C.D (valid ipv4 address)>
# client_v6=<auto|X:X::X:X (valid ipv6 address)>
# auto: The gogoCLIENT will find the local IP address endpoint.
#
# Recommended value: auto
#
client_v4=auto
client_v6=auto
#
# Script Name:
# File name of the script to run to install the tunnel interface. The
# scripts are located in the template directory under the client
# installation directory.
#
# template=<checktunnel|freebsd|netbsd|openbsd|linux|windows|darwin|cisco|solaris>
#
# Default value is set during installation.
#
template=linux
#
# Proxy client:
# Indicates that this client will request a tunnel for another endpoint,
# such as a Cisco router.
#
# proxy_client=<yes|no>
#
# NOTE: NAT traversal is not possible in proxy mode.
#
proxy_client=no
############################ BROKER REDIRECTION ###############################
#
# Broker List File Name:
# The 'broker_list' directive specifies the filename where the broker
# list received during broker redirection will be saved.
#
# broker_list=<file_name>
#
broker_list=/var/lib/gogoc/tsp-broker-list.txt
#
# Last Server Used File Name:
# The 'last_server' directive specifies the filename where the address of
# the last broker to which a connection was successfully established will
# be saved.
#
# last_server=<file_name>
#
last_server=/var/lib/gogoc/tsp-last-server.txt
#
# Always Use Last Known Working Server:
# The value of the 'always_use_same_server' directive determines whether the
# client should always try to connect to the broker found in the
# 'last_server' directive filename.
#
# always_use_same_server=<yes|no>
#
always_use_same_server=no
#################################### LOGGING ##################################
#
# Log Verbosity Configuration:
# The format is 'log_<destination>=level', where possible values for
# 'destination' are:
#
# - console (logging to the console [AKA stdout])
# - stderr (logging to standard error)
# - file (logging to a file)
# - syslog (logging to syslog [Unix only])
#
# and 'level' is a digit between 0 and 3. A 'level' value of 0 disables
# logging to the destination, while values 1 to 3 request increasing levels
# of log verbosity and detail. If 'level' is not specified, a value of 1 is
# assumed.
#
# Example:
# log_file=3 (Maximal logging to a file)
# log_stderr=0 (Logging to standard error disabled)
# log_console= (Minimal logging to the console)
#
# - Default configuration on Windows platforms:
#
# log_console=0
# log_stderr=0
# log_file=1
#
# - Default configuration on Unix platforms:
#
# log_console=0
# log_stderr=1
# log_file=0
# log_syslog=0
#
log_console=3
log_stderr=0
#log_file=
#log_syslog=
#
# Log File Name:
# When logging to file is requested using the 'log_file' directive, the name
# and path of the file to use may be specified using this directive.
#
# log_filename=<file_name>
#
log_filename=/var/log/gogoc/gogoc.log
#
# Log File Rotation:
# When logging to file is requested using the 'log_file' directive, log file
# rotation may be enabled. When enabled, the contents of the log file will
# be moved to a backup file just before it reaches the maximum log file size
# specified via this directive.
#
# The name of the backup file is the name of the original log file with
# '.<timestamp>' inserted before the file extension. If the file does not
# have an extension, '.<timestamp>' is appended to the name of the original
# log file. The timestamp specifies when the rotation occurred.
#
# After the contents of the log file have been moved to the backup file, the
# original file is cleared, and logging resumes at the beginning of the file.
#
# log_rotation=<yes|no>
#
log_rotation=yes
#
# Log File Rotation Size:
# The 'log_rotation_size' directive specifies the maximum size a log file may
# reach before rotation occurs, if enabled. The value is expressed in
# kilobytes.
#
# log_rotation_size=<16|32|128|1024>
#
log_rotation_size=32
#
# Deletion of rotated log files:
# The 'log_rotation_delete' directive specifies that no log backup will be
# kept. When rotation occurs, the file is immediately wiped out and a new
# log file is started.
#
# log_rotation_delete=<yes|no>
#
log_rotation_delete=no
#
# Syslog Logging Facility [Unix Only]:
# When logging to syslog is requested using the 'log_syslog' directive, the
# facility to use may be specified using this directive.
#
# syslog_facility=<USER|LOCAL[0-7]>
#
syslog_facility=USER
# end of gogoc.conf
#------------------------------------------------------------------------------

View File

@ -1,151 +0,0 @@
/*
* Copyright (c) 2011-2012, 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.
*
*/
/**
* \file
* Code for sending the JSON data as a UDP packet
* Specify proto = "udp", port = <server-udp-port>
* host = <ipv6-server-address>
*
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "contiki.h"
#include "httpd-ws.h"
#include "jsontree.h"
#include "jsonparse.h"
#include "json-ws.h"
#include <stdio.h>
#include <string.h>
#define DEBUG DEBUG_FULL
#include "net/ipv6/uip-debug.h"
static struct uip_udp_conn *client_conn;
static uip_ipaddr_t server_ipaddr;
static uint16_t server_port;
#define SENDER_PORT 8181
/*---------------------------------------------------------------------------*/
int
json_ws_udp_setup(const char *host, uint16_t port)
{
server_port = port;
if(client_conn != NULL) {
/* this should be a macro uip_udp_conn_free() or something */
uip_udp_remove(client_conn);
client_conn = NULL;
}
uip_ipaddr_t *ipaddr;
/* First check if the host is an IP address. */
ipaddr = &server_ipaddr;
if(uiplib_ipaddrconv(host, &server_ipaddr) == 0) {
#if 0 && UIP_UDP
if(resolv_lookup(host, &ipaddr) != RESOLV_STATUS_CACHED) {
return 0;
}
#else /* UIP_UDP */
return 0;
#endif /* UIP_UDP */
}
/* new connection with remote host */
client_conn = udp_new(&server_ipaddr, UIP_HTONS(server_port), NULL);
udp_bind(client_conn, UIP_HTONS(SENDER_PORT));
PRINTF("Created a connection with the server ");
PRINT6ADDR(&client_conn->ripaddr);
PRINTF(" local/remote port %u/%u\n",
UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
return 1;
}
/*---------------------------------------------------------------------------*/
static char *udp_buf;
static int pos;
static int size;
static int
putchar_udp(int c)
{
if(udp_buf != NULL && pos <= size) {
udp_buf[pos++] = c;
return c;
}
return 0;
}
/*---------------------------------------------------------------------------*/
void
json_ws_udp_send(struct jsontree_value *tree, const char *path)
{
struct jsontree_context json;
/* maxsize = 70 bytes */
char buf[70];
udp_buf = buf;
/* reset state and set max-size */
/* NOTE: packet will be truncated at 70 bytes */
pos = 0;
size = sizeof(buf);
json.values[0] = (struct json_value *)tree;
jsontree_reset(&json);
find_json_path(&json, path);
json.path = json.depth;
json.putchar = putchar_udp;
while(jsontree_print_next(&json) && json.path <= json.depth);
printf("Real UDP size: %d\n", pos);
buf[pos] = 0;
uip_udp_packet_sendto(client_conn, &buf, pos,
&server_ipaddr, UIP_HTONS(server_port));
}
/*---------------------------------------------------------------------------*/
void
json_ws_udp_debug(char *string)
{
int len;
len = strlen(string);
uip_udp_packet_sendto(client_conn, string, len,
&server_ipaddr, UIP_HTONS(server_port));
}
/*---------------------------------------------------------------------------*/

View File

@ -1,521 +0,0 @@
/*
* Copyright (c) 2011-2012, 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* JSON webservice util
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*/
#include "contiki.h"
#if PLATFORM_HAS_LEDS
#include "dev/leds.h"
#endif
#include "httpd-ws.h"
#include "jsontree.h"
#include "jsonparse.h"
#include "json-ws.h"
#include <stdio.h>
#include <string.h>
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#ifdef JSON_WS_CONF_CALLBACK_PROTO
#define CALLBACK_PROTO JSON_WS_CONF_CALLBACK_PROTO
#else
#define CALLBACK_PROTO "http"
#endif /* JSON_WS_CONF_CALLBACK_PROTO */
#ifdef JSON_WS_CONF_CALLBACK_PORT
#define CALLBACK_PORT JSON_WS_CONF_CALLBACK_PORT
#else
#define CALLBACK_PORT 8080;
#endif /* JSON_WS_CONF_CALLBACK_PORT */
/* Predefined startup-send interval */
#ifdef JSON_WS_CONF_CALLBACK_INTERVAL
#define SEND_INTERVAL JSON_WS_CONF_CALLBACK_INTERVAL
#else
#define SEND_INTERVAL 120
#endif
static const char http_content_type_json[] = "application/json";
/* Maximum 40 chars in host name?: 5 x 8 */
static char callback_host[40] = "[fd00::1]";
static uint16_t callback_port = CALLBACK_PORT;
static uint16_t callback_interval = SEND_INTERVAL;
static char callback_path[80] = "/debug/";
static char callback_appdata[80] = "";
static char callback_proto[8] = CALLBACK_PROTO;
static const char *callback_json_path = NULL;
static struct jsontree_object *tree;
static struct ctimer periodic_timer;
long json_time_offset = 0;
/* support for submitting to cosm */
#if WITH_COSM
extern struct jsontree_callback cosm_value_callback;
JSONTREE_OBJECT_EXT(cosm_tree,
JSONTREE_PAIR("current_value", &cosm_value_callback));
#endif /* WITH_COSM */
static void periodic(void *ptr);
/*---------------------------------------------------------------------------*/
static void
json_copy_string(struct jsonparse_state *parser, char *string, int len)
{
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, string, len);
}
/*---------------------------------------------------------------------------*/
static int
cfg_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
if(strncmp(path, "host", 4) == 0) {
jsontree_write_string(js_ctx, callback_host);
} else if(strncmp(path, "port", 4) == 0) {
jsontree_write_int(js_ctx, callback_port);
} else if(strncmp(path, "interval", 8) == 0) {
jsontree_write_int(js_ctx, callback_interval);
} else if(strncmp(path, "path", 4) == 0) {
jsontree_write_string(js_ctx, callback_path);
} else if(strncmp(path, "appdata", 7) == 0) {
jsontree_write_string(js_ctx, callback_appdata[0] == '\0' ? "" : "***");
} else if(strncmp(path, "proto", 5) == 0) {
jsontree_write_string(js_ctx, callback_proto);
}
return 0;
}
static int
cfg_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
int update = 0;
while((type = jsonparse_next(parser)) != 0) {
if(type == JSON_TYPE_PAIR_NAME) {
if(jsonparse_strcmp_value(parser, "host") == 0) {
json_copy_string(parser, callback_host, sizeof(callback_host));
update++;
} else if(jsonparse_strcmp_value(parser, "path") == 0) {
json_copy_string(parser, callback_path, sizeof(callback_path));
update++;
} else if(jsonparse_strcmp_value(parser, "appdata") == 0) {
json_copy_string(parser, callback_appdata, sizeof(callback_appdata));
update++;
} else if(jsonparse_strcmp_value(parser, "proto") == 0) {
json_copy_string(parser, callback_proto, sizeof(callback_proto));
update++;
} else if(jsonparse_strcmp_value(parser, "port") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
callback_port = jsonparse_get_value_as_int(parser);
if(callback_port == 0) {
callback_port = CALLBACK_PORT;
}
update++;
} else if(jsonparse_strcmp_value(parser, "interval") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
callback_interval = jsonparse_get_value_as_int(parser);
if(callback_interval == 0) {
callback_interval = SEND_INTERVAL;
}
update++;
}
}
}
if(update && callback_json_path != NULL) {
#if WITH_UDP
if(strncmp(callback_proto, "udp", 3) == 0) {
json_ws_udp_setup(callback_host, callback_port);
}
#endif
ctimer_set(&periodic_timer, CLOCK_SECOND * callback_interval,
periodic, NULL);
}
return 0;
}
static struct jsontree_callback cfg_callback =
JSONTREE_CALLBACK(cfg_get, cfg_set);
JSONTREE_OBJECT_EXT(json_subscribe_callback,
JSONTREE_PAIR("host", &cfg_callback),
JSONTREE_PAIR("port", &cfg_callback),
JSONTREE_PAIR("path", &cfg_callback),
JSONTREE_PAIR("appdata", &cfg_callback),
JSONTREE_PAIR("proto", &cfg_callback),
JSONTREE_PAIR("interval", &cfg_callback));
/*---------------------------------------------------------------------------*/
static int
time_get(struct jsontree_context *js_ctx)
{
/* unix time */
char buf[20];
unsigned long time = json_time_offset + clock_seconds();
snprintf(buf, 20, "%lu", time);
jsontree_write_atom(js_ctx, buf);
return 0;
}
static int
time_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
unsigned long time;
while((type = jsonparse_next(parser)) != 0) {
if(type == JSON_TYPE_PAIR_NAME) {
if(jsonparse_strcmp_value(parser, "time") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
time = jsonparse_get_value_as_long(parser);
json_time_offset = time - clock_seconds();
}
}
}
return 0;
}
struct jsontree_callback json_time_callback =
JSONTREE_CALLBACK(time_get, time_set);
/*---------------------------------------------------------------------------*/
#if PLATFORM_HAS_LEDS
#include "dev/leds.h"
static int
ws_leds_get(struct jsontree_context *js_ctx)
{
char buf[4];
unsigned char leds = leds_get();
snprintf(buf, 4, "%u", leds);
jsontree_write_atom(js_ctx, buf);
return 0;
}
static int
ws_leds_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type, old_leds, new_leds;
while((type = jsonparse_next(parser)) != 0) {
if(type == JSON_TYPE_PAIR_NAME) {
if(jsonparse_strcmp_value(parser, "leds") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
new_leds = jsonparse_get_value_as_int(parser);
old_leds = leds_get();
leds_on(~old_leds & new_leds);
leds_off(old_leds & ~new_leds);
}
}
}
return 0;
}
struct jsontree_callback json_leds_callback =
JSONTREE_CALLBACK(ws_leds_get, ws_leds_set);
#endif /* PLATFORM_HAS_LEDS */
/*---------------------------------------------------------------------------*/
static struct httpd_ws_state *json_putchar_context;
static int
json_putchar(int c)
{
if(json_putchar_context != NULL &&
json_putchar_context->outbuf_pos < HTTPD_OUTBUF_SIZE) {
json_putchar_context->outbuf[json_putchar_context->outbuf_pos++] = c;
return c;
}
return 0;
}
static int putchar_size = 0;
static int
json_putchar_count(int c)
{
putchar_size++;
return c;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_values(struct httpd_ws_state *s))
{
json_putchar_context = s;
PSOCK_BEGIN(&s->sout);
s->json.putchar = json_putchar;
s->outbuf_pos = 0;
if(s->json.values[0] == NULL) {
/* Nothing to do */
} else if(s->request_type == HTTPD_WS_POST &&
s->state == HTTPD_WS_STATE_OUTPUT) {
/* Set value */
struct jsontree_value *v;
struct jsontree_callback *c;
while((v = jsontree_find_next(&s->json, JSON_TYPE_CALLBACK)) != NULL) {
c = (struct jsontree_callback *)v;
if(c->set != NULL) {
struct jsonparse_state js;
jsonparse_setup(&js, s->inputbuf, s->content_len);
c->set(&s->json, &js);
}
}
memcpy(s->outbuf, "{\"Status\":\"OK\"}", 15);
s->outbuf_pos = 15;
} else {
/* Get value */
while(jsontree_print_next(&s->json) && s->json.path <= s->json.depth) {
if(s->outbuf_pos >= UIP_TCP_MSS) {
SEND_STRING(&s->sout, s->outbuf, UIP_TCP_MSS);
s->outbuf_pos -= UIP_TCP_MSS;
if(s->outbuf_pos > 0) {
memcpy(s->outbuf, &s->outbuf[UIP_TCP_MSS], s->outbuf_pos);
}
}
}
}
if(s->outbuf_pos > 0) {
SEND_STRING(&s->sout, s->outbuf, s->outbuf_pos);
s->outbuf_pos = 0;
}
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
struct jsontree_value *
find_json_path(struct jsontree_context *json, const char *path)
{
struct jsontree_value *v;
const char *start;
const char *end;
int len;
v = json->values[0];
start = path;
do {
end = strchr(start, '/');
if(end == start) {
break;
}
if(end != NULL) {
len = end - start;
end++;
} else {
len = strlen(start);
}
if(v->type != JSON_TYPE_OBJECT) {
v = NULL;
} else {
struct jsontree_object *o;
int i;
o = (struct jsontree_object *)v;
v = NULL;
for(i = 0; i < o->count; i++) {
if(strncmp(start, o->pairs[i].name, len) == 0) {
v = o->pairs[i].value;
json->index[json->depth] = i;
json->depth++;
json->values[json->depth] = v;
json->index[json->depth] = 0;
break;
}
}
}
start = end;
} while(end != NULL && *end != '\0' && v != NULL);
json->callback_state = 0;
return v;
}
/*---------------------------------------------------------------------------*/
static int
calculate_json_size(const char *path, struct jsontree_value *v)
{
/* check size of JSON expression */
struct jsontree_context json;
json.values[0] = (v == NULL) ? (struct jsontree_value *)tree : v;
jsontree_reset(&json);
if(path != NULL) {
find_json_path(&json, path);
}
json.path = json.depth;
json.putchar = json_putchar_count;
putchar_size = 0;
while(jsontree_print_next(&json) && json.path <= json.depth);
return putchar_size;
}
/*---------------------------------------------------------------------------*/
httpd_ws_script_t
httpd_ws_get_script(struct httpd_ws_state *s)
{
struct jsontree_value *v;
s->json.values[0] = v = (struct jsontree_value *)tree;
jsontree_reset(&s->json);
if(s->filename[1] == '\0') {
/* Default page: show full JSON tree. */
} else {
v = find_json_path(&s->json, &s->filename[1]);
}
if(v != NULL) {
s->json.path = s->json.depth;
s->content_type = http_content_type_json;
return send_values;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
#if JSON_POST_EXTRA_HEADER || WITH_COSM
static int
output_headers(struct httpd_ws_state *s, char *buffer, int buffer_size,
int index)
{
if(index == 0) {
#ifdef JSON_POST_EXTRA_HEADER
return snprintf(buffer, buffer_size, "%s\r\n", JSON_POST_EXTRA_HEADER);
} else if(index == 1) {
#endif
#if WITH_COSM
if(strncmp(callback_proto, "cosm", 4) == 0 && callback_appdata[0] != '\0') {
return snprintf(buffer, buffer_size, "X-PachubeApiKey:%s\r\n",
callback_appdata);
}
#endif
}
return 0;
}
#endif /* JSON_POST_EXTRA_HEADER || WITH_COSM */
/*---------------------------------------------------------------------------*/
static void
periodic(void *ptr)
{
struct httpd_ws_state *s;
int callback_size;
if(callback_json_path != NULL && strlen(callback_host) > 2) {
ctimer_restart(&periodic_timer);
if(strncmp(callback_proto, "http", 4) == 0) {
callback_size = calculate_json_size(callback_json_path, NULL);
s = httpd_ws_request(HTTPD_WS_POST, callback_host, NULL, callback_port,
callback_path, http_content_type_json,
callback_size, send_values);
if(s != NULL) {
PRINTF("PERIODIC POST %s\n", callback_json_path);
#if JSON_POST_EXTRA_HEADER
s->output_extra_headers = output_headers;
#endif
s->json.values[0] = (struct jsontree_value *)tree;
jsontree_reset(&s->json);
find_json_path(&s->json, callback_json_path);
s->json.path = s->json.depth;
} else {
PRINTF("PERIODIC CALLBACK FAILED\n");
}
#if WITH_COSM
} else if(strncmp(callback_proto, "cosm", 4) == 0) {
callback_size = calculate_json_size(NULL, (struct jsontree_value *)
&cosm_tree);
/* printf("JSON Size:%d\n", callback_size); */
s = httpd_ws_request(HTTPD_WS_PUT, callback_host, "api.pachube.com",
callback_port, callback_path,
http_content_type_json, callback_size, send_values);
/* host = cosm host */
/* path => path to datastream / data point */
s->output_extra_headers = output_headers;
s->json.values[0] = (struct jsontree_value *)&cosm_tree;
jsontree_reset(&s->json);
s->json.path = 0;
PRINTF("PERIODIC cosm callback: %d\n", callback_size);
#endif /* WITH_COSM */
}
#if WITH_UDP
else {
callback_size = calculate_json_size(callback_json_path, NULL);
PRINTF("PERIODIC UDP size: %d\n", callback_size);
json_ws_udp_send(tree, callback_json_path);
}
#endif /* WITH_UDP */
} else {
printf("PERIODIC CALLBACK - nothing todo\n");
}
}
/*---------------------------------------------------------------------------*/
void
json_ws_init(struct jsontree_object *json)
{
PRINTF("JSON INIT (callback %s every %u seconds)\n",
CALLBACK_PROTO, SEND_INTERVAL);
tree = json;
ctimer_set(&periodic_timer, CLOCK_SECOND * SEND_INTERVAL, periodic, NULL);
process_start(&httpd_ws_process, NULL);
#if WITH_UDP
if(strncmp(callback_proto, "udp", 3) == 0) {
json_ws_udp_setup(callback_host, callback_port);
}
#endif /* WITH_UDP */
}
/*---------------------------------------------------------------------------*/
void
json_ws_set_callback(const char *path)
{
callback_json_path = path;
ctimer_restart(&periodic_timer);
}
/*---------------------------------------------------------------------------*/

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2011-2012, 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* JSON webservice util
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*/
#ifndef JSON_WS_H_
#define JSON_WS_H_
#include "jsontree.h"
void json_ws_init(struct jsontree_object *json);
void json_ws_set_callback(const char *json_path);
int json_ws_udp_setup(const char *host, uint16_t port);
extern struct jsontree_object json_subscribe_callback;
extern struct jsontree_callback json_time_callback;
#if PLATFORM_HAS_LEDS
extern struct jsontree_callback json_leds_callback;
#endif
extern struct jsontree_object cosm_tree;
#endif /* JSON_WS_H_ */

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2012, 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.
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#include "jsontree.h"
#define HTTPD_WS_CONF_USER_STATE struct jsontree_context json
/* #define JSON_WS_CONF_CALLBACK_PROTO "http" | "udp" | "cosm" */
#define JSON_WS_CONF_CALLBACK_PROTO "http"
#define JSON_WS_CONF_CALLBACK_PORT 80
#define JSON_WS_CONF_CALLBACK_INTERVAL 120
#define WEBSERVER_CONF_INBUF_SIZE 200
#define WEBSERVER_CONF_OUTBUF_SIZE (UIP_TCP_MSS + 20 + 80)
#define WEBSERVER_CONF_CFS_CONNS 3
#endif /* PROJECT_CONF_H_ */

View File

@ -1,30 +0,0 @@
#!/usr/bin/python
# python set time code
import httplib,sys
# edit the key and feed parameters to match your COSM account and feed
key = "<your-key>"
feed = "<your-feed>"
cosmaddr = "[2001:470:1f10:333::2]"
print "JSON-WS COSM configuration utility\n Currently set to COSM feed: %s Key: '%s'" % (feed, key)
if len(sys.argv) > 2:
host = sys.argv[1]
stream = sys.argv[2]
else:
print "Usage: ", sys.argv[0], "<host> <feed-id>"
sys.exit()
print "Setting cosm config at:", host, " feed:", feed, " stream:",stream
conn = httplib.HTTPConnection(host)
# NAT64 address =
#conn.request("POST","", '{"host":"[2001:778:0:ffff:64:0:d834:e97a]","port":80,"path":"/v2/feeds/55180/datastreams/1","interval":120}')
requestData = '{"host":"%s","port":80,"path":"/v2/feeds/%s/datastreams/%s","appdata":"%s","interval":120,"proto":"cosm"}' % (cosmaddr, feed, stream, key)
print "Posting to node: ", requestData
conn.request("POST","", requestData)
res = conn.getresponse()
print res.status, res.reason

View File

@ -1,130 +0,0 @@
/*
* Copyright (c) 2011-2012, 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Websense for Sky mote
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*/
#include "contiki.h"
#include "dev/leds.h"
#include "dev/sht11/sht11-sensor.h"
#include "jsontree.h"
#include "json-ws.h"
#include <stdio.h>
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
PROCESS(websense_process, "Websense (sky)");
AUTOSTART_PROCESSES(&websense_process);
/*---------------------------------------------------------------------------*/
static CC_INLINE int
get_temp(void)
{
return ((sht11_sensor.value(SHT11_SENSOR_TEMP) / 10) - 396) / 10;
}
/*---------------------------------------------------------------------------*/
static int
output_temp(struct jsontree_context *path)
{
char buf[5];
snprintf(buf, sizeof(buf), "%3d", get_temp());
jsontree_write_atom(path, buf);
return 0;
}
static struct jsontree_callback temp_sensor_callback =
JSONTREE_CALLBACK(output_temp, NULL);
/*---------------------------------------------------------------------------*/
static struct jsontree_string desc = JSONTREE_STRING("Tmote Sky");
static struct jsontree_string temp_unit = JSONTREE_STRING("Celcius");
JSONTREE_OBJECT(node_tree,
JSONTREE_PAIR("node-type", &desc),
JSONTREE_PAIR("time", &json_time_callback));
JSONTREE_OBJECT(temp_sensor_tree,
JSONTREE_PAIR("unit", &temp_unit),
JSONTREE_PAIR("value", &temp_sensor_callback));
JSONTREE_OBJECT(rsc_tree,
JSONTREE_PAIR("temperature", &temp_sensor_tree),
JSONTREE_PAIR("leds", &json_leds_callback));
/* complete node tree */
JSONTREE_OBJECT(tree,
JSONTREE_PAIR("node", &node_tree),
JSONTREE_PAIR("rsc", &rsc_tree),
JSONTREE_PAIR("cfg", &json_subscribe_callback));
/*---------------------------------------------------------------------------*/
/* for cosm plugin */
#if WITH_COSM
/* set COSM value callback to be the temp sensor */
struct jsontree_callback cosm_value_callback =
JSONTREE_CALLBACK(output_temp, NULL);
#endif
PROCESS_THREAD(websense_process, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
json_ws_init(&tree);
SENSORS_ACTIVATE(sht11_sensor);
json_ws_set_callback("rsc");
while(1) {
/* Alive indication with the LED */
etimer_set(&timer, CLOCK_SECOND * 5);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
leds_on(LEDS_RED);
etimer_set(&timer, CLOCK_SECOND / 8);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
leds_off(LEDS_RED);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/