Add query parameter to generic resouce macros

Modify all callback functions to use new signature.
ota-update now uses this to pass the partition to some get/put methods.
This commit is contained in:
Ralf Schlatterbeck 2017-08-20 15:01:30 +02:00
parent 954da749eb
commit e3784fa9c7
20 changed files with 357 additions and 82 deletions

View file

@ -119,6 +119,20 @@ static const char *get_uri (void *request)
return buf;
}
static const char *get_query (void *request)
{
static char buf [MAX_QUERY_STRING_LENGTH];
const char *query;
size_t len = coap_get_header_uri_query (request, &query);
if (len > sizeof (buf) - 1) {
*buf = '\0';
} else {
strncpy (buf, query, len);
buf [len] = '\0';
}
return buf;
}
void generic_get_handler
( void *request
, void *response
@ -127,7 +141,12 @@ void generic_get_handler
, int32_t *offset
, char *name
, int is_str
, size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize)
, size_t (*to_str)
( const char *name
, const char *uri
, const char *query
, char *buf, size_t bsize
)
)
{
int success = 1;
@ -135,6 +154,7 @@ void generic_get_handler
size_t len = 0;
unsigned int accept = -1;
const char *uri = get_uri (request);
const char *query = get_query (request);
REST.get_header_accept (request, &accept);
if ( accept != -1
@ -160,7 +180,7 @@ void generic_get_handler
success = 0;
goto out;
}
len += to_str (name, uri, temp + len, sizeof (temp) - len);
len += to_str (name, uri, query, temp + len, sizeof (temp) - len);
if (len > sizeof (temp)) {
success = 0;
goto out;
@ -176,7 +196,7 @@ void generic_get_handler
goto out;
}
} else { // TEXT Format
len += to_str (name, uri, temp + len, sizeof (temp) - len);
len += to_str (name, uri, query, temp + len, sizeof (temp) - len);
if (len > sizeof (temp)) {
success = 0;
goto out;
@ -203,7 +223,8 @@ void generic_put_handler
, uint16_t preferred_size
, int32_t *offset
, char *name
, int (*from_str)(const char *name, const char *uri, const char *s)
, int (*from_str)
(const char *name, const char *uri, const char *query, const char *s)
)
{
int success = 1;
@ -212,6 +233,7 @@ void generic_put_handler
const uint8_t *bytes = NULL;
unsigned int c_ctype;
const char *uri = get_uri (request);
const char *query = get_query (request);
REST.get_header_content_type (request, &c_ctype);
if (from_str && (len = coap_get_payload (request, &bytes))) {
@ -226,7 +248,7 @@ void generic_put_handler
goto out;
}
}
if (from_str (name, uri, temp) < 0) {
if (from_str (name, uri, query, temp) < 0) {
success = 0;
} else {
REST.set_response_status (response, REST.status.CHANGED);

View file

@ -52,6 +52,7 @@
#define MAX_GET_STRING_LENGTH 100
#define MAX_URI_STRING_LENGTH 30
#define MAX_QUERY_STRING_LENGTH 30
/*
* A macro that extends the resource definition and also sets up the
@ -124,11 +125,8 @@ extern int8_t json_parse_variable
*
* The callback functions get the name of the parameter as a first
* argument, this allows to re-use the same function for different
* parameters.
* For the to_str function the is_json flag allows to generate a
* different string depending on the content-type. In addition it gets a
* buffer and the size of the buffer. It needs to return the number of
* bytes output, similar to sprintf.
* parameters. In addition it gets a buffer and the size of the buffer.
* It needs to return the number of bytes output, similar to sprintf.
*/
extern void generic_get_handler
( void *request
@ -138,7 +136,13 @@ extern void generic_get_handler
, int32_t *offset
, char *name
, int is_str
, size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize)
, size_t (*to_str)
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
);
/**
@ -161,7 +165,8 @@ extern void generic_put_handler
, uint16_t preferred_size
, int32_t *offset
, char *name
, int (*from_str)(const char *name, const char *uri, const char *s)
, int (*from_str)
(const char *name, const char *uri, const char *query, const char *s)
);
/*

View file

@ -35,7 +35,8 @@ static size_t get_index_from_uri (const char *uri)
return idx;
}
int crontab_from_string (const char *name, const char *uri, const char *s)
int crontab_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
const char *err;
int res;
@ -52,7 +53,13 @@ int crontab_from_string (const char *name, const char *uri, const char *s)
}
size_t
crontab_to_string (const char *name, const char *uri, char *buf, size_t bsize)
crontab_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
/* FIXME: For now we only return "valid" or "invalid" until someone
* comes up with a clever algorithm to reconstruct a crontab string

View file

@ -17,7 +17,8 @@
#include "er-coap.h"
#include "generic_resource.h"
size_t time_to_string (const char *name, const char *uri, char *buf, size_t bs)
size_t time_to_string
(const char *name, const char *uri, const char *query, char *buf, size_t bs)
{
struct xtimeval tv;
struct xtm tm;

View file

@ -21,7 +21,8 @@
#include "er-coap.h"
#include "generic_resource.h"
int timestamp_from_string (const char *name, const char *uri, const char *s)
int timestamp_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
struct xtimeval tv;
// FIXME: Platform has no strtoll (long long)?
@ -31,7 +32,13 @@ int timestamp_from_string (const char *name, const char *uri, const char *s)
}
size_t
timestamp_to_string (const char *name, const char *uri, char *buf, size_t bsize)
timestamp_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
struct xtimeval tv;
xgettimeofday (&tv, NULL);

View file

@ -17,14 +17,21 @@
#include "er-coap.h"
#include "generic_resource.h"
int timezone_from_string (const char *name, const char *uri, const char *s)
int timezone_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
set_tz (s);
return 0;
}
size_t
timezone_to_string (const char *name, const char *uri, char *buf, size_t bsize)
timezone_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
if (get_tz (buf, bsize) == NULL) {
*buf = '\0';

View file

@ -46,12 +46,19 @@ static uint8_t name_to_offset (const char * name)
}
static size_t
color_to_string (const char *name, const char *uri, char *buf, size_t bsize)
color_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]);
}
int color_from_string (const char *name, const char *uri, const char *s)
int color_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
color_rgb [name_to_offset (name)] = atoi (s);
Driver.begin();
@ -97,9 +104,9 @@ void setup (void)
NETSTACK_MAC.off(1);
rest_activate_resource (&res_red, "led/R");
rest_activate_resource (&res_green, "led/G");
rest_activate_resource (&res_blue, "led/B");
rest_activate_resource (&res_red, (char *)"led/R");
rest_activate_resource (&res_green, (char *)"led/G");
rest_activate_resource (&res_blue, (char *)"led/B");
Driver.begin();
Driver.SetColor(color_rgb [0], color_rgb [1], color_rgb [2]);

View file

@ -17,7 +17,8 @@
#include "generic_resource.h"
#include "led_pwm.h"
int pwm_from_string (const char *name, const char *uri, const char *s)
int pwm_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
if (tmp > 255) {
@ -28,7 +29,13 @@ int pwm_from_string (const char *name, const char *uri, const char *s)
}
size_t
pwm_to_string (const char *name, const char *uri, char *buf, size_t bufsize)
pwm_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf (buf, bufsize, "%d", pwm);
}
@ -42,7 +49,8 @@ GENERIC_RESOURCE \
, pwm_to_string
);
int period_from_string (const char *name, const char *uri, const char *s)
int period_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = (strtoul (s, NULL, 10) + 50) / 100;
if (tmp > 10) {
@ -56,7 +64,13 @@ int period_from_string (const char *name, const char *uri, const char *s)
}
size_t
period_to_string (const char *name, const char *uri, char *buf, size_t bufsize)
period_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf (buf, bufsize, "%d", period_100ms * 100);
}
@ -71,7 +85,13 @@ GENERIC_RESOURCE \
);
size_t
analog2_v (const char *name, const char *uri, char *buf, size_t bufsize)
analog2_v
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf
(buf, bufsize, "%d.%03d", analog2_voltage / 1000, analog2_voltage % 1000);
@ -87,7 +107,13 @@ GENERIC_RESOURCE \
);
size_t
analog5_v (const char *name, const char *uri, char *buf, size_t bufsize)
analog5_v
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf
(buf, bufsize, "%d.%03d", analog5_voltage / 1000, analog5_voltage % 1000);

View file

@ -25,10 +25,10 @@ void setup (void)
{
arduino_pwm_timer_init ();
rest_init_engine ();
rest_activate_resource (&res_led_pwm, "led/pwm");
rest_activate_resource (&res_led_period, "led/period");
rest_activate_resource (&res_analog2_voltage, "analog/2");
rest_activate_resource (&res_analog5_voltage, "analog/5");
rest_activate_resource (&res_led_pwm, (char *)"led/pwm");
rest_activate_resource (&res_led_period, (char *)"led/period");
rest_activate_resource (&res_analog2_voltage, (char *)"analog/2");
rest_activate_resource (&res_analog5_voltage, (char *)"analog/5");
}
void loop (void)
@ -37,7 +37,7 @@ void loop (void)
analogWrite (LED_PIN, 255 - pwm);
analog2_voltage = analogRead (A2) * 1600L / 1023L;
analog5_voltage = analogRead (A5) * 1600L / 1023L;
printf ("clock : %u\nmillis: %lu\n", clock_time (), millis ());
printf ("clock : %lu\nmillis: %lu\n", clock_time (), millis ());
delay (period_100ms * 100);
analogWrite (LED_PIN, 255); /* OFF: LED on merkur-board is wired to +3.3V */
delay (period_100ms * 100);

View file

@ -20,7 +20,8 @@
uint8_t valve;
int valve_from_string (const char *name, const char *uri, const char *s)
int valve_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
if (tmp) {
@ -49,7 +50,13 @@ int valve_from_string (const char *name, const char *uri, const char *s)
}
size_t
valve_to_string (const char *name, const char *uri, char *buf, size_t bufsize)
valve_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf (buf, bufsize, "%d", valve);
}

View file

@ -25,7 +25,7 @@ void setup (void)
digitalWrite (BRIDGE2_PIN, LOW);
rest_init_engine ();
rest_activate_resource (&res_valve, "valve");
rest_activate_resource (&res_valve, (char *)"valve");
}
void loop (void)

