Skip to content

Commit 7da09f6

Browse files
committed
Add COAP example
Adds a COAP client and server example. Requires libcoap and tinydtls.
1 parent 84e8d48 commit 7da09f6

16 files changed

+1406
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ App|Description
196196
[picow_http_client](pico_w/wifi/http_client) | Demonstrates how to make http and https requests
197197
[picow_http_client_verify](pico_w/wifi/http_client) | Demonstrates how to make a https request with server authentication
198198
[picow_mqtt_client](pico_w/wifi/mqtt) | Demonstrates how to implement a MQTT client application
199+
[picow_coap](pico_w/wifi/mqtt) | Demonstrates how to implment a COAP client
199200

200201
#### FreeRTOS examples
201202

pico_w/wifi/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ else()
1919
add_subdirectory_exclude_platforms(udp_beacon)
2020
add_subdirectory_exclude_platforms(http_client)
2121
add_subdirectory_exclude_platforms(mqtt)
22+
add_subdirectory_exclude_platforms(coap)
2223

2324
if (NOT PICO_MBEDTLS_PATH)
2425
message("Skipping tls examples as PICO_MBEDTLS_PATH is not defined")

pico_w/wifi/coap/CMakeLists.txt

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
if (DEFINED ENV{COAP_SERVER} AND NOT COAP_SERVER)
2+
set(COAP_SERVER $ENV{COAP_SERVER})
3+
message("Using COAP_SERVER from environment ('${COAP_SERVER}')")
4+
endif()
5+
if (NOT COAP_SERVER)
6+
message("Skipping COAP example as COAP_SERVER is not defined")
7+
return()
8+
endif()
9+
set(COAP_SERVER "${COAP_SERVER}" CACHE INTERNAL "COAP server for examples")
10+
if (DEFINED ENV{LIB_COAP_DIR} AND NOT LIB_COAP_DIR)
11+
set(LIB_COAP_DIR $ENV{LIB_COAP_DIR})
12+
endif()
13+
if (NOT LIB_COAP_DIR)
14+
message("Skipping COAP example as LIB_COAP_DIR is not defined")
15+
return()
16+
endif()
17+
set(LIB_COAP_DIR "${LIB_COAP_DIR}" CACHE INTERNAL "LIB_COAP_DIR for examples")
18+
if (DEFINED ENV{LIB_TINYDTLS_DIR} AND NOT LIB_TINYDTLS_DIR)
19+
set(LIB_TINYDTLS_DIR $ENV{LIB_TINYDTLS_DIR})
20+
endif()
21+
if (NOT LIB_TINYDTLS_DIR)
22+
message("Skipping COAP example as LIB_TINYDTLS_DIR is not defined")
23+
return()
24+
endif()
25+
set(LIB_TINYDTLS_DIR "${LIB_TINYDTLS_DIR}" CACHE INTERNAL "LIB_TINYDTLS_DIR for examples")
26+
include(libcoap.cmake)
27+
include(libtinydtls.cmake)
28+
29+
set(TARGET_NAME coap_server)
30+
add_executable(${TARGET_NAME}
31+
coap_server.c
32+
)
33+
target_include_directories(${TARGET_NAME} PRIVATE
34+
${CMAKE_CURRENT_LIST_DIR}
35+
${CMAKE_CURRENT_LIST_DIR}/.. # for our common headers
36+
)
37+
target_link_libraries(${TARGET_NAME} PRIVATE
38+
pico_cyw43_arch_lwip_threadsafe_background
39+
pico_async_context_threadsafe_background
40+
pico_lwip_nosys
41+
pico_stdlib
42+
pico_coap
43+
hardware_adc
44+
pico_tinydtls
45+
)
46+
target_compile_definitions(${TARGET_NAME} PRIVATE
47+
CYW43_HOST_NAME=\"pico_coap_example\"
48+
)
49+
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/certs/${COAP_SERVER}")
50+
target_compile_definitions(${TARGET_NAME} PRIVATE
51+
COAP_CERT_INC=\"certs/${COAP_SERVER}/coap_server.inc\"
52+
)
53+
endif()
54+
target_compile_definitions(${TARGET_NAME} PRIVATE
55+
WIFI_SSID=\"${WIFI_SSID}\"
56+
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
57+
)
58+
pico_add_extra_outputs(${TARGET_NAME})
59+
60+
set(TARGET_NAME coap_client)
61+
add_executable(${TARGET_NAME}
62+
coap_client.c
63+
)
64+
target_include_directories(${TARGET_NAME} PRIVATE
65+
${CMAKE_CURRENT_LIST_DIR}
66+
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts
67+
)
68+
target_link_libraries(${TARGET_NAME} PRIVATE
69+
pico_cyw43_arch_lwip_threadsafe_background
70+
pico_lwip_nosys
71+
pico_stdlib
72+
pico_coap
73+
pico_tinydtls
74+
)
75+
target_compile_definitions(${TARGET_NAME} PRIVATE
76+
COAP_SERVER=\"${COAP_SERVER}\"
77+
)
78+
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/certs/${COAP_SERVER}")
79+
target_compile_definitions(${TARGET_NAME} PRIVATE
80+
COAP_CERT_INC=\"certs/${COAP_SERVER}/coap_client.inc\"
81+
)
82+
endif()
83+
target_compile_definitions(${TARGET_NAME} PRIVATE
84+
WIFI_SSID=\"${WIFI_SSID}\"
85+
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
86+
)
87+
pico_add_extra_outputs(${TARGET_NAME})

pico_w/wifi/coap/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Setup
2+
3+
These examples require libcoap and tinydtls to work. Clone these repos somewhere,,,
4+
5+
```
6+
git clone https://github.com/obgm/libcoap.git
7+
git submodule update --init
8+
```
9+
10+
You can define these paths in environment variables or pass the names to cmake
11+
12+
```
13+
export LIB_COAP_DIR=/home/pi/libcoap
14+
export LIB_TINYDTLS_DIR=/home/pi/tinydtls
15+
```
16+
17+
You also need to define the coap server in another environment variable...
18+
19+
```
20+
export COAP_SERVER=myhost
21+
```
22+
23+
The examples use keys generated by a script in the certs folder...
24+
25+
```
26+
cd certs
27+
./makecerts.sh
28+
```
29+
30+
The code should now build.
31+
tinydtls and this example currently only supports raw public keys.
32+
33+
```
34+
cd libcoap
35+
mkdir build
36+
cd build
37+
cmake .. -DDTLS_BACKEND=tinydtls
38+
make -j8
39+
```
40+
41+
# Coap Client
42+
43+
To test the client you need a server to talk to. The libcoap library comes with the coap-server example that should work.
44+
server.key is generated by the makecerts.sh script above.
45+
46+
```
47+
coap-server -M server.key -v 7
48+
```
49+
50+
The coap client example requests "coap://<COAP_SERVER>/.well-known/core" and subscribes to "coap://<COAP_SERVER>/time" and coap://<COAP_SERVER>/subscribe?123/led
51+
52+
# Coap Server
53+
54+
The coap server example supports the following...
55+
56+
* Find out what requests it supports: coap-client -M client.key -m get coaps://$COAP_SERVER/.well-known/core
57+
* Get the current temperature: coap-client -M client.key -m get coaps://$COAP_SERVER/temp
58+
* Get the current led state: coap-client -M client.key -m get coaps://$COAP_SERVER/led
59+
* Turn the led on: coap-client -M client.key -m put coaps://$COAP_SERVER/led -e 1
60+
* Subscribe to temperature changes: coap-client -M client.key -m get coaps://$COAP_SERVER/temp -s 60 -w
61+
* Get time: coap-client -M client.key -m get coaps://$COAP_SERVER/time
62+
63+
$COAP_SERVER is the name of the coap server.
64+
client.key is generated by the makecerts.sh script above.

pico_w/wifi/coap/certs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*/
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/bash
2+
3+
if [ "${PWD##*/}" != "certs" ]; then
4+
echo Run this in the certs folder
5+
exit 1
6+
fi
7+
if [ -z "$COAP_SERVER" ]; then
8+
echo Define COAP_SERVER
9+
exit 1
10+
fi
11+
SERVER_NAME=$COAP_SERVER
12+
13+
if [ -d "$SERVER_NAME" ]; then
14+
echo Run \"rm -fr $SERVER_NAME\" to regenerate these keys
15+
exit 1
16+
fi
17+
mkdir $SERVER_NAME
18+
echo Generating keys in $PWD/$SERVER_NAME
19+
20+
openssl ecparam -name prime256v1 -genkey -noout -out $SERVER_NAME/client.key
21+
openssl ec -in $SERVER_NAME/client.key -pubout -out $SERVER_NAME/client.pub
22+
23+
echo -n \#define COAP_KEY \" > $SERVER_NAME/coap_client.inc
24+
cat $SERVER_NAME/client.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_client.inc
25+
echo "\"" >> $SERVER_NAME/coap_client.inc
26+
echo >> $SERVER_NAME/coap_client.inc
27+
28+
echo -n \#define COAP_PUB_KEY \" >> $SERVER_NAME/coap_client.inc
29+
cat $SERVER_NAME/client.pub | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_client.inc
30+
echo "\"" >> $SERVER_NAME/coap_client.inc
31+
32+
openssl ecparam -name prime256v1 -genkey -noout -out $SERVER_NAME/server.key
33+
openssl ec -in $SERVER_NAME/server.key -pubout -out $SERVER_NAME/server.pub
34+
35+
echo -n \#define COAP_KEY \" > $SERVER_NAME/coap_server.inc
36+
cat $SERVER_NAME/server.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_server.inc
37+
echo "\"" >> $SERVER_NAME/coap_server.inc
38+
echo >> $SERVER_NAME/coap_server.inc
39+
40+
echo -n \#define COAP_PUB_KEY \" >> $SERVER_NAME/coap_server.inc
41+
cat $SERVER_NAME/server.pub | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_server.inc
42+
echo "\"" >> $SERVER_NAME/coap_server.inc

0 commit comments

Comments
 (0)