Align to current master
This commit is contained in:
commit
17aafb9daa
217 changed files with 16131 additions and 8628 deletions
|
@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_send();
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Set our prefix when we receive one over SLIP */
|
||||
|
|
|
@ -59,7 +59,7 @@ slip_input_callback(void)
|
|||
PRINTF("SIN: %u\n", uip_len);
|
||||
if((char)uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
if((char)uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* USB (CDC_ACM) functionality.
|
||||
*
|
||||
* It will print out periodically. Anything you type in the dongle's
|
||||
* serial console will be echoed back
|
||||
* serial console will be echoed back after a newline.
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
|
|
|
@ -6,8 +6,9 @@ boards. More specifically, the example demonstrates:
|
|||
* How to take sensor readings
|
||||
* How to use buttons and the reed relay (triggered by holding a magnet near S3
|
||||
on the SensorTag).
|
||||
* How to send out BLE advertisements. The device will periodically send out BLE
|
||||
beacons with the platform name as payload. Those beacons/BLE ADV packets can
|
||||
be captured with any BLE capable device. Two such applications for iOS are the
|
||||
TI Multitool and the TI Sensortag app. They can be found in the Apple App
|
||||
Store. If you have a BLE-capable Mac, you can also use LightBlue for OS X.
|
||||
* How to send out BLE advertisements, if the chip has BLE capability. The
|
||||
device will periodically send out BLE beacons with the platform name as
|
||||
payload. Those beacons/BLE ADV packets can be captured with any BLE-capable
|
||||
device. Two such applications for iOS are the TI Multitool and the TI
|
||||
Sensortag app. They can be found in the Apple App Store. If you have a
|
||||
BLE-capable Mac, you can also use LightBlue for OS X.
|
||||
|
|
|
@ -88,13 +88,12 @@
|
|||
#include "sys/etimer.h"
|
||||
#include "sys/ctimer.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/serial-line.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "random.h"
|
||||
#include "button-sensor.h"
|
||||
#include "batmon-sensor.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "cc26xx-rf.h"
|
||||
#include "rf-core/rf-ble.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
|
@ -104,7 +103,6 @@
|
|||
#define CC26XX_DEMO_LOOP_INTERVAL (CLOCK_SECOND * 20)
|
||||
#define CC26XX_DEMO_LEDS_PERIODIC LEDS_YELLOW
|
||||
#define CC26XX_DEMO_LEDS_BUTTON LEDS_RED
|
||||
#define CC26XX_DEMO_LEDS_SERIAL_IN LEDS_ORANGE
|
||||
#define CC26XX_DEMO_LEDS_REBOOT LEDS_ALL
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CC26XX_DEMO_SENSOR_NONE (void *)0xFFFFFFFF
|
||||
|
@ -370,8 +368,8 @@ PROCESS_THREAD(cc26xx_demo_process, ev, data)
|
|||
init_sensors();
|
||||
|
||||
/* Init the BLE advertisement daemon */
|
||||
cc26xx_rf_ble_beacond_config(0, BOARD_STRING);
|
||||
cc26xx_rf_ble_beacond_start();
|
||||
rf_ble_beacond_config(0, BOARD_STRING);
|
||||
rf_ble_beacond_start();
|
||||
|
||||
etimer_set(&et, CC26XX_DEMO_LOOP_INTERVAL);
|
||||
get_sync_sensor_readings();
|
||||
|
|
|
@ -5,7 +5,7 @@ all: cc26xx-web-demo
|
|||
REST_RESOURCES_DIR = ./resources
|
||||
|
||||
REST_RESOURCES_FILES += res-leds.c res-toggle-leds.c res-device.c
|
||||
REST_RESOURCES_FILES += res-sensors.c res-ble-advd.c
|
||||
REST_RESOURCES_FILES += res-sensors.c res-ble-advd.c res-net.c
|
||||
|
||||
PROJECTDIRS += $(REST_RESOURCES_DIR)
|
||||
PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES)
|
||||
|
|
|
@ -10,12 +10,11 @@ demonstrate the CC26xx capability. The applications are:
|
|||
* A web server which can be used to display sensor readings but also to
|
||||
configure MQTT functionality
|
||||
|
||||
The example has been configured to run for both CC26xx-based boards: i) The
|
||||
SensorTag 2.0 and ii) The Srf06EB with a CC26xx EM mounted on it.
|
||||
The example has been configured to run for all CC26xx-based boards: i) The
|
||||
SensorTag 2.0 and ii) The Srf06EB with a CC26xx or CC13xx EM mounted on it.
|
||||
|
||||
To build the example for the Srf, simply run `make`. To build for the tag,
|
||||
run `make BOARD=sensortag`. Do not forget to `make clean` when switching
|
||||
between the two platforms.
|
||||
To change between target boards, follow the instructions in the platform's
|
||||
REDME file. Do not forget to `make clean` when switching between the boards.
|
||||
|
||||
You can disable some of those individual components by changing the respective
|
||||
defines in `project-conf.h`. For instance, to disable the CoAP functionality,
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "lib/sensors.h"
|
||||
#include "lib/list.h"
|
||||
#include "sys/process.h"
|
||||
#include "net/ipv6/sicslowpan.h"
|
||||
#include "button-sensor.h"
|
||||
#include "batmon-sensor.h"
|
||||
#include "httpd-simple.h"
|
||||
|
@ -77,13 +78,20 @@ struct ctimer bmp_timer, hdc_timer, tmp_timer, opt_timer, mpu_timer;
|
|||
static struct etimer et;
|
||||
static struct ctimer ct;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Parent RSSI functionality */
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
static struct uip_icmp6_echo_reply_notification echo_reply_notification;
|
||||
static struct etimer echo_request_timer;
|
||||
int def_rt_rssi = 0;
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
process_event_t cc26xx_web_demo_publish_event;
|
||||
process_event_t cc26xx_web_demo_config_loaded_event;
|
||||
process_event_t cc26xx_web_demo_load_config_defaults;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Saved settings on flash: store, offset, magic */
|
||||
#define CONFIG_FLASH_OFFSET 0
|
||||
#define CONFIG_MAGIC 0xCC265001
|
||||
#define CONFIG_MAGIC 0xCC265002
|
||||
|
||||
cc26xx_web_demo_config_t cc26xx_web_demo_config;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -374,8 +382,57 @@ sensor_readings_handler(char *key, int key_len, char *val, int val_len)
|
|||
return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
static int
|
||||
ping_interval_post_handler(char *key, int key_len, char *val, int val_len)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if(key_len != strlen("ping_interval") ||
|
||||
strncasecmp(key, "ping_interval", strlen("ping_interval")) != 0) {
|
||||
/* Not ours */
|
||||
return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN;
|
||||
}
|
||||
|
||||
rv = atoi(val);
|
||||
|
||||
if(rv < CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN ||
|
||||
rv > CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX) {
|
||||
return HTTPD_SIMPLE_POST_HANDLER_ERROR;
|
||||
}
|
||||
|
||||
cc26xx_web_demo_config.def_rt_ping_interval = rv * CLOCK_SECOND;
|
||||
|
||||
return HTTPD_SIMPLE_POST_HANDLER_OK;
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
HTTPD_SIMPLE_POST_HANDLER(sensor, sensor_readings_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(defaults, defaults_post_handler);
|
||||
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
HTTPD_SIMPLE_POST_HANDLER(ping_interval, ping_interval_post_handler);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data,
|
||||
uint16_t datalen)
|
||||
{
|
||||
if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) {
|
||||
def_rt_rssi = sicslowpan_get_last_rssi();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
ping_parent(void)
|
||||
{
|
||||
if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0,
|
||||
CC26XX_WEB_DEMO_ECHO_REQ_PAYLOAD_LEN);
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
get_batmon_reading(void *data)
|
||||
|
@ -828,6 +885,8 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)
|
|||
* own defaults and restore saved config from flash...
|
||||
*/
|
||||
cc26xx_web_demo_config.sensors_bitmap = 0xFFFFFFFF; /* all on by default */
|
||||
cc26xx_web_demo_config.def_rt_ping_interval =
|
||||
CC26XX_WEB_DEMO_DEFAULT_RSSI_MEAS_INTERVAL;
|
||||
load_config();
|
||||
|
||||
/*
|
||||
|
@ -841,6 +900,15 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)
|
|||
httpd_simple_register_post_handler(&sensor_handler);
|
||||
httpd_simple_register_post_handler(&defaults_handler);
|
||||
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
httpd_simple_register_post_handler(&ping_interval_handler);
|
||||
|
||||
def_rt_rssi = 0x8000000;
|
||||
uip_icmp6_echo_reply_callback_add(&echo_reply_notification,
|
||||
echo_reply_handler);
|
||||
etimer_set(&echo_request_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
#endif
|
||||
|
||||
etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
|
||||
/*
|
||||
|
@ -848,6 +916,25 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)
|
|||
* (e.g a button press / or reed trigger)
|
||||
*/
|
||||
while(1) {
|
||||
if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) {
|
||||
if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) {
|
||||
leds_on(CC26XX_WEB_DEMO_STATUS_LED);
|
||||
ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL);
|
||||
etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
}
|
||||
}
|
||||
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
if(ev == PROCESS_EVENT_TIMER && etimer_expired(&echo_request_timer)) {
|
||||
if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) {
|
||||
etimer_set(&echo_request_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
} else {
|
||||
ping_parent();
|
||||
etimer_set(&echo_request_timer, cc26xx_web_demo_config.def_rt_ping_interval);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ev == sensors_event && data == CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER) {
|
||||
if((CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER)->value(
|
||||
BUTTON_SENSOR_VALUE_DURATION) > CLOCK_SECOND * 5) {
|
||||
|
@ -858,12 +945,6 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)
|
|||
|
||||
process_post(PROCESS_BROADCAST, cc26xx_web_demo_publish_event, NULL);
|
||||
}
|
||||
} else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) {
|
||||
if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) {
|
||||
leds_on(CC26XX_WEB_DEMO_STATUS_LED);
|
||||
ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL);
|
||||
etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
}
|
||||
} else if(ev == httpd_simple_event_new_config) {
|
||||
save_config();
|
||||
#if BOARD_SENSORTAG
|
||||
|
|
|
@ -80,6 +80,16 @@
|
|||
#define CC26XX_WEB_DEMO_NET_UART 1
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Active probing of RSSI from our preferred parent */
|
||||
#if (CC26XX_WEB_DEMO_COAP_SERVER || CC26XX_WEB_DEMO_MQTT_CLIENT)
|
||||
#define CC26XX_WEB_DEMO_READ_PARENT_RSSI 1
|
||||
#else
|
||||
#define CC26XX_WEB_DEMO_READ_PARENT_RSSI 0
|
||||
#endif
|
||||
|
||||
#define CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */
|
||||
#define CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN 5 /* secs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* User configuration */
|
||||
/* Take a sensor reading on button press */
|
||||
#define CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER &button_left_sensor
|
||||
|
@ -91,7 +101,7 @@
|
|||
/* Force an MQTT publish on sensor event */
|
||||
#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &reed_relay_sensor
|
||||
#else
|
||||
#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_right_sensor
|
||||
#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_down_sensor
|
||||
#endif
|
||||
|
||||
#define CC26XX_WEB_DEMO_STATUS_LED LEDS_GREEN
|
||||
|
@ -101,7 +111,11 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Default configuration values */
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_ORG_ID "quickstart"
|
||||
#if CPU_FAMILY_CC13XX
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_TYPE_ID "cc13xx"
|
||||
#else
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_TYPE_ID "cc26xx"
|
||||
#endif
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_EVENT_TYPE_ID "status"
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_SUBSCRIBE_CMD_TYPE "+"
|
||||
#define CC26XX_WEB_DEMO_DEFAULT_BROKER_PORT 1883
|
||||
|
@ -165,6 +179,7 @@ typedef struct cc26xx_web_demo_config_s {
|
|||
uint32_t magic;
|
||||
int len;
|
||||
uint32_t sensors_bitmap;
|
||||
int def_rt_ping_interval;
|
||||
mqtt_client_config_t mqtt_config;
|
||||
net_uart_config_t net_uart;
|
||||
} cc26xx_web_demo_config_t;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "contiki-net.h"
|
||||
#include "rest-engine.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "dev/cc26xx-rf.h"
|
||||
#include "rf-core/rf-ble.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -56,7 +56,10 @@ extern resource_t res_device_hw;
|
|||
extern resource_t res_device_uptime;
|
||||
extern resource_t res_device_cfg_reset;
|
||||
|
||||
#if CC26XX_RF_BLE_SUPPORT
|
||||
extern resource_t res_parent_rssi;
|
||||
extern resource_t res_parent_ip;
|
||||
|
||||
#if RF_BLE_ENABLED
|
||||
extern resource_t res_ble_advd;
|
||||
#endif
|
||||
|
||||
|
@ -138,7 +141,10 @@ PROCESS_THREAD(coap_server_process, ev, data)
|
|||
rest_activate_resource(&res_device_uptime, "dev/uptime");
|
||||
rest_activate_resource(&res_device_cfg_reset, "dev/cfg_reset");
|
||||
|
||||
#if CC26XX_RF_BLE_SUPPORT
|
||||
rest_activate_resource(&res_parent_rssi, "net/parent/RSSI");
|
||||
rest_activate_resource(&res_parent_ip, "net/parent/IPv6");
|
||||
|
||||
#if RF_BLE_ENABLED
|
||||
rest_activate_resource(&res_ble_advd, "dev/ble_advd");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -93,8 +93,8 @@ static int state;
|
|||
#define STRINGIFY(x) XSTR(x)
|
||||
#define XSTR(x) #x
|
||||
|
||||
#define RSSI_INT_MAX STRINGIFY(MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX)
|
||||
#define RSSI_INT_MIN STRINGIFY(MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN)
|
||||
#define RSSI_INT_MAX STRINGIFY(CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX)
|
||||
#define RSSI_INT_MIN STRINGIFY(CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN)
|
||||
#define PUB_INT_MAX STRINGIFY(MQTT_CLIENT_PUBLISH_INTERVAL_MAX)
|
||||
#define PUB_INT_MIN STRINGIFY(MQTT_CLIENT_PUBLISH_INTERVAL_MIN)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -568,12 +568,54 @@ PT_THREAD(generate_config(struct httpd_state *s))
|
|||
s->reading->publish ? "" : " Checked",
|
||||
config_div_close));
|
||||
}
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"<input type=\"submit\" value=\"Submit\">"));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "</form>"));
|
||||
|
||||
/* RSSI measurements */
|
||||
#if CC26XX_WEB_DEMO_READ_PARENT_RSSI
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "<h1>RSSI Probing</h1>"));
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"<form name=\"input\" action=\"%s\" ",
|
||||
http_dev_cfg_page.filename));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "method=\"post\" enctype=\""));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" "));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">"));
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "%sPeriod (secs):%s",
|
||||
config_div_left, config_div_close));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "%s<input type=\"number\" ",
|
||||
config_div_right));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "value=\"%lu\" ",
|
||||
(clock_time_t)
|
||||
(cc26xx_web_demo_config.def_rt_ping_interval
|
||||
/ CLOCK_SECOND)));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"min=\"" RSSI_INT_MIN "\" "
|
||||
"max=\"" RSSI_INT_MAX "\" "
|
||||
"name=\"ping_interval\">%s",
|
||||
config_div_close));
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"<input type=\"submit\" value=\"Submit\">"));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "</form>"));
|
||||
#endif
|
||||
|
||||
/* Actions */
|
||||
PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "<h1>Actions</h1>"));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
|
@ -732,24 +774,6 @@ PT_THREAD(generate_mqtt_config(struct httpd_state *s))
|
|||
"name=\"broker_port\">%s",
|
||||
config_div_close));
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "%sRSSI Interval (secs):%s",
|
||||
config_div_left, config_div_close));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "%s<input type=\"number\" ",
|
||||
config_div_right));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, "value=\"%lu\" ",
|
||||
(clock_time_t)
|
||||
(cc26xx_web_demo_config.mqtt_config.def_rt_ping_interval
|
||||
/ CLOCK_SECOND)));
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"min=\"" RSSI_INT_MIN "\" "
|
||||
"max=\"" RSSI_INT_MAX "\" "
|
||||
"name=\"ping_interval\">%s",
|
||||
config_div_close));
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0,
|
||||
"<input type=\"submit\" value=\"Submit\">"));
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Ideally a multiple of TCP_MSS */
|
||||
#ifdef HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE
|
||||
#define HTTPD_SIMPLE_MAIN_BUF_SIZE HTTPD_SIMPLE_CONF_BUF_SIZE
|
||||
#define HTTPD_SIMPLE_MAIN_BUF_SIZE HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE
|
||||
#else
|
||||
#define HTTPD_SIMPLE_MAIN_BUF_SIZE UIP_TCP_MSS
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "net/rpl/rpl.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/sicslowpan.h"
|
||||
#include "sys/etimer.h"
|
||||
#include "sys/ctimer.h"
|
||||
#include "lib/sensors.h"
|
||||
|
@ -86,7 +85,7 @@ static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd";
|
|||
* Number of times to try reconnecting to the broker.
|
||||
* Can be a limited number (e.g. 3, 10 etc) or can be set to RETRY_FOREVER
|
||||
*/
|
||||
#define RECONNECT_ATTEMPTS RETRY_FOREVER
|
||||
#define RECONNECT_ATTEMPTS 5
|
||||
#define CONNECTION_STABLE_TIME (CLOCK_SECOND * 5)
|
||||
#define NEW_CONFIG_WAIT_INTERVAL (CLOCK_SECOND * 20)
|
||||
static struct timer connection_life;
|
||||
|
@ -139,9 +138,7 @@ static uint16_t seq_nr_value = 0;
|
|||
static uip_ip6addr_t def_route;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Parent RSSI functionality */
|
||||
static struct uip_icmp6_echo_reply_notification echo_reply_notification;
|
||||
static struct etimer echo_request_timer;
|
||||
int def_rt_rssi = 0;
|
||||
extern int def_rt_rssi;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const static cc26xx_web_demo_sensor_reading_t *reading;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -388,29 +385,6 @@ reconnect_post_handler(char *key, int key_len, char *val, int val_len)
|
|||
return HTTPD_SIMPLE_POST_HANDLER_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
ping_interval_post_handler(char *key, int key_len, char *val, int val_len)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if(key_len != strlen("ping_interval") ||
|
||||
strncasecmp(key, "ping_interval", strlen("ping_interval")) != 0) {
|
||||
/* Not ours */
|
||||
return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN;
|
||||
}
|
||||
|
||||
rv = atoi(val);
|
||||
|
||||
if(rv < MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN ||
|
||||
rv > MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX) {
|
||||
return HTTPD_SIMPLE_POST_HANDLER_ERROR;
|
||||
}
|
||||
|
||||
conf->def_rt_ping_interval = rv * CLOCK_SECOND;
|
||||
|
||||
return HTTPD_SIMPLE_POST_HANDLER_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
HTTPD_SIMPLE_POST_HANDLER(org_id, org_id_post_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(type_id, type_id_post_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(event_type_id, event_type_id_post_handler);
|
||||
|
@ -420,16 +394,6 @@ HTTPD_SIMPLE_POST_HANDLER(ip_addr, ip_addr_post_handler);
|
|||
HTTPD_SIMPLE_POST_HANDLER(port, port_post_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(interval, interval_post_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(reconnect, reconnect_post_handler);
|
||||
HTTPD_SIMPLE_POST_HANDLER(ping_interval, ping_interval_post_handler);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data,
|
||||
uint16_t datalen)
|
||||
{
|
||||
if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) {
|
||||
def_rt_rssi = sicslowpan_get_last_rssi();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk,
|
||||
|
@ -624,7 +588,6 @@ init_config()
|
|||
|
||||
conf->broker_port = CC26XX_WEB_DEMO_DEFAULT_BROKER_PORT;
|
||||
conf->pub_interval = CC26XX_WEB_DEMO_DEFAULT_PUBLISH_INTERVAL;
|
||||
conf->def_rt_ping_interval = CC26XX_WEB_DEMO_DEFAULT_RSSI_MEAS_INTERVAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -641,7 +604,6 @@ register_http_post_handlers(void)
|
|||
httpd_simple_register_post_handler(&port_handler);
|
||||
httpd_simple_register_post_handler(&ip_addr_handler);
|
||||
httpd_simple_register_post_handler(&reconnect_handler);
|
||||
httpd_simple_register_post_handler(&ping_interval_handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -664,6 +626,7 @@ publish(void)
|
|||
/* Publish MQTT topic in IBM quickstart format */
|
||||
int len;
|
||||
int remaining = APP_BUFFER_SIZE;
|
||||
char def_rt_str[64];
|
||||
|
||||
seq_nr_value++;
|
||||
|
||||
|
@ -686,7 +649,6 @@ publish(void)
|
|||
buf_ptr += len;
|
||||
|
||||
/* Put our Default route's string representation in a buffer */
|
||||
char def_rt_str[64];
|
||||
memset(def_rt_str, 0, sizeof(def_rt_str));
|
||||
cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str),
|
||||
uip_ds6_defrt_choose());
|
||||
|
@ -743,17 +705,6 @@ connect_to_broker(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
ping_parent(void)
|
||||
{
|
||||
if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0,
|
||||
CC26XX_WEB_DEMO_ECHO_REQ_PAYLOAD_LEN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
state_machine(void)
|
||||
{
|
||||
switch(state) {
|
||||
|
@ -794,7 +745,6 @@ state_machine(void)
|
|||
if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) {
|
||||
/* Registered and with a public IP. Connect */
|
||||
DBG("Registered. Connect attempt %u\n", connect_attempt);
|
||||
ping_parent();
|
||||
connect_to_broker();
|
||||
}
|
||||
etimer_set(&publish_periodic_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
|
||||
|
@ -923,11 +873,6 @@ PROCESS_THREAD(mqtt_client_process, ev, data)
|
|||
|
||||
update_config();
|
||||
|
||||
def_rt_rssi = 0x8000000;
|
||||
uip_icmp6_echo_reply_callback_add(&echo_reply_notification,
|
||||
echo_reply_handler);
|
||||
etimer_set(&echo_request_timer, conf->def_rt_ping_interval);
|
||||
|
||||
/* Main loop */
|
||||
while(1) {
|
||||
|
||||
|
@ -956,11 +901,6 @@ PROCESS_THREAD(mqtt_client_process, ev, data)
|
|||
state_machine();
|
||||
}
|
||||
|
||||
if(ev == PROCESS_EVENT_TIMER && data == &echo_request_timer) {
|
||||
ping_parent();
|
||||
etimer_set(&echo_request_timer, conf->def_rt_ping_interval);
|
||||
}
|
||||
|
||||
if(ev == cc26xx_web_demo_load_config_defaults) {
|
||||
init_config();
|
||||
etimer_set(&publish_periodic_timer, NEW_CONFIG_WAIT_INTERVAL);
|
||||
|
|
|
@ -45,8 +45,6 @@
|
|||
#define MQTT_CLIENT_CONFIG_CMD_TYPE_LEN 8
|
||||
#define MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN 64
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */
|
||||
#define MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN 5 /* secs */
|
||||
#define MQTT_CLIENT_PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */
|
||||
#define MQTT_CLIENT_PUBLISH_INTERVAL_MIN 5 /* secs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -63,7 +61,6 @@ typedef struct mqtt_client_config {
|
|||
char broker_ip[MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN];
|
||||
char cmd_type[MQTT_CLIENT_CONFIG_CMD_TYPE_LEN];
|
||||
clock_time_t pub_interval;
|
||||
int def_rt_ping_interval;
|
||||
uint16_t broker_port;
|
||||
} mqtt_client_config_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -32,11 +32,9 @@
|
|||
#define PROJECT_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Change to match your configuration */
|
||||
#define NETSTACK_CONF_RDC contikimac_driver
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
#define CC26XX_RF_CONF_CHANNEL 25
|
||||
#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /* CC2650 */
|
||||
#define CC26XX_RF_CONF_BLE_SUPPORT 1 /* Only available with CC2650 */
|
||||
#define RF_CORE_CONF_CHANNEL 25
|
||||
#define RF_BLE_CONF_ENABLED 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Enable/Disable Components of this Demo */
|
||||
#define CC26XX_WEB_DEMO_CONF_MQTT_CLIENT 1
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
#include "dev/cc26xx-rf.h"
|
||||
#include "rf-core/rf-ble.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -64,7 +64,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
|
||||
if(len > 0 && len < BLE_NAME_BUF_LEN) {
|
||||
memcpy(name, text, len);
|
||||
cc26xx_rf_ble_beacond_config(0, name);
|
||||
rf_ble_beacond_config(0, name);
|
||||
success = 1;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
rv = atoi(text);
|
||||
|
||||
if(rv > 0) {
|
||||
cc26xx_rf_ble_beacond_config((clock_time_t)(rv * CLOCK_SECOND), NULL);
|
||||
rf_ble_beacond_config((clock_time_t)(rv * CLOCK_SECOND), NULL);
|
||||
success = 1;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
|
||||
if(len) {
|
||||
if(strncmp(text, "on", len) == 0) {
|
||||
if(cc26xx_rf_ble_beacond_start()) {
|
||||
if(rf_ble_beacond_start()) {
|
||||
success = 1;
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.FORBIDDEN);
|
||||
|
@ -90,7 +90,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
return;
|
||||
}
|
||||
} else if(strncmp(text, "off", len) == 0) {
|
||||
cc26xx_rf_ble_beacond_stop();
|
||||
rf_ble_beacond_stop();
|
||||
success = 1;
|
||||
} else {
|
||||
success = 0;
|
||||
|
|
|
@ -40,37 +40,65 @@
|
|||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
#include "sys/clock.h"
|
||||
#include "cc26xx-model.h"
|
||||
#include "coap-server.h"
|
||||
#include "cc26xx-web-demo.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t
|
||||
detect_chip(void)
|
||||
{
|
||||
if(ti_lib_chipinfo_chip_family_is_cc26xx()) {
|
||||
if(ti_lib_chipinfo_supports_ieee_802_15_4() == true) {
|
||||
if(ti_lib_chipinfo_supports_ble() == true) {
|
||||
return 2650;
|
||||
} else {
|
||||
return 2630;
|
||||
}
|
||||
} else {
|
||||
return 2640;
|
||||
}
|
||||
} else if(ti_lib_chipinfo_chip_family_is_cc13xx()) {
|
||||
if(ti_lib_chipinfo_supports_ble() == false &&
|
||||
ti_lib_chipinfo_supports_ieee_802_15_4() == false) {
|
||||
return 1310;
|
||||
} else if(ti_lib_chipinfo_supports_ble() == true &&
|
||||
ti_lib_chipinfo_supports_ieee_802_15_4() == true) {
|
||||
return 1350;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_hw(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
uint16_t chip = detect_chip();
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s on CC%u", BOARD_STRING,
|
||||
CC26XX_MODEL_CPU_VARIANT);
|
||||
chip);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"HW Ver\":\"%s on CC%u\"}",
|
||||
BOARD_STRING, CC26XX_MODEL_CPU_VARIANT);
|
||||
BOARD_STRING, chip);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<hw-ver val=\"%s on CC%u\"/>", BOARD_STRING,
|
||||
CC26XX_MODEL_CPU_VARIANT);
|
||||
chip);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
|
|
126
examples/cc26xx/cc26xx-web-demo/resources/res-net.c
Normal file
126
examples/cc26xx/cc26xx-web-demo/resources/res-net.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* 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 copyright holder 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 COPYRIGHT HOLDERS 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
|
||||
* COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-web-demo
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* CoAP resource handler for network-related resources
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
#include "coap-server.h"
|
||||
#include "cc26xx-web-demo.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern int def_rt_rssi;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_parent_rssi(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", def_rt_rssi);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent RSSI\":\"%d\"}",
|
||||
def_rt_rssi);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<parent-rssi val=\"%d\"/>", def_rt_rssi);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_pref_parent(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
char def_rt_str[64];
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
memset(def_rt_str, 0, sizeof(def_rt_str));
|
||||
cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str),
|
||||
uip_ds6_defrt_choose());
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", def_rt_str);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent\":\"%s\"}",
|
||||
def_rt_str);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<parent=\"%s\"/>", def_rt_str);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
RESOURCE(res_parent_rssi, "title=\"Parent RSSI\";rt=\"dBm\"",
|
||||
res_get_handler_parent_rssi, NULL, NULL, NULL);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
RESOURCE(res_parent_ip, "title=\"Preferred Parent\";rt=\"IPv6 address\"",
|
||||
res_get_handler_pref_parent, NULL, NULL, NULL);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -35,11 +35,9 @@
|
|||
#define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 0
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Change to match your configuration */
|
||||
#define NETSTACK_CONF_RDC contikimac_driver
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
#define CC26XX_RF_CONF_CHANNEL 25
|
||||
#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /* CC2650 */
|
||||
#define CC26XX_RF_CONF_BLE_SUPPORT 1 /* Only available with CC2650 */
|
||||
#define RF_CORE_CONF_CHANNEL 25
|
||||
#define RF_BLE_CONF_ENABLED 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
12
examples/cc26xx/very-sleepy-demo/Makefile
Normal file
12
examples/cc26xx/very-sleepy-demo/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
|
||||
CONTIKI_PROJECT = very-sleepy-demo
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI_WITH_IPV6 = 1
|
||||
|
||||
APPS += er-coap
|
||||
APPS += rest-engine
|
||||
|
||||
CONTIKI = ../../..
|
||||
include $(CONTIKI)/Makefile.include
|
1
examples/cc26xx/very-sleepy-demo/Makefile.target
Normal file
1
examples/cc26xx/very-sleepy-demo/Makefile.target
Normal file
|
@ -0,0 +1 @@
|
|||
TARGET = srf06-cc26xx
|
91
examples/cc26xx/very-sleepy-demo/README.md
Normal file
91
examples/cc26xx/very-sleepy-demo/README.md
Normal file
|
@ -0,0 +1,91 @@
|
|||
# CC13xx/CC26xx Very Sleepy Demo
|
||||
|
||||
This example demonstrates a way of deploying a very low-consuming, very sleepy
|
||||
node. The node has two modes of operation:
|
||||
|
||||
* Normal: ContikiMAC duty-cycles the radio as usual. The node is reachable.
|
||||
* Very Sleepy: Radio cycling mostly off, except when we need to perform network
|
||||
maintenance tasks. In this mode, the node is unreachable for most of the time.
|
||||
|
||||
The node will operate in RPL leaf mode. This means that it will be reachable
|
||||
downwards, but it will not advertise the DODAG and it will not participate in
|
||||
routing.
|
||||
|
||||
After booting, the node will enter "normal" mode.
|
||||
|
||||
The node exposes an OBSERVEable CoAP resource. It will notify subscribers with
|
||||
a new value for this resource every `interval` seconds. It will then stay in
|
||||
normal mode for `duration` seconds. During this time window, it will be
|
||||
reachable over the network in order to e.g. receive a new configuration.
|
||||
When this time window expires, the node will switch back to very sleepy mode.
|
||||
This will only happen if very sleepy mode has been enabled by setting `mode=1`
|
||||
as per the instructions below.
|
||||
|
||||
When the node is duty-cycling the radio, either because it is in normal mode or
|
||||
because network maintenance is taking place, it will keep its green LED on thus
|
||||
providing an indication that it is reachable.
|
||||
|
||||
A normal mode stint can be manually triggered by pressing the left button.
|
||||
|
||||
## Requirements
|
||||
|
||||
To run this example you will need:
|
||||
|
||||
* A border router operating with the same RDC, same channel, same radio mode
|
||||
(e.g. IEEE or sub-ghz), same PAN ID. Alternatively, you can
|
||||
use [6lbr](https://github.com/cetic/6lbr) with a suitable slip-radio.
|
||||
* The [Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/)
|
||||
addon for Firefox
|
||||
|
||||
## Configuration
|
||||
|
||||
To configure the node, send a CoAP POST message to the `very_sleepy_config`
|
||||
resource. The POST message's payload must specify _at least one_ of:
|
||||
|
||||
* `mode=0|1`: Send `mode=1` to enable very sleepy mode, `mode=0` to disable it.
|
||||
* `interval=n` where `n` is the number of seconds between two consecutive normal
|
||||
mode periods. This interval also dictates the OBSERVEr notification period.
|
||||
* `duration=n` where `n` is the number of seconds that the node will stay in
|
||||
normal mode before dropping to very sleepy mode. This value is only relevant
|
||||
if `mode==1`.
|
||||
|
||||
A POST request must contain at least one of the above, but they are otherwise
|
||||
all optional. So, for example, a POST may simply specify `interval=n`. To send
|
||||
multiple values, delimit them with `&`. So you can send something like
|
||||
`mode=1&interval=60&duration=20`
|
||||
|
||||
The current running configuration can be retrieved by sending a GET request to
|
||||
the same CoAP resource.
|
||||
|
||||
## Running the example
|
||||
|
||||
* Deploy your border router or 6lbr
|
||||
* Turn on the very sleepy node.
|
||||
* Fire up the Copper addon
|
||||
* Select `.well-known/core` and hit `GET`
|
||||
* Configure very sleepy operation:
|
||||
* Select the `very_sleepy_config` resource
|
||||
* In the `Outgoing` pane, type your POST payload as per the instructions
|
||||
above. For example, you can type: `mode=1&interval=30&duration=10`
|
||||
* Hit `POST`
|
||||
* Select the `sen/readings` resource and hit `OBSERVE`
|
||||
|
||||
## Caveats
|
||||
|
||||
If you click on a resource in the Copper resources tree while you are observing
|
||||
a different resource, the OBSERVEr for the latter will be stopped without
|
||||
notifying the CoAP server. This will result in the server sending out OBSERVE
|
||||
notifications that will be responded to with port unreachable ICMPv6 messages.
|
||||
This will continue for quite a while, until the server detects that the
|
||||
OBSERVEr has been lost (a test currently performed once every 20 notifications).
|
||||
In order to prevent this from happening, hit the "Cancel" button for the
|
||||
OBSERVE before switching views to a different resource. This will unregister
|
||||
the observer.
|
||||
|
||||
In very sleepy mode, the radio is not truly always off. The contiki core needs
|
||||
to perform other periodic tasks in order to maintain network connectivity. For
|
||||
that reason, this example will allow the radio to turn on periodically even
|
||||
while in very sleepy mode. Thus, you may see that the node becomes briefly
|
||||
reachable every now and then. However, do not count on those periods of
|
||||
reachability to perform any tasks, as they will be brief and will be disrupted
|
||||
without warning.
|
51
examples/cc26xx/very-sleepy-demo/project-conf.h
Normal file
51
examples/cc26xx/very-sleepy-demo/project-conf.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* 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 copyright holder 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 COPYRIGHT HOLDERS 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
|
||||
* COPYRIGHT HOLDER 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_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Change to match your configuration */
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
#define RF_CORE_CONF_CHANNEL 25
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* For very sleepy operation */
|
||||
#define RF_BLE_CONF_ENABLED 0
|
||||
#define UIP_DS6_CONF_PERIOD CLOCK_SECOND
|
||||
#define UIP_CONF_TCP 0
|
||||
#define RPL_CONF_LEAF_ONLY 1
|
||||
|
||||
/*
|
||||
* We'll fail without RPL probing, so turn it on explicitly even though it's
|
||||
* on by default
|
||||
*/
|
||||
#define RPL_CONF_WITH_PROBING 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
423
examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c
Normal file
423
examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c
Normal file
|
@ -0,0 +1,423 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* 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 copyright holder 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 COPYRIGHT HOLDERS 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
|
||||
* COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "sys/etimer.h"
|
||||
#include "sys/stimer.h"
|
||||
#include "sys/process.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "button-sensor.h"
|
||||
#include "batmon-sensor.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/ipv6/uip-ds6-nbr.h"
|
||||
#include "net/ipv6/uip-ds6-route.h"
|
||||
#include "net/rpl/rpl.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Normal mode duration params in seconds */
|
||||
#define NORMAL_OP_DURATION_DEFAULT 10
|
||||
#define NORMAL_OP_DURATION_MIN 10
|
||||
#define NORMAL_OP_DURATION_MAX 60
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Observer notification period params in seconds */
|
||||
#define PERIODIC_INTERVAL_DEFAULT 30
|
||||
#define PERIODIC_INTERVAL_MIN 30
|
||||
#define PERIODIC_INTERVAL_MAX 86400 /* 1 day */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define VERY_SLEEPY_MODE_OFF 0
|
||||
#define VERY_SLEEPY_MODE_ON 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MAC_CAN_BE_TURNED_OFF 0
|
||||
#define MAC_MUST_STAY_ON 1
|
||||
|
||||
#define KEEP_MAC_ON_MIN_PERIOD 10 /* secs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PERIODIC_INTERVAL CLOCK_SECOND
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define POST_STATUS_BAD 0x80
|
||||
#define POST_STATUS_HAS_MODE 0x40
|
||||
#define POST_STATUS_HAS_DURATION 0x20
|
||||
#define POST_STATUS_HAS_INTERVAL 0x10
|
||||
#define POST_STATUS_NONE 0x00
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct sleepy_config_s {
|
||||
unsigned long interval;
|
||||
unsigned long duration;
|
||||
uint8_t mode;
|
||||
} sleepy_config_t;
|
||||
|
||||
sleepy_config_t config;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define STATE_NORMAL 0
|
||||
#define STATE_NOTIFY_OBSERVERS 1
|
||||
#define STATE_VERY_SLEEPY 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct stimer st_duration;
|
||||
static struct stimer st_interval;
|
||||
static struct stimer st_min_mac_on_duration;
|
||||
static struct etimer et_periodic;
|
||||
static process_event_t event_new_config;
|
||||
static uint8_t state;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const char *not_supported_msg = "Supported:text/plain,application/json";
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(very_sleepy_demo_process, "CC13xx/CC26xx very sleepy process");
|
||||
AUTOSTART_PROCESSES(&very_sleepy_demo_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
readings_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
int temp;
|
||||
int voltage;
|
||||
|
||||
if(request != NULL) {
|
||||
REST.get_header_accept(request, &accept);
|
||||
}
|
||||
|
||||
temp = batmon_sensor.value(BATMON_SENSOR_TYPE_TEMP);
|
||||
|
||||
voltage = batmon_sensor.value(BATMON_SENSOR_TYPE_VOLT);
|
||||
|
||||
if(accept == -1 || accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"{\"temp\":{\"v\":%d,\"u\":\"C\"},"
|
||||
"\"voltage\":{\"v\":%d,\"u\":\"mV\"}}",
|
||||
temp, (voltage * 125) >> 5);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Temp=%dC, Voltage=%dmV",
|
||||
temp, (voltage * 125) >> 5);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, not_supported_msg,
|
||||
strlen(not_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
RESOURCE(readings_resource, "title=\"Sensor Readings\";obs",
|
||||
readings_get_handler, NULL, NULL, NULL);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
conf_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
if(request != NULL) {
|
||||
REST.get_header_accept(request, &accept);
|
||||
}
|
||||
|
||||
if(accept == -1 || accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"{\"config\":{\"mode\":%u,\"duration\":%lu,\"interval\":%lu}}",
|
||||
config.mode, config.duration, config.interval);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"Mode=%u, Duration=%lusecs, Interval=%lusecs",
|
||||
config.mode, config.duration, config.interval);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, not_supported_msg,
|
||||
strlen(not_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
conf_post_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
char tmp_buf[16];
|
||||
unsigned long interval = 0;
|
||||
unsigned long duration = 0;
|
||||
uint8_t mode = VERY_SLEEPY_MODE_OFF;
|
||||
uint8_t post_status = POST_STATUS_NONE;
|
||||
int rv;
|
||||
|
||||
rv = REST.get_post_variable(request, "mode", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
rv = atoi(tmp_buf);
|
||||
|
||||
if(rv == 1) {
|
||||
mode = VERY_SLEEPY_MODE_ON;
|
||||
post_status |= POST_STATUS_HAS_MODE;
|
||||
} else if(rv == 0) {
|
||||
mode = VERY_SLEEPY_MODE_OFF;
|
||||
post_status |= POST_STATUS_HAS_MODE;
|
||||
} else {
|
||||
post_status = POST_STATUS_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
rv = REST.get_post_variable(request, "duration", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
rv = atoi(tmp_buf);
|
||||
|
||||
duration = (unsigned long)rv;
|
||||
if(duration < NORMAL_OP_DURATION_MIN || duration > NORMAL_OP_DURATION_MAX) {
|
||||
post_status = POST_STATUS_BAD;
|
||||
} else {
|
||||
post_status |= POST_STATUS_HAS_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
rv = REST.get_post_variable(request, "interval", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
rv = atoi(tmp_buf);
|
||||
interval = (unsigned long)rv;
|
||||
if(interval < PERIODIC_INTERVAL_MIN || interval > PERIODIC_INTERVAL_MAX) {
|
||||
post_status = POST_STATUS_BAD;
|
||||
} else {
|
||||
post_status |= POST_STATUS_HAS_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if((post_status & POST_STATUS_BAD) == POST_STATUS_BAD ||
|
||||
post_status == POST_STATUS_NONE) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"mode=0|1&duration=[%u,%u]&interval=[%u,%u]",
|
||||
NORMAL_OP_DURATION_MIN, NORMAL_OP_DURATION_MAX,
|
||||
PERIODIC_INTERVAL_MIN, PERIODIC_INTERVAL_MAX);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Values are sane. Update the config and notify the process */
|
||||
if(post_status & POST_STATUS_HAS_MODE) {
|
||||
config.mode = mode;
|
||||
}
|
||||
|
||||
if(post_status & POST_STATUS_HAS_INTERVAL) {
|
||||
config.interval = interval;
|
||||
}
|
||||
|
||||
if(post_status & POST_STATUS_HAS_DURATION) {
|
||||
config.duration = duration;
|
||||
}
|
||||
|
||||
process_post(&very_sleepy_demo_process, event_new_config, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
RESOURCE(very_sleepy_conf,
|
||||
"title=\"Very sleepy conf: "
|
||||
"GET|POST mode=0|1&interval=<secs>&duration=<secs>\";rt=\"Control\"",
|
||||
conf_get_handler, conf_post_handler, NULL, NULL);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* If our preferred parent is not NBR_REACHABLE in the ND cache, NUD will send
|
||||
* a unicast NS and wait for NA. If NA fails then the neighbour will be removed
|
||||
* from the ND cache and the default route will be deleted. To prevent this,
|
||||
* keep the MAC on until the parent becomes NBR_REACHABLE. We also keep the MAC
|
||||
* on if we are about to do RPL probing.
|
||||
*
|
||||
* In all cases, the radio will be locked on for KEEP_MAC_ON_MIN_PERIOD secs
|
||||
*/
|
||||
static uint8_t
|
||||
keep_mac_on(void)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr;
|
||||
uint8_t rv = MAC_CAN_BE_TURNED_OFF;
|
||||
|
||||
if(!stimer_expired(&st_min_mac_on_duration)) {
|
||||
return MAC_MUST_STAY_ON;
|
||||
}
|
||||
|
||||
#if RPL_WITH_PROBING
|
||||
/* Determine if we are about to send a RPL probe */
|
||||
if(CLOCK_LT(etimer_expiration_time(
|
||||
&rpl_get_default_instance()->probing_timer.etimer),
|
||||
(clock_time() + PERIODIC_INTERVAL))) {
|
||||
rv = MAC_MUST_STAY_ON;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* It's OK to pass a NULL pointer, the callee checks and returns NULL */
|
||||
nbr = uip_ds6_nbr_lookup(uip_ds6_defrt_choose());
|
||||
|
||||
if(nbr == NULL) {
|
||||
/* We don't have a default route, or it's not reachable (NUD likely). */
|
||||
rv = MAC_MUST_STAY_ON;
|
||||
} else {
|
||||
if(nbr->state != NBR_REACHABLE) {
|
||||
rv = MAC_MUST_STAY_ON;
|
||||
}
|
||||
}
|
||||
|
||||
if(rv == MAC_MUST_STAY_ON && stimer_expired(&st_min_mac_on_duration)) {
|
||||
stimer_set(&st_min_mac_on_duration, KEEP_MAC_ON_MIN_PERIOD);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
switch_to_normal(void)
|
||||
{
|
||||
state = STATE_NOTIFY_OBSERVERS;
|
||||
|
||||
/*
|
||||
* Stay in normal mode for 'duration' secs.
|
||||
* Transition back to normal in 'interval' secs, _including_ 'duration'
|
||||
*/
|
||||
stimer_set(&st_duration, config.duration);
|
||||
stimer_set(&st_interval, config.interval);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
switch_to_very_sleepy(void)
|
||||
{
|
||||
state = STATE_VERY_SLEEPY;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(very_sleepy_demo_process, ev, data)
|
||||
{
|
||||
uint8_t mac_keep_on;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
SENSORS_ACTIVATE(batmon_sensor);
|
||||
|
||||
config.mode = VERY_SLEEPY_MODE_OFF;
|
||||
config.interval = PERIODIC_INTERVAL_DEFAULT;
|
||||
config.duration = NORMAL_OP_DURATION_DEFAULT;
|
||||
|
||||
state = STATE_NORMAL;
|
||||
|
||||
event_new_config = process_alloc_event();
|
||||
|
||||
rest_init_engine();
|
||||
|
||||
readings_resource.flags += IS_OBSERVABLE;
|
||||
rest_activate_resource(&readings_resource, "sen/readings");
|
||||
rest_activate_resource(&very_sleepy_conf, "very_sleepy_config");
|
||||
|
||||
printf("Very Sleepy Demo Process\n");
|
||||
|
||||
switch_to_normal();
|
||||
|
||||
etimer_set(&et_periodic, PERIODIC_INTERVAL);
|
||||
|
||||
while(1) {
|
||||
|
||||
PROCESS_YIELD();
|
||||
|
||||
if(ev == sensors_event && data == &button_left_sensor) {
|
||||
switch_to_normal();
|
||||
}
|
||||
|
||||
if(ev == event_new_config) {
|
||||
stimer_set(&st_interval, config.interval);
|
||||
stimer_set(&st_duration, config.duration);
|
||||
}
|
||||
|
||||
if((ev == PROCESS_EVENT_TIMER && data == &et_periodic) ||
|
||||
(ev == sensors_event && data == &button_left_sensor) ||
|
||||
(ev == event_new_config)) {
|
||||
|
||||
/*
|
||||
* Determine if the stack is about to do essential network maintenance
|
||||
* and, if so, keep the MAC layer on
|
||||
*/
|
||||
mac_keep_on = keep_mac_on();
|
||||
|
||||
if(mac_keep_on == MAC_MUST_STAY_ON || state != STATE_VERY_SLEEPY) {
|
||||
leds_on(LEDS_GREEN);
|
||||
NETSTACK_MAC.on();
|
||||
}
|
||||
|
||||
/*
|
||||
* Next, switch between normal and very sleepy mode depending on config,
|
||||
* send notifications to observers as required.
|
||||
*/
|
||||
if(state == STATE_NOTIFY_OBSERVERS) {
|
||||
REST.notify_subscribers(&readings_resource);
|
||||
state = STATE_NORMAL;
|
||||
}
|
||||
|
||||
if(state == STATE_NORMAL) {
|
||||
if(stimer_expired(&st_duration)) {
|
||||
stimer_set(&st_duration, config.duration);
|
||||
if(config.mode == VERY_SLEEPY_MODE_ON) {
|
||||
switch_to_very_sleepy();
|
||||
}
|
||||
}
|
||||
} else if(state == STATE_VERY_SLEEPY) {
|
||||
if(stimer_expired(&st_interval)) {
|
||||
switch_to_normal();
|
||||
}
|
||||
}
|
||||
|
||||
if(mac_keep_on == MAC_CAN_BE_TURNED_OFF && state == STATE_VERY_SLEEPY) {
|
||||
leds_off(LEDS_GREEN);
|
||||
NETSTACK_MAC.off(0);
|
||||
} else {
|
||||
leds_on(LEDS_GREEN);
|
||||
NETSTACK_MAC.on();
|
||||
}
|
||||
|
||||
/* Schedule next pass */
|
||||
etimer_set(&et_periodic, PERIODIC_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -311,7 +311,7 @@ request_prefix(void)
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_send();
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -59,7 +59,7 @@ slip_input_callback(void)
|
|||
// PRINTF("SIN: %u\n", uip_len);
|
||||
if(uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
if(uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
|
@ -85,7 +85,7 @@ slip_input_callback(void)
|
|||
slip_send();
|
||||
|
||||
}
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/* Save the last sender received over SLIP to avoid bouncing the
|
||||
packet back if no route is found */
|
||||
|
|
|
@ -162,7 +162,7 @@ slip_input_callback(void)
|
|||
{
|
||||
PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]);
|
||||
cmd_input(uip_buf, uip_len);
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
|
|
@ -1 +1 @@
|
|||
DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS
|
||||
DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS,MTU_SIZE=1000
|
||||
|
|
|
@ -13,6 +13,8 @@ uip_buf_t uip_aligned_buf;
|
|||
|
||||
uint16_t uip_len;
|
||||
|
||||
uint8_t uip_ext_len;
|
||||
|
||||
struct uip_stats uip_stat;
|
||||
|
||||
uip_lladdr_t uip_lladdr;
|
||||
|
|
|
@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_send();
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Set our prefix when we receive one over SLIP */
|
||||
|
|
|
@ -60,7 +60,7 @@ slip_input_callback(void)
|
|||
PRINTF("SIN: %u\n", uip_len);
|
||||
if((char)uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
if((char)uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
|
|
|
@ -34,20 +34,6 @@
|
|||
#include "shell.h"
|
||||
#include "serial-shell.h"
|
||||
|
||||
#include "dev/watchdog.h"
|
||||
|
||||
#include "net/rime/rime.h"
|
||||
#include "cc2420.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/light.h"
|
||||
#include "dev/sht11/sht11.h"
|
||||
#include "dev/battery-sensor.h"
|
||||
|
||||
#include "net/rime/timesynch.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(sky_shell_process, "Sky Contiki shell");
|
||||
AUTOSTART_PROCESSES(&sky_shell_process);
|
||||
|
|
|
@ -1 +1 @@
|
|||
DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_ARGS
|
||||
DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS,WITH_ARGS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue