1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #9261 from kb2ma/gcoap/refine_re-register

net/gcoap: Refine Observe re-registration
This commit is contained in:
Martine Lenders 2018-06-13 16:05:40 +02:00 committed by GitHub
commit e91e0a7807
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 11 deletions

View File

@ -158,7 +158,13 @@
* bytes long. For resources that change slowly, this length can be reduced via
* GCOAP_OBS_VALUE_WIDTH.
*
* To cancel a notification, the server expects to receive a GET request with
* A client always may re-register for a resource with the same token or with
* a new token to indicate continued interest in receiving notifications about
* it. Of course the client must not already be using any new token in the
* registration for a different resource. Successful registration always is
* indicated by the presence of the Observe option in the response.
*
* To cancel registration, the server expects to receive a GET request with
* the Observe option value set to 1. The server does not support cancellation
* via a reset (RST) response to a non-confirmable notification.
*

View File

@ -279,21 +279,34 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
case GCOAP_RESOURCE_NO_PATH:
return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
case GCOAP_RESOURCE_FOUND:
/* find observe registration for resource */
_find_obs_memo_resource(&resource_memo, resource);
break;
}
if (coap_get_observe(pdu) == COAP_OBS_REGISTER) {
/* lookup remote+token */
int empty_slot = _find_obs_memo(&memo, remote, pdu);
/* record observe memo */
if (memo == NULL) {
if ((resource_memo != NULL)
&& _endpoints_equal(remote, resource_memo->observer)) {
/* observer re-registering with new token */
memo = resource_memo;
observer = resource_memo->observer;
/* validate re-registration request */
if (resource_memo != NULL) {
if (memo != NULL) {
if (memo != resource_memo) {
/* reject token already used for a different resource */
memo = NULL;
coap_clear_observe(pdu);
DEBUG("gcoap: can't change resource for token\n");
}
/* otherwise OK to re-register resource with the same token */
}
else if ((empty_slot >= 0) && (resource_memo == NULL)) {
else if (_endpoints_equal(remote, resource_memo->observer)) {
/* accept new token for resource */
memo = resource_memo;
}
}
/* initialize new registration request */
if ((memo == NULL) && coap_has_observe(pdu)) {
/* verify resource not already registerered (for another endpoint) */
if ((empty_slot >= 0) && (resource_memo == NULL)) {
int obs_slot = _find_observer(&observer, remote);
/* cache new observer */
if (observer == NULL) {
@ -306,6 +319,7 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}
if (observer != NULL) {
memo = &_coap_state.observe_memos[empty_slot];
memo->observer = observer;
}
}
if (memo == NULL) {
@ -313,9 +327,10 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
DEBUG("gcoap: can't register observe memo\n");
}
}
/* finish registration */
if (memo != NULL) {
memo->observer = observer;
memo->resource = resource;
/* resource may be assigned here if it is not already registered */
memo->resource = resource;
memo->token_len = coap_get_token_len(pdu);
if (memo->token_len) {
memcpy(&memo->token[0], pdu->token, memo->token_len);