View file

@ -81,7 +81,13 @@ uint8_t led_status;
static size_t
ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
ip_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
#define IP(x) UIP_NTOHS(server_ipaddr.u16[x])
return snprintf
@ -90,7 +96,8 @@ ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
);
}
int ip_from_string (const char *name, const char *uri, const char *s)
int ip_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
/* Returns 1 if successful, only copy valid address */
if (uiplib_ip6addrconv (s, &tmp_addr)) {
@ -110,12 +117,19 @@ GENERIC_RESOURCE
);
static size_t
resource_to_string (const char *name, const char *uri, char *buf, size_t bsize)
resource_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%s", server_resource);
}
int resource_from_string (const char *name, const char *uri, const char *s)
int resource_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
strncpy (server_resource, s, sizeof (server_resource));
server_resource [sizeof (server_resource) - 1] = 0;
@ -132,12 +146,19 @@ GENERIC_RESOURCE
);
static size_t
interval_to_string (const char *name, const char *uri, char *buf, size_t bsize)
interval_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%d", interval);
}
int interval_from_string (const char *name, const char *uri, const char *s)
int interval_from_string
( const char *name, const char *uri, const char *query, const char *s)
{
interval = atoi (s);
return 0;

View file

@ -5,8 +5,15 @@
extern "C" {
#endif
size_t color_to_string (const char *name, const char *uri, char *buf, size_t bsize);
int color_from_string (const char *name, const char *uri, const char *s);
size_t color_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
);
int color_from_string
(const char *name, const char *uri, const char *query, const char *s);
int color_rgb_from_string (const char *r, const char *g, const char *b);
#ifdef __cplusplus

View file

@ -68,13 +68,20 @@ name_to_offset (const char * name)
}
extern "C" size_t
color_to_string (const char *name, const char *uri, char *buf, size_t bsize)
color_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]);
}
extern "C" int
color_from_string (const char *name, const char *uri, const char *s)
color_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
color_rgb [name_to_offset (name)] = atoi (s);
leds.setColorRGB(0,color_rgb [0], color_rgb [1], color_rgb [2]);
@ -93,7 +100,13 @@ color_rgb_from_string (const char *r, const char *g, const char *b)
}
static size_t
ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
ip_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
#define IP(x) UIP_NTOHS(server_ipaddr.u16[x])
return snprintf
@ -102,7 +115,8 @@ ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
);
}
int ip_from_string (const char *name, const char *uri, const char *s)
int ip_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
/* Returns 1 if successful, only copy valid address */
if (uiplib_ip6addrconv (s, &tmp_addr)) {

View file

@ -5,8 +5,15 @@
extern "C" {
#endif
size_t color_to_string (const char *name, const char *uri, char *buf, size_t bsize);
int color_from_string (const char *name, const char *uri, const char *s);
size_t color_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
);
int color_from_string
(const char *name, const char *uri, const char *query, const char *s);
int color_rgb_from_string (const char *r, const char *g, const char *b);
#ifdef __cplusplus

View file

@ -70,13 +70,20 @@ name_to_offset (const char * name)
}
extern "C" size_t
color_to_string (const char *name, const char *uri, char *buf, size_t bsize)
color_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]);
}
extern "C" int
color_from_string (const char *name, const char *uri, const char *s)
color_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
color_rgb [name_to_offset (name)] = atoi (s);
leds.setColorRGB(0,color_rgb [0], color_rgb [1], color_rgb [2]);
@ -95,7 +102,13 @@ color_rgb_from_string (const char *r, const char *g, const char *b)
}
static size_t
ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
ip_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
#define IP(x) UIP_NTOHS(server_ipaddr.u16[x])
return snprintf
@ -104,7 +117,8 @@ ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
);
}
int ip_from_string (const char *name, const char *uri, const char *s)
int ip_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
/* Returns 1 if successful, only copy valid address */
if (uiplib_ip6addrconv (s, &tmp_addr)) {

View file

@ -56,7 +56,13 @@
*/
static size_t
part_count (const char *name, const char *uri, char *buf, size_t bsize)
part_count
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_part_count ());
}
@ -71,7 +77,13 @@ GENERIC_RESOURCE
);
static size_t
part_size (const char *name, const char *uri, char *buf, size_t bsize)
part_size
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_part_size ());
}
@ -86,13 +98,20 @@ GENERIC_RESOURCE
);
static size_t
get_boot_default (const char *name, const char *uri, char *buf, size_t bsize)
get_boot_default
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_boot_default ());
}
static int
set_boot_default (const char *name, const char *uri, const char *s)
set_boot_default
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
bootloader_set_boot_default (tmp);
@ -109,13 +128,20 @@ GENERIC_RESOURCE
);
static size_t
get_boot_next (const char *name, const char *uri, char *buf, size_t bsize)
get_boot_next
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_boot_next ());
}
static int
set_boot_next (const char *name, const char *uri, const char *s)
set_boot_next
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
bootloader_set_boot_next (tmp);
@ -132,7 +158,13 @@ GENERIC_RESOURCE
);
static size_t
get_callers_part (const char *name, const char *uri, char *buf, size_t bsize)
get_callers_part
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_callers_part ());
}
@ -146,5 +178,72 @@ GENERIC_RESOURCE
, get_callers_part
);
/*
* Parse query info. We insist that the query starts with 'part='
* Then we parse the integer following the part= string and return the
* number. The number is always positive, if something goes wrong we
* return a negative number.
*/
static int get_query_partition (const char *query)
{
if (strncmp (query, "part=", 5)) {
return -1;
}
return strtoul (query + 5, NULL, 10);
}
static size_t
get_part_start
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
int idx = get_query_partition (query);
printf ("part: %d", idx);
if (idx < 0) {
return snprintf (buf, bsize, "Invalid: %s", query);
}
return snprintf (buf, bsize, "%ld", bootloader_get_part_start (idx));
}
GENERIC_RESOURCE
( part_start
, Start of partition
, count
, 0
, NULL
, get_part_start
);
static int
set_part_ok
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
int idx = get_query_partition (query);
printf ("part: %d", idx);
if (idx < 0) {
return -1;
}
if (tmp) {
bootloader_set_part_ok (idx);
} else {
bootloader_clr_part_ok (idx);
}
return 0;
}
GENERIC_RESOURCE
( part_ok
, Set/Clear Partition OK flag
, count
, 0
, set_part_ok
, NULL
);
// FIXME: Find out how to pass two parameters, for set/clr_part_ok and
// for get_part_start

View file

@ -11,7 +11,6 @@ extern "C" {
#include "contiki.h"
#include "contiki-net.h"
#include "er-coap.h"
#include "bootloader_if.h"
#include "resources.h"
char resname[] = "update";
}
@ -26,15 +25,10 @@ void setup (void)
rest_activate_resource (&res_boot_default, (char *)"boot_default");
rest_activate_resource (&res_boot_next, (char *)"boot_next");
rest_activate_resource (&res_callers_part, (char *)"callers_part");
rest_activate_resource (&res_part_start, (char *)"part_start");
rest_activate_resource (&res_part_ok, (char *)"part_ok");
}
void loop (void)
{
printf ("part-count: %ld\n", bootloader_get_part_count ());
printf ("part-size: %ld\n", bootloader_get_part_size ());
printf ("part-start 0: 0x%lx\n", bootloader_get_part_start (0));
printf ("part-start 1: 0x%lx\n", bootloader_get_part_start (1));
printf ("boot-default: %ld\n", bootloader_get_boot_default ());
printf ("boot-next: %ld\n", bootloader_get_boot_next ());
printf ("callers-part: %ld\n", bootloader_get_callers_part ());
}

View file

@ -77,7 +77,13 @@ 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, const char *uri, char *buf, size_t bsize)
ip_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
#define IP(x) UIP_NTOHS(server_ipaddr.u16[x])
return snprintf
@ -86,7 +92,8 @@ ip_to_string (const char *name, const char *uri, char *buf, size_t bsize)
);
}
int ip_from_string (const char *name, const char *uri, const char *s)
int ip_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
/* Returns 1 if successful, only copy valid address */
if (uiplib_ip6addrconv (s, &tmp_addr)) {
@ -106,12 +113,19 @@ GENERIC_RESOURCE
);
static size_t
resource_to_string (const char *name, const char *uri, char *buf, size_t bsize)
resource_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%s", server_resource);
}
int resource_from_string (const char *name, const char *uri, const char *s)
int resource_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
strncpy (server_resource, s, sizeof (server_resource));
server_resource [sizeof (server_resource) - 1] = 0;
@ -128,12 +142,19 @@ GENERIC_RESOURCE
);
static size_t
interval_to_string (const char *name, const char *uri, char *buf, size_t bsize)
interval_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%d", interval);
}
int interval_from_string (const char *name, const char *uri, const char *s)
int interval_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
interval = atoi (s);
return 0;

View file

@ -36,7 +36,8 @@ void led_pwm_init (void)
DDRE |= (1<<PINE5);
}
void pwm_from_string (const char *name, const char *s)
int pwm_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
pwm = atoi (s);
if (pwm > max_ticks) {
@ -50,9 +51,16 @@ void pwm_from_string (const char *name, const char *s)
( "TCNT3: %04X TCCR3A: %04X TCCR3B: %04X TCCR3C: %04X OCR3C: %04X\n"
, TCNT3, TCCR3A, TCCR3B, TCCR3C, OCR3C
);
return 0;
}
size_t pwm_to_string (const char *n, uint8_t is_json, char *buf, size_t bufsize)
size_t pwm_to_string
( const char *n
, const char *uri
, const char *query
, char *buf
, size_t bufsize
)
{
return snprintf (buf, bufsize, "%d", pwm);
}
@ -61,6 +69,7 @@ GENERIC_RESOURCE \
( led_pwm
, LED PWM
, duty-cycle
, 0
, pwm_from_string
, pwm_to_string
);