ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len) { if (coap_get_code_class(pkt) != COAP_REQ) { DEBUG("coap_handle_req(): not a request.\n"); return -EBADMSG; } if (pkt->hdr->code == 0) { return coap_build_reply(pkt, COAP_CODE_EMPTY, resp_buf, resp_buf_len, 0); } unsigned method_flag = coap_method2flag(coap_get_code_detail(pkt)); for (unsigned i = 0; i < coap_resources_numof; i++) { const coap_resource_t *resource = &coap_resources[i]; if (!(resource->methods & method_flag)) { continue; } int res = strcmp((char *)pkt->url, resource->path); if (res > 0) { continue; } else if (res < 0) { break; } else { return resource->handler(pkt, resp_buf, resp_buf_len, resource->context); } } return coap_build_reply(pkt, COAP_CODE_404, resp_buf, resp_buf_len, 0); }
/* * 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; }
/* 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; } }