examples: Add CoAP server demo

Test CoAP protocol server
This commit is contained in:
Liu Han 2016-12-10 13:48:38 +08:00 committed by Wu Jian Gang
parent d0b10ba2dd
commit 899f61f4a2
5 changed files with 264 additions and 0 deletions

View file

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := coap_server
include $(IDF_PATH)/make/project.mk

View file

@ -0,0 +1,22 @@
menu "Example Configuration"
config LOCAL_PORT_NUMBER
int "Local port number"
range 0 65535
default 5683
help
Local port number for the example to use.
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
endmenu

View file

@ -0,0 +1,190 @@
/* 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.
*/
#include "coap_server.h"
#include <string.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_loop.h"
#include "nvs_flash.h"
#include <sys/socket.h>
#include "coap_config.h"
#include "resource.h"
#include "coap.h"
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const static int CONNECTED_BIT = BIT0;
const static char *TAG = "CoAP_demo";
static coap_async_state_t *async = NULL;
static void
send_async_response(coap_context_t *ctx, const coap_endpoint_t *local_if)
{
coap_pdu_t *response;
unsigned char buf[3];
const char* response_data = "Hello World!";
size_t size = sizeof(coap_hdr_t) + 20;
response = coap_pdu_init(async->flags & COAP_MESSAGE_CON, COAP_RESPONSE_CODE(205), 0, size);
response->hdr->id = coap_new_message_id(ctx);
if (async->tokenlen)
coap_add_token(response, async->tokenlen, async->token);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
coap_add_data (response, strlen(response_data), (unsigned char *)response_data);
if (coap_send(ctx, local_if, &async->peer, response) == COAP_INVALID_TID) {
}
coap_delete_pdu(response);
coap_async_state_t *tmp;
coap_remove_async(ctx, async->id, &tmp);
coap_free_async(async);
async = NULL;
}
/*
* The resource handler
*/
static void
async_handler(coap_context_t *ctx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
async = coap_register_async(ctx, peer, request, COAP_ASYNC_SEPARATE | COAP_ASYNC_CONFIRM, (void*)"no data");
}
static void coap_demo_thread(void *p)
{
coap_context_t* ctx = NULL;
coap_address_t serv_addr;
coap_resource_t* resource = NULL;
fd_set readfds;
struct timeval tv;
int flags = 0;
/* Prepare the CoAP server socket */
coap_address_init(&serv_addr);
serv_addr.addr.sin.sin_family = AF_INET;
serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
serv_addr.addr.sin.sin_port = htons(COAP_DEFAULT_PORT);
ctx = coap_new_context(&serv_addr);
if (ctx) {
flags = fcntl(ctx->sockfd, F_GETFL, 0);
fcntl(ctx->sockfd, F_SETFL, flags|O_NONBLOCK);
tv.tv_usec = COAP_DEFAULT_TIME_USEC;
tv.tv_sec = COAP_DEFAULT_TIME_SEC;
/* Initialize the resource */
resource = coap_resource_init((unsigned char *)"Espressif", 9, 0);
if (resource){
coap_register_handler(resource, COAP_REQUEST_GET, async_handler);
coap_add_resource(ctx, resource);
/*For incoming connections*/
for (;;) {
FD_ZERO(&readfds);
FD_CLR( ctx->sockfd, &readfds);
FD_SET( ctx->sockfd, &readfds);
int result = select( FD_SETSIZE, &readfds, 0, 0, &tv );
if (result > 0){
if (FD_ISSET( ctx->sockfd, &readfds ))
coap_read(ctx);
} else if (result < 0){
break;
} else {
printf("select timeout\n");
}
if (async)
send_async_response(ctx, ctx->endpoint);
}
}
coap_free_context(ctx);
}
vTaskDelete(NULL);
}
static void coap_server_init(void)
{
int ret = pdPASS;
xTaskHandle coap_handle = NULL;
ret = xTaskCreate(coap_demo_thread,
COAP_DEMO_THREAD_NAME,
COAP_DEMO_THREAD_STACK_WORDS,
NULL,
COAP_DEMO_THREAD_PRORIOTY,
&coap_handle);
if (ret != pdPASS) {
ESP_LOGI(TAG, "create thread %s failed", COAP_DEMO_THREAD_NAME);
}
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
coap_server_init();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_conn_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
void app_main(void)
{
nvs_flash_init();
wifi_conn_init();
}

View file

@ -0,0 +1,38 @@
/* 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.
*/
#ifndef _COAP_SERVER_H_
#define _COAP_SERVER_H_
#include <sdkconfig.h>
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#define COAP_DEMO_THREAD_NAME "CoAP_demo"
#define COAP_DEMO_THREAD_STACK_WORDS 10240
#define COAP_DEMO_THREAD_PRORIOTY 8
/* The examples use local port number of 5683 that you can set via 'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define OPENSSL_DEMO_TARGET_TCP_PORT 5683
*/
#define COAP_DEFAULT_PORT CONFIG_LOCAL_PORT_NUMBER
#define COAP_DEFAULT_TIME_SEC 5
#define COAP_DEFAULT_TIME_USEC 0
#endif

View file

@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)