tests/zoap: Add tests for the observe feature

Change-Id: I993437169715ce57f6c5c9f3e95689f785db65c4
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
This commit is contained in:
Vinicius Costa Gomes 2016-09-14 11:40:31 -03:00 committed by Anas Nashif
parent 7079a18267
commit 08e0e86bb0

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <errno.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
@ -36,9 +37,11 @@
#define ZOAP_LIMITED_BUF_SIZE 9
#define NUM_PENDINGS 3
#define NUM_OBSERVERS 3
#define NUM_REPLIES 3
static struct nano_fifo zoap_fifo;
static NET_BUF_POOL(zoap_pool, 1, ZOAP_BUF_SIZE,
static NET_BUF_POOL(zoap_pool, 2, ZOAP_BUF_SIZE,
&zoap_fifo, NULL, sizeof(struct ip_buf));
static struct nano_fifo zoap_incoming_fifo;
@ -50,6 +53,27 @@ static NET_BUF_POOL(zoap_limited_pool, 1, ZOAP_LIMITED_BUF_SIZE,
&zoap_limited_fifo, NULL, sizeof(struct ip_buf));
static struct zoap_pending pendings[NUM_PENDINGS];
static struct zoap_observer observers[NUM_OBSERVERS];
static struct zoap_reply replies[NUM_REPLIES];
/* Some forward declarations */
static void server_notify_callback(struct zoap_resource *resource,
struct zoap_observer *observer);
static int server_resource_1_get(struct zoap_resource *resource,
struct zoap_packet *request,
const uip_ipaddr_t *addr,
uint16_t port);
static const char * const server_resource_1_path[] = { "s", "1", NULL };
static struct zoap_resource server_resources[] = {
{ .path = server_resource_1_path,
.get = server_resource_1_get,
.notify = server_notify_callback },
{ },
};
#define MY_PORT 12345
static uip_ipaddr_t dummy_addr;
static int test_build_empty_pdu(void)
{
@ -403,9 +427,8 @@ done:
static int test_retransmit_second_round(void)
{
struct zoap_packet resp;
struct zoap_packet pkt, resp;
struct zoap_pending *pending, *resp_pending;
struct zoap_packet pkt;
struct net_buf *buf, *resp_buf = NULL;
uint16_t id;
int result = TC_FAIL;
@ -457,7 +480,7 @@ static int test_retransmit_second_round(void)
goto done;
}
resp_buf = net_buf_get(&zoap_incoming_fifo, 0);
resp_buf = net_buf_get(&zoap_fifo, 0);
if (!resp_buf) {
TC_PRINT("Could not get buffer from pool\n");
goto done;
@ -502,6 +525,294 @@ done:
return result;
}
static void server_notify_callback(struct zoap_resource *resource,
struct zoap_observer *observer)
{
if (!uip_ipaddr_cmp(&observer->addr, &dummy_addr)) {
TC_ERROR("The address of the observer doesn't match.\n");
return;
}
if (observer->port != MY_PORT) {
TC_ERROR("The port of the observer doesn't match.\n");
return;
}
zoap_remove_observer(resource, observer);
TC_PRINT("You should see this\n");
}
static int server_resource_1_get(struct zoap_resource *resource,
struct zoap_packet *request,
const uip_ipaddr_t *addr,
uint16_t port)
{
struct zoap_packet response;
struct zoap_observer *observer;
struct net_buf *buf = resource->user_data;
char payload[] = "This is the payload";
const uint8_t *token;
uint8_t tkl, *p;
uint16_t id, len;
int r;
if (!zoap_request_is_observe(request)) {
TC_PRINT("The request should enable observing\n");
return -EINVAL;
}
observer = zoap_observer_next_unused(observers, NUM_OBSERVERS);
if (!observer) {
TC_PRINT("There should be an available observer.\n");
return -EINVAL;
}
token = zoap_header_get_token(request, &tkl);
id = zoap_header_get_id(request);
zoap_observer_init(observer, request, addr, port);
zoap_register_observer(resource, observer);
r = zoap_packet_init(&response, buf);
if (r < 0) {
TC_PRINT("Unable to initialize packet.\n");
return -EINVAL;
}
zoap_header_set_version(&response, 1);
zoap_header_set_type(&response, ZOAP_TYPE_ACK);
zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_OK);
zoap_header_set_id(&response, id);
zoap_header_set_token(&response, token, tkl);
zoap_add_option_int(&response, ZOAP_OPTION_OBSERVE,
resource->age);
p = zoap_packet_get_payload(&response, &len);
memcpy(p, payload, sizeof(payload));
r = zoap_packet_set_used(&response, sizeof(payload));
if (r < 0) {
TC_PRINT("Not enough room for payload.\n");
return -EINVAL;
}
return 0;
}
static int test_observer_server(void)
{
uint8_t valid_request_pdu[] = {
0x45, 0x01, 0x12, 0x34,
't', 'o', 'k', 'e', 'n',
0x60, /* enable observe option */
0x51, 's', 0x01, '1', /* path */
};
uint8_t not_found_request_pdu[] = {
0x45, 0x01, 0x12, 0x34,
't', 'o', 'k', 'e', 'n',
0x60, /* enable observe option */
0x51, 's', 0x01, '2', /* path */
};
struct zoap_packet req;
struct net_buf *buf, *rsp_buf = NULL;
int result = TC_FAIL;
int r;
buf = net_buf_get(&zoap_fifo, 0);
if (!buf) {
TC_PRINT("Could not get buffer from pool\n");
goto done;
}
ip_buf_appdata(buf) = net_buf_tail(buf);
ip_buf_appdatalen(buf) = net_buf_tailroom(buf);
memcpy(ip_buf_appdata(buf), valid_request_pdu,
sizeof(valid_request_pdu));
ip_buf_appdatalen(buf) = sizeof(valid_request_pdu);
r = zoap_packet_parse(&req, buf);
if (r) {
TC_PRINT("Could not initialize packet\n");
goto done;
}
rsp_buf = net_buf_get(&zoap_fifo, 0);
if (!buf) {
TC_PRINT("Could not get buffer from pool\n");
goto done;
}
ip_buf_appdata(rsp_buf) = net_buf_tail(rsp_buf);
ip_buf_appdatalen(rsp_buf) = net_buf_tailroom(rsp_buf);
server_resources[0].user_data = rsp_buf;
r = zoap_handle_request(&req, server_resources, &dummy_addr, MY_PORT);
if (r) {
TC_PRINT("Could not handle packet\n");
goto done;
}
/* Suppose some time passes */
r = zoap_resource_notify(&server_resources[0]);
if (r) {
TC_PRINT("Could not notify resource\n");
goto done;
}
/* Everything worked fine, let's try something else */
ip_buf_appdata(buf) = net_buf_tail(buf);
ip_buf_appdatalen(buf) = net_buf_tailroom(buf);
memcpy(ip_buf_appdata(buf), not_found_request_pdu,
sizeof(not_found_request_pdu));
ip_buf_appdatalen(buf) = sizeof(not_found_request_pdu);
r = zoap_packet_parse(&req, buf);
if (r) {
TC_PRINT("Could not initialize packet\n");
goto done;
}
r = zoap_handle_request(&req, server_resources, &dummy_addr, MY_PORT);
if (r != -ENOENT) {
TC_PRINT("There should be no handler for this resource\n");
goto done;
}
result = TC_PASS;
done:
net_buf_unref(buf);
if (rsp_buf) {
net_buf_unref(rsp_buf);
}
TC_END_RESULT(result);
return result;
}
static int resource_reply_cb(const struct zoap_packet *response,
struct zoap_reply *reply,
const uip_ipaddr_t *addr,
uint16_t port)
{
return 0;
}
static int test_observer_client(void)
{
struct zoap_packet req, rsp;
struct zoap_reply *reply;
struct net_buf *buf, *rsp_buf = NULL;
const char token[] = "rndtoken";
const char * const *p;
int observe = 0;
int result = TC_FAIL;
int r;
buf = net_buf_get(&zoap_fifo, 0);
if (!buf) {
TC_PRINT("Could not get buffer from pool\n");
goto done;
}
ip_buf_appdata(buf) = net_buf_tail(buf);
ip_buf_appdatalen(buf) = net_buf_tailroom(buf);
r = zoap_packet_init(&req, buf);
if (r < 0) {
TC_PRINT("Unable to initialize request\n");
goto done;
}
/* FIXME: Could be that zoap_packet_init() sets some defaults */
zoap_header_set_version(&req, 1);
zoap_header_set_type(&req, ZOAP_TYPE_CON);
zoap_header_set_code(&req, ZOAP_METHOD_GET);
zoap_header_set_id(&req, zoap_next_id());
zoap_header_set_token(&req,
(const uint8_t *) token, strlen(token));
/* Enable observing the resource. */
r = zoap_add_option(&req, ZOAP_OPTION_OBSERVE,
&observe, sizeof(observe));
if (r < 0) {
TC_PRINT("Unable add option to request.\n");
goto done;
}
for (p = server_resource_1_path; p && *p; p++) {
r = zoap_add_option(&req, ZOAP_OPTION_URI_PATH,
*p, strlen(*p));
if (r < 0) {
TC_PRINT("Unable add option to request.\n");
goto done;
}
}
reply = zoap_reply_next_unused(replies, NUM_REPLIES);
if (!reply) {
printk("No resources for waiting for replies.\n");
goto done;
}
zoap_reply_init(reply, &req);
reply->reply = resource_reply_cb;
/* Server side, not interesting for this test */
r = zoap_packet_parse(&req, buf);
if (r) {
TC_PRINT("Could not initialize packet\n");
goto done;
}
rsp_buf = net_buf_get(&zoap_fifo, 0);
if (!buf) {
TC_PRINT("Could not get buffer from pool\n");
goto done;
}
ip_buf_appdata(rsp_buf) = net_buf_tail(rsp_buf);
ip_buf_appdatalen(rsp_buf) = net_buf_tailroom(rsp_buf);
server_resources[0].user_data = rsp_buf;
r = zoap_handle_request(&req, server_resources, &dummy_addr, MY_PORT);
if (r) {
TC_PRINT("Could not handle packet\n");
goto done;
}
/* The uninteresting part ends here */
/* 'rsp_buf' contains the response now */
r = zoap_packet_parse(&rsp, rsp_buf);
if (r) {
TC_PRINT("Could not initialize packet\n");
goto done;
}
reply = zoap_response_received(&rsp, &dummy_addr, MY_PORT,
replies, NUM_REPLIES);
if (!reply) {
TC_PRINT("Couldn't find a matching waiting reply\n");
goto done;
}
result = TC_PASS;
done:
net_buf_unref(buf);
TC_END_RESULT(result);
return result;
}
static const struct {
const char *name;
int (*func)(void);
@ -512,6 +823,8 @@ static const struct {
{ "Parse emtpy PDU test", test_parse_empty_pdu, },
{ "Parse simple PDU test", test_parse_simple_pdu, },
{ "Test retransmission", test_retransmit_second_round, },
{ "Test observer server", test_observer_server, },
{ "Test observer server", test_observer_client, },
};
int main(int argc, char *argv[])