/* * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting * 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. */ /** * \defgroup Generic CoAP Resource Handler * * This factors the boilerplate code necessary for defining a resource * together with the necessary handler. Currently this supports * text/plain and application/json and outputs the resource with its * name in json format. This may change in the future as more CoRE * standards (e.g. see RFC 6690) get defined. * * @{ */ /** * \file * Generic CoAP Resource Handler * \author * Ralf Schlatterbeck */ #define STR__(s) #s #define STR_(s) STR__(s) /* * A macro that extends the resource definition and also sets up the * necessary handler function that calls format/parse routines that * convert from/to string (fs and ts). The ts function needs to return * the length written, similar to sprintf. * The content type definitions ct="0 5" are text/plain and * application/json, respectively, see rfc7252 Table 9 p. 91. * Yes, this *is* a hack. But I hate boilerplate code. */ #define GENERIC_RESOURCE(name, methods, path, title, unit, fs, ts) \ void name##_handler \ ( void *request \ , void *response \ , uint8_t *buffer \ , uint16_t ps \ , int32_t *offset \ ) \ { \ generic_handler \ (request, response, buffer, ps, offset, STR_(name), fs, ts); \ } \ \ RESOURCE ( name, methods, path \ , "title=\"" STR_(title) "\"" \ ";rt=UCUM:\"" STR_(unit) "\"" \ ";ct=\"0 5\"" \ ) /** * \brief Parse a resource in json format * \param bytes: Input string received via coap * \param len: Length of input string * \param name: Name to search in json input * \param buf: Output buffer * \param buflen: Output buffer length * \return 0 for success, -1 for error * * If compiled with DEBUG also prints the error encountered */ extern int8_t json_parse_variable (const uint8_t *bytes, size_t len, char *name, char *buf, size_t buflen); /** * \brief Generic coap resource handler * \param name: The name of the variable in json * \param from_str: Application method to parse value from string * and act on it, may be NULL in which case the resource only * supports GET not PUT * \param to_str: Application method to format value for output; * the function may chose to format differently for coap or text * The other parameters are the same as a normal resource handler * This helps avoid boilerplate code for request handlers * * The callback functions get the name of the parameter as a first * argument, this allows to re-use the same function for different * parameters. The from_str in addition gets the string to parse. * 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. */ extern void generic_handler ( void *request , void *response , uint8_t *buffer , uint16_t preferred_size , int32_t *offset , char *name , void (*from_str)(const char *name, const char *s) , size_t (*to_str)(const char *name, uint8_t is_json, char *buf, size_t bsize) ); /* * VI settings, see coding style * ex:ts=8:et:sw=2 */ /** @} */