changes for coap18

This commit is contained in:
Harald Pichler 2014-12-31 09:53:24 +01:00
parent 2b8aeee115
commit d742fc4b76
2 changed files with 74 additions and 257 deletions

View file

@ -1,91 +1,58 @@
all: er-example-server \ all: er-example-server er-example-client
er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep # use target "er-plugtest-server" explicitly when requried
# use this target explicitly if requried: er-plugtest-server
# variable for this Makefile
# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08)
WITH_COAP=13
# for some platforms
UIP_CONF_IPV6=1
# IPv6 make config disappeared completely
CFLAGS += -DUIP_CONF_IPV6=1
CONTIKI=../../.. CONTIKI=../../..
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
PROJECT_SOURCEFILES += # automatically build RESTful resources
REST_RESOURCES_DIR = ./resources
# variable for Makefile.include ifndef TARGET
ifneq ($(TARGET), minimal-net) REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c'))
CFLAGS += -DUIP_CONF_IPV6_RPL=1
else else
# minimal-net does not support RPL under Linux and is mostly used to test CoAP only ifeq ($(TARGET), native)
${info INFO: compiling without RPL} REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c'))
CFLAGS += -DUIP_CONF_IPV6_RPL=0 else
CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c' ! -name 'res-plugtest*'))
${info INFO: compiling with large buffers}
CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048
CFLAGS += -DREST_MAX_CHUNK_SIZE=1024
CFLAGS += -DCOAP_MAX_HEADER_SIZE=640
endif endif
endif
PROJECTDIRS += $(REST_RESOURCES_DIR)
PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES)
# linker optimizations # linker optimizations
SMALL=1 SMALL=1
# REST framework, requires WITH_COAP # REST Engine shall use Erbium CoAP implementation
ifeq ($(WITH_COAP), 13) APPS += er-coap
${info INFO: compiling with CoAP-13} APPS += rest-engine
CFLAGS += -DWITH_COAP=13
CFLAGS += -DREST=coap_rest_implementation
CFLAGS += -DUIP_CONF_TCP=0
APPS += er-coap-13
else ifeq ($(WITH_COAP), 12)
${info INFO: compiling with CoAP-12}
CFLAGS += -DWITH_COAP=12
CFLAGS += -DREST=coap_rest_implementation
CFLAGS += -DUIP_CONF_TCP=0
APPS += er-coap-12
else ifeq ($(WITH_COAP), 7)
${info INFO: compiling with CoAP-08}
CFLAGS += -DWITH_COAP=7
CFLAGS += -DREST=coap_rest_implementation
CFLAGS += -DUIP_CONF_TCP=0
APPS += er-coap-07
else ifeq ($(WITH_COAP), 3)
${info INFO: compiling with CoAP-03}
CFLAGS += -DWITH_COAP=3
CFLAGS += -DREST=coap_rest_implementation
CFLAGS += -DUIP_CONF_TCP=0
APPS += er-coap-03
else
${info INFO: compiling with HTTP}
CFLAGS += -DWITH_HTTP
CFLAGS += -DREST=http_rest_implementation
CFLAGS += -DUIP_CONF_TCP=1
APPS += er-http-engine
endif
APPS += erbium time json json-resource # optional rules to get assembly
#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1
#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1
CONTIKI_WITH_IPV6 = 1
include $(CONTIKI)/Makefile.include include $(CONTIKI)/Makefile.include
er-example-server.osd-merkur.hex: er-example-server.osd-merkur # minimal-net target is currently broken in Contiki
avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur \ ifeq ($(TARGET), minimal-net)
er-example-server.osd-merkur.hex CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\"
${info INFO: er-example compiling with large buffers}
CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300
CFLAGS += -DREST_MAX_CHUNK_SIZE=1024
CFLAGS += -DCOAP_MAX_HEADER_SIZE=176
CONTIKI_WITH_RPL=0
endif
er-example-server.osd-merkur.eep: er-example-server.osd-merkur # optional rules to get assembly
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ #$(OBJECTDIR)/%.o: asmdir/%.S
--change-section-lma .eeprom=0 -O ihex \ # $(CC) $(CFLAGS) -MMD -c $< -o $@
er-example-server.osd-merkur er-example-server.osd-merkur.eep # @$(FINALIZE_DEPENDENCY)
#
flash: er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep #asmdir/%.S: %.c
avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ # $(CC) $(CFLAGS) -MMD -S $< -o $@
flash:w:er-example-server.osd-merkur.hex:a -U \
eeprom:w:er-example-server.osd-merkur.eep:a
.PHONY: flash
# border router rules
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
(cd $(CONTIKI)/tools && $(MAKE) tunslip6) (cd $(CONTIKI)/tools && $(MAKE) tunslip6)
@ -93,7 +60,10 @@ connect-router: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64
connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-router-cooja: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64
connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native
sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64
connect-minimal: connect-minimal:
sudo ip address add fdfd::1/64 dev tap0 sudo ip address add fdfd::1/64 dev tap0

View file

@ -42,191 +42,44 @@
#include <string.h> #include <string.h>
#include "contiki.h" #include "contiki.h"
#include "contiki-net.h" #include "contiki-net.h"
#include "er-coap-engine.h"
#include "time.h" #include "time.h"
#include "time_resource.h" #include "time_resource.h"
#include "jsonparse.h" #include "jsonparse.h"
/* Define which resources to include to meet memory constraints. */ #if PLATFORM_HAS_BUTTON
#define REST_RES_INFO 1
#define REST_RES_LEDS 1
#define REST_RES_TOGGLE 0
#define REST_RES_BATTERY 1
#include "erbium.h"
#if defined (PLATFORM_HAS_BUTTON)
#include "dev/button-sensor.h" #include "dev/button-sensor.h"
#endif #endif
#if defined (PLATFORM_HAS_LEDS)
#include "dev/leds.h"
#endif
#if defined (PLATFORM_HAS_BATTERY)
#include "dev/battery-sensor.h"
#endif
#define DEBUG 0
/* For CoAP-specific example: not required for normal RESTful Web service. */
#if WITH_COAP == 3
#include "er-coap-03.h"
#elif WITH_COAP == 7
#include "er-coap-07.h"
#elif WITH_COAP == 12
#include "er-coap-12.h"
#elif WITH_COAP == 13
#include "er-coap-13.h"
#else
#warning "Erbium example without CoAP-specifc functionality"
#endif /* CoAP-specific example */
#define DEBUG 1
#if DEBUG #if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__) #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 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]) #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 #else
#define PRINTF(...) #define PRINTF(...)
#define PRINT6ADDR(addr) #define PRINT6ADDR(addr)
#define PRINTLLADDR(addr) #define PRINTLLADDR(addr)
#endif #endif
/******************************************************************************/ #if PLATFORM_HAS_LEDS
#include "dev/leds.h"
extern resource_t res_leds, res_toggle;
#endif
#if REST_RES_INFO #if PLATFORM_HAS_BATTERY
#include "dev/battery-sensor.h"
extern resource_t res_battery;
#endif
/* /*
* Resources are defined by the RESOURCE macro. #if PLATFORM_HAS_RADIO
* Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). #include "dev/radio-sensor.h"
*/ extern resource_t res_radio;
RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\"");
/*
* A handler function named [resource name]_handler must be implemented for each RESOURCE.
* A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore
* preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer.
* If a smaller block size is requested for CoAP, the REST framework automatically splits the data.
*/
void
info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
char message[100];
int index = 0;
int length = 0; /* |<-------->| */
/* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */
// jSON Format
index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre1\",\n");
index += sprintf(message + index," \"name\" : \"Wallclock-time\"\n");
index += sprintf(message + index,"}\n");
length = strlen(message);
memcpy(buffer, message,length );
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
REST.set_response_payload(response, buffer, length);
}
#endif #endif
*/
/******************************************************************************/ //******************************************************************************/
#if defined (PLATFORM_HAS_LEDS)
/******************************************************************************/
#if REST_RES_LEDS
/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/
RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"");
void
leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
size_t len = 0;
const char *color = NULL;
const char *mode = NULL;
uint8_t led = 0;
int success = 1;
if ((len=REST.get_query_variable(request, "color", &color))) {
PRINTF("color %.*s\n", len, color);
if (strncmp(color, "r", len)==0) {
led = LEDS_RED;
} else if(strncmp(color,"g", len)==0) {
led = LEDS_GREEN;
} else if (strncmp(color,"b", len)==0) {
led = LEDS_BLUE;
} else {
success = 0;
}
} else {
success = 0;
}
if (success && (len=REST.get_post_variable(request, "mode", &mode))) {
PRINTF("mode %s\n", mode);
if (strncmp(mode, "on", len)==0) {
leds_on(led);
} else if (strncmp(mode, "off", len)==0) {
leds_off(led);
} else {
success = 0;
}
} else {
success = 0;
}
if (!success) {
REST.set_response_status(response, REST.status.BAD_REQUEST);
}
}
#endif
/******************************************************************************/
#if REST_RES_TOGGLE
/* A simple actuator example. Toggles the red led */
RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\"");
void
toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
leds_toggle(LEDS_RED);
}
#endif
#endif /* PLATFORM_HAS_LEDS */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY)
/* A simple getter example. Returns the reading from light sensor with a simple etag */
RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\"");
void
battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
int battery = battery_sensor.value(0);
const uint16_t *accept = NULL;
int num = REST.get_header_accept(request, &accept);
if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN))
{
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery);
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
}
else if (num && (accept[0]==REST.type.APPLICATION_JSON))
{
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery);
REST.set_response_payload(response, buffer, strlen((char *)buffer));
}
else
{
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
const char *msg = "Supporting content-types text/plain and application/json";
REST.set_response_payload(response, msg, strlen(msg));
}
}
#endif /* PLATFORM_HAS_BATTERY */
/******************************************************************************/
void void
hw_init() hw_init()
@ -269,24 +122,18 @@ PROCESS_THREAD(rest_server_example, ev, data)
rest_init_engine(); rest_init_engine();
/* Activate the application-specific resources. */ /* Activate the application-specific resources. */
#if REST_RES_INFO rest_activate_resource(&res_info);
rest_activate_resource(&resource_info); rest_activate_resource(&res_leds, "s/leds");
#endif
#if defined (PLATFORM_HAS_LEDS)
#if REST_RES_LEDS
rest_activate_resource(&resource_leds);
#endif
#if REST_RES_TOGGLE
rest_activate_resource(&resource_toggle);
#endif
#endif /* PLATFORM_HAS_LEDS */
#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY
SENSORS_ACTIVATE(battery_sensor); SENSORS_ACTIVATE(battery_sensor);
rest_activate_resource(&resource_battery); rest_activate_resource(&res_battery, "s/battery");
#endif #endif
rest_activate_resource(&resource_timestamp);
rest_activate_resource(&resource_localtime); rest_activate_resource(&res_timestamp, "s/timestamp");
rest_activate_resource(&resource_utc); rest_activate_resource(&res_localtime, "localtime");
rest_activate_resource(&res_utc, "utc");
/* Define application-specific events here. */ /* Define application-specific events here. */
while(1) { while(1) {