Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
3.8 KiB

  1. /*
  2. WEBSOCKET MODULE
  3. Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #pragma once
  6. #include "espurna.h"
  7. #include <IPAddress.h>
  8. #include <cstdint>
  9. #include <memory>
  10. #include <vector>
  11. constexpr const size_t WS_DEBUG_MSG_BUFFER = 8;
  12. // -----------------------------------------------------------------------------
  13. // WS authentication
  14. // -----------------------------------------------------------------------------
  15. struct ws_ticket_t {
  16. IPAddress ip;
  17. unsigned long timestamp = 0;
  18. };
  19. // -----------------------------------------------------------------------------
  20. // WS callbacks
  21. // -----------------------------------------------------------------------------
  22. struct ws_counter_t {
  23. ws_counter_t() : current(0), start(0), stop(0) {}
  24. ws_counter_t(uint32_t start, uint32_t stop) :
  25. current(start), start(start), stop(stop) {}
  26. void reset() {
  27. current = start;
  28. }
  29. void next() {
  30. if (current < stop) {
  31. ++current;
  32. }
  33. }
  34. bool done() {
  35. return (current >= stop);
  36. }
  37. uint32_t current;
  38. uint32_t start;
  39. uint32_t stop;
  40. };
  41. struct ws_data_t {
  42. enum mode_t {
  43. SEQUENCE,
  44. ALL
  45. };
  46. ws_data_t(const ws_on_send_callback_f& cb) :
  47. storage(new ws_on_send_callback_list_t {cb}),
  48. client_id(0),
  49. mode(ALL),
  50. callbacks(*storage.get()),
  51. counter(0, 1)
  52. {}
  53. ws_data_t(uint32_t client_id, const ws_on_send_callback_f& cb) :
  54. storage(new ws_on_send_callback_list_t {cb}),
  55. client_id(client_id),
  56. mode(ALL),
  57. callbacks(*storage.get()),
  58. counter(0, 1)
  59. {}
  60. ws_data_t(const uint32_t client_id, ws_on_send_callback_list_t&& callbacks, mode_t mode = SEQUENCE) :
  61. storage(new ws_on_send_callback_list_t(std::move(callbacks))),
  62. client_id(client_id),
  63. mode(mode),
  64. callbacks(*storage.get()),
  65. counter(0, (storage.get())->size())
  66. {}
  67. ws_data_t(const uint32_t client_id, const ws_on_send_callback_list_t& callbacks, mode_t mode = SEQUENCE) :
  68. client_id(client_id),
  69. mode(mode),
  70. callbacks(callbacks),
  71. counter(0, callbacks.size())
  72. {}
  73. bool done() {
  74. return counter.done();
  75. }
  76. void sendAll(JsonObject& root) {
  77. while (!counter.done()) counter.next();
  78. for (auto& callback : callbacks) {
  79. callback(root);
  80. }
  81. }
  82. void sendCurrent(JsonObject& root) {
  83. callbacks[counter.current](root);
  84. counter.next();
  85. }
  86. void send(JsonObject& root) {
  87. switch (mode) {
  88. case SEQUENCE: sendCurrent(root); break;
  89. case ALL: sendAll(root); break;
  90. }
  91. }
  92. std::unique_ptr<ws_on_send_callback_list_t> storage;
  93. const uint32_t client_id;
  94. const mode_t mode;
  95. const ws_on_send_callback_list_t& callbacks;
  96. ws_counter_t counter;
  97. };
  98. // -----------------------------------------------------------------------------
  99. // Debug
  100. // -----------------------------------------------------------------------------
  101. using ws_debug_msg_t = std::pair<String, String>;
  102. struct ws_debug_t {
  103. ws_debug_t(size_t capacity) :
  104. flush(false),
  105. current(0),
  106. capacity(capacity)
  107. {
  108. messages.reserve(capacity);
  109. }
  110. void clear() {
  111. messages.clear();
  112. current = 0;
  113. flush = false;
  114. }
  115. void add(const char* prefix, const char* message) {
  116. if (current >= capacity) {
  117. flush = true;
  118. send(wsConnected());
  119. }
  120. messages.emplace(messages.begin() + current, prefix, message);
  121. flush = true;
  122. ++current;
  123. }
  124. void send(const bool connected);
  125. bool flush;
  126. size_t current;
  127. const size_t capacity;
  128. std::vector<ws_debug_msg_t> messages;
  129. };