123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- #include <iostream>
- #include <string>
- #include <atomic>
- #include <vector>
- #include <kbf.h>
- #include <kbf/wifi_legacy.h>
- #include <kbf/rtos.h>
- #include <kbf/http/client.h>
- #include <kbf/web_service.h>
- #include <unity.h>
- using std::cout;
- using std::endl;
- using std::string;
- using std::atomic;
- #define KBF_TEST_WIFI_SSID "kbf_test_wifi_ap"
- #define KBF_TEST_WIFI_DUAL_MASTER_SSID "kbf_test_wifi_master"
- #define KBF_TEST_WIFI_DUAL_SLAVE_SSID "kbf_test_wifi_slave"
- #define KBF_TEST_WIFI_PASS "Pas$w0Rd1337"
- static atomic<int> state{0};
- static void fail() {
- TEST_ASSERT_EQUAL_MESSAGE(-1337, state, "fail(): unexpected call to event handler");
- }
- static void waitForState(int expectedState, int timeoutSeconds) {
- int hax = 10;
- for (int i = 1; i < timeoutSeconds * hax; i++) {
- if (state == expectedState) break;
- if (i % hax == 0) {
- cout << "waitForState: " << state << " / " << expectedState << "; ";
- cout << i << " / " << timeoutSeconds * hax << endl;
- }
- kbf::sleep(1000 / hax);
- }
- }
- TEST_CASE("WiFi legacy STA mode reconnect", "[kbf_wifi_legacy]") {
- using namespace kbf;
- state = 0;
- auto sta = wifi::STA::create();
- sta->onStart = {[]() { TEST_ASSERT_EQUAL(0, state++); }};
- sta->onConnect = fail;
- sta->onIp = fail;
- sta->onReconnecting = {[](int attempt, int limit) {
- TEST_ASSERT_EQUAL(state++, attempt);
- TEST_ASSERT_EQUAL(2, limit);
- return true;
- }};
- sta->onDisconnect = {[]() { TEST_ASSERT_EQUAL(3, state++); }};
- wifi::start(sta);
- waitForState(1, 1);
- TEST_ASSERT_EQUAL(1, state);
- sta->connect(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS, 2);
- waitForState(4, 10);
- cout << "waiting for any more reconnect attempts..." << endl;
- kbf::sleep(5000);
- TEST_ASSERT_EQUAL(4, state);
- wifi::stop();
- }
- TEST_CASE("WiFi legacy STA mode reconnect cancel", "[kbf_wifi_legacy]") {
- using namespace kbf;
- wifi::start(wifi::STA::create());
- auto sta = wifi::getSTA();
- state = 0;
- sta->onStart = {[]() { TEST_ASSERT_EQUAL(0, state++); }};
- sta->onConnect = fail;
- sta->onIp = fail;
- sta->onReconnecting = {[](int attempt, int limit) {
- state++;
- TEST_ASSERT_EQUAL(1, attempt);
- TEST_ASSERT_EQUAL(5, limit);
- return false;
- }};
- sta->onDisconnect = {[]() { TEST_ASSERT_EQUAL(2, state++); }};
- waitForState(1, 1);
- TEST_ASSERT_EQUAL(1, state);
- sta->connect(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS, 5);
- waitForState(3, 10);
- cout << "waiting for any more reconnect attempts..." << endl;
- kbf::sleep(5000);
- TEST_ASSERT_EQUAL(3, state);
- wifi::stop();
- }
- void wifiSingleMaster() {
- using namespace kbf;
- wifi::start(wifi::AP::create(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS));
- auto ap = wifi::getAP();
- TEST_ASSERT_EQUAL_STRING(KBF_TEST_WIFI_SSID, ap->ssid.c_str());
- TEST_ASSERT_EQUAL_STRING(KBF_TEST_WIFI_PASS, ap->password.c_str());
- state = 0;
- ap->onStart = {[]() { TEST_ASSERT_EQUAL(0, state++); }};
- ap->onConnect = {[](wifi::AP::STA &) { TEST_ASSERT_EQUAL(1, state++); }};
- ap->onDisconnect = {[](wifi::AP::STA &) { TEST_ASSERT_EQUAL(2, state++); }};
- ap->onStop = {[]() { TEST_ASSERT_EQUAL(3, state++); }};
- waitForState(3, 30);
- wifi::stop();
- waitForState(4, 1);
- TEST_ASSERT_EQUAL(4, state);
- }
- void wifiSingleSlave() {
- using namespace kbf;
- wifi::start(wifi::STA::create());
- auto sta = wifi::getSTA();
- state = 0;
- sta->onStart = {[]() { TEST_ASSERT_EQUAL(0, state++); }};
- sta->onConnect = {[]() { TEST_ASSERT_EQUAL(1, state++); }};
- sta->onIp = {[]() { TEST_ASSERT_EQUAL(2, state++); }};
- sta->onDisconnect = {[]() { TEST_ASSERT_EQUAL(3, state++); }};
- sta->onStop = {[]() { TEST_ASSERT_EQUAL(4, state++); }};
- waitForState(1, 1);
- TEST_ASSERT_EQUAL(1, state);
- sta->connect(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS);
- waitForState(3, 30);
- TEST_ASSERT_EQUAL(3, state);
- const string ip = sta->ip().str();
- TEST_ASSERT_GREATER_THAN(0, ip.length());
- sta->disconnect();
- waitForState(4, 1);
- TEST_ASSERT_EQUAL(4, state);
- wifi::stop();
- waitForState(5, 1);
- TEST_ASSERT_EQUAL(5, state);
- }
- TEST_CASE_MULTIPLE_DEVICES("WiFi legacy AP <--> STA", "[kbf_wifi_legacy]", wifiSingleMaster, wifiSingleSlave)
- void wifiDualMaster() {
- using namespace kbf;
- auto ap = wifi::AP::create(KBF_TEST_WIFI_DUAL_MASTER_SSID, KBF_TEST_WIFI_PASS);
- auto sta = wifi::STA::create();
- state = 0;
- ap->onStart = {[]() {
- TEST_ASSERT_EQUAL(0, state++);
- }};
- ap->onConnect = {[](wifi::AP::STA &) {
- TEST_ASSERT_EQUAL(1, state++);
- auto sta = wifi::getSTA();
- sta->connect(KBF_TEST_WIFI_DUAL_SLAVE_SSID, KBF_TEST_WIFI_PASS);
- }};
- sta->onConnect = {[]() {
- TEST_ASSERT_EQUAL(2, state++);
- auto sta = wifi::getSTA();
- sta->disconnect();
- }};
- sta->onDisconnect = {[]() {
- TEST_ASSERT_EQUAL(3, state++);
- }};
- ap->onDisconnect = {[](wifi::AP::STA &) {
- TEST_ASSERT_EQUAL(4, state++);
- }};
- wifi::start(ap, sta);
- waitForState(5, 30);
- wifi::stop();
- }
- void wifiDualSlave() {
- using namespace kbf;
- auto ap = wifi::AP::create(KBF_TEST_WIFI_DUAL_SLAVE_SSID, KBF_TEST_WIFI_PASS);
- auto sta = wifi::STA::create();
- state = 0;
- ap->onStart = {[]() {
- TEST_ASSERT_EQUAL(0, state++);
- auto sta = wifi::getSTA();
- sta->connect(KBF_TEST_WIFI_DUAL_MASTER_SSID, KBF_TEST_WIFI_PASS);
- }};
- sta->onConnect = {[]() {
- TEST_ASSERT_EQUAL(1, state++);
- }};
- ap->onConnect = {[](wifi::AP::STA &) {
- TEST_ASSERT_EQUAL(2, state++);
- }};
- ap->onDisconnect = {[](wifi::AP::STA &) {
- TEST_ASSERT_EQUAL(3, state++);
- auto sta = wifi::getSTA();
- sta->disconnect();
- }};
- sta->onDisconnect = {[]() {
- TEST_ASSERT_EQUAL(4, state++);
- }};
- wifi::start(ap, sta);
- waitForState(5, 30);
- wifi::stop();
- }
- TEST_CASE_MULTIPLE_DEVICES("WiFi legacy AP+STA <--> AP+STA", "[kbf_wifi_legacy]", wifiDualMaster, wifiDualSlave)
- void wifiScanMaster() {
- using namespace kbf;
- auto ap = wifi::AP::create(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS);
- state = 0;
- ap->onDisconnect = {[](wifi::AP::STA &) {
- TEST_ASSERT_EQUAL(0, state++);
- }};
- wifi::start(ap);
- waitForState(1, 30);
- wifi::stop();
- }
- void wifiScanSlave() {
- using namespace kbf;
- using std::vector;
- state = 0;
- wifi::start();
- auto sta = wifi::getSTA();
- sta->onScanDone = {[](vector<wifi::APInfo> &apList, void *data) {
- TEST_ASSERT_EQUAL(0, state++);
- TEST_ASSERT_EQUAL_STRING("foobar!", (char *) data);
- bool found = false;
- for (const auto &ap : apList) {
- if (ap.ssid == KBF_TEST_WIFI_SSID) {
- found = true;
- break;
- }
- }
- TEST_ASSERT_TRUE(found)
- wifi::getSTA()->connect(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS);
- }};
- sta->onConnect = {[]() {
- TEST_ASSERT_EQUAL(1, state++);
- }};
- sta->startScan((void *) "foobar!");
- waitForState(2, 30);
- wifi::stop();
- }
- TEST_CASE_MULTIPLE_DEVICES("WiFi legacy scan", "[kbf_wifi_legacy]", wifiScanMaster, wifiScanSlave)
- static kbf::rtos::EventGroup eventGroup;
- void wifiIpMaster() {
- using namespace kbf;
- eventGroup = rtos::EventGroup();
- auto ap = wifi::AP::create(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS, net::IP("192.168.1.1"));
- ap->onDisconnect = {[](wifi::AP::STA &) {
- eventGroup.setBit(0);
- }};
- wifi::start(ap);
- eventGroup.waitForBit(0);
- wifi::stop();
- }
- void wifiIpSlave() {
- using namespace kbf;
- using namespace std;
- eventGroup = rtos::EventGroup();
- wifi::start();
- auto sta = wifi::getSTA();
- sta->onIp = {[]() {
- auto ip = wifi::getSTA()->ip();
- eventGroup.setBit(0);
- TEST_ASSERT_EQUAL(192, ip[0]);
- TEST_ASSERT_EQUAL(168, ip[1]);
- TEST_ASSERT_EQUAL(1, ip[2]);
- TEST_ASSERT_EQUAL(2, ip[3]);
- }};
- sta->connect(KBF_TEST_WIFI_SSID, KBF_TEST_WIFI_PASS);
- eventGroup.waitForBit(0);
- wifi::stop();
- }
- TEST_CASE_MULTIPLE_DEVICES("WiFi legacy custom IP address", "[kbf_wifi_legacy]", wifiIpMaster, wifiIpSlave)
- static kbf::http::Client *client;
- void wifiModeSwitchMaster() {
- using namespace kbf;
- eventGroup = rtos::EventGroup();
- auto ap = wifi::AP::create(
- KBF_TEST_WIFI_DUAL_MASTER_SSID,
- KBF_TEST_WIFI_PASS,
- net::IP("192.168.1.1")
- );
- ap->onConnect = {[](wifi::AP::STA &) {
- wifi::getSTA()->connect(KBF_TEST_WIFI_DUAL_SLAVE_SSID, KBF_TEST_WIFI_PASS);
- }};
- delete client;
- client = new http::Client();
- auto sta = wifi::STA::create();
- sta->onIp = {[]() {
- wifi::stopAP();
- kbf::sleep(1000);
- auto response = client->get("http://192.168.2.1/");
- TEST_ASSERT_EQUAL(200, response->status);
- eventGroup.setBit(0);
- }};
- wifi::start(ap, sta);
- eventGroup.waitForBit(0);
- wifi::stop();
- }
- class TestController : public kbf::WebService::Controller {
- public:
- TestController() : kbf::WebService::Controller("/") {}
- kbf::http::Response get(const kbf::http::Request &request) override {
- eventGroup.setBit(0);
- if (eventGroup.getBit(1)) return kbf::http::Response("", 501);
- if (!eventGroup.getBit(2)) return kbf::http::Response("", 502);
- return kbf::http::Response("", 200);
- }
- };
- void wifiModeSwitchSlave() {
- using namespace kbf;
- using namespace std;
- eventGroup = rtos::EventGroup();
- auto ap = wifi::AP::create(
- KBF_TEST_WIFI_DUAL_SLAVE_SSID,
- KBF_TEST_WIFI_PASS,
- net::IP("192.168.2.1")
- );
- ap->onDisconnect = {[](wifi::AP::STA &) {
- eventGroup.setBit(1);
- }};
- auto sta = wifi::STA::create();
- sta->onReconnecting = {[](int, int) {
- return false;
- }};
- sta->onDisconnect = {[]() {
- eventGroup.setBit(2);
- }};
- wifi::start(ap, sta);
- auto webService = WebService();
- webService.controller<TestController>();
- webService.start();
- sta->connect(KBF_TEST_WIFI_DUAL_MASTER_SSID, KBF_TEST_WIFI_PASS);
- eventGroup.waitForBit(0);
- kbf::sleep(1000);
- wifi::stop();
- }
- TEST_CASE_MULTIPLE_DEVICES("WiFi legacy mode switching", "[kbf_wifi_legacy]", wifiModeSwitchMaster, wifiModeSwitchSlave)
- TEST_CASE("WiFi legacy state handling", "[kbf_wifi_legacy]") {
- using namespace kbf;
- wifi::stop();
- TEST_ASSERT_FALSE(wifi::isRunning())
- wifi::start();
- kbf::sleep(1000);
- TEST_ASSERT_TRUE(wifi::isRunning())
- wifi::stop();
- kbf::sleep(1000);
- TEST_ASSERT_FALSE(wifi::isRunning())
- wifi::stop();
- }
|