coap_server_example_main.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* CoAP server Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/event_groups.h"
  12. #include "esp_log.h"
  13. #include "esp_wifi.h"
  14. #include "esp_event_loop.h"
  15. #include "nvs_flash.h"
  16. #include "coap.h"
  17. /* The examples use simple WiFi configuration that you can set via
  18. 'make menuconfig'.
  19. If you'd rather not, just change the below entries to strings with
  20. the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
  21. */
  22. #define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
  23. #define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
  24. #define COAP_DEFAULT_TIME_SEC 5
  25. #define COAP_DEFAULT_TIME_USEC 0
  26. static EventGroupHandle_t wifi_event_group;
  27. /* The event group allows multiple bits for each event,
  28. but we only care about one event - are we connected
  29. to the AP with an IP? */
  30. const static int CONNECTED_BIT = BIT0;
  31. const static char *TAG = "CoAP_server";
  32. static coap_async_state_t *async = NULL;
  33. static void
  34. send_async_response(coap_context_t *ctx, const coap_endpoint_t *local_if)
  35. {
  36. coap_pdu_t *response;
  37. unsigned char buf[3];
  38. const char* response_data = "Hello World!";
  39. response = coap_pdu_init(async->flags & COAP_MESSAGE_CON, COAP_RESPONSE_CODE(205), 0, COAP_MAX_PDU_SIZE);
  40. response->hdr->id = coap_new_message_id(ctx);
  41. if (async->tokenlen)
  42. coap_add_token(response, async->tokenlen, async->token);
  43. coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
  44. coap_add_data (response, strlen(response_data), (unsigned char *)response_data);
  45. if (coap_send(ctx, local_if, &async->peer, response) == COAP_INVALID_TID) {
  46. }
  47. coap_delete_pdu(response);
  48. coap_async_state_t *tmp;
  49. coap_remove_async(ctx, async->id, &tmp);
  50. coap_free_async(async);
  51. async = NULL;
  52. }
  53. /*
  54. * The resource handler
  55. */
  56. static void
  57. async_handler(coap_context_t *ctx, struct coap_resource_t *resource,
  58. const coap_endpoint_t *local_interface, coap_address_t *peer,
  59. coap_pdu_t *request, str *token, coap_pdu_t *response)
  60. {
  61. async = coap_register_async(ctx, peer, request, COAP_ASYNC_SEPARATE | COAP_ASYNC_CONFIRM, (void*)"no data");
  62. }
  63. static void coap_example_thread(void *p)
  64. {
  65. coap_context_t* ctx = NULL;
  66. coap_address_t serv_addr;
  67. coap_resource_t* resource = NULL;
  68. fd_set readfds;
  69. struct timeval tv;
  70. int flags = 0;
  71. while (1) {
  72. /* Wait for the callback to set the CONNECTED_BIT in the
  73. event group.
  74. */
  75. xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
  76. false, true, portMAX_DELAY);
  77. ESP_LOGI(TAG, "Connected to AP");
  78. /* Prepare the CoAP server socket */
  79. coap_address_init(&serv_addr);
  80. serv_addr.addr.sin.sin_family = AF_INET;
  81. serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
  82. serv_addr.addr.sin.sin_port = htons(COAP_DEFAULT_PORT);
  83. ctx = coap_new_context(&serv_addr);
  84. if (ctx) {
  85. flags = fcntl(ctx->sockfd, F_GETFL, 0);
  86. fcntl(ctx->sockfd, F_SETFL, flags|O_NONBLOCK);
  87. tv.tv_usec = COAP_DEFAULT_TIME_USEC;
  88. tv.tv_sec = COAP_DEFAULT_TIME_SEC;
  89. /* Initialize the resource */
  90. resource = coap_resource_init((unsigned char *)"Espressif", 9, 0);
  91. if (resource){
  92. coap_register_handler(resource, COAP_REQUEST_GET, async_handler);
  93. coap_add_resource(ctx, resource);
  94. /*For incoming connections*/
  95. for (;;) {
  96. FD_ZERO(&readfds);
  97. FD_CLR( ctx->sockfd, &readfds);
  98. FD_SET( ctx->sockfd, &readfds);
  99. int result = select( ctx->sockfd+1, &readfds, 0, 0, &tv );
  100. if (result > 0){
  101. if (FD_ISSET( ctx->sockfd, &readfds ))
  102. coap_read(ctx);
  103. } else if (result < 0){
  104. break;
  105. } else {
  106. ESP_LOGE(TAG, "select timeout");
  107. }
  108. if (async) {
  109. send_async_response(ctx, ctx->endpoint);
  110. }
  111. }
  112. }
  113. coap_free_context(ctx);
  114. }
  115. }
  116. vTaskDelete(NULL);
  117. }
  118. static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
  119. {
  120. switch(event->event_id) {
  121. case SYSTEM_EVENT_STA_START:
  122. esp_wifi_connect();
  123. break;
  124. case SYSTEM_EVENT_STA_GOT_IP:
  125. xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
  126. break;
  127. case SYSTEM_EVENT_STA_DISCONNECTED:
  128. /* This is a workaround as ESP32 WiFi libs don't currently
  129. auto-reassociate. */
  130. esp_wifi_connect();
  131. xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
  132. break;
  133. default:
  134. break;
  135. }
  136. return ESP_OK;
  137. }
  138. static void wifi_conn_init(void)
  139. {
  140. tcpip_adapter_init();
  141. wifi_event_group = xEventGroupCreate();
  142. ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) );
  143. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  144. ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
  145. ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
  146. wifi_config_t wifi_config = {
  147. .sta = {
  148. .ssid = EXAMPLE_WIFI_SSID,
  149. .password = EXAMPLE_WIFI_PASS,
  150. },
  151. };
  152. ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
  153. ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
  154. ESP_ERROR_CHECK( esp_wifi_start() );
  155. }
  156. void app_main(void)
  157. {
  158. ESP_ERROR_CHECK( nvs_flash_init() );
  159. wifi_conn_init();
  160. xTaskCreate(coap_example_thread, "coap", 2048, NULL, 5, NULL);
  161. }