remove(coap)!: Move CoAP examples to idf-extra-components repository

Related:
https://github.com/espressif/idf-extra-components/pull/188
This commit is contained in:
Harshit Malpani 2023-06-23 17:13:08 +05:30 committed by Mahavir Jain
parent cefbecd41b
commit d9e8aca7ee
No known key found for this signature in database
GPG Key ID: 99324EF4A00734E0
28 changed files with 22 additions and 1348 deletions

View File

@ -7,3 +7,4 @@ Migration from 5.1 to 5.2
:maxdepth: 1
peripherals
protocols

View File

@ -0,0 +1,10 @@
Protocols
=========
:link_to_translation:`zh_CN:[中文]`
CoAP
----
CoAP examples have been moved to `idf-extra-components <https://github.com/espressif/idf-extra-components/tree/master/coap/examples>`__ repository.

View File

@ -7,3 +7,4 @@
:maxdepth: 1
peripherals
protocols

View File

@ -0,0 +1,10 @@
协议
====
:link_to_translation:`en:[English]`
CoAP
----
CoAP 相关示例已迁移至 `idf-extra-components <https://github.com/espressif/idf-extra-components/tree/master/coap/examples>`__ 仓库.

View File

@ -1,11 +1,5 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/protocols/coap_client:
disable_test:
- if: IDF_TARGET != "esp32"
reason: running this test on single platform is sufficient for coverage
examples/protocols/esp_http_client:
enable:
- if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux"

View File

@ -1,10 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(coap_client)

View File

@ -1,111 +0,0 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# CoAP client example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This CoAP client example is very simplified adaptation of one of the
[libcoap](https://github.com/obgm/libcoap) examples.
CoAP client example will connect your ESP32 device to a CoAP server, send off a GET request and
fetch the response data from CoAP server. The client can be extended to PUT / POST / DELETE requests,
as well as supporting the Observer extensions [RFC7641](https://tools.ietf.org/html/rfc7641).
If the URI is prefixed with coaps:// instead of coap://, then the CoAP client will attempt to use
the DTLS protocol using the defined Pre-Shared Keys(PSK) or Public Key Infrastructure (PKI) which the
CoAP server needs to know about.
If the URI is prefixed with coap+tcp://, then the CoAP will try to use TCP for the communication.
The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with
constrained nodes and constrained networks in the Internet of Things.
The protocol is designed for machine-to-machine (M2M) applications such as smart energy and
building automation.
Please refer to [RFC7252](https://www.rfc-editor.org/rfc/pdfrfc/rfc7252.txt.pdf) for more details.
## How to use example
### Configure the project
```
idf.py menuconfig
```
Example Connection Configuration --->
* Set WiFi SSID
* Set WiFi Password
Component config --->
CoAP Configuration --->
* Set encryption method definition, PSK (default) or PKI
* Enable CoAP debugging if required
* Disable CoAP using TCP if this is not required (TCP needed for TLS)
* Disable CoAP server functionality to reduce code size
Example CoAP Client Configuration --->
* Set CoAP Target Uri
* If PSK, Set CoAP Preshared Key to use in connection to the server
* If PSK, Set CoAP PSK Client identity (username)
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py build
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
Prerequisite: we startup a CoAP server on coap server example,
or use the default of coap://californium.eclipseprojects.io.
and you could receive data from CoAP server if succeed,
such as the following log:
```
...
I (332) wifi: mode : sta (30:ae:a4:04:1b:7c)
I (1672) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1
I (1672) wifi: state: init -> auth (b0)
I (1682) wifi: state: auth -> assoc (0)
I (1692) wifi: state: assoc -> run (10)
I (1692) wifi: connected with huawei_cw, channel 11
I (1692) wifi: pm start, type: 1
I (2582) event: sta ip: 192.168.3.89, mask: 255.255.255.0, gw: 192.168.3.1
I (2582) CoAP_client: Connected to AP
I (2582) CoAP_client: DNS lookup succeeded. IP=35.185.40.182
Received:
****************************************************************
CoAP RFC 7252 Cf 3.0.0-SNAPSHOT
****************************************************************
This server is using the Eclipse Californium (Cf) CoAP framework
published under EPL+EDL: http://www.eclipse.org/californium/
(c) 2014-2020 Institute for Pervasive Computing, ETH Zurich and others
****************************************************************
...
```
## libcoap Documentation
This can be found at [libcoap Documentation](https://libcoap.net/documentation.html).
The current API is 4.3.0.
## libcoap Specific Issues
These can be raised at [libcoap Issues](https://github.com/obgm/libcoap/issues).
## Troubleshooting
* Please make sure Target Url includes valid `host`, optional `port`,
optional `path`, and begins with `coap://`, `coaps://`, `coap+tcp://` or `coaps+tcp://`
(not all hosts support TCP/TLS including coap+tcp://californium.eclipseprojects.io).
* CoAP logging can be enabled by running 'idf.py menuconfig -> Component config -> CoAP Configuration -> Enable CoAP debugging'
and setting appropriate log level. If Mbed TLS logging is required, this needs to be configured separately under mbedTLS
Component Configuration and the CoAP logging level set to mbedTLS.
* CoAP library does not support IPv6 only configuration, so it is necessary to enable `LWIP_IPv4`

View File

@ -1,4 +0,0 @@
# Embed CA, certificate & key directly into binary
idf_component_register(SRCS "coap_client_example_main.c"
INCLUDE_DIRS "."
EMBED_TXTFILES certs/coap_ca.pem certs/coap_client.crt certs/coap_client.key)

View File

@ -1,33 +0,0 @@
menu "Example CoAP Client Configuration"
# Hidden option that selects IPv4
config EXAMPLE_COAP_NEEDS_IPV4
bool
default true
select LWIP_IPV4
config EXAMPLE_TARGET_DOMAIN_URI
string "Target Uri"
default "coaps://californium.eclipseprojects.io"
help
Target uri for the example to use. Use coaps:// prefix for encrypted traffic
using Pre-Shared Key (PSK) or Public Key Infrastructure (PKI).
config EXAMPLE_COAP_PSK_KEY
string "Preshared Key (PSK) to used in the connection to the CoAP server"
depends on COAP_MBEDTLS_PSK
default "sesame"
help
The Preshared Key to use to encrypt the communicatons. The same key must be
used at both ends of the CoAP connection, and the CoaP client must request
an URI prefixed with coaps:// instead of coap:// for DTLS to be used.
config EXAMPLE_COAP_PSK_IDENTITY
string "PSK Client identity (username)"
depends on COAP_MBEDTLS_PSK
default "password"
help
The identity (or username) to use to identify to the CoAP server which
PSK key to use.
endmenu

View File

@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICDzCCAbSgAwIBAgIIAbOUoVFDz/QwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
MDMzWhcNMjExMTExMTAzMDMzWjBaMQ4wDAYDVQQDEwVjZi1jYTEUMBIGA1UECxML
Q2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZPdHRh
d2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7/3EXOZn
GZXNEIj7LuQAMZ8lfRYSCnpME1TBjKjZPtVeztLtGWgkkLvIX11pAJcBh51cpi7Z
fQtGpVE9CLOh6aNgMF4wHQYDVR0OBBYEFEvf57UcJhYYkx14twkeitd691fVMAsG
A1UdDwQEAwIBBjAPBgNVHRMECDAGAQH/AgEBMB8GA1UdIwQYMBaAFAsi3KbVERiK
JzFCfC/GVrYksGzEMAwGCCqGSM49BAMCBQADRwAwRAIgc5nVF/5Pip0XB17IZXqi
V84FXanWdn9Z0SiPdpOgvZMCIH13vL9tkCCjPN3tg3TYRY/bzyGohFGBcTrrEtUr
rVIm
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB4DCCAYWgAwIBAgIIQR8ro8AQ02AwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
MDMyWhcNMjExMTExMTAzMDMyWjBcMRAwDgYDVQQDEwdjZi1yb290MRQwEgYDVQQL
EwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBzZSBJb1QxDzANBgNVBAcTBk90
dGF3YTELMAkGA1UEBhMCQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATZ1BRM
T1//Fzh9sneRZNwS4kgCxN1PvgwT271qCpYqyxnjLEa38AP1IAanhpiD/OkVc0Zd
7NgDPCw7n94EULMyoy8wLTAdBgNVHQ4EFgQUCyLcptURGIonMUJ8L8ZWtiSwbMQw
DAYDVR0TBAUwAwEB/zAMBggqhkjOPQQDAgUAA0cAMEQCIAdLEgcUWdpAl9jwdJiz
/cHW7/CBIWEvqiQfzE+XLyLOAiAvuxSdOtSDjh2aC5qEjUCH8CSKCxWB74j23tmp
aqPH4A==
-----END CERTIFICATE-----

View File

@ -1,13 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICAzCCAaagAwIBAgIJAJnE6sMNQNAoMAwGCCqGSM49BAMCBQAwWjEOMAwGA1UE
AxMFY2YtY2ExFDASBgNVBAsTC0NhbGlmb3JuaXVtMRQwEgYDVQQKEwtFY2xpcHNl
IElvVDEPMA0GA1UEBxMGT3R0YXdhMQswCQYDVQQGEwJDQTAeFw0yMDExMTExMDMw
NDVaFw0yMTExMTExMDMwNDVaMF4xEjAQBgNVBAMTCWNmLWNsaWVudDEUMBIGA1UE
CxMLQ2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZP
dHRhd2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFGno
107kFgJ4AvABQviE9hTJlEeB4wfS3L58Q5J8srWxSunEgniIbfr0p8Shw+C1XAcz
FxJrn8SjFCVqOKjrrqNPME0wHQYDVR0OBBYEFIwAAdmpYSm184Jx1ycc3BQGybhN
MAsGA1UdDwQEAwIHgDAfBgNVHSMEGDAWgBRL3+e1HCYWGJMdeLcJHorXevdX1TAM
BggqhkjOPQQDAgUAA0kAMEYCIQC+w/hm8TfTCqUV6midHAvmNxJN7MfMcpAiyi4e
6NBrPAIhAPeMUrnOlykTMcpYMRZs4YnyM6ihgU/F8UjknhDpkywm
-----END CERTIFICATE-----

View File

@ -1,4 +0,0 @@
-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBgNuyqKuRW0RxU1DVs
aEpBPtVRVLRZYq6hZRzvZ6igBw==
-----END PRIVATE KEY-----

View File

@ -1,505 +0,0 @@
/* CoAP client Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* WARNING
* libcoap is not multi-thread safe, so only this thread must make any coap_*()
* calls. Any external (to this thread) data transmitted in/out via libcoap
* therefore has to be passed in/out by xQueue*() via this thread.
*/
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "coap3/coap.h"
#ifndef CONFIG_COAP_CLIENT_SUPPORT
#error COAP_CLIENT_SUPPORT needs to be enabled
#endif /* COAP_CLIENT_SUPPORT */
#define COAP_DEFAULT_TIME_SEC 60
/* The examples use simple Pre-Shared-Key configuration that you can set via
'idf.py menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
Note: PSK will only be used if the URI is prefixed with coaps://
instead of coap:// and the PSK must be one that the server supports
(potentially associated with the IDENTITY)
*/
#define EXAMPLE_COAP_PSK_KEY CONFIG_EXAMPLE_COAP_PSK_KEY
#define EXAMPLE_COAP_PSK_IDENTITY CONFIG_EXAMPLE_COAP_PSK_IDENTITY
/* The examples use uri Logging Level that
you can set via 'idf.py menuconfig'.
If you'd rather not, just change the below entry to a value
that is between 0 and 7 with
the config you want - ie #define EXAMPLE_COAP_LOG_DEFAULT_LEVEL 7
*/
#define EXAMPLE_COAP_LOG_DEFAULT_LEVEL CONFIG_COAP_LOG_DEFAULT_LEVEL
/* The examples use uri "coap://californium.eclipseprojects.io" that
you can set via the project configuration (idf.py menuconfig)
If you'd rather not, just change the below entries to strings with
the config you want - ie #define COAP_DEFAULT_DEMO_URI "coaps://californium.eclipseprojects.io"
*/
#define COAP_DEFAULT_DEMO_URI CONFIG_EXAMPLE_TARGET_DOMAIN_URI
const static char *TAG = "CoAP_client";
static int resp_wait = 1;
static coap_optlist_t *optlist = NULL;
static int wait_ms;
#ifdef CONFIG_COAP_MBEDTLS_PKI
/* CA cert, taken from coap_ca.pem
Client cert, taken from coap_client.crt
Client key, taken from coap_client.key
The PEM, CRT and KEY file are examples taken from
https://github.com/eclipse/californium/tree/master/demo-certs/src/main/resources
as the Certificate test (by default) is against the californium server.
To embed it in the app binary, the PEM, CRT and KEY file is named
in the component.mk COMPONENT_EMBED_TXTFILES variable.
*/
extern uint8_t ca_pem_start[] asm("_binary_coap_ca_pem_start");
extern uint8_t ca_pem_end[] asm("_binary_coap_ca_pem_end");
extern uint8_t client_crt_start[] asm("_binary_coap_client_crt_start");
extern uint8_t client_crt_end[] asm("_binary_coap_client_crt_end");
extern uint8_t client_key_start[] asm("_binary_coap_client_key_start");
extern uint8_t client_key_end[] asm("_binary_coap_client_key_end");
#endif /* CONFIG_COAP_MBEDTLS_PKI */
static coap_response_t
message_handler(coap_session_t *session,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t mid)
{
const unsigned char *data = NULL;
size_t data_len;
size_t offset;
size_t total;
coap_pdu_code_t rcvd_code = coap_pdu_get_code(received);
if (COAP_RESPONSE_CLASS(rcvd_code) == 2) {
if (coap_get_data_large(received, &data_len, &data, &offset, &total)) {
if (data_len != total) {
printf("Unexpected partial data received offset %u, length %u\n", offset, data_len);
}
printf("Received:\n%.*s\n", (int)data_len, data);
resp_wait = 0;
}
return COAP_RESPONSE_OK;
}
printf("%d.%02d", (rcvd_code >> 5), rcvd_code & 0x1F);
if (coap_get_data_large(received, &data_len, &data, &offset, &total)) {
printf(": ");
while(data_len--) {
printf("%c", isprint(*data) ? *data : '.');
data++;
}
}
printf("\n");
resp_wait = 0;
return COAP_RESPONSE_OK;
}
#ifdef CONFIG_COAP_MBEDTLS_PKI
static int
verify_cn_callback(const char *cn,
const uint8_t *asn1_public_cert,
size_t asn1_length,
coap_session_t *session,
unsigned depth,
int validated,
void *arg
)
{
coap_log(LOG_INFO, "CN '%s' presented by server (%s)\n",
cn, depth ? "CA" : "Certificate");
return 1;
}
#endif /* CONFIG_COAP_MBEDTLS_PKI */
static void
coap_log_handler (coap_log_t level, const char *message)
{
uint32_t esp_level = ESP_LOG_INFO;
char *cp = strchr(message, '\n');
if (cp)
ESP_LOG_LEVEL(esp_level, TAG, "%.*s", (int)(cp-message), message);
else
ESP_LOG_LEVEL(esp_level, TAG, "%s", message);
}
static coap_address_t *
coap_get_address(coap_uri_t *uri)
{
static coap_address_t dst_addr;
char *phostname = NULL;
struct addrinfo hints;
struct addrinfo *addrres;
int error;
char tmpbuf[INET6_ADDRSTRLEN];
phostname = (char *)calloc(1, uri->host.length + 1);
if (phostname == NULL) {
ESP_LOGE(TAG, "calloc failed");
return NULL;
}
memcpy(phostname, uri->host.s, uri->host.length);
memset ((char *)&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_family = AF_UNSPEC;
error = getaddrinfo(phostname, NULL, &hints, &addrres);
if (error != 0) {
ESP_LOGE(TAG, "DNS lookup failed for destination address %s. error: %d", phostname, error);
free(phostname);
return NULL;
}
if (addrres == NULL) {
ESP_LOGE(TAG, "DNS lookup %s did not return any addresses", phostname);
free(phostname);
return NULL;
}
free(phostname);
coap_address_init(&dst_addr);
switch (addrres->ai_family) {
case AF_INET:
memcpy(&dst_addr.addr.sin, addrres->ai_addr, sizeof(dst_addr.addr.sin));
dst_addr.addr.sin.sin_port = htons(uri->port);
inet_ntop(AF_INET, &dst_addr.addr.sin.sin_addr, tmpbuf, sizeof(tmpbuf));
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
break;
case AF_INET6:
memcpy(&dst_addr.addr.sin6, addrres->ai_addr, sizeof(dst_addr.addr.sin6));
dst_addr.addr.sin6.sin6_port = htons(uri->port);
inet_ntop(AF_INET6, &dst_addr.addr.sin6.sin6_addr, tmpbuf, sizeof(tmpbuf));
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
break;
default:
ESP_LOGE(TAG, "DNS lookup response failed");
return NULL;
}
freeaddrinfo(addrres);
return &dst_addr;
}
static int
coap_build_optlist(coap_uri_t *uri)
{
#define BUFSIZE 40
unsigned char _buf[BUFSIZE];
unsigned char *buf;
size_t buflen;
int res;
optlist = NULL;
if (uri->scheme == COAP_URI_SCHEME_COAPS && !coap_dtls_is_supported()) {
ESP_LOGE(TAG, "MbedTLS DTLS Client Mode not configured");
return 0;
}
if (uri->scheme == COAP_URI_SCHEME_COAPS_TCP && !coap_tls_is_supported()) {
ESP_LOGE(TAG, "MbedTLS TLS Client Mode not configured");
return 0;
}
if (uri->scheme == COAP_URI_SCHEME_COAP_TCP && !coap_tcp_is_supported()) {
ESP_LOGE(TAG, "TCP Client Mode not configured");
return 0;
}
if (uri->path.length) {
buflen = BUFSIZE;
buf = _buf;
res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
while (res--) {
coap_insert_optlist(&optlist,
coap_new_optlist(COAP_OPTION_URI_PATH,
coap_opt_length(buf),
coap_opt_value(buf)));
buf += coap_opt_size(buf);
}
}
if (uri->query.length) {
buflen = BUFSIZE;
buf = _buf;
res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
while (res--) {
coap_insert_optlist(&optlist,
coap_new_optlist(COAP_OPTION_URI_QUERY,
coap_opt_length(buf),
coap_opt_value(buf)));
buf += coap_opt_size(buf);
}
}
return 1;
}
#ifdef CONFIG_COAP_MBEDTLS_PSK
static coap_session_t *
coap_start_psk_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t *uri)
{
static coap_dtls_cpsk_t dtls_psk;
static char client_sni[256];
memset(client_sni, 0, sizeof(client_sni));
memset (&dtls_psk, 0, sizeof(dtls_psk));
dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
dtls_psk.validate_ih_call_back = NULL;
dtls_psk.ih_call_back_arg = NULL;
if (uri->host.length)
memcpy(client_sni, uri->host.s, MIN(uri->host.length, sizeof(client_sni) - 1));
else
memcpy(client_sni, "localhost", 9);
dtls_psk.client_sni = client_sni;
dtls_psk.psk_info.identity.s = (const uint8_t *)EXAMPLE_COAP_PSK_IDENTITY;
dtls_psk.psk_info.identity.length = sizeof(EXAMPLE_COAP_PSK_IDENTITY)-1;
dtls_psk.psk_info.key.s = (const uint8_t *)EXAMPLE_COAP_PSK_KEY;
dtls_psk.psk_info.key.length = sizeof(EXAMPLE_COAP_PSK_KEY)-1;
return coap_new_client_session_psk2(ctx, NULL, dst_addr,
uri->scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
&dtls_psk);
}
#endif /* CONFIG_COAP_MBEDTLS_PSK */
#ifdef CONFIG_COAP_MBEDTLS_PKI
static coap_session_t *
coap_start_pki_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t *uri)
{
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
unsigned int client_crt_bytes = client_crt_end - client_crt_start;
unsigned int client_key_bytes = client_key_end - client_key_start;
static coap_dtls_pki_t dtls_pki;
static char client_sni[256];
memset (&dtls_pki, 0, sizeof(dtls_pki));
dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION;
if (ca_pem_bytes) {
/*
* Add in additional certificate checking.
* This list of enabled can be tuned for the specific
* requirements - see 'man coap_encryption'.
*
* Note: A list of root cas file can be setup separately using
* coap_context_set_pki_root_cas(), but the below is used to
* define what checking actually takes place.
*/
dtls_pki.verify_peer_cert = 1;
dtls_pki.check_common_ca = 1;
dtls_pki.allow_self_signed = 1;
dtls_pki.allow_expired_certs = 1;
dtls_pki.cert_chain_validation = 1;
dtls_pki.cert_chain_verify_depth = 2;
dtls_pki.check_cert_revocation = 1;
dtls_pki.allow_no_crl = 1;
dtls_pki.allow_expired_crl = 1;
dtls_pki.allow_bad_md_hash = 1;
dtls_pki.allow_short_rsa_length = 1;
dtls_pki.validate_cn_call_back = verify_cn_callback;
dtls_pki.cn_call_back_arg = NULL;
dtls_pki.validate_sni_call_back = NULL;
dtls_pki.sni_call_back_arg = NULL;
memset(client_sni, 0, sizeof(client_sni));
if (uri->host.length) {
memcpy(client_sni, uri->host.s, MIN(uri->host.length, sizeof(client_sni)));
} else {
memcpy(client_sni, "localhost", 9);
}
dtls_pki.client_sni = client_sni;
}
dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM_BUF;
dtls_pki.pki_key.key.pem_buf.public_cert = client_crt_start;
dtls_pki.pki_key.key.pem_buf.public_cert_len = client_crt_bytes;
dtls_pki.pki_key.key.pem_buf.private_key = client_key_start;
dtls_pki.pki_key.key.pem_buf.private_key_len = client_key_bytes;
dtls_pki.pki_key.key.pem_buf.ca_cert = ca_pem_start;
dtls_pki.pki_key.key.pem_buf.ca_cert_len = ca_pem_bytes;
return coap_new_client_session_pki(ctx, NULL, dst_addr,
uri->scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
&dtls_pki);
}
#endif /* CONFIG_COAP_MBEDTLS_PKI */
static void coap_example_client(void *p)
{
coap_address_t *dst_addr;
static coap_uri_t uri;
const char *server_uri = COAP_DEFAULT_DEMO_URI;
coap_context_t *ctx = NULL;
coap_session_t *session = NULL;
coap_pdu_t *request = NULL;
unsigned char token[8];
size_t tokenlength;
/* Set up the CoAP logging */
coap_set_log_handler(coap_log_handler);
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
/* Set up the CoAP context */
ctx = coap_new_context(NULL);
if (!ctx) {
ESP_LOGE(TAG, "coap_new_context() failed");
goto clean_up;
}
coap_context_set_block_mode(ctx,
COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY);
coap_register_response_handler(ctx, message_handler);
if (coap_split_uri((const uint8_t *)server_uri, strlen(server_uri), &uri) == -1) {
ESP_LOGE(TAG, "CoAP server uri error");
goto clean_up;
}
if (!coap_build_optlist(&uri))
goto clean_up;
dst_addr = coap_get_address(&uri);
if (!dst_addr)
goto clean_up;
/*
* Note that if the URI starts with just coap:// (not coaps://) the
* session will still be plain text.
*/
if (uri.scheme == COAP_URI_SCHEME_COAPS || uri.scheme == COAP_URI_SCHEME_COAPS_TCP) {
#ifndef CONFIG_MBEDTLS_TLS_CLIENT
ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured");
goto clean_up;
#endif /* CONFIG_MBEDTLS_TLS_CLIENT */
#ifdef CONFIG_COAP_MBEDTLS_PSK
session = coap_start_psk_session(ctx, dst_addr, &uri);
#endif /* CONFIG_COAP_MBEDTLS_PSK */
#ifdef CONFIG_COAP_MBEDTLS_PKI
session = coap_start_pki_session(ctx, dst_addr, &uri);
#endif /* CONFIG_COAP_MBEDTLS_PKI */
} else {
session = coap_new_client_session(ctx, NULL, dst_addr,
uri.scheme == COAP_URI_SCHEME_COAP_TCP ? COAP_PROTO_TCP :
COAP_PROTO_UDP);
}
if (!session) {
ESP_LOGE(TAG, "coap_new_client_session() failed");
goto clean_up;
}
while (1) {
request = coap_new_pdu(coap_is_mcast(dst_addr) ? COAP_MESSAGE_NON : COAP_MESSAGE_CON,
COAP_REQUEST_CODE_GET, session);
if (!request) {
ESP_LOGE(TAG, "coap_new_pdu() failed");
goto clean_up;
}
/* Add in an unique token */
coap_session_new_token(session, &tokenlength, token);
coap_add_token(request, tokenlength, token);
/*
* To make this a POST, you will need to do the following
* Change COAP_REQUEST_CODE_GET to COAP_REQUEST_CODE_POST for coap_new_pdu()
* Add in here a Content-Type Option based on the format of the POST text. E.G. for JSON
* u_char buf[4];
* coap_insert_optlist(&optlist,
* coap_new_optlist(COAP_OPTION_CONTENT_FORMAT,
* coap_encode_var_safe (buf, sizeof (buf),
* COAP_MEDIATYPE_APPLICATION_JSON),
* buf));
* Add in here the POST data of length length. E.G.
* coap_add_data_large_request(session, request length, data, NULL, NULL);
*/
coap_add_optlist_pdu(request, &optlist);
resp_wait = 1;
coap_send(session, request);
wait_ms = COAP_DEFAULT_TIME_SEC * 1000;
while (resp_wait) {
int result = coap_io_process(ctx, wait_ms > 1000 ? 1000 : wait_ms);
if (result >= 0) {
if (result >= wait_ms) {
ESP_LOGE(TAG, "No response from server");
break;
} else {
wait_ms -= result;
}
}
}
for(int countdown = 10; countdown >= 0; countdown--) {
ESP_LOGI(TAG, "%d... ", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "Starting again!");
}
clean_up:
if (optlist) {
coap_delete_optlist(optlist);
optlist = NULL;
}
if (session) {
coap_session_release(session);
}
if (ctx) {
coap_free_context(ctx);
}
coap_cleanup();
ESP_LOGI(TAG, "Finished");
vTaskDelete(NULL);
}
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
xTaskCreate(coap_example_client, "coap", 8 * 1024, NULL, 5, NULL);
}

View File

@ -1,2 +0,0 @@
dependencies:
espressif/coap: "^4.3.0"

View File

@ -1,21 +0,0 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pexpect
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.ethernet
def test_coap_example(dut: Dut) -> None:
dut.expect('Loaded app from partition at offset', timeout=30)
try:
dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)
except pexpect.exceptions.TIMEOUT:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
dut.expect('DNS lookup succeeded', timeout=30)
dut.expect('Received', timeout=30)
dut.expect(r'This server is using the Eclipse Californium \(Cf\) CoAP framework', timeout=30)
dut.expect(r'published under EPL\+EDL: http://www\.eclipse\.org/californium/', timeout=30)
dut.expect('Starting again!', timeout=30)

View File

@ -1,8 +0,0 @@
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1

View File

@ -1,5 +0,0 @@
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
CONFIG_MBEDTLS_PSK_MODES=y
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
CONFIG_LWIP_NETBUF_RECVINFO=y
CONFIG_COAP_CLIENT_SUPPORT=y

View File

@ -1,10 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(coap_server)

View File

@ -1,96 +0,0 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# CoAP server example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This CoAP server example is very simplified adaptation of one of the
[libcoap](https://github.com/obgm/libcoap) examples.
CoAP server example will startup a daemon task, receive requests / data from CoAP client and transmit
data to CoAP client.
If the incoming request requests the use of DTLS (connecting to port 5684), then the CoAP server will
try to establish a DTLS session using the previously defined Pre-Shared Key (PSK) - which
must be the same as the one that the CoAP client is using, or Public Key Infrastructure (PKI) where
the PKI information must match as requested.
The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with
constrained nodes and constrained networks in the Internet of Things.
The protocol is designed for machine-to-machine (M2M) applications such as smart energy and
building automation.
Please refer to [RFC7252](https://www.rfc-editor.org/rfc/pdfrfc/rfc7252.txt.pdf) for more details.
## How to use example
### Configure the project
```
idf.py menuconfig
```
Example Connection Configuration --->
* Set WiFi SSID
* Set WiFi Password
Component config --->
CoAP Configuration --->
* Set encryption method definition, PSK (default) or PKI
* Enable CoAP debugging if required
* Disable CoAP using TCP if this is not required (TCP needed for TLS)
* Disable CoAP client functionality to reduce code size unless this server is a proxy
Example CoAP Server Configuration --->
* If PSK, Set CoAP Preshared Key to use for connections to the server
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py build
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
current CoAP server would startup a daemon task,
and the log is such as the following:
```
...
I (332) wifi: mode : sta (30:ae:a4:04:1b:7c)
I (1672) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1
I (1672) wifi: state: init -> auth (b0)
I (1682) wifi: state: auth -> assoc (0)
I (1692) wifi: state: assoc -> run (10)
I (1692) wifi: connected with huawei_cw, channel 11
I (1692) wifi: pm start, type: 1
I (2622) event: sta ip: 192.168.3.84, mask: 255.255.255.0, gw: 192.168.3.1
I (2622) CoAP_server: Connected to AP
...
```
If a CoAP client queries the `/Espressif` resource, CoAP server will return `"Hello World!"`
until a CoAP client does a PUT with different data.
## libcoap Documentation
This can be found at [libcoap Documentation](https://libcoap.net/documentation.html).
The current API is 4.3.0.
## libcoap Specific Issues
These can be raised at [libcoap Issues](https://github.com/obgm/libcoap/issues).
## Troubleshooting
* Please make sure CoAP client fetchs or puts data under path: `/Espressif` or
fetches `/.well-known/core`
* CoAP logging can be enabled by running 'idf.py menuconfig -> Component config -> CoAP Configuration -> Enable CoAP debugging'
and setting appropriate log level. If Mbed TLS logging is required, this needs to be configured separately under mbedTLS
Component Configuration and the CoAP logging level set to mbedTLS.
* CoAP library does not support IPv6 only configuration, so it is necessary to enable `LWIP_IPv4`

View File

@ -1,3 +0,0 @@
idf_component_register(SRCS "coap_server_example_main.c"
INCLUDE_DIRS "."
EMBED_TXTFILES certs/coap_ca.pem certs/coap_server.crt certs/coap_server.key)

View File

@ -1,67 +0,0 @@
menu "Example CoAP Server Configuration"
# Hidden option that selects IPv4
config EXAMPLE_COAP_NEEDS_IPV4
bool
default true
select LWIP_IPV4
config EXAMPLE_COAP_PSK_KEY
string "Preshared Key (PSK) to used in the connection from the CoAP client"
depends on COAP_MBEDTLS_PSK
default "secret-key"
help
The Preshared Key to use to encrypt the communicatons. The same key must be
used at both ends of the CoAP connection, and the CoaP client must request
an URI prefixed with coaps:// instead of coap:// for DTLS to be used.
choice EXAMPLE_COAP_MCAST_IP_MODE
prompt "Receive Multicast IP type"
help
Example can receive multicast IPV4, IPV6, both or none.
config EXAMPLE_COAP_MCAST_NONE
bool "None"
config EXAMPLE_COAP_MCAST_IPV4_V6
bool "IPV4 & IPV6"
select EXAMPLE_COAP_MCAST_IPV4
select EXAMPLE_COAP_MCAST_IPV6
config EXAMPLE_COAP_MCAST_IPV4_ONLY
bool "IPV4"
select EXAMPLE_COAP_MCAST_IPV4
config EXAMPLE_COAP_MCAST_IPV6_ONLY
bool "IPV6"
select EXAMPLE_COAP_MCAST_IPV6
endchoice
config EXAMPLE_COAP_MCAST_IPV4
bool
config EXAMPLE_COAP_MCAST_IPV6
bool
select EXAMPLE_CONNECT_IPV6 if IDF_TARGET_ESP32
config EXAMPLE_COAP_MULTICAST_IPV4_ADDR
string "CoAP Multicast IPV4 Address (receive)"
default "224.0.1.187"
depends on EXAMPLE_COAP_MCAST_IPV4
help
IPV4 multicast address to receive multicast traffic on.
The default CoAP IPV4 address is 224.0.1.187.
config EXAMPLE_COAP_MULTICAST_IPV6_ADDR
string "CoAP Multicast IPV6 Address (receive)"
default "FF02::FD"
depends on EXAMPLE_COAP_MCAST_IPV6
help
IPV6 multicast address to receive multicast traffic on.
The default CoAP FF02::FD address is a link-local multicast address.
Consult IPV6 specifications or documentation for information about
meaning of different IPV6 multicast ranges.
endmenu

View File

@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICDzCCAbSgAwIBAgIIAbOUoVFDz/QwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
MDMzWhcNMjExMTExMTAzMDMzWjBaMQ4wDAYDVQQDEwVjZi1jYTEUMBIGA1UECxML
Q2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZPdHRh
d2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7/3EXOZn
GZXNEIj7LuQAMZ8lfRYSCnpME1TBjKjZPtVeztLtGWgkkLvIX11pAJcBh51cpi7Z
fQtGpVE9CLOh6aNgMF4wHQYDVR0OBBYEFEvf57UcJhYYkx14twkeitd691fVMAsG
A1UdDwQEAwIBBjAPBgNVHRMECDAGAQH/AgEBMB8GA1UdIwQYMBaAFAsi3KbVERiK
JzFCfC/GVrYksGzEMAwGCCqGSM49BAMCBQADRwAwRAIgc5nVF/5Pip0XB17IZXqi
V84FXanWdn9Z0SiPdpOgvZMCIH13vL9tkCCjPN3tg3TYRY/bzyGohFGBcTrrEtUr
rVIm
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB4DCCAYWgAwIBAgIIQR8ro8AQ02AwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
MDMyWhcNMjExMTExMTAzMDMyWjBcMRAwDgYDVQQDEwdjZi1yb290MRQwEgYDVQQL
EwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBzZSBJb1QxDzANBgNVBAcTBk90
dGF3YTELMAkGA1UEBhMCQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATZ1BRM
T1//Fzh9sneRZNwS4kgCxN1PvgwT271qCpYqyxnjLEa38AP1IAanhpiD/OkVc0Zd
7NgDPCw7n94EULMyoy8wLTAdBgNVHQ4EFgQUCyLcptURGIonMUJ8L8ZWtiSwbMQw
DAYDVR0TBAUwAwEB/zAMBggqhkjOPQQDAgUAA0cAMEQCIAdLEgcUWdpAl9jwdJiz
/cHW7/CBIWEvqiQfzE+XLyLOAiAvuxSdOtSDjh2aC5qEjUCH8CSKCxWB74j23tmp
aqPH4A==
-----END CERTIFICATE-----

View File

@ -1,13 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICAzCCAaagAwIBAgIJANqCHDjOKHh+MAwGCCqGSM49BAMCBQAwWjEOMAwGA1UE
AxMFY2YtY2ExFDASBgNVBAsTC0NhbGlmb3JuaXVtMRQwEgYDVQQKEwtFY2xpcHNl
IElvVDEPMA0GA1UEBxMGT3R0YXdhMQswCQYDVQQGEwJDQTAeFw0yMDExMTExMDMw
MzRaFw0yMTExMTExMDMwMzRaMF4xEjAQBgNVBAMTCWNmLXNlcnZlcjEUMBIGA1UE
CxMLQ2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZP
dHRhd2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+obM
gHmMB7zS4KArciXPD7CrvgEYqlnAf7NOTdb54RbTr4qEpPL+OJ6Pg8VhrF4hGEne
T6Aa4qqpmTkxmfT0vqNPME0wHQYDVR0OBBYEFE4XpfFad+F3+RcwI+s1cmJbTZWG
MAsGA1UdDwQEAwIHgDAfBgNVHSMEGDAWgBRL3+e1HCYWGJMdeLcJHorXevdX1TAM
BggqhkjOPQQDAgUAA0kAMEYCIQCEo+O5zqYKdwi/ElB4wfNVIf76P1OhIXAT5CHc
3ebBPQIhAN6UhCgQ0av6kf7INCazV3KmN7HmPXARaY4YKWsRwsg+
-----END CERTIFICATE-----

View File

@ -1,4 +0,0 @@
-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCLBQT66xp2w4+1K+Ai
/TXEC8tQZBxl9brFyK4F7AQNGw==
-----END PRIVATE KEY-----

View File

@ -1,370 +0,0 @@
/* CoAP server Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* WARNING
* libcoap is not multi-thread safe, so only this thread must make any coap_*()
* calls. Any external (to this thread) data transmitted in/out via libcoap
* therefore has to be passed in/out by xQueue*() via this thread.
*/
#include <string.h>
#include <sys/socket.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "coap3/coap.h"
#ifndef CONFIG_COAP_SERVER_SUPPORT
#error COAP_SERVER_SUPPORT needs to be enabled
#endif /* COAP_SERVER_SUPPORT */
/* The examples use simple Pre-Shared-Key configuration that you can set via
'idf.py menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
Note: PSK will only be used if the URI is prefixed with coaps://
instead of coap:// and the PSK must be one that the server supports
(potentially associated with the IDENTITY)
*/
#define EXAMPLE_COAP_PSK_KEY CONFIG_EXAMPLE_COAP_PSK_KEY
/* The examples use CoAP Logging Level that
you can set via 'idf.py menuconfig'.
If you'd rather not, just change the below entry to a value
that is between 0 and 7 with
the config you want - ie #define EXAMPLE_COAP_LOG_DEFAULT_LEVEL 7
*/
#define EXAMPLE_COAP_LOG_DEFAULT_LEVEL CONFIG_COAP_LOG_DEFAULT_LEVEL
const static char *TAG = "CoAP_server";
static char espressif_data[100];
static int espressif_data_len = 0;
#ifdef CONFIG_COAP_MBEDTLS_PKI
/* CA cert, taken from coap_ca.pem
Server cert, taken from coap_server.crt
Server key, taken from coap_server.key
The PEM, CRT and KEY file are examples taken from
https://github.com/eclipse/californium/tree/master/demo-certs/src/main/resources
as the Certificate test (by default) for the coap_client is against the
californium server.
To embed it in the app binary, the PEM, CRT and KEY file is named
in the component.mk COMPONENT_EMBED_TXTFILES variable.
*/
extern uint8_t ca_pem_start[] asm("_binary_coap_ca_pem_start");
extern uint8_t ca_pem_end[] asm("_binary_coap_ca_pem_end");
extern uint8_t server_crt_start[] asm("_binary_coap_server_crt_start");
extern uint8_t server_crt_end[] asm("_binary_coap_server_crt_end");
extern uint8_t server_key_start[] asm("_binary_coap_server_key_start");
extern uint8_t server_key_end[] asm("_binary_coap_server_key_end");
#endif /* CONFIG_COAP_MBEDTLS_PKI */
#define INITIAL_DATA "Hello World!"
/*
* The resource handler
*/
static void
hnd_espressif_get(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response)
{
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN, 60, 0,
(size_t)espressif_data_len,
(const u_char *)espressif_data,
NULL, NULL);
}
static void
hnd_espressif_put(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response)
{
size_t size;
size_t offset;
size_t total;
const unsigned char *data;
coap_resource_notify_observers(resource, NULL);
if (strcmp (espressif_data, INITIAL_DATA) == 0) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
} else {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
}
/* coap_get_data_large() sets size to 0 on error */
(void)coap_get_data_large(request, &size, &data, &offset, &total);
if (size == 0) { /* re-init */
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
espressif_data_len = strlen(espressif_data);
} else {
espressif_data_len = size > sizeof (espressif_data) ? sizeof (espressif_data) : size;
memcpy (espressif_data, data, espressif_data_len);
}
}
static void
hnd_espressif_delete(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response)
{
coap_resource_notify_observers(resource, NULL);
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
espressif_data_len = strlen(espressif_data);
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
}
#ifdef CONFIG_COAP_MBEDTLS_PKI
static int
verify_cn_callback(const char *cn,
const uint8_t *asn1_public_cert,
size_t asn1_length,
coap_session_t *session,
unsigned depth,
int validated,
void *arg
)
{
coap_log(LOG_INFO, "CN '%s' presented by server (%s)\n",
cn, depth ? "CA" : "Certificate");
return 1;
}
#endif /* CONFIG_COAP_MBEDTLS_PKI */
static void
coap_log_handler (coap_log_t level, const char *message)
{
uint32_t esp_level = ESP_LOG_INFO;
char *cp = strchr(message, '\n');
if (cp)
ESP_LOG_LEVEL(esp_level, TAG, "%.*s", (int)(cp-message), message);
else
ESP_LOG_LEVEL(esp_level, TAG, "%s", message);
}
static void coap_example_server(void *p)
{
coap_context_t *ctx = NULL;
coap_address_t serv_addr;
coap_resource_t *resource = NULL;
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
espressif_data_len = strlen(espressif_data);
coap_set_log_handler(coap_log_handler);
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
while (1) {
coap_endpoint_t *ep = NULL;
unsigned wait_ms;
int have_dtls = 0;
/* Prepare the CoAP server socket */
coap_address_init(&serv_addr);
serv_addr.addr.sin6.sin6_family = AF_INET6;
serv_addr.addr.sin6.sin6_port = htons(COAP_DEFAULT_PORT);
ctx = coap_new_context(NULL);
if (!ctx) {
ESP_LOGE(TAG, "coap_new_context() failed");
continue;
}
coap_context_set_block_mode(ctx,
COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY);
#ifdef CONFIG_COAP_MBEDTLS_PSK
/* Need PSK setup before we set up endpoints */
coap_context_set_psk(ctx, "CoAP",
(const uint8_t *)EXAMPLE_COAP_PSK_KEY,
sizeof(EXAMPLE_COAP_PSK_KEY) - 1);
#endif /* CONFIG_COAP_MBEDTLS_PSK */
#ifdef CONFIG_COAP_MBEDTLS_PKI
/* Need PKI setup before we set up endpoints */
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
unsigned int server_crt_bytes = server_crt_end - server_crt_start;
unsigned int server_key_bytes = server_key_end - server_key_start;
coap_dtls_pki_t dtls_pki;
memset (&dtls_pki, 0, sizeof(dtls_pki));
dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION;
if (ca_pem_bytes) {
/*
* Add in additional certificate checking.
* This list of enabled can be tuned for the specific
* requirements - see 'man coap_encryption'.
*
* Note: A list of root ca file can be setup separately using
* coap_context_set_pki_root_cas(), but the below is used to
* define what checking actually takes place.
*/
dtls_pki.verify_peer_cert = 1;
dtls_pki.check_common_ca = 1;
dtls_pki.allow_self_signed = 1;
dtls_pki.allow_expired_certs = 1;
dtls_pki.cert_chain_validation = 1;
dtls_pki.cert_chain_verify_depth = 2;
dtls_pki.check_cert_revocation = 1;
dtls_pki.allow_no_crl = 1;
dtls_pki.allow_expired_crl = 1;
dtls_pki.allow_bad_md_hash = 1;
dtls_pki.allow_short_rsa_length = 1;
dtls_pki.validate_cn_call_back = verify_cn_callback;
dtls_pki.cn_call_back_arg = NULL;
dtls_pki.validate_sni_call_back = NULL;
dtls_pki.sni_call_back_arg = NULL;
}
dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM_BUF;
dtls_pki.pki_key.key.pem_buf.public_cert = server_crt_start;
dtls_pki.pki_key.key.pem_buf.public_cert_len = server_crt_bytes;
dtls_pki.pki_key.key.pem_buf.private_key = server_key_start;
dtls_pki.pki_key.key.pem_buf.private_key_len = server_key_bytes;
dtls_pki.pki_key.key.pem_buf.ca_cert = ca_pem_start;
dtls_pki.pki_key.key.pem_buf.ca_cert_len = ca_pem_bytes;
coap_context_set_pki(ctx, &dtls_pki);
#endif /* CONFIG_COAP_MBEDTLS_PKI */
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_UDP);
if (!ep) {
ESP_LOGE(TAG, "udp: coap_new_endpoint() failed");
goto clean_up;
}
if (coap_tcp_is_supported()) {
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_TCP);
if (!ep) {
ESP_LOGE(TAG, "tcp: coap_new_endpoint() failed");
goto clean_up;
}
}
#if defined(CONFIG_COAP_MBEDTLS_PSK) || defined(CONFIG_COAP_MBEDTLS_PKI)
if (coap_dtls_is_supported()) {
#ifndef CONFIG_MBEDTLS_TLS_SERVER
/* This is not critical as unencrypted support is still available */
ESP_LOGI(TAG, "MbedTLS DTLS Server Mode not configured");
#else /* CONFIG_MBEDTLS_TLS_SERVER */
serv_addr.addr.sin6.sin6_port = htons(COAPS_DEFAULT_PORT);
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_DTLS);
if (!ep) {
ESP_LOGE(TAG, "dtls: coap_new_endpoint() failed");
goto clean_up;
}
have_dtls = 1;
#endif /* CONFIG_MBEDTLS_TLS_SERVER */
}
if (coap_tls_is_supported()) {
#ifndef CONFIG_MBEDTLS_TLS_SERVER
/* This is not critical as unencrypted support is still available */
ESP_LOGI(TAG, "MbedTLS TLS Server Mode not configured");
#else /* CONFIG_MBEDTLS_TLS_SERVER */
serv_addr.addr.sin6.sin6_port = htons(COAPS_DEFAULT_PORT);
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_TLS);
if (!ep) {
ESP_LOGE(TAG, "tls: coap_new_endpoint() failed");
goto clean_up;
}
#endif /* CONFIG_MBEDTLS_TLS_SERVER */
}
if (!have_dtls) {
/* This is not critical as unencrypted support is still available */
ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured");
}
#endif /* CONFIG_COAP_MBEDTLS_PSK || CONFIG_COAP_MBEDTLS_PKI */
resource = coap_resource_init(coap_make_str_const("Espressif"), 0);
if (!resource) {
ESP_LOGE(TAG, "coap_resource_init() failed");
goto clean_up;
}
coap_register_handler(resource, COAP_REQUEST_GET, hnd_espressif_get);
coap_register_handler(resource, COAP_REQUEST_PUT, hnd_espressif_put);
coap_register_handler(resource, COAP_REQUEST_DELETE, hnd_espressif_delete);
/* We possibly want to Observe the GETs */
coap_resource_set_get_observable(resource, 1);
coap_add_resource(ctx, resource);
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV4) || defined(CONFIG_EXAMPLE_COAP_MCAST_IPV6)
esp_netif_t *netif = NULL;
for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) {
char buf[8];
netif = esp_netif_next(netif);
esp_netif_get_netif_impl_name(netif, buf);
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV4)
coap_join_mcast_group_intf(ctx, CONFIG_EXAMPLE_COAP_MULTICAST_IPV4_ADDR, buf);
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV4 */
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV6)
/* When adding IPV6 esp-idf requires ifname param to be filled in */
coap_join_mcast_group_intf(ctx, CONFIG_EXAMPLE_COAP_MULTICAST_IPV6_ADDR, buf);
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV6 */
}
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV4 || CONFIG_EXAMPLE_COAP_MCAST_IPV6 */
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
while (1) {
int result = coap_io_process(ctx, wait_ms);
if (result < 0) {
break;
} else if (result && (unsigned)result < wait_ms) {
/* decrement if there is a result wait time returned */
wait_ms -= result;
}
if (result) {
/* result must have been >= wait_ms, so reset wait_ms */
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
}
}
}
clean_up:
coap_free_context(ctx);
coap_cleanup();
vTaskDelete(NULL);
}
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
xTaskCreate(coap_example_server, "coap", 8 * 1024, NULL, 5, NULL);
}

View File

@ -1,2 +0,0 @@
dependencies:
espressif/coap: "^4.3.0"

View File

@ -1,5 +0,0 @@
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
CONFIG_MBEDTLS_PSK_MODES=y
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
CONFIG_LWIP_NETBUF_RECVINFO=y
CONFIG_COAP_SERVER_SUPPORT=y

View File

@ -1395,8 +1395,6 @@ examples/peripherals/uart/uart_repl/main/uart_repl_example_main.c
examples/peripherals/uart/uart_select/main/uart_select_example_main.c
examples/peripherals/usb/host/msc/components/msc/test/msc_device.c
examples/peripherals/wave_gen/main/wave_gen_example_main.c
examples/protocols/coap_client/main/coap_client_example_main.c
examples/protocols/coap_server/main/coap_server_example_main.c
examples/protocols/esp_http_client/esp_http_client_test.py
examples/protocols/esp_http_client/main/esp_http_client_example.c
examples/protocols/esp_local_ctrl/example_test.py