Commit 4e651c81 authored by Kishen Maloor's avatar Kishen Maloor

Merge branch 'origin/master' into fargo

Signed-off-by: Kishen Maloor's avatarKishen Maloor <kishen.maloor@intel.com>
parents 62c29f82 562110ef
Pipeline #240 passed with stage
in 50 seconds
......@@ -206,6 +206,35 @@ oc_blockwise_scrub_buffers(bool all)
}
#ifdef OC_CLIENT
static oc_blockwise_state_t *
oc_blockwise_find_buffer_by_token(oc_list_t list, uint8_t *token,
uint8_t token_len)
{
oc_blockwise_state_t *buffer = oc_list_head(list);
while (buffer) {
if (token_len > 0 && buffer->role == OC_BLOCKWISE_CLIENT &&
buffer->token_len == token_len &&
memcmp(buffer->token, token, token_len) == 0)
break;
buffer = buffer->next;
}
return buffer;
}
oc_blockwise_state_t *
oc_blockwise_find_request_buffer_by_token(uint8_t *token, uint8_t token_len)
{
return oc_blockwise_find_buffer_by_token(oc_blockwise_requests, token,
token_len);
}
oc_blockwise_state_t *
oc_blockwise_find_response_buffer_by_token(uint8_t *token, uint8_t token_len)
{
return oc_blockwise_find_buffer_by_token(oc_blockwise_responses, token,
token_len);
}
static oc_blockwise_state_t *
oc_blockwise_find_buffer_by_mid(oc_list_t list, uint16_t mid)
{
......@@ -328,8 +357,9 @@ oc_blockwise_handle_block(oc_blockwise_state_t *buffer,
{
if (incoming_block_offset >= (unsigned)OC_MAX_APP_DATA_SIZE ||
incoming_block_size > (OC_MAX_APP_DATA_SIZE - incoming_block_offset) ||
incoming_block_offset > buffer->next_block_offset)
incoming_block_offset > buffer->next_block_offset) {
return false;
}
if (buffer->next_block_offset == incoming_block_offset) {
memcpy(&buffer->buffer[buffer->next_block_offset], incoming_block,
......
......@@ -130,10 +130,25 @@ oc_delete_link(oc_link_t *link)
}
}
static oc_event_callback_retval_t
batch_notify_collection(void *data)
{
coap_notify_collection_batch(data);
return OC_EVENT_DONE;
}
static oc_event_callback_retval_t
baseline_notify_collection(void *data)
{
coap_notify_collection_baseline(data);
return OC_EVENT_DONE;
}
static oc_event_callback_retval_t
links_list_notify_collection(void *data)
{
coap_notify_links_list(data);
coap_notify_collection_links_list(data);
oc_set_delayed_callback(data, baseline_notify_collection, 0);
return OC_EVENT_DONE;
}
......@@ -385,13 +400,6 @@ oc_get_next_collection_with_link(oc_resource_t *resource,
return collection;
}
static oc_event_callback_retval_t
batch_notify_collection_for_link(void *data)
{
coap_notify_observers(data, NULL, NULL);
return OC_EVENT_DONE;
}
bool
oc_handle_collection_request(oc_method_t method, oc_request_t *request,
oc_interface_mask_t iface_mask,
......@@ -904,8 +912,6 @@ oc_handle_collection_request(oc_method_t method, oc_request_t *request,
if ((method == OC_PUT || method == OC_POST) &&
response_buffer.code <
oc_status_code(OC_STATUS_BAD_REQUEST)) {
oc_set_delayed_callback(link->resource,
batch_notify_collection_for_link, 0);
}
if (response_buffer.code <
oc_status_code(OC_STATUS_BAD_REQUEST)) {
......@@ -974,8 +980,12 @@ oc_handle_collection_request(oc_method_t method, oc_request_t *request,
if ((method == OC_PUT || method == OC_POST) &&
code < oc_status_code(OC_STATUS_BAD_REQUEST)) {
coap_notify_collection_observers(
request->resource, request->response->response_buffer, iface_mask);
if (iface_mask == OC_IF_CREATE) {
coap_notify_collection_observers(
request->resource, request->response->response_buffer, iface_mask);
} else if (iface_mask == OC_IF_B) {
oc_set_delayed_callback(request->resource, batch_notify_collection, 0);
}
}
return true;
......
......@@ -968,38 +968,29 @@ oc_ri_invoke_coap_entity_handler(void *request, void *response, uint8_t *buffer,
}
#if defined(OC_COLLECTIONS)
if (resource_is_collection) {
/* The implementation currently permits observations of collections
* via
* only the batch interface.
*/
if (iface_mask != OC_IF_B && iface_mask != OC_IF_LL &&
iface_mask != OC_IF_CREATE) {
set_observe_option = false;
} else {
oc_collection_t *collection = (oc_collection_t *)cur_resource;
oc_link_t *links = (oc_link_t *)oc_list_head(collection->links);
oc_collection_t *collection = (oc_collection_t *)cur_resource;
oc_link_t *links = (oc_link_t *)oc_list_head(collection->links);
#ifdef OC_SECURITY
while (links) {
if (links->resource &&
links->resource->properties & OC_OBSERVABLE) {
if (!oc_sec_check_acl(OC_GET, links->resource, endpoint)) {
set_observe_option = false;
break;
}
while (links) {
if (links->resource &&
links->resource->properties & OC_OBSERVABLE) {
if (!oc_sec_check_acl(OC_GET, links->resource, endpoint)) {
set_observe_option = false;
break;
}
links = links->next;
}
links = links->next;
}
#endif /* OC_SECURITY */
if (set_observe_option) {
if (iface_mask == OC_IF_B) {
links = (oc_link_t *)oc_list_head(collection->links);
while (links) {
if (links->resource &&
links->resource->properties & OC_PERIODIC) {
add_periodic_observe_callback(links->resource);
}
links = links->next;
if (set_observe_option) {
if (iface_mask == OC_IF_B) {
links = (oc_link_t *)oc_list_head(collection->links);
while (links) {
if (links->resource &&
links->resource->properties & OC_PERIODIC) {
add_periodic_observe_callback(links->resource);
}
links = links->next;
}
}
}
......@@ -1343,6 +1334,7 @@ oc_ri_invoke_client_cb(void *response, oc_client_cb_t *cb,
} else {
if (pkt->type == COAP_TYPE_ACK && pkt->code == 0) {
separate = true;
cb->separate = 1;
} else if (!cb->discovery) {
oc_response_handler_t handler =
(oc_response_handler_t)cb->handler.response;
......@@ -1387,6 +1379,8 @@ oc_ri_invoke_client_cb(void *response, oc_client_cb_t *cb,
while (dup_cb != NULL) {
if (dup_cb != cb && dup_cb->observe_seq != -1 &&
dup_cb->token_len == cb->token_len &&
memcmp(dup_cb->token, cb->token, cb->token_len) == 0 &&
oc_string_len(dup_cb->uri) == uri_len &&
strncmp(oc_string(dup_cb->uri), oc_string(cb->uri), uri_len) == 0 &&
oc_endpoint_compare(&dup_cb->endpoint, endpoint) == 0) {
......
......@@ -284,6 +284,7 @@ register_resources(void)
#if defined(OC_COLLECTIONS)
oc_resource_t *col = oc_new_collection("roomlights", "/lights", 1, 0);
oc_resource_bind_resource_type(col, "oic.wk.col");
oc_resource_bind_resource_interface(col, OC_IF_CREATE);
oc_resource_set_discoverable(col, true);
oc_link_t *l1 = oc_new_link(res1);
......@@ -331,10 +332,10 @@ main(void)
sa.sa_handler = handle_signal;
sigaction(SIGINT, &sa, NULL);
static const oc_handler_t handler = {.init = app_init,
.signal_event_loop = signal_event_loop,
.register_resources =
register_resources };
static const oc_handler_t handler = { .init = app_init,
.signal_event_loop = signal_event_loop,
.register_resources =
register_resources };
oc_clock_time_t next_event;
......
......@@ -52,6 +52,8 @@ typedef struct oc_blockwise_state_s
#endif /* !OC_DYNAMIC_ALLOCATION */
oc_string_t uri_query;
#ifdef OC_CLIENT
uint8_t token[COAP_TOKEN_LEN];
uint8_t token_len;
uint16_t mid;
void *client_cb;
#endif /* OC_CLIENT */
......@@ -76,6 +78,12 @@ oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_mid(uint16_t mid);
oc_blockwise_state_t *oc_blockwise_find_response_buffer_by_mid(uint16_t mid);
oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_token(
uint8_t *token, uint8_t token_len);
oc_blockwise_state_t *oc_blockwise_find_response_buffer_by_token(
uint8_t *token, uint8_t token_len);
oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_client_cb(
oc_endpoint_t *endpoint, void *client_cb);
......
......@@ -85,6 +85,7 @@ typedef struct oc_client_cb_t
bool multicast;
bool stop_multicast_receive;
uint8_t ref_count;
uint8_t separate;
} oc_client_cb_t;
#ifdef OC_BLOCK_WISE
......
......@@ -150,6 +150,10 @@ coap_receive(oc_message_t *msg)
oc_blockwise_state_t *request_buffer = NULL, *response_buffer = NULL;
#endif /* OC_BLOCK_WISE */
#ifdef OC_CLIENT
oc_client_cb_t *client_cb = 0;
#endif /* OC_CLIENT */
#ifdef OC_TCP
if (msg->endpoint.flags & TCP) {
coap_status_code =
......@@ -544,7 +548,6 @@ coap_receive(oc_message_t *msg)
uint16_t response_mid = coap_get_mid();
bool error_response = false;
#endif /* OC_BLOCK_WISE */
oc_client_cb_t *client_cb = 0;
if (message->type != COAP_TYPE_RST) {
client_cb =
oc_ri_find_client_cb_by_token(message->token, message->token_len);
......@@ -574,6 +577,10 @@ coap_receive(oc_message_t *msg)
&msg->endpoint, client_cb);
} else {
request_buffer = oc_blockwise_find_request_buffer_by_mid(message->mid);
if (!request_buffer) {
request_buffer = oc_blockwise_find_request_buffer_by_token(
message->token, message->token_len);
}
}
if (!error_response && request_buffer &&
(block1 || message->code == REQUEST_ENTITY_TOO_LARGE_4_13)) {
......@@ -654,6 +661,10 @@ coap_receive(oc_message_t *msg)
} else {
response_buffer =
oc_blockwise_find_response_buffer_by_mid(message->mid);
if (!response_buffer) {
response_buffer = oc_blockwise_find_response_buffer_by_token(
message->token, message->token_len);
}
}
if (!error_response && response_buffer) {
OC_DBG("got response buffer for uri %s",
......@@ -709,11 +720,12 @@ coap_receive(oc_message_t *msg)
* signal from the server. In this case, the client_cb continues
* to live until the response arrives (or it times out).
*/
if (!oc_ri_is_client_cb_valid(client_cb)) {
if (client_cb->separate == 0) {
if (response_buffer) {
response_buffer->ref_count = 0;
}
}
client_cb->separate = 0;
goto send_message;
#else /* OC_BLOCK_WISE */
oc_ri_invoke_client_cb(message, client_cb, &msg->endpoint);
......@@ -765,6 +777,16 @@ send_message:
i += sizeof(r);
}
response->token_len = (uint8_t)i;
if (request_buffer) {
memcpy(request_buffer->token, response->token,
response->token_len);
request_buffer->token_len = response->token_len;
}
if (response_buffer) {
memcpy(response_buffer->token, response->token,
response->token_len);
response_buffer->token_len = response->token_len;
}
} else {
coap_set_token(response, message->token, message->token_len);
}
......
......@@ -83,7 +83,7 @@ OC_MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS);
/*---------------------------------------------------------------------------*/
static int
coap_remove_observer_handle_by_uri(oc_endpoint_t *endpoint, const char *uri,
int uri_len)
int uri_len, oc_interface_mask_t iface_mask)
{
int removed = 0;
coap_observer_t *obs = (coap_observer_t *)oc_list_head(observers_list), *next;
......@@ -92,7 +92,8 @@ coap_remove_observer_handle_by_uri(oc_endpoint_t *endpoint, const char *uri,
next = obs->next;
if (((oc_endpoint_compare(&obs->endpoint, endpoint) == 0)) &&
(oc_string_len(obs->url) == (size_t)uri_len &&
memcmp(oc_string(obs->url), uri, uri_len) == 0)) {
memcmp(oc_string(obs->url), uri, uri_len) == 0) &&
obs->iface_mask == iface_mask) {
obs->resource->num_observers--;
oc_list_remove(observers_list, obs);
oc_memb_free(&observers_memb, obs);
......@@ -116,7 +117,8 @@ add_observer(oc_resource_t *resource, oc_endpoint_t *endpoint,
#endif /* !OC_BLOCK_WISE */
{
/* Remove existing observe relationship, if any. */
int dup = coap_remove_observer_handle_by_uri(endpoint, uri, (int)uri_len);
int dup =
coap_remove_observer_handle_by_uri(endpoint, uri, (int)uri_len, iface_mask);
coap_observer_t *o = oc_memb_alloc(&observers_memb);
......@@ -286,7 +288,6 @@ coap_notify_collection_observers(oc_resource_t *resource,
if (obs->resource != resource || obs->iface_mask != iface_mask) {
continue;
}
OC_DBG("coap_notify_collections: notifying observer");
coap_transaction_t *transaction = NULL;
coap_packet_t notification[1];
......@@ -389,18 +390,53 @@ leave_notify_collections:
}
int
coap_notify_links_list(oc_collection_t *collection)
coap_notify_collection_baseline(oc_collection_t *collection)
{
#ifndef OC_DYNAMIC_ALLOCATION
uint8_t buffer[OC_MAX_APP_DATA_SIZE];
#else /* !OC_DYNAMIC_ALLOCATION */
uint8_t *buffer = malloc(OC_MAX_APP_DATA_SIZE);
if (!buffer) {
OC_WRN("coap_notify_collections: out of memory allocating buffer");
OC_WRN("coap_notify_collection_baseline: out of memory allocating buffer");
return -1;
}
#endif /* OC_DYNAMIC_ALLOCATION */
oc_request_t request = { 0 };
oc_response_t response = { 0 };
response.separate_response = 0;
oc_response_buffer_t response_buffer;
response_buffer.buffer = buffer;
response_buffer.buffer_size = (uint16_t)OC_MAX_APP_DATA_SIZE;
response.response_buffer = &response_buffer;
request.response = &response;
request.request_payload = NULL;
oc_rep_new(response_buffer.buffer, response_buffer.buffer_size);
request.resource = (oc_resource_t *)collection;
oc_handle_collection_request(OC_GET, &request, OC_IF_BASELINE, NULL);
coap_notify_collection_observers(request.resource, &response_buffer,
OC_IF_BASELINE);
#ifdef OC_DYNAMIC_ALLOCATION
if (buffer)
free(buffer);
#endif /* OC_DYNAMIC_ALLOCATION */
return 0;
}
int
coap_notify_collection_batch(oc_collection_t *collection)
{
#ifndef OC_DYNAMIC_ALLOCATION
uint8_t buffer[OC_MAX_APP_DATA_SIZE];
#else /* !OC_DYNAMIC_ALLOCATION */
uint8_t *buffer = malloc(OC_MAX_APP_DATA_SIZE);
if (!buffer) {
OC_WRN("coap_notify_collection_batch: out of memory allocating buffer");
return -1;
}
#endif /* OC_DYNAMIC_ALLOCATION */
oc_request_t request = { 0 };
oc_response_t response = { 0 };
response.separate_response = 0;
......@@ -414,8 +450,43 @@ coap_notify_links_list(oc_collection_t *collection)
request.resource = (oc_resource_t *)collection;
oc_handle_collection_request(OC_GET, &request, OC_IF_LL, NULL);
oc_handle_collection_request(OC_GET, &request, OC_IF_B, NULL);
coap_notify_collection_observers(request.resource, &response_buffer, OC_IF_B);
#ifdef OC_DYNAMIC_ALLOCATION
if (buffer)
free(buffer);
#endif /* OC_DYNAMIC_ALLOCATION */
return 0;
}
int
coap_notify_collection_links_list(oc_collection_t *collection)
{
#ifndef OC_DYNAMIC_ALLOCATION
uint8_t buffer[OC_MAX_APP_DATA_SIZE];
#else /* !OC_DYNAMIC_ALLOCATION */
uint8_t *buffer = malloc(OC_MAX_APP_DATA_SIZE);
if (!buffer) {
OC_WRN(
"coap_notify_collection_links_list: out of memory allocating buffer");
return -1;
}
#endif /* OC_DYNAMIC_ALLOCATION */
oc_request_t request = { 0 };
oc_response_t response = { 0 };
response.separate_response = 0;
oc_response_buffer_t response_buffer;
response_buffer.buffer = buffer;
response_buffer.buffer_size = (uint16_t)OC_MAX_APP_DATA_SIZE;
response.response_buffer = &response_buffer;
request.response = &response;
request.request_payload = NULL;
oc_rep_new(response_buffer.buffer, response_buffer.buffer_size);
request.resource = (oc_resource_t *)collection;
oc_handle_collection_request(OC_GET, &request, OC_IF_LL, NULL);
coap_notify_collection_observers(request.resource, &response_buffer,
OC_IF_LL);
......@@ -457,8 +528,8 @@ coap_notify_collections(oc_resource_t *resource)
for (collection = oc_get_next_collection_with_link(resource, NULL);
collection != NULL && collection->num_observers > 0;
collection = oc_get_next_collection_with_link(resource, collection)) {
OC_DBG(
"coap_notify_collections: Issue GET request to collection for resource");
OC_DBG("coap_notify_collections: Issue GET request to collection for "
"resource");
request.resource = (oc_resource_t *)collection;
......@@ -585,33 +656,34 @@ coap_notify_observers(oc_resource_t *resource,
continue;
} // obs->resource != resource || endpoint != obs->endpoint
if (response.separate_response != NULL &&
response_buf->code == oc_status_code(OC_STATUS_OK)) {
coap_packet_t req[1];
if (response.separate_response != NULL) {
if (response_buf->code == oc_status_code(OC_STATUS_OK)) {
coap_packet_t req[1];
#ifdef OC_TCP
if (obs->endpoint.flags & TCP) {
coap_tcp_init_message(req, COAP_GET);
} else
if (obs->endpoint.flags & TCP) {
coap_tcp_init_message(req, COAP_GET);
} else
#endif /* OC_TCP */
{
coap_udp_init_message(req, COAP_TYPE_NON, COAP_GET, 0);
}
memcpy(req->token, obs->token, obs->token_len);
req->token_len = obs->token_len;
{
coap_udp_init_message(req, COAP_TYPE_NON, COAP_GET, 0);
}
memcpy(req->token, obs->token, obs->token_len);
req->token_len = obs->token_len;
coap_set_header_uri_path(req, oc_string(resource->uri),
oc_string_len(resource->uri));
coap_set_header_uri_path(req, oc_string(resource->uri),
oc_string_len(resource->uri));
OC_DBG(
"coap_notify_observers: Creating separate response for notification");
OC_DBG("coap_notify_observers: Creating separate response for "
"notification");
#ifdef OC_BLOCK_WISE
if (coap_separate_accept(req, response.separate_response,
&obs->endpoint, 0, obs->block2_size) == 1)
if (coap_separate_accept(req, response.separate_response,
&obs->endpoint, 0, obs->block2_size) == 1)
#else /* OC_BLOCK_WISE */
if (coap_separate_accept(req, response.separate_response,
&obs->endpoint, 0) == 1)
if (coap_separate_accept(req, response.separate_response,
&obs->endpoint, 0) == 1)
#endif /* !OC_BLOCK_WISE */
response.separate_response->active = 1;
response.separate_response->active = 1;
}
} // separate response
else {
OC_DBG("coap_notify_observers: notifying observer");
......
......@@ -94,7 +94,9 @@ int coap_notify_collection_observers(oc_resource_t *resource,
int coap_notify_observers(oc_resource_t *resource,
oc_response_buffer_t *response_buf,
oc_endpoint_t *endpoint);
int coap_notify_links_list(oc_collection_t *collection);
int coap_notify_collection_links_list(oc_collection_t *collection);
int coap_notify_collection_batch(oc_collection_t *collection);
int coap_notify_collection_baseline(oc_collection_t *collection);
#ifdef OC_BLOCK_WISE
int coap_observe_handler(void *request, void *response, oc_resource_t *resource,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment