Skip to content

Commit da014c7

Browse files
committed
examples/unicoap_server: add sample unicoap server application
1 parent c4fd9a8 commit da014c7

File tree

5 files changed

+478
-0
lines changed

5 files changed

+478
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Default Makefile, for unicoap message APIs
2+
3+
# name of your application
4+
APPLICATION = unicoap_server
5+
6+
# If no BOARD is found in the environment, use this default:
7+
BOARD ?= native
8+
9+
# This has to be the absolute path to the RIOT base directory:
10+
RIOTBASE ?= $(CURDIR)/../../../..
11+
12+
# Include packages that pull up and auto-init the link layer.
13+
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
14+
USEMODULE += netdev_default
15+
16+
# use GNRC by default
17+
LWIP_IPV4 ?= 0
18+
LWIP_IPV6 ?= 0
19+
20+
ifeq (,$(filter 1, $(LWIP_IPV4) $(LWIP_IPV6)))
21+
USEMODULE += auto_init_gnrc_netif
22+
# Specify the mandatory networking modules
23+
USEMODULE += gnrc_ipv6_default
24+
# Additional networking modules that can be dropped if not needed
25+
USEMODULE += gnrc_icmpv6_echo
26+
else
27+
ifeq (1,$(LWIP_IPV4))
28+
USEMODULE += ipv4_addr
29+
30+
USEMODULE += lwip_arp
31+
USEMODULE += lwip_ipv4
32+
USEMODULE += lwip_dhcp_auto
33+
CFLAGS += -DETHARP_SUPPORT_STATIC_ENTRIES=1
34+
endif
35+
36+
ifeq (1,$(LWIP_IPV6))
37+
USEMODULE += ipv6_addr
38+
39+
USEMODULE += lwip_ipv6
40+
USEMODULE += lwip_ipv6_autoconfig
41+
endif
42+
endif
43+
44+
USEMODULE += unicoap
45+
USEMODULE += unicoap_resources_xfa
46+
47+
# This module is needed for CoAP over UDP
48+
USEMODULE += unicoap_driver_udp
49+
50+
# This module is needed for CoAP over DTLS
51+
USEMODULE += unicoap_driver_dtls
52+
53+
# It is okay to import only either of the CoAP over UDP and CoAP over DTLS drivers.
54+
55+
# Comment this out to disable code in RIOT that does safety checking
56+
# which is not needed in a production environment but helps in the
57+
# development process:
58+
DEVELHELP ?= 1
59+
60+
# Change this to 0 show compiler invocation lines by default:
61+
QUIET ?= 1
62+
63+
include $(RIOTBASE)/Makefile.include
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_UNICOAP_DEBUG_LOGGING=y
2+
CONFIG_UNICOAP_ASSIST=y
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env python3
2+
3+
import logging
4+
import asyncio
5+
import sys
6+
from argparse import ArgumentParser, Namespace
7+
8+
from aiocoap import *
9+
import aiocoap.resource as resource
10+
11+
logging.basicConfig(level=logging.DEBUG)
12+
13+
print("usage: client.py -m <GET|PUT|POST|DELETE|PATCH|iPATCH|FETCH> -u <URI> [--type <NON|CON>] [--observe] [-p <PAYLOAD>]")
14+
15+
def _get(_list, i, default):
16+
return _list[i] if len(_list) > i else default
17+
18+
def message_type(arg):
19+
return { "CON": CON, "NON": NON }[arg]
20+
21+
def method(arg):
22+
return {
23+
"GET": GET,
24+
"PUT": PUT,
25+
"POST": POST,
26+
"DELETE": DELETE,
27+
"PATCH": PATCH,
28+
"iPATCH": iPATCH,
29+
"FETCH": FETCH
30+
}[arg]
31+
32+
async def main():
33+
parser = ArgumentParser()
34+
35+
parser.add_argument(
36+
"-m", "--method",
37+
help='GET|PUT|POST|DELETE|PATCH|iPATCH|FETCH',
38+
required=True)
39+
40+
parser.add_argument(
41+
"-u", "--uri",
42+
help='URI',
43+
required=True)
44+
45+
parser.add_argument(
46+
"-t", "--type",
47+
help='NON|CON',
48+
default="NON")
49+
50+
parser.add_argument(
51+
"--observe",
52+
action="store_true",
53+
help='Register for notifications',
54+
default=False)
55+
56+
parser.add_argument(
57+
"--observe-cancel",
58+
action="store_true",
59+
help='Cancel notifications',
60+
default=False)
61+
62+
parser.add_argument(
63+
"-p", "--payload",
64+
help='Payload',
65+
default=None)
66+
67+
args = parser.parse_args()
68+
69+
observeValue = None
70+
71+
if args.observe and args.observe_cancel:
72+
raise ValueError("Cannot register for and cancel notifications")
73+
74+
if args.observe:
75+
observeValue = 0
76+
77+
elif args.observe_cancel:
78+
observeValue = 1
79+
80+
print(f"using {message_type(args.type)} {method(args.method)} request");
81+
82+
port = 5600
83+
protocol = await Context.create_server_context(bind=("::", port), site=resource.Site())
84+
protocol.client_credentials.load_from_dict({
85+
'*': {
86+
'dtls': {
87+
'psk': b'secretPSK',
88+
'client-identity': b'Client_identity',
89+
}
90+
}
91+
})
92+
93+
request = Message(
94+
mtype=message_type(args.type),
95+
code=method(args.method),
96+
uri=args.uri,
97+
payload=bytes(args.payload, 'utf-8') if args.payload else "",
98+
observe=observeValue
99+
)
100+
101+
try:
102+
pr = protocol.request(request)
103+
104+
r = await pr.response
105+
print("response: %s\n%r" % (r.code, r.payload))
106+
107+
if args.observe:
108+
print("waiting for resource notifications")
109+
async for r in pr.observation:
110+
print("notification: %s\n%r" % (r, r.payload))
111+
break;
112+
113+
except Exception as e:
114+
print("error:")
115+
print(e)
116+
117+
if __name__ == "__main__":
118+
asyncio.run(main())

0 commit comments

Comments
 (0)