Skip to content

Commit

Permalink
add request test
Browse files Browse the repository at this point in the history
  • Loading branch information
smlng committed Aug 17, 2016
1 parent 7d32cf6 commit d9d4a4c
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
38 changes: 37 additions & 1 deletion coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int coap_make_request(const uint16_t msgid, const coap_buffer_t* tok,
pkt->hdr.tkl = 0;
pkt->hdr.code = resource->method;
pkt->hdr.id = msgid;
pkt->numopts = 1;
pkt->numopts = 0;
// set token
if (tok) {
pkt->hdr.tkl = tok->len;
Expand All @@ -167,12 +167,14 @@ int coap_make_request(const uint16_t msgid, const coap_buffer_t* tok,
pkt->opts[i].num = COAP_OPTION_URI_PATH;
pkt->opts[i].buf.p = (const uint8_t *) path->items[i];
pkt->opts[i].buf.len = strlen(path->items[i]);
pkt->numopts++;
}
// set content type, if present afterwards
if (COAP_GET_CONTENTTYPE(resource->content_type, 2) != COAP_CONTENTTYPE_NONE) {
pkt->opts[i].num = COAP_OPTION_CONTENT_FORMAT;
pkt->opts[i].buf.p = resource->content_type;
pkt->opts[i].buf.len = 2;
pkt->numopts++;
}
// attach payload
pkt->payload.p = content;
Expand Down Expand Up @@ -259,6 +261,40 @@ int coap_handle_request(coap_resource_t *resources,
NULL, NULL, 0, pkt);
}

int coap_handle_response(coap_resource_t *resources,
const coap_packet_t *reqpkt,
coap_packet_t *rsppkt)
{
if (reqpkt->hdr.id != rsppkt->hdr.id )
return COAP_ERR_REQUEST_MSGID_MISMATCH;
if (reqpkt->hdr.tkl != rsppkt->hdr.tkl)
return COAP_ERR_REQUEST_TOKEN_MISMATCH;
else if (memcmp(reqpkt->tok.p, rsppkt->tok.p, reqpkt->tok.len) != 0)
return COAP_ERR_REQUEST_TOKEN_MISMATCH;
if (rsppkt->hdr.code >= COAP_RSPCODE_BAD_REQUEST)
return COAP_ERR_RESPONSE;
uint8_t count;
const coap_option_t *opt = _find_options(reqpkt, COAP_OPTION_URI_PATH, &count);
// find handler for requested resource
for (coap_resource_t *rs = resources; rs->handler && opt; ++rs) {
if (count == rs->path->count) {
int i;
for (i = 0; i < count; ++i) {
if (opt[i].buf.len != strlen(rs->path->items[i])) {
break;
}
if (memcmp(rs->path->items[i], opt[i].buf.p, opt[i].buf.len)) {
break;
}
}
if (i == count) { // matching resource found
return rs->handler(rs, reqpkt, rsppkt);
}
}
}
return COAP_ERR_REQUEST_NOT_FOUND;
}

int coap_make_link_format(const coap_resource_t *resources,
char *buf, size_t buflen)
{
Expand Down
9 changes: 8 additions & 1 deletion coap.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ typedef enum
COAP_ERR_UNSUPPORTED = 10,
COAP_ERR_OPTION_DELTA_INVALID = 11,
COAP_ERR_OPTION_NOT_FOUND = 12,
COAP_ERR_REQUEST_NOT_FOUND,
COAP_ERR_REQUEST_MSGID_MISMATCH,
COAP_ERR_REQUEST_TOKEN_MISMATCH,
COAP_ERR_RESPONSE,
COAP_ERR_MAX = 99,
} coap_error_t;
#define COAP_SUCCESS COAP_ERR_NONE //!< Success return value if no error occured
Expand All @@ -230,6 +234,7 @@ typedef enum {
COAP_STATE_RDY = (COAP_ERR_MAX + 1),
COAP_STATE_ACK,
COAP_STATE_RSP,
COAP_STATE_REQ,
} coap_state_t;


Expand Down Expand Up @@ -396,7 +401,9 @@ int coap_handle_request(coap_resource_t *resources,
const coap_packet_t *inpkt,
coap_packet_t *pkt);

int coap_handle_response();
int coap_handle_response(coap_resource_t *resources,
const coap_packet_t *reqpkt,
coap_packet_t *rsppkt);
int coap_handle_packet();

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/piggyback.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <strings.h>

#include "coap.h"
#include "coap_dump.h"

const uint16_t rsplen = 128;
static char rsp[128] = "";
Expand Down Expand Up @@ -109,4 +108,5 @@ int main(void)
}
}
}
return 0;
}
99 changes: 99 additions & 0 deletions tests/request.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <errno.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

#include "coap.h"

#define DSTADDR "::1"
#define DSTPORT "5683"

static const coap_resource_path_t path_well_known_core = {2, {".well-known", "core"}};
static int handle_get_well_known_core(const coap_resource_t *resource,
const coap_packet_t *reqpkt,
coap_packet_t *rsppkt)
{
printf("handle_get_well_known_core\n");
printf("%.*s\n", (int)rsppkt->payload.len, (char *)rsppkt->payload.p);
return COAP_STATE_REQ;
}

coap_resource_t resources[] =
{
{COAP_STATE_RDY, COAP_METHOD_GET, COAP_TYPE_ACK,
handle_get_well_known_core, &path_well_known_core,
COAP_SET_CONTENTTYPE(COAP_CONTENTTYPE_APP_LINKFORMAT)},
{(coap_state_t)0, (coap_method_t)0, (coap_msgtype_t)0,
NULL, NULL,
COAP_SET_CONTENTTYPE(COAP_CONTENTTYPE_NONE)}
};

int main(void)
{
int fd;
struct addrinfo hints, *dstinfo, *p;
struct sockaddr_storage cliaddr;
int rv;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;

if ((rv = getaddrinfo(DSTADDR, DSTPORT, &hints, &dstinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

for (p = dstinfo; p != NULL; p = p->ai_next) {
if ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "failed to bind socket\n");
return 2;
}

int n, rc;
socklen_t len = sizeof(cliaddr);
coap_packet_t req, rsp;
uint16_t msgid = 1;
printf(" + coap_make_request\n");
coap_make_request(msgid, NULL, &resources[0], NULL, 0, &req);
uint8_t buf[1024];
size_t buflen = sizeof(buf);
if (0 != (rc = coap_build(&req, buf, &buflen))) {
printf("coap_build failed rc=%d\n", rc);
return 1;
}
else {
printf(" + send request\n");
if ((n = sendto(fd, buf, buflen, 0, p->ai_addr, p->ai_addrlen)) == -1) {
perror("sendto");
return 1;
}
printf(" + wait for response ...\n");
for (int state = 0; state != COAP_STATE_REQ; ) {
n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len);
printf(" +++ received message of %d bytes\n", n);
if (0 != (rc = coap_parse(buf, n, &rsp))) {
printf("Bad packet rc=%d\n", rc);
return 1;
}
state = coap_handle_response(resources, &req, &rsp);
}
}
// cleanup and exit
freeaddrinfo(dstinfo);
close(fd);
return 0;
}

0 comments on commit d9d4a4c

Please sign in to comment.