Skip to content

Add COAP example #616

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

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ App|Description
[picow_http_client](pico_w/wifi/http_client) | Demonstrates how to make http and https requests
[picow_http_client_verify](pico_w/wifi/http_client) | Demonstrates how to make a https request with server authentication
[picow_mqtt_client](pico_w/wifi/mqtt) | Demonstrates how to implement a MQTT client application
[picow_coap](pico_w/wifi/mqtt) | Demonstrates how to implment a COAP client

#### FreeRTOS examples

Expand Down
1 change: 1 addition & 0 deletions pico_w/wifi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ else()
add_subdirectory_exclude_platforms(udp_beacon)
add_subdirectory_exclude_platforms(http_client)
add_subdirectory_exclude_platforms(mqtt)
add_subdirectory_exclude_platforms(coap)

if (NOT PICO_MBEDTLS_PATH)
message("Skipping tls examples as PICO_MBEDTLS_PATH is not defined")
Expand Down
87 changes: 87 additions & 0 deletions pico_w/wifi/coap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
if (DEFINED ENV{COAP_SERVER} AND NOT COAP_SERVER)
set(COAP_SERVER $ENV{COAP_SERVER})
message("Using COAP_SERVER from environment ('${COAP_SERVER}')")
endif()
if (NOT COAP_SERVER)
message("Skipping COAP example as COAP_SERVER is not defined")
return()
endif()
set(COAP_SERVER "${COAP_SERVER}" CACHE INTERNAL "COAP server for examples")
if (DEFINED ENV{LIB_COAP_DIR} AND NOT LIB_COAP_DIR)
set(LIB_COAP_DIR $ENV{LIB_COAP_DIR})
endif()
if (NOT LIB_COAP_DIR)
message("Skipping COAP example as LIB_COAP_DIR is not defined")
return()
endif()
set(LIB_COAP_DIR "${LIB_COAP_DIR}" CACHE INTERNAL "LIB_COAP_DIR for examples")
if (DEFINED ENV{LIB_TINYDTLS_DIR} AND NOT LIB_TINYDTLS_DIR)
set(LIB_TINYDTLS_DIR $ENV{LIB_TINYDTLS_DIR})
endif()
if (NOT LIB_TINYDTLS_DIR)
message("Skipping COAP example as LIB_TINYDTLS_DIR is not defined")
return()
endif()
set(LIB_TINYDTLS_DIR "${LIB_TINYDTLS_DIR}" CACHE INTERNAL "LIB_TINYDTLS_DIR for examples")
include(libcoap.cmake)
include(libtinydtls.cmake)

set(TARGET_NAME coap_server)
add_executable(${TARGET_NAME}
coap_server.c
)
target_include_directories(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common headers
)
target_link_libraries(${TARGET_NAME} PRIVATE
pico_cyw43_arch_lwip_threadsafe_background
pico_async_context_threadsafe_background
pico_lwip_nosys
pico_stdlib
pico_coap
hardware_adc
pico_tinydtls
)
target_compile_definitions(${TARGET_NAME} PRIVATE
CYW43_HOST_NAME=\"pico_coap_example\"
)
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/certs/${COAP_SERVER}")
target_compile_definitions(${TARGET_NAME} PRIVATE
COAP_CERT_INC=\"certs/${COAP_SERVER}/coap_server.inc\"
)
endif()
target_compile_definitions(${TARGET_NAME} PRIVATE
WIFI_SSID=\"${WIFI_SSID}\"
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
)
pico_add_extra_outputs(${TARGET_NAME})

set(TARGET_NAME coap_client)
add_executable(${TARGET_NAME}
coap_client.c
)
target_include_directories(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts
)
target_link_libraries(${TARGET_NAME} PRIVATE
pico_cyw43_arch_lwip_threadsafe_background
pico_lwip_nosys
pico_stdlib
pico_coap
pico_tinydtls
)
target_compile_definitions(${TARGET_NAME} PRIVATE
COAP_SERVER=\"${COAP_SERVER}\"
)
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/certs/${COAP_SERVER}")
target_compile_definitions(${TARGET_NAME} PRIVATE
COAP_CERT_INC=\"certs/${COAP_SERVER}/coap_client.inc\"
)
endif()
target_compile_definitions(${TARGET_NAME} PRIVATE
WIFI_SSID=\"${WIFI_SSID}\"
WIFI_PASSWORD=\"${WIFI_PASSWORD}\"
)
pico_add_extra_outputs(${TARGET_NAME})
64 changes: 64 additions & 0 deletions pico_w/wifi/coap/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Setup

These examples require libcoap and tinydtls to work. Clone these repos somewhere,,,

```
git clone https://github.com/obgm/libcoap.git
git submodule update --init
```

You can define these paths in environment variables or pass the names to cmake

```
export LIB_COAP_DIR=/home/pi/libcoap
export LIB_TINYDTLS_DIR=/home/pi/tinydtls
```

You also need to define the coap server in another environment variable...

```
export COAP_SERVER=myhost
```

The examples use keys generated by a script in the certs folder...

```
cd certs
./makecerts.sh
```

The code should now build.
tinydtls and this example currently only supports raw public keys.

```
cd libcoap
mkdir build
cd build
cmake .. -DDTLS_BACKEND=tinydtls
make -j8
```

# Coap Client

To test the client you need a server to talk to. The libcoap library comes with the coap-server example that should work.
server.key is generated by the makecerts.sh script above.

```
coap-server -M server.key -v 7
```

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

# Coap Server

The coap server example supports the following...

* Find out what requests it supports: coap-client -M client.key -m get coaps://$COAP_SERVER/.well-known/core
* Get the current temperature: coap-client -M client.key -m get coaps://$COAP_SERVER/temp
* Get the current led state: coap-client -M client.key -m get coaps://$COAP_SERVER/led
* Turn the led on: coap-client -M client.key -m put coaps://$COAP_SERVER/led -e 1
* Subscribe to temperature changes: coap-client -M client.key -m get coaps://$COAP_SERVER/temp -s 60 -w
* Get time: coap-client -M client.key -m get coaps://$COAP_SERVER/time

$COAP_SERVER is the name of the coap server.
client.key is generated by the makecerts.sh script above.
1 change: 1 addition & 0 deletions pico_w/wifi/coap/certs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/
42 changes: 42 additions & 0 deletions pico_w/wifi/coap/certs/makecerts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/bash

if [ "${PWD##*/}" != "certs" ]; then
echo Run this in the certs folder
exit 1
fi
if [ -z "$COAP_SERVER" ]; then
echo Define COAP_SERVER
exit 1
fi
SERVER_NAME=$COAP_SERVER

if [ -d "$SERVER_NAME" ]; then
echo Run \"rm -fr $SERVER_NAME\" to regenerate these keys
exit 1
fi
mkdir $SERVER_NAME
echo Generating keys in $PWD/$SERVER_NAME

openssl ecparam -name prime256v1 -genkey -noout -out $SERVER_NAME/client.key
openssl ec -in $SERVER_NAME/client.key -pubout -out $SERVER_NAME/client.pub

echo -n \#define COAP_KEY \" > $SERVER_NAME/coap_client.inc
cat $SERVER_NAME/client.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_client.inc
echo "\"" >> $SERVER_NAME/coap_client.inc
echo >> $SERVER_NAME/coap_client.inc

echo -n \#define COAP_PUB_KEY \" >> $SERVER_NAME/coap_client.inc
cat $SERVER_NAME/client.pub | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_client.inc
echo "\"" >> $SERVER_NAME/coap_client.inc

openssl ecparam -name prime256v1 -genkey -noout -out $SERVER_NAME/server.key
openssl ec -in $SERVER_NAME/server.key -pubout -out $SERVER_NAME/server.pub

echo -n \#define COAP_KEY \" > $SERVER_NAME/coap_server.inc
cat $SERVER_NAME/server.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_server.inc
echo "\"" >> $SERVER_NAME/coap_server.inc
echo >> $SERVER_NAME/coap_server.inc

echo -n \#define COAP_PUB_KEY \" >> $SERVER_NAME/coap_server.inc
cat $SERVER_NAME/server.pub | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/coap_server.inc
echo "\"" >> $SERVER_NAME/coap_server.inc
Loading