/* * Main request handler: generates response PDU in the provided buffer. * * Caller must finish the PDU and send it. * * return length of response pdu, or < 0 if can't handle */ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, sock_udp_ep_t *remote) { coap_resource_t *resource; gcoap_listener_t *listener; sock_udp_ep_t *observer = NULL; gcoap_observe_memo_t *memo = NULL; gcoap_observe_memo_t *resource_memo = NULL; _find_resource(pdu, &resource, &listener); if (resource == NULL) { return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND); } else { /* used below to ensure a memo not already recorded for the resource */ _find_obs_memo_resource(&resource_memo, resource); } if (coap_get_observe(pdu) == COAP_OBS_REGISTER) { int empty_slot = _find_obs_memo(&memo, remote, pdu); /* record observe memo */ if (memo == NULL) { if (empty_slot >= 0 && resource_memo == NULL) { int obs_slot = _find_observer(&observer, remote); /* cache new observer */ if (observer == NULL) { if (obs_slot >= 0) { observer = &_coap_state.observers[obs_slot]; memcpy(observer, remote, sizeof(sock_udp_ep_t)); } else { DEBUG("gcoap: can't register observer\n"); } } if (observer != NULL) { memo = &_coap_state.observe_memos[empty_slot]; } } if (memo == NULL) { coap_clear_observe(pdu); DEBUG("gcoap: can't register observe memo\n"); } } if (memo != NULL) { memo->observer = observer; memo->resource = resource; memo->token_len = coap_get_token_len(pdu); if (memo->token_len) { memcpy(&memo->token[0], pdu->token, memo->token_len); } DEBUG("gcoap: Registered observer for: %s\n", memo->resource->path); /* generate initial notification value */ uint32_t now = xtimer_now_usec(); pdu->observe_value = (now >> GCOAP_OBS_TICK_EXPONENT) & 0xFFFFFF; }
/* * Main request handler: generates response PDU in the provided buffer. * * Caller must finish the PDU and send it. * * return length of response pdu, or < 0 if can't handle */ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, sock_udp_ep_t *remote) { coap_resource_t *resource = NULL; gcoap_listener_t *listener = NULL; sock_udp_ep_t *observer = NULL; gcoap_observe_memo_t *memo = NULL; gcoap_observe_memo_t *resource_memo = NULL; switch (_find_resource(pdu, &resource, &listener)) { case GCOAP_RESOURCE_WRONG_METHOD: return gcoap_response(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED); case GCOAP_RESOURCE_NO_PATH: return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND); case GCOAP_RESOURCE_FOUND: _find_obs_memo_resource(&resource_memo, resource); break; } if (coap_get_observe(pdu) == COAP_OBS_REGISTER) { 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; } else if ((empty_slot >= 0) && (resource_memo == NULL)) { int obs_slot = _find_observer(&observer, remote); /* cache new observer */ if (observer == NULL) { if (obs_slot >= 0) { observer = &_coap_state.observers[obs_slot]; memcpy(observer, remote, sizeof(sock_udp_ep_t)); } else { DEBUG("gcoap: can't register observer\n"); } } if (observer != NULL) { memo = &_coap_state.observe_memos[empty_slot]; } } if (memo == NULL) { coap_clear_observe(pdu); DEBUG("gcoap: can't register observe memo\n"); } } if (memo != NULL) { memo->observer = observer; memo->resource = resource; memo->token_len = coap_get_token_len(pdu); if (memo->token_len) { memcpy(&memo->token[0], pdu->token, memo->token_len); } DEBUG("gcoap: Registered observer for: %s\n", memo->resource->path); /* generate initial notification value */ uint32_t now = xtimer_now_usec(); pdu->observe_value = (now >> GCOAP_OBS_TICK_EXPONENT) & 0xFFFFFF; }