Skip to content

Commit 4d00949

Browse files
committed
examples/unicoap_server: add sample unicoap server application
1 parent 5503d4f commit 4d00949

File tree

6 files changed

+484
-0
lines changed

6 files changed

+484
-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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
BOARD_INSUFFICIENT_MEMORY := \
2+
arduino-duemilanove \
3+
arduino-nano \
4+
arduino-uno \
5+
atmega328p \
6+
atmega328p-xplained-mini \
7+
atmega8 \
8+
#
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: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env python3
2+
3+
import logging
4+
import asyncio
5+
from argparse import ArgumentParser
6+
7+
from aiocoap import CON, NON, GET, PUT, POST, DELETE, PATCH, iPATCH, FETCH, Context, Message
8+
import aiocoap.resource as resource
9+
10+
logging.basicConfig(level=logging.DEBUG)
11+
12+
print(
13+
"usage: client.py" +
14+
" -m <GET|PUT|POST|DELETE|PATCH|iPATCH|FETCH>" +
15+
" -u <URI>" +
16+
" [--type <NON|CON>] [--observe] [-p <PAYLOAD>]")
17+
18+
19+
def _get(_list, i, default):
20+
return _list[i] if len(_list) > i else default
21+
22+
23+
def message_type(arg):
24+
return {"CON": CON, "NON": NON}[arg]
25+
26+
27+
def method(arg):
28+
return {
29+
"GET": GET,
30+
"PUT": PUT,
31+
"POST": POST,
32+
"DELETE": DELETE,
33+
"PATCH": PATCH,
34+
"iPATCH": iPATCH,
35+
"FETCH": FETCH
36+
}[arg]
37+
38+
39+
async def main():
40+
parser = ArgumentParser()
41+
42+
parser.add_argument(
43+
"-m", "--method",
44+
help='GET|PUT|POST|DELETE|PATCH|iPATCH|FETCH',
45+
required=True)
46+
47+
parser.add_argument(
48+
"-u", "--uri",
49+
help='URI',
50+
required=True)
51+
52+
parser.add_argument(
53+
"-t", "--type",
54+
help='NON|CON',
55+
default="NON")
56+
57+
parser.add_argument(
58+
"--observe",
59+
action="store_true",
60+
help='Register for notifications',
61+
default=False)
62+
63+
parser.add_argument(
64+
"--observe-cancel",
65+
action="store_true",
66+
help='Cancel notifications',
67+
default=False)
68+
69+
parser.add_argument(
70+
"-p", "--payload",
71+
help='Payload',
72+
default=None)
73+
74+
args = parser.parse_args()
75+
76+
observeValue = None
77+
78+
if args.observe and args.observe_cancel:
79+
raise ValueError("Cannot register for and cancel notifications")
80+
81+
if args.observe:
82+
observeValue = 0
83+
84+
elif args.observe_cancel:
85+
observeValue = 1
86+
87+
print(f"using {message_type(args.type)} {method(args.method)} request")
88+
89+
port = 5600
90+
protocol = await Context.create_server_context(bind=("::", port), site=resource.Site())
91+
protocol.client_credentials.load_from_dict({
92+
'*': {
93+
'dtls': {
94+
'psk': b'secretPSK',
95+
'client-identity': b'Client_identity',
96+
}
97+
}
98+
})
99+
100+
request = Message(
101+
mtype=message_type(args.type),
102+
code=method(args.method),
103+
uri=args.uri,
104+
payload=bytes(args.payload, 'utf-8') if args.payload else "",
105+
observe=observeValue
106+
)
107+
108+
try:
109+
pr = protocol.request(request)
110+
111+
r = await pr.response
112+
print("response: %s\n%r" % (r.code, r.payload))
113+
114+
if args.observe:
115+
print("waiting for resource notifications")
116+
117+
async for r in pr.observation:
118+
print("notification: %s\n%r" % (r, r.payload))
119+
break
120+
121+
except Exception as e:
122+
print("error:")
123+
print(e)
124+
125+
if __name__ == "__main__":
126+
asyncio.run(main())

0 commit comments

Comments
 (0)