Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples/gcoap: replace _parse_endpoint by sock_udp_name2ep #17870

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions examples/gcoap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
186 changes: 74 additions & 112 deletions examples/gcoap/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
* @author Ken Bannister <kb2ma@runbox.com>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*
* @}
*/
Expand All @@ -24,8 +25,11 @@
#include <stdlib.h>
#include <string.h>

#include <arpa/inet.h>

#include "fmt.h"
#include "net/gcoap.h"
#include "net/sock/util.h"
#include "net/utils.h"
#include "od.h"

Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 {
Expand All @@ -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;
}
Expand All @@ -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 <IPv4 addr> <port>\n", argv[0]);
}

if (IS_ACTIVE(SOCK_HAS_IPV6)) {
printf("usage: %s proxy set <IPv6 addr>[%%iface] <port>\n", argv[0]);
}

printf("usage: %s proxy set <host>[:port]\n", argv[0]);
printf(" %s proxy unset\n", argv[0]);
return 1;
}
Expand All @@ -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) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it would also be possible to remove the port completely from the string.

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);
Expand All @@ -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);
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -404,18 +375,9 @@ int gcoap_cli_cmd(int argc, char **argv)
return 0;
}
else {
if (IS_ACTIVE(SOCK_HAS_IPV4)) {
printf("usage: %s <get|post|put> [-c] <IPv4 addr> <port> <path> [data]\n",
argv[0]);
printf(" %s ping <IPv4 addr> <port>\n", argv[0]);
}

if (IS_ACTIVE(SOCK_HAS_IPV6)) {
printf("usage: %s <get|post|put> [-c] <IPv6 addr>[%%iface] <port> <path> [data]\n",
argv[0]);
printf(" %s ping <IPv6 addr>[%%iface] <port>\n", argv[0]);
}

printf("usage: %s <get|post|put> [-c] <host>[:port] <path> [data]\n",
argv[0]);
printf(" %s ping <host>[:port]\n", argv[0]);
printf("Options\n");
printf(" -c Send confirmably (defaults to non-confirmable)\n");
return 1;
Expand Down