coap_server_example_main.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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.h"
  15. #include "nvs_flash.h"
  16. #include "protocol_examples_common.h"
  17. #include "coap.h"
  18. /* Set this to 9 to get verbose logging from within libcoap */
  19. #define COAP_LOGGING_LEVEL 0
  20. static char espressif_data[100];
  21. static int espressif_data_len = 0;
  22. /*
  23. * The resource handler
  24. */
  25. static void
  26. hnd_espressif_get(coap_context_t *ctx, coap_resource_t *resource,
  27. coap_session_t *session,
  28. coap_pdu_t *request, coap_binary_t *token,
  29. coap_string_t *query, coap_pdu_t *response)
  30. {
  31. coap_add_data_blocked_response(resource, session, request, response, token,
  32. COAP_MEDIATYPE_TEXT_PLAIN, 0,
  33. (size_t)espressif_data_len,
  34. (const u_char *)espressif_data);
  35. }
  36. static void
  37. hnd_espressif_put(coap_context_t *ctx,
  38. coap_resource_t *resource,
  39. coap_session_t *session,
  40. coap_pdu_t *request,
  41. coap_binary_t *token,
  42. coap_string_t *query,
  43. coap_pdu_t *response)
  44. {
  45. size_t size;
  46. unsigned char *data;
  47. coap_resource_notify_observers(resource, NULL);
  48. if (strcmp (espressif_data, "no data") == 0) {
  49. response->code = COAP_RESPONSE_CODE(201);
  50. }
  51. else {
  52. response->code = COAP_RESPONSE_CODE(204);
  53. }
  54. /* coap_get_data() sets size to 0 on error */
  55. (void)coap_get_data(request, &size, &data);
  56. if (size == 0) { /* re-init */
  57. snprintf(espressif_data, sizeof(espressif_data), "no data");
  58. espressif_data_len = strlen(espressif_data);
  59. } else {
  60. espressif_data_len = size > sizeof (espressif_data) ? sizeof (espressif_data) : size;
  61. memcpy (espressif_data, data, espressif_data_len);
  62. }
  63. }
  64. static void
  65. hnd_espressif_delete(coap_context_t *ctx,
  66. coap_resource_t *resource,
  67. coap_session_t *session,
  68. coap_pdu_t *request,
  69. coap_binary_t *token,
  70. coap_string_t *query,
  71. coap_pdu_t *response)
  72. {
  73. coap_resource_notify_observers(resource, NULL);
  74. snprintf(espressif_data, sizeof(espressif_data), "no data");
  75. espressif_data_len = strlen(espressif_data);
  76. response->code = COAP_RESPONSE_CODE(202);
  77. }
  78. static void coap_example_thread(void *p)
  79. {
  80. coap_context_t *ctx = NULL;
  81. coap_address_t serv_addr;
  82. coap_resource_t *resource = NULL;
  83. snprintf(espressif_data, sizeof(espressif_data), "no data");
  84. espressif_data_len = strlen(espressif_data);
  85. coap_set_log_level(COAP_LOGGING_LEVEL);
  86. while (1) {
  87. coap_endpoint_t *ep_udp = NULL;
  88. coap_endpoint_t *ep_tcp = NULL;
  89. unsigned wait_ms;
  90. /* Prepare the CoAP server socket */
  91. coap_address_init(&serv_addr);
  92. serv_addr.addr.sin.sin_family = AF_INET;
  93. serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
  94. serv_addr.addr.sin.sin_port = htons(COAP_DEFAULT_PORT);
  95. ctx = coap_new_context(NULL);
  96. if (!ctx) {
  97. continue;
  98. }
  99. ep_udp = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_UDP);
  100. if (!ep_udp) {
  101. goto clean_up;
  102. }
  103. ep_tcp = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_TCP);
  104. if (!ep_tcp) {
  105. goto clean_up;
  106. }
  107. resource = coap_resource_init(coap_make_str_const("Espressif"), 0);
  108. if (!resource) {
  109. goto clean_up;
  110. }
  111. coap_register_handler(resource, COAP_REQUEST_GET, hnd_espressif_get);
  112. coap_register_handler(resource, COAP_REQUEST_PUT, hnd_espressif_put);
  113. coap_register_handler(resource, COAP_REQUEST_DELETE, hnd_espressif_delete);
  114. /* We possibly want to Observe the GETs */
  115. coap_resource_set_get_observable(resource, 1);
  116. coap_add_resource(ctx, resource);
  117. wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
  118. while (1) {
  119. int result = coap_run_once(ctx, wait_ms);
  120. if (result < 0) {
  121. break;
  122. } else if (result && (unsigned)result < wait_ms) {
  123. /* decrement if there is a result wait time returned */
  124. wait_ms -= result;
  125. }
  126. if (result) {
  127. /* result must have been >= wait_ms, so reset wait_ms */
  128. wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
  129. }
  130. }
  131. }
  132. clean_up:
  133. coap_free_context(ctx);
  134. coap_cleanup();
  135. vTaskDelete(NULL);
  136. }
  137. void app_main(void)
  138. {
  139. ESP_ERROR_CHECK( nvs_flash_init() );
  140. tcpip_adapter_init();
  141. ESP_ERROR_CHECK(esp_event_loop_create_default());
  142. /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
  143. * Read "Establishing Wi-Fi or Ethernet Connection" section in
  144. * examples/protocols/README.md for more information about this function.
  145. */
  146. ESP_ERROR_CHECK(example_connect());
  147. xTaskCreate(coap_example_thread, "coap", 1024 * 5, NULL, 5, NULL);
  148. }