I am working with the libcoap-dev-1 library under Raspbian with a Raspberry Pi using the library with a simple client and simple server to implement the CoAP protocol. I have a working client and a working server and am now trying to modify the server so that it can accept a URI with a query string and I can then fetch the query string of the URI.
The URI I am currently testing is coap://127.0.0.1/hello?item=1 which has a query parameter, the item=1 after the ?.
The request handler in the server is the following function which is a stub to test out sending a canned response back to the client as JSON text. This works fine and the client receives the JSON text and is able to use the Fast JSON library to parse it.
// header for the libcoap library. it should be in /usr/include/coap
#include <coap/coap.h>
/*
* The resource handler which the libcoap library will invoke when the registered
* URI is specified.
*/
static void
hello_handler(coap_context_t *ctx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
static int iCount = 0;
unsigned char buf[3];
const char* response_data = "{\"device\": \"DEV-01-123\", \"item\" : %d }";
char response_buf[256] = {0};
response->hdr->code = COAP_RESPONSE_CODE(205);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
sprintf (response_buf, response_data, iCount);
coap_add_data (response, strlen(response_buf), (unsigned char *)response_buf);
iCount++;
printf (" request %s\n", resource->uri.s);
}
The printf() at the end of the function prints the URI without the query portion. So what is printed is hello and not hello?item=1.
My question is how can I access the query portion of the URI the client is sending?
The
libcoapfunctions for creating a server and a client require a few more steps as part of formatting and retrieving the URI and the URI query information into/from a CoAP request.The complete sample applications, client.c and server.c, are in my GitHub repository at https://github.com/RichardChambers/raspberrypi/tree/master/coap .
On the server side the message handler will use an option iterator, a
coap_opt_iterator_tstruct object, to iterate over the options of thecoap_pdu_tstruct request object. While iterating, the server will be looking for options of typeCOAP_OPTION_URI_QUERYwhich will contain a query argument, usually a keyword equal value pair.So the function
hello_handler()of the posted question could be rewritten with a helper function to obtain the list of URI query items as follows:On the client side we would build our request adding the queries we want to include in the request with a series of calls of function
coap_add_option()as in:These statements create a CoAP request to a particular URI with a set of arguments or query options so that the server's handler of the URI can provide a specific response back to the request. For this example the variables used are hard coded with values like the following:
The two sample programs can be run in two separate terminal windows, starting the server first. Trying the client three times, the first with a URI of "hello", the second with a URI of "goodbye", and the third time again with a URI of "hello" we see the following output.
From the server:
From the terminal window of the client: