/* * Server callback for /cli/stats. Accepts either a GET or a PUT. * * GET: Returns the count of packets sent by the CLI. * PUT: Updates the count of packets. Rejects an obviously bad request, but * allows any two byte value for example purposes. Semantically, the only * valid action is to set the value to 0. */ static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len) { /* read coap method type in packet */ unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu)); switch(method_flag) { case COAP_GET: gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); /* write the response buffer with the request count value */ size_t payload_len = fmt_u16_dec((char *)pdu->payload, req_count); return gcoap_finish(pdu, payload_len, COAP_FORMAT_TEXT); case COAP_PUT: /* convert the payload to an integer and update the internal value */ if (pdu->payload_len <= 5) { char payload[6] = { 0 }; memcpy(payload, (char *)pdu->payload, pdu->payload_len); req_count = (uint16_t)strtoul(payload, NULL, 10); return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED); } else { return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); } } return 0; }
/* * 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; }
/* Handler für den "/dino/move"-Pfad */ static ssize_t _dino_move(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { (void)ctx; /* Wenn die Anfrage eine POST-Anfrage war */ if (coap_method2flag(coap_get_code_detail(pdu)) == COAP_POST) { /* Wiederverwende den GPIO-IRQ-Callback um den Dino zu bewegen */ _toggle_dino(NULL); /* Sende eine Antwort, dass die Anfrage erfolgreich bearbeitet wurde */ return gcoap_response(pdu, buf, len, COAP_CODE_VALID); } /* sonst */ else { /* lass die Bibliothek das die Antwort erstellen und senden */ return 0; } }
static ssize_t _luke_points(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { unsigned p = 0; unsigned code; (void)ctx; switch (coap_method2flag(coap_get_code_detail(pdu))) { case COAP_GET: { size_t payload_len; gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); mutex_lock(&_points_mutex); payload_len = sprintf((char *)pdu->payload, LUKE_PAYLOAD_FMT, _points); mutex_unlock(&_points_mutex); return gcoap_finish(pdu, payload_len, COAP_FORMAT_JSON); } case COAP_POST: printf("POST %s\n", (char *)pdu->url); if ((pdu->payload_len < LUKE_PAYLOAD_MIN_SIZE) || (pdu->payload_len > LUKE_PAYLOAD_MAX_SIZE) || (pdu->content_type != COAP_FORMAT_JSON) || (sscanf((char *)pdu->payload, LUKE_PAYLOAD_FMT, &p) != 1)) { printf("(%u < %u) || (%u > %u) || (%u != %u) || " "(payload unparsable)\n", pdu->payload_len, LUKE_PAYLOAD_MIN_SIZE, pdu->payload_len, LUKE_PAYLOAD_MAX_SIZE, pdu->content_type, COAP_FORMAT_JSON); code = COAP_CODE_BAD_REQUEST; } else { code = COAP_CODE_VALID; _increment_points(p); } puts("Sending response"); return gcoap_response(pdu, buf, len, code); default: return 0; } }
/* * 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; }