diff --git a/apps/json-resource/generic_resource.c b/apps/json-resource/generic_resource.c index 9ac8ac93b..0a333eddc 100644 --- a/apps/json-resource/generic_resource.c +++ b/apps/json-resource/generic_resource.c @@ -105,6 +105,20 @@ json_parse_variable return 0; } +static const char *get_uri (void *request) +{ + static char buf [MAX_URI_STRING_LENGTH]; + const char *uri; + size_t len = coap_get_header_uri_path (request, &uri); + if (len > sizeof (buf) - 1) { + *buf = '\0'; + } else { + strncpy (buf, uri, len); + buf [len] = '\0'; + } + return buf; +} + void generic_get_handler ( void *request , void *response @@ -112,13 +126,15 @@ void generic_get_handler , uint16_t preferred_size , int32_t *offset , char *name - , size_t (*to_str)(const char *name, uint8_t is_json, char *buf, size_t bsize) + , int is_str + , size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize) ) { int success = 1; - char temp [100]; + char temp [MAX_GET_STRING_LENGTH]; size_t len = 0; unsigned int accept = -1; + const char *uri = get_uri (request); REST.get_header_accept (request, &accept); if ( accept != -1 @@ -127,30 +143,40 @@ void generic_get_handler ) { success = 0; - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_status (response, REST.status.NOT_ACCEPTABLE); return; } // TEXT format if (accept == REST.type.APPLICATION_JSON) { len += snprintf - (temp + len, sizeof (temp) - len, "{\n \"%s\" : ", name); + ( temp + len + , sizeof (temp) - len + , "{\n \"%s\" : %s" + , name + , is_str ? "\"" : "" + ); if (len > sizeof (temp)) { success = 0; goto out; } - len += to_str (name, 1, temp + len, sizeof (temp) - len); + len += to_str (name, uri, temp + len, sizeof (temp) - len); if (len > sizeof (temp)) { success = 0; goto out; } - len += snprintf (temp + len, sizeof (temp) - len, "\n}\n"); + len += snprintf + ( temp + len + , sizeof (temp) - len + , "%s\n}\n" + , is_str ? "\"" : "" + ); if (len > sizeof (temp)) { success = 0; goto out; } } else { // TEXT Format - len += to_str (name, 0, temp + len, sizeof (temp) - len); + len += to_str (name, uri, temp + len, sizeof (temp) - len); if (len > sizeof (temp)) { success = 0; goto out; @@ -166,7 +192,7 @@ void generic_get_handler REST.set_response_payload (response, buffer, len); out : if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); + REST.set_response_status (response, REST.status.BAD_REQUEST); } } @@ -177,7 +203,7 @@ void generic_put_handler , uint16_t preferred_size , int32_t *offset , char *name - , void (*from_str)(const char *name, const char *s) + , int (*from_str)(const char *name, const char *uri, const char *s) ) { int success = 1; @@ -185,9 +211,10 @@ void generic_put_handler size_t len = 0; const uint8_t *bytes = NULL; uint16_t c_ctype; + const char *uri = get_uri (request); REST.get_header_content_type (request, &c_ctype); - if (from_str && (len = coap_get_payload(request, &bytes))) { + if (from_str && (len = coap_get_payload (request, &bytes))) { if (c_ctype == REST.type.TEXT_PLAIN) { int l = MIN (len, sizeof (temp) - 1); temp [sizeof (temp) - 1] = 0; @@ -199,14 +226,17 @@ void generic_put_handler goto out; } } - from_str (name, temp); - REST.set_response_status(response, REST.status.CHANGED); + if (from_str (name, uri, temp) < 0) { + success = 0; + } else { + REST.set_response_status (response, REST.status.CHANGED); + } } else { success = 0; } out: if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); + REST.set_response_status (response, REST.status.BAD_REQUEST); } } diff --git a/apps/json-resource/generic_resource.h b/apps/json-resource/generic_resource.h index 245beb1cd..2c0e6ca05 100644 --- a/apps/json-resource/generic_resource.h +++ b/apps/json-resource/generic_resource.h @@ -50,6 +50,9 @@ #define STR__(s) #s #define STR_(s) STR__(s) +#define MAX_GET_STRING_LENGTH 100 +#define MAX_URI_STRING_LENGTH 30 + /* * A macro that extends the resource definition and also sets up the * necessary handler function that calls format/parse routines that @@ -60,7 +63,7 @@ * Yes, this *is* a hack. But I hate boilerplate code. */ -#define GENERIC_RESOURCE(name, title, unit, fs, ts) \ +#define GENERIC_RESOURCE(name, title, unit, is_str, fs, ts) \ static void name##_get_handler \ ( void *request \ , void *response \ @@ -70,7 +73,7 @@ ) \ { \ generic_get_handler \ - (request, response, buffer, ps, offset, STR_(name), ts); \ + (request, response, buffer, ps, offset, STR_(name), is_str, ts); \ } \ static void name##_put_handler \ ( void *request \ @@ -134,7 +137,8 @@ extern void generic_get_handler , uint16_t preferred_size , int32_t *offset , char *name - , size_t (*to_str)(const char *name, uint8_t is_json, char *buf, size_t bsize) + , int is_str + , size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize) ); /** @@ -157,7 +161,7 @@ extern void generic_put_handler , uint16_t preferred_size , int32_t *offset , char *name - , void (*from_str)(const char *name, const char *s) + , int (*from_str)(const char *name, const char *uri, const char *s) ); /* diff --git a/apps/time/resource_gmtime.c b/apps/time/resource_gmtime.c index b56d6a0c5..16ba6db02 100644 --- a/apps/time/resource_gmtime.c +++ b/apps/time/resource_gmtime.c @@ -17,7 +17,7 @@ #include "er-coap.h" #include "generic_resource.h" -size_t time_to_string (const char *name, uint8_t is_json, char *buf, size_t bs) +size_t time_to_string (const char *name, const char *uri, char *buf, size_t bs) { struct timeval tv; struct tm tm; @@ -30,12 +30,10 @@ size_t time_to_string (const char *name, uint8_t is_json, char *buf, size_t bs) return snprintf ( buf , bs - , "%s%lu-%02u-%02u %02u:%02u:%02u %s%s" - , is_json ? "\"" : "" + , "%lu-%02u-%02u %02u:%02u:%02u %s" , 1900 + tm.tm_year , tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec , tm.tm_zone - , is_json ? "\"" : "" ); } @@ -43,6 +41,7 @@ GENERIC_RESOURCE \ ( localtime , Local time , formatted time + , 1 , NULL , time_to_string ); @@ -51,6 +50,7 @@ GENERIC_RESOURCE \ ( utc , UTC , formatted time + , 1 , NULL , time_to_string ); diff --git a/apps/time/resource_timestamp.c b/apps/time/resource_timestamp.c index 6616569e8..2406bfea9 100644 --- a/apps/time/resource_timestamp.c +++ b/apps/time/resource_timestamp.c @@ -21,32 +21,30 @@ #include "er-coap.h" #include "generic_resource.h" -void timestamp_from_string (const char *name, const char *s) +int timestamp_from_string (const char *name, const char *uri, const char *s) { struct timeval tv; // FIXME: Platform has no strtoll (long long)? tv.tv_sec = strtol (s, NULL, 10); settimeofday (&tv, NULL); + return 0; } size_t -timestamp_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +timestamp_to_string (const char *name, const char *uri, char *buf, size_t bsize) { struct timeval tv; - char *fmt = "%ld"; - if (is_json) { - fmt = "\"%ld\""; - } gettimeofday (&tv, NULL); // FIXME: Platform doesn't seem to support long long printing // We get empty string - return snprintf (buf, bsize, fmt, (long)tv.tv_sec); + return snprintf (buf, bsize, "%ld", (long)tv.tv_sec); } GENERIC_RESOURCE ( timestamp , Time , s + , 1 , timestamp_from_string , timestamp_to_string ); diff --git a/apps/time/resource_timezone.c b/apps/time/resource_timezone.c index d24807e17..2937a3de3 100644 --- a/apps/time/resource_timezone.c +++ b/apps/time/resource_timezone.c @@ -17,13 +17,14 @@ #include "er-coap.h" #include "generic_resource.h" -void timezone_from_string (const char *name, const char *s) +int timezone_from_string (const char *name, const char *uri, const char *s) { set_tz (s); + return 0; } size_t -timezone_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +timezone_to_string (const char *name, const char *uri, char *buf, size_t bsize) { if (get_tz (buf, bsize) == NULL) { *buf = '\0'; @@ -35,6 +36,7 @@ GENERIC_RESOURCE ( timezone , TZ , s + , 1 , timezone_from_string , timezone_to_string ); diff --git a/examples/osd/arduino-ledstrip/sketch.pde b/examples/osd/arduino-ledstrip/sketch.pde index 451c7c41e..cd8f8d42d 100644 --- a/examples/osd/arduino-ledstrip/sketch.pde +++ b/examples/osd/arduino-ledstrip/sketch.pde @@ -46,27 +46,25 @@ static uint8_t name_to_offset (const char * name) } static size_t -color_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +color_to_string (const char *name, const char *uri, char *buf, size_t bsize) { - char *fmt = "%d"; - if (is_json) { - fmt = "\"%d\""; - } - return snprintf (buf, bsize, fmt, color_rgb [name_to_offset (name)]); + return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]); } -void color_from_string (const char *name, const char *s) +int color_from_string (const char *name, const char *uri, const char *s) { color_rgb [name_to_offset (name)] = atoi (s); Driver.begin(); Driver.SetColor(color_rgb [0], color_rgb [1], color_rgb [2]); Driver.end(); + return 0; } GENERIC_RESOURCE ( red , RED_LED , s + , 1 , color_from_string , color_to_string ); @@ -75,6 +73,7 @@ GENERIC_RESOURCE ( green , GREEN_LED , s + , 1 , color_from_string , color_to_string ); @@ -83,6 +82,7 @@ GENERIC_RESOURCE ( blue , BLUE_LED , s + , 1 , color_from_string , color_to_string ); @@ -136,4 +136,3 @@ void loop (void) } */ } - diff --git a/examples/osd/arduino-sketch/resource_led_pwm.c b/examples/osd/arduino-sketch/resource_led_pwm.c index 751e9e192..2dbfa0611 100644 --- a/examples/osd/arduino-sketch/resource_led_pwm.c +++ b/examples/osd/arduino-sketch/resource_led_pwm.c @@ -17,17 +17,18 @@ #include "generic_resource.h" #include "led_pwm.h" -void pwm_from_string (const char *name, const char *s) +int pwm_from_string (const char *name, const char *uri, const char *s) { uint32_t tmp = strtoul (s, NULL, 10); if (tmp > 255) { tmp = 255; } pwm = tmp; + return 0; } size_t -pwm_to_string (const char *name, uint8_t is_json, char *buf, size_t bufsize) +pwm_to_string (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d", pwm); } @@ -36,11 +37,12 @@ GENERIC_RESOURCE \ ( led_pwm , LED PWM , duty-cycle + , 0 , pwm_from_string , pwm_to_string ); -void period_from_string (const char *name, const char *s) +int period_from_string (const char *name, const char *uri, const char *s) { uint32_t tmp = (strtoul (s, NULL, 10) + 50) / 100; if (tmp > 10) { @@ -50,10 +52,11 @@ void period_from_string (const char *name, const char *s) tmp = 1; } period_100ms = tmp; + return 0; } size_t -period_to_string (const char *name, uint8_t is_json, char *buf, size_t bufsize) +period_to_string (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d", period_100ms * 100); } @@ -62,12 +65,13 @@ GENERIC_RESOURCE \ ( led_period , LED Period , ms + , 0 , period_from_string , period_to_string ); size_t -analog2_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) +analog2_v (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d.%03d", analog2_voltage / 1000, analog2_voltage % 1000); @@ -77,12 +81,13 @@ GENERIC_RESOURCE \ ( analog2_voltage , Analog 2 voltage , V + , 0 , NULL , analog2_v ); size_t -analog5_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) +analog5_v (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d.%03d", analog5_voltage / 1000, analog5_voltage % 1000); @@ -92,6 +97,7 @@ GENERIC_RESOURCE \ ( analog5_voltage , Analog 5 voltage , V + , 0 , NULL , analog5_v ); diff --git a/examples/osd/led-strip/led-strip.c b/examples/osd/led-strip/led-strip.c index a16edc0ed..d691a91a5 100644 --- a/examples/osd/led-strip/led-strip.c +++ b/examples/osd/led-strip/led-strip.c @@ -77,16 +77,12 @@ static uint8_t name_to_offset (const char * name) } static size_t -color_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +color_to_string (const char *name, const char *uri, char *buf, size_t bsize) { - char *fmt = "%d"; - if (is_json) { - fmt = "\"%d\""; - } - return snprintf (buf, bsize, fmt, color_rgb [name_to_offset (name)]); + return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]); } -void color_from_string (const char *name, const char *s) +int color_from_string (const char *name, const char *uri, const char *s) { color_rgb [name_to_offset (name)] = atoi (s); led_strip_begin (); @@ -95,12 +91,14 @@ void color_from_string (const char *name, const char *s) printf ("Set to R:%d G:%d B:%d\n" , color_rgb [0], color_rgb [1], color_rgb [2]) ; + return 0; } GENERIC_RESOURCE ( red , RED_LED , s + , 1 , color_from_string , color_to_string ); @@ -109,6 +107,7 @@ GENERIC_RESOURCE ( green , GREEN_LED , s + , 1 , color_from_string , color_to_string ); @@ -117,6 +116,7 @@ GENERIC_RESOURCE ( blue , BLUE_LED , s + , 1 , color_from_string , color_to_string ); diff --git a/examples/osd/poti/poti.c b/examples/osd/poti/poti.c index dbe98d510..2e7c82143 100644 --- a/examples/osd/poti/poti.c +++ b/examples/osd/poti/poti.c @@ -77,74 +77,73 @@ char server_resource [20] = "led/G"; int interval = 10; /* Retransmit interval after no change in value */ static size_t -ip_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +ip_to_string (const char *name, const char *uri, char *buf, size_t bsize) { #define IP(x) UIP_NTOHS(server_ipaddr.u16[x]) - char *q = "\""; - if (!is_json) { - q = ""; - } return snprintf - ( buf, bsize, "%s%x:%x:%x:%x:%x:%x:%x:%x%s" - , q, IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7), q + ( buf, bsize, "%x:%x:%x:%x:%x:%x:%x:%x" + , IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7) ); } -void ip_from_string (const char *name, const char *s) +int ip_from_string (const char *name, const char *uri, const char *s) { /* Returns 1 if successful, only copy valid address */ if (uiplib_ip6addrconv (s, &tmp_addr)) { uip_ip6addr_copy (&server_ipaddr, &tmp_addr); + return 0; } + return -1; } GENERIC_RESOURCE ( server_ip , ip , ipv6_address + , 1 , ip_from_string , ip_to_string ); static size_t -resource_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +resource_to_string (const char *name, const char *uri, char *buf, size_t bsize) { - char *q = "\""; - if (!is_json) { - q = ""; - } - return snprintf (buf, bsize, "%s%s%s", q, server_resource, q); + return snprintf (buf, bsize, "%s", server_resource); } -void resource_from_string (const char *name, const char *s) +int resource_from_string (const char *name, const char *uri, const char *s) { strncpy (server_resource, s, sizeof (server_resource)); server_resource [sizeof (server_resource) - 1] = 0; + return 0; } GENERIC_RESOURCE ( server_resource , led-resource , resource-name + , 1 , resource_from_string , resource_to_string ); static size_t -interval_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +interval_to_string (const char *name, const char *uri, char *buf, size_t bsize) { return snprintf (buf, bsize, "%d", interval); } -void interval_from_string (const char *name, const char *s) +int interval_from_string (const char *name, const char *uri, const char *s) { interval = atoi (s); + return 0; } GENERIC_RESOURCE ( interval , interval , s + , 0 , interval_from_string , interval_to_string );