examples/gcoap: add handling of proxied requests
This commit is contained in:
parent
50900a1fbe
commit
7cda842a00
@ -30,6 +30,10 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
static bool _proxied = false;
|
||||||
|
static sock_udp_ep_t _proxy_remote;
|
||||||
|
static char proxy_uri[64];
|
||||||
|
|
||||||
static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
|
static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
|
||||||
size_t maxlen, coap_link_encoder_ctx_t *context);
|
size_t maxlen, coap_link_encoder_ctx_t *context);
|
||||||
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
|
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
|
||||||
@ -58,7 +62,7 @@ static gcoap_listener_t _listener = {
|
|||||||
/* Retain request path to re-request if response includes block. User must not
|
/* Retain request path to re-request if response includes block. User must not
|
||||||
* start a new request (with a new path) until any blockwise transfer
|
* start a new request (with a new path) until any blockwise transfer
|
||||||
* completes or times out. */
|
* completes or times out. */
|
||||||
#define _LAST_REQ_PATH_MAX (32)
|
#define _LAST_REQ_PATH_MAX (64)
|
||||||
static char _last_req_path[_LAST_REQ_PATH_MAX];
|
static char _last_req_path[_LAST_REQ_PATH_MAX];
|
||||||
|
|
||||||
/* Counts requests sent by CLI. */
|
/* Counts requests sent by CLI. */
|
||||||
@ -137,13 +141,25 @@ static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_proxied) {
|
||||||
|
gcoap_req_init(pdu, (uint8_t *)pdu->hdr, CONFIG_GCOAP_PDU_BUF_SIZE,
|
||||||
|
COAP_METHOD_GET, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
gcoap_req_init(pdu, (uint8_t *)pdu->hdr, CONFIG_GCOAP_PDU_BUF_SIZE,
|
gcoap_req_init(pdu, (uint8_t *)pdu->hdr, CONFIG_GCOAP_PDU_BUF_SIZE,
|
||||||
COAP_METHOD_GET, _last_req_path);
|
COAP_METHOD_GET, _last_req_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (msg_type == COAP_TYPE_ACK) {
|
if (msg_type == COAP_TYPE_ACK) {
|
||||||
coap_hdr_set_type(pdu->hdr, COAP_TYPE_CON);
|
coap_hdr_set_type(pdu->hdr, COAP_TYPE_CON);
|
||||||
}
|
}
|
||||||
block.blknum++;
|
block.blknum++;
|
||||||
coap_opt_add_block2_control(pdu, &block);
|
coap_opt_add_block2_control(pdu, &block);
|
||||||
|
|
||||||
|
if (_proxied) {
|
||||||
|
coap_opt_add_proxy_uri(pdu, _last_req_path);
|
||||||
|
}
|
||||||
|
|
||||||
int len = coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
|
int len = coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
|
||||||
gcoap_req_send((uint8_t *)pdu->hdr, len, remote,
|
gcoap_req_send((uint8_t *)pdu->hdr, len, remote,
|
||||||
_resp_handler, memo->context);
|
_resp_handler, memo->context);
|
||||||
@ -214,52 +230,70 @@ static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, vo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _send(uint8_t *buf, size_t len, char *addr_str, char *port_str)
|
static bool _parse_endpoint(sock_udp_ep_t *remote,
|
||||||
|
char *addr_str, char *port_str)
|
||||||
{
|
{
|
||||||
ipv6_addr_t addr;
|
ipv6_addr_t addr;
|
||||||
size_t bytes_sent;
|
remote->family = AF_INET6;
|
||||||
sock_udp_ep_t remote;
|
|
||||||
|
|
||||||
remote.family = AF_INET6;
|
|
||||||
|
|
||||||
/* parse for interface */
|
/* parse for interface */
|
||||||
char *iface = ipv6_addr_split_iface(addr_str);
|
char *iface = ipv6_addr_split_iface(addr_str);
|
||||||
if (!iface) {
|
if (!iface) {
|
||||||
if (gnrc_netif_numof() == 1) {
|
if (gnrc_netif_numof() == 1) {
|
||||||
/* assign the single interface found in gnrc_netif_numof() */
|
/* assign the single interface found in gnrc_netif_numof() */
|
||||||
remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
|
remote->netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
remote.netif = SOCK_ADDR_ANY_NETIF;
|
remote->netif = SOCK_ADDR_ANY_NETIF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int pid = atoi(iface);
|
int pid = atoi(iface);
|
||||||
if (gnrc_netif_get_by_pid(pid) == NULL) {
|
if (gnrc_netif_get_by_pid(pid) == NULL) {
|
||||||
puts("gcoap_cli: interface not valid");
|
puts("gcoap_cli: interface not valid");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
remote.netif = pid;
|
remote->netif = pid;
|
||||||
}
|
}
|
||||||
/* parse destination address */
|
/* parse destination address */
|
||||||
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
||||||
puts("gcoap_cli: unable to parse destination address");
|
puts("gcoap_cli: unable to parse destination address");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
if ((remote.netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) {
|
if ((remote->netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) {
|
||||||
puts("gcoap_cli: must specify interface for link local target");
|
puts("gcoap_cli: must specify interface for link local target");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8));
|
memcpy(&remote->addr.ipv6[0], &addr.u8[0], sizeof(addr.u8));
|
||||||
|
|
||||||
/* parse port */
|
/* parse port */
|
||||||
remote.port = atoi(port_str);
|
remote->port = atoi(port_str);
|
||||||
if (remote.port == 0) {
|
if (remote->port == 0) {
|
||||||
puts("gcoap_cli: unable to parse destination port");
|
puts("gcoap_cli: unable to parse destination port");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_sent = gcoap_req_send(buf, len, &remote, _resp_handler, NULL);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _send(uint8_t *buf, size_t len, char *addr_str, char *port_str)
|
||||||
|
{
|
||||||
|
size_t bytes_sent;
|
||||||
|
|
||||||
|
sock_udp_ep_t *remote;
|
||||||
|
|
||||||
|
if (_proxied) {
|
||||||
|
remote = &_proxy_remote;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sock_udp_ep_t new_remote;
|
||||||
|
if (!_parse_endpoint(&new_remote, addr_str, port_str)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
remote = &new_remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_sent = gcoap_req_send(buf, len, remote, _resp_handler, NULL);
|
||||||
if (bytes_sent > 0) {
|
if (bytes_sent > 0) {
|
||||||
req_count++;
|
req_count++;
|
||||||
}
|
}
|
||||||
@ -285,10 +319,40 @@ int gcoap_cli_cmd(int argc, char **argv)
|
|||||||
printf("CoAP server is listening on port %u\n", CONFIG_GCOAP_PORT);
|
printf("CoAP server is listening on port %u\n", CONFIG_GCOAP_PORT);
|
||||||
printf(" CLI requests sent: %u\n", req_count);
|
printf(" CLI requests sent: %u\n", req_count);
|
||||||
printf("CoAP open requests: %u\n", open_reqs);
|
printf("CoAP open requests: %u\n", open_reqs);
|
||||||
|
printf("Configured Proxy: ");
|
||||||
|
if (_proxied) {
|
||||||
|
char addrstr[IPV6_ADDR_MAX_STR_LEN];
|
||||||
|
printf("[%s]:%u\n",
|
||||||
|
ipv6_addr_to_str(addrstr,
|
||||||
|
(ipv6_addr_t *) &_proxy_remote.addr.ipv6,
|
||||||
|
sizeof(addrstr)),
|
||||||
|
_proxy_remote.port);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("None");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[1], "proxy") == 0) {
|
||||||
|
if ((argc == 5) && (strcmp(argv[2], "set") == 0)) {
|
||||||
|
if (!_parse_endpoint(&_proxy_remote, argv[3], argv[4])) {
|
||||||
|
puts("Could not set proxy");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
_proxied = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((argc == 3) && (strcmp(argv[2], "unset") == 0)) {
|
||||||
|
memset(&_proxy_remote, 0, sizeof(_proxy_remote));
|
||||||
|
_proxied = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf("usage: %s proxy set <addr>[%%iface] <port>\n", argv[0]);
|
||||||
|
printf(" %s proxy unset\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* if not 'info', must be a method code */
|
/* if not 'info' and 'proxy', must be a method code */
|
||||||
int code_pos = -1;
|
int code_pos = -1;
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(method_codes); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(method_codes); i++) {
|
||||||
if (strcmp(argv[1], method_codes[i]) == 0) {
|
if (strcmp(argv[1], method_codes[i]) == 0) {
|
||||||
@ -314,17 +378,36 @@ int gcoap_cli_cmd(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
if (((argc == apos + 3) && (code_pos == 0)) ||
|
if (((argc == apos + 3) && (code_pos == 0)) ||
|
||||||
((argc == apos + 4) && (code_pos != 0))) {
|
((argc == apos + 4) && (code_pos != 0))) {
|
||||||
gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos+1, argv[apos+2]);
|
|
||||||
|
char *uri = argv[apos+2];
|
||||||
|
int uri_len = strlen(argv[apos+2]);
|
||||||
|
|
||||||
|
if (_proxied) {
|
||||||
|
uri_len = snprintf(proxy_uri, 64, "coap://[%s]:%s%s", argv[apos], argv[apos+1], uri);
|
||||||
|
uri = proxy_uri;
|
||||||
|
|
||||||
|
gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos+1, NULL);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos+1, uri);
|
||||||
|
}
|
||||||
coap_hdr_set_type(pdu.hdr, msg_type);
|
coap_hdr_set_type(pdu.hdr, msg_type);
|
||||||
|
|
||||||
memset(_last_req_path, 0, _LAST_REQ_PATH_MAX);
|
memset(_last_req_path, 0, _LAST_REQ_PATH_MAX);
|
||||||
if (strlen(argv[apos+2]) < _LAST_REQ_PATH_MAX) {
|
if (uri_len < _LAST_REQ_PATH_MAX) {
|
||||||
memcpy(_last_req_path, argv[apos+2], strlen(argv[apos+2]));
|
memcpy(_last_req_path, uri, uri_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t paylen = (argc == apos + 4) ? strlen(argv[apos+3]) : 0;
|
size_t paylen = (argc == apos + 4) ? strlen(argv[apos+3]) : 0;
|
||||||
if (paylen) {
|
if (paylen) {
|
||||||
coap_opt_add_format(&pdu, COAP_FORMAT_TEXT);
|
coap_opt_add_format(&pdu, COAP_FORMAT_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_proxied) {
|
||||||
|
coap_opt_add_proxy_uri(&pdu, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paylen) {
|
||||||
len = coap_opt_finish(&pdu, COAP_OPT_FINISH_PAYLOAD);
|
len = coap_opt_finish(&pdu, COAP_OPT_FINISH_PAYLOAD);
|
||||||
if (pdu.payload_len >= paylen) {
|
if (pdu.payload_len >= paylen) {
|
||||||
memcpy(pdu.payload, argv[apos+3], paylen);
|
memcpy(pdu.payload, argv[apos+3], paylen);
|
||||||
@ -374,7 +457,7 @@ int gcoap_cli_cmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
printf("usage: %s <get|post|put|info>\n", argv[0]);
|
printf("usage: %s <get|post|put|proxy|info>\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user