Remove the JSON-WS example
Does not seem to build for any platforms.
This commit is contained in:
parent
0fdd1015e2
commit
f50671ce37
@ -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
|
@ -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).
|
@ -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
|
||||
#------------------------------------------------------------------------------
|
@ -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));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -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_ */
|
@ -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_ */
|
@ -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
|
@ -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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
Loading…
Reference in New Issue
Block a user