diff --git a/examples/gcoap/README.md b/examples/gcoap/README.md index ad0abd1aa1a6..b7e9139e35dd 100644 --- a/examples/gcoap/README.md +++ b/examples/gcoap/README.md @@ -56,9 +56,21 @@ Start the libcoap example server with the command below. ./coap-server -Enter the query below in the RIOT CLI. +\ +Below are some example queries to enter into the RIOT CLI. Ports can be omitted. +The port defaults to 5683 for the `gcoap` and to 5684 for the `gcoap_dtls` example. - > coap get fe80::d8b8:65ff:feee:121b%6 5683 /.well-known/core +- For IPv6 setup (network interface can be omitted) + + > coap get [fe80::d8b8:65ff:feee:121b%6]:5683 /.well-known/core + +- For IPv4 setup + + > coap get 192.168.2.135:5683 /.well-known/core + +- When including the module `sock_dns` for domain resolution + + > coap get example.com:5683 /.well-known/core CLI output: diff --git a/examples/gcoap/client.c b/examples/gcoap/client.c index 370c1c74c317..8c4275c485b1 100644 --- a/examples/gcoap/client.c +++ b/examples/gcoap/client.c @@ -15,6 +15,7 @@ * * @author Ken Bannister * @author Hauke Petersen + * @author Hendrik van Essen * * @} */ @@ -24,8 +25,11 @@ #include #include +#include + #include "fmt.h" #include "net/gcoap.h" +#include "net/sock/util.h" #include "net/utils.h" #include "od.h" @@ -141,59 +145,7 @@ static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu, } } -static bool _parse_endpoint(sock_udp_ep_t *remote, const char *addr_str, const char *port_str) -{ - bool is_ipv4 = false; - bool is_ipv6 = false; - - if (IS_ACTIVE(SOCK_HAS_IPV6)) { - netif_t *netif; - /* IPv6 might contain '.', but IPv4 cannot contain ':' */ - if (strstr(addr_str, ":") != NULL) { - - /* parse hostname */ - if (netutils_get_ipv6((ipv6_addr_t *)&remote->addr, &netif, addr_str) < 0) { - puts("gcoap_cli: unable to parse destination ipv6 address"); - return false; - } - - is_ipv6 = true; - remote->netif = netif ? netif_get_id(netif) : SOCK_ADDR_ANY_NETIF; - remote->family = AF_INET6; - } - } - - if (IS_ACTIVE(SOCK_HAS_IPV4)) { - if (!is_ipv6 && strstr(addr_str, ".") != NULL) { /* IPv4 */ - - /* parse hostname */ - if (netutils_get_ipv4((ipv4_addr_t *)&remote->addr, addr_str) < 0) { - puts("gcoap_cli: unable to parse destination ipv4 address"); - return false; - } - - is_ipv4 = true; - remote->netif = SOCK_ADDR_ANY_NETIF; - remote->family = AF_INET; - } - } - - if (!is_ipv4 && !is_ipv6) { - puts("gcoap_cli: unable to parse destination address"); - return false; - } - - /* parse port */ - remote->port = atoi(port_str); - if (remote->port == 0) { - puts("gcoap_cli: unable to parse destination port"); - return false; - } - - return true; -} - -static size_t _send(uint8_t *buf, size_t len, char *addr_str, char *port_str) +static size_t _send(uint8_t *buf, size_t len, char *addr_str) { size_t bytes_sent; sock_udp_ep_t *remote; @@ -203,9 +155,19 @@ static size_t _send(uint8_t *buf, size_t len, char *addr_str, char *port_str) remote = &_proxy_remote; } else { - if (!_parse_endpoint(&new_remote, addr_str, port_str)) { + if (sock_udp_name2ep(&new_remote, addr_str) != 0) { return 0; } + + if (new_remote.port == 0) { + if (IS_USED(MODULE_GCOAP_DTLS)) { + new_remote.port = CONFIG_GCOAPS_PORT; + } + else { + new_remote.port = CONFIG_GCOAP_PORT; + } + } + remote = &new_remote; } @@ -257,28 +219,13 @@ int gcoap_cli_cmd(int argc, char **argv) #else char addrstr[IPV4_ADDR_MAX_STR_LEN]; #endif + inet_ntop(_proxy_remote.family, &_proxy_remote.addr, addrstr, sizeof(addrstr)); - switch (_proxy_remote.family) { -#ifdef SOCK_HAS_IPV4 - case AF_INET: - printf("%s:%u\n", - ipv4_addr_to_str(addrstr, - (ipv4_addr_t *) &_proxy_remote.addr.ipv4, - sizeof(addrstr)), - _proxy_remote.port); - break; -#endif -#ifdef SOCK_HAS_IPV6 - case AF_INET6: - printf("[%s]:%u\n", - ipv6_addr_to_str(addrstr, - (ipv6_addr_t *) &_proxy_remote.addr.ipv6, - sizeof(addrstr)), - _proxy_remote.port); - break; -#endif - default: - assert(0); + if (_proxy_remote.family == AF_INET6) { + printf("[%s]:%u\n", addrstr, _proxy_remote.port); + } + else { + printf("%s:%u\n", addrstr, _proxy_remote.port); } } else { @@ -287,11 +234,21 @@ int gcoap_cli_cmd(int argc, char **argv) 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])) { + if ((argc == 4) && (strcmp(argv[2], "set") == 0)) { + if (sock_udp_name2ep(&_proxy_remote, argv[3]) != 0) { puts("Could not set proxy"); return 1; } + + if (_proxy_remote.port == 0) { + if (IS_USED(MODULE_GCOAP_DTLS)) { + _proxy_remote.port = CONFIG_GCOAPS_PORT; + } + else { + _proxy_remote.port = CONFIG_GCOAP_PORT; + } + } + _proxied = true; return 0; } @@ -300,15 +257,7 @@ int gcoap_cli_cmd(int argc, char **argv) _proxied = false; return 0; } - - if (IS_ACTIVE(SOCK_HAS_IPV4)) { - printf("usage: %s proxy set \n", argv[0]); - } - - if (IS_ACTIVE(SOCK_HAS_IPV6)) { - printf("usage: %s proxy set [%%iface] \n", argv[0]); - } - + printf("usage: %s proxy set [:port]\n", argv[0]); printf(" %s proxy unset\n", argv[0]); return 1; } @@ -333,27 +282,49 @@ int gcoap_cli_cmd(int argc, char **argv) apos++; } - if (((argc == apos + 2) && (code_pos == 0)) || /* ping */ - ((argc == apos + 3) && (code_pos == 1)) || /* get */ - ((argc == apos + 3 || - argc == apos + 4) && (code_pos > 1))) { /* post or put */ + if (((argc == apos + 1) && (code_pos == 0)) || /* ping */ + ((argc == apos + 2) && (code_pos == 1)) || /* get */ + ((argc == apos + 2 || + argc == apos + 3) && (code_pos > 1))) { /* post or put */ char *uri = NULL; int uri_len = 0; if (code_pos) { - uri = argv[apos+2]; - uri_len = strlen(argv[apos+2]); + uri = argv[apos+1]; + uri_len = strlen(argv[apos+1]); } if (_proxied) { - /* IPv6 might contain '.', but IPv4 cannot contain ':' */ - if (strstr(argv[apos], ":") != NULL) { - uri_len = snprintf(proxy_uri, 64, "coap://[%s]:%s%s", - argv[apos], argv[apos+1], uri); + sock_udp_ep_t tmp_remote; + if (sock_udp_name2ep(&tmp_remote, argv[apos]) != 0) { + return _print_usage(argv); + } + + if (tmp_remote.port == 0) { + if (IS_USED(MODULE_GCOAP_DTLS)) { + tmp_remote.port = CONFIG_GCOAPS_PORT; + } + else { + tmp_remote.port = CONFIG_GCOAP_PORT; + } + } + +#ifdef SOCK_HAS_IPV6 + char addrstr[IPV6_ADDR_MAX_STR_LEN]; +#else + char addrstr[IPV4_ADDR_MAX_STR_LEN]; +#endif + inet_ntop(tmp_remote.family, &tmp_remote.addr, addrstr, sizeof(addrstr)); + + if (tmp_remote.family == AF_INET6) { + uri_len = snprintf(proxy_uri, sizeof(proxy_uri), "coap://[%s]:%d%s", + addrstr, tmp_remote.port, uri); } else { - uri_len = snprintf(proxy_uri, 64, "coap://%s:%s%s", argv[apos], argv[apos+1], uri); + uri_len = snprintf(proxy_uri, sizeof(proxy_uri), "coap://%s:%d%s", + addrstr, tmp_remote.port, uri); } + uri = proxy_uri; gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos, NULL); @@ -368,7 +339,7 @@ int gcoap_cli_cmd(int argc, char **argv) memcpy(_last_req_path, uri, uri_len); } - size_t paylen = (argc == apos + 4) ? strlen(argv[apos+3]) : 0; + size_t paylen = (argc == apos + 3) ? strlen(argv[apos+2]) : 0; if (paylen) { coap_opt_add_format(&pdu, COAP_FORMAT_TEXT); } @@ -380,7 +351,7 @@ int gcoap_cli_cmd(int argc, char **argv) if (paylen) { len = coap_opt_finish(&pdu, COAP_OPT_FINISH_PAYLOAD); if (pdu.payload_len >= paylen) { - memcpy(pdu.payload, argv[apos+3], paylen); + memcpy(pdu.payload, argv[apos+2], paylen); len += paylen; } else { @@ -394,7 +365,7 @@ int gcoap_cli_cmd(int argc, char **argv) printf("gcoap_cli: sending msg ID %u, %u bytes\n", coap_get_id(&pdu), (unsigned) len); - if (!_send(&buf[0], len, argv[apos], argv[apos+1])) { + if (!_send(&buf[0], len, argv[apos])) { puts("gcoap_cli: msg send failed"); } else { @@ -404,18 +375,9 @@ int gcoap_cli_cmd(int argc, char **argv) return 0; } else { - if (IS_ACTIVE(SOCK_HAS_IPV4)) { - printf("usage: %s [-c] [data]\n", - argv[0]); - printf(" %s ping \n", argv[0]); - } - - if (IS_ACTIVE(SOCK_HAS_IPV6)) { - printf("usage: %s [-c] [%%iface] [data]\n", - argv[0]); - printf(" %s ping [%%iface] \n", argv[0]); - } - + printf("usage: %s [-c] [:port] [data]\n", + argv[0]); + printf(" %s ping [:port]\n", argv[0]); printf("Options\n"); printf(" -c Send confirmably (defaults to non-confirmable)\n"); return 1;