test_wifi_modeswitch.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <vector>
  2. #include <esp_log.h>
  3. #include "kbf.h"
  4. #include "kbf/wifi.h"
  5. #include "kbf/rtos.h"
  6. #include "kbf/web_service.h"
  7. #include "kbf/http/client.h"
  8. #include "kbf/http/exception.h"
  9. #include <unity.h>
  10. #define MASTER_SSID "kbf_test_wifi_master"
  11. #define SLAVE_SSID "kbf_test_wifi_slave"
  12. #define WIFI_PASS "Pas$w0Rd1337"
  13. #define MASTER_AP "http://192.168.1.1/ping"
  14. #define MASTER_STA "http://192.168.2.2/ping"
  15. #define SLAVE_AP "http://192.168.2.1/ping"
  16. #define SLAVE_STA "http://192.168.1.2/ping"
  17. #define PING_RESPONSE "P0NG"
  18. #define PING 0
  19. using namespace kbf;
  20. using std::vector;
  21. static rtos::EventGroup event; // NOLINT(cert-err58-cpp)
  22. static string lastPingID;
  23. class PingController : public WebService::Controller {
  24. public:
  25. PingController() : Controller("/ping") {}
  26. protected:
  27. http::Response get(const http::Request &request) override {
  28. lastPingID = request.query.at("id");
  29. ESP_LOGI("PingController", "%s", lastPingID.c_str());
  30. event.setBit(PING);
  31. return http::Response(PING_RESPONSE);
  32. }
  33. };
  34. static auto client = new http::Client(); // NOLINT(cert-err58-cpp)
  35. static void pingOK(const string &url, int id) {
  36. const auto response = client->get(url + "?id=" + std::to_string(id));
  37. TEST_ASSERT_EQUAL(200, response->status);
  38. TEST_ASSERT_EQUAL_STRING(PING_RESPONSE, response->body.c_str());
  39. }
  40. static void pingFail(const string &url) {
  41. try {
  42. client->get(url);
  43. } catch (http::exception::ConnectionError &) {
  44. return;
  45. }
  46. TEST_FAIL();
  47. }
  48. static void waitForPing(int id) {
  49. ESP_LOGI(__func__, "%d", id);
  50. event.waitForBit(PING);
  51. event.clear();
  52. TEST_ASSERT_EQUAL_STRING(std::to_string(id).c_str(), lastPingID.c_str());
  53. }
  54. static void fail() {
  55. TEST_FAIL();
  56. }
  57. static void fail(wifi::STA &) {
  58. TEST_FAIL();
  59. }
  60. void master() {
  61. constexpr const char *const TAG = __func__;
  62. auto pingService = WebService();
  63. pingService.controller<PingController>();
  64. ESP_LOGI(TAG, "0 - starting AP");
  65. wifi::ap::onDisconnect = fail;
  66. wifi::sta::onDisconnect = fail;
  67. wifi::ap::start(MASTER_SSID, WIFI_PASS);
  68. TEST_ASSERT_EQUAL(wifi::Mode::AP, wifi::mode());
  69. pingService.start();
  70. ESP_LOGI(TAG, "1 - master is AP, slave is STA");
  71. waitForPing(0);
  72. pingOK(SLAVE_STA, 1);
  73. pingFail(SLAVE_AP);
  74. ESP_LOGI(TAG, "2 - master is AP, slave switches to DUAL");
  75. waitForPing(2);
  76. pingOK(SLAVE_STA, 3);
  77. pingFail(SLAVE_AP);
  78. ESP_LOGI(TAG, "3 - master switches to DUAL, slave is DUAL");
  79. wifi::sta::start();
  80. TEST_ASSERT_EQUAL(wifi::Mode::DUAL, wifi::mode());
  81. wifi::sta::connect(SLAVE_SSID, WIFI_PASS);
  82. pingOK(SLAVE_STA, 4);
  83. pingOK(SLAVE_AP, 5);
  84. waitForPing(6);
  85. waitForPing(7);
  86. ESP_LOGI(TAG, "4 - master switches to STA, slave is DUAL");
  87. kbf::sleep(100); // wait for slave to disable onDisconnect
  88. wifi::ap::stop();
  89. TEST_ASSERT_EQUAL(wifi::Mode::STA, wifi::mode());
  90. pingOK(SLAVE_AP, 8);
  91. waitForPing(9);
  92. pingFail(SLAVE_STA);
  93. ESP_LOGI(TAG, "5 - master is STA, slave switches to AP");
  94. waitForPing(10);
  95. pingOK(SLAVE_AP, 11);
  96. pingFail(SLAVE_STA);
  97. ESP_LOGI(TAG, "finished");
  98. wifi::sta::onDisconnect = nullptr;
  99. kbf::sleep(100); // wait for slave to disable onDisconnect
  100. pingService.stop();
  101. wifi::stop();
  102. TEST_ASSERT_EQUAL(wifi::Mode::OFF, wifi::mode());
  103. }
  104. void slave() {
  105. constexpr const char *const TAG = __func__;
  106. auto pingService = WebService();
  107. pingService.controller<PingController>();
  108. ESP_LOGI(TAG, "0 - starting STA");
  109. wifi::ap::onDisconnect = fail;
  110. wifi::sta::onDisconnect = fail;
  111. wifi::sta::start();
  112. TEST_ASSERT_EQUAL(wifi::Mode::STA, wifi::mode());
  113. pingService.start();
  114. ESP_LOGI(TAG, "1 - master: AP, slave is STA");
  115. wifi::sta::connect(MASTER_SSID, WIFI_PASS);
  116. pingOK(MASTER_AP, 0);
  117. waitForPing(1);
  118. pingFail(MASTER_STA);
  119. ESP_LOGI(TAG, "2 - master is AP, slave switches to DUAL");
  120. wifi::ap::start(SLAVE_SSID, WIFI_PASS);
  121. TEST_ASSERT_EQUAL(wifi::Mode::DUAL, wifi::mode());
  122. pingOK(MASTER_AP, 2);
  123. waitForPing(3);
  124. pingFail(MASTER_STA);
  125. ESP_LOGI(TAG, "3 - master switches to DUAL, slave is DUAL");
  126. waitForPing(4);
  127. waitForPing(5);
  128. pingOK(MASTER_STA, 6);
  129. pingOK(MASTER_AP, 7);
  130. ESP_LOGI(TAG, "4 - master switches to STA, slave is DUAL");
  131. wifi::sta::onDisconnect = nullptr;
  132. waitForPing(8);
  133. pingOK(MASTER_STA, 9);
  134. pingFail(MASTER_AP);
  135. ESP_LOGI(TAG, "5 - master is STA, slave switches to AP");
  136. wifi::sta::stop();
  137. TEST_ASSERT_EQUAL(wifi::Mode::AP, wifi::mode());
  138. pingOK(MASTER_STA, 10);
  139. waitForPing(11);
  140. pingFail(MASTER_AP);
  141. ESP_LOGI(TAG, "finished");
  142. wifi::ap::onDisconnect = nullptr;
  143. kbf::sleep(100); // wait for master to disable onDisconnect
  144. pingService.stop();
  145. wifi::stop();
  146. TEST_ASSERT_EQUAL(wifi::Mode::OFF, wifi::mode());
  147. }
  148. TEST_CASE_MULTIPLE_DEVICES("WiFi mode STA to DUAL", "[kbf_wifi]", master, slave);