15 #include <sys/select.h>
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
30 #define COAP_RESOURCE_CHECK_TIME 2
33 #define min(a,b) ((a) < (b) ? (a) : (b))
54 #define INDEX "This is a test server made with libcoap (see http://libcoap.sf.net)\n" \
55 "Copyright (C) 2010--2013 Olaf Bergmann <bergmann@tzi.org>\n\n"
80 unsigned char buf[40];
92 if (request != NULL &&
99 if (resource->
dirty == 1)
122 len = snprintf((
char *)buf,
124 "%u", (
unsigned int)now);
130 len = strftime((
char *)buf,
132 "%b %d %H:%M:%S", tmp);
180 #ifndef WITHOUT_ASYNC
187 unsigned long delay = 5;
191 if (async->
id != request->
hdr->
id) {
205 delay = delay * 10 + (*p -
'0');
210 (
void *)(COAP_TICKS_PER_SECOND * delay));
220 if (!async || now < async->created + (
unsigned long)async->
appdata)
228 debug(
"check_async: insufficient memory, we'll try later\n");
230 (
void *)((
unsigned long)async->
appdata + 15 * COAP_TICKS_PER_SECOND);
242 debug(
"check_async: cannot send response for message %d\n",
259 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
260 coap_add_attr(r, (
unsigned char *)
"title", 5, (
unsigned char *)
"\"General Info\"", 14, 0);
271 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
272 coap_add_attr(r, (
unsigned char *)
"title", 5, (
unsigned char *)
"\"Internal Clock\"", 16, 0);
273 coap_add_attr(r, (
unsigned char *)
"rt", 2, (
unsigned char *)
"\"Ticks\"", 7, 0);
275 coap_add_attr(r, (
unsigned char *)
"if", 2, (
unsigned char *)
"\"clock\"", 7, 0);
279 #ifndef WITHOUT_ASYNC
283 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
289 usage(
const char *program,
const char *version) {
292 p = strrchr( program,
'/' );
296 fprintf( stderr,
"%s v%s -- a small CoAP implementation\n"
297 "(c) 2010,2011 Olaf Bergmann <bergmann@tzi.org>\n\n"
298 "usage: %s [-A address] [-p port]\n\n"
299 "\t-A address\tinterface address to bind to\n"
300 "\t-p port\t\tlisten on specified port\n"
301 "\t-v num\t\tverbosity level (default: 3)\n",
302 program, version, program );
309 struct addrinfo hints;
310 struct addrinfo *result, *rp;
312 memset(&hints, 0,
sizeof(
struct addrinfo));
313 hints.ai_family = AF_UNSPEC;
314 hints.ai_socktype = SOCK_DGRAM;
315 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
317 s = getaddrinfo(node, port, &hints, &result);
319 fprintf(stderr,
"getaddrinfo: %s\n", gai_strerror(s));
324 for (rp = result; rp != NULL; rp = rp->ai_next) {
327 if (rp->ai_addrlen <=
sizeof(addr.addr)) {
329 addr.size = rp->ai_addrlen;
330 memcpy(&addr.addr, rp->ai_addr, rp->ai_addrlen);
340 fprintf(stderr,
"no context available for interface '%s'\n", node);
343 freeaddrinfo(result);
351 struct timeval tv, *timeout;
355 char addr_str[NI_MAXHOST] =
"::";
356 char port_str[NI_MAXSERV] =
"5683";
360 while ((opt = getopt(argc, argv,
"A:p:v:")) != -1) {
363 strncpy(addr_str, optarg, NI_MAXHOST-1);
364 addr_str[NI_MAXHOST - 1] =
'\0';
367 strncpy(port_str, optarg, NI_MAXSERV-1);
368 port_str[NI_MAXSERV - 1] =
'\0';
371 log_level = strtol(optarg, NULL, 10);
391 FD_SET( ctx->sockfd, &readfds );
396 while ( nextpdu && nextpdu->
t <= now ) {
403 tv.tv_usec = ((nextpdu->
t - now) % COAP_TICKS_PER_SECOND) * 1000000 / COAP_TICKS_PER_SECOND;
404 tv.tv_sec = (nextpdu->
t - now) / COAP_TICKS_PER_SECOND;
411 result = select( FD_SETSIZE, &readfds, 0, 0, timeout );
416 }
else if ( result > 0 ) {
417 if ( FD_ISSET( ctx->sockfd, &readfds ) ) {
425 #ifndef WITHOUT_ASYNC
430 #ifndef WITHOUT_OBSERVE