Merge pull request #167 from nfi/contrib/coap-lwm2m-dtls
Updated CoAP and LWM2M with added DTLS support
This commit is contained in:
commit
0971088260
|
@ -13,3 +13,9 @@
|
|||
[submodule "tools/cooja"]
|
||||
path = tools/cooja
|
||||
url = https://github.com/contiki-ng/cooja.git
|
||||
[submodule "os/net/security/tinydtls"]
|
||||
path = os/net/security/tinydtls
|
||||
url = https://github.com/contiki-ng/tinydtls.git
|
||||
[submodule "tests/18-coap-lwm2m/example-lwm2m-standalone"]
|
||||
path = tests/18-coap-lwm2m/example-lwm2m-standalone
|
||||
url = https://github.com/contiki-ng/example-lwm2m-standalone.git
|
||||
|
|
|
@ -26,6 +26,7 @@ env:
|
|||
- TEST_NAME='rpl-lite'
|
||||
- TEST_NAME='rpl-classic'
|
||||
- TEST_NAME='tun-rpl-br'
|
||||
- TEST_NAME='coap-lwm2m'
|
||||
- TEST_NAME='simulation-base'
|
||||
- TEST_NAME='ieee802154'
|
||||
- TEST_NAME='compile-nxp-ports'
|
||||
|
|
|
@ -360,6 +360,9 @@ viewconf:
|
|||
@echo "##### \"MAKE_MAC\": ______________________________ $(MAKE_MAC)"
|
||||
@echo "##### \"MAKE_NET\": ______________________________ $(MAKE_NET)"
|
||||
@echo "##### \"MAKE_ROUTING\": __________________________ $(MAKE_ROUTING)"
|
||||
ifdef MAKE_COAP_DTLS_KEYSTORE
|
||||
@echo "##### \"MAKE_COAP_DTLS_KEYSTORE\": _______________ $(MAKE_COAP_DTLS_KEYSTORE)"
|
||||
endif
|
||||
@echo "----------------- C variables: -----------------"
|
||||
$(Q)$(CC) $(CFLAGS) -E $(CONTIKI)/tools/viewconf.c | grep \#\#\#\#\#
|
||||
@echo "------------------------------------------------"
|
||||
|
|
|
@ -9,24 +9,13 @@ ifeq ($(TARGET),native)
|
|||
MODULES_REL += ./resources-plugtest
|
||||
endif
|
||||
MODULES_REL += ./resources
|
||||
MODULES_REL += $(TARGET)
|
||||
|
||||
# Include the CoAP implementation
|
||||
MODULES += os/net/app-layer/coap
|
||||
|
||||
# optional rules to get assembly
|
||||
#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1
|
||||
#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
||||
|
||||
# optional rules to get assembly
|
||||
#$(OBJECTDIR)/%.o: asmdir/%.S
|
||||
# $(CC) $(CFLAGS) -MMD -c $< -o $@
|
||||
# @$(FINALIZE_DEPENDENCY)
|
||||
#
|
||||
#asmdir/%.S: %.c
|
||||
# $(CC) $(CFLAGS) -MMD -S $< -o $@
|
||||
|
||||
# border router rules
|
||||
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
|
||||
(cd $(CONTIKI)/tools && $(MAKE) tunslip6)
|
||||
|
@ -37,8 +26,8 @@ connect-router: $(CONTIKI)/tools/tunslip6
|
|||
connect-router-cooja: $(CONTIKI)/tools/tunslip6
|
||||
sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 fd00::1/64
|
||||
|
||||
connect-router-native: $(CONTIKI)/examples/native-border-router/border-router.native
|
||||
sudo $(CONTIKI)/examples/native-border-router/border-router.native -a 127.0.0.1 -p 60001 fd00::1/64
|
||||
connect-router-native: $(CONTIKI)/examples/rpl-border-router/border-router.native
|
||||
sudo $(CONTIKI)/examples/rpl-border-router/border-router.native -a 127.0.0.1 -p 60001 fd00::1/64
|
||||
|
||||
connect-minimal:
|
||||
sudo ip address add fdfd::1/64 dev tap0
|
||||
connect-native:
|
||||
sudo ip address add fdfd::1/64 dev tun0
|
||||
|
|
|
@ -1,109 +1,44 @@
|
|||
A Quick Introduction to the Erbium (Er) REST Engine
|
||||
A Quick Introduction to the Erbium (Er) CoAP Engine
|
||||
===================================================
|
||||
|
||||
EXAMPLE FILES
|
||||
-------------
|
||||
|
||||
- coap-example-server.c: A RESTful server example showing how to use the REST
|
||||
layer to develop server-side applications (at the moment only CoAP is
|
||||
implemented for the REST Engine).
|
||||
- coap-example-server.c: A CoAP server example showing how to use the CoAP
|
||||
layer to develop server-side applications.
|
||||
- coap-example-client.c: A CoAP client that polls the /actuators/toggle resource
|
||||
every 10 seconds and cycles through 4 resources on button press (target
|
||||
address is hard-coded).
|
||||
- plugtest-server.c: The server used for draft compliance testing at ETSI
|
||||
IoT CoAP Plugtests. Erbium (Er) participated in Paris, France, March 2012 and
|
||||
Sophia-Antipolis, France, November 2012 (configured for minimal-net).
|
||||
Sophia-Antipolis, France, November 2012 (configured for native).
|
||||
|
||||
PRELIMINARIES
|
||||
-------------
|
||||
|
||||
- Make sure rpl-border-router has the same stack and fits into mote memory:
|
||||
You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on).
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
- Alternatively, you can use the native-border-router together with the slip-radio.
|
||||
- For convenience, define the Cooja addresses in /etc/hosts
|
||||
fd00::0212:7401:0001:0101 cooja1
|
||||
fd00::0212:7402:0002:0202 cooja2
|
||||
...
|
||||
- Get the Copper (Cu) CoAP user-agent from
|
||||
[https://addons.mozilla.org/en-US/firefox/addon/copper-270430](https://addons.mozilla.org/en-US/firefox/addon/copper-270430)
|
||||
- Optional: Save your target as default target
|
||||
make TARGET=sky savetarget
|
||||
|
||||
COOJA HOWTO
|
||||
-----------
|
||||
TMOTE SKY HOWTO
|
||||
---------------
|
||||
|
||||
###Server only:
|
||||
The CoAP example no longer fits in the limited ROM of the Tmote Sky.
|
||||
Please use a platform with larger ROM instead.
|
||||
|
||||
make TARGET=cooja server-only.csc
|
||||
|
||||
Open new terminal
|
||||
|
||||
make connect-router-cooja
|
||||
|
||||
- Start Copper and discover resources at coap://cooja2:5683/
|
||||
- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after
|
||||
requesting /test/separate
|
||||
- Do the same when observing /test/event
|
||||
|
||||
###With client:
|
||||
|
||||
make TARGET=cooja server-client.csc
|
||||
|
||||
Open new terminal
|
||||
|
||||
make connect-router-cooja
|
||||
|
||||
- Wait until red LED toggles on mote 2 (server)
|
||||
- Choose "Click button on Sky 3" from the context menu of mote 3 (client) and
|
||||
watch serial output
|
||||
|
||||
TMOTES HOWTO
|
||||
NATIVE HOWTO
|
||||
------------
|
||||
|
||||
###Server:
|
||||
|
||||
1. Connect two Tmote Skys (check with $ make TARGET=sky sky-motelist)
|
||||
|
||||
make TARGET=sky coap-example-server.upload MOTE=2
|
||||
make TARGET=sky login MOTE=2
|
||||
|
||||
2. Press reset button, get address, abort with Ctrl+C:
|
||||
Line: "Tentative link-local IPv6 address fe80:0000:0000:0000:____:____:____:____"
|
||||
|
||||
cd ../rpl-border-router/
|
||||
make TARGET=sky border-router.upload MOTE=1
|
||||
make connect-router
|
||||
|
||||
For a BR tty other than USB0:
|
||||
|
||||
make connect-router-port PORT=X
|
||||
|
||||
3. Start Copper and discover resources at:
|
||||
|
||||
coap://[fd00::____:____:____:____]:5683/
|
||||
|
||||
### Add a client:
|
||||
|
||||
1. Change the hard-coded server address in coap-example-client.c to fd00::____:____:____:____
|
||||
2. Connect a third Tmote Sky
|
||||
|
||||
make TARGET=sky coap-example-client.upload MOTE=3
|
||||
|
||||
MINIMAL-NET HOWTO
|
||||
-----------------
|
||||
|
||||
With the target minimal-net you can test your CoAP applications without
|
||||
With the target native you can test your CoAP applications without
|
||||
constraints, i.e., with large buffers, debug output, memory protection, etc.
|
||||
The plugtest-server is thought for the minimal-net platform, as it requires
|
||||
The plugtest-server is thought for the native platform, as it requires
|
||||
an 1280-byte IP buffer and 1024-byte blocks.
|
||||
|
||||
make TARGET=minimal-net plugtest-server
|
||||
sudo ./plugtest-server.minimal-net
|
||||
make TARGET=native plugtest-server
|
||||
sudo ./plugtest-server.native
|
||||
|
||||
Open new terminal
|
||||
|
||||
make connect-minimal
|
||||
make connect-native
|
||||
|
||||
- Start Copper and discover resources at coap://[fdfd::ff:fe00:10]:5683/
|
||||
- You can enable the ETSI Plugtest menu in Copper's preferences
|
||||
|
@ -130,12 +65,12 @@ in coap-example-server.c. In general, coap supports:
|
|||
|
||||
- All draft-18 header options
|
||||
- CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS)
|
||||
- Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see plugtest-server.c for
|
||||
- Blockwise Transfers (note COAP_MAX_CHUNK_SIZE, see plugtest-server.c for
|
||||
Block1 uploads)
|
||||
- Separate Responses (no rest_set_pre_handler() required anymore, note
|
||||
coap_separate_accept(), _reject(), and _resume())
|
||||
- Resource Discovery
|
||||
- Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note
|
||||
- Observing Resources (see EVENT_ and PERIODIC_RESOURCE, note
|
||||
COAP_MAX_OBSERVERS)
|
||||
|
||||
TODOs
|
||||
|
|
|
@ -42,33 +42,22 @@
|
|||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap-blocking-api.h"
|
||||
#include "dev/button-sensor.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "client"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */
|
||||
#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) /* cooja2 */
|
||||
/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */
|
||||
|
||||
#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1)
|
||||
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
#define SERVER_EP "coap://[fe80::212:7402:0002:0202]"
|
||||
|
||||
#define TOGGLE_INTERVAL 10
|
||||
|
||||
PROCESS(er_example_client, "Erbium Example Client");
|
||||
AUTOSTART_PROCESSES(&er_example_client);
|
||||
|
||||
uip_ipaddr_t server_ipaddr;
|
||||
static struct etimer et;
|
||||
|
||||
/* Example URIs that can be queried. */
|
||||
|
@ -82,7 +71,7 @@ static int uri_switch = 0;
|
|||
|
||||
/* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */
|
||||
void
|
||||
client_chunk_handler(void *response)
|
||||
client_chunk_handler(coap_message_t *response)
|
||||
{
|
||||
const uint8_t *chunk;
|
||||
|
||||
|
@ -92,14 +81,15 @@ client_chunk_handler(void *response)
|
|||
}
|
||||
PROCESS_THREAD(er_example_client, ev, data)
|
||||
{
|
||||
coap_endpoint_t server_ep;
|
||||
PROCESS_BEGIN();
|
||||
|
||||
static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
static coap_message_t request[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
|
||||
SERVER_NODE(&server_ipaddr);
|
||||
coap_endpoint_parse(SERVER_EP, strlen(SERVER_EP), &server_ep);
|
||||
|
||||
/* receives all CoAP messages */
|
||||
coap_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND);
|
||||
|
||||
|
@ -122,11 +112,10 @@ PROCESS_THREAD(er_example_client, ev, data)
|
|||
|
||||
coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1);
|
||||
|
||||
PRINT6ADDR(&server_ipaddr);
|
||||
PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT));
|
||||
LOG_INFO_COAP_EP(&server_ep);
|
||||
LOG_INFO_("\n");
|
||||
|
||||
COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request,
|
||||
client_chunk_handler);
|
||||
COAP_BLOCKING_REQUEST(&server_ep, request, client_chunk_handler);
|
||||
|
||||
printf("\n--Done--\n");
|
||||
|
||||
|
@ -142,10 +131,10 @@ PROCESS_THREAD(er_example_client, ev, data)
|
|||
|
||||
printf("--Requesting %s--\n", service_urls[uri_switch]);
|
||||
|
||||
PRINT6ADDR(&server_ipaddr);
|
||||
PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT));
|
||||
LOG_INFO_COAP_EP(&server_ep);
|
||||
LOG_INFO_("\n");
|
||||
|
||||
COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request,
|
||||
COAP_BLOCKING_REQUEST(&server_ep, request,
|
||||
client_chunk_handler);
|
||||
|
||||
printf("\n--Done--\n");
|
||||
|
|
|
@ -49,19 +49,8 @@
|
|||
#if DEBUG
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINTFLN(format, ...) printf(format "\n", ##__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" \
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x]", \
|
||||
((uint8_t *)addr)[0], ((uint8_t *)addr)[1], \
|
||||
((uint8_t *)addr)[2], ((uint8_t *)addr)[3], \
|
||||
((uint8_t *)addr)[4], ((uint8_t *)addr)[5], \
|
||||
((uint8_t *)addr)[6], ((uint8_t *)addr)[7], \
|
||||
((uint8_t *)addr)[8], ((uint8_t *)addr)[9], \
|
||||
((uint8_t *)addr)[10], ((uint8_t *)addr)[11], \
|
||||
((uint8_t *)addr)[12], ((uint8_t *)addr)[13], \
|
||||
((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTFLN(...)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
/**
|
||||
* \file
|
||||
* Erbium (Er) REST Engine example.
|
||||
* Erbium (Er) CoAP Engine example.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
@ -40,8 +40,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
#if PLATFORM_HAS_BUTTON
|
||||
#include "dev/button-sensor.h"
|
||||
|
@ -51,19 +50,15 @@
|
|||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Resources to be activated need to be imported through the extern keyword.
|
||||
* The build system automatically compiles the resources in the corresponding sub-directory.
|
||||
*/
|
||||
extern resource_t
|
||||
extern coap_resource_t
|
||||
res_hello,
|
||||
res_mirror,
|
||||
res_chunks,
|
||||
|
@ -73,29 +68,29 @@ extern resource_t
|
|||
res_sub,
|
||||
res_b1_sep_b2;
|
||||
#if PLATFORM_HAS_LEDS
|
||||
extern resource_t res_leds, res_toggle;
|
||||
extern coap_resource_t res_leds, res_toggle;
|
||||
#endif
|
||||
#if PLATFORM_HAS_LIGHT
|
||||
#include "dev/light-sensor.h"
|
||||
extern resource_t res_light;
|
||||
extern coap_resource_t res_light;
|
||||
#endif
|
||||
#if PLATFORM_HAS_BATTERY
|
||||
#include "dev/battery-sensor.h"
|
||||
extern resource_t res_battery;
|
||||
extern coap_resource_t res_battery;
|
||||
#endif
|
||||
#if PLATFORM_HAS_TEMPERATURE
|
||||
#include "dev/temperature-sensor.h"
|
||||
extern resource_t res_temperature;
|
||||
extern coap_resource_t res_temperature;
|
||||
#endif
|
||||
/*
|
||||
extern resource_t res_battery;
|
||||
extern coap_resource_t res_battery;
|
||||
#endif
|
||||
#if PLATFORM_HAS_RADIO
|
||||
extern resource_t res_radio;
|
||||
extern coap_resource_t res_radio;
|
||||
#endif
|
||||
#if PLATFORM_HAS_SHT11
|
||||
#include "dev/sht11/sht11-sensor.h"
|
||||
extern resource_t res_sht11;
|
||||
extern coap_resource_t res_sht11;
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
@ -120,47 +115,49 @@ PROCESS_THREAD(er_example_server, ev, data)
|
|||
PRINTF("uIP buffer: %u\n", UIP_BUFSIZE);
|
||||
PRINTF("LL header: %u\n", UIP_LLH_LEN);
|
||||
PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN);
|
||||
PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE);
|
||||
PRINTF("CoAP max chunk: %u\n", COAP_MAX_CHUNK_SIZE);
|
||||
|
||||
/* Initialize the REST engine. */
|
||||
rest_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
/*
|
||||
* Bind the resources to their Uri-Path.
|
||||
* WARNING: Activating twice only means alternate path, not two instances!
|
||||
* All static variables are the same for each URI path.
|
||||
*/
|
||||
rest_activate_resource(&res_hello, "test/hello");
|
||||
/* rest_activate_resource(&res_mirror, "debug/mirror"); */
|
||||
/* rest_activate_resource(&res_chunks, "test/chunks"); */
|
||||
/* rest_activate_resource(&res_separate, "test/separate"); */
|
||||
rest_activate_resource(&res_push, "test/push");
|
||||
/* rest_activate_resource(&res_event, "sensors/button"); */
|
||||
/* rest_activate_resource(&res_sub, "test/sub"); */
|
||||
/* rest_activate_resource(&res_b1_sep_b2, "test/b1sepb2"); */
|
||||
coap_activate_resource(&res_hello, "test/hello");
|
||||
coap_activate_resource(&res_mirror, "debug/mirror");
|
||||
coap_activate_resource(&res_chunks, "test/chunks");
|
||||
coap_activate_resource(&res_separate, "test/separate");
|
||||
coap_activate_resource(&res_push, "test/push");
|
||||
#if PLATFORM_HAS_BUTTON
|
||||
coap_activate_resource(&res_event, "sensors/button");
|
||||
#endif /* PLATFORM_HAS_BUTTON */
|
||||
coap_activate_resource(&res_sub, "test/sub");
|
||||
coap_activate_resource(&res_b1_sep_b2, "test/b1sepb2");
|
||||
#if PLATFORM_HAS_LEDS
|
||||
/* rest_activate_resource(&res_leds, "actuators/leds"); */
|
||||
rest_activate_resource(&res_toggle, "actuators/toggle");
|
||||
/* coap_activate_resource(&res_leds, "actuators/leds"); */
|
||||
coap_activate_resource(&res_toggle, "actuators/toggle");
|
||||
#endif
|
||||
#if PLATFORM_HAS_LIGHT
|
||||
rest_activate_resource(&res_light, "sensors/light");
|
||||
SENSORS_ACTIVATE(light_sensor);
|
||||
coap_activate_resource(&res_light, "sensors/light");
|
||||
SENSORS_ACTIVATE(light_sensor);
|
||||
#endif
|
||||
#if PLATFORM_HAS_BATTERY
|
||||
rest_activate_resource(&res_battery, "sensors/battery");
|
||||
SENSORS_ACTIVATE(battery_sensor);
|
||||
coap_activate_resource(&res_battery, "sensors/battery");
|
||||
SENSORS_ACTIVATE(battery_sensor);
|
||||
#endif
|
||||
#if PLATFORM_HAS_TEMPERATURE
|
||||
rest_activate_resource(&res_temperature, "sensors/temperature");
|
||||
SENSORS_ACTIVATE(temperature_sensor);
|
||||
coap_activate_resource(&res_temperature, "sensors/temperature");
|
||||
SENSORS_ACTIVATE(temperature_sensor);
|
||||
#endif
|
||||
/*
|
||||
#if PLATFORM_HAS_RADIO
|
||||
rest_activate_resource(&res_radio, "sensors/radio");
|
||||
coap_activate_resource(&res_radio, "sensors/radio");
|
||||
#endif
|
||||
#if PLATFORM_HAS_SHT11
|
||||
rest_activate_resource(&res_sht11, "sensors/sht11");
|
||||
SENSORS_ACTIVATE(sht11_sensor);
|
||||
coap_activate_resource(&res_sht11, "sensors/sht11");
|
||||
SENSORS_ACTIVATE(sht11_sensor);
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
21,23c21
|
||||
< #ifdef __INSIDE_CYGWIN__
|
||||
< uint32_t __s6_addr32[4];
|
||||
< #endif
|
||||
---
|
||||
> u_int __s6_addr32[4];
|
||||
36d33
|
||||
< #ifdef __INSIDE_CYGWIN__
|
||||
39d35
|
||||
< #endif
|
|
@ -44,7 +44,7 @@
|
|||
#include "coap.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "coap-separate.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
/*
|
||||
|
@ -52,7 +52,7 @@
|
|||
* The build system automatically compiles the resources in the corresponding
|
||||
* sub-directory.
|
||||
*/
|
||||
extern resource_t
|
||||
extern coap_resource_t
|
||||
res_plugtest_test,
|
||||
res_plugtest_validate,
|
||||
res_plugtest_create1,
|
||||
|
@ -95,29 +95,29 @@ PROCESS_THREAD(plugtest_server, ev, data)
|
|||
PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE);
|
||||
|
||||
/* Initialize the REST engine. */
|
||||
rest_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
/* Activate the application-specific resources. */
|
||||
rest_activate_resource(&res_plugtest_test, "test");
|
||||
rest_activate_resource(&res_plugtest_validate, "validate");
|
||||
rest_activate_resource(&res_plugtest_create1, "create1");
|
||||
rest_activate_resource(&res_plugtest_create2, "create2");
|
||||
rest_activate_resource(&res_plugtest_create3, "create3");
|
||||
rest_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3");
|
||||
rest_activate_resource(&res_plugtest_query, "query");
|
||||
rest_activate_resource(&res_plugtest_locquery, "location-query");
|
||||
rest_activate_resource(&res_plugtest_multi, "multi-format");
|
||||
rest_activate_resource(&res_plugtest_link1, "link1");
|
||||
rest_activate_resource(&res_plugtest_link2, "link2");
|
||||
rest_activate_resource(&res_plugtest_link3, "link3");
|
||||
rest_activate_resource(&res_plugtest_path, "path");
|
||||
rest_activate_resource(&res_plugtest_separate, "separate");
|
||||
rest_activate_resource(&res_plugtest_large, "large");
|
||||
rest_activate_resource(&res_plugtest_large_update, "large-update");
|
||||
rest_activate_resource(&res_plugtest_large_create, "large-create");
|
||||
rest_activate_resource(&res_plugtest_obs, "obs");
|
||||
coap_activate_resource(&res_plugtest_test, "test");
|
||||
coap_activate_resource(&res_plugtest_validate, "validate");
|
||||
coap_activate_resource(&res_plugtest_create1, "create1");
|
||||
coap_activate_resource(&res_plugtest_create2, "create2");
|
||||
coap_activate_resource(&res_plugtest_create3, "create3");
|
||||
coap_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3");
|
||||
coap_activate_resource(&res_plugtest_query, "query");
|
||||
coap_activate_resource(&res_plugtest_locquery, "location-query");
|
||||
coap_activate_resource(&res_plugtest_multi, "multi-format");
|
||||
coap_activate_resource(&res_plugtest_link1, "link1");
|
||||
coap_activate_resource(&res_plugtest_link2, "link2");
|
||||
coap_activate_resource(&res_plugtest_link3, "link3");
|
||||
coap_activate_resource(&res_plugtest_path, "path");
|
||||
coap_activate_resource(&res_plugtest_separate, "separate");
|
||||
coap_activate_resource(&res_plugtest_large, "large");
|
||||
coap_activate_resource(&res_plugtest_large_update, "large-update");
|
||||
coap_activate_resource(&res_plugtest_large_create, "large-create");
|
||||
coap_activate_resource(&res_plugtest_obs, "obs");
|
||||
|
||||
rest_activate_resource(&res_mirror, "mirror");
|
||||
coap_activate_resource(&res_mirror, "mirror");
|
||||
|
||||
/* Define application-specific events here. */
|
||||
while(1) {
|
||||
|
|
|
@ -47,12 +47,8 @@
|
|||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
/* double expansion */
|
||||
|
|
|
@ -36,43 +36,37 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef __PROJECT_ERBIUM_CONF_H__
|
||||
#define __PROJECT_ERBIUM_CONF_H__
|
||||
#ifndef PROJECT_ERBIUM_CONF_H_
|
||||
#define PROJECT_ERBIUM_CONF_H_
|
||||
|
||||
/* Custom channel and PAN ID configuration for your project. */
|
||||
/*
|
||||
#define RF_CHANNEL 26
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
*/
|
||||
/* #define RF_CHANNEL 26 */
|
||||
/* #define IEEE802154_CONF_PANID 0xABCD */
|
||||
|
||||
/* IP buffer size must match all other hops, in particular the border router. */
|
||||
/*
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
*/
|
||||
/* #define UIP_CONF_BUFFER_SIZE 256 */
|
||||
|
||||
/* Increase rpl-border-router IP-buffer when using more than 64. */
|
||||
#define REST_MAX_CHUNK_SIZE 48
|
||||
#define COAP_MAX_CHUNK_SIZE 48
|
||||
|
||||
/* Estimate your header size, especially when using Proxy-Uri. */
|
||||
/*
|
||||
#define COAP_MAX_HEADER_SIZE 70
|
||||
*/
|
||||
/* #define COAP_MAX_HEADER_SIZE 70 */
|
||||
|
||||
/* Multiplies with chunk size, be aware of memory constraints. */
|
||||
#ifndef COAP_MAX_OPEN_TRANSACTIONS
|
||||
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
||||
#endif /* COAP_MAX_OPEN_TRANSACTIONS */
|
||||
|
||||
/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */
|
||||
/*
|
||||
#define COAP_MAX_OBSERVERS 2
|
||||
*/
|
||||
/* #define COAP_MAX_OBSERVERS 2 */
|
||||
|
||||
/* Filtering .well-known/core per query can be disabled to save space. */
|
||||
#define COAP_LINK_FORMAT_FILTERING 0
|
||||
#define COAP_PROXY_OPTION_PROCESSING 0
|
||||
|
||||
/* Turn off DAO-ACK to make code smaller */
|
||||
#define RPL_CONF_WITH_DAO_ACK 0
|
||||
|
||||
/* Enable client-side support for COAP observe */
|
||||
#define COAP_OBSERVE_CLIENT 1
|
||||
#endif /* __PROJECT_ERBIUM_CONF_H__ */
|
||||
#ifndef COAP_OBSERVE_CLIENT
|
||||
#define COAP_OBSERVE_CLIENT 1
|
||||
#endif /* COAP_OBSERVE_CLIENT */
|
||||
|
||||
#endif /* PROJECT_ERBIUM_CONF_H_ */
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create1,
|
||||
"title=\"Creates on PUT\"",
|
||||
|
@ -54,27 +54,27 @@ RESOURCE(res_plugtest_create1,
|
|||
static uint8_t create1_exists = 0;
|
||||
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create1 PUT");
|
||||
|
||||
if(coap_get_header_if_none_match(request)) {
|
||||
if(!create1_exists) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
|
||||
create1_exists = 1;
|
||||
} else {
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
coap_set_status_code(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
}
|
||||
}
|
||||
static void
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create1 DELETE ");
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
coap_set_status_code(response, DELETED_2_02);
|
||||
|
||||
create1_exists = 0;
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create2,
|
||||
"title=\"Creates on POST\"",
|
||||
|
@ -51,10 +51,10 @@ RESOURCE(res_plugtest_create2,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create2 ");
|
||||
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "/location1/location2/location3");
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
coap_set_header_location_path(response, "/location1/location2/location3");
|
||||
}
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create3,
|
||||
"title=\"Default test resource\"",
|
||||
|
@ -54,27 +54,27 @@ RESOURCE(res_plugtest_create3,
|
|||
static uint8_t create3_exists = 0;
|
||||
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create3 PUT ");
|
||||
|
||||
if(coap_get_header_if_none_match(request)) {
|
||||
if(!create3_exists) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
|
||||
create3_exists = 1;
|
||||
} else {
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
coap_set_status_code(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
}
|
||||
}
|
||||
static void
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create3 DELETE ");
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
coap_set_status_code(response, DELETED_2_02);
|
||||
|
||||
create3_exists = 0;
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* Large resource that can be created using POST method
|
||||
|
@ -54,38 +54,38 @@ RESOURCE(res_plugtest_large_create,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
uint8_t *incoming = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
unsigned int ct = -1;
|
||||
|
||||
if(!REST.get_header_content_type(request, &ct)) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
if(!coap_get_header_content_format(request, &ct)) {
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
const char *error_msg = "NoContentType";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) {
|
||||
if((len = coap_get_payload(request, (const uint8_t **)&incoming))) {
|
||||
if(coap_req->block1_num * coap_req->block1_size + len <= 2048) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "/nirvana");
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
coap_set_header_location_path(response, "/nirvana");
|
||||
coap_set_header_block1(response, coap_req->block1_num, 0,
|
||||
coap_req->block1_size);
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
coap_set_status_code(response, REQUEST_ENTITY_TOO_LARGE_4_13);
|
||||
const char *error_msg = "2048B max.";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
const char *error_msg = "NoPayload";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sys/cc.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(
|
||||
res_plugtest_large_update,
|
||||
|
@ -58,21 +59,21 @@ static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 };
|
|||
static unsigned int large_update_ct = APPLICATION_OCTET_STREAM;
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Check the offset for boundaries of the resource data. */
|
||||
if(*offset >= large_update_size) {
|
||||
REST.set_response_status(response, REST.status.BAD_OPTION);
|
||||
coap_set_status_code(response, BAD_OPTION_4_02);
|
||||
/* A block error message should not exceed the minimum block size (16). */
|
||||
|
||||
const char *error_msg = "BlockOutOfScope";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, large_update_store + *offset,
|
||||
coap_set_payload(response, large_update_store + *offset,
|
||||
MIN(large_update_size - *offset, preferred_size));
|
||||
REST.set_header_content_type(response, large_update_ct);
|
||||
coap_set_header_content_format(response, large_update_ct);
|
||||
|
||||
/* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
|
||||
*offset += preferred_size;
|
||||
|
@ -83,22 +84,22 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
}
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
uint8_t *incoming = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
unsigned int ct = -1;
|
||||
|
||||
if(!REST.get_header_content_type(request, &ct)) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
if(!coap_get_header_content_format(request, &ct)) {
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
const char *error_msg = "NoContentType";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) {
|
||||
if((len = coap_get_payload(request, (const uint8_t **)&incoming))) {
|
||||
if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) {
|
||||
memcpy(
|
||||
large_update_store + coap_req->block1_num * coap_req->block1_size,
|
||||
|
@ -106,13 +107,13 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
large_update_size = coap_req->block1_num * coap_req->block1_size + len;
|
||||
large_update_ct = ct;
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
coap_set_header_block1(response, coap_req->block1_num, 0,
|
||||
coap_req->block1_size);
|
||||
} else {
|
||||
REST.set_response_status(response,
|
||||
REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
REST.set_response_payload(
|
||||
coap_set_status_code(response,
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.",
|
||||
|
@ -120,9 +121,9 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
const char *error_msg = "NoPayload";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_large,
|
||||
"title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"",
|
||||
|
@ -51,17 +52,17 @@ RESOURCE(res_plugtest_large,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int32_t strpos = 0;
|
||||
|
||||
/* Check the offset for boundaries of the resource data. */
|
||||
if(*offset >= CHUNKS_TOTAL) {
|
||||
REST.set_response_status(response, REST.status.BAD_OPTION);
|
||||
coap_set_status_code(response, BAD_OPTION_4_02);
|
||||
/* A block error message should not exceed the minimum block size (16). */
|
||||
|
||||
const char *error_msg = "BlockOutOfScope";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,8 +80,8 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
if(*offset + (int32_t)strpos > CHUNKS_TOTAL) {
|
||||
strpos = CHUNKS_TOTAL - *offset;
|
||||
}
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
coap_set_payload(response, buffer, strpos);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
|
||||
/* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
|
||||
*offset += strpos;
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_link1,
|
||||
"rt=\"Type1 Type2\";if=\"If1\"",
|
||||
|
@ -63,9 +63,9 @@ RESOURCE(res_plugtest_link3,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *msg = "Dummy link";
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_locquery,
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
|
@ -51,15 +51,15 @@ RESOURCE(res_plugtest_locquery,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
#if DEBUG
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
#endif
|
||||
|
||||
PRINTF(
|
||||
"/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "?first=1&second=2");
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
coap_set_header_location_query(response, "?first=1&second=2");
|
||||
}
|
||||
|
|
|
@ -36,12 +36,14 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_longpath,
|
||||
"title=\"Long path resource\"",
|
||||
|
@ -51,14 +53,14 @@ RESOURCE(res_plugtest_longpath,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
PRINTF("/seg1/seg2/seg3 GET ");
|
||||
/* Code 2.05 CONTENT is default. */
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_multi,
|
||||
"title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"",
|
||||
|
@ -51,27 +52,27 @@ RESOURCE(res_plugtest_multi,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
PRINTF("/multi-format GET (%s %u) ", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code,
|
||||
coap_req->mid, accept != -1 ? "\nAccept: 0" : ""));
|
||||
PRINTF("PLAIN\n");
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
REST.set_response_payload(
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
|
@ -79,9 +80,9 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
coap_req->type, coap_req->code, coap_req->mid, accept));
|
||||
PRINTF("XML\n");
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain and application/xml";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
PRINTF("ERROR\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,15 +36,16 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "coap-observe.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_periodic_handler(void);
|
||||
|
||||
PERIODIC_RESOURCE(res_plugtest_obs,
|
||||
|
@ -67,35 +68,35 @@ static void
|
|||
obs_purge_list()
|
||||
{
|
||||
PRINTF("### SERVER ACTION ### Purging obs list");
|
||||
coap_remove_observer_by_uri(NULL, 0, res_plugtest_obs.url);
|
||||
coap_remove_observer_by_uri(NULL, res_plugtest_obs.url);
|
||||
}
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Keep server log clean from ticking events */
|
||||
if(request != NULL) {
|
||||
PRINTF("/obs GET\n");
|
||||
}
|
||||
REST.set_header_content_type(response, obs_format);
|
||||
REST.set_header_max_age(response, 5);
|
||||
coap_set_header_content_format(response, obs_format);
|
||||
coap_set_header_max_age(response, 5);
|
||||
|
||||
if(obs_content_len) {
|
||||
REST.set_header_content_type(response, obs_format);
|
||||
REST.set_response_payload(response, obs_content, obs_content_len);
|
||||
coap_set_header_content_format(response, obs_format);
|
||||
coap_set_payload(response, obs_content, obs_content_len);
|
||||
} else {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, obs_content,
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, obs_content,
|
||||
snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", (unsigned long) obs_counter));
|
||||
}
|
||||
/* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */
|
||||
/* A post_handler that handles subscriptions will be called for periodic resources by the CoAP framework. */
|
||||
}
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
uint8_t *incoming = NULL;
|
||||
unsigned int ct = -1;
|
||||
|
||||
REST.get_header_content_type(request, &ct);
|
||||
coap_get_header_content_format(request, &ct);
|
||||
|
||||
PRINTF("/obs PUT\n");
|
||||
|
||||
|
@ -103,26 +104,26 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
obs_status = 1;
|
||||
obs_format = ct;
|
||||
} else {
|
||||
obs_content_len = REST.get_request_payload(request,
|
||||
obs_content_len = coap_get_payload(request,
|
||||
(const uint8_t **)&incoming);
|
||||
memcpy(obs_content, incoming, obs_content_len);
|
||||
res_periodic_handler();
|
||||
}
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
}
|
||||
static void
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/obs DELETE\n");
|
||||
|
||||
obs_status = 2;
|
||||
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
coap_set_status_code(response, DELETED_2_02);
|
||||
}
|
||||
/*
|
||||
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
|
||||
* It will be called by the REST manager process with the defined period.
|
||||
* It will be called by the CoAP manager process with the defined period.
|
||||
*/
|
||||
static void
|
||||
res_periodic_handler()
|
||||
|
@ -134,7 +135,7 @@ res_periodic_handler()
|
|||
if(obs_status == 1) {
|
||||
|
||||
/* Notify the registered observers with the given message type, observe option, and payload. */
|
||||
REST.notify_subscribers(&res_plugtest_obs);
|
||||
coap_notify_observers(&res_plugtest_obs);
|
||||
|
||||
PRINTF("######### sending 5.00\n");
|
||||
|
||||
|
@ -142,7 +143,7 @@ res_periodic_handler()
|
|||
} else if(obs_status == 2) {
|
||||
|
||||
/* Notify the registered observers with the given message type, observe option, and payload. */
|
||||
REST.notify_subscribers(&res_plugtest_obs);
|
||||
coap_notify_observers(&res_plugtest_obs);
|
||||
|
||||
obs_purge_list();
|
||||
|
||||
|
@ -150,6 +151,6 @@ res_periodic_handler()
|
|||
obs_content_len = 0;
|
||||
} else {
|
||||
/* Notify the registered observers with the given message type, observe option, and payload. */
|
||||
REST.notify_subscribers(&res_plugtest_obs);
|
||||
coap_notify_observers(&res_plugtest_obs);
|
||||
} obs_status = 0;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
PARENT_RESOURCE(res_plugtest_path,
|
||||
"title=\"Path test resource\";ct=\"40\"",
|
||||
|
@ -51,22 +52,22 @@ PARENT_RESOURCE(res_plugtest_path,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
|
||||
const char *uri_path = NULL;
|
||||
int len = REST.get_url(request, &uri_path);
|
||||
int len = coap_get_header_uri_path(request, &uri_path);
|
||||
int base_len = strlen(res_plugtest_path.url);
|
||||
|
||||
if(len == base_len) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT);
|
||||
coap_set_header_content_format(response, APPLICATION_LINK_FORMAT);
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"</path/sub1>,</path/sub2>,</path/sub3>");
|
||||
} else {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path);
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_query,
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
|
@ -51,22 +52,22 @@ RESOURCE(res_plugtest_query,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
int len = 0;
|
||||
const char *query = NULL;
|
||||
|
||||
PRINTF(
|
||||
"/query GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if((len = REST.get_query(request, &query))) {
|
||||
if((len = coap_get_header_uri_query(request, &query))) {
|
||||
PRINTF("Query: %.*s\n", len, query);
|
||||
/* Code 2.05 CONTENT is default. */
|
||||
}
|
||||
REST.set_header_content_type(response,
|
||||
REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(
|
||||
coap_set_header_content_format(response,
|
||||
TEXT_PLAIN);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "coap-separate.h"
|
||||
#include "plugtest.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_resume_handler(void);
|
||||
|
||||
PERIODIC_RESOURCE(res_plugtest_separate,
|
||||
|
@ -67,9 +68,9 @@ static uint8_t separate_active = 0;
|
|||
static application_separate_store_t separate_store[1];
|
||||
|
||||
void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
PRINTF("/separate ");
|
||||
if(separate_active) {
|
||||
|
@ -97,17 +98,16 @@ res_resume_handler()
|
|||
PRINTF("/separate ");
|
||||
coap_transaction_t *transaction = NULL;
|
||||
if((transaction = coap_new_transaction(separate_store->request_metadata.mid,
|
||||
&separate_store->request_metadata.addr,
|
||||
separate_store->request_metadata.port))) {
|
||||
&separate_store->request_metadata.endpoint))) {
|
||||
PRINTF(
|
||||
"RESPONSE (%s %u)\n", separate_store->request_metadata.type == COAP_TYPE_CON ? "CON" : "NON", separate_store->request_metadata.mid);
|
||||
|
||||
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
coap_message_t response[1]; /* This way the message can be treated as pointer as usual. */
|
||||
|
||||
/* Restore the request information for the response. */
|
||||
coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05);
|
||||
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, separate_store->buffer,
|
||||
strlen(separate_store->buffer));
|
||||
|
||||
|
@ -120,8 +120,8 @@ res_resume_handler()
|
|||
separate_store->request_metadata.block2_size);
|
||||
|
||||
/* Warning: No check for serialization error. */
|
||||
transaction->packet_len = coap_serialize_message(response,
|
||||
transaction->packet);
|
||||
transaction->message_len = coap_serialize_message(response,
|
||||
transaction->message);
|
||||
coap_send_transaction(transaction);
|
||||
/* The engine will clear the transaction (right after send for NON, after acked for CON). */
|
||||
|
||||
|
|
|
@ -36,15 +36,17 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
#include "random.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_test, "title=\"Default test resource\"", res_get_handler, res_post_handler, res_put_handler, res_delete_handler);
|
||||
|
||||
|
@ -69,9 +71,9 @@ test_update_etag()
|
|||
PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", test_etag_len, test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]);
|
||||
}
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
if(test_change) {
|
||||
test_update_etag();
|
||||
|
@ -82,48 +84,48 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
&& len == test_etag_len
|
||||
&& memcmp(test_etag, bytes, len) == 0) {
|
||||
PRINTF("validate ");
|
||||
REST.set_response_status(response, REST.status.NOT_MODIFIED);
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
coap_set_status_code(response, VALID_2_03);
|
||||
coap_set_header_etag(response, test_etag, test_etag_len);
|
||||
|
||||
test_change = 1;
|
||||
PRINTF("### SERVER ACTION ### Resource will change\n");
|
||||
} else {
|
||||
/* Code 2.05 CONTENT is default. */
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
REST.set_header_max_age(response, 30);
|
||||
REST.set_response_payload(
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_header_etag(response, test_etag, test_etag_len);
|
||||
coap_set_header_max_age(response, 30);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
|
||||
}
|
||||
}
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
#if DEBUG
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
#endif
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "/location1/location2/location3");
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
coap_set_header_location_path(response, "/location1/location2/location3");
|
||||
}
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
#if DEBUG
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
#endif
|
||||
|
||||
if(coap_get_header_if_none_match(request)) {
|
||||
if(test_none_match_okay) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
coap_set_status_code(response, CREATED_2_01);
|
||||
|
||||
test_none_match_okay = 0;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n");
|
||||
} else {
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
coap_set_status_code(response, PRECONDITION_FAILED_4_12);
|
||||
|
||||
test_none_match_okay = 1;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n");
|
||||
|
@ -133,9 +135,9 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
&& memcmp(test_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
test_update_etag();
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
coap_set_header_etag(response, test_etag, test_etag_len);
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
|
||||
if(len > 0) {
|
||||
test_change = 1;
|
||||
|
@ -148,15 +150,15 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]);
|
||||
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
coap_set_status_code(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
}
|
||||
static void
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
#if DEBUG
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
#endif
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
coap_set_status_code(response, DELETED_2_02);
|
||||
}
|
||||
|
|
|
@ -36,13 +36,15 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "plugtest.h"
|
||||
#include "random.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_validate,
|
||||
"title=\"Validation test resource\"",
|
||||
|
@ -72,9 +74,9 @@ validate_update_etag()
|
|||
validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
}
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
|
||||
if(validate_change) {
|
||||
validate_update_etag();
|
||||
|
@ -85,17 +87,17 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
if((len = coap_get_header_etag(request, &bytes)) > 0
|
||||
&& len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) {
|
||||
PRINTF("validate ");
|
||||
REST.set_response_status(response, REST.status.NOT_MODIFIED);
|
||||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
coap_set_status_code(response, VALID_2_03);
|
||||
coap_set_header_etag(response, validate_etag, validate_etag_len);
|
||||
|
||||
validate_change = 1;
|
||||
PRINTF("### SERVER ACTION ### Resouce will change\n");
|
||||
} else {
|
||||
/* Code 2.05 CONTENT is default. */
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
REST.set_header_max_age(response, 30);
|
||||
REST.set_response_payload(
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_header_etag(response, validate_etag, validate_etag_len);
|
||||
coap_set_header_max_age(response, 30);
|
||||
coap_set_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
|
@ -104,10 +106,10 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
}
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
#if DEBUG
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_req = (coap_message_t *)request;
|
||||
#endif
|
||||
|
||||
PRINTF("/validate PUT ");
|
||||
|
@ -118,9 +120,9 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
&& memcmp(validate_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
validate_update_etag();
|
||||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
coap_set_header_etag(response, validate_etag, validate_etag_len);
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
|
||||
if(len > 0) {
|
||||
validate_change = 1;
|
||||
|
@ -134,6 +136,6 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
coap_set_status_code(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,13 +36,14 @@
|
|||
* Lars Schmertmann <SmallLars@t-online.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap-block1.h"
|
||||
#include "coap-separate.h"
|
||||
#include "coap-transactions.h"
|
||||
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
SEPARATE_RESOURCE(res_b1_sep_b2, "title=\"Block1 + Separate + Block2 demo\"", NULL, res_post_handler, NULL, NULL, NULL);
|
||||
|
||||
#define MAX_DATA_LEN 256
|
||||
|
@ -52,7 +53,7 @@ static size_t big_msg_len = 0;
|
|||
static coap_separate_t request_metadata;
|
||||
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Example allows only one request on time. There are no checks for multiply access !!! */
|
||||
if(*offset == 0) {
|
||||
|
@ -75,8 +76,8 @@ res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t prefer
|
|||
|
||||
/* Send first block */
|
||||
coap_transaction_t *transaction = NULL;
|
||||
if((transaction = coap_new_transaction(request_metadata.mid, &request_metadata.addr, request_metadata.port))) {
|
||||
coap_packet_t resp[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
if((transaction = coap_new_transaction(request_metadata.mid, &request_metadata.endpoint))) {
|
||||
coap_message_t resp[1]; /* This way the message can be treated as pointer as usual. */
|
||||
|
||||
/* Restore the request information for the response. */
|
||||
coap_separate_resume(resp, &request_metadata, CONTENT_2_05);
|
||||
|
@ -88,7 +89,7 @@ res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t prefer
|
|||
}
|
||||
|
||||
/* Warning: No check for serialization error. */
|
||||
transaction->packet_len = coap_serialize_message(resp, transaction->packet);
|
||||
transaction->message_len = coap_serialize_message(resp, transaction->message);
|
||||
coap_send_transaction(transaction);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -41,10 +41,11 @@
|
|||
#if PLATFORM_HAS_BATTERY
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include <stdio.h>
|
||||
#include "coap-engine.h"
|
||||
#include "dev/battery-sensor.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
||||
RESOURCE(res_battery,
|
||||
|
@ -55,27 +56,27 @@ RESOURCE(res_battery,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int battery = battery_sensor.value(0);
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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", battery);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "%d", battery);
|
||||
|
||||
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, "{'battery':%d}", battery);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "{'battery':%d}", battery);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_BATTERY */
|
||||
|
|
|
@ -36,13 +36,14 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* For data larger than REST_MAX_CHUNK_SIZE (e.g., when stored in flash) resources must be aware of the buffer limitation
|
||||
* For data larger than COAP_MAX_CHUNK_SIZE (e.g., when stored in flash) resources must be aware of the buffer limitation
|
||||
* and split their responses by themselves. To transfer the complete resource through a TCP stream or CoAP's blockwise transfer,
|
||||
* the byte offset where to continue is provided to the handler as int32_t pointer.
|
||||
* These chunk-wise resources must set the offset value to its new position or -1 of the end is reached.
|
||||
|
@ -58,17 +59,17 @@ RESOURCE(res_chunks,
|
|||
#define CHUNKS_TOTAL 2050
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int32_t strpos = 0;
|
||||
|
||||
/* Check the offset for boundaries of the resource data. */
|
||||
if(*offset >= CHUNKS_TOTAL) {
|
||||
REST.set_response_status(response, REST.status.BAD_OPTION);
|
||||
coap_set_status_code(response, BAD_OPTION_4_02);
|
||||
/* A block error message should not exceed the minimum block size (16). */
|
||||
|
||||
const char *error_msg = "BlockOutOfScope";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
coap_set_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
if(*offset + (int32_t)strpos > CHUNKS_TOTAL) {
|
||||
strpos = CHUNKS_TOTAL - *offset;
|
||||
}
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
coap_set_payload(response, buffer, strpos);
|
||||
|
||||
/* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
|
||||
*offset += strpos;
|
||||
|
|
|
@ -36,8 +36,9 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
@ -52,7 +53,7 @@
|
|||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_event_handler(void);
|
||||
|
||||
/*
|
||||
|
@ -74,10 +75,10 @@ EVENT_RESOURCE(res_event,
|
|||
static int32_t event_counter = 0;
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", (unsigned long) event_counter));
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", (unsigned long) event_counter));
|
||||
|
||||
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
|
||||
}
|
||||
|
@ -96,6 +97,6 @@ res_event_handler(void)
|
|||
PRINTF("TICK %u for /%s\n", event_counter, res_event.url);
|
||||
|
||||
/* Notify the registered observers which will trigger the res_get_handler to create the response. */
|
||||
REST.notify_subscribers(&res_event);
|
||||
coap_notify_observers(&res_event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* A handler function named [resource name]_handler must be implemented for each RESOURCE.
|
||||
|
@ -56,7 +56,7 @@ RESOURCE(res_hello,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *len = NULL;
|
||||
/* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */
|
||||
|
@ -64,7 +64,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
int length = 12; /* |<-------->| */
|
||||
|
||||
/* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */
|
||||
if(REST.get_query_variable(request, "len", &len)) {
|
||||
if(coap_get_query_variable(request, "len", &len)) {
|
||||
length = atoi(len);
|
||||
if(length < 0) {
|
||||
length = 0;
|
||||
|
@ -75,7 +75,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
memcpy(buffer, message, length);
|
||||
} else {
|
||||
memcpy(buffer, message, length);
|
||||
} REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */
|
||||
REST.set_header_etag(response, (uint8_t *)&length, 1);
|
||||
REST.set_response_payload(response, buffer, length);
|
||||
} coap_set_header_content_format(response, TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */
|
||||
coap_set_header_etag(response, (uint8_t *)&length, 1);
|
||||
coap_set_payload(response, buffer, length);
|
||||
}
|
||||
|
|
|
@ -39,9 +39,8 @@
|
|||
#include "contiki.h"
|
||||
|
||||
#if PLATFORM_HAS_LEDS
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
@ -56,9 +55,9 @@
|
|||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/
|
||||
/* A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated */
|
||||
RESOURCE(res_leds,
|
||||
"title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"",
|
||||
NULL,
|
||||
|
@ -67,7 +66,7 @@ RESOURCE(res_leds,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_put_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char *color = NULL;
|
||||
|
@ -75,7 +74,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t pr
|
|||
uint8_t led = 0;
|
||||
int success = 1;
|
||||
|
||||
if((len = REST.get_query_variable(request, "color", &color))) {
|
||||
if((len = coap_get_query_variable(request, "color", &color))) {
|
||||
PRINTF("color %.*s\n", len, color);
|
||||
|
||||
if(strncmp(color, "r", len) == 0) {
|
||||
|
@ -89,7 +88,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t pr
|
|||
}
|
||||
} else {
|
||||
success = 0;
|
||||
} if(success && (len = REST.get_post_variable(request, "mode", &mode))) {
|
||||
} if(success && (len = coap_get_post_variable(request, "mode", &mode))) {
|
||||
PRINTF("mode %s\n", mode);
|
||||
|
||||
if(strncmp(mode, "on", len) == 0) {
|
||||
|
@ -102,7 +101,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t pr
|
|||
} else {
|
||||
success = 0;
|
||||
} if(!success) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_LEDS */
|
||||
|
|
|
@ -40,11 +40,12 @@
|
|||
|
||||
#if PLATFORM_HAS_LIGHT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/light-sensor.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
||||
RESOURCE(res_light,
|
||||
|
@ -55,33 +56,33 @@ RESOURCE(res_light,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC);
|
||||
uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR);
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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, "%u;%u", light_photosynthetic, light_solar);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)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, "<light photosynthetic=\"%u\" solar=\"%u\"/>", light_photosynthetic, light_solar);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "<light photosynthetic=\"%u\" solar=\"%u\"/>", light_photosynthetic, light_solar);
|
||||
|
||||
REST.set_response_payload(response, 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, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain, application/xml, and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_LIGHT */
|
||||
|
|
|
@ -36,8 +36,9 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
@ -52,7 +53,7 @@
|
|||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
static void res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_any_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */
|
||||
RESOURCE(res_mirror,
|
||||
|
@ -63,7 +64,7 @@ RESOURCE(res_mirror,
|
|||
res_any_handler);
|
||||
|
||||
static void
|
||||
res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_any_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* The ETag and Token is copied to the header. */
|
||||
uint8_t opaque[] = { 0x0A, 0xBC, 0xDE };
|
||||
|
@ -89,28 +90,28 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
/* snprintf() counts the terminating '\0' to the size parameter.
|
||||
* The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework.
|
||||
* Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */
|
||||
if(REST.get_header_content_type(request, &content_format)) {
|
||||
if(coap_get_header_content_format(request, &content_format)) {
|
||||
strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE + 1, "CF %u\n", content_format);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_accept(request, &content_format))) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_accept(request, &content_format))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ac %u\n", content_format);
|
||||
/* Some getters such as for ETag or Location are omitted, as these options should not appear in a request.
|
||||
* Max-Age might appear in HTTP requests or used for special purposes in CoAP. */
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_max_age(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", (unsigned long) longint);
|
||||
/* For HTTP this is the Length option, for CoAP it is the Size option. */
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_size1(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", (unsigned long) longint);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_uri_host(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UH %.*s\n", len, str);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_url(request, &str))) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_uri_path(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UP %.*s\n", len, str);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &str))) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_uri_query(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UQ %.*s\n", len, str);
|
||||
/* Undefined request options for debugging: actions not required for normal RESTful Web service. */
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LQ %.*s\n", len, str);
|
||||
/* CoAP-specific example: actions not required for normal RESTful Web service. */
|
||||
}
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)request;
|
||||
coap_message_t *const coap_pkt = (coap_message_t *)request;
|
||||
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_pkt->token_len > 0) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "To 0x");
|
||||
|
@ -132,10 +133,10 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n");
|
||||
}
|
||||
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_is_option(coap_pkt, COAP_OPTION_OBSERVE)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", (unsigned long) coap_pkt->observe);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_is_option(coap_pkt, COAP_OPTION_ETAG)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "ET 0x");
|
||||
int index = 0;
|
||||
for(index = 0; index < coap_pkt->etag_len; ++index) {
|
||||
|
@ -149,22 +150,22 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", (unsigned long) block_num, block_more ? "+" : "", block_size);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) {
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_payload(request, &bytes))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%.*s", len, bytes);
|
||||
}
|
||||
if(strpos >= REST_MAX_CHUNK_SIZE) {
|
||||
buffer[REST_MAX_CHUNK_SIZE - 1] = 0xBB; /* '»' to indicate truncation */
|
||||
}
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
coap_set_payload(response, buffer, strpos);
|
||||
|
||||
PRINTF("/mirror options received: %s\n", buffer);
|
||||
|
||||
/* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */
|
||||
REST.set_header_etag(response, opaque, 2);
|
||||
REST.set_header_location(response, location); /* Initial slash is omitted by framework */
|
||||
REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */
|
||||
coap_set_header_etag(response, opaque, 2);
|
||||
coap_set_header_location_path(response, location); /* Initial slash is omitted by framework */
|
||||
coap_set_header_size1(response, strpos); /* For HTTP, browsers will not re-request the page for 10 s. CoAP action depends on the client. */
|
||||
|
||||
/* CoAP-specific example: actions not required for normal RESTful Web service. */
|
||||
coap_set_header_uri_host(response, "tiki");
|
||||
|
|
|
@ -36,11 +36,12 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_periodic_handler(void);
|
||||
|
||||
PERIODIC_RESOURCE(res_push,
|
||||
|
@ -58,18 +59,18 @@ PERIODIC_RESOURCE(res_push,
|
|||
static int32_t event_counter = 0;
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/*
|
||||
* For minimal complexity, request query and options should be ignored for GET on observable resources.
|
||||
* Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers().
|
||||
* Otherwise the requests must be stored with the observer list and passed by coap_notify_subscribers().
|
||||
* This would be a TODO in the corresponding files in contiki/apps/erbium/!
|
||||
*/
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND);
|
||||
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", (unsigned long) event_counter));
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND);
|
||||
coap_set_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", (unsigned long) event_counter));
|
||||
|
||||
/* The REST.subscription_handler() will be called for observable resources by the REST framework. */
|
||||
/* The coap_subscription_handler() will be called for observable resources by the REST framework. */
|
||||
}
|
||||
/*
|
||||
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
|
||||
|
@ -84,6 +85,6 @@ res_periodic_handler()
|
|||
/* Usually a condition is defined under with subscribers are notified, e.g., large enough delta in sensor reading. */
|
||||
if(1) {
|
||||
/* Notify the registered observers which will trigger the res_get_handler to create the response. */
|
||||
REST.notify_subscribers(&res_push);
|
||||
coap_notify_observers(&res_push);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@
|
|||
#include "contiki.h"
|
||||
|
||||
#if PLATFORM_HAS_RADIO
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */
|
||||
RESOURCE(res_radio,
|
||||
|
@ -55,7 +55,7 @@ RESOURCE(res_radio,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char *p = NULL;
|
||||
|
@ -64,9 +64,9 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
int success = 0;
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
if((len = REST.get_query_variable(request, "p", &p))) {
|
||||
if((len = coap_get_query_variable(request, "p", &p))) {
|
||||
if(strncmp(p, "rssi", len) == 0) {
|
||||
if(NETSTACK_RADIO.get_value(RADIO_PARAM_RSSI, &value) ==
|
||||
RADIO_RESULT_OK) {
|
||||
|
@ -77,23 +77,23 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
|
||||
if(success) {
|
||||
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", rssi);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "%d", 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);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", rssi);
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "{'rssi':%d}", rssi);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_RADIO */
|
||||
|
|
|
@ -37,11 +37,12 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include <stdio.h>
|
||||
#include "coap-engine.h"
|
||||
#include "coap-separate.h"
|
||||
#include "coap-transactions.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_resume_handler(void);
|
||||
|
||||
SEPARATE_RESOURCE(res_separate,
|
||||
|
@ -68,7 +69,7 @@ static uint8_t separate_active = 0;
|
|||
static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE];
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/*
|
||||
* Example allows only one open separate response.
|
||||
|
@ -96,11 +97,11 @@ res_resume_handler()
|
|||
{
|
||||
if(separate_active) {
|
||||
coap_transaction_t *transaction = NULL;
|
||||
if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) {
|
||||
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.endpoint))) {
|
||||
coap_message_t response[1]; /* This way the message can be treated as pointer as usual. */
|
||||
|
||||
/* Restore the request information for the response. */
|
||||
coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK);
|
||||
coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05);
|
||||
|
||||
coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer));
|
||||
|
||||
|
@ -111,7 +112,7 @@ res_resume_handler()
|
|||
coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size);
|
||||
|
||||
/* Warning: No check for serialization error. */
|
||||
transaction->packet_len = coap_serialize_message(response, transaction->packet);
|
||||
transaction->message_len = coap_serialize_message(response, transaction->message);
|
||||
coap_send_transaction(transaction);
|
||||
/* The engine will clear the transaction (right after send for NON, after acked for CON). */
|
||||
|
||||
|
|
|
@ -43,11 +43,12 @@
|
|||
|
||||
#if PLATFORM_HAS_SHT11
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/sht11/sht11-sensor.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* Get Method Example. Returns the reading from temperature and humidity sensors. */
|
||||
RESOURCE(res_sht11,
|
||||
|
@ -58,7 +59,7 @@ RESOURCE(res_sht11,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Temperature in Celsius (t in 14 bits resolution at 3 Volts)
|
||||
* T = -39.60 + 0.01*t
|
||||
|
@ -70,27 +71,27 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
|
|||
uint16_t rh = sht11_sensor.value(SHT11_SENSOR_HUMIDITY);
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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, "%u;%u", temperature, rh);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "%u;%u", temperature, rh);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)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, "<Temperature =\"%u\" Humidity=\"%u\"/>", temperature, rh);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "<Temperature =\"%u\" Humidity=\"%u\"/>", temperature, rh);
|
||||
|
||||
REST.set_response_payload(response, 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, "{'Sht11':{'Temperature':%u,'Humidity':%u}}", temperature, rh);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "{'Sht11':{'Temperature':%u,'Humidity':%u}}", temperature, rh);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain, application/xml, and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_SHT11 */
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* Example for a resource that also handles all its sub-resources.
|
||||
* Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path.
|
||||
* Use coap_get_url() to multiplex the handling of the request depending on the Uri-Path.
|
||||
*/
|
||||
PARENT_RESOURCE(res_sub,
|
||||
"title=\"Sub-resource demo\"",
|
||||
|
@ -53,17 +54,17 @@ PARENT_RESOURCE(res_sub,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
|
||||
const char *uri_path = NULL;
|
||||
int len = REST.get_url(request, &uri_path);
|
||||
int len = coap_get_header_uri_path(request, &uri_path);
|
||||
int base_len = strlen(res_sub.url);
|
||||
|
||||
if(len == base_len) {
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", res_sub.url);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", res_sub.url);
|
||||
} else {
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len - base_len, uri_path + base_len);
|
||||
} REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, ".%.*s", len - base_len, uri_path + base_len);
|
||||
} coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
}
|
||||
|
|
|
@ -44,11 +44,12 @@
|
|||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/temperature-sensor.h"
|
||||
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_periodic_handler(void);
|
||||
|
||||
#define MAX_AGE 60
|
||||
|
@ -69,43 +70,43 @@ PERIODIC_RESOURCE(res_temperature,
|
|||
res_periodic_handler);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/*
|
||||
* For minimal complexity, request query and options should be ignored for GET on observable resources.
|
||||
* Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers().
|
||||
* Otherwise the requests must be stored with the observer list and passed by coap_notify_observers().
|
||||
* This would be a TODO in the corresponding files in contiki/apps/erbium/!
|
||||
*/
|
||||
|
||||
int temperature = temperature_sensor.value(0);
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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", temperature);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "%d", temperature);
|
||||
|
||||
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, "{'temperature':%d}", temperature);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
const char *msg = "Supporting content-types text/plain and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
coap_set_payload(response, msg, strlen(msg));
|
||||
}
|
||||
|
||||
REST.set_header_max_age(response, MAX_AGE);
|
||||
coap_set_header_max_age(response, MAX_AGE);
|
||||
|
||||
/* The REST.subscription_handler() will be called for observable resources by the REST framework. */
|
||||
/* The coap_subscription_handler() will be called for observable resources by the coap_framework. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
|
||||
* It will be called by the REST manager process with the defined period.
|
||||
* It will be called by the coap_manager process with the defined period.
|
||||
*/
|
||||
static void
|
||||
res_periodic_handler()
|
||||
|
@ -119,7 +120,7 @@ res_periodic_handler()
|
|||
interval_counter = 0;
|
||||
temperature_old = temperature;
|
||||
/* Notify the registered observers which will trigger the res_get_handler to create the response. */
|
||||
REST.notify_subscribers(&res_temperature);
|
||||
coap_notify_observers(&res_temperature);
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_TEMPERATURE */
|
||||
|
|
|
@ -42,10 +42,10 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple actuator example. Toggles the red led */
|
||||
RESOURCE(res_toggle,
|
||||
|
@ -56,7 +56,7 @@ RESOURCE(res_toggle,
|
|||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_toggle(LEDS_RED);
|
||||
}
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>REST with RPL router</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>50.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>slipradio</identifier>
|
||||
<description>Sky SLIP radio</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.c</source>
|
||||
<commands EXPORT="discard">make slip-radio.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>server</identifier>
|
||||
<description>Erbium Server</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-server.c</source>
|
||||
<commands EXPORT="discard">make coap-example-server.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-server.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>client</identifier>
|
||||
<description>Erbium Client</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-client.c</source>
|
||||
<commands EXPORT="discard">make coap-example-client.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-client.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>30.303994886410642</x>
|
||||
<y>17.22128424003353</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>slipradio</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>46.57186415376375</x>
|
||||
<y>37.25589203828498</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>server</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>18.194682268367348</x>
|
||||
<y>50.210548118402656</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>3</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>client</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>0</z>
|
||||
<height>179</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>2</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AddressVisualizerSkin</skin>
|
||||
<viewport>2.255467003316979 0.0 0.0 2.255467003316979 59.30641698643764 -13.478401994502008</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>2</z>
|
||||
<height>178</height>
|
||||
<location_x>262</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>762</width>
|
||||
<z>4</z>
|
||||
<height>491</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>182</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan" />
|
||||
</plugin_config>
|
||||
<width>451</width>
|
||||
<z>-1</z>
|
||||
<height>305</height>
|
||||
<location_x>73</location_x>
|
||||
<location_y>140</location_y>
|
||||
<minimized>true</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<mote>1</mote>
|
||||
<mote>2</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<showWatchpoints />
|
||||
<zoomfactor>25.49079397896416</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1624</width>
|
||||
<z>5</z>
|
||||
<height>252</height>
|
||||
<location_x>6</location_x>
|
||||
<location_y>712</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.MoteInterfaceViewer
|
||||
<mote_arg>1</mote_arg>
|
||||
<plugin_config>
|
||||
<interface>Serial port</interface>
|
||||
<scrollpos>0,0</scrollpos>
|
||||
</plugin_config>
|
||||
<width>853</width>
|
||||
<z>3</z>
|
||||
<height>491</height>
|
||||
<location_x>765</location_x>
|
||||
<location_y>182</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.serialsocket.SerialSocketServer
|
||||
<mote_arg>0</mote_arg>
|
||||
<width>422</width>
|
||||
<z>1</z>
|
||||
<height>82</height>
|
||||
<location_x>606</location_x>
|
||||
<location_y>51</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>REST with RPL router</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>50.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>rplroot</identifier>
|
||||
<description>Sky RPL Root</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/rpl-border-router/border-router.c</source>
|
||||
<commands EXPORT="discard">make border-router.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/rpl-border-router/border-router.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>server</identifier>
|
||||
<description>Erbium Server</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-server.c</source>
|
||||
<commands EXPORT="discard">make coap-example-server.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-server.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>client</identifier>
|
||||
<description>Erbium Client</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-observe-client.c</source>
|
||||
<commands EXPORT="discard">make coap-example-observe-client.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-observe-client.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>33.260163187353555</x>
|
||||
<y>30.643217359962595</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>rplroot</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>54.537149936813485</x>
|
||||
<y>51.51086225537906</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>server</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>77.97942851220571</x>
|
||||
<y>67.86182390447284</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>3</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>client</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>3</z>
|
||||
<height>179</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AddressVisualizerSkin</skin>
|
||||
<viewport>2.092412892721766 0.0 0.0 2.092412892721766 34.70057915472623 -45.606066372444175</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>4</z>
|
||||
<height>178</height>
|
||||
<location_x>261</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>762</width>
|
||||
<z>0</z>
|
||||
<height>491</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>182</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>167</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan" />
|
||||
</plugin_config>
|
||||
<width>560</width>
|
||||
<z>1</z>
|
||||
<height>492</height>
|
||||
<location_x>764</location_x>
|
||||
<location_y>181</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.serialsocket.SerialSocketServer
|
||||
<mote_arg>0</mote_arg>
|
||||
<plugin_config>
|
||||
<port>60001</port>
|
||||
<bound>true</bound>
|
||||
</plugin_config>
|
||||
<width>362</width>
|
||||
<z>2</z>
|
||||
<height>116</height>
|
||||
<location_x>561</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>REST with RPL router</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>50.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>rplroot</identifier>
|
||||
<description>Sky RPL Root</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/rpl-border-router/border-router.c</source>
|
||||
<commands EXPORT="discard">make border-router.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/rpl-border-router/border-router.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>server</identifier>
|
||||
<description>Erbium Server</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-server.c</source>
|
||||
<commands EXPORT="discard">make coap-example-server.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-server.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>client</identifier>
|
||||
<description>Erbium Client</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-client.c</source>
|
||||
<commands EXPORT="discard">make coap-example-client.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-client.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>33.260163187353555</x>
|
||||
<y>30.643217359962595</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>rplroot</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>46.57186415376375</x>
|
||||
<y>40.35946215910942</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>server</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>18.638049428485125</x>
|
||||
<y>47.55034515769599</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>3</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>client</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>0</z>
|
||||
<height>179</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AddressVisualizerSkin</skin>
|
||||
<viewport>3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>2</z>
|
||||
<height>178</height>
|
||||
<location_x>261</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>762</width>
|
||||
<z>3</z>
|
||||
<height>491</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>182</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan" />
|
||||
</plugin_config>
|
||||
<width>451</width>
|
||||
<z>-1</z>
|
||||
<height>305</height>
|
||||
<location_x>73</location_x>
|
||||
<location_y>140</location_y>
|
||||
<minimized>true</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.serialsocket.SerialSocketServer
|
||||
<mote_arg>0</mote_arg>
|
||||
<width>422</width>
|
||||
<z>4</z>
|
||||
<height>74</height>
|
||||
<location_x>578</location_x>
|
||||
<location_y>18</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<mote>1</mote>
|
||||
<mote>2</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<showWatchpoints />
|
||||
<zoomfactor>25.49079397896416</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1624</width>
|
||||
<z>5</z>
|
||||
<height>252</height>
|
||||
<location_x>6</location_x>
|
||||
<location_y>712</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.MoteInterfaceViewer
|
||||
<mote_arg>2</mote_arg>
|
||||
<plugin_config>
|
||||
<interface>Serial port</interface>
|
||||
<scrollpos>0,0</scrollpos>
|
||||
</plugin_config>
|
||||
<width>853</width>
|
||||
<z>1</z>
|
||||
<height>491</height>
|
||||
<location_x>765</location_x>
|
||||
<location_y>182</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>REST with RPL router</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>50.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>rplroot</identifier>
|
||||
<description>Sky RPL Root</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/rpl-border-router/border-router.c</source>
|
||||
<commands EXPORT="discard">make border-router.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/rpl-border-router/border-router.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<motetype>
|
||||
org.contikios.cooja.mspmote.SkyMoteType
|
||||
<identifier>server</identifier>
|
||||
<description>Erbium Server</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/coap/coap-example-server.c</source>
|
||||
<commands EXPORT="discard">make coap-example-server.sky TARGET=sky</commands>
|
||||
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/coap/coap-example-server.sky</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||
</motetype>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>33.260163187353555</x>
|
||||
<y>30.643217359962595</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>rplroot</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<breakpoints />
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>35.100895239785295</x>
|
||||
<y>39.70574552287428</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<motetype_identifier>server</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>259</width>
|
||||
<z>0</z>
|
||||
<height>179</height>
|
||||
<location_x>2</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.AddressVisualizerSkin</skin>
|
||||
<viewport>7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535</viewport>
|
||||
</plugin_config>
|
||||
<width>300</width>
|
||||
<z>1</z>
|
||||
<height>175</height>
|
||||
<location_x>262</location_x>
|
||||
<location_y>2</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>560</width>
|
||||
<z>3</z>
|
||||
<height>326</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>293</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan" />
|
||||
</plugin_config>
|
||||
<width>451</width>
|
||||
<z>-1</z>
|
||||
<height>305</height>
|
||||
<location_x>73</location_x>
|
||||
<location_y>140</location_y>
|
||||
<minimized>true</minimized>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.serialsocket.SerialSocketServer
|
||||
<mote_arg>0</mote_arg>
|
||||
<width>422</width>
|
||||
<z>4</z>
|
||||
<height>74</height>
|
||||
<location_x>39</location_x>
|
||||
<location_y>199</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<mote>1</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<showWatchpoints />
|
||||
<zoomfactor>25.49079397896416</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1624</width>
|
||||
<z>5</z>
|
||||
<height>252</height>
|
||||
<location_x>4</location_x>
|
||||
<location_y>622</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.MoteInterfaceViewer
|
||||
<mote_arg>1</mote_arg>
|
||||
<plugin_config>
|
||||
<interface>Serial port</interface>
|
||||
<scrollpos>0,0</scrollpos>
|
||||
</plugin_config>
|
||||
<width>702</width>
|
||||
<z>2</z>
|
||||
<height>646</height>
|
||||
<location_x>564</location_x>
|
||||
<location_y>2</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018, RISE SICS AB.
|
||||
* 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
#error The CoAP example no longer fits the limited ROM in the Tmote Sky. \
|
||||
Please select another platform with more ROM to compile the CoAP example.
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define COAP_OBSERVE_CLIENT 0
|
||||
|
||||
#define COAP_MAX_CHUNK_SIZE 48
|
||||
|
||||
/* Turn off DAO-ACK and probing to make code smaller */
|
||||
#define RPL_CONF_WITH_DAO_ACK 0
|
||||
|
||||
#define LOG_CONF_LEVEL_MAIN 0
|
||||
|
||||
#define DCOSYNCH_CONF_ENABLED 0
|
||||
|
||||
#define PROCESS_CONF_NUMEVENTS 8
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -38,7 +38,13 @@
|
|||
|
||||
#include "contiki.h"
|
||||
#include "services/lwm2m/lwm2m-engine.h"
|
||||
#include "services/lwm2m/lwm2m-rd-client.h"
|
||||
#include "services/lwm2m/lwm2m-device.h"
|
||||
#include "services/lwm2m/lwm2m-server.h"
|
||||
#include "services/lwm2m/lwm2m-security.h"
|
||||
#include "services/ipso-objects/ipso-objects.h"
|
||||
#include "services/ipso-objects/ipso-sensor-template.h"
|
||||
#include "services/ipso-objects/ipso-control-template.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
@ -52,9 +58,84 @@
|
|||
#endif
|
||||
|
||||
#ifndef LWM2M_SERVER_ADDRESS
|
||||
#define LWM2M_SERVER_ADDRESS "fd00::1"
|
||||
#define LWM2M_SERVER_ADDRESS "coap://[fd00::1]"
|
||||
#endif
|
||||
|
||||
#if BOARD_SENSORTAG
|
||||
#include "board-peripherals.h"
|
||||
|
||||
/* Temperature reading */
|
||||
static lwm2m_status_t
|
||||
read_temp_value(const ipso_sensor_t *s, int32_t *value)
|
||||
{
|
||||
*value = 10 * hdc_1000_sensor.value(HDC_1000_SENSOR_TYPE_TEMP);
|
||||
return LWM2M_STATUS_OK;
|
||||
}
|
||||
/* Humitidy reading */
|
||||
static lwm2m_status_t
|
||||
read_hum_value(const ipso_sensor_t *s, int32_t *value)
|
||||
{
|
||||
*value = 10 * hdc_1000_sensor.value(HDC_1000_SENSOR_TYPE_HUMIDITY);
|
||||
return LWM2M_STATUS_OK;
|
||||
}
|
||||
/* Lux reading */
|
||||
static lwm2m_status_t
|
||||
read_lux_value(const ipso_sensor_t *s, int32_t *value)
|
||||
{
|
||||
*value = 10 * opt_3001_sensor.value(0);
|
||||
return LWM2M_STATUS_OK;
|
||||
}
|
||||
/* Barometer reading */
|
||||
static lwm2m_status_t
|
||||
read_bar_value(const ipso_sensor_t *s, int32_t *value)
|
||||
{
|
||||
*value = 10 * bmp_280_sensor.value(BMP_280_SENSOR_TYPE_PRESS);
|
||||
return LWM2M_STATUS_OK;
|
||||
}
|
||||
/* LED control */
|
||||
static lwm2m_status_t
|
||||
leds_set_val(ipso_control_t *control, uint8_t value)
|
||||
{
|
||||
if(value > 0) {
|
||||
leds_on(LEDS_YELLOW);
|
||||
} else {
|
||||
leds_off(LEDS_YELLOW);
|
||||
}
|
||||
return LWM2M_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
IPSO_CONTROL(led_control, 3311, 0, leds_set_val);
|
||||
|
||||
IPSO_SENSOR(temp_sensor, 3303, read_temp_value,
|
||||
.max_range = 100000, /* 100 cel milli celcius */
|
||||
.min_range = -10000, /* -10 cel milli celcius */
|
||||
.unit = "Cel",
|
||||
.update_interval = 30
|
||||
);
|
||||
|
||||
IPSO_SENSOR(hum_sensor, 3304, read_hum_value,
|
||||
.max_range = 100000, /* 100 % RH */
|
||||
.min_range = 0,
|
||||
.unit = "% RH",
|
||||
.update_interval = 30
|
||||
);
|
||||
|
||||
IPSO_SENSOR(lux_sensor, 3301, read_lux_value,
|
||||
.max_range = 100000,
|
||||
.min_range = -10000,
|
||||
.unit = "LUX",
|
||||
.update_interval = 30
|
||||
);
|
||||
|
||||
IPSO_SENSOR(bar_sensor, 3315, read_bar_value,
|
||||
.max_range = 100000, /* 100 cel milli celcius */
|
||||
.min_range = -10000, /* -10 cel milli celcius */
|
||||
.unit = "hPa",
|
||||
.update_interval = 30
|
||||
);
|
||||
#endif /* BOARD_SENSORTAG */
|
||||
|
||||
PROCESS(example_ipso_objects, "IPSO object example");
|
||||
AUTOSTART_PROCESSES(&example_ipso_objects);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -62,39 +143,70 @@ static void
|
|||
setup_lwm2m_servers(void)
|
||||
{
|
||||
#ifdef LWM2M_SERVER_ADDRESS
|
||||
uip_ipaddr_t addr;
|
||||
if(uiplib_ipaddrconv(LWM2M_SERVER_ADDRESS, &addr)) {
|
||||
lwm2m_engine_register_with_bootstrap_server(&addr, 0);
|
||||
lwm2m_engine_register_with_server(&addr, 0);
|
||||
coap_endpoint_t server_ep;
|
||||
if(coap_endpoint_parse(LWM2M_SERVER_ADDRESS, strlen(LWM2M_SERVER_ADDRESS),
|
||||
&server_ep) != 0) {
|
||||
lwm2m_rd_client_register_with_bootstrap_server(&server_ep);
|
||||
lwm2m_rd_client_register_with_server(&server_ep);
|
||||
}
|
||||
#endif /* LWM2M_SERVER_ADDRESS */
|
||||
|
||||
lwm2m_engine_use_bootstrap_server(REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER);
|
||||
lwm2m_engine_use_registration_server(REGISTER_WITH_LWM2M_SERVER);
|
||||
lwm2m_rd_client_use_bootstrap_server(REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER);
|
||||
lwm2m_rd_client_use_registration_server(REGISTER_WITH_LWM2M_SERVER);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(example_ipso_objects, ev, data)
|
||||
{
|
||||
static struct etimer periodic;
|
||||
PROCESS_BEGIN();
|
||||
|
||||
PROCESS_PAUSE();
|
||||
|
||||
PRINTF("Starting IPSO objects example\n");
|
||||
|
||||
PRINTF("Starting IPSO objects example%s\n",
|
||||
REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER ? " (bootstrap)" : "");
|
||||
/* Initialize the OMA LWM2M engine */
|
||||
lwm2m_engine_init();
|
||||
|
||||
/* Register default LWM2M objects */
|
||||
lwm2m_engine_register_default_objects();
|
||||
lwm2m_device_init();
|
||||
lwm2m_security_init();
|
||||
lwm2m_server_init();
|
||||
|
||||
/* Register default IPSO objects */
|
||||
#if BOARD_SENSORTAG
|
||||
ipso_sensor_add(&temp_sensor);
|
||||
ipso_sensor_add(&hum_sensor);
|
||||
ipso_sensor_add(&lux_sensor);
|
||||
ipso_sensor_add(&bar_sensor);
|
||||
ipso_control_add(&led_control);
|
||||
ipso_button_init();
|
||||
|
||||
SENSORS_ACTIVATE(hdc_1000_sensor);
|
||||
SENSORS_ACTIVATE(opt_3001_sensor);
|
||||
SENSORS_ACTIVATE(bmp_280_sensor);
|
||||
#else /* BOARD_SENSORTAG */
|
||||
/* Register default IPSO objects - such as button..*/
|
||||
ipso_objects_init();
|
||||
#endif /* BOARD_SENSORTAG */
|
||||
|
||||
setup_lwm2m_servers();
|
||||
/* Tick loop each 5 seconds */
|
||||
etimer_set(&periodic, CLOCK_SECOND * 5);
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
}
|
||||
if(ev == PROCESS_EVENT_TIMER && etimer_expired(&periodic)) {
|
||||
#if BOARD_SENSORTAG
|
||||
/* deactive / activate to do a new reading */
|
||||
SENSORS_DEACTIVATE(hdc_1000_sensor);
|
||||
SENSORS_DEACTIVATE(opt_3001_sensor);
|
||||
SENSORS_DEACTIVATE(bmp_280_sensor);
|
||||
|
||||
SENSORS_ACTIVATE(hdc_1000_sensor);
|
||||
SENSORS_ACTIVATE(opt_3001_sensor);
|
||||
SENSORS_ACTIVATE(bmp_280_sensor);
|
||||
#endif /* BOARD_SENSORTAG */
|
||||
etimer_reset(&periodic);
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "coap-constants.h"
|
||||
#include "coap-engine.h"
|
||||
#include "lwm2m-engine.h"
|
||||
#include "oma-tlv.h"
|
||||
#include "lwm2m-tlv.h"
|
||||
#include "dev/serial-line.h"
|
||||
#include "serial-protocol.h"
|
||||
|
||||
|
@ -187,13 +187,13 @@ client_chunk_handler(void *response)
|
|||
} else {
|
||||
/* otherwise update the current value */
|
||||
if(format == LWM2M_TLV) {
|
||||
oma_tlv_t tlv;
|
||||
lwm2m_tlv_t tlv;
|
||||
/* we can only read int32 for now ? */
|
||||
if(oma_tlv_read(&tlv, chunk, len) > 0) {
|
||||
if(lwm2m_tlv_read(&tlv, chunk, len) > 0) {
|
||||
/* printf("TLV.type=%d len=%d id=%d value[0]=%d\n", */
|
||||
/* tlv.type, tlv.length, tlv.id, tlv.value[0]); */
|
||||
|
||||
int value = oma_tlv_get_int32(&tlv);
|
||||
int value = lwm2m_tlv_get_int32(&tlv);
|
||||
snprintf(current_value, sizeof(current_value), "%d", value);
|
||||
}
|
||||
} else {
|
||||
|
@ -257,8 +257,8 @@ setup_network(void)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(router_process, ev, data)
|
||||
{
|
||||
/* This way the packet can be treated as pointer as usual. */
|
||||
static coap_packet_t request[1];
|
||||
/* This way the message can be treated as pointer as usual. */
|
||||
static coap_message_t request[1];
|
||||
static struct etimer timer;
|
||||
uip_ds6_route_t *r;
|
||||
uip_ipaddr_t *nexthop;
|
||||
|
@ -269,7 +269,7 @@ PROCESS_THREAD(router_process, ev, data)
|
|||
PROCESS_PAUSE();
|
||||
|
||||
/* receives all CoAP messages */
|
||||
coap_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
setup_network();
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#ifndef PROJECT_CONF_H_
|
||||
#define PROJECT_CONF_H_
|
||||
|
||||
/* No sleep on CC2538 to enable full 32 KiB RAM */
|
||||
#define LPM_CONF_ENABLE 0
|
||||
|
||||
#ifdef BOARD_STRING
|
||||
#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING
|
||||
#elif defined(CONTIKI_TARGET_WISMOTE)
|
||||
|
@ -40,10 +43,14 @@
|
|||
#define PLATFORM_REBOOT watchdog_reboot
|
||||
#endif
|
||||
|
||||
#if BOARD_SENSORTAG
|
||||
/* Real sensor is present... */
|
||||
#else
|
||||
#define IPSO_TEMPERATURE example_ipso_temperature
|
||||
#endif /* BOARD_SENSORTAG */
|
||||
|
||||
/* Increase rpl-border-router IP-buffer when using more than 64. */
|
||||
#define REST_MAX_CHUNK_SIZE 64
|
||||
#define COAP_MAX_CHUNK_SIZE 64
|
||||
|
||||
/* Multiplies with chunk size, be aware of memory constraints. */
|
||||
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_COAP LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_LWM2M LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_6TOP LOG_LEVEL_DBG
|
||||
|
||||
/* Enable cooja annotations */
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "lib/sensors.h"
|
||||
#include "lib/list.h"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "rf-core/rf-ble.h"
|
||||
#include "cc26xx-web-demo.h"
|
||||
|
@ -47,48 +47,48 @@
|
|||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common resources */
|
||||
extern resource_t res_leds;
|
||||
extern coap_resource_t res_leds;
|
||||
|
||||
extern resource_t res_batmon_temp;
|
||||
extern resource_t res_batmon_volt;
|
||||
extern coap_resource_t res_batmon_temp;
|
||||
extern coap_resource_t res_batmon_volt;
|
||||
|
||||
extern resource_t res_device_sw;
|
||||
extern resource_t res_device_hw;
|
||||
extern resource_t res_device_uptime;
|
||||
extern resource_t res_device_cfg_reset;
|
||||
extern coap_resource_t res_device_sw;
|
||||
extern coap_resource_t res_device_hw;
|
||||
extern coap_resource_t res_device_uptime;
|
||||
extern coap_resource_t res_device_cfg_reset;
|
||||
|
||||
extern resource_t res_parent_rssi;
|
||||
extern resource_t res_parent_ip;
|
||||
extern coap_resource_t res_parent_rssi;
|
||||
extern coap_resource_t res_parent_ip;
|
||||
|
||||
#if RF_BLE_ENABLED
|
||||
extern resource_t res_ble_advd;
|
||||
extern coap_resource_t res_ble_advd;
|
||||
#endif
|
||||
|
||||
extern resource_t res_toggle_red;
|
||||
extern resource_t res_toggle_green;
|
||||
extern coap_resource_t res_toggle_red;
|
||||
extern coap_resource_t res_toggle_green;
|
||||
|
||||
/* Board-specific resources */
|
||||
#if BOARD_SENSORTAG
|
||||
extern resource_t res_bmp280_temp;
|
||||
extern resource_t res_bmp280_press;
|
||||
extern resource_t res_tmp007_amb;
|
||||
extern resource_t res_tmp007_obj;
|
||||
extern resource_t res_hdc1000_temp;
|
||||
extern resource_t res_hdc1000_hum;
|
||||
extern resource_t res_opt3001_light;
|
||||
extern resource_t res_mpu_acc_x;
|
||||
extern resource_t res_mpu_acc_y;
|
||||
extern resource_t res_mpu_acc_z;
|
||||
extern resource_t res_mpu_gyro_x;
|
||||
extern resource_t res_mpu_gyro_y;
|
||||
extern resource_t res_mpu_gyro_z;
|
||||
extern coap_resource_t res_bmp280_temp;
|
||||
extern coap_resource_t res_bmp280_press;
|
||||
extern coap_resource_t res_tmp007_amb;
|
||||
extern coap_resource_t res_tmp007_obj;
|
||||
extern coap_resource_t res_hdc1000_temp;
|
||||
extern coap_resource_t res_hdc1000_hum;
|
||||
extern coap_resource_t res_opt3001_light;
|
||||
extern coap_resource_t res_mpu_acc_x;
|
||||
extern coap_resource_t res_mpu_acc_y;
|
||||
extern coap_resource_t res_mpu_acc_z;
|
||||
extern coap_resource_t res_mpu_gyro_x;
|
||||
extern coap_resource_t res_mpu_gyro_y;
|
||||
extern coap_resource_t res_mpu_gyro_z;
|
||||
#else
|
||||
extern resource_t res_toggle_orange;
|
||||
extern resource_t res_toggle_yellow;
|
||||
extern coap_resource_t res_toggle_orange;
|
||||
extern coap_resource_t res_toggle_yellow;
|
||||
#endif
|
||||
|
||||
#if CC26XX_WEB_DEMO_ADC_DEMO
|
||||
extern resource_t res_adc_dio23;
|
||||
extern coap_resource_t res_adc_dio23;
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const char *coap_server_not_found_msg = "Resource not found";
|
||||
|
@ -101,27 +101,27 @@ static void
|
|||
start_board_resources(void)
|
||||
{
|
||||
|
||||
rest_activate_resource(&res_toggle_green, "lt/g");
|
||||
rest_activate_resource(&res_toggle_red, "lt/r");
|
||||
rest_activate_resource(&res_leds, "lt");
|
||||
coap_activate_resource(&res_toggle_green, "lt/g");
|
||||
coap_activate_resource(&res_toggle_red, "lt/r");
|
||||
coap_activate_resource(&res_leds, "lt");
|
||||
|
||||
#if BOARD_SENSORTAG
|
||||
rest_activate_resource(&res_bmp280_temp, "sen/bar/temp");
|
||||
rest_activate_resource(&res_bmp280_press, "sen/bar/pres");
|
||||
rest_activate_resource(&res_tmp007_amb, "sen/tmp/amb");
|
||||
rest_activate_resource(&res_tmp007_obj, "sen/tmp/obj");
|
||||
rest_activate_resource(&res_hdc1000_temp, "sen/hdc/t");
|
||||
rest_activate_resource(&res_hdc1000_hum, "sen/hdc/h");
|
||||
rest_activate_resource(&res_opt3001_light, "sen/opt/light");
|
||||
rest_activate_resource(&res_mpu_acc_x, "sen/mpu/acc/x");
|
||||
rest_activate_resource(&res_mpu_acc_y, "sen/mpu/acc/y");
|
||||
rest_activate_resource(&res_mpu_acc_z, "sen/mpu/acc/z");
|
||||
rest_activate_resource(&res_mpu_gyro_x, "sen/mpu/gyro/x");
|
||||
rest_activate_resource(&res_mpu_gyro_y, "sen/mpu/gyro/y");
|
||||
rest_activate_resource(&res_mpu_gyro_z, "sen/mpu/gyro/z");
|
||||
coap_activate_resource(&res_bmp280_temp, "sen/bar/temp");
|
||||
coap_activate_resource(&res_bmp280_press, "sen/bar/pres");
|
||||
coap_activate_resource(&res_tmp007_amb, "sen/tmp/amb");
|
||||
coap_activate_resource(&res_tmp007_obj, "sen/tmp/obj");
|
||||
coap_activate_resource(&res_hdc1000_temp, "sen/hdc/t");
|
||||
coap_activate_resource(&res_hdc1000_hum, "sen/hdc/h");
|
||||
coap_activate_resource(&res_opt3001_light, "sen/opt/light");
|
||||
coap_activate_resource(&res_mpu_acc_x, "sen/mpu/acc/x");
|
||||
coap_activate_resource(&res_mpu_acc_y, "sen/mpu/acc/y");
|
||||
coap_activate_resource(&res_mpu_acc_z, "sen/mpu/acc/z");
|
||||
coap_activate_resource(&res_mpu_gyro_x, "sen/mpu/gyro/x");
|
||||
coap_activate_resource(&res_mpu_gyro_y, "sen/mpu/gyro/y");
|
||||
coap_activate_resource(&res_mpu_gyro_z, "sen/mpu/gyro/z");
|
||||
#elif BOARD_SMARTRF06EB
|
||||
rest_activate_resource(&res_toggle_yellow, "lt/y");
|
||||
rest_activate_resource(&res_toggle_orange, "lt/o");
|
||||
coap_activate_resource(&res_toggle_yellow, "lt/y");
|
||||
coap_activate_resource(&res_toggle_orange, "lt/o");
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -134,25 +134,25 @@ PROCESS_THREAD(coap_server_process, ev, data)
|
|||
printf("CC26XX CoAP Server\n");
|
||||
|
||||
/* Initialize the REST engine. */
|
||||
rest_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
rest_activate_resource(&res_batmon_temp, "sen/batmon/temp");
|
||||
rest_activate_resource(&res_batmon_volt, "sen/batmon/voltage");
|
||||
coap_activate_resource(&res_batmon_temp, "sen/batmon/temp");
|
||||
coap_activate_resource(&res_batmon_volt, "sen/batmon/voltage");
|
||||
|
||||
#if CC26XX_WEB_DEMO_ADC_DEMO
|
||||
rest_activate_resource(&res_adc_dio23, "sen/adc/dio23");
|
||||
coap_activate_resource(&res_adc_dio23, "sen/adc/dio23");
|
||||
#endif
|
||||
|
||||
rest_activate_resource(&res_device_hw, "dev/mdl/hw");
|
||||
rest_activate_resource(&res_device_sw, "dev/mdl/sw");
|
||||
rest_activate_resource(&res_device_uptime, "dev/uptime");
|
||||
rest_activate_resource(&res_device_cfg_reset, "dev/cfg_reset");
|
||||
coap_activate_resource(&res_device_hw, "dev/mdl/hw");
|
||||
coap_activate_resource(&res_device_sw, "dev/mdl/sw");
|
||||
coap_activate_resource(&res_device_uptime, "dev/uptime");
|
||||
coap_activate_resource(&res_device_cfg_reset, "dev/cfg_reset");
|
||||
|
||||
rest_activate_resource(&res_parent_rssi, "net/parent/RSSI");
|
||||
rest_activate_resource(&res_parent_ip, "net/parent/IPv6");
|
||||
coap_activate_resource(&res_parent_rssi, "net/parent/RSSI");
|
||||
coap_activate_resource(&res_parent_ip, "net/parent/IPv6");
|
||||
|
||||
#if RF_BLE_ENABLED
|
||||
rest_activate_resource(&res_ble_advd, "dev/ble_advd");
|
||||
coap_activate_resource(&res_ble_advd, "dev/ble_advd");
|
||||
#endif
|
||||
|
||||
start_board_resources();
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "rf-core/rf-ble.h"
|
||||
|
||||
|
@ -49,7 +49,8 @@ const char *forbidden_payload = "Name to advertise unspecified.\n"
|
|||
"Use name=<name> in the request";
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
||||
res_ble_post_put_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
@ -60,7 +61,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
|
||||
memset(name, 0, BLE_NAME_BUF_LEN);
|
||||
|
||||
len = REST.get_post_variable(request, "name", &text);
|
||||
len = coap_get_post_variable(request, "name", &text);
|
||||
|
||||
if(len > 0 && len < BLE_NAME_BUF_LEN) {
|
||||
memcpy(name, text, len);
|
||||
|
@ -68,7 +69,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
success = 1;
|
||||
}
|
||||
|
||||
len = REST.get_post_variable(request, "interval", &text);
|
||||
len = coap_get_post_variable(request, "interval", &text);
|
||||
|
||||
rv = atoi(text);
|
||||
|
||||
|
@ -77,15 +78,15 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
success = 1;
|
||||
}
|
||||
|
||||
len = REST.get_post_variable(request, "mode", &text);
|
||||
len = coap_get_post_variable(request, "mode", &text);
|
||||
|
||||
if(len) {
|
||||
if(strncmp(text, "on", len) == 0) {
|
||||
if(rf_ble_beacond_start()) {
|
||||
success = 1;
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.FORBIDDEN);
|
||||
REST.set_response_payload(response, forbidden_payload,
|
||||
coap_set_status_code(response, FORBIDDEN_4_03);
|
||||
coap_set_payload(response, forbidden_payload,
|
||||
strlen(forbidden_payload));
|
||||
return;
|
||||
}
|
||||
|
@ -98,7 +99,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
|
||||
if(!success) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "sys/clock.h"
|
||||
#include "coap-server.h"
|
||||
|
@ -46,6 +46,7 @@
|
|||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t
|
||||
detect_chip(void)
|
||||
|
@ -74,106 +75,110 @@ detect_chip(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_hw(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_hw(coap_message_t *request, coap_message_t *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);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s on CC%u", BOARD_STRING,
|
||||
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);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"HW Ver\":\"%s on CC%u\"}",
|
||||
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);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<hw-ver val=\"%s on CC%u\"/>", BOARD_STRING,
|
||||
chip);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_sw(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_sw(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", CONTIKI_VERSION_STRING);
|
||||
|
||||
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);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"SW Ver\":\"%s\"}",
|
||||
CONTIKI_VERSION_STRING);
|
||||
|
||||
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);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<sw-ver val=\"%s\"/>", CONTIKI_VERSION_STRING);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_uptime(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_uptime(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%lu", clock_seconds());
|
||||
|
||||
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);
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"uptime\":%lu}",
|
||||
clock_seconds());
|
||||
|
||||
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);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<uptime val=\"%lu\" unit=\"sec\"/>", clock_seconds());
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_handler_cfg_reset(void *request, void *response, uint8_t *buffer,
|
||||
res_post_handler_cfg_reset(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
cc26xx_web_demo_restore_defaults();
|
||||
|
|
|
@ -40,13 +40,14 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
||||
res_post_put_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
@ -55,7 +56,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
uint8_t led = 0;
|
||||
int success = 1;
|
||||
|
||||
if((len = REST.get_query_variable(request, "color", &color))) {
|
||||
if((len = coap_get_query_variable(request, "color", &color))) {
|
||||
if(strncmp(color, "r", len) == 0) {
|
||||
led = LEDS_RED;
|
||||
} else if(strncmp(color, "g", len) == 0) {
|
||||
|
@ -73,7 +74,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
success = 0;
|
||||
}
|
||||
|
||||
if(success && (len = REST.get_post_variable(request, "mode", &mode))) {
|
||||
if(success && (len = coap_get_post_variable(request, "mode", &mode))) {
|
||||
if(strncmp(mode, "on", len) == 0) {
|
||||
leds_on(led);
|
||||
} else if(strncmp(mode, "off", len) == 0) {
|
||||
|
@ -86,7 +87,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
|
||||
if(!success) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -37,82 +37,86 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "coap-server.h"
|
||||
#include "cc26xx-web-demo.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern int def_rt_rssi;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_parent_rssi(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_parent_rssi(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_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\"}",
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_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,
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE,
|
||||
"<parent-rssi val=\"%d\"/>", def_rt_rssi);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_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,
|
||||
res_get_handler_pref_parent(coap_message_t *request, coap_message_t *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);
|
||||
coap_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);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_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\"}",
|
||||
coap_set_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_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,
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE,
|
||||
"<parent=\"%s\"/>", def_rt_str);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
#include "cc26xx-web-demo.h"
|
||||
#include "coap-server.h"
|
||||
|
@ -51,7 +51,8 @@
|
|||
* called by all handlers and populates the CoAP response
|
||||
*/
|
||||
static void
|
||||
res_get_handler_all(int sens_type, void *request, void *response,
|
||||
res_get_handler_all(int sens_type, coap_message_t *request,
|
||||
coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
@ -60,43 +61,44 @@ res_get_handler_all(int sens_type, void *request, void *response,
|
|||
reading = cc26xx_web_demo_sensor_lookup(sens_type);
|
||||
|
||||
if(reading == NULL) {
|
||||
REST.set_response_status(response, REST.status.NOT_FOUND);
|
||||
REST.set_response_payload(response, coap_server_not_found_msg,
|
||||
coap_set_status_code(response, NOT_FOUND_4_04);
|
||||
coap_set_payload(response, coap_server_not_found_msg,
|
||||
strlen(coap_server_not_found_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_get_header_accept(request, &accept);
|
||||
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", reading->converted);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer,
|
||||
coap_set_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);
|
||||
} else if(accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"%s\":%s}",
|
||||
reading->descr, reading->converted);
|
||||
|
||||
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);
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == APPLICATION_XML) {
|
||||
coap_set_header_content_format(response, APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE,
|
||||
"<%s val=\"%s\" unit=\"%s\"/>", reading->xml_element,
|
||||
reading->converted, reading->units);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_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,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, coap_server_supported_msg,
|
||||
strlen(coap_server_supported_msg));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* BatMon resources and handler: Temperature, Voltage */
|
||||
static void
|
||||
res_get_handler_batmon_temp(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_batmon_temp(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BATMON_TEMP, request, response,
|
||||
|
@ -104,7 +106,8 @@ res_get_handler_batmon_temp(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_batmon_volt(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_batmon_volt(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BATMON_VOLT, request, response,
|
||||
|
@ -120,7 +123,8 @@ RESOURCE(res_batmon_volt, "title=\"Battery Voltage\";rt=\"mV\"",
|
|||
#if CC26XX_WEB_DEMO_ADC_DEMO
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_adc_dio23(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_adc_dio23(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_ADC_DIO23, request, response,
|
||||
|
@ -136,7 +140,8 @@ RESOURCE(res_adc_dio23, "title=\"ADC DIO23\";rt=\"mV\"",
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* MPU resources and handler: Accelerometer and Gyro */
|
||||
static void
|
||||
res_get_handler_mpu_acc_x(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_acc_x(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_X, request, response,
|
||||
|
@ -144,7 +149,8 @@ res_get_handler_mpu_acc_x(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_mpu_acc_y(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_acc_y(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_Y, request, response,
|
||||
|
@ -152,7 +158,8 @@ res_get_handler_mpu_acc_y(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_mpu_acc_z(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_acc_z(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_Z, request, response,
|
||||
|
@ -160,7 +167,8 @@ res_get_handler_mpu_acc_z(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_mpu_gyro_x(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_gyro_x(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_X, request, response,
|
||||
|
@ -168,7 +176,8 @@ res_get_handler_mpu_gyro_x(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_mpu_gyro_y(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_gyro_y(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Y, request, response,
|
||||
|
@ -176,7 +185,8 @@ res_get_handler_mpu_gyro_y(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_mpu_gyro_z(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_mpu_gyro_z(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Z, request, response,
|
||||
|
@ -199,7 +209,8 @@ RESOURCE(res_mpu_gyro_z, "title=\"Gyro Z\";rt=\"deg/sec\"",
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* TMP sensor resources and handlers: Object, Ambient */
|
||||
static void
|
||||
res_get_handler_obj_temp(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_obj_temp(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_TMP_OBJECT, request, response,
|
||||
|
@ -207,7 +218,8 @@ res_get_handler_obj_temp(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_amb_temp(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_amb_temp(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_TMP_AMBIENT, request, response,
|
||||
|
@ -222,7 +234,8 @@ RESOURCE(res_tmp007_amb, "title=\"Temperature (Ambient)\";rt=\"C\"",
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* BMP sensor resources: Temperature, Pressure */
|
||||
static void
|
||||
res_get_handler_bmp_temp(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_bmp_temp(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BMP_TEMP, request, response,
|
||||
|
@ -230,7 +243,8 @@ res_get_handler_bmp_temp(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_bmp_press(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_bmp_press(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BMP_PRES, request, response,
|
||||
|
@ -246,7 +260,8 @@ RESOURCE(res_bmp280_press,
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* HDC1000 sensor resources and handler: Temperature, Pressure */
|
||||
static void
|
||||
res_get_handler_hdc_temp(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_hdc_temp(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_HDC_TEMP, request, response,
|
||||
|
@ -254,7 +269,8 @@ res_get_handler_hdc_temp(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_get_handler_hdc_humidity(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_hdc_humidity(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_HDC_HUMIDITY, request, response,
|
||||
|
@ -269,7 +285,8 @@ RESOURCE(res_hdc1000_hum, "title=\"Humidity\";rt=\"%RH\"",
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Illuminance resources and handler */
|
||||
static void
|
||||
res_get_handler_opt(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler_opt(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_OPT_LIGHT, request, response,
|
||||
|
|
|
@ -42,20 +42,22 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_handler_red(void *request, void *response, uint8_t *buffer,
|
||||
res_post_handler_red(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_toggle(LEDS_RED);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_handler_green(void *request, void *response, uint8_t *buffer,
|
||||
res_post_handler_green(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_toggle(LEDS_GREEN);
|
||||
|
@ -81,14 +83,16 @@ RESOURCE(res_toggle_green,
|
|||
#if BOARD_SMARTRF06EB
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_handler_yellow(void *request, void *response, uint8_t *buffer,
|
||||
res_post_handler_yellow(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_toggle(LEDS_YELLOW);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
res_post_handler_orange(void *request, void *response, uint8_t *buffer,
|
||||
res_post_handler_orange(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_toggle(LEDS_ORANGE);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#if UIP_CONF_IPV6_RPL_LITE == 0
|
||||
#include "rpl-private.h"
|
||||
#endif /* UIP_CONF_IPV6_RPL_LITE == 0 */
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
@ -104,38 +104,38 @@ 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)
|
||||
readings_get_handler(coap_message_t *request, coap_message_t *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);
|
||||
coap_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,
|
||||
if(accept == -1 || accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_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",
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE, "Temp=%dC, Voltage=%dmV",
|
||||
temp, (voltage * 125) >> 5);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, not_supported_msg,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_payload(response, not_supported_msg,
|
||||
strlen(not_supported_msg));
|
||||
}
|
||||
}
|
||||
|
@ -144,39 +144,39 @@ 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)
|
||||
conf_get_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
unsigned int accept = -1;
|
||||
|
||||
if(request != NULL) {
|
||||
REST.get_header_accept(request, &accept);
|
||||
coap_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,
|
||||
if(accept == -1 || accept == APPLICATION_JSON) {
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
snprintf((char *)buffer, COAP_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,
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
snprintf((char *)buffer, COAP_MAX_CHUNK_SIZE,
|
||||
"Mode=%u, Duration=%lusecs, Interval=%lusecs",
|
||||
config.mode, config.duration, config.interval);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
REST.set_response_payload(response, not_supported_msg,
|
||||
coap_set_status_code(response, NOT_ACCEPTABLE_4_06);
|
||||
coap_set_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)
|
||||
conf_post_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
char tmp_buf[16];
|
||||
|
@ -186,7 +186,7 @@ conf_post_handler(void *request, void *response, uint8_t *buffer,
|
|||
uint8_t post_status = POST_STATUS_NONE;
|
||||
int rv;
|
||||
|
||||
rv = REST.get_post_variable(request, "mode", &ptr);
|
||||
rv = coap_get_post_variable(request, "mode", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
|
@ -203,7 +203,7 @@ conf_post_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
rv = REST.get_post_variable(request, "duration", &ptr);
|
||||
rv = coap_get_post_variable(request, "duration", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
|
@ -217,7 +217,7 @@ conf_post_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
rv = REST.get_post_variable(request, "interval", &ptr);
|
||||
rv = coap_get_post_variable(request, "interval", &ptr);
|
||||
if(rv && rv < 16) {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memcpy(tmp_buf, ptr, rv);
|
||||
|
@ -232,13 +232,13 @@ conf_post_handler(void *request, void *response, uint8_t *buffer,
|
|||
|
||||
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,
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
snprintf((char *)buffer, COAP_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));
|
||||
coap_set_payload(response, buffer, strlen((char *)buffer));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -345,11 +345,11 @@ PROCESS_THREAD(very_sleepy_demo_process, ev, data)
|
|||
|
||||
event_new_config = process_alloc_event();
|
||||
|
||||
rest_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
readings_resource.flags += IS_OBSERVABLE;
|
||||
rest_activate_resource(&readings_resource, "sen/readings");
|
||||
rest_activate_resource(&very_sleepy_conf, "very_sleepy_config");
|
||||
coap_activate_resource(&readings_resource, "sen/readings");
|
||||
coap_activate_resource(&very_sleepy_conf, "very_sleepy_config");
|
||||
|
||||
printf("Very Sleepy Demo Process\n");
|
||||
|
||||
|
@ -390,7 +390,7 @@ PROCESS_THREAD(very_sleepy_demo_process, ev, data)
|
|||
* send notifications to observers as required.
|
||||
*/
|
||||
if(state == STATE_NOTIFY_OBSERVERS) {
|
||||
REST.notify_subscribers(&readings_resource);
|
||||
coap_notify_observers(&readings_resource);
|
||||
state = STATE_NORMAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,15 +35,15 @@
|
|||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "tools/rpl-tools.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "sys/ctimer.h"
|
||||
#include <stdio.h>
|
||||
#include "dev/leds.h"
|
||||
|
||||
static void ct_callback(void *ptr);
|
||||
static void put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_toggle_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
static struct ctimer ct;
|
||||
|
||||
|
@ -77,7 +77,7 @@ RESOURCE(resource_led_toggle,
|
|||
put_post_led_toggle_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_toggle_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
static int led_state = 0;
|
||||
unsigned int accept = -1;
|
||||
|
@ -110,10 +110,10 @@ put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint
|
|||
break;
|
||||
}
|
||||
/* Return message */
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -137,8 +137,8 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
rpl_tools_init(NULL);
|
||||
} printf("Starting RPL node\n");
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_led_toggle, "Dongle/LED-toggle");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_led_toggle, "Dongle/LED-toggle");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "tools/rpl-tools.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "light-sensor.h"
|
||||
#include "ht-sensor.h"
|
||||
#include "dev/leds.h"
|
||||
|
@ -46,19 +46,19 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
static void event_sensors_dr1175_handler(void);
|
||||
static void get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_sensors_dr1175_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_light_sensor_value_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_light_sensor_unit_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_temperature_value_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_temperature_unit_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_humidity_value_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_humidity_unit_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_white_led_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_rgb_led_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d6_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
|
||||
#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } }
|
||||
|
@ -90,26 +90,26 @@ EVENT_RESOURCE(resource_sensors_dr1175, /* name */
|
|||
NULL, /* DELETE handler */
|
||||
event_sensors_dr1175_handler); /* event handler */
|
||||
static void
|
||||
get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_sensors_dr1175_handler(coap_message_t *request, coap_message_t *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.APPLICATION_JSON) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == APPLICATION_JSON) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("{\"DR1175\":[");
|
||||
CONTENT_PRINTF("{\"Humidity\":\"%d\"},", ht_sensor.value(HT_SENSOR_HUM));
|
||||
CONTENT_PRINTF("{\"Light\":\"%d\"},", light_sensor.value(0));
|
||||
CONTENT_PRINTF("{\"Temp\":\"%d\"}", ht_sensor.value(HT_SENSOR_TEMP));
|
||||
CONTENT_PRINTF("]}");
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
static void
|
||||
event_sensors_dr1175_handler()
|
||||
{
|
||||
/* Registered observers are notified and will trigger the GET handler to create the response. */
|
||||
REST.notify_subscribers(&resource_sensors_dr1175);
|
||||
coap_notify_observers(&resource_sensors_dr1175);
|
||||
}
|
||||
/*****************************************************/
|
||||
/* Resource and handler to obtain light sensor value */
|
||||
|
@ -121,15 +121,15 @@ RESOURCE(resource_light_sensor_value,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_light_sensor_value_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("%d", light_sensor.value(0));
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/***************************************************/
|
||||
|
@ -142,15 +142,15 @@ RESOURCE(resource_light_sensor_unit,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_light_sensor_unit_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("Lux");
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/***********************************************************/
|
||||
|
@ -163,15 +163,15 @@ RESOURCE(resource_temperature_value,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_temperature_value_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_TEMP));
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/*********************************************************/
|
||||
|
@ -184,15 +184,15 @@ RESOURCE(resource_temperature_unit,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_temperature_unit_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("degrees C");
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/********************************************************/
|
||||
|
@ -205,15 +205,15 @@ RESOURCE(resource_humidity_value,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_humidity_value_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_HUM));
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/******************************************************/
|
||||
|
@ -226,15 +226,15 @@ RESOURCE(resource_humidity_unit,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_humidity_unit_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("relative %%");
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/***************************************************/
|
||||
|
@ -247,15 +247,15 @@ RESOURCE(resource_white_led,
|
|||
put_post_white_led_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_white_led_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content = NULL;
|
||||
int level;
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
level = atoi((const char *)request_content);
|
||||
CLIP(level, 255)
|
||||
leds_set_level(level, LEDS_WHITE);
|
||||
|
@ -271,7 +271,7 @@ RESOURCE(resource_rgb_led,
|
|||
put_post_rgb_led_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_rgb_led_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content = NULL;
|
||||
char *pch;
|
||||
|
@ -279,9 +279,9 @@ put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_
|
|||
int index = 0;
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
pch = strtok((char *)request_content, " ");
|
||||
while((pch != NULL) && (index != sizeof(RGB) / sizeof(int))) {
|
||||
/* Convert token to int */
|
||||
|
@ -306,13 +306,13 @@ RESOURCE(resource_led_d3_1174,
|
|||
put_post_led_d3_1174_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d3_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_GP0);
|
||||
}
|
||||
}
|
||||
|
@ -326,13 +326,13 @@ RESOURCE(resource_led_d6_1174,
|
|||
put_post_led_d6_1174_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d6_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_GP1);
|
||||
}
|
||||
}
|
||||
|
@ -357,18 +357,18 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
rpl_tools_init(NULL);
|
||||
} printf("Starting RPL node\n");
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_light_sensor_value, "DR1175/LightSensor/Value");
|
||||
rest_activate_resource(&resource_light_sensor_unit, "DR1175/LightSensor/Unit");
|
||||
rest_activate_resource(&resource_temperature_unit, "DR1175/Temperature/Unit");
|
||||
rest_activate_resource(&resource_temperature_value, "DR1175/Temperature/Value");
|
||||
rest_activate_resource(&resource_humidity_unit, "DR1175/Humidity/Unit");
|
||||
rest_activate_resource(&resource_humidity_value, "DR1175/Humidity/Value");
|
||||
rest_activate_resource(&resource_white_led, "DR1175/WhiteLED");
|
||||
rest_activate_resource(&resource_rgb_led, "DR1175/ColorLED/RGBValue");
|
||||
rest_activate_resource(&resource_led_d3_1174, "DR1175/LED/D3On1174");
|
||||
rest_activate_resource(&resource_led_d6_1174, "DR1175/LED/D6On1174");
|
||||
rest_activate_resource(&resource_sensors_dr1175, "DR1175/AllSensors");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_light_sensor_value, "DR1175/LightSensor/Value");
|
||||
coap_activate_resource(&resource_light_sensor_unit, "DR1175/LightSensor/Unit");
|
||||
coap_activate_resource(&resource_temperature_unit, "DR1175/Temperature/Unit");
|
||||
coap_activate_resource(&resource_temperature_value, "DR1175/Temperature/Value");
|
||||
coap_activate_resource(&resource_humidity_unit, "DR1175/Humidity/Unit");
|
||||
coap_activate_resource(&resource_humidity_value, "DR1175/Humidity/Value");
|
||||
coap_activate_resource(&resource_white_led, "DR1175/WhiteLED");
|
||||
coap_activate_resource(&resource_rgb_led, "DR1175/ColorLED/RGBValue");
|
||||
coap_activate_resource(&resource_led_d3_1174, "DR1175/LED/D3On1174");
|
||||
coap_activate_resource(&resource_led_d6_1174, "DR1175/LED/D6On1174");
|
||||
coap_activate_resource(&resource_sensors_dr1175, "DR1175/AllSensors");
|
||||
|
||||
/* Level of LEDS=0, so no light after start-up */
|
||||
leds_on(LEDS_WHITE | LEDS_RED | LEDS_GREEN | LEDS_BLUE);
|
||||
|
|
|
@ -35,30 +35,30 @@
|
|||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "tools/rpl-tools.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
#include "button-sensor.h"
|
||||
#include "pot-sensor.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
|
||||
static void event_sensors_dr1199_handler();
|
||||
static void get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_sensors_dr1199_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw2_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw3_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_sw4_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_switch_dio8_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_pot_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d2_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d3_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_d6_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_led_all_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } }
|
||||
|
||||
|
@ -93,25 +93,25 @@ EVENT_RESOURCE(resource_sensors_dr1199, /* name */
|
|||
NULL, /* DELETE handler */
|
||||
event_sensors_dr1199_handler); /* event handler */
|
||||
static void
|
||||
get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_sensors_dr1199_handler(coap_message_t *request, coap_message_t *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.APPLICATION_JSON) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == APPLICATION_JSON) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("{\"DR1199\":[");
|
||||
CONTENT_PRINTF("{\"Switch\":\"0x%X\"},", button_sensor.value(0));
|
||||
CONTENT_PRINTF("{\"Pot\":\"%d\"}", pot_sensor.value(0));
|
||||
CONTENT_PRINTF("]}");
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, APPLICATION_JSON);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
static void
|
||||
event_sensors_dr1199_handler()
|
||||
{
|
||||
/* Registered observers are notified and will trigger the GET handler to create the response. */
|
||||
REST.notify_subscribers(&resource_sensors_dr1199);
|
||||
coap_notify_observers(&resource_sensors_dr1199);
|
||||
}
|
||||
/***********************************************/
|
||||
/* Resource and handler to obtain switch value */
|
||||
|
@ -123,15 +123,15 @@ RESOURCE(resource_switch_sw1,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_switch_sw1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
PARSE_SWITCH(1)
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
RESOURCE(resource_switch_sw2,
|
||||
|
@ -141,15 +141,15 @@ RESOURCE(resource_switch_sw2,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_switch_sw2_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
PARSE_SWITCH(2)
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
RESOURCE(resource_switch_sw3,
|
||||
|
@ -159,15 +159,15 @@ RESOURCE(resource_switch_sw3,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_switch_sw3_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
PARSE_SWITCH(3)
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
RESOURCE(resource_switch_sw4,
|
||||
|
@ -177,15 +177,15 @@ RESOURCE(resource_switch_sw4,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_switch_sw4_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
PARSE_SWITCH(4)
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
RESOURCE(resource_switch_dio8,
|
||||
|
@ -195,15 +195,15 @@ RESOURCE(resource_switch_dio8,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_switch_dio8_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
PARSE_SWITCH(0)
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/*******************************************************/
|
||||
|
@ -216,15 +216,15 @@ RESOURCE(resource_pot,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_pot_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
content_len = 0;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
CONTENT_PRINTF("%d", pot_sensor.value(0));
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/************************************/
|
||||
|
@ -237,13 +237,13 @@ RESOURCE(resource_led_d1,
|
|||
put_post_led_d1_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_GREEN)
|
||||
}
|
||||
}
|
||||
|
@ -254,13 +254,13 @@ RESOURCE(resource_led_d2,
|
|||
put_post_led_d2_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d2_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_BLUE)
|
||||
}
|
||||
}
|
||||
|
@ -271,13 +271,13 @@ RESOURCE(resource_led_d3,
|
|||
put_post_led_d3_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d3_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_RED)
|
||||
}
|
||||
}
|
||||
|
@ -288,13 +288,13 @@ RESOURCE(resource_led_d3_1174,
|
|||
put_post_led_d3_1174_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d3_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_GP0);
|
||||
}
|
||||
}
|
||||
|
@ -305,13 +305,13 @@ RESOURCE(resource_led_d6_1174,
|
|||
put_post_led_d6_1174_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_d6_1174_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
SET_LED(LEDS_GP1);
|
||||
}
|
||||
}
|
||||
|
@ -322,13 +322,13 @@ RESOURCE(resource_led_all,
|
|||
put_post_led_all_handler,
|
||||
NULL);
|
||||
static void
|
||||
put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_led_all_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
if(atoi((const char *)request_content) != 0) {
|
||||
leds_on(LEDS_ALL);
|
||||
} else {
|
||||
|
@ -358,20 +358,20 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
rpl_tools_init(NULL);
|
||||
} printf("Starting RPL node\n");
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_switch_sw1, "DR1199/Switch/SW1");
|
||||
rest_activate_resource(&resource_switch_sw2, "DR1199/Switch/SW2");
|
||||
rest_activate_resource(&resource_switch_sw3, "DR1199/Switch/SW3");
|
||||
rest_activate_resource(&resource_switch_sw4, "DR1199/Switch/SW4");
|
||||
rest_activate_resource(&resource_switch_dio8, "DR1199/Switch/DIO8");
|
||||
rest_activate_resource(&resource_pot, "DR1199/Potentiometer");
|
||||
rest_activate_resource(&resource_led_d1, "DR1199/LED/D1");
|
||||
rest_activate_resource(&resource_led_d2, "DR1199/LED/D2");
|
||||
rest_activate_resource(&resource_led_d3, "DR1199/LED/D3");
|
||||
rest_activate_resource(&resource_led_d3_1174, "DR1199/LED/D3On1174");
|
||||
rest_activate_resource(&resource_led_d6_1174, "DR1199/LED/D6On1174");
|
||||
rest_activate_resource(&resource_led_all, "DR1199/LED/All");
|
||||
rest_activate_resource(&resource_sensors_dr1199, "DR1199/AllSensors");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_switch_sw1, "DR1199/Switch/SW1");
|
||||
coap_activate_resource(&resource_switch_sw2, "DR1199/Switch/SW2");
|
||||
coap_activate_resource(&resource_switch_sw3, "DR1199/Switch/SW3");
|
||||
coap_activate_resource(&resource_switch_sw4, "DR1199/Switch/SW4");
|
||||
coap_activate_resource(&resource_switch_dio8, "DR1199/Switch/DIO8");
|
||||
coap_activate_resource(&resource_pot, "DR1199/Potentiometer");
|
||||
coap_activate_resource(&resource_led_d1, "DR1199/LED/D1");
|
||||
coap_activate_resource(&resource_led_d2, "DR1199/LED/D2");
|
||||
coap_activate_resource(&resource_led_d3, "DR1199/LED/D3");
|
||||
coap_activate_resource(&resource_led_d3_1174, "DR1199/LED/D3On1174");
|
||||
coap_activate_resource(&resource_led_d6_1174, "DR1199/LED/D6On1174");
|
||||
coap_activate_resource(&resource_led_all, "DR1199/LED/All");
|
||||
coap_activate_resource(&resource_sensors_dr1199, "DR1199/AllSensors");
|
||||
/* If sensor process generates an event, call event_handler of resource.
|
||||
This will make this resource observable by the client */
|
||||
while(1) {
|
||||
|
@ -382,4 +382,3 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,15 @@
|
|||
#include "net/ipv6/uip.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "rpl-tools.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <AppHardwareApi.h>
|
||||
|
||||
static void set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void set_tx_power_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_tx_power_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
|
||||
#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); }
|
||||
|
@ -63,15 +63,15 @@ RESOURCE(resource_set_tx_power,
|
|||
set_tx_power_handler,
|
||||
NULL);
|
||||
static void
|
||||
set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
set_tx_power_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content = NULL;
|
||||
int tx_level;
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
tx_level = atoi((const char *)request_content);
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_TXPOWER, tx_level);
|
||||
}
|
||||
|
@ -84,17 +84,17 @@ RESOURCE(resource_get_tx_power,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_tx_power_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int tx_level;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
NETSTACK_RADIO.get_value(RADIO_PARAM_TXPOWER, &tx_level);
|
||||
CONTENT_PRINTF("%d", tx_level);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -113,9 +113,9 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
}
|
||||
printf("Starting RPL node\n");
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_set_tx_power, "Set-TX-Power");
|
||||
rest_activate_resource(&resource_get_tx_power, "Get-TX-Power");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_set_tx_power, "Set-TX-Power");
|
||||
coap_activate_resource(&resource_get_tx_power, "Get-TX-Power");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "net/mac/tsch/tsch-schedule.h"
|
||||
#include "net/netstack.h"
|
||||
#include "dev/slip.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "rpl-tools.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -56,10 +56,10 @@
|
|||
static uip_ipaddr_t prefix;
|
||||
static uint8_t prefix_set;
|
||||
|
||||
static void get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_rssi_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_last_rssi_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
|
||||
#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); }
|
||||
|
@ -74,17 +74,17 @@ RESOURCE(resource_get_rssi,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_rssi_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int rssi_level;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
NETSTACK_RADIO.get_value(RADIO_PARAM_RSSI, &rssi_level);
|
||||
CONTENT_PRINTF("%d", rssi_level);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,17 +95,17 @@ RESOURCE(resource_get_last_rssi,
|
|||
NULL,
|
||||
NULL);
|
||||
static void
|
||||
get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_last_rssi_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int last_rssi_level;
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &last_rssi_level);
|
||||
CONTENT_PRINTF("%d", last_rssi_level);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,9 +159,9 @@ PROCESS_THREAD(border_router_process, ev, data)
|
|||
|
||||
rpl_tools_init(&prefix);
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_get_rssi, "Get-RSSI");
|
||||
rest_activate_resource(&resource_get_last_rssi, "Get-Last-RSSI");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_get_rssi, "Get-RSSI");
|
||||
coap_activate_resource(&resource_get_last_rssi, "Get-Last-RSSI");
|
||||
|
||||
|
||||
PROCESS_END();
|
||||
|
|
|
@ -36,22 +36,22 @@
|
|||
#include "net/ipv6/uip.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "rpl-tools.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "sys/ctimer.h"
|
||||
#include "dev/uart-driver.h"
|
||||
#include "uart1.h"
|
||||
#include <AppHardwareApi.h>
|
||||
|
||||
static void get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void get_coap_rx_uart1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void event_coap_rx_uart1_handler(void);
|
||||
static void put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void put_post_tx_uart1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void string2uart1(uint8_t *c);
|
||||
static int handleRxChar(uint8_t c);
|
||||
static int get_ringbuf(uint8_t *c);
|
||||
static int put_ringbuf(uint8_t c);
|
||||
|
||||
/* COAP helpers */
|
||||
static char content[REST_MAX_CHUNK_SIZE];
|
||||
static char content[COAP_MAX_CHUNK_SIZE];
|
||||
static int content_len = 0;
|
||||
#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); }
|
||||
|
||||
|
@ -85,15 +85,15 @@ EVENT_RESOURCE(resource_coap_rx_uart1, /* name */
|
|||
NULL, /* DELETE handler */
|
||||
event_coap_rx_uart1_handler); /* event handler */
|
||||
static void
|
||||
get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
get_coap_rx_uart1_handler(coap_message_t *request, coap_message_t *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) {
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
content_len = 0;
|
||||
CONTENT_PRINTF("%s", rx_buf);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, (uint8_t *)content, content_len);
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, (uint8_t *)content, content_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ static void
|
|||
event_coap_rx_uart1_handler(void)
|
||||
{
|
||||
/* Registered observers are notified and will trigger the GET handler to create the response. */
|
||||
REST.notify_subscribers(&resource_coap_rx_uart1);
|
||||
coap_notify_observers(&resource_coap_rx_uart1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -115,14 +115,14 @@ RESOURCE(resource_coap_tx_uart1, /* name */
|
|||
NULL); /* DELETE handler */
|
||||
|
||||
static void
|
||||
put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
put_post_tx_uart1_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *request_content = NULL;
|
||||
unsigned int accept = -1;
|
||||
|
||||
REST.get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.get_request_payload(request, &request_content);
|
||||
coap_get_header_accept(request, &accept);
|
||||
if(accept == -1 || accept == TEXT_PLAIN) {
|
||||
coap_get_payload(request, &request_content);
|
||||
string2uart1((uint8_t *)request_content);
|
||||
}
|
||||
}
|
||||
|
@ -154,9 +154,9 @@ PROCESS_THREAD(start_app, ev, data)
|
|||
}
|
||||
printf("Starting RPL node\n");
|
||||
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&resource_coap_rx_uart1, "UART1-RX");
|
||||
rest_activate_resource(&resource_coap_tx_uart1, "UART1-TX");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&resource_coap_rx_uart1, "UART1-RX");
|
||||
coap_activate_resource(&resource_coap_tx_uart1, "UART1-TX");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
@ -256,4 +256,3 @@ put_ringbuf(uint8_t c)
|
|||
uart1_enable_interrupts();
|
||||
return return_val;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ $(error Please specify whether coap-client or coap-server should be built)
|
|||
endif
|
||||
|
||||
ifneq ($(filter coap-client coap-client.flash, $(MAKECMDGOALS)),)
|
||||
ifeq ($(SERVER_IPV6_ADDR),)
|
||||
$(error Please define SERVER_IPV6_ADDR=<full ipv6 addr>)
|
||||
ifeq ($(SERVER_IPV6_EP),)
|
||||
$(error Please define SERVER_IPV6_EP=<full-coap-IPv6-URI>)
|
||||
else
|
||||
CFLAGS += -DSERVER_IPV6_ADDR=\"$(SERVER_IPV6_ADDR)\"
|
||||
CFLAGS += -DSERVER_IPV6_EP=\"$(SERVER_IPV6_EP)\"
|
||||
CFLAGS += -DDEVICE_NAME=\"nRF52_DK_CoAP_Client\"
|
||||
endif
|
||||
else
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap-endpoint.h"
|
||||
#include "dev/button-sensor.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
|
@ -63,13 +64,11 @@
|
|||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
#define OBS_RESOURCE_URI "lights/led3"
|
||||
#define SUBS_LED LEDS_4
|
||||
#define OBS_LED LEDS_3
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static uip_ipaddr_t server_ipaddr[1]; /* holds the server ip address */
|
||||
static coap_observee_t *obs;
|
||||
static struct ctimer ct;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
@ -146,11 +145,11 @@ notification_callback(coap_observee_t *obs, void *notification,
|
|||
PROCESS_THREAD(er_example_observe_client, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
uiplib_ipaddrconv(SERVER_IPV6_ADDR, server_ipaddr);
|
||||
static coap_endpoint_t server_endpoint;
|
||||
coap_endpoint_parse(SERVER_IPV6_EP, strlen(SERVER_IPV6_EP), &server_endpoint);
|
||||
|
||||
/* receives all CoAP messages */
|
||||
coap_init_engine();
|
||||
coap_engine_init();
|
||||
|
||||
#if PLATFORM_HAS_BUTTON
|
||||
SENSORS_ACTIVATE(button_1);
|
||||
|
@ -164,7 +163,7 @@ PROCESS_THREAD(er_example_observe_client, ev, data)
|
|||
if (ev == sensors_event) {
|
||||
if (data == &button_1 && button_1.value(BUTTON_SENSOR_VALUE_STATE) == 0) {
|
||||
PRINTF("Starting observation\n");
|
||||
obs = coap_obs_request_registration(server_ipaddr, REMOTE_PORT,
|
||||
obs = coap_obs_request_registration(&server_endpoint,
|
||||
OBS_RESOURCE_URI, notification_callback,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include <string.h>
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap-engine.h"
|
||||
#include "uip.h"
|
||||
#include "dev/button-sensor.h"
|
||||
#include "dev/leds.h"
|
||||
|
@ -63,7 +63,7 @@
|
|||
* Resources to be activated need to be imported through the extern keyword.
|
||||
* The build system automatically compiles the resources in the corresponding sub-directory.
|
||||
*/
|
||||
extern resource_t res_led3;
|
||||
extern coap_resource_t res_led3;
|
||||
|
||||
static void
|
||||
print_local_addresses(void)
|
||||
|
@ -99,13 +99,13 @@ PROCESS_THREAD(er_example_server, ev, data)
|
|||
PRINTF("uIP buffer: %u\n", UIP_BUFSIZE);
|
||||
PRINTF("LL header: %u\n", UIP_LLH_LEN);
|
||||
PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN);
|
||||
PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE);
|
||||
PRINTF("REST max chunk: %u\n", COAP_MAX_CHUNK_SIZE);
|
||||
|
||||
print_local_addresses();
|
||||
|
||||
/* Initialize the REST engine. */
|
||||
rest_init_engine();
|
||||
rest_activate_resource(&res_led3, "lights/led3");
|
||||
coap_engine_init();
|
||||
coap_activate_resource(&res_led3, "lights/led3");
|
||||
|
||||
SENSORS_ACTIVATE(button_1);
|
||||
|
||||
|
|
|
@ -40,22 +40,25 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
#include "coap.h"
|
||||
#include "coap-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
static void
|
||||
res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
||||
res_post_put_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
static void
|
||||
res_event_handler();
|
||||
res_event_handler(void);
|
||||
|
||||
/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/
|
||||
EVENT_RESOURCE(res_led3,
|
||||
|
@ -68,30 +71,30 @@ EVENT_RESOURCE(res_led3,
|
|||
);
|
||||
|
||||
static void
|
||||
res_post_put_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
res_post_put_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const uint8_t *payload;
|
||||
REST.get_request_payload(request, &payload);
|
||||
coap_get_payload(request, &payload);
|
||||
|
||||
if (*payload == '0' || *payload == '1') {
|
||||
if (*payload == '1') {
|
||||
if(*payload == '0' || *payload == '1') {
|
||||
if(*payload == '1') {
|
||||
leds_on(LEDS_3);
|
||||
} else {
|
||||
leds_off(LEDS_3);
|
||||
}
|
||||
REST.notify_subscribers(&res_led3);
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_notify_observers(&res_led3);
|
||||
coap_set_status_code(response, CHANGED_2_04);
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
coap_set_status_code(response, BAD_REQUEST_4_00);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(coap_message_t *request, coap_message_t *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "%d", (leds_get() & LEDS_3) ? 1 : 0));
|
||||
coap_set_header_content_format(response, TEXT_PLAIN);
|
||||
coap_set_payload(response, buffer, snprintf((char *)buffer, preferred_size, "%d", (leds_get() & LEDS_3) ? 1 : 0));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -102,5 +105,5 @@ static void
|
|||
res_event_handler()
|
||||
{
|
||||
/* Notify the registered observers which will trigger the res_get_handler to create the response. */
|
||||
REST.notify_subscribers(&res_led3);
|
||||
coap_notify_observers(&res_led3);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
MAKE_WITH_DTLS ?= 0
|
||||
|
||||
ifeq ($(MAKE_WITH_DTLS),1)
|
||||
|
||||
TINYDTLS_PATH := os/net/security/tinydtls
|
||||
|
||||
ifeq (${wildcard $(CONTIKI)/$(TINYDTLS_PATH)/Makefile},)
|
||||
${error Could not find the tinyDTLS submodule. Please run "git submodule update --init" and try again}
|
||||
endif
|
||||
|
||||
CFLAGS += -DWITH_DTLS=1
|
||||
|
||||
MODULES += os/net/app-layer/coap/tinydtls-support
|
||||
MODULES += $(TINYDTLS_PATH) ${addprefix $(TINYDTLS_PATH)/,aes sha2 ecc}
|
||||
|
||||
MAKE_COAP_DTLS_KEYSTORE_NONE := 0
|
||||
MAKE_COAP_DTLS_KEYSTORE_SIMPLE := 1
|
||||
MAKE_COAP_DTLS_KEYSTORE_LWM2M := 2
|
||||
|
||||
MAKE_COAP_DTLS_KEYSTORE ?= MAKE_COAP_DTLS_KEYSTORE_LWM2M
|
||||
|
||||
ifeq ($(MAKE_COAP_DTLS_KEYSTORE),MAKE_COAP_DTLS_KEYSTORE_SIMPLE)
|
||||
CFLAGS += -DCOAP_DTLS_KEYSTORE_CONF_WITH_SIMPLE=1
|
||||
else ifeq ($(MAKE_COAP_DTLS_KEYSTORE),MAKE_COAP_DTLS_KEYSTORE_LWM2M)
|
||||
CFLAGS += -DCOAP_DTLS_KEYSTORE_CONF_WITH_LWM2M=1
|
||||
else ifeq ($(MAKE_COAP_DTLS_KEYSTORE),MAKE_COAP_DTLS_KEYSTORE_NONE)
|
||||
# No C flag needed for no keystore
|
||||
else
|
||||
${error Unsupported CoAP DTLS keystore: $(MAKE_COAP_DTLS_KEYSTORE)}
|
||||
endif
|
||||
endif
|
|
@ -36,24 +36,23 @@
|
|||
* Lars Schmertmann <SmallLars@t-online.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-block1.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-block1"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Block 1 support within a coap-ressource
|
||||
|
@ -77,39 +76,39 @@
|
|||
* -1 if initialisation failed
|
||||
*/
|
||||
int
|
||||
coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len)
|
||||
coap_block1_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *target, size_t *len, size_t max_len)
|
||||
{
|
||||
const uint8_t *payload = 0;
|
||||
int pay_len = REST.get_request_payload(request, &payload);
|
||||
int pay_len = coap_get_payload(request, &payload);
|
||||
|
||||
if(!pay_len || !payload) {
|
||||
erbium_status_code = REST.status.BAD_REQUEST;
|
||||
coap_status_code = BAD_REQUEST_4_00;
|
||||
coap_error_message = "NoPayload";
|
||||
return -1;
|
||||
}
|
||||
|
||||
coap_packet_t *packet = (coap_packet_t *)request;
|
||||
|
||||
if(packet->block1_offset + pay_len > max_len) {
|
||||
erbium_status_code = REST.status.REQUEST_ENTITY_TOO_LARGE;
|
||||
if(request->block1_offset + pay_len > max_len) {
|
||||
coap_status_code = REQUEST_ENTITY_TOO_LARGE_4_13;
|
||||
coap_error_message = "Message to big";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(target && len) {
|
||||
memcpy(target + packet->block1_offset, payload, pay_len);
|
||||
*len = packet->block1_offset + pay_len;
|
||||
memcpy(target + request->block1_offset, payload, pay_len);
|
||||
*len = request->block1_offset + pay_len;
|
||||
}
|
||||
|
||||
if(IS_OPTION(packet, COAP_OPTION_BLOCK1)) {
|
||||
PRINTF("Blockwise: block 1 request: Num: %u, More: %u, Size: %u, Offset: %u\n",
|
||||
packet->block1_num,
|
||||
packet->block1_more,
|
||||
packet->block1_size,
|
||||
packet->block1_offset);
|
||||
if(coap_is_option(request, COAP_OPTION_BLOCK1)) {
|
||||
LOG_DBG("Blockwise: block 1 request: Num: %"PRIu32
|
||||
", More: %u, Size: %u, Offset: %"PRIu32"\n",
|
||||
request->block1_num,
|
||||
request->block1_more,
|
||||
request->block1_size,
|
||||
request->block1_offset);
|
||||
|
||||
coap_set_header_block1(response, packet->block1_num, packet->block1_more, packet->block1_size);
|
||||
if(packet->block1_more) {
|
||||
coap_set_header_block1(response, request->block1_num, request->block1_more, request->block1_size);
|
||||
if(request->block1_more) {
|
||||
coap_set_status_code(response, CONTINUE_2_31);
|
||||
return 1;
|
||||
}
|
||||
|
@ -117,3 +116,5 @@ coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len,
|
|||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -36,12 +36,20 @@
|
|||
* Lars Schmertmann <SmallLars@t-online.de>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_BLOCK1_H_
|
||||
#define COAP_BLOCK1_H_
|
||||
|
||||
#include "coap.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len);
|
||||
int coap_block1_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *target, size_t *len, size_t max_len);
|
||||
|
||||
#endif /* COAP_BLOCK1_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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
|
||||
* CoAP implementation for the REST Engine.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-engine.h"
|
||||
#include "coap-blocking-api.h"
|
||||
#include "sys/cc.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-blocking-api"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Client Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_blocking_request_callback(void *callback_data, coap_message_t *response)
|
||||
{
|
||||
coap_request_state_t *state = (coap_request_state_t *)callback_data;
|
||||
|
||||
state->response = response;
|
||||
process_poll(state->process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(coap_blocking_request
|
||||
(coap_request_state_t *state, process_event_t ev,
|
||||
coap_endpoint_t *remote_ep,
|
||||
coap_message_t *request,
|
||||
coap_blocking_response_handler_t request_callback))
|
||||
{
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
static uint32_t res_block;
|
||||
static uint8_t more;
|
||||
static uint8_t block_error;
|
||||
|
||||
state->block_num = 0;
|
||||
state->response = NULL;
|
||||
state->process = PROCESS_CURRENT();
|
||||
|
||||
more = 0;
|
||||
res_block = 0;
|
||||
block_error = 0;
|
||||
|
||||
do {
|
||||
request->mid = coap_get_mid();
|
||||
if((state->transaction = coap_new_transaction(request->mid, remote_ep))) {
|
||||
state->transaction->callback = coap_blocking_request_callback;
|
||||
state->transaction->callback_data = state;
|
||||
|
||||
if(state->block_num > 0) {
|
||||
coap_set_header_block2(request, state->block_num, 0,
|
||||
COAP_MAX_CHUNK_SIZE);
|
||||
}
|
||||
state->transaction->message_len = coap_serialize_message(request,
|
||||
state->
|
||||
transaction->
|
||||
message);
|
||||
|
||||
coap_send_transaction(state->transaction);
|
||||
LOG_DBG("Requested #%"PRIu32" (MID %u)\n", state->block_num, request->mid);
|
||||
|
||||
PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL);
|
||||
|
||||
if(!state->response) {
|
||||
LOG_WARN("Server not responding\n");
|
||||
PT_EXIT(&state->pt);
|
||||
}
|
||||
|
||||
coap_get_header_block2(state->response, &res_block, &more, NULL, NULL);
|
||||
|
||||
LOG_DBG("Received #%"PRIu32"%s (%u bytes)\n", res_block, more ? "+" : "",
|
||||
state->response->payload_len);
|
||||
|
||||
if(res_block == state->block_num) {
|
||||
request_callback(state->response);
|
||||
++(state->block_num);
|
||||
} else {
|
||||
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n",
|
||||
res_block, state->block_num);
|
||||
++block_error;
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("Could not allocate transaction buffer");
|
||||
PT_EXIT(&state->pt);
|
||||
}
|
||||
} while(more && block_error < COAP_MAX_ATTEMPTS);
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_BLOCKING_API_H_
|
||||
#define COAP_BLOCKING_API_H_
|
||||
|
||||
#include "sys/pt.h"
|
||||
#include "coap-transactions.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Client Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct coap_request_state {
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
coap_transaction_t *transaction;
|
||||
coap_message_t *response;
|
||||
uint32_t block_num;
|
||||
} coap_request_state_t;
|
||||
|
||||
typedef void (* coap_blocking_response_handler_t)(coap_message_t *response);
|
||||
|
||||
PT_THREAD(coap_blocking_request
|
||||
(coap_request_state_t *state, process_event_t ev,
|
||||
coap_endpoint_t *remote,
|
||||
coap_message_t *request,
|
||||
coap_blocking_response_handler_t request_callback));
|
||||
|
||||
#define COAP_BLOCKING_REQUEST(server_endpoint, request, chunk_handler) \
|
||||
{ \
|
||||
static coap_request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_endpoint, \
|
||||
request, chunk_handler) \
|
||||
); \
|
||||
}
|
||||
|
||||
#endif /* COAP_BLOCKING_API_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2016, SICS Swedish ICT
|
||||
* 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
|
||||
* Callback API for doing CoAP requests
|
||||
* Adapted from the blocking API
|
||||
* \author
|
||||
* Joakim Eriksson, joakime@sics.se
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-engine.h"
|
||||
#include "coap-callback-api.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "sys/cc.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-callback-api"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/* These should go into the state struct so that we can have multiple
|
||||
requests */
|
||||
|
||||
static uint32_t res_block;
|
||||
static uint8_t more;
|
||||
static uint8_t block_error;
|
||||
|
||||
static void coap_request_callback(void *callback_data, coap_message_t *response);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
progress_request(coap_request_state_t *state) {
|
||||
coap_message_t *request = state->request;
|
||||
request->mid = coap_get_mid();
|
||||
if((state->transaction =
|
||||
coap_new_transaction(request->mid, state->remote_endpoint))) {
|
||||
state->transaction->callback = coap_request_callback;
|
||||
state->transaction->callback_data = state;
|
||||
|
||||
if(state->block_num > 0) {
|
||||
coap_set_header_block2(request, state->block_num, 0,
|
||||
COAP_MAX_CHUNK_SIZE);
|
||||
}
|
||||
state->transaction->message_len =
|
||||
coap_serialize_message(request, state->transaction->message);
|
||||
|
||||
coap_send_transaction(state->transaction);
|
||||
LOG_DBG("Requested #%lu (MID %u)\n", (unsigned long)state->block_num,
|
||||
request->mid);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
coap_request_callback(void *callback_data, coap_message_t *response)
|
||||
{
|
||||
coap_request_state_t *state = (coap_request_state_t *)callback_data;
|
||||
uint32_t res_block1;
|
||||
|
||||
state->response = response;
|
||||
|
||||
LOG_DBG("request callback\n");
|
||||
|
||||
if(!state->response) {
|
||||
LOG_WARN("Server not responding giving up...\n");
|
||||
state->callback(state);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Got a response */
|
||||
coap_get_header_block2(state->response, &res_block, &more, NULL, NULL);
|
||||
coap_get_header_block1(state->response, &res_block1, NULL, NULL, NULL);
|
||||
|
||||
LOG_DBG("Received #%lu%s B1:%lu (%u bytes)\n",
|
||||
(unsigned long)res_block, (unsigned)more ? "+" : "",
|
||||
(unsigned long)res_block1,
|
||||
state->response->payload_len);
|
||||
|
||||
if(res_block == state->block_num) {
|
||||
/* Call the callback function as we have more data */
|
||||
state->callback(state);
|
||||
/* this is only for counting BLOCK2 blocks.*/
|
||||
++(state->block_num);
|
||||
} else {
|
||||
LOG_WARN("WRONG BLOCK %lu/%lu\n", (unsigned long)res_block,
|
||||
(unsigned long)state->block_num);
|
||||
++block_error;
|
||||
}
|
||||
|
||||
if(more && block_error < COAP_MAX_ATTEMPTS) {
|
||||
progress_request(state);
|
||||
} else {
|
||||
/* failure - now we give up and notify the callback */
|
||||
state->response = NULL;
|
||||
state->callback(state);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint,
|
||||
coap_message_t *request,
|
||||
void (*callback)(coap_request_state_t *state))
|
||||
{
|
||||
/* can we have these variables shared between multiple requests? */
|
||||
/* ripped from blocking request */
|
||||
more = 0;
|
||||
res_block = 0;
|
||||
block_error = 0;
|
||||
|
||||
state->block_num = 0;
|
||||
state->response = NULL;
|
||||
state->request = request;
|
||||
state->remote_endpoint = endpoint;
|
||||
state->callback = callback;
|
||||
|
||||
progress_request(state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
89
os/net/ipv6/uip-debug.c → os/net/app-layer/coap/coap-callback-api.h
Executable file → Normal file
89
os/net/ipv6/uip-debug.c → os/net/app-layer/coap/coap-callback-api.h
Executable file → Normal file
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2016, SICS Swedish ICT
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -26,65 +26,48 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A set of debugging tools for the IP stack
|
||||
* Callback API for doing CoAP requests
|
||||
* Adapted from the blocking API
|
||||
* \author
|
||||
* Nicolas Tsiftes <nvt@sics.se>
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
* Joakim Eriksson, joakime@sics.se
|
||||
*/
|
||||
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
#include "net/ipv6/ip64-addr.h"
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_CALLBACK_API_H_
|
||||
#define COAP_CALLBACK_API_H_
|
||||
|
||||
#include "coap-engine.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||
{
|
||||
uint16_t a;
|
||||
unsigned int i;
|
||||
int f;
|
||||
|
||||
if(addr == NULL) {
|
||||
PRINTA("(NULL IP addr)");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
|
||||
/*
|
||||
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
|
||||
*
|
||||
* "An alternative form that is sometimes more
|
||||
* convenient when dealing with a mixed environment
|
||||
* of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d,
|
||||
* where the 'x's are the hexadecimal values of the
|
||||
* six high-order 16-bit pieces of the address, and
|
||||
* the 'd's are the decimal values of the four
|
||||
* low-order 8-bit pieces of the address (standard
|
||||
* IPv4 representation)."
|
||||
*
|
||||
* [1] https://tools.ietf.org/html/rfc4291#page-4
|
||||
*/
|
||||
PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]);
|
||||
} else {
|
||||
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
|
||||
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||
if(a == 0 && f >= 0) {
|
||||
if(f++ == 0) {
|
||||
PRINTA("::");
|
||||
}
|
||||
} else {
|
||||
if(f > 0) {
|
||||
f = -1;
|
||||
} else if(i > 0) {
|
||||
PRINTA(":");
|
||||
}
|
||||
PRINTA("%x", a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*- Client Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct coap_request_state coap_request_state_t;
|
||||
|
||||
struct coap_request_state {
|
||||
coap_transaction_t *transaction;
|
||||
coap_message_t *response;
|
||||
coap_message_t *request;
|
||||
coap_endpoint_t *remote_endpoint;
|
||||
uint32_t block_num;
|
||||
void *user_data;
|
||||
coap_timer_t coap_timer;
|
||||
void (*callback)(coap_request_state_t *state);
|
||||
};
|
||||
|
||||
void coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint,
|
||||
coap_message_t *request,
|
||||
void (*callback)(coap_request_state_t *state));
|
||||
|
||||
#endif /* COAP_CALLBACK_API_H_ */
|
||||
/** @} */
|
|
@ -36,8 +36,33 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_CONF_H_
|
||||
#define ER_COAP_CONF_H_
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_CONF_H_
|
||||
#define COAP_CONF_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
/*
|
||||
* The maximum buffer size that is provided for resource responses and must be
|
||||
* respected due to the limited IP buffer. Larger data must be handled by the
|
||||
* resource and will be sent chunk-wise through a TCP stream or CoAP blocks.
|
||||
*/
|
||||
#ifndef COAP_MAX_CHUNK_SIZE
|
||||
#ifdef REST_MAX_CHUNK_SIZE
|
||||
#define COAP_MAX_CHUNK_SIZE REST_MAX_CHUNK_SIZE
|
||||
#else /* REST_MAX_CHUNK_SIZE */
|
||||
#define COAP_MAX_CHUNK_SIZE 64
|
||||
#endif /* REST_MAX_CHUNK_SIZE */
|
||||
#endif /* COAP_MAX_CHUNK_SIZE */
|
||||
|
||||
/* Define REST_MAX_CHUNK_SIZE for backward compatibility */
|
||||
#ifndef REST_MAX_CHUNK_SIZE
|
||||
#define REST_MAX_CHUNK_SIZE COAP_MAX_CHUNK_SIZE
|
||||
#endif /* REST_MAX_CHUNK_SIZE */
|
||||
|
||||
/* Features that can be disabled to achieve smaller memory footprint */
|
||||
#ifndef COAP_LINK_FORMAT_FILTERING
|
||||
|
@ -78,4 +103,5 @@
|
|||
#define COAP_OBSERVE_REFRESH_INTERVAL 20
|
||||
#endif /* COAP_OBSERVE_REFRESH_INTERVAL */
|
||||
|
||||
#endif /* ER_COAP_CONF_H_ */
|
||||
#endif /* COAP_CONF_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -36,10 +36,16 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_CONSTANTS_H_
|
||||
#define ER_COAP_CONSTANTS_H_
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_CONSTANTS_H_
|
||||
#define COAP_CONSTANTS_H_
|
||||
|
||||
#define COAP_DEFAULT_PORT 5683
|
||||
#define COAP_DEFAULT_SECURE_PORT 5684
|
||||
|
||||
#define COAP_DEFAULT_MAX_AGE 60
|
||||
#define COAP_RESPONSE_TIMEOUT 3
|
||||
|
@ -163,4 +169,24 @@ typedef enum {
|
|||
APPLICATION_X_OBIX_BINARY = 51
|
||||
} coap_content_format_t;
|
||||
|
||||
#endif /* ER_COAP_CONSTANTS_H_ */
|
||||
/**
|
||||
* Resource flags for allowed methods and special functionalities.
|
||||
*/
|
||||
typedef enum {
|
||||
NO_FLAGS = 0,
|
||||
|
||||
/* methods to handle */
|
||||
METHOD_GET = (1 << 0),
|
||||
METHOD_POST = (1 << 1),
|
||||
METHOD_PUT = (1 << 2),
|
||||
METHOD_DELETE = (1 << 3),
|
||||
|
||||
/* special flags */
|
||||
HAS_SUB_RESOURCES = (1 << 4),
|
||||
IS_SEPARATE = (1 << 5),
|
||||
IS_OBSERVABLE = (1 << 6),
|
||||
IS_PERIODIC = (1 << 7)
|
||||
} coap_resource_flags_t;
|
||||
|
||||
#endif /* COAP_CONSTANTS_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2018, SICS, Swedish ICT AB.
|
||||
* 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
|
||||
* API to address CoAP endpoints
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap-transport
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_ENDPOINT_H_
|
||||
#define COAP_ENDPOINT_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef COAP_ENDPOINT_CUSTOM
|
||||
#include "net/ipv6/uip.h"
|
||||
|
||||
typedef struct {
|
||||
uip_ipaddr_t ipaddr;
|
||||
uint16_t port;
|
||||
uint8_t secure;
|
||||
} coap_endpoint_t;
|
||||
#endif /* COAP_ENDPOINT_CUSTOM */
|
||||
|
||||
/**
|
||||
* \brief Copy a CoAP endpoint from one memory area to another.
|
||||
*
|
||||
* \param dest A pointer to a CoAP endpoint to copy to.
|
||||
* \param src A pointer to a CoAP endpoint to copy from.
|
||||
*/
|
||||
void coap_endpoint_copy(coap_endpoint_t *dest, const coap_endpoint_t *src);
|
||||
|
||||
/**
|
||||
* \brief Compare two CoAP endpoints.
|
||||
*
|
||||
* \param e1 A pointer to the first CoAP endpoint.
|
||||
* \param e2 A pointer to the second CoAP endpoint.
|
||||
* \return Non-zero if the endpoints are identical and zero otherwise.
|
||||
*/
|
||||
int coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2);
|
||||
|
||||
/**
|
||||
* \brief Print a CoAP endpoint via the logging module.
|
||||
*
|
||||
* \param ep A pointer to the CoAP endpoint to log.
|
||||
*/
|
||||
void coap_endpoint_log(const coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Print a CoAP endpoint.
|
||||
*
|
||||
* \param ep A pointer to the CoAP endpoint to print.
|
||||
*/
|
||||
void coap_endpoint_print(const coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Print a CoAP endpoint to a string. The output is always
|
||||
* null-terminated unless size is zero.
|
||||
*
|
||||
* \param str The string to write to.
|
||||
* \param size The max number of characters to write.
|
||||
* \param ep A pointer to the CoAP endpoint to print.
|
||||
* \return Returns the number of characters needed for the output
|
||||
* excluding the ending null-terminator or negative if an
|
||||
* error occurred.
|
||||
*/
|
||||
int coap_endpoint_snprint(char *str, size_t size,
|
||||
const coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Parse a CoAP endpoint.
|
||||
*
|
||||
* \param text The string to parse.
|
||||
* \param size The max number of characters in the string.
|
||||
* \param ep A pointer to the CoAP endpoint to write to.
|
||||
* \return Returns non-zero if the endpoint was successfully parsed and
|
||||
* zero otherwise.
|
||||
*/
|
||||
int coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Check if a CoAP endpoint is secure (encrypted).
|
||||
*
|
||||
* \param ep A pointer to a CoAP endpoint.
|
||||
* \return Returns non-zero if the endpoint is secure and zero otherwise.
|
||||
*/
|
||||
int coap_endpoint_is_secure(const coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Check if a CoAP endpoint is connected.
|
||||
*
|
||||
* \param ep A pointer to a CoAP endpoint.
|
||||
* \return Returns non-zero if the endpoint is connected and zero otherwise.
|
||||
*/
|
||||
int coap_endpoint_is_connected(const coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Request a connection to a CoAP endpoint.
|
||||
*
|
||||
* \param ep A pointer to a CoAP endpoint.
|
||||
* \return Returns zero if an error occured and non-zero otherwise.
|
||||
*/
|
||||
int coap_endpoint_connect(coap_endpoint_t *ep);
|
||||
|
||||
/**
|
||||
* \brief Request that any connection to a CoAP endpoint is discontinued.
|
||||
*
|
||||
* \param ep A pointer to a CoAP endpoint.
|
||||
*/
|
||||
void coap_endpoint_disconnect(coap_endpoint_t *ep);
|
||||
|
||||
#endif /* COAP_ENDPOINT_H_ */
|
||||
/** @} */
|
|
@ -31,490 +31,484 @@
|
|||
|
||||
/**
|
||||
* \file
|
||||
* CoAP implementation for the REST Engine.
|
||||
* CoAP implementation Engine.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-engine.h"
|
||||
#include "sys/cc.h"
|
||||
#include "lib/list.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "coap-engine.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-engine"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
PROCESS(coap_engine, "CoAP Engine");
|
||||
static void process_callback(coap_timer_t *t);
|
||||
|
||||
/*
|
||||
* To be called by HTTP/COAP server as a callback function when a new service
|
||||
* request appears. This function dispatches the corresponding CoAP service.
|
||||
*/
|
||||
static int invoke_coap_resource_service(coap_message_t *request,
|
||||
coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t buffer_size,
|
||||
int32_t *offset);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Variables ---------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static service_callback_t service_cbk = NULL;
|
||||
LIST(coap_handlers);
|
||||
LIST(coap_resource_services);
|
||||
LIST(coap_resource_periodic_services);
|
||||
static uint8_t is_initialized = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*- CoAP service handlers---------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
coap_receive(void)
|
||||
void
|
||||
coap_add_handler(coap_handler_t *handler)
|
||||
{
|
||||
erbium_status_code = NO_ERROR;
|
||||
list_add(coap_handlers, handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_remove_handler(coap_handler_t *handler)
|
||||
{
|
||||
list_remove(coap_handlers, handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_handler_status_t
|
||||
coap_call_handlers(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t buffer_size, int32_t *offset)
|
||||
{
|
||||
coap_handler_status_t status;
|
||||
coap_handler_t *r;
|
||||
for(r = list_head(coap_handlers); r != NULL; r = r->next) {
|
||||
if(r->handler) {
|
||||
status = r->handler(request, response, buffer, buffer_size, offset);
|
||||
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
||||
/* Request handled. */
|
||||
|
||||
PRINTF("handle_incoming_data(): received uip_datalen=%u \n",
|
||||
(uint16_t)uip_datalen());
|
||||
|
||||
/* static declaration reduces stack peaks and program code size */
|
||||
static coap_packet_t message[1]; /* this way the packet can be treated as pointer as usual */
|
||||
static coap_packet_t response[1];
|
||||
static coap_transaction_t *transaction = NULL;
|
||||
|
||||
if(uip_newdata()) {
|
||||
|
||||
PRINTF("receiving UDP datagram from: ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINTF(":%u\n Length: %u\n", uip_ntohs(UIP_UDP_BUF->srcport),
|
||||
uip_datalen());
|
||||
|
||||
erbium_status_code =
|
||||
coap_parse_message(message, uip_appdata, uip_datalen());
|
||||
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
|
||||
/*TODO duplicates suppression, if required by application */
|
||||
|
||||
PRINTF(" Parsed: v %u, t %u, tkl %u, c %u, mid %u\n", message->version,
|
||||
message->type, message->token_len, message->code, message->mid);
|
||||
PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path);
|
||||
PRINTF(" Payload: %.*s\n", message->payload_len, message->payload);
|
||||
|
||||
/* handle requests */
|
||||
if(message->code >= COAP_GET && message->code <= COAP_DELETE) {
|
||||
|
||||
/* use transaction buffer for response to confirmable request */
|
||||
if((transaction =
|
||||
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport))) {
|
||||
uint32_t block_num = 0;
|
||||
uint16_t block_size = COAP_MAX_BLOCK_SIZE;
|
||||
uint32_t block_offset = 0;
|
||||
int32_t new_offset = 0;
|
||||
|
||||
/* prepare response */
|
||||
if(message->type == COAP_TYPE_CON) {
|
||||
/* reliable CON requests are answered with an ACK */
|
||||
coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
|
||||
message->mid);
|
||||
} else {
|
||||
/* unreliable NON requests are answered with a NON as well */
|
||||
coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
|
||||
coap_get_mid());
|
||||
/* mirror token */
|
||||
} if(message->token_len) {
|
||||
coap_set_token(response, message->token, message->token_len);
|
||||
/* get offset for blockwise transfers */
|
||||
}
|
||||
if(coap_get_header_block2
|
||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||
PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n",
|
||||
block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset);
|
||||
block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
|
||||
new_offset = block_offset;
|
||||
}
|
||||
|
||||
/* invoke resource handler */
|
||||
if(service_cbk) {
|
||||
|
||||
/* call REST framework and check if found and allowed */
|
||||
if(service_cbk
|
||||
(message, response, transaction->packet + COAP_MAX_HEADER_SIZE,
|
||||
block_size, &new_offset)) {
|
||||
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
|
||||
/* TODO coap_handle_blockwise(request, response, start_offset, end_offset); */
|
||||
|
||||
/* resource is unaware of Block1 */
|
||||
if(IS_OPTION(message, COAP_OPTION_BLOCK1)
|
||||
&& response->code < BAD_REQUEST_4_00
|
||||
&& !IS_OPTION(response, COAP_OPTION_BLOCK1)) {
|
||||
PRINTF("Block1 NOT IMPLEMENTED\n");
|
||||
|
||||
erbium_status_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoBlock1Support";
|
||||
|
||||
/* client requested Block2 transfer */
|
||||
} else if(IS_OPTION(message, COAP_OPTION_BLOCK2)) {
|
||||
|
||||
/* unchanged new_offset indicates that resource is unaware of blockwise transfer */
|
||||
if(new_offset == block_offset) {
|
||||
PRINTF
|
||||
("Blockwise: unaware resource with payload length %u/%u\n",
|
||||
response->payload_len, block_size);
|
||||
if(block_offset >= response->payload_len) {
|
||||
PRINTF
|
||||
("handle_incoming_data(): block_offset >= response->payload_len\n");
|
||||
|
||||
response->code = BAD_OPTION_4_02;
|
||||
coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */
|
||||
} else {
|
||||
coap_set_header_block2(response, block_num,
|
||||
response->payload_len -
|
||||
block_offset > block_size,
|
||||
block_size);
|
||||
coap_set_payload(response,
|
||||
response->payload + block_offset,
|
||||
MIN(response->payload_len -
|
||||
block_offset, block_size));
|
||||
} /* if(valid offset) */
|
||||
|
||||
/* resource provides chunk-wise data */
|
||||
} else {
|
||||
PRINTF("Blockwise: blockwise resource, new offset %ld\n",
|
||||
new_offset);
|
||||
coap_set_header_block2(response, block_num,
|
||||
new_offset != -1
|
||||
|| response->payload_len >
|
||||
block_size, block_size);
|
||||
|
||||
if(response->payload_len > block_size) {
|
||||
coap_set_payload(response, response->payload,
|
||||
block_size);
|
||||
}
|
||||
} /* if(resource aware of blockwise) */
|
||||
|
||||
/* Resource requested Block2 transfer */
|
||||
} else if(new_offset != 0) {
|
||||
PRINTF
|
||||
("Blockwise: no block option for blockwise resource, using block size %u\n",
|
||||
COAP_MAX_BLOCK_SIZE);
|
||||
|
||||
coap_set_header_block2(response, 0, new_offset != -1,
|
||||
COAP_MAX_BLOCK_SIZE);
|
||||
coap_set_payload(response, response->payload,
|
||||
MIN(response->payload_len,
|
||||
COAP_MAX_BLOCK_SIZE));
|
||||
} /* blockwise transfer handling */
|
||||
} /* no errors/hooks */
|
||||
/* successful service callback */
|
||||
/* serialize response */
|
||||
}
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
if((transaction->packet_len = coap_serialize_message(response,
|
||||
transaction->
|
||||
packet)) ==
|
||||
0) {
|
||||
erbium_status_code = PACKET_SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
erbium_status_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoServiceCallbck"; /* no 'a' to fit into 16 bytes */
|
||||
} /* if(service callback) */
|
||||
} else {
|
||||
erbium_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_error_message = "NoFreeTraBuffer";
|
||||
} /* if(transaction buffer) */
|
||||
|
||||
/* handle responses */
|
||||
} else {
|
||||
|
||||
if(message->type == COAP_TYPE_CON && message->code == 0) {
|
||||
PRINTF("Received Ping\n");
|
||||
erbium_status_code = PING_RESPONSE;
|
||||
} else if(message->type == COAP_TYPE_ACK) {
|
||||
/* transactions are closed through lookup below */
|
||||
PRINTF("Received ACK\n");
|
||||
} else if(message->type == COAP_TYPE_RST) {
|
||||
PRINTF("Received RST\n");
|
||||
/* cancel possible subscriptions */
|
||||
coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport, message->mid);
|
||||
/* Check response code before doing observe! */
|
||||
if(request->code == COAP_GET) {
|
||||
coap_observe_handler(NULL, request, response);
|
||||
}
|
||||
|
||||
if((transaction = coap_get_transaction_by_mid(message->mid))) {
|
||||
/* free transaction memory before callback, as it may create a new transaction */
|
||||
restful_response_handler callback = transaction->callback;
|
||||
void *callback_data = transaction->callback_data;
|
||||
|
||||
coap_clear_transaction(transaction);
|
||||
|
||||
/* check if someone registered for the response */
|
||||
if(callback) {
|
||||
callback(callback_data, message);
|
||||
}
|
||||
}
|
||||
/* if(ACKed transaction) */
|
||||
transaction = NULL;
|
||||
|
||||
#if COAP_OBSERVE_CLIENT
|
||||
/* if observe notification */
|
||||
if((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON)
|
||||
&& IS_OPTION(message, COAP_OPTION_OBSERVE)) {
|
||||
PRINTF("Observe [%u]\n", message->observe);
|
||||
coap_handle_notification(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
|
||||
message);
|
||||
}
|
||||
#endif /* COAP_OBSERVE_CLIENT */
|
||||
} /* request or response */
|
||||
} /* parsed correctly */
|
||||
|
||||
/* if(parsed correctly) */
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
if(transaction) {
|
||||
coap_send_transaction(transaction);
|
||||
return status;
|
||||
}
|
||||
} else if(erbium_status_code == MANUAL_RESPONSE) {
|
||||
PRINTF("Clearing transaction for manual response");
|
||||
coap_clear_transaction(transaction);
|
||||
} else {
|
||||
coap_message_type_t reply_type = COAP_TYPE_ACK;
|
||||
|
||||
PRINTF("ERROR %u: %s\n", erbium_status_code, coap_error_message);
|
||||
coap_clear_transaction(transaction);
|
||||
|
||||
if(erbium_status_code == PING_RESPONSE) {
|
||||
erbium_status_code = 0;
|
||||
reply_type = COAP_TYPE_RST;
|
||||
} else if(erbium_status_code >= 192) {
|
||||
/* set to sendable error code */
|
||||
erbium_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
/* reuse input buffer for error message */
|
||||
}
|
||||
coap_init_message(message, reply_type, erbium_status_code,
|
||||
message->mid);
|
||||
coap_set_payload(message, coap_error_message,
|
||||
strlen(coap_error_message));
|
||||
coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
|
||||
uip_appdata, coap_serialize_message(message,
|
||||
uip_appdata));
|
||||
}
|
||||
}
|
||||
return COAP_HANDLER_STATUS_CONTINUE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CC_INLINE coap_handler_status_t
|
||||
call_service(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t buffer_size, int32_t *offset)
|
||||
{
|
||||
coap_handler_status_t status;
|
||||
status = coap_call_handlers(request, response, buffer, buffer_size, offset);
|
||||
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
||||
return status;
|
||||
}
|
||||
status = invoke_coap_resource_service(request, response, buffer, buffer_size, offset);
|
||||
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* if(new data) */
|
||||
return erbium_status_code;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_init_engine(void)
|
||||
{
|
||||
process_start(&coap_engine, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_set_service_callback(service_callback_t callback)
|
||||
{
|
||||
service_cbk = callback;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rest_resource_flags_t
|
||||
coap_get_rest_method(void *packet)
|
||||
{
|
||||
return (rest_resource_flags_t)(1 <<
|
||||
(((coap_packet_t *)packet)->code - 1));
|
||||
coap_set_status_code(response, NOT_FOUND_4_04);
|
||||
|
||||
return COAP_HANDLER_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Server Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* the discover resource is automatically included for CoAP */
|
||||
extern resource_t res_well_known_core;
|
||||
#ifdef WITH_DTLS
|
||||
extern resource_t res_dtls;
|
||||
#endif
|
||||
extern coap_resource_t res_well_known_core;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(coap_engine, ev, data)
|
||||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_receive(const coap_endpoint_t *src,
|
||||
uint8_t *payload, uint16_t payload_length)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
PRINTF("Starting %s receiver...\n", coap_rest_implementation.name);
|
||||
/* static declaration reduces stack peaks and program code size */
|
||||
static coap_message_t message[1]; /* this way the message can be treated as pointer as usual */
|
||||
static coap_message_t response[1];
|
||||
coap_transaction_t *transaction = NULL;
|
||||
coap_handler_status_t status;
|
||||
|
||||
rest_activate_resource(&res_well_known_core, ".well-known/core");
|
||||
coap_status_code = coap_parse_message(message, payload, payload_length);
|
||||
coap_set_src_endpoint(message, src);
|
||||
|
||||
coap_register_as_transaction_handler();
|
||||
coap_init_connection(SERVER_LISTEN_PORT);
|
||||
if(coap_status_code == NO_ERROR) {
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD();
|
||||
/*TODO duplicates suppression, if required by application */
|
||||
|
||||
if(ev == tcpip_event) {
|
||||
coap_receive();
|
||||
} else if(ev == PROCESS_EVENT_TIMER) {
|
||||
/* retransmissions are handled here */
|
||||
coap_check_transactions();
|
||||
LOG_DBG(" Parsed: v %u, t %u, tkl %u, c %u, mid %u\n", message->version,
|
||||
message->type, message->token_len, message->code, message->mid);
|
||||
LOG_DBG(" URL:");
|
||||
LOG_DBG_COAP_STRING(message->uri_path, message->uri_path_len);
|
||||
LOG_DBG_("\n");
|
||||
LOG_DBG(" Payload: ");
|
||||
LOG_DBG_COAP_STRING((const char *)message->payload, message->payload_len);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
/* handle requests */
|
||||
if(message->code >= COAP_GET && message->code <= COAP_DELETE) {
|
||||
|
||||
/* use transaction buffer for response to confirmable request */
|
||||
if((transaction = coap_new_transaction(message->mid, src))) {
|
||||
uint32_t block_num = 0;
|
||||
uint16_t block_size = COAP_MAX_BLOCK_SIZE;
|
||||
uint32_t block_offset = 0;
|
||||
int32_t new_offset = 0;
|
||||
|
||||
/* prepare response */
|
||||
if(message->type == COAP_TYPE_CON) {
|
||||
/* reliable CON requests are answered with an ACK */
|
||||
coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
|
||||
message->mid);
|
||||
} else {
|
||||
/* unreliable NON requests are answered with a NON as well */
|
||||
coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
|
||||
coap_get_mid());
|
||||
/* mirror token */
|
||||
}
|
||||
if(message->token_len) {
|
||||
coap_set_token(response, message->token, message->token_len);
|
||||
/* get offset for blockwise transfers */
|
||||
}
|
||||
if(coap_get_header_block2
|
||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||
LOG_DBG("Blockwise: block request %"PRIu32" (%u/%u) @ %"PRIu32" bytes\n",
|
||||
block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset);
|
||||
block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
|
||||
new_offset = block_offset;
|
||||
}
|
||||
|
||||
/* call CoAP framework and check if found and allowed */
|
||||
status = call_service(message, response,
|
||||
transaction->message + COAP_MAX_HEADER_SIZE,
|
||||
block_size, &new_offset);
|
||||
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
||||
|
||||
if(coap_status_code == NO_ERROR) {
|
||||
|
||||
/* TODO coap_handle_blockwise(request, response, start_offset, end_offset); */
|
||||
|
||||
/* resource is unaware of Block1 */
|
||||
if(coap_is_option(message, COAP_OPTION_BLOCK1)
|
||||
&& response->code < BAD_REQUEST_4_00
|
||||
&& !coap_is_option(response, COAP_OPTION_BLOCK1)) {
|
||||
LOG_DBG("Block1 NOT IMPLEMENTED\n");
|
||||
|
||||
coap_status_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoBlock1Support";
|
||||
|
||||
/* client requested Block2 transfer */
|
||||
} else if(coap_is_option(message, COAP_OPTION_BLOCK2)) {
|
||||
|
||||
/* unchanged new_offset indicates that resource is unaware of blockwise transfer */
|
||||
if(new_offset == block_offset) {
|
||||
LOG_DBG("Blockwise: unaware resource with payload length %u/%u\n",
|
||||
response->payload_len, block_size);
|
||||
if(block_offset >= response->payload_len) {
|
||||
LOG_DBG("handle_incoming_data(): block_offset >= response->payload_len\n");
|
||||
|
||||
response->code = BAD_OPTION_4_02;
|
||||
coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */
|
||||
} else {
|
||||
coap_set_header_block2(response, block_num,
|
||||
response->payload_len -
|
||||
block_offset > block_size,
|
||||
block_size);
|
||||
coap_set_payload(response,
|
||||
response->payload + block_offset,
|
||||
MIN(response->payload_len -
|
||||
block_offset, block_size));
|
||||
} /* if(valid offset) */
|
||||
|
||||
/* resource provides chunk-wise data */
|
||||
} else {
|
||||
LOG_DBG("Blockwise: blockwise resource, new offset %"PRId32"\n",
|
||||
new_offset);
|
||||
coap_set_header_block2(response, block_num,
|
||||
new_offset != -1
|
||||
|| response->payload_len >
|
||||
block_size, block_size);
|
||||
|
||||
if(response->payload_len > block_size) {
|
||||
coap_set_payload(response, response->payload,
|
||||
block_size);
|
||||
}
|
||||
} /* if(resource aware of blockwise) */
|
||||
|
||||
/* Resource requested Block2 transfer */
|
||||
} else if(new_offset != 0) {
|
||||
LOG_DBG("Blockwise: no block option for blockwise resource, using block size %u\n",
|
||||
COAP_MAX_BLOCK_SIZE);
|
||||
|
||||
coap_set_header_block2(response, 0, new_offset != -1,
|
||||
COAP_MAX_BLOCK_SIZE);
|
||||
coap_set_payload(response, response->payload,
|
||||
MIN(response->payload_len,
|
||||
COAP_MAX_BLOCK_SIZE));
|
||||
} /* blockwise transfer handling */
|
||||
} /* no errors/hooks */
|
||||
/* successful service callback */
|
||||
/* serialize response */
|
||||
}
|
||||
if(coap_status_code == NO_ERROR) {
|
||||
if((transaction->message_len = coap_serialize_message(response,
|
||||
transaction->
|
||||
message)) ==
|
||||
0) {
|
||||
coap_status_code = PACKET_SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
coap_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_error_message = "NoFreeTraBuffer";
|
||||
} /* if(transaction buffer) */
|
||||
|
||||
/* handle responses */
|
||||
} else {
|
||||
|
||||
if(message->type == COAP_TYPE_CON && message->code == 0) {
|
||||
LOG_INFO("Received Ping\n");
|
||||
coap_status_code = PING_RESPONSE;
|
||||
} else if(message->type == COAP_TYPE_ACK) {
|
||||
/* transactions are closed through lookup below */
|
||||
LOG_DBG("Received ACK\n");
|
||||
} else if(message->type == COAP_TYPE_RST) {
|
||||
LOG_INFO("Received RST\n");
|
||||
/* cancel possible subscriptions */
|
||||
coap_remove_observer_by_mid(src, message->mid);
|
||||
}
|
||||
|
||||
if((transaction = coap_get_transaction_by_mid(message->mid))) {
|
||||
/* free transaction memory before callback, as it may create a new transaction */
|
||||
coap_resource_response_handler_t callback = transaction->callback;
|
||||
void *callback_data = transaction->callback_data;
|
||||
|
||||
coap_clear_transaction(transaction);
|
||||
|
||||
/* check if someone registered for the response */
|
||||
if(callback) {
|
||||
callback(callback_data, message);
|
||||
}
|
||||
}
|
||||
/* if(ACKed transaction) */
|
||||
transaction = NULL;
|
||||
|
||||
#if COAP_OBSERVE_CLIENT
|
||||
/* if observe notification */
|
||||
if((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON)
|
||||
&& coap_is_option(message, COAP_OPTION_OBSERVE)) {
|
||||
LOG_DBG("Observe [%"PRId32"]\n", message->observe);
|
||||
coap_handle_notification(src, message);
|
||||
}
|
||||
#endif /* COAP_OBSERVE_CLIENT */
|
||||
} /* request or response */
|
||||
} /* parsed correctly */
|
||||
|
||||
/* if(parsed correctly) */
|
||||
if(coap_status_code == NO_ERROR) {
|
||||
if(transaction) {
|
||||
coap_send_transaction(transaction);
|
||||
}
|
||||
} /* while (1) */
|
||||
} else if(coap_status_code == MANUAL_RESPONSE) {
|
||||
LOG_DBG("Clearing transaction for manual response");
|
||||
coap_clear_transaction(transaction);
|
||||
} else {
|
||||
coap_message_type_t reply_type = COAP_TYPE_ACK;
|
||||
|
||||
PROCESS_END();
|
||||
LOG_WARN("ERROR %u: %s\n", coap_status_code, coap_error_message);
|
||||
coap_clear_transaction(transaction);
|
||||
|
||||
if(coap_status_code == PING_RESPONSE) {
|
||||
coap_status_code = 0;
|
||||
reply_type = COAP_TYPE_RST;
|
||||
} else if(coap_status_code >= 192) {
|
||||
/* set to sendable error code */
|
||||
coap_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
/* reuse input buffer for error message */
|
||||
}
|
||||
coap_init_message(message, reply_type, coap_status_code,
|
||||
message->mid);
|
||||
coap_set_payload(message, coap_error_message,
|
||||
strlen(coap_error_message));
|
||||
coap_sendto(src, payload, coap_serialize_message(message, payload));
|
||||
}
|
||||
|
||||
/* if(new data) */
|
||||
return coap_status_code;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Client Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_blocking_request_callback(void *callback_data, void *response)
|
||||
coap_engine_init(void)
|
||||
{
|
||||
struct request_state_t *state = (struct request_state_t *)callback_data;
|
||||
|
||||
state->response = (coap_packet_t *)response;
|
||||
process_poll(state->process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(coap_blocking_request
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t *remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t *request,
|
||||
blocking_response_handler request_callback))
|
||||
{
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
static uint8_t more;
|
||||
static uint32_t res_block;
|
||||
static uint8_t block_error;
|
||||
|
||||
state->block_num = 0;
|
||||
state->response = NULL;
|
||||
state->process = PROCESS_CURRENT();
|
||||
|
||||
more = 0;
|
||||
res_block = 0;
|
||||
block_error = 0;
|
||||
|
||||
do {
|
||||
request->mid = coap_get_mid();
|
||||
if((state->transaction = coap_new_transaction(request->mid, remote_ipaddr,
|
||||
remote_port))) {
|
||||
state->transaction->callback = coap_blocking_request_callback;
|
||||
state->transaction->callback_data = state;
|
||||
|
||||
if(state->block_num > 0) {
|
||||
coap_set_header_block2(request, state->block_num, 0,
|
||||
REST_MAX_CHUNK_SIZE);
|
||||
}
|
||||
state->transaction->packet_len = coap_serialize_message(request,
|
||||
state->
|
||||
transaction->
|
||||
packet);
|
||||
|
||||
coap_send_transaction(state->transaction);
|
||||
PRINTF("Requested #%lu (MID %u)\n", state->block_num, request->mid);
|
||||
|
||||
PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL);
|
||||
|
||||
if(!state->response) {
|
||||
PRINTF("Server not responding\n");
|
||||
PT_EXIT(&state->pt);
|
||||
}
|
||||
|
||||
coap_get_header_block2(state->response, &res_block, &more, NULL, NULL);
|
||||
|
||||
PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "",
|
||||
state->response->payload_len);
|
||||
|
||||
if(res_block == state->block_num) {
|
||||
request_callback(state->response);
|
||||
++(state->block_num);
|
||||
} else {
|
||||
PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num);
|
||||
++block_error;
|
||||
}
|
||||
} else {
|
||||
PRINTF("Could not allocate transaction buffer");
|
||||
PT_EXIT(&state->pt);
|
||||
}
|
||||
} while(more && block_error < COAP_MAX_ATTEMPTS);
|
||||
|
||||
PT_END(&state->pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- REST Engine Interface ---------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct rest_implementation coap_rest_implementation = {
|
||||
"CoAP-18",
|
||||
|
||||
coap_init_engine,
|
||||
coap_set_service_callback,
|
||||
|
||||
coap_get_header_uri_path,
|
||||
coap_get_rest_method,
|
||||
coap_set_status_code,
|
||||
|
||||
coap_get_header_content_format,
|
||||
coap_set_header_content_format,
|
||||
coap_get_header_accept,
|
||||
coap_get_header_size2,
|
||||
coap_set_header_size2,
|
||||
coap_get_header_max_age,
|
||||
coap_set_header_max_age,
|
||||
coap_set_header_etag,
|
||||
coap_get_header_if_match,
|
||||
coap_get_header_if_none_match,
|
||||
coap_get_header_uri_host,
|
||||
coap_set_header_location_path,
|
||||
|
||||
coap_get_payload,
|
||||
coap_set_payload,
|
||||
|
||||
coap_get_header_uri_query,
|
||||
coap_get_query_variable,
|
||||
coap_get_post_variable,
|
||||
|
||||
coap_notify_observers,
|
||||
coap_observe_handler,
|
||||
|
||||
{
|
||||
CONTENT_2_05,
|
||||
CREATED_2_01,
|
||||
CHANGED_2_04,
|
||||
DELETED_2_02,
|
||||
VALID_2_03,
|
||||
BAD_REQUEST_4_00,
|
||||
UNAUTHORIZED_4_01,
|
||||
BAD_OPTION_4_02,
|
||||
FORBIDDEN_4_03,
|
||||
NOT_FOUND_4_04,
|
||||
METHOD_NOT_ALLOWED_4_05,
|
||||
NOT_ACCEPTABLE_4_06,
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13,
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15,
|
||||
INTERNAL_SERVER_ERROR_5_00,
|
||||
NOT_IMPLEMENTED_5_01,
|
||||
BAD_GATEWAY_5_02,
|
||||
SERVICE_UNAVAILABLE_5_03,
|
||||
GATEWAY_TIMEOUT_5_04,
|
||||
PROXYING_NOT_SUPPORTED_5_05
|
||||
},
|
||||
|
||||
{
|
||||
TEXT_PLAIN,
|
||||
TEXT_XML,
|
||||
TEXT_CSV,
|
||||
TEXT_HTML,
|
||||
IMAGE_GIF,
|
||||
IMAGE_JPEG,
|
||||
IMAGE_PNG,
|
||||
IMAGE_TIFF,
|
||||
AUDIO_RAW,
|
||||
VIDEO_RAW,
|
||||
APPLICATION_LINK_FORMAT,
|
||||
APPLICATION_XML,
|
||||
APPLICATION_OCTET_STREAM,
|
||||
APPLICATION_RDF_XML,
|
||||
APPLICATION_SOAP_XML,
|
||||
APPLICATION_ATOM_XML,
|
||||
APPLICATION_XMPP_XML,
|
||||
APPLICATION_EXI,
|
||||
APPLICATION_FASTINFOSET,
|
||||
APPLICATION_SOAP_FASTINFOSET,
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_X_OBIX_BINARY
|
||||
/* avoid initializing twice */
|
||||
if(is_initialized) {
|
||||
LOG_DBG("already running - double initialization?\n");
|
||||
return;
|
||||
}
|
||||
};
|
||||
is_initialized = 1;
|
||||
|
||||
LOG_INFO("Starting CoAP engine...\n");
|
||||
|
||||
list_init(coap_handlers);
|
||||
list_init(coap_resource_services);
|
||||
list_init(coap_resource_periodic_services);
|
||||
|
||||
coap_activate_resource(&res_well_known_core, ".well-known/core");
|
||||
|
||||
coap_transport_init();
|
||||
coap_init_connection();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Makes a resource available under the given URI path
|
||||
* \param resource A pointer to a resource implementation
|
||||
* \param path The URI path string for this resource
|
||||
*
|
||||
* The resource implementation must be imported first using the
|
||||
* extern keyword. The build system takes care of compiling every
|
||||
* *.c file in the ./resources/ sub-directory (see example Makefile).
|
||||
*/
|
||||
void
|
||||
coap_activate_resource(coap_resource_t *resource, const char *path)
|
||||
{
|
||||
coap_periodic_resource_t *periodic;
|
||||
resource->url = path;
|
||||
list_add(coap_resource_services, resource);
|
||||
|
||||
LOG_INFO("Activating: %s\n", resource->url);
|
||||
|
||||
/* Only add periodic resources with a periodic_handler and a period > 0. */
|
||||
if(resource->flags & IS_PERIODIC && resource->periodic
|
||||
&& resource->periodic->periodic_handler
|
||||
&& resource->periodic->period) {
|
||||
LOG_DBG("Periodic resource: %p (%s)\n", resource->periodic, path);
|
||||
list_add(coap_resource_periodic_services, resource->periodic);
|
||||
periodic = resource->periodic;
|
||||
coap_timer_set_callback(&periodic->periodic_timer, process_callback);
|
||||
coap_timer_set_user_data(&periodic->periodic_timer, resource);
|
||||
coap_timer_set(&periodic->periodic_timer, periodic->period);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_resource_t *
|
||||
coap_get_first_resource(void)
|
||||
{
|
||||
return list_head(coap_resource_services);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_resource_t *
|
||||
coap_get_next_resource(coap_resource_t *resource)
|
||||
{
|
||||
return list_item_next(resource);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
invoke_coap_resource_service(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t buffer_size,
|
||||
int32_t *offset)
|
||||
{
|
||||
uint8_t found = 0;
|
||||
uint8_t allowed = 1;
|
||||
|
||||
coap_resource_t *resource = NULL;
|
||||
const char *url = NULL;
|
||||
int url_len, res_url_len;
|
||||
|
||||
url_len = coap_get_header_uri_path(request, &url);
|
||||
for(resource = list_head(coap_resource_services);
|
||||
resource; resource = resource->next) {
|
||||
|
||||
/* if the web service handles that kind of requests and urls matches */
|
||||
res_url_len = strlen(resource->url);
|
||||
if((url_len == res_url_len
|
||||
|| (url_len > res_url_len
|
||||
&& (resource->flags & HAS_SUB_RESOURCES)
|
||||
&& url[res_url_len] == '/'))
|
||||
&& strncmp(resource->url, url, res_url_len) == 0) {
|
||||
coap_resource_flags_t method = coap_get_method_type(request);
|
||||
found = 1;
|
||||
|
||||
LOG_INFO("/%s, method %u, resource->flags %u\n", resource->url,
|
||||
(uint16_t)method, resource->flags);
|
||||
|
||||
if((method & METHOD_GET) && resource->get_handler != NULL) {
|
||||
/* call handler function */
|
||||
resource->get_handler(request, response, buffer, buffer_size, offset);
|
||||
} else if((method & METHOD_POST) && resource->post_handler != NULL) {
|
||||
/* call handler function */
|
||||
resource->post_handler(request, response, buffer, buffer_size,
|
||||
offset);
|
||||
} else if((method & METHOD_PUT) && resource->put_handler != NULL) {
|
||||
/* call handler function */
|
||||
resource->put_handler(request, response, buffer, buffer_size, offset);
|
||||
} else if((method & METHOD_DELETE) && resource->delete_handler != NULL) {
|
||||
/* call handler function */
|
||||
resource->delete_handler(request, response, buffer, buffer_size,
|
||||
offset);
|
||||
} else {
|
||||
allowed = 0;
|
||||
coap_set_status_code(response, METHOD_NOT_ALLOWED_4_05);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
coap_set_status_code(response, NOT_FOUND_4_04);
|
||||
} else if(allowed) {
|
||||
/* final handler for special flags */
|
||||
if(resource->flags & IS_OBSERVABLE) {
|
||||
coap_observe_handler(resource, request, response);
|
||||
}
|
||||
}
|
||||
return found & allowed;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* This callback occurs when t is expired */
|
||||
static void
|
||||
process_callback(coap_timer_t *t)
|
||||
{
|
||||
coap_resource_t *resource;
|
||||
resource = coap_timer_get_user_data(t);
|
||||
if(resource != NULL && (resource->flags & IS_PERIODIC)
|
||||
&& resource->periodic != NULL && resource->periodic->period) {
|
||||
LOG_DBG("Periodic: timer expired for /%s (period: %"PRIu32")\n",
|
||||
resource->url, resource->periodic->period);
|
||||
|
||||
if(!is_initialized) {
|
||||
/* CoAP has not yet been initialized. */
|
||||
} else if(resource->periodic->periodic_handler) {
|
||||
/* Call the periodic_handler function. */
|
||||
resource->periodic->periodic_handler();
|
||||
}
|
||||
|
||||
coap_timer_set(t, resource->periodic->period);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -31,56 +31,148 @@
|
|||
|
||||
/**
|
||||
* \file
|
||||
* CoAP implementation for the REST Engine.
|
||||
* CoAP engine implementation.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_ENGINE_H_
|
||||
#define ER_COAP_ENGINE_H_
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_ENGINE_H_
|
||||
#define COAP_ENGINE_H_
|
||||
|
||||
typedef struct coap_resource_s coap_resource_t;
|
||||
typedef struct coap_periodic_resource_s coap_periodic_resource_t;
|
||||
|
||||
#include "pt.h"
|
||||
#include "coap.h"
|
||||
#include "coap-timer.h"
|
||||
|
||||
typedef enum {
|
||||
COAP_HANDLER_STATUS_CONTINUE,
|
||||
COAP_HANDLER_STATUS_PROCESSED
|
||||
} coap_handler_status_t;
|
||||
|
||||
typedef coap_handler_status_t
|
||||
(* coap_handler_callback_t)(coap_message_t *request,
|
||||
coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t buffer_size,
|
||||
int32_t *offset);
|
||||
|
||||
typedef struct coap_handler coap_handler_t;
|
||||
|
||||
struct coap_handler {
|
||||
coap_handler_t *next;
|
||||
coap_handler_callback_t handler;
|
||||
};
|
||||
|
||||
#define COAP_HANDLER(name, handler) \
|
||||
coap_handler_t name = { NULL, handler }
|
||||
|
||||
void coap_add_handler(coap_handler_t *handler);
|
||||
void coap_remove_handler(coap_handler_t *handler);
|
||||
|
||||
void coap_engine_init(void);
|
||||
|
||||
int coap_receive(const coap_endpoint_t *src,
|
||||
uint8_t *payload, uint16_t payload_length);
|
||||
|
||||
coap_handler_status_t coap_call_handlers(coap_message_t *request,
|
||||
coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t buffer_size,
|
||||
int32_t *offset);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* signatures of handler functions */
|
||||
typedef void (* coap_resource_handler_t)(coap_message_t *request,
|
||||
coap_message_t *response,
|
||||
uint8_t *buffer,
|
||||
uint16_t preferred_size,
|
||||
int32_t *offset);
|
||||
typedef void (* coap_resource_periodic_handler_t)(void);
|
||||
typedef void (* coap_resource_response_handler_t)(void *data,
|
||||
coap_message_t *response);
|
||||
typedef void (* coap_resource_trigger_handler_t)(void);
|
||||
|
||||
/* data structure representing a resource in CoAP */
|
||||
struct coap_resource_s {
|
||||
coap_resource_t *next; /* for LIST, points to next resource defined */
|
||||
const char *url; /*handled URL */
|
||||
coap_resource_flags_t flags; /* handled CoAP methods */
|
||||
const char *attributes; /* link-format attributes */
|
||||
coap_resource_handler_t get_handler; /* handler function */
|
||||
coap_resource_handler_t post_handler; /* handler function */
|
||||
coap_resource_handler_t put_handler; /* handler function */
|
||||
coap_resource_handler_t delete_handler; /* handler function */
|
||||
union {
|
||||
coap_periodic_resource_t *periodic; /* special data depending on flags */
|
||||
coap_resource_trigger_handler_t trigger;
|
||||
coap_resource_trigger_handler_t resume;
|
||||
};
|
||||
};
|
||||
|
||||
struct coap_periodic_resource_s {
|
||||
uint32_t period;
|
||||
coap_timer_t periodic_timer;
|
||||
const coap_resource_periodic_handler_t periodic_handler;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macro to define a CoAP resource.
|
||||
* Resources are statically defined for the sake of efficiency and better memory management.
|
||||
*/
|
||||
#define RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \
|
||||
coap_resource_t name = { NULL, NULL, NO_FLAGS, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } }
|
||||
|
||||
#define PARENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \
|
||||
coap_resource_t name = { NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } }
|
||||
|
||||
#define SEPARATE_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, resume_handler) \
|
||||
coap_resource_t name = { NULL, NULL, IS_SEPARATE, attributes, get_handler, post_handler, put_handler, delete_handler, { .resume = resume_handler } }
|
||||
|
||||
#define EVENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, event_handler) \
|
||||
coap_resource_t name = { NULL, NULL, IS_OBSERVABLE, attributes, get_handler, post_handler, put_handler, delete_handler, { .trigger = event_handler } }
|
||||
|
||||
/*
|
||||
* Macro to define a periodic resource.
|
||||
* The corresponding [name]_periodic_handler() function will be called every period.
|
||||
* For instance polling a sensor and publishing a changed value to subscribed clients would be done there.
|
||||
*/
|
||||
#define PERIODIC_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, period, periodic_handler) \
|
||||
static coap_periodic_resource_t periodic_##name = { period, { 0 }, periodic_handler }; \
|
||||
coap_resource_t name = { NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes, get_handler, post_handler, put_handler, delete_handler, { .periodic = &periodic_##name } }
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* \brief Resources wanted to be accessible should be activated with the following code.
|
||||
* \param resource
|
||||
* A CoAP resource defined through the RESOURCE macros.
|
||||
* \param path
|
||||
* The local URI path where to provide the resource.
|
||||
*/
|
||||
void coap_activate_resource(coap_resource_t *resource, const char *path);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Returns the first of registered CoAP resources.
|
||||
* \return The first registered CoAP resource or NULL if none exists.
|
||||
*/
|
||||
coap_resource_t *coap_get_first_resource(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Returns the next registered CoAP resource.
|
||||
* \return The next resource or NULL if no more exists.
|
||||
*/
|
||||
coap_resource_t *coap_get_next_resource(coap_resource_t *resource);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "coap-transactions.h"
|
||||
#include "coap-observe.h"
|
||||
#include "coap-separate.h"
|
||||
#include "coap-observe-client.h"
|
||||
#include "coap-transport.h"
|
||||
|
||||
#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT)
|
||||
|
||||
typedef coap_packet_t rest_request_t;
|
||||
typedef coap_packet_t rest_response_t;
|
||||
|
||||
void coap_init_engine(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Client Part -------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct request_state_t {
|
||||
struct pt pt;
|
||||
struct process *process;
|
||||
coap_transaction_t *transaction;
|
||||
coap_packet_t *response;
|
||||
uint32_t block_num;
|
||||
};
|
||||
|
||||
typedef void (*blocking_response_handler)(void *response);
|
||||
|
||||
PT_THREAD(coap_blocking_request
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t *remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t *request,
|
||||
blocking_response_handler request_callback));
|
||||
|
||||
#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \
|
||||
{ \
|
||||
static struct request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_addr, server_port, \
|
||||
request, chunk_handler) \
|
||||
); \
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* ER_COAP_ENGINE_H_ */
|
||||
#endif /* COAP_ENGINE_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Yanzi Networks AB.
|
||||
* Copyright (c) 2017, RISE SICS AB.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -29,61 +29,69 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup oma-lwm2m
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* A simple keystore with fixed credentials.
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implementation of the Contiki OMA LWM2M TLV writer
|
||||
* \author
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* \addtogroup coap-keystore
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "lwm2m-object.h"
|
||||
#include "oma-tlv.h"
|
||||
#include "coap-endpoint.h"
|
||||
#include "coap-keystore.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WITH_DTLS
|
||||
#ifdef COAP_DTLS_PSK_DEFAULT_IDENTITY
|
||||
#ifdef COAP_DTLS_PSK_DEFAULT_KEY
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
write_boolean_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
|
||||
int value)
|
||||
static int
|
||||
get_default_psk_info(const coap_endpoint_t *address_info,
|
||||
coap_keystore_psk_entry_t *info)
|
||||
{
|
||||
return oma_tlv_write_int32(ctx->resource_id, value != 0 ? 1 : 0,
|
||||
outbuf, outlen);
|
||||
if(info != NULL) {
|
||||
if(info->identity == NULL || info->identity_len == 0) {
|
||||
/* Identity requested */
|
||||
info->identity = (uint8_t *)COAP_DTLS_PSK_DEFAULT_IDENTITY;
|
||||
info->identity_len = strlen(COAP_DTLS_PSK_DEFAULT_IDENTITY);
|
||||
return 1;
|
||||
}
|
||||
if(info->identity_len != strlen(COAP_DTLS_PSK_DEFAULT_IDENTITY) ||
|
||||
memcmp(info->identity, COAP_DTLS_PSK_DEFAULT_IDENTITY,
|
||||
info->identity_len) != 0) {
|
||||
/* Identity not matching */
|
||||
return 0;
|
||||
}
|
||||
info->key = (uint8_t *)COAP_DTLS_PSK_DEFAULT_KEY;
|
||||
info->key_len = strlen(COAP_DTLS_PSK_DEFAULT_KEY);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
write_int_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
|
||||
int32_t value)
|
||||
{
|
||||
return oma_tlv_write_int32(ctx->resource_id, value, outbuf, outlen);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
write_float32fix_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf,
|
||||
size_t outlen, int32_t value, int bits)
|
||||
{
|
||||
return oma_tlv_write_float32(ctx->resource_id, value, bits, outbuf, outlen);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
write_string_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
|
||||
const char *value, size_t stringlen)
|
||||
{
|
||||
oma_tlv_t tlv;
|
||||
tlv.type = OMA_TLV_TYPE_RESOURCE;
|
||||
tlv.value = (uint8_t *) value;
|
||||
tlv.length = (uint32_t) stringlen;
|
||||
tlv.id = ctx->resource_id;
|
||||
return oma_tlv_write(&tlv, outbuf, outlen);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const lwm2m_writer_t oma_tlv_writer = {
|
||||
write_int_tlv,
|
||||
write_string_tlv,
|
||||
write_float32fix_tlv,
|
||||
write_boolean_tlv
|
||||
static const coap_keystore_t simple_key_store = {
|
||||
.coap_get_psk_info = get_default_psk_info
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* COAP_DTLS_PSK_DEFAULT_KEY */
|
||||
#endif /* COAP_DTLS_PSK_DEFAULT_IDENTITY */
|
||||
#endif /* WITH_DTLS */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_keystore_simple_init(void)
|
||||
{
|
||||
#ifdef WITH_DTLS
|
||||
#ifdef COAP_DTLS_PSK_DEFAULT_IDENTITY
|
||||
#ifdef COAP_DTLS_PSK_DEFAULT_KEY
|
||||
|
||||
coap_set_keystore(&simple_key_store);
|
||||
|
||||
#endif /* COAP_DTLS_PSK_DEFAULT_KEY */
|
||||
#endif /* COAP_DTLS_PSK_DEFAULT_IDENTITY */
|
||||
#endif /* WITH_DTLS */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2017, RISE SICS AB.
|
||||
* 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A simple keystore with fixed credentials.
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap-keystore
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_KEYSTORE_SIMPLE_H_
|
||||
#define COAP_KEYSTORE_SIMPLE_H_
|
||||
|
||||
/**
|
||||
* \brief Registers a simple CoAP DTLS keystore with fixed pre-shared key
|
||||
* credentials.
|
||||
*
|
||||
* The credentials can be configured in project-conf.h as shown in the
|
||||
* following example:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~{.c}
|
||||
* #define COAP_DTLS_PSK_DEFAULT_IDENTITY "user"
|
||||
* #define COAP_DTLS_PSK_DEFAULT_KEY "password"
|
||||
* ~~~~~~~~~~~~~~~
|
||||
*/
|
||||
void coap_keystore_simple_init(void);
|
||||
|
||||
#endif /* COAP_KEYSTORE_SIMPLE_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2017, RISE SICS
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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
|
||||
* API for CoAP keystore
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*
|
||||
* \defgroup coap-keystore CoAP keystore API
|
||||
* @{
|
||||
*
|
||||
* The CoAP keystore API defines a common interface for retrieving
|
||||
* authorization information for CoAP/DTLS.
|
||||
*/
|
||||
|
||||
#ifndef COAP_KEYSTORE_H_
|
||||
#define COAP_KEYSTORE_H_
|
||||
|
||||
#include "coap-endpoint.h"
|
||||
|
||||
/**
|
||||
* The structure of a CoAP pre-shared key info.
|
||||
*/
|
||||
typedef struct {
|
||||
const uint8_t *identity_hint;
|
||||
uint16_t identity_hint_len;
|
||||
const uint8_t *identity;
|
||||
uint16_t identity_len;
|
||||
const uint8_t *key;
|
||||
uint16_t key_len;
|
||||
} coap_keystore_psk_entry_t;
|
||||
|
||||
/**
|
||||
* The structure of a CoAP keystore.
|
||||
*
|
||||
* The keystore implementation provides a function callback for each type of
|
||||
* authorization supported. The API currently only specifies a function
|
||||
* callback for pre-shared keys.
|
||||
*/
|
||||
typedef struct {
|
||||
int (* coap_get_psk_info)(const coap_endpoint_t *address_info,
|
||||
coap_keystore_psk_entry_t *info);
|
||||
} coap_keystore_t;
|
||||
|
||||
/**
|
||||
* \brief Set the CoAP keystore to use by CoAP.
|
||||
* \param keystore A pointer to a CoAP keystore.
|
||||
*/
|
||||
void coap_set_keystore(const coap_keystore_t *keystore);
|
||||
|
||||
#endif /* COAP_KEYSTORE_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2017, RISE SICS.
|
||||
* 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Log support for CoAP
|
||||
* \author
|
||||
* Niclas Finne <niclas.finne@ri.se>
|
||||
* Joakim Eriksson <joakim.eriksson@ri.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-log.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_log_string(const char *text, size_t len)
|
||||
{
|
||||
int i;
|
||||
if(text == NULL) {
|
||||
LOG_OUTPUT("(NULL STR)");
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < len && *text != '\0'; i++, text++) {
|
||||
LOG_OUTPUT("%c", *text);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2017, RISE SICS.
|
||||
* 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Log support for CoAP
|
||||
* \author
|
||||
* Niclas Finne <niclas.finne@ri.se>
|
||||
* Joakim Eriksson <joakim.eriksson@ri.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_LOG_H_
|
||||
#define COAP_LOG_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#ifdef COAP_LOG_CONF_PATH
|
||||
#include COAP_LOG_CONF_PATH
|
||||
#else /* COAP_LOG_CONF_PATH */
|
||||
#include "sys/log.h"
|
||||
#endif /* COAP_LOG_CONF_PATH */
|
||||
|
||||
#include "coap-endpoint.h"
|
||||
|
||||
/* CoAP endpoint */
|
||||
#define LOG_COAP_EP(level, endpoint) do { \
|
||||
if(level <= (LOG_LEVEL)) { \
|
||||
coap_endpoint_log(endpoint); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_ERR_COAP_EP(endpoint) LOG_COAP_EP(LOG_LEVEL_ERR, endpoint)
|
||||
#define LOG_WARN_COAP_EP(endpoint) LOG_COAP_EP(LOG_LEVEL_WARN, endpoint)
|
||||
#define LOG_INFO_COAP_EP(endpoint) LOG_COAP_EP(LOG_LEVEL_INFO, endpoint)
|
||||
#define LOG_DBG_COAP_EP(endpoint) LOG_COAP_EP(LOG_LEVEL_DBG, endpoint)
|
||||
|
||||
/* CoAP strings */
|
||||
#define LOG_COAP_STRING(level, text, len) do { \
|
||||
if(level <= (LOG_LEVEL)) { \
|
||||
coap_log_string(text, len); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_ERR_COAP_STRING(text, len) LOG_COAP_STRING(LOG_LEVEL_ERR, text, len)
|
||||
#define LOG_WARN_COAP_STRING(text, len) LOG_COAP_STRING(LOG_LEVEL_WARN, text, len)
|
||||
#define LOG_INFO_COAP_STRING(text, len) LOG_COAP_STRING(LOG_LEVEL_INFO, text, len)
|
||||
#define LOG_DBG_COAP_STRING(text, len) LOG_COAP_STRING(LOG_LEVEL_DBG, text, len)
|
||||
|
||||
/**
|
||||
* \brief Logs a CoAP string that has a length but might not be 0-terminated.
|
||||
* \param text The CoAP string
|
||||
* \param len The number of characters in the CoAP string
|
||||
*/
|
||||
void coap_log_string(const char *text, size_t len);
|
||||
|
||||
#endif /* COAP_LOG_H_ */
|
||||
/** @} */
|
|
@ -37,57 +37,42 @@
|
|||
* Daniele Alessandrelli <daniele.alessandrelli@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-observe-client.h"
|
||||
#include "sys/cc.h"
|
||||
#include "lib/memb.h"
|
||||
#include "lib/list.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Compile this code only if client-side support for CoAP Observe is required */
|
||||
#if COAP_OBSERVE_CLIENT
|
||||
|
||||
#define DEBUG 1
|
||||
#if DEBUG
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" \
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x]", \
|
||||
((uint8_t *)addr)[0], ((uint8_t *)addr)[1], \
|
||||
((uint8_t *)addr)[2], ((uint8_t *)addr)[3], \
|
||||
((uint8_t *)addr)[4], ((uint8_t *)addr)[5], \
|
||||
((uint8_t *)addr)[6], ((uint8_t *)addr)[7], \
|
||||
((uint8_t *)addr)[8], ((uint8_t *)addr)[9], \
|
||||
((uint8_t *)addr)[10], ((uint8_t *)addr)[11], \
|
||||
((uint8_t *)addr)[12], ((uint8_t *)addr)[13], \
|
||||
((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", \
|
||||
(lladdr)->addr[0], (lladdr)->addr[1], \
|
||||
(lladdr)->addr[2], (lladdr)->addr[3], \
|
||||
(lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-observe-client"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES);
|
||||
LIST(obs_subjects_list);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
get_token(void *packet, const uint8_t **token)
|
||||
get_token(coap_message_t *coap_pkt, const uint8_t **token)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
*token = coap_pkt->token;
|
||||
|
||||
return coap_pkt->token_len;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int
|
||||
set_token(void *packet, const uint8_t *token, size_t token_len)
|
||||
set_token(coap_message_t *coap_pkt, const uint8_t *token, size_t token_len)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
|
||||
memcpy(coap_pkt->token, token, coap_pkt->token_len);
|
||||
|
||||
|
@ -95,7 +80,7 @@ set_token(void *packet, const uint8_t *token, size_t token_len)
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
coap_observee_t *
|
||||
coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_obs_add_observee(const coap_endpoint_t *endpoint,
|
||||
const uint8_t *token, size_t token_len, const char *url,
|
||||
notification_callback_t notification_callback,
|
||||
void *data)
|
||||
|
@ -103,20 +88,18 @@ coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
|||
coap_observee_t *o;
|
||||
|
||||
/* Remove existing observe relationship, if any. */
|
||||
coap_obs_remove_observee_by_url(addr, port, url);
|
||||
coap_obs_remove_observee_by_url(endpoint, url);
|
||||
o = memb_alloc(&obs_subjects_memb);
|
||||
if(o) {
|
||||
o->url = url;
|
||||
uip_ipaddr_copy(&o->addr, addr);
|
||||
o->port = port;
|
||||
coap_endpoint_copy(&o->endpoint, endpoint);
|
||||
o->token_len = token_len;
|
||||
memcpy(o->token, token, token_len);
|
||||
/* o->last_mid = 0; */
|
||||
o->notification_callback = notification_callback;
|
||||
o->data = data;
|
||||
/* stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); */
|
||||
PRINTF("Adding obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
LOG_DBG("Adding obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
list_add(obs_subjects_list, o);
|
||||
}
|
||||
|
||||
|
@ -126,8 +109,8 @@ coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
|||
void
|
||||
coap_obs_remove_observee(coap_observee_t *o)
|
||||
{
|
||||
PRINTF("Removing obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
LOG_DBG("Removing obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
memb_free(&obs_subjects_memb, o);
|
||||
list_remove(obs_subjects_list, o);
|
||||
}
|
||||
|
@ -139,7 +122,7 @@ coap_get_obs_subject_by_token(const uint8_t *token, size_t token_len)
|
|||
|
||||
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Looking for token 0x%02X%02X\n", token[0], token[1]);
|
||||
LOG_DBG("Looking for token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(obs->token_len == token_len
|
||||
&& memcmp(obs->token, token, token_len) == 0) {
|
||||
return obs;
|
||||
|
@ -150,7 +133,7 @@ coap_get_obs_subject_by_token(const uint8_t *token, size_t token_len)
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_obs_remove_observee_by_token(const coap_endpoint_t *endpoint,
|
||||
uint8_t *token, size_t token_len)
|
||||
{
|
||||
int removed = 0;
|
||||
|
@ -158,9 +141,8 @@ coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
|||
|
||||
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr)
|
||||
&& obs->port == port
|
||||
LOG_DBG("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(coap_endpoint_cmp(&obs->endpoint, endpoint)
|
||||
&& obs->token_len == token_len
|
||||
&& memcmp(obs->token, token, token_len) == 0) {
|
||||
coap_obs_remove_observee(obs);
|
||||
|
@ -171,7 +153,7 @@ coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_obs_remove_observee_by_url(const coap_endpoint_t *endpoint,
|
||||
const char *url)
|
||||
{
|
||||
int removed = 0;
|
||||
|
@ -179,9 +161,8 @@ coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
|||
|
||||
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check URL %s\n", url);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr)
|
||||
&& obs->port == port
|
||||
LOG_DBG("Remove check URL %s\n", url);
|
||||
if(coap_endpoint_cmp(&obs->endpoint, endpoint)
|
||||
&& (obs->url == url || memcmp(obs->url, url, strlen(obs->url)) == 0)) {
|
||||
coap_obs_remove_observee(obs);
|
||||
removed++;
|
||||
|
@ -191,34 +172,31 @@ coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
simple_reply(coap_message_type_t type, uip_ip6addr_t *addr, uint16_t port,
|
||||
coap_packet_t *notification)
|
||||
simple_reply(coap_message_type_t type, const coap_endpoint_t *endpoint,
|
||||
coap_message_t *notification)
|
||||
{
|
||||
static coap_packet_t response[1];
|
||||
static coap_message_t response[1];
|
||||
size_t len;
|
||||
|
||||
coap_init_message(response, type, NO_ERROR, notification->mid);
|
||||
len = coap_serialize_message(response, uip_appdata);
|
||||
coap_send_message(addr, port, uip_appdata, len);
|
||||
len = coap_serialize_message(response, coap_databuf());
|
||||
coap_sendto(endpoint, coap_databuf(), len);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static coap_notification_flag_t
|
||||
classify_notification(void *response, int first)
|
||||
classify_notification(coap_message_t *response, int first)
|
||||
{
|
||||
coap_packet_t *pkt;
|
||||
|
||||
pkt = (coap_packet_t *)response;
|
||||
if(!pkt) {
|
||||
PRINTF("no response\n");
|
||||
if(!response) {
|
||||
LOG_DBG("no response\n");
|
||||
return NO_REPLY_FROM_SERVER;
|
||||
}
|
||||
PRINTF("server replied\n");
|
||||
if(!IS_RESPONSE_CODE_2_XX(pkt)) {
|
||||
PRINTF("error response code\n");
|
||||
LOG_DBG("server replied\n");
|
||||
if(!IS_RESPONSE_CODE_2_XX(response)) {
|
||||
LOG_DBG("error response code\n");
|
||||
return ERROR_RESPONSE_CODE;
|
||||
}
|
||||
if(!IS_OPTION(pkt, COAP_OPTION_OBSERVE)) {
|
||||
PRINTF("server does not support observe\n");
|
||||
if(!coap_is_option(response, COAP_OPTION_OBSERVE)) {
|
||||
LOG_DBG("server does not support observe\n");
|
||||
return OBSERVE_NOT_SUPPORTED;
|
||||
}
|
||||
if(first) {
|
||||
|
@ -228,35 +206,33 @@ classify_notification(void *response, int first)
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_handle_notification(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_packet_t *notification)
|
||||
coap_handle_notification(const coap_endpoint_t *endpoint,
|
||||
coap_message_t *notification)
|
||||
{
|
||||
coap_packet_t *pkt;
|
||||
const uint8_t *token;
|
||||
int token_len;
|
||||
coap_observee_t *obs;
|
||||
coap_notification_flag_t flag;
|
||||
uint32_t observe;
|
||||
|
||||
PRINTF("coap_handle_notification()\n");
|
||||
pkt = (coap_packet_t *)notification;
|
||||
token_len = get_token(pkt, &token);
|
||||
PRINTF("Getting token\n");
|
||||
LOG_DBG("coap_handle_notification()\n");
|
||||
token_len = get_token(notification, &token);
|
||||
LOG_DBG("Getting token\n");
|
||||
if(0 == token_len) {
|
||||
PRINTF("Error while handling coap observe notification: "
|
||||
"no token in message\n");
|
||||
LOG_DBG("Error while handling coap observe notification: "
|
||||
"no token in message\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("Getting observee info\n");
|
||||
LOG_DBG("Getting observee info\n");
|
||||
obs = coap_get_obs_subject_by_token(token, token_len);
|
||||
if(NULL == obs) {
|
||||
PRINTF("Error while handling coap observe notification: "
|
||||
"no matching token found\n");
|
||||
simple_reply(COAP_TYPE_RST, addr, port, notification);
|
||||
LOG_DBG("Error while handling coap observe notification: "
|
||||
"no matching token found\n");
|
||||
simple_reply(COAP_TYPE_RST, endpoint, notification);
|
||||
return;
|
||||
}
|
||||
if(notification->type == COAP_TYPE_CON) {
|
||||
simple_reply(COAP_TYPE_ACK, addr, port, notification);
|
||||
simple_reply(COAP_TYPE_ACK, endpoint, notification);
|
||||
}
|
||||
if(obs->notification_callback != NULL) {
|
||||
flag = classify_notification(notification, 0);
|
||||
|
@ -265,7 +241,7 @@ coap_handle_notification(uip_ipaddr_t *addr, uint16_t port,
|
|||
if(flag == NOTIFICATION_OK) {
|
||||
coap_get_header_observe(notification, &observe);
|
||||
if(observe == obs->last_observe) {
|
||||
PRINTF("Discarding duplicate\n");
|
||||
LOG_DBG("Discarding duplicate\n");
|
||||
return;
|
||||
}
|
||||
obs->last_observe = observe;
|
||||
|
@ -275,13 +251,13 @@ coap_handle_notification(uip_ipaddr_t *addr, uint16_t port,
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_obs_registration_response(void *data, void *response)
|
||||
handle_obs_registration_response(void *data, coap_message_t *response)
|
||||
{
|
||||
coap_observee_t *obs;
|
||||
notification_callback_t notification_callback;
|
||||
coap_notification_flag_t flag;
|
||||
|
||||
PRINTF("handle_obs_registration_response(): ");
|
||||
LOG_DBG("handle_obs_registration_response()\n");
|
||||
obs = (coap_observee_t *)data;
|
||||
notification_callback = obs->notification_callback;
|
||||
flag = classify_notification(response, 1);
|
||||
|
@ -305,11 +281,11 @@ coap_generate_token(uint8_t **token_ptr)
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
coap_observee_t *
|
||||
coap_obs_request_registration(uip_ipaddr_t *addr, uint16_t port, char *uri,
|
||||
coap_obs_request_registration(const coap_endpoint_t *endpoint, char *uri,
|
||||
notification_callback_t notification_callback,
|
||||
void *data)
|
||||
{
|
||||
coap_packet_t request[1];
|
||||
coap_message_t request[1];
|
||||
coap_transaction_t *t;
|
||||
uint8_t *token;
|
||||
uint8_t token_len;
|
||||
|
@ -321,22 +297,23 @@ coap_obs_request_registration(uip_ipaddr_t *addr, uint16_t port, char *uri,
|
|||
coap_set_header_observe(request, 0);
|
||||
token_len = coap_generate_token(&token);
|
||||
set_token(request, token, token_len);
|
||||
t = coap_new_transaction(request->mid, addr, port);
|
||||
t = coap_new_transaction(request->mid, endpoint);
|
||||
if(t) {
|
||||
obs = coap_obs_add_observee(addr, port, (uint8_t *)token, token_len, uri,
|
||||
obs = coap_obs_add_observee(endpoint, (uint8_t *)token, token_len, uri,
|
||||
notification_callback, data);
|
||||
if(obs) {
|
||||
t->callback = handle_obs_registration_response;
|
||||
t->callback_data = obs;
|
||||
t->packet_len = coap_serialize_message(request, t->packet);
|
||||
t->message_len = coap_serialize_message(request, t->message);
|
||||
coap_send_transaction(t);
|
||||
} else {
|
||||
PRINTF("Could not allocate obs_subject resource buffer");
|
||||
LOG_DBG("Could not allocate obs_subject resource buffer\n");
|
||||
coap_clear_transaction(t);
|
||||
}
|
||||
} else {
|
||||
PRINTF("Could not allocate transaction buffer");
|
||||
LOG_DBG("Could not allocate transaction buffer\n");
|
||||
}
|
||||
return obs;
|
||||
}
|
||||
#endif /* COAP_OBSERVE_CLIENT */
|
||||
/** @} */
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
* Daniele Alessandrelli <daniele.alessandrelli@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_OBSERVING_CLIENT_H_
|
||||
#define COAP_OBSERVING_CLIENT_H_
|
||||
|
||||
|
@ -79,8 +84,7 @@ typedef void (*notification_callback_t)(coap_observee_t *subject,
|
|||
|
||||
struct coap_observee_s {
|
||||
coap_observee_t *next; /* for LIST */
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
coap_endpoint_t endpoint;
|
||||
const char *url;
|
||||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
|
@ -90,7 +94,7 @@ struct coap_observee_s {
|
|||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
coap_observee_t *coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_observee_t *coap_obs_add_observee(const coap_endpoint_t *endpoint,
|
||||
const uint8_t *token, size_t token_len,
|
||||
const char *url,
|
||||
notification_callback_t
|
||||
|
@ -101,17 +105,17 @@ void coap_obs_remove_observee(coap_observee_t *o);
|
|||
coap_observee_t *coap_obs_get_observee_by_token(const uint8_t *token,
|
||||
size_t token_len);
|
||||
|
||||
int coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
int coap_obs_remove_observee_by_token(const coap_endpoint_t *endpoint,
|
||||
uint8_t *token, size_t token_len);
|
||||
|
||||
int coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
||||
int coap_obs_remove_observee_by_url(const coap_endpoint_t *endpoint,
|
||||
const char *url);
|
||||
|
||||
void coap_handle_notification(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_packet_t *notification);
|
||||
void coap_handle_notification(const coap_endpoint_t *endpoint,
|
||||
coap_message_t *notification);
|
||||
|
||||
coap_observee_t *coap_obs_request_registration(uip_ipaddr_t *addr,
|
||||
uint16_t port, char *uri,
|
||||
coap_observee_t *coap_obs_request_registration(const coap_endpoint_t *endpoint,
|
||||
char *uri,
|
||||
notification_callback_t
|
||||
notification_callback,
|
||||
void *data);
|
||||
|
@ -119,3 +123,4 @@ coap_observee_t *coap_obs_request_registration(uip_ipaddr_t *addr,
|
|||
uint8_t coap_generate_token(uint8_t **token_ptr);
|
||||
|
||||
#endif /* COAP_OBSERVING_CLIENT_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -36,21 +36,22 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "coap-observe.h"
|
||||
#include "coap-engine.h"
|
||||
#include "lib/memb.h"
|
||||
#include "lib/list.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-observe"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS);
|
||||
|
@ -59,11 +60,11 @@ LIST(observers_list);
|
|||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static coap_observer_t *
|
||||
add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
|
||||
add_observer(const coap_endpoint_t *endpoint, const uint8_t *token,
|
||||
size_t token_len, const char *uri, int uri_len)
|
||||
{
|
||||
/* Remove existing observe relationship, if any. */
|
||||
coap_remove_observer_by_uri(addr, port, uri);
|
||||
coap_remove_observer_by_uri(endpoint, uri);
|
||||
|
||||
coap_observer_t *o = memb_alloc(&observers_memb);
|
||||
|
||||
|
@ -74,15 +75,14 @@ add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
|
|||
}
|
||||
memcpy(o->url, uri, max);
|
||||
o->url[max] = 0;
|
||||
uip_ipaddr_copy(&o->addr, addr);
|
||||
o->port = port;
|
||||
coap_endpoint_copy(&o->endpoint, endpoint);
|
||||
o->token_len = token_len;
|
||||
memcpy(o->token, token, token_len);
|
||||
o->last_mid = 0;
|
||||
|
||||
PRINTF("Adding observer (%u/%u) for /%s [0x%02X%02X]\n",
|
||||
list_length(observers_list) + 1, COAP_MAX_OBSERVERS,
|
||||
o->url, o->token[0], o->token[1]);
|
||||
LOG_INFO("Adding observer (%u/%u) for /%s [0x%02X%02X]\n",
|
||||
list_length(observers_list) + 1, COAP_MAX_OBSERVERS,
|
||||
o->url, o->token[0], o->token[1]);
|
||||
list_add(observers_list, o);
|
||||
}
|
||||
|
||||
|
@ -94,25 +94,25 @@ add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
|
|||
void
|
||||
coap_remove_observer(coap_observer_t *o)
|
||||
{
|
||||
PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
LOG_INFO("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
|
||||
memb_free(&observers_memb, o);
|
||||
list_remove(observers_list, o);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port)
|
||||
coap_remove_observer_by_client(const coap_endpoint_t *endpoint)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
LOG_DBG("Remove check client ");
|
||||
LOG_DBG_COAP_EP(endpoint);
|
||||
LOG_DBG_("\n");
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check client ");
|
||||
PRINT6ADDR(addr);
|
||||
PRINTF(":%u\n", port);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port) {
|
||||
if(coap_endpoint_cmp(&obs->endpoint, endpoint)) {
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_remove_observer_by_token(const coap_endpoint_t *endpoint,
|
||||
uint8_t *token, size_t token_len)
|
||||
{
|
||||
int removed = 0;
|
||||
|
@ -129,8 +129,8 @@ coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
|||
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port
|
||||
LOG_DBG("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(coap_endpoint_cmp(&obs->endpoint, endpoint)
|
||||
&& obs->token_len == token_len
|
||||
&& memcmp(obs->token, token, token_len) == 0) {
|
||||
coap_remove_observer(obs);
|
||||
|
@ -141,7 +141,7 @@ coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
||||
coap_remove_observer_by_uri(const coap_endpoint_t *endpoint,
|
||||
const char *uri)
|
||||
{
|
||||
int removed = 0;
|
||||
|
@ -149,9 +149,9 @@ coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
|||
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check URL %p\n", uri);
|
||||
if((addr == NULL
|
||||
|| (uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port))
|
||||
LOG_DBG("Remove check URL %p\n", uri);
|
||||
if((endpoint == NULL
|
||||
|| (coap_endpoint_cmp(&obs->endpoint, endpoint)))
|
||||
&& (obs->url == uri || memcmp(obs->url, uri, strlen(obs->url)) == 0)) {
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
|
@ -161,15 +161,15 @@ coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid)
|
||||
coap_remove_observer_by_mid(const coap_endpoint_t *endpoint, uint16_t mid)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check MID %u\n", mid);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port
|
||||
LOG_DBG("Remove check MID %u\n", mid);
|
||||
if(coap_endpoint_cmp(&obs->endpoint, endpoint)
|
||||
&& obs->last_mid == mid) {
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
|
@ -181,29 +181,40 @@ coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid)
|
|||
/*- Notification ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_notify_observers(resource_t *resource)
|
||||
coap_notify_observers(coap_resource_t *resource)
|
||||
{
|
||||
coap_notify_observers_sub(resource, NULL);
|
||||
}
|
||||
/* Can be used either for sub - or when there is not resource - just
|
||||
a handler */
|
||||
void
|
||||
coap_notify_observers_sub(resource_t *resource, const char *subpath)
|
||||
coap_notify_observers_sub(coap_resource_t *resource, const char *subpath)
|
||||
{
|
||||
/* build notification */
|
||||
coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */
|
||||
coap_packet_t request[1]; /* this way the packet can be treated as pointer as usual */
|
||||
coap_message_t notification[1]; /* this way the message can be treated as pointer as usual */
|
||||
coap_message_t request[1]; /* this way the message can be treated as pointer as usual */
|
||||
coap_observer_t *obs = NULL;
|
||||
int url_len, obs_url_len;
|
||||
char url[COAP_OBSERVER_URL_LEN];
|
||||
uint8_t sub_ok = 0;
|
||||
|
||||
url_len = strlen(resource->url);
|
||||
strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1);
|
||||
if(url_len < COAP_OBSERVER_URL_LEN - 1 && subpath != NULL) {
|
||||
strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1);
|
||||
if(resource != NULL) {
|
||||
url_len = strlen(resource->url);
|
||||
strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1);
|
||||
if(url_len < COAP_OBSERVER_URL_LEN - 1 && subpath != NULL) {
|
||||
strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1);
|
||||
}
|
||||
} else if(subpath != NULL) {
|
||||
strncpy(url, subpath, COAP_OBSERVER_URL_LEN - 1);
|
||||
} else {
|
||||
/* No resource, no subpath */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure url is null terminated because strncpy does not guarantee this */
|
||||
url[COAP_OBSERVER_URL_LEN - 1] = '\0';
|
||||
/* url now contains the notify URL that needs to match the observer */
|
||||
PRINTF("Observe: Notification from %s\n", url);
|
||||
LOG_INFO("Notification from %s\n", url);
|
||||
|
||||
coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0);
|
||||
/* create a "fake" request for the URI */
|
||||
|
@ -212,30 +223,35 @@ coap_notify_observers_sub(resource_t *resource, const char *subpath)
|
|||
|
||||
/* iterate over observers */
|
||||
url_len = strlen(url);
|
||||
/* Assumes lazy evaluation... */
|
||||
sub_ok = (resource == NULL) || (resource->flags & HAS_SUB_RESOURCES);
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
obs_url_len = strlen(obs->url);
|
||||
|
||||
/* Do a match based on the parent/sub-resource match so that it is
|
||||
possible to do parent-node observe */
|
||||
|
||||
/***** TODO fix here so that we handle the notofication correctly ******/
|
||||
/* All the new-style ... is assuming that the URL might be within */
|
||||
if((obs_url_len == url_len
|
||||
|| (obs_url_len > url_len
|
||||
&& (resource->flags & HAS_SUB_RESOURCES)
|
||||
&& sub_ok
|
||||
&& obs->url[url_len] == '/'))
|
||||
&& strncmp(url, obs->url, url_len) == 0) {
|
||||
coap_transaction_t *transaction = NULL;
|
||||
|
||||
/*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */
|
||||
|
||||
if((transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port))) {
|
||||
if((transaction = coap_new_transaction(coap_get_mid(), &obs->endpoint))) {
|
||||
if(obs->obs_counter % COAP_OBSERVE_REFRESH_INTERVAL == 0) {
|
||||
PRINTF(" Force Confirmable for\n");
|
||||
LOG_DBG(" Force Confirmable for\n");
|
||||
notification->type = COAP_TYPE_CON;
|
||||
}
|
||||
|
||||
PRINTF(" Observer ");
|
||||
PRINT6ADDR(&obs->addr);
|
||||
PRINTF(":%u\n", obs->port);
|
||||
LOG_DBG(" Observer ");
|
||||
LOG_DBG_COAP_EP(&obs->endpoint);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
/* update last MID for RST matching */
|
||||
obs->last_mid = transaction->mid;
|
||||
|
@ -243,9 +259,21 @@ coap_notify_observers_sub(resource_t *resource, const char *subpath)
|
|||
/* prepare response */
|
||||
notification->mid = transaction->mid;
|
||||
|
||||
resource->get_handler(request, notification,
|
||||
transaction->packet + COAP_MAX_HEADER_SIZE,
|
||||
REST_MAX_CHUNK_SIZE, NULL);
|
||||
/* Either old style get_handler or the full handler */
|
||||
if(coap_call_handlers(request, notification, transaction->message +
|
||||
COAP_MAX_HEADER_SIZE, COAP_MAX_CHUNK_SIZE,
|
||||
NULL) > 0) {
|
||||
LOG_DBG("Notification on new handlers\n");
|
||||
} else {
|
||||
if(resource != NULL) {
|
||||
resource->get_handler(request, notification,
|
||||
transaction->message + COAP_MAX_HEADER_SIZE,
|
||||
COAP_MAX_CHUNK_SIZE, NULL);
|
||||
} else {
|
||||
/* What to do here? */
|
||||
notification->code = BAD_REQUEST_4_00;
|
||||
}
|
||||
}
|
||||
|
||||
if(notification->code < BAD_REQUEST_4_00) {
|
||||
coap_set_header_observe(notification, (obs->obs_counter)++);
|
||||
|
@ -254,8 +282,8 @@ coap_notify_observers_sub(resource_t *resource, const char *subpath)
|
|||
}
|
||||
coap_set_token(notification, obs->token, obs->token_len);
|
||||
|
||||
transaction->packet_len =
|
||||
coap_serialize_message(notification, transaction->packet);
|
||||
transaction->message_len =
|
||||
coap_serialize_message(notification, transaction->message);
|
||||
|
||||
coap_send_transaction(transaction);
|
||||
}
|
||||
|
@ -264,16 +292,21 @@ coap_notify_observers_sub(resource_t *resource, const char *subpath)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_observe_handler(resource_t *resource, void *request, void *response)
|
||||
coap_observe_handler(coap_resource_t *resource, coap_message_t *coap_req,
|
||||
coap_message_t *coap_res)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_packet_t *const coap_res = (coap_packet_t *)response;
|
||||
const coap_endpoint_t *src_ep;
|
||||
coap_observer_t *obs;
|
||||
|
||||
LOG_DBG("CoAP observer handler rsc: %d\n", resource != NULL);
|
||||
|
||||
if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */
|
||||
if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) {
|
||||
if(coap_req->observe == 0) {
|
||||
obs = add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
|
||||
if(coap_is_option(coap_req, COAP_OPTION_OBSERVE)) {
|
||||
src_ep = coap_get_src_endpoint(coap_req);
|
||||
if(src_ep == NULL) {
|
||||
/* No source endpoint, can not add */
|
||||
} else if(coap_req->observe == 0) {
|
||||
obs = add_observer(src_ep,
|
||||
coap_req->token, coap_req->token_len,
|
||||
coap_req->uri_path, coap_req->uri_path_len);
|
||||
if(obs) {
|
||||
|
@ -300,11 +333,11 @@ coap_observe_handler(resource_t *resource, void *request, void *response)
|
|||
} else if(coap_req->observe == 1) {
|
||||
|
||||
/* remove client if it is currently observe */
|
||||
coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport, coap_req->token,
|
||||
coap_req->token_len);
|
||||
coap_remove_observer_by_token(src_ep,
|
||||
coap_req->token, coap_req->token_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -36,53 +36,49 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_OBSERVE_H_
|
||||
#define COAP_OBSERVE_H_
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "stimer.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
#define COAP_OBSERVER_URL_LEN 20
|
||||
|
||||
typedef struct coap_observable {
|
||||
uint32_t observe_clock;
|
||||
struct stimer orphan_timer;
|
||||
list_t observers;
|
||||
coap_packet_t notification;
|
||||
uint8_t buffer[COAP_MAX_PACKET_SIZE + 1];
|
||||
} coap_observable_t;
|
||||
|
||||
typedef struct coap_observer {
|
||||
struct coap_observer *next; /* for LIST */
|
||||
|
||||
char url[COAP_OBSERVER_URL_LEN];
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
coap_endpoint_t endpoint;
|
||||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
uint16_t last_mid;
|
||||
|
||||
int32_t obs_counter;
|
||||
|
||||
struct etimer retrans_timer;
|
||||
coap_timer_t retrans_timer;
|
||||
uint8_t retrans_counter;
|
||||
} coap_observer_t;
|
||||
|
||||
list_t coap_get_observers(void);
|
||||
void coap_remove_observer(coap_observer_t *o);
|
||||
int coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port);
|
||||
int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
int coap_remove_observer_by_client(const coap_endpoint_t *ep);
|
||||
int coap_remove_observer_by_token(const coap_endpoint_t *ep,
|
||||
uint8_t *token, size_t token_len);
|
||||
int coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
||||
int coap_remove_observer_by_uri(const coap_endpoint_t *ep,
|
||||
const char *uri);
|
||||
int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port,
|
||||
int coap_remove_observer_by_mid(const coap_endpoint_t *ep,
|
||||
uint16_t mid);
|
||||
|
||||
void coap_notify_observers(resource_t *resource);
|
||||
void coap_notify_observers_sub(resource_t *resource, const char *subpath);
|
||||
void coap_notify_observers(coap_resource_t *resource);
|
||||
void coap_notify_observers_sub(coap_resource_t *resource, const char *subpath);
|
||||
|
||||
void coap_observe_handler(resource_t *resource, void *request,
|
||||
void *response);
|
||||
void coap_observe_handler(coap_resource_t *resource, coap_message_t *request,
|
||||
coap_message_t *response);
|
||||
|
||||
#endif /* COAP_OBSERVE_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -36,20 +36,19 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "coap-engine.h"
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include "coap-engine.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-res-well-known-core"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
#define ADD_CHAR_IF_POSSIBLE(char) \
|
||||
if(strpos >= *offset && bufpos < preferred_size) { \
|
||||
|
@ -67,7 +66,7 @@
|
|||
+ (*offset - (int32_t)strpos > 0 ? \
|
||||
*offset - (int32_t)strpos : 0)); \
|
||||
if(bufpos op preferred_size) { \
|
||||
PRINTF("res: BREAK at %s (%p)\n", string, resource); \
|
||||
LOG_DBG("BREAK at %s (%p)\n", string, resource); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
|
@ -76,14 +75,15 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/*- Resource Handlers -------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
static void
|
||||
well_known_core_get_handler(coap_message_t *request, coap_message_t *response,
|
||||
uint8_t *buffer, uint16_t preferred_size,
|
||||
int32_t *offset)
|
||||
{
|
||||
size_t strpos = 0; /* position in overall string (which is larger than the buffer) */
|
||||
size_t bufpos = 0; /* position within buffer (bytes written) */
|
||||
size_t tmplen = 0;
|
||||
resource_t *resource = NULL;
|
||||
coap_resource_t *resource = NULL;
|
||||
|
||||
#if COAP_LINK_FORMAT_FILTERING
|
||||
/* For filtering. */
|
||||
|
@ -101,7 +101,9 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
++value;
|
||||
len -= strlen(filter) + 1;
|
||||
|
||||
PRINTF("Filter %s = %.*s\n", filter, len, value);
|
||||
LOG_DBG("Filter %s = ", filter);
|
||||
LOG_DBG_COAP_STRING(value, len);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
if(strcmp(filter, "href") == 0 && value[0] == '/') {
|
||||
++value;
|
||||
|
@ -111,10 +113,10 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
lastchar = value[len - 1];
|
||||
value[len - 1] = '\0';
|
||||
}
|
||||
#endif
|
||||
#endif /* COAP_LINK_FORMAT_FILTERING */
|
||||
|
||||
for(resource = (resource_t *)list_head(rest_get_resources()); resource;
|
||||
resource = resource->next) {
|
||||
for(resource = coap_get_first_resource(); resource;
|
||||
resource = coap_get_next_resource(resource)) {
|
||||
#if COAP_LINK_FORMAT_FILTERING
|
||||
/* Filtering */
|
||||
if(len) {
|
||||
|
@ -135,7 +137,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
end = strchr(attrib, '"');
|
||||
}
|
||||
|
||||
PRINTF("Filter: res has attrib %s (%s)\n", attrib, value);
|
||||
LOG_DBG("Filter: res has attrib %s (%s)\n", attrib, value);
|
||||
found = attrib;
|
||||
while((found = strstr(found, value)) != NULL) {
|
||||
if(found > end) {
|
||||
|
@ -150,17 +152,17 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
if(found == NULL) {
|
||||
continue;
|
||||
}
|
||||
PRINTF("Filter: res has prefix %s\n", found);
|
||||
LOG_DBG("Filter: res has prefix %s\n", found);
|
||||
if(lastchar != '*'
|
||||
&& (found[len] != '"' && found[len] != ' ' && found[len] != '\0')) {
|
||||
continue;
|
||||
}
|
||||
PRINTF("Filter: res has match\n");
|
||||
LOG_DBG("Filter: res has match\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource,
|
||||
strpos, (long)*offset, bufpos);
|
||||
LOG_DBG("/%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource,
|
||||
strpos, (long)*offset, bufpos);
|
||||
|
||||
if(strpos > 0) {
|
||||
ADD_CHAR_IF_POSSIBLE(',');
|
||||
|
@ -177,28 +179,30 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
|
||||
/* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */
|
||||
if(bufpos > preferred_size && strpos - bufpos > *offset) {
|
||||
PRINTF("res: BREAK at %s (%p)\n", resource->url, resource);
|
||||
LOG_DBG("BREAK at %s (%p)\n", resource->url, resource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bufpos > 0) {
|
||||
PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer);
|
||||
LOG_DBG("BUF %zu: ", bufpos);
|
||||
LOG_DBG_COAP_STRING((char *)buffer, bufpos);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
coap_set_payload(response, buffer, bufpos);
|
||||
coap_set_header_content_format(response, APPLICATION_LINK_FORMAT);
|
||||
} else if(strpos > 0) {
|
||||
PRINTF("well_known_core_handler(): bufpos<=0\n");
|
||||
LOG_DBG("well_known_core_handler(): bufpos<=0\n");
|
||||
|
||||
coap_set_status_code(response, BAD_OPTION_4_02);
|
||||
coap_set_payload(response, "BlockOutOfScope", 15);
|
||||
}
|
||||
|
||||
if(resource == NULL) {
|
||||
PRINTF("res: DONE\n");
|
||||
LOG_DBG("DONE\n");
|
||||
*offset = -1;
|
||||
} else {
|
||||
PRINTF("res: MORE at %s (%p)\n", resource->url, resource);
|
||||
LOG_DBG("MORE at %s (%p)\n", resource->url, resource);
|
||||
*offset += preferred_size;
|
||||
}
|
||||
}
|
||||
|
@ -206,3 +210,4 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
RESOURCE(res_well_known_core, "ct=40", well_known_core_get_handler, NULL,
|
||||
NULL, NULL);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -36,23 +36,21 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-separate.h"
|
||||
#include "coap-transactions.h"
|
||||
#include "sys/cc.h"
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-separate"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Separate Response API ---------------------------------------------------*/
|
||||
|
@ -69,13 +67,13 @@ void
|
|||
coap_separate_reject()
|
||||
{
|
||||
/* TODO: Accept string pointer for custom error message */
|
||||
erbium_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_error_message = "AlreadyInUse";
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initiate a separate response with an empty ACK
|
||||
* \param request The request to accept
|
||||
* \param coap_req The request to accept
|
||||
* \param separate_store A pointer to the data structure that will store the
|
||||
* relevant information for the response
|
||||
*
|
||||
|
@ -85,29 +83,33 @@ coap_separate_reject()
|
|||
* then retry later.
|
||||
*/
|
||||
void
|
||||
coap_separate_accept(void *request, coap_separate_t *separate_store)
|
||||
coap_separate_accept(coap_message_t *coap_req, coap_separate_t *separate_store)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid);
|
||||
|
||||
PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len,
|
||||
coap_req->uri_path, coap_req->mid);
|
||||
LOG_DBG("Separate ACCEPT: /");
|
||||
LOG_DBG_COAP_STRING(coap_req->uri_path, coap_req->uri_path_len);
|
||||
LOG_DBG_(" MID %u\n", coap_req->mid);
|
||||
if(t) {
|
||||
/* send separate ACK for CON */
|
||||
if(coap_req->type == COAP_TYPE_CON) {
|
||||
coap_packet_t ack[1];
|
||||
coap_message_t ack[1];
|
||||
const coap_endpoint_t *ep;
|
||||
|
||||
/* ACK with empty code (0) */
|
||||
coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
|
||||
/* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */
|
||||
coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
|
||||
(uip_appdata), coap_serialize_message(ack,
|
||||
uip_appdata));
|
||||
ep = coap_get_src_endpoint(coap_req);
|
||||
if(ep == NULL) {
|
||||
LOG_ERR("ERROR: no endpoint in request\n");
|
||||
} else {
|
||||
/* ACK with empty code (0) */
|
||||
coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
|
||||
/* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */
|
||||
coap_sendto(ep, coap_databuf(),
|
||||
coap_serialize_message(ack, coap_databuf()));
|
||||
}
|
||||
}
|
||||
|
||||
/* store remote address */
|
||||
uip_ipaddr_copy(&separate_store->addr, &t->addr);
|
||||
separate_store->port = t->port;
|
||||
/* store remote endpoint address */
|
||||
coap_endpoint_copy(&separate_store->endpoint, &t->endpoint);
|
||||
|
||||
/* store correct response type */
|
||||
separate_store->type =
|
||||
|
@ -124,15 +126,15 @@ coap_separate_accept(void *request, coap_separate_t *separate_store)
|
|||
separate_store->block2_size = coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size) : COAP_MAX_BLOCK_SIZE;
|
||||
|
||||
/* signal the engine to skip automatic response and clear transaction by engine */
|
||||
erbium_status_code = MANUAL_RESPONSE;
|
||||
coap_status_code = MANUAL_RESPONSE;
|
||||
} else {
|
||||
PRINTF("ERROR: Response transaction for separate request not found!\n");
|
||||
erbium_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
LOG_ERR("ERROR: Response transaction for separate request not found!\n");
|
||||
coap_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_separate_resume(void *response, coap_separate_t *separate_store,
|
||||
coap_separate_resume(coap_message_t *response, coap_separate_t *separate_store,
|
||||
uint8_t code)
|
||||
{
|
||||
coap_init_message(response, separate_store->type, code,
|
||||
|
@ -147,3 +149,4 @@ coap_separate_resume(void *response, coap_separate_t *separate_store,
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -36,15 +36,20 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_SEPARATE_H_
|
||||
#define COAP_SEPARATE_H_
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-engine.h"
|
||||
|
||||
typedef struct coap_separate {
|
||||
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
coap_endpoint_t endpoint;
|
||||
|
||||
coap_message_type_t type;
|
||||
uint16_t mid;
|
||||
|
@ -59,11 +64,14 @@ typedef struct coap_separate {
|
|||
uint16_t block2_size;
|
||||
} coap_separate_t;
|
||||
|
||||
int coap_separate_handler(resource_t *resource, void *request,
|
||||
void *response);
|
||||
int coap_separate_handler(coap_resource_t *resource, coap_message_t *request,
|
||||
coap_message_t *response);
|
||||
void coap_separate_reject(void);
|
||||
void coap_separate_accept(void *request, coap_separate_t *separate_store);
|
||||
void coap_separate_resume(void *response, coap_separate_t *separate_store,
|
||||
void coap_separate_accept(coap_message_t *request,
|
||||
coap_separate_t *separate_store);
|
||||
void coap_separate_resume(coap_message_t *response,
|
||||
coap_separate_t *separate_store,
|
||||
uint8_t code);
|
||||
|
||||
#endif /* COAP_SEPARATE_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2016, SICS, Swedish ICT AB.
|
||||
* 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
|
||||
* CoAP timer driver implementation based on Contiki etimers
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap-timer
|
||||
* @{
|
||||
*
|
||||
* \defgroup coap-timer-default CoAP timer for Contiki-NG
|
||||
* @{
|
||||
*
|
||||
* This is an implementation of CoAP timer for Contiki-NG.
|
||||
*/
|
||||
|
||||
#include "coap-timer.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/etimer.h"
|
||||
#include "sys/process.h"
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-timer-default"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
PROCESS(coap_timer_process, "coap timer process");
|
||||
|
||||
static uint64_t current_time;
|
||||
static struct etimer timer;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_timer(void)
|
||||
{
|
||||
uint64_t remaining;
|
||||
remaining = coap_timer_time_to_next_expiration();
|
||||
LOG_DBG("remaining %lu msec\n", (unsigned long)remaining);
|
||||
if(remaining == 0) {
|
||||
/* Run as soon as possible */
|
||||
process_poll(&coap_timer_process);
|
||||
} else {
|
||||
remaining *= CLOCK_SECOND;
|
||||
remaining /= 1000;
|
||||
if(remaining > CLOCK_SECOND * 60) {
|
||||
/* Make sure the CoAP timer clock is updated at least once per minute */
|
||||
remaining = CLOCK_SECOND * 60;
|
||||
} else if(remaining < 1) {
|
||||
/* Wait minimum one system clock tick */
|
||||
remaining = 1;
|
||||
}
|
||||
etimer_set(&timer, (clock_time_t)remaining);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(coap_timer_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
etimer_set(&timer, CLOCK_SECOND);
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER ||
|
||||
ev == PROCESS_EVENT_POLL);
|
||||
|
||||
if(coap_timer_run()) {
|
||||
/* Needs to run again */
|
||||
process_poll(&coap_timer_process);
|
||||
} else {
|
||||
update_timer();
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint64_t
|
||||
uptime(void)
|
||||
{
|
||||
static clock_time_t last;
|
||||
clock_time_t now;
|
||||
uint64_t diff;
|
||||
|
||||
now = clock_time();
|
||||
diff = (clock_time_t)(now - last);
|
||||
if(diff > 0) {
|
||||
current_time += (diff * 1000) / CLOCK_SECOND;
|
||||
last = now;
|
||||
}
|
||||
return current_time;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
process_start(&coap_timer_process, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
update(void)
|
||||
{
|
||||
process_poll(&coap_timer_process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const coap_timer_driver_t coap_timer_default_driver = {
|
||||
.init = init,
|
||||
.uptime = uptime,
|
||||
.update = update,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright (c) 2016, SICS, Swedish ICT AB.
|
||||
* 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
|
||||
* CoAP timer implementation.
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap-timer
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-timer.h"
|
||||
#include "lib/list.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-timer"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
LIST(timer_list);
|
||||
static uint8_t is_initialized;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
add_timer(coap_timer_t *timer)
|
||||
{
|
||||
coap_timer_t *n, *l, *p;
|
||||
|
||||
if(!is_initialized) {
|
||||
/* The coap_timer system has not yet been initialized */
|
||||
coap_timer_init();
|
||||
}
|
||||
|
||||
LOG_DBG("adding timer %p at %lu\n", timer,
|
||||
(unsigned long)timer->expiration_time);
|
||||
|
||||
p = list_head(timer_list);
|
||||
|
||||
/* Make sure the timer is not already added to the timer list */
|
||||
list_remove(timer_list, timer);
|
||||
|
||||
for(l = NULL, n = list_head(timer_list); n != NULL; l = n, n = n->next) {
|
||||
if(timer->expiration_time < n->expiration_time) {
|
||||
list_insert(timer_list, l, timer);
|
||||
timer = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(timer != NULL) {
|
||||
list_insert(timer_list, l, timer);
|
||||
}
|
||||
|
||||
if(p != list_head(timer_list)) {
|
||||
/* The next timer to expire has changed so we need to notify the driver */
|
||||
COAP_TIMER_DRIVER.update();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_timer_stop(coap_timer_t *timer)
|
||||
{
|
||||
LOG_DBG("stopping timer %p\n", timer);
|
||||
|
||||
/* Mark timer as expired right now */
|
||||
timer->expiration_time = coap_timer_uptime();
|
||||
|
||||
list_remove(timer_list, timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_timer_set(coap_timer_t *timer, uint64_t time)
|
||||
{
|
||||
timer->expiration_time = coap_timer_uptime() + time;
|
||||
add_timer(timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_timer_reset(coap_timer_t *timer, uint64_t time)
|
||||
{
|
||||
timer->expiration_time += time;
|
||||
add_timer(timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint64_t
|
||||
coap_timer_time_to_next_expiration(void)
|
||||
{
|
||||
uint64_t now;
|
||||
coap_timer_t *next;
|
||||
|
||||
next = list_head(timer_list);
|
||||
if(next == NULL) {
|
||||
/* No pending timers - return a time in the future */
|
||||
return 60000;
|
||||
}
|
||||
|
||||
now = coap_timer_uptime();
|
||||
if(now < next->expiration_time) {
|
||||
return next->expiration_time - now;
|
||||
}
|
||||
/* The next timer should already have expired */
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_timer_run(void)
|
||||
{
|
||||
uint64_t now;
|
||||
coap_timer_t *next;
|
||||
|
||||
/* Always get the current time because it might trigger clock updates */
|
||||
now = coap_timer_uptime();
|
||||
|
||||
next = list_head(timer_list);
|
||||
if(next == NULL) {
|
||||
/* No pending timers */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(next->expiration_time <= now) {
|
||||
LOG_DBG("timer %p expired at %lu\n", next, (unsigned long)now);
|
||||
|
||||
/* This timer should expire now */
|
||||
list_remove(timer_list, next);
|
||||
|
||||
if(next->callback) {
|
||||
next->callback(next);
|
||||
}
|
||||
|
||||
/* The next timer has changed */
|
||||
COAP_TIMER_DRIVER.update();
|
||||
|
||||
/* Check if there is another pending timer */
|
||||
next = list_head(timer_list);
|
||||
if(next != NULL && next->expiration_time <= coap_timer_uptime()) {
|
||||
/* Need to run again */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_timer_init(void)
|
||||
{
|
||||
if(is_initialized) {
|
||||
return;
|
||||
}
|
||||
is_initialized = 1;
|
||||
list_init(timer_list);
|
||||
if(COAP_TIMER_DRIVER.init) {
|
||||
COAP_TIMER_DRIVER.init();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (c) 2016, SICS, Swedish ICT AB.
|
||||
* 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
|
||||
* CoAP timer API.
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*
|
||||
* \defgroup coap-timer CoAP timer API
|
||||
* @{
|
||||
*
|
||||
* The CoAP timer API defines a common interface for CoAP timer and time functionality.
|
||||
*/
|
||||
|
||||
#ifndef COAP_TIMER_H_
|
||||
#define COAP_TIMER_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct coap_timer coap_timer_t;
|
||||
struct coap_timer {
|
||||
coap_timer_t *next;
|
||||
void (* callback)(coap_timer_t *);
|
||||
void *user_data;
|
||||
uint64_t expiration_time;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void (* init)(void);
|
||||
uint64_t (* uptime)(void);
|
||||
void (* update)(void);
|
||||
} coap_timer_driver_t;
|
||||
|
||||
#ifndef COAP_TIMER_DRIVER
|
||||
#ifdef COAP_TIMER_CONF_DRIVER
|
||||
#define COAP_TIMER_DRIVER COAP_TIMER_CONF_DRIVER
|
||||
#else /* COAP_TIMER_CONF_DRIVER */
|
||||
#define COAP_TIMER_DRIVER coap_timer_default_driver
|
||||
#endif /* COAP_TIMER_CONF_DRIVER */
|
||||
#endif /* COAP_TIMER_DRIVER */
|
||||
|
||||
extern const coap_timer_driver_t COAP_TIMER_DRIVER;
|
||||
|
||||
/**
|
||||
* \brief Get the time since boot in milliseconds.
|
||||
* \return The number of milliseconds since boot.
|
||||
*/
|
||||
static inline uint64_t
|
||||
coap_timer_uptime(void)
|
||||
{
|
||||
return COAP_TIMER_DRIVER.uptime();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the time since boot in seconds.
|
||||
* \return The number of seconds since boot.
|
||||
*/
|
||||
static inline uint32_t
|
||||
coap_timer_seconds(void)
|
||||
{
|
||||
return (uint32_t)(COAP_TIMER_DRIVER.uptime() / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a callback function to be called when a CoAP timer expires.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \param callback A callback function.
|
||||
*/
|
||||
static inline void
|
||||
coap_timer_set_callback(coap_timer_t *timer, void (* callback)(coap_timer_t *))
|
||||
{
|
||||
timer->callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get user data that has been attached to a CoAP timer.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \return An opaque pointer to user data or NULL if no user data is
|
||||
* attached to the timer.
|
||||
*/
|
||||
static inline void *
|
||||
coap_timer_get_user_data(coap_timer_t *timer)
|
||||
{
|
||||
return timer->user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Attach user data to a CoAP timer.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \param data An opaque pointer to user data.
|
||||
*/
|
||||
static inline void
|
||||
coap_timer_set_user_data(coap_timer_t *timer, void *data)
|
||||
{
|
||||
timer->user_data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if a CoAP timer has expired.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \return Non-zero if the timer has expired, zero otherwise.
|
||||
*/
|
||||
static inline int
|
||||
coap_timer_expired(const coap_timer_t *timer)
|
||||
{
|
||||
return timer->expiration_time <= coap_timer_uptime();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop a pending CoAP timer.
|
||||
*
|
||||
* After this function has been called, the timer will be expired
|
||||
* and will not call the callback function.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
*/
|
||||
void coap_timer_stop(coap_timer_t *timer);
|
||||
|
||||
/**
|
||||
* \brief Set a CoAP timer to expire after the specified time.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \param time The time until the timer expires.
|
||||
*/
|
||||
void coap_timer_set(coap_timer_t *timer, uint64_t time);
|
||||
|
||||
/**
|
||||
* \brief Reset a CoAP timer to expire a specified time after the
|
||||
* last expiration time.
|
||||
*
|
||||
* This function sets the CoAP timer to expire the specified time
|
||||
* after the previous expiration time. If the new expiration time
|
||||
* has already passed, the timer will expire as soon as possible.
|
||||
*
|
||||
* If the timer has not yet expired when this function is called,
|
||||
* the time until the timer expires will be extended by the
|
||||
* specified time.
|
||||
*
|
||||
* \param timer A pointer to a CoAP timer.
|
||||
* \param time The time after previous expiration the timer expires.
|
||||
*/
|
||||
void coap_timer_reset(coap_timer_t *timer, uint64_t time);
|
||||
|
||||
/**
|
||||
* Get the time until next CoAP timer expires or 0 if there already exists
|
||||
* expired timers that have not yet been processed. This function is normally
|
||||
* never called by application code.
|
||||
*
|
||||
* Returns the time to next CoAP timer expires or 0 if unprocessed expired
|
||||
* timers exists. Returns a time in the future if there are no timers pending.
|
||||
*/
|
||||
uint64_t coap_timer_time_to_next_expiration(void);
|
||||
|
||||
/**
|
||||
* This function must be called periodically by the CoAP timer driver to
|
||||
* process any expired CoAP timers. This function is normally never called by
|
||||
* application code.
|
||||
*
|
||||
* Returns non-zero if it needs to run again to process more timers.
|
||||
*/
|
||||
int coap_timer_run(void);
|
||||
|
||||
/**
|
||||
* This function initializes the CoAP timer library. It is automatically
|
||||
* called at first use of a CoAP timer. This function is normally never called
|
||||
* by application code.
|
||||
*/
|
||||
void coap_timer_init(void);
|
||||
|
||||
#endif /* COAP_TIMER_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -36,39 +36,47 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "coap-transactions.h"
|
||||
#include "coap-observe.h"
|
||||
#include "coap-timer.h"
|
||||
#include "lib/memb.h"
|
||||
#include "lib/list.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-transactions"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS);
|
||||
LIST(transactions_list);
|
||||
|
||||
static struct process *transaction_handler_process = NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
coap_retransmit_transaction(coap_timer_t *nt)
|
||||
{
|
||||
coap_transaction_t *t = coap_timer_get_user_data(nt);
|
||||
if(t == NULL) {
|
||||
LOG_DBG("No retransmission data in coap_timer!\n");
|
||||
return;
|
||||
}
|
||||
++(t->retrans_counter);
|
||||
LOG_DBG("Retransmitting %u (%u)\n", t->mid, t->retrans_counter);
|
||||
coap_send_transaction(t);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_register_as_transaction_handler()
|
||||
{
|
||||
transaction_handler_process = PROCESS_CURRENT();
|
||||
}
|
||||
coap_transaction_t *
|
||||
coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port)
|
||||
coap_new_transaction(uint16_t mid, const coap_endpoint_t *endpoint)
|
||||
{
|
||||
coap_transaction_t *t = memb_alloc(&transactions_memb);
|
||||
|
||||
|
@ -77,8 +85,7 @@ coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port)
|
|||
t->retrans_counter = 0;
|
||||
|
||||
/* save client address */
|
||||
uip_ipaddr_copy(&t->addr, addr);
|
||||
t->port = port;
|
||||
coap_endpoint_copy(&t->endpoint, endpoint);
|
||||
|
||||
list_add(transactions_list, t); /* list itself makes sure same element is not added twice */
|
||||
}
|
||||
|
@ -89,43 +96,40 @@ coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port)
|
|||
void
|
||||
coap_send_transaction(coap_transaction_t *t)
|
||||
{
|
||||
PRINTF("Sending transaction %u\n", t->mid);
|
||||
LOG_DBG("Sending transaction %u\n", t->mid);
|
||||
|
||||
coap_send_message(&t->addr, t->port, t->packet, t->packet_len);
|
||||
coap_sendto(&t->endpoint, t->message, t->message_len);
|
||||
|
||||
if(COAP_TYPE_CON ==
|
||||
((COAP_HEADER_TYPE_MASK & t->packet[0]) >> COAP_HEADER_TYPE_POSITION)) {
|
||||
((COAP_HEADER_TYPE_MASK & t->message[0]) >> COAP_HEADER_TYPE_POSITION)) {
|
||||
if(t->retrans_counter < COAP_MAX_RETRANSMIT) {
|
||||
/* not timed out yet */
|
||||
PRINTF("Keeping transaction %u\n", t->mid);
|
||||
LOG_DBG("Keeping transaction %u\n", t->mid);
|
||||
|
||||
if(t->retrans_counter == 0) {
|
||||
t->retrans_timer.timer.interval =
|
||||
COAP_RESPONSE_TIMEOUT_TICKS + (random_rand()
|
||||
%
|
||||
(clock_time_t)
|
||||
coap_timer_set_callback(&t->retrans_timer, coap_retransmit_transaction);
|
||||
coap_timer_set_user_data(&t->retrans_timer, t);
|
||||
t->retrans_interval =
|
||||
COAP_RESPONSE_TIMEOUT_TICKS + (rand() %
|
||||
COAP_RESPONSE_TIMEOUT_BACKOFF_MASK);
|
||||
PRINTF("Initial interval %f\n",
|
||||
(float)t->retrans_timer.timer.interval / CLOCK_SECOND);
|
||||
LOG_DBG("Initial interval %lu msec\n",
|
||||
(unsigned long)t->retrans_interval);
|
||||
} else {
|
||||
t->retrans_timer.timer.interval <<= 1; /* double */
|
||||
PRINTF("Doubled (%u) interval %f\n", t->retrans_counter,
|
||||
(float)t->retrans_timer.timer.interval / CLOCK_SECOND);
|
||||
t->retrans_interval <<= 1; /* double */
|
||||
LOG_DBG("Doubled (%u) interval %lu s\n", t->retrans_counter,
|
||||
(unsigned long)(t->retrans_interval / 1000));
|
||||
}
|
||||
|
||||
PROCESS_CONTEXT_BEGIN(transaction_handler_process);
|
||||
etimer_restart(&t->retrans_timer); /* interval updated above */
|
||||
PROCESS_CONTEXT_END(transaction_handler_process);
|
||||
|
||||
t = NULL;
|
||||
/* interval updated above */
|
||||
coap_timer_set(&t->retrans_timer, t->retrans_interval);
|
||||
} else {
|
||||
/* timed out */
|
||||
PRINTF("Timeout\n");
|
||||
restful_response_handler callback = t->callback;
|
||||
LOG_DBG("Timeout\n");
|
||||
coap_resource_response_handler_t callback = t->callback;
|
||||
void *callback_data = t->callback_data;
|
||||
|
||||
/* handle observers */
|
||||
coap_remove_observer_by_client(&t->addr, t->port);
|
||||
coap_remove_observer_by_client(&t->endpoint);
|
||||
|
||||
coap_clear_transaction(t);
|
||||
|
||||
|
@ -142,13 +146,14 @@ void
|
|||
coap_clear_transaction(coap_transaction_t *t)
|
||||
{
|
||||
if(t) {
|
||||
PRINTF("Freeing transaction %u: %p\n", t->mid, t);
|
||||
LOG_DBG("Freeing transaction %u: %p\n", t->mid, t);
|
||||
|
||||
etimer_stop(&t->retrans_timer);
|
||||
coap_timer_stop(&t->retrans_timer);
|
||||
list_remove(transactions_list, t);
|
||||
memb_free(&transactions_memb, t);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_transaction_t *
|
||||
coap_get_transaction_by_mid(uint16_t mid)
|
||||
{
|
||||
|
@ -156,24 +161,11 @@ coap_get_transaction_by_mid(uint16_t mid)
|
|||
|
||||
for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) {
|
||||
if(t->mid == mid) {
|
||||
PRINTF("Found transaction for MID %u: %p\n", t->mid, t);
|
||||
LOG_DBG("Found transaction for MID %u: %p\n", t->mid, t);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_check_transactions()
|
||||
{
|
||||
coap_transaction_t *t = NULL;
|
||||
|
||||
for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) {
|
||||
if(etimer_expired(&t->retrans_timer)) {
|
||||
++(t->retrans_counter);
|
||||
PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter);
|
||||
coap_send_transaction(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -36,45 +36,48 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_TRANSACTIONS_H_
|
||||
#define COAP_TRANSACTIONS_H_
|
||||
|
||||
#include "coap.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap-timer.h"
|
||||
|
||||
/*
|
||||
* Modulo mask (thus +1) for a random number to get the tick number for the random
|
||||
* retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR.
|
||||
*/
|
||||
#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT)
|
||||
#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK (long)((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * ((float)COAP_RESPONSE_RANDOM_FACTOR - 1.0)) + 0.5) + 1
|
||||
#define COAP_RESPONSE_TIMEOUT_TICKS (1000 * COAP_RESPONSE_TIMEOUT)
|
||||
#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK (uint32_t)(((1000 * COAP_RESPONSE_TIMEOUT * ((float)COAP_RESPONSE_RANDOM_FACTOR - 1.0)) + 0.5) + 1)
|
||||
|
||||
/* container for transactions with message buffer and retransmission info */
|
||||
typedef struct coap_transaction {
|
||||
struct coap_transaction *next; /* for LIST */
|
||||
|
||||
uint16_t mid;
|
||||
struct etimer retrans_timer;
|
||||
coap_timer_t retrans_timer;
|
||||
uint32_t retrans_interval;
|
||||
uint8_t retrans_counter;
|
||||
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
coap_endpoint_t endpoint;
|
||||
|
||||
restful_response_handler callback;
|
||||
coap_resource_response_handler_t callback;
|
||||
void *callback_data;
|
||||
|
||||
uint16_t packet_len;
|
||||
uint8_t packet[COAP_MAX_PACKET_SIZE + 1]; /* +1 for the terminating '\0' which will not be sent
|
||||
uint16_t message_len;
|
||||
uint8_t message[COAP_MAX_PACKET_SIZE + 1]; /* +1 for the terminating '\0' which will not be sent
|
||||
* Use snprintf(buf, len+1, "", ...) to completely fill payload */
|
||||
} coap_transaction_t;
|
||||
|
||||
void coap_register_as_transaction_handler(void);
|
||||
|
||||
coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr,
|
||||
uint16_t port);
|
||||
coap_transaction_t *coap_new_transaction(uint16_t mid, const coap_endpoint_t *ep);
|
||||
void coap_send_transaction(coap_transaction_t *t);
|
||||
void coap_clear_transaction(coap_transaction_t *t);
|
||||
coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid);
|
||||
|
||||
void coap_check_transactions(void);
|
||||
|
||||
#endif /* COAP_TRANSACTIONS_H_ */
|
||||
/** @} */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue