14 #include <sys/select.h>
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
29 #define COAP_RESOURCE_CHECK_TIME_SEC 1
32 #define min(a,b) ((a) < (b) ? (a) : (b))
38 #define COAP_OPT_BLOCK_SZX_MAX 6
40 #define REQUIRE_ETAG 0x01
76 #define INDEX "libcoap server for ETSI CoAP Plugtest, March 2012, Paris\n" \
77 "Copyright (C) 2012 Olaf Bergmann <bergmann@tzi.org>\n\n"
132 unsigned char buf[3];
151 unsigned char buf[2];
169 memset(etag, 0,
sizeof(etag));
246 size_t l = 6 +
sizeof(
void *);
253 unsigned char *buf = _buf;
261 if (!(test_payload && uri)) {
270 uri->
length =
min(l, snprintf((
char *)uri->
data, l,
"test/%p", test_payload));
271 test_payload->
length = len;
273 memcpy(test_payload->
data, data, len);
319 if (payload && payload->
max_data < len) {
334 memcpy(payload->
data, data, len);
351 warn(
"cannot modify resource\n");
379 unsigned char buf[70];
393 L =
min(
sizeof(buf) - len, 11);
394 memcpy(buf + len,
"Uri-Query: ", L);
401 if (len <
sizeof(buf))
416 unsigned long delay = 5;
419 if (async->
id != request->
hdr->
id) {
445 debug(
"set delay to %lu\n", delay);
458 unsigned char buf[2];
461 if (!async || now < async->created + (
unsigned long)async->
appdata)
471 debug(
"check_async: insufficient memory, we'll try later\n");
488 debug(
"check_async: cannot send response for message %d\n",
501 FILE *inputfile = NULL;
508 if (stat(filename, &statbuf) < 0) {
509 warn(
"cannot stat file %s\n", filename);
517 inputfile = fopen(filename,
"r");
519 warn(
"cannot read file %s\n", filename);
524 payload->
length = fread(payload->
data, 1, statbuf.st_size, inputfile);
541 test_payload->
length = 13;
542 memcpy(test_payload->
data,
"put data here", test_payload->
length);
551 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
552 coap_add_attr(r, (
unsigned char *)
"rt", 2, (
unsigned char *)
"test", 4, 0);
553 coap_add_attr(r, (
unsigned char *)
"if", 2, (
unsigned char *)
"core#b", 6, 0);
563 test_payload =
make_large(
"etsi_iot_01_largedata.txt");
570 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"41", 2, 0);
571 coap_add_attr(r, (
unsigned char *)
"rt", 2, (
unsigned char *)
"large", 5, 0);
584 test_payload->
length = 10;
585 memcpy(test_payload->
data,
"segsegseg!", test_payload->
length);
591 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
601 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
608 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"0", 1, 0);
609 coap_add_attr(r, (
unsigned char *)
"rt", 2, (
unsigned char *)
"separate", 8, 0);
614 usage(
const char *program,
const char *version) {
617 p = strrchr( program,
'/' );
621 fprintf( stderr,
"%s v%s -- ETSI CoAP plugtest server\n"
622 "(c) 2012 Olaf Bergmann <bergmann@tzi.org>\n\n"
623 "usage: %s [-A address] [-p port]\n\n"
624 "\t-A address\tinterface address to bind to\n"
625 "\t-p port\t\tlisten on specified port\n"
626 "\t-v num\t\tverbosity level (default: 3)\n",
627 program, version, program );
634 struct addrinfo hints;
635 struct addrinfo *result, *rp;
637 memset(&hints, 0,
sizeof(
struct addrinfo));
638 hints.ai_family = AF_UNSPEC;
639 hints.ai_socktype = SOCK_DGRAM;
640 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
642 s = getaddrinfo(node, port, &hints, &result);
644 fprintf(stderr,
"getaddrinfo: %s\n", gai_strerror(s));
649 for (rp = result; rp != NULL; rp = rp->ai_next) {
652 if (rp->ai_addrlen <=
sizeof(addr.addr)) {
654 addr.size = rp->ai_addrlen;
655 memcpy(&addr.addr, rp->ai_addr, rp->ai_addrlen);
665 fprintf(stderr,
"no context available for interface '%s'\n", node);
668 freeaddrinfo(result);
676 struct timeval tv, *timeout;
680 char addr_str[NI_MAXHOST] =
"::";
681 char port_str[NI_MAXSERV] =
"5683";
685 while ((opt = getopt(argc, argv,
"A:p:v:")) != -1) {
688 strncpy(addr_str, optarg, NI_MAXHOST-1);
689 addr_str[NI_MAXHOST - 1] =
'\0';
692 strncpy(port_str, optarg, NI_MAXSERV-1);
693 port_str[NI_MAXSERV - 1] =
'\0';
696 log_level = strtol(optarg, NULL, 10);
718 FD_SET( ctx->
sockfd, &readfds );
723 while ( nextpdu && nextpdu->
t <= now ) {
738 result = select( FD_SETSIZE, &readfds, 0, 0, timeout );
743 }
else if ( result > 0 ) {
744 if ( FD_ISSET( ctx->
sockfd, &readfds ) ) {