coap_server.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * File : coap_server.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009-2018 RT-Thread Develop Team
  5. */
  6. #include <rtthread.h>
  7. #include "finsh.h"
  8. #include <string.h>
  9. #include <netdb.h>
  10. #include "coap.h"
  11. #define COAP_DEFAULT_TIME_SEC 5
  12. #define COAP_DEFAULT_TIME_USEC 0
  13. static coap_async_state_t *async = NULL;
  14. static void send_async_response(coap_context_t *ctx, const coap_endpoint_t *local_if)
  15. {
  16. coap_pdu_t *response;
  17. unsigned char buf[3];
  18. const char *response_data = "Hello rtthread!";
  19. size_t size = sizeof(coap_hdr_t) + strlen(response_data) + 20;
  20. response = coap_pdu_init(async->flags & COAP_MESSAGE_CON, COAP_RESPONSE_CODE(205), 0, size);
  21. response->hdr->id = coap_new_message_id(ctx);
  22. if (async->tokenlen)
  23. coap_add_token(response, async->tokenlen, async->token);
  24. coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
  25. coap_add_data(response, strlen(response_data), (unsigned char *)response_data);
  26. if (coap_send(ctx, local_if, &async->peer, response) == COAP_INVALID_TID)
  27. {
  28. rt_kprintf("Error: coap send to client return error.\n");
  29. }
  30. coap_delete_pdu(response);
  31. coap_async_state_t *tmp;
  32. coap_remove_async(ctx, async->id, &tmp);
  33. coap_free_async(async);
  34. async = NULL;
  35. }
  36. static void async_handler(coap_context_t *ctx, struct coap_resource_t *resource,
  37. const coap_endpoint_t *local_interface, coap_address_t *peer,
  38. coap_pdu_t *request, str *token, coap_pdu_t *response)
  39. {
  40. async = coap_register_async(ctx, peer, request, COAP_ASYNC_SEPARATE | COAP_ASYNC_CONFIRM, (void *)"#$ no data #$");
  41. }
  42. static void coap_server_task(void *arg)
  43. {
  44. coap_context_t *ctx = NULL;
  45. coap_address_t serv_addr;
  46. coap_resource_t *resource = NULL;
  47. fd_set readfds;
  48. struct timeval tv;
  49. int flags = 0;
  50. for (;;)
  51. {
  52. /* Prepare the CoAP server socket */
  53. coap_address_init(&serv_addr);
  54. serv_addr.addr.sin.sin_family = AF_INET;
  55. serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
  56. serv_addr.addr.sin.sin_port = htons(COAP_DEFAULT_PORT);
  57. ctx = coap_new_context(&serv_addr);
  58. if (ctx)
  59. {
  60. tv.tv_usec = COAP_DEFAULT_TIME_USEC;
  61. tv.tv_sec = COAP_DEFAULT_TIME_SEC;
  62. /* Initialize the resource, first param is uri */
  63. resource = coap_resource_init((unsigned char *)"rtthread", 8, 0);
  64. if (resource)
  65. {
  66. coap_register_handler(resource, COAP_REQUEST_GET, async_handler);
  67. coap_add_resource(ctx, resource);
  68. /*For incoming connections*/
  69. for (;;)
  70. {
  71. FD_ZERO(&readfds);
  72. FD_CLR(ctx->sockfd, &readfds);
  73. FD_SET(ctx->sockfd, &readfds);
  74. int result = select(ctx->sockfd + 1, &readfds, 0, 0, &tv);
  75. if (result > 0)
  76. {
  77. if (FD_ISSET(ctx->sockfd, &readfds))
  78. coap_read(ctx);
  79. }
  80. else if (result < 0)
  81. {
  82. break;
  83. }
  84. else
  85. {
  86. rt_kprintf("select waiting...\n");
  87. }
  88. if (async)
  89. {
  90. send_async_response(ctx, ctx->endpoint);
  91. }
  92. }
  93. }
  94. coap_free_context(ctx);
  95. }
  96. }
  97. }
  98. static int coap_server(void)
  99. {
  100. rt_thread_t tid;
  101. tid = rt_thread_create("CoAPServer",
  102. coap_server_task, RT_NULL,
  103. 4096,
  104. RT_THREAD_PRIORITY_MAX - 2,
  105. 10);
  106. if (tid != RT_NULL)
  107. rt_thread_startup(tid);
  108. return 0;
  109. }
  110. MSH_CMD_EXPORT(coap_server, Start a coap server No input param);