diff --git a/examples/tinymqtt-test/tinymqtt-test.ino b/examples/tinymqtt-test/tinymqtt-test.ino index c9ed61c..7fb5b7c 100644 --- a/examples/tinymqtt-test/tinymqtt-test.ino +++ b/examples/tinymqtt-test/tinymqtt-test.ino @@ -4,12 +4,12 @@ #include // https://github.com/hsaturn/TinyMqtt #include #if defined(ESP8266) - #include +#include #elif defined(ESP32) - #include - #include +#include +#include #else - #error Unsupported platform +#error Unsupported platform #endif #include @@ -23,15 +23,15 @@ auto cyan = TinyConsole::cyan; auto yellow = TinyConsole::yellow; /** Very complex example - * Console allowing to make any kind of test, - * even some stress tests. - * - * Upload the sketch, the use the terminal. - * Press H for mini help. - * - * tested with mqtt-spy-0.5.4 - * TODO examples of scripts - */ + * Console allowing to make any kind of test, + * even some stress tests. + * + * Upload the sketch, the use the terminal. + * Press H for mini help. + * + * tested with mqtt-spy-0.5.4 + * TODO examples of scripts + */ const char* ssid = "Freebox-786A2F"; const char* password = "usurpavi8dalum64lumine?"; @@ -40,20 +40,20 @@ std::string topic="sensor/temperature"; void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) { - Console << cyan << "--> " << srce->id().c_str() << ": received " << topic.c_str() << white; - if (payload) - { - Console << ", payload[" << length << "]=["; - while(length--) - { - const char c=*payload++; - if (c<32) - Console << '?'; - else - Console << c; - } - Console << ']' << endl; - } + Console << cyan << "--> " << srce->id().c_str() << ": received " << topic.c_str() << white; + if (payload) + { + Console << ", payload[" << length << "]=["; + while(length--) + { + const char c=*payload++; + if (c<32) + Console << '?'; + else + Console << c; + } + Console << ']' << endl; + } } std::map clients; @@ -61,28 +61,28 @@ std::map brokers; void setup() { - WiFi.persistent(false); // https://github.com/esp8266/Arduino/issues/1054 + WiFi.persistent(false); // https://github.com/esp8266/Arduino/issues/1054 Serial.begin(115200); - Console.begin(Serial); - Console.setPrompt("> "); - Console.setCallback(onCommand); - delay(500); + Console.begin(Serial); + Console.setPrompt("> "); + Console.setCallback(onCommand); + delay(500); - Console.cls(); + Console.cls(); Console << endl << endl; Console << yellow - << "***************************************************************" << endl; + << "***************************************************************" << endl; Console << "* Welcome to the TinyMqtt console" << endl; Console << "* The console allows to test all features of the libraries." << endl; - Console << "* Enter help to view the list of commands." << endl; + Console << "* Enter help to view the list of commands." << endl; Console << "***************************************************************" << endl; Console << endl; if (strlen(ssid)==0) Console << red << "* ERROR: You must modify ssid/password in order" << endl - << " to be able to connect to your Wifi network." << endl; + << " to be able to connect to your Wifi network." << endl; Console << endl << white; - Console << "Connecting to '" << ssid << "' "; + Console << "Connecting to '" << ssid << "' "; WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); @@ -102,332 +102,332 @@ void setup() Console << " ok." << endl; - MqttBroker* broker = new MqttBroker(1883); - broker->begin(); - brokers["broker"] = broker; + MqttBroker* broker = new MqttBroker(1883); + broker->begin(); + brokers["broker"] = broker; } std::string getword(std::string& str, const char* if_empty=nullptr, char sep=' '); int getint(std::string& str, const int if_empty=0) { - std::string str2=str; - std::string sword = getword(str); - if (sword[0] and isdigit(sword[0])) - { - int ret=atoi(sword.c_str()); - while(isdigit(sword[0]) or sword[0]==' ') sword.erase(0,1); - if (sword.length()) str = sword+' '+str; - return ret; - } - str=str2; + std::string str2=str; + std::string sword = getword(str); + if (sword[0] and isdigit(sword[0])) + { + int ret=atoi(sword.c_str()); + while(isdigit(sword[0]) or sword[0]==' ') sword.erase(0,1); + if (sword.length()) str = sword+' '+str; + return ret; + } + str=str2; return if_empty; } std::string getword(std::string& str, const char* if_empty/*=nullptr*/, char sep/*=' '*/) { - char quote=(str[0]=='"' or str[0]=='\'' ? str[0] : 0); - if (quote) str.erase(0,1); - std::string sword; - while(str.length() and (str[0]!=sep or quote)) - { - if (str[0]==quote) - { - str.erase(0,1); - break; - } - sword += str[0]; - str.erase(0,1); - } - while(str[0]==sep) str.erase(0,1); - if (if_empty and sword.length()==0) return if_empty; - if (quote==false and sword.length()>=4 and sword.substr(0,3)=="rnd") - { - sword.erase(0,3); - if (sword[0]=='(') - { - int to = 100; - sword.erase(0,1); - int from=getint(sword); - if (sword[0]==',') - { - sword.erase(0,1); - to = getint(sword); - if (sword[0]!=')') Console << "Missing ')'" << endl; - } - else - { - to=from; - from=0; - } - return String(random(from,to)).c_str(); - } - else - { - Console << "Missing '('" << endl; - } - } - while(str[0]==' ') str.erase(0,1); - return sword; + char quote=(str[0]=='"' or str[0]=='\'' ? str[0] : 0); + if (quote) str.erase(0,1); + std::string sword; + while(str.length() and (str[0]!=sep or quote)) + { + if (str[0]==quote) + { + str.erase(0,1); + break; + } + sword += str[0]; + str.erase(0,1); + } + while(str[0]==sep) str.erase(0,1); + if (if_empty and sword.length()==0) return if_empty; + if (quote==false and sword.length()>=4 and sword.substr(0,3)=="rnd") + { + sword.erase(0,3); + if (sword[0]=='(') + { + int to = 100; + sword.erase(0,1); + int from=getint(sword); + if (sword[0]==',') + { + sword.erase(0,1); + to = getint(sword); + if (sword[0]!=')') Console << "Missing ')'" << endl; + } + else + { + to=from; + from=0; + } + return String(random(from,to)).c_str(); + } + else + { + Console << "Missing '('" << endl; + } + } + while(str[0]==' ') str.erase(0,1); + return sword; } bool isaddr(std::string s) { - if (s.length()==0 or s.length()>3) return false; - for(char c: s) - if (c<'0' or c>'9') return false; - return true; + if (s.length()==0 or s.length()>3) return false; + for(char c: s) + if (c<'0' or c>'9') return false; + return true; } std::string getip(std::string& str, const char* if_empty=nullptr, char sep=' ') { - std::string addr=getword(str, if_empty, sep); - std::string ip=addr; - std::vector build; - while(ip.length()) - { - std::string b=getword(ip,nullptr,'.'); - if (isaddr(b) && build.size()<4) - { - build.push_back(b); - } - else - return addr; - } - IPAddress local=WiFi.localIP(); - addr.clear(); - while(build.size()!=4) - { - std::stringstream b; - b << (int)local[3-build.size()]; - build.insert(build.begin(), b.str()); - } - for(std::string s: build) - { - if (addr.length()) addr += '.'; - addr += s; - } - return addr; + std::string addr=getword(str, if_empty, sep); + std::string ip=addr; + std::vector build; + while(ip.length()) + { + std::string b=getword(ip,nullptr,'.'); + if (isaddr(b) && build.size()<4) + { + build.push_back(b); + } + else + return addr; + } + IPAddress local=WiFi.localIP(); + addr.clear(); + while(build.size()!=4) + { + std::stringstream b; + b << (int)local[3-build.size()]; + build.insert(build.begin(), b.str()); + } + for(std::string s: build) + { + if (addr.length()) addr += '.'; + addr += s; + } + return addr; } std::map vars; std::set commands = { - "auto", "broker", "blink", "client", "connect", - "create", "delete", "help", "interval", - "ls", "ip", "off", "on", "set", - "publish", "reset", "subscribe", "unsubscribe", "view", "echo", "every" + "auto", "broker", "blink", "client", "connect", + "create", "delete", "help", "interval", + "ls", "ip", "off", "on", "set", + "publish", "reset", "subscribe", "unsubscribe", "view", "echo", "every" }; void convertToCommand(std::string& search) { - while(search[0]==' ') search.erase(0,1); - if (search.length()==0) return; - std::string matches; - int count=0; - for(std::string cmd: commands) - { - if (cmd.substr(0, search.length()) == search) - { - if (count) matches +=", "; - count++; - matches += cmd; - } - } - if (count==1) - search = matches; - else if (count>1) - { - Console << "Ambiguous command: " << matches << endl; - search.clear(); - } + while(search[0]==' ') search.erase(0,1); + if (search.length()==0) return; + std::string matches; + int count=0; + for(std::string cmd: commands) + { + if (cmd.substr(0, search.length()) == search) + { + if (count) matches +=", "; + count++; + matches += cmd; + } + } + if (count==1) + search = matches; + else if (count>1) + { + Console << "Ambiguous command: " << matches << endl; + search.clear(); + } } void replace(const char* d, std::string& str, std::string srch, std::string to) { - if (d[0] && d[1]) - { - srch=d[0]+srch+d[1]; - to=d[0]+to+d[1]; + if (d[0] && d[1]) + { + srch=d[0]+srch+d[1]; + to=d[0]+to+d[1]; - size_t pos = 0; - while((pos=str.find(srch, pos)) != std::string::npos) - { - str.erase(pos, srch.length()); - str.insert(pos, to); - pos += to.length()-1; - } - } + size_t pos = 0; + while((pos=str.find(srch, pos)) != std::string::npos) + { + str.erase(pos, srch.length()); + str.insert(pos, to); + pos += to.length()-1; + } + } } void replaceVars(std::string& cmd) { - cmd = ' '+cmd+' '; + cmd = ' '+cmd+' '; - for(auto it: vars) - { - replace("..", cmd, it.first, it.second); - replace(". ", cmd, it.first, it.second); - replace(" .", cmd, it.first, it.second); - replace(" ", cmd, it.first, it.second); - } - cmd.erase(0, cmd.find_first_not_of(" ")); - cmd.erase(cmd.find_last_not_of(" ")+1); + for(auto it: vars) + { + replace("..", cmd, it.first, it.second); + replace(". ", cmd, it.first, it.second); + replace(" .", cmd, it.first, it.second); + replace(" ", cmd, it.first, it.second); + } + cmd.erase(0, cmd.find_first_not_of(" ")); + cmd.erase(cmd.find_last_not_of(" ")+1); } // publish at regular interval class Automatic { - public: - Automatic(MqttClient* clt, uint32_t intervl) - : client(clt), topic_(::topic) - { - interval(intervl); - autos[clt] = this; - } + public: + Automatic(MqttClient* clt, uint32_t intervl) + : client(clt), topic_(::topic) + { + interval(intervl); + autos[clt] = this; + } - void interval(uint32_t new_interval) - { - interval_ = new_interval; - if (interval_<1000) interval_=1000; - timer_ = millis() + interval_; - } + void interval(uint32_t new_interval) + { + interval_ = new_interval; + if (interval_<1000) interval_=1000; + timer_ = millis() + interval_; + } - void loop_() - { - if (!bon) return; - if (interval_ && millis() > timer_) - { - Console << "AUTO PUBLISH " << interval_ << endl; - timer_ += interval_; - client->publish(topic_, std::string(String(15+millis()%10).c_str())); - } - } + void loop_() + { + if (!bon) return; + if (interval_ && millis() > timer_) + { + Console << "AUTO PUBLISH " << interval_ << endl; + timer_ += interval_; + client->publish(topic_, std::string(String(15+millis()%10).c_str())); + } + } - void topic(std::string new_topic) { topic_ = new_topic; } + void topic(std::string new_topic) { topic_ = new_topic; } - static void loop() - { - for(auto it: autos) - it.second->loop_(); - } + static void loop() + { + for(auto it: autos) + it.second->loop_(); + } - static void command(MqttClient* who, std::string cmd) - { - Automatic* autop = nullptr; - if (autos.find(who) != autos.end()) - { - autop=autos[who]; - } - std::string s = getword(cmd); - if (compare(s, "create")) - { - std::string seconds=getword(cmd, "10000"); - if (autop) delete autop; - std::string top = getword(cmd, ::topic.c_str()); - autos[who] = new Automatic(who, atol(seconds.c_str())); - autos[who]->topic(top); - autos[who]->bon=true; - Console << "New auto (" << seconds.c_str() << " topic:" << top.c_str() << ')' << endl; - } - else if (autop) - { - while(s.length()) - { - if (s=="on") - { - autop->bon = true; - autop->interval(autop->interval_); - } - else if (s=="off") - autop->bon=false; - else if (s=="interval") - { - int32_t i=getint(cmd); - if (i) - autop->interval(atol(s.c_str())); - else - Console << "Bad value" << endl; - } - else if (s=="view") - { - Console << " Automatic " - << (int32_t)autop->client - << " interval " << autop->interval_ - << (autop->bon ? " on" : " off") << endl; - } - else - { - Console << "Unknown auto command (" << s.c_str() << ")" << endl; - break; - } - s=getword(cmd); - } - } - else if (who==nullptr) - { - for(auto it: autos) - command(it.first, s+' '+cmd); - } - else - Console << "what ? (" << s.c_str() << ")" << endl; - } + static void command(MqttClient* who, std::string cmd) + { + Automatic* autop = nullptr; + if (autos.find(who) != autos.end()) + { + autop=autos[who]; + } + std::string s = getword(cmd); + if (compare(s, "create")) + { + std::string seconds=getword(cmd, "10000"); + if (autop) delete autop; + std::string top = getword(cmd, ::topic.c_str()); + autos[who] = new Automatic(who, atol(seconds.c_str())); + autos[who]->topic(top); + autos[who]->bon=true; + Console << "New auto (" << seconds.c_str() << " topic:" << top.c_str() << ')' << endl; + } + else if (autop) + { + while(s.length()) + { + if (s=="on") + { + autop->bon = true; + autop->interval(autop->interval_); + } + else if (s=="off") + autop->bon=false; + else if (s=="interval") + { + int32_t i=getint(cmd); + if (i) + autop->interval(atol(s.c_str())); + else + Console << "Bad value" << endl; + } + else if (s=="view") + { + Console << " Automatic " + << (int32_t)autop->client + << " interval " << autop->interval_ + << (autop->bon ? " on" : " off") << endl; + } + else + { + Console << "Unknown auto command (" << s.c_str() << ")" << endl; + break; + } + s=getword(cmd); + } + } + else if (who==nullptr) + { + for(auto it: autos) + command(it.first, s+' '+cmd); + } + else + Console << "what ? (" << s.c_str() << ")" << endl; + } - static void help() - { - Console << " auto [$id] on/off" << endl; - Console << " auto [$id] view" << endl; - Console << " auto [$id] interval [s]" << endl; - Console << " auto [$id] create [millis] [topic]" << endl; - } + static void help() + { + Console << " auto [$id] on/off" << endl; + Console << " auto [$id] view" << endl; + Console << " auto [$id] interval [s]" << endl; + Console << " auto [$id] create [millis] [topic]" << endl; + } - private: - MqttClient* client; - uint32_t interval_; - uint32_t timer_; - std::string topic_; - bool bon=false; - static std::map autos; - float temp=19; + private: + MqttClient* client; + uint32_t interval_; + uint32_t timer_; + std::string topic_; + bool bon=false; + static std::map autos; + float temp=19; }; std::map Automatic::autos; bool compare(std::string s, const char* cmd) { - uint8_t p=0; - while(s[p++]==*cmd++) - { - if (*cmd==0 or s[p]==0) return true; - if (s[p]==' ') return true; - } - return false; + uint8_t p=0; + while(s[p++]==*cmd++) + { + if (*cmd==0 or s[p]==0) return true; + if (s[p]==' ') return true; + } + return false; } using ClientFunction = void(*)(std::string& cmd, MqttClient* publish); struct Every { - std::string cmd; - uint32_t ms; - uint32_t next; - uint32_t underrun=0; - bool active=true; + std::string cmd; + uint32_t ms; + uint32_t next; + uint32_t underrun=0; + bool active=true; - void dump() - { - if (active) - Console << green << "enabled"; - else - Console << red << "disabled"; + void dump() + { + if (active) + Console << green << "enabled"; + else + Console << red << "disabled"; - auto mill=millis(); - Console << white << ms << "ms [" << cmd << "] next in "; - if (mill > next) - Console << "now"; - else - Console << next-mill << "ms"; - } + auto mill=millis(); + Console << white << ms << "ms [" << cmd << "] next in "; + if (mill > next) + Console << "now"; + else + Console << next-mill << "ms"; + } }; uint32_t blink_ms_on[16]; @@ -441,475 +441,475 @@ std::vector everies; void onCommand(const std::string& command) { Console << endl; - std::string cmd=command; - if (cmd.substr(0,3)!="set") replaceVars(cmd); - eval(cmd); + std::string cmd=command; + if (cmd.substr(0,3)!="set") replaceVars(cmd); + eval(cmd); } void eval(std::string& cmd) { - while(cmd.length()) - { - MqttError retval = MqttOk; + while(cmd.length()) + { + MqttError retval = MqttOk; - std::string s; - MqttBroker* broker = nullptr; - MqttClient* client = nullptr; + std::string s; + MqttBroker* broker = nullptr; + MqttClient* client = nullptr; - // client.function notation - if (cmd.find('.') != std::string::npos && - cmd.find('.') < cmd.find(' ')) - { - s=getword(cmd, nullptr, '.'); + // client.function notation + if (cmd.find('.') != std::string::npos && + cmd.find('.') < cmd.find(' ')) + { + s=getword(cmd, nullptr, '.'); - if (s.length()) - { - if (clients.find(s) != clients.end()) - { - client = clients[s]; - } - else if (brokers.find(s) != brokers.end()) - { - broker = brokers[s]; - } - else - { - Console << red << "Unknown class (" << s.c_str() << ")" << white << endl; - cmd.clear(); - } - } - } + if (s.length()) + { + if (clients.find(s) != clients.end()) + { + client = clients[s]; + } + else if (brokers.find(s) != brokers.end()) + { + broker = brokers[s]; + } + else + { + Console << red << "Unknown class (" << s.c_str() << ")" << white << endl; + cmd.clear(); + } + } + } - s = getword(cmd); - if (s.length()) convertToCommand(s); - if (s.length()==0) - {} - else if (compare(s, "delete")) - { - if (client==nullptr && broker==nullptr) - { - s = getword(cmd); - if (clients.find(s) != clients.end()) - { - client = clients[s]; - } - else if (brokers.find(s) != brokers.end()) - { - broker = brokers[s]; - } - else - Console << red << "Unable to find (" << s.c_str() << ")" << white << endl; - } - if (client) - { - for (auto it: clients) - { - if (it.second != client) continue; - Console << "deleted" << endl; - delete (it.second); - clients.erase(it.first); - break; - } - cmd += " ls"; - } - else if (broker) - { - for(auto it: brokers) - { - if (broker != it.second) continue; - Console << "deleted" << endl; - delete (it.second); - brokers.erase(it.first); - break; - } - cmd += " ls"; - } - else - Console << "Nothing to delete" << endl; - } - else if (broker) - { - if (compare(s,"connect")) - { - Console << "NYI" << endl; - } - else if (compare(s, "view")) - { - broker->dump(); - } - else - { - Console << "Unknown broker command (" << s << ")" << endl; - s.clear(); - } - } - else if (client) - { - if (compare(s,"connect")) - { - client->connect(getip(cmd,"192.168.1.40").c_str(), getint(cmd, 1883), getint(cmd, 60)); - Console << (client->connected() ? "connected." : "not connected") << endl; - } - else if (compare(s,"publish")) - { - retval = client->publish(getword(cmd, topic.c_str()), getword(cmd)); - } - else if (compare(s,"subscribe")) - { - client->subscribe(getword(cmd, topic.c_str())); - } - else if (compare(s, "unsubscribe")) - { - client->unsubscribe(getword(cmd, topic.c_str())); - } - else if (compare(s, "view")) - { - client->dump(); - } - else - { - Console << "Unknown client command (" << s << ")" << endl; - s.clear(); - } - } - else if (compare(s, "on")) - { - uint8_t pin=getint(cmd, 2); - pinMode(pin, OUTPUT); - digitalWrite(pin, HIGH); - } - else if (compare(s, "off")) - { - uint8_t pin=getint(cmd, 2); - pinMode(pin, OUTPUT); - digitalWrite(pin, LOW); - } - else if (compare(s, "echo")) - { - s=getword(cmd); - if (s=="on") - echo_on = true; - else if (s=="off") - echo_on = false; - else - { - Console << s << ' '; - while(cmd.length()) - { - Console << getword(cmd) << ' '; - } - } - } - else if (compare(s, "every")) - { - uint32_t ms = getint(cmd, 0); - if (ms) - { - if (cmd.length()) - { - Every every; - every.ms=ms; - every.cmd=cmd; - every.next=millis()+ms; - everies.push_back(every); - every.dump(); - Console << endl; - cmd.clear(); - } - } - else if (compare(cmd, "off") or compare(cmd, "on")) - { - bool active=getword(cmd)=="on"; - uint8_t ever=getint(cmd, 100); - uint8_t count=0; - for(auto& every: everies) - { - if (count==ever or (ever==100)) - { - if (every.active != active) - { - Console << "every #" << count << (active ? " on" :" off") << endl; - every.active = active; - every.underrun = 0; - } - } - count++; - } - } - else if (compare(cmd, "list") or cmd.length()==0) - { - getword(cmd); - Console << "List of everies (ms=" << millis() << ")" << endl; - uint8_t count=0; - for(auto& every: everies) - { - Console << count << ": "; - every.dump(); - Console << endl; - count++; - } - } - else if (compare(cmd, "remove")) - { - Console << "Removing..." << endl; - getword(cmd); - int8_t every=getint(cmd, -1); - if (every==-1 and compare(cmd, "last") and everies.size()) - { - getword(cmd); - everies.erase(everies.begin()+everies.size()-1); - } - else if (every==-1 and compare(cmd, "all")) - { - getword(cmd); - everies.clear(); - } - else if (everies.size() > (uint8_t)every) - { - everies.erase(everies.begin()+every); - } - else - Console << "Bad colmmand" << endl; - } - else - Console << "Bad command" << endl; - } - else if (compare(s, "blink")) - { - int8_t blink_nr = getint(cmd, -1); - if (blink_nr >= 0) - { - blink_ms_on[blink_nr]=getint(cmd, blink_ms_on[blink_nr]); - blink_ms_off[blink_nr]=getint(cmd, blink_ms_on[blink_nr]); - pinMode(blink_nr, OUTPUT); - blink_next[blink_nr] = millis(); - Console << "Blink " << blink_nr << ' ' << (blink_ms_on[blink_nr] ? "on" : "off") << endl; - if (blink_ms_on[blink_nr]) - blink |= 1<< blink_nr; - else - { - blink &= ~(1<< blink_nr); - } - } - } - else if (compare(s, "auto")) - { - Automatic::command(client, cmd); - if (client == nullptr) - cmd.clear(); - } - else if (compare(s, "broker")) - { - std::string id=getword(cmd); + s = getword(cmd); + if (s.length()) convertToCommand(s); + if (s.length()==0) + {} + else if (compare(s, "delete")) + { + if (client==nullptr && broker==nullptr) + { + s = getword(cmd); + if (clients.find(s) != clients.end()) + { + client = clients[s]; + } + else if (brokers.find(s) != brokers.end()) + { + broker = brokers[s]; + } + else + Console << red << "Unable to find (" << s.c_str() << ")" << white << endl; + } + if (client) + { + for (auto it: clients) + { + if (it.second != client) continue; + Console << "deleted" << endl; + delete (it.second); + clients.erase(it.first); + break; + } + cmd += " ls"; + } + else if (broker) + { + for(auto it: brokers) + { + if (broker != it.second) continue; + Console << "deleted" << endl; + delete (it.second); + brokers.erase(it.first); + break; + } + cmd += " ls"; + } + else + Console << "Nothing to delete" << endl; + } + else if (broker) + { + if (compare(s,"connect")) + { + Console << "NYI" << endl; + } + else if (compare(s, "view")) + { + broker->dump(); + } + else + { + Console << "Unknown broker command (" << s << ")" << endl; + s.clear(); + } + } + else if (client) + { + if (compare(s,"connect")) + { + client->connect(getip(cmd,"192.168.1.40").c_str(), getint(cmd, 1883), getint(cmd, 60)); + Console << (client->connected() ? "connected." : "not connected") << endl; + } + else if (compare(s,"publish")) + { + retval = client->publish(getword(cmd, topic.c_str()), getword(cmd)); + } + else if (compare(s,"subscribe")) + { + client->subscribe(getword(cmd, topic.c_str())); + } + else if (compare(s, "unsubscribe")) + { + client->unsubscribe(getword(cmd, topic.c_str())); + } + else if (compare(s, "view")) + { + client->dump(); + } + else + { + Console << "Unknown client command (" << s << ")" << endl; + s.clear(); + } + } + else if (compare(s, "on")) + { + uint8_t pin=getint(cmd, 2); + pinMode(pin, OUTPUT); + digitalWrite(pin, HIGH); + } + else if (compare(s, "off")) + { + uint8_t pin=getint(cmd, 2); + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); + } + else if (compare(s, "echo")) + { + s=getword(cmd); + if (s=="on") + echo_on = true; + else if (s=="off") + echo_on = false; + else + { + Console << s << ' '; + while(cmd.length()) + { + Console << getword(cmd) << ' '; + } + } + } + else if (compare(s, "every")) + { + uint32_t ms = getint(cmd, 0); + if (ms) + { + if (cmd.length()) + { + Every every; + every.ms=ms; + every.cmd=cmd; + every.next=millis()+ms; + everies.push_back(every); + every.dump(); + Console << endl; + cmd.clear(); + } + } + else if (compare(cmd, "off") or compare(cmd, "on")) + { + bool active=getword(cmd)=="on"; + uint8_t ever=getint(cmd, 100); + uint8_t count=0; + for(auto& every: everies) + { + if (count==ever or (ever==100)) + { + if (every.active != active) + { + Console << "every #" << count << (active ? " on" :" off") << endl; + every.active = active; + every.underrun = 0; + } + } + count++; + } + } + else if (compare(cmd, "list") or cmd.length()==0) + { + getword(cmd); + Console << "List of everies (ms=" << millis() << ")" << endl; + uint8_t count=0; + for(auto& every: everies) + { + Console << count << ": "; + every.dump(); + Console << endl; + count++; + } + } + else if (compare(cmd, "remove")) + { + Console << "Removing..." << endl; + getword(cmd); + int8_t every=getint(cmd, -1); + if (every==-1 and compare(cmd, "last") and everies.size()) + { + getword(cmd); + everies.erase(everies.begin()+everies.size()-1); + } + else if (every==-1 and compare(cmd, "all")) + { + getword(cmd); + everies.clear(); + } + else if (everies.size() > (uint8_t)every) + { + everies.erase(everies.begin()+every); + } + else + Console << "Bad colmmand" << endl; + } + else + Console << "Bad command" << endl; + } + else if (compare(s, "blink")) + { + int8_t blink_nr = getint(cmd, -1); + if (blink_nr >= 0) + { + blink_ms_on[blink_nr]=getint(cmd, blink_ms_on[blink_nr]); + blink_ms_off[blink_nr]=getint(cmd, blink_ms_on[blink_nr]); + pinMode(blink_nr, OUTPUT); + blink_next[blink_nr] = millis(); + Console << "Blink " << blink_nr << ' ' << (blink_ms_on[blink_nr] ? "on" : "off") << endl; + if (blink_ms_on[blink_nr]) + blink |= 1<< blink_nr; + else + { + blink &= ~(1<< blink_nr); + } + } + } + else if (compare(s, "auto")) + { + Automatic::command(client, cmd); + if (client == nullptr) + cmd.clear(); + } + else if (compare(s, "broker")) + { + std::string id=getword(cmd); if (clients.find(id) != clients.end()) { Console << "A client already have that name" << endl; cmd.clear(); } - else if (id.length() or brokers.find(id)!=brokers.end()) - { - int port=getint(cmd, 0); - if (port) - { - MqttBroker* broker = new MqttBroker(port); - broker->begin(); - - brokers[id] = broker; - Console << "new broker (" << id.c_str() << ")" << endl; - } - else + else if (id.length() or brokers.find(id)!=brokers.end()) + { + int port=getint(cmd, 0); + if (port) { - Console << "Missing port" << endl; + MqttBroker* broker = new MqttBroker(port); + broker->begin(); + + brokers[id] = broker; + Console << "new broker (" << id.c_str() << ")" << endl; + } + else + { + Console << "Missing port" << endl; cmd.clear(); } - } - else + } + else { - Console << "Missing or existing broker name (" << id.c_str() << ")" << endl; + Console << "Missing or existing broker name (" << id.c_str() << ")" << endl; cmd.clear(); } - } - else if (compare(s, "client")) - { - std::string id=getword(cmd); + } + else if (compare(s, "client")) + { + std::string id=getword(cmd); if (brokers.find(id) != brokers.end()) { - Console << "A broker have that name" << endl; - cmd.clear(); - } - else if (id.length() or clients.find(id)!=clients.end()) - { - s=getword(cmd); // broker name - if (s=="" or brokers.find(s) != brokers.end()) - { - MqttBroker* broker = nullptr; - if (s.length()) broker = brokers[s]; - MqttClient* client = new MqttClient(broker); - client->id(id); - clients[id]=client; - client->setCallback(onPublish); - client->subscribe(topic); - Console << "new client (" << id.c_str() << ", " << s.c_str() << ')' << endl; - } - else if (s.length()) - { - Console << " not found." << endl; - cmd.clear(); - } - } - else - { - Console << "Missing or existing client name" << endl; + Console << "A broker have that name" << endl; cmd.clear(); - } - } - else if (compare(s, "set")) - { - std::string name(getword(cmd)); - if (name.length()==0) - { - for(auto it: vars) - { - Console << " " << it.first << " -> " << it.second << endl; - } - } - else if (commands.find(name) != commands.end()) - { - Console << "Reserved keyword (" << name << ")" << endl; - cmd.clear(); - } - else - { - if (cmd.length()) - { - vars[name] = cmd; - cmd.clear(); - } - else if (vars.find(name) != vars.end()) - vars.erase(vars.find(name)); - } - } - else if (compare(s, "ls") or compare(s, "view")) - { - Console << "--< " << clients.size() << " client/s. >--" << endl; - for(auto it: clients) - { - it.second->dump(" "); - } + } + else if (id.length() or clients.find(id)!=clients.end()) + { + s=getword(cmd); // broker name + if (s=="" or brokers.find(s) != brokers.end()) + { + MqttBroker* broker = nullptr; + if (s.length()) broker = brokers[s]; + MqttClient* client = new MqttClient(broker); + client->id(id); + clients[id]=client; + client->setCallback(onPublish); + client->subscribe(topic); + Console << "new client (" << id.c_str() << ", " << s.c_str() << ')' << endl; + } + else if (s.length()) + { + Console << " not found." << endl; + cmd.clear(); + } + } + else + { + Console << "Missing or existing client name" << endl; + cmd.clear(); + } + } + else if (compare(s, "set")) + { + std::string name(getword(cmd)); + if (name.length()==0) + { + for(auto it: vars) + { + Console << " " << it.first << " -> " << it.second << endl; + } + } + else if (commands.find(name) != commands.end()) + { + Console << "Reserved keyword (" << name << ")" << endl; + cmd.clear(); + } + else + { + if (cmd.length()) + { + vars[name] = cmd; + cmd.clear(); + } + else if (vars.find(name) != vars.end()) + vars.erase(vars.find(name)); + } + } + else if (compare(s, "ls") or compare(s, "view")) + { + Console << "--< " << clients.size() << " client/s. >--" << endl; + for(auto it: clients) + { + it.second->dump(" "); + } - Console << "--< " << brokers.size() << " brokers/s. >--" << endl; - for(auto it: brokers) - { - Console << " +-- '" << it.first.c_str() << "' " << it.second->clientsCount() << " client/s."<< endl; - it.second->dump(" "); - } - } - else if (compare(s, "reset")) - ESP.restart(); - else if (compare(s, "ip")) - Console << "IP: " << WiFi.localIP() << endl; - else if (compare(s,"help")) - { - Console << "syntax:" << endl; - Console << " MqttBroker:" << endl; - Console << " broker {broker_name} {port} : create a new broker" << endl; + Console << "--< " << brokers.size() << " brokers/s. >--" << endl; + for(auto it: brokers) + { + Console << " +-- '" << it.first.c_str() << "' " << it.second->clientsCount() << " client/s."<< endl; + it.second->dump(" "); + } + } + else if (compare(s, "reset")) + ESP.restart(); + else if (compare(s, "ip")) + Console << "IP: " << WiFi.localIP() << endl; + else if (compare(s,"help")) + { + Console << "syntax:" << endl; + Console << " MqttBroker:" << endl; + Console << " broker {broker_name} {port} : create a new broker" << endl; Console << " broker_name.delete : delete a broker (buggy)" << endl; Console << " broker_name.view : dump a broker" << endl; - Console << endl; - Console << " MqttClient:" << endl; - Console << " client {name} {parent broker} : create a client then" << endl; - Console << " name.connect [ip] [port] [alive]" << endl; - Console << " name.[un]subscribe [topic]" << endl; - Console << " name.publish [topic][payload]" << endl; - Console << " name.view" << endl; - Console << " name.delete" << endl; - Console << endl; + Console << endl; + Console << " MqttClient:" << endl; + Console << " client {name} {parent broker} : create a client then" << endl; + Console << " name.connect [ip] [port] [alive]" << endl; + Console << " name.[un]subscribe [topic]" << endl; + Console << " name.publish [topic][payload]" << endl; + Console << " name.view" << endl; + Console << " name.delete" << endl; + Console << endl; - Automatic::help(); - Console << endl; - Console << " help" << endl; - Console << " blink [Dx on_ms off_ms] : make pin blink" << endl; - Console << " ls / ip / reset" << endl; - Console << " set [name][value]" << endl; - Console << " ! repeat last command" << endl; - Console << endl; - Console << " echo [on|off] or strings" << endl; - Console << " every ms [command]; every list; every remove [nr|all]; every (on|off) [#]" << endl; - Console << " on {output}; off {output}" << endl; - Console << " $id : name of the client." << endl; - Console << " rnd[(min[,max])] random number." << endl; - Console << " default topic is '" << topic.c_str() << "'" << endl; - Console << endl; - } - else - { - while(s[0]==' ') s.erase(0,1); - if (s.length()) - Console << "Unknown command (" << s.c_str() << ")" << endl; - } + Automatic::help(); + Console << endl; + Console << " help" << endl; + Console << " blink [Dx on_ms off_ms] : make pin blink" << endl; + Console << " ls / ip / reset" << endl; + Console << " set [name][value]" << endl; + Console << " ! repeat last command" << endl; + Console << endl; + Console << " echo [on|off] or strings" << endl; + Console << " every ms [command]; every list; every remove [nr|all]; every (on|off) [#]" << endl; + Console << " on {output}; off {output}" << endl; + Console << " $id : name of the client." << endl; + Console << " rnd[(min[,max])] random number." << endl; + Console << " default topic is '" << topic.c_str() << "'" << endl; + Console << endl; + } + else + { + while(s[0]==' ') s.erase(0,1); + if (s.length()) + Console << "Unknown command (" << s.c_str() << ")" << endl; + } - if (retval != MqttOk) - { - Console << "# MQTT ERROR " << retval << endl; - } - } + if (retval != MqttOk) + { + Console << "# MQTT ERROR " << retval << endl; + } + } } void loop() { - auto ms=millis(); - int8_t out=0; - int16_t blink_bits = blink; - uint8_t e=0; + auto ms=millis(); + int8_t out=0; + int16_t blink_bits = blink; + uint8_t e=0; - for(auto& every: everies) - { - if (not every.active) continue; - if (every.ms && every.cmd.length() && ms > every.next) - { - std::string cmd(every.cmd); - eval(cmd); - every.next += every.ms; - if (ms > every.next and ms > every.underrun) - { - Console << "Underrun every #" << e << ", " << (ms - every.next) << "ms late" << endl; - every.underrun = ms+5000; - } - } - e++; - } + for(auto& every: everies) + { + if (not every.active) continue; + if (every.ms && every.cmd.length() && ms > every.next) + { + std::string cmd(every.cmd); + eval(cmd); + every.next += every.ms; + if (ms > every.next and ms > every.underrun) + { + Console << "Underrun every #" << e << ", " << (ms - every.next) << "ms late" << endl; + every.underrun = ms+5000; + } + } + e++; + } - while(blink_bits) - { - if (blink_ms_on[out] and ms > blink_next[out]) - { - if (blink_state[out]) - { - blink_next[out] += blink_ms_on[out]; - digitalWrite(out, LOW); - } - else - { - blink_next[out] += blink_ms_off[out]; - digitalWrite(abs(out), HIGH); - } - blink_state[out] = not blink_state[out]; - } - blink_bits >>=1; - out++; - } + while(blink_bits) + { + if (blink_ms_on[out] and ms > blink_next[out]) + { + if (blink_state[out]) + { + blink_next[out] += blink_ms_on[out]; + digitalWrite(out, LOW); + } + else + { + blink_next[out] += blink_ms_off[out]; + digitalWrite(abs(out), HIGH); + } + blink_state[out] = not blink_state[out]; + } + blink_bits >>=1; + out++; + } - static long count; - #if defined(ESP9266) + static long count; +#if defined(ESP9266) MDNS.update(); - #endif +#endif - for(auto it: brokers) - it.second->loop(); + for(auto it: brokers) + it.second->loop(); - for(auto it: clients) - it.second->loop(); + for(auto it: clients) + it.second->loop(); - Automatic::loop(); - Console.loop(); + Automatic::loop(); + Console.loop(); } diff --git a/src/StringIndexer.h b/src/StringIndexer.h index 2be35a9..bdb2da4 100644 --- a/src/StringIndexer.h +++ b/src/StringIndexer.h @@ -1,3 +1,4 @@ +// vim: ts=2 sw=2 expandtab #pragma once #include #include diff --git a/src/TinyMqtt.h b/src/TinyMqtt.h index 5383dd0..8b32037 100644 --- a/src/TinyMqtt.h +++ b/src/TinyMqtt.h @@ -230,7 +230,7 @@ class MqttClient uint32_t ms=millis(); Console << indent << "+-- " << '\'' << clientId.c_str() << "' " << (connected() ? " ON " : " OFF"); Console << ", alive=" << alive << '/' << ms << ", ka=" << keep_alive << ' '; - if (client) + if (client) { if (client->connected()) Console << TinyConsole::green << "connected"; diff --git a/src/my_credentials.h b/src/my_credentials.h deleted file mode 100644 index e794643..0000000 --- a/src/my_credentials.h +++ /dev/null @@ -1,2 +0,0 @@ -const char *ssid = "YOUR-SSID-HERE"; -const char *password = "YOUR-PASSWORD-HERE"; diff --git a/tests/length-tests.todo/length-tests.ino b/tests/length-tests.todo/length-tests.ino index 53b63b9..5e58fe1 100644 --- a/tests/length-tests.todo/length-tests.ino +++ b/tests/length-tests.todo/length-tests.ino @@ -1,53 +1,54 @@ +// vim: ts=2 sw=2 expandtab #include #include #include /** - * TinyMqtt local unit tests. - * - * Clients are connected to pseudo remote broker - * The remote should be 127.0.0.1:1883 <--- But this does not work due to Esp network limitations - * We are using 127.0.0.1 because this is simpler to test with a single ESP - * Also, this will allow to mock and thus run Action on github - **/ + * TinyMqtt local unit tests. + * + * Clients are connected to pseudo remote broker + * The remote should be 127.0.0.1:1883 <--- But this does not work due to Esp network limitations + * We are using 127.0.0.1 because this is simpler to test with a single ESP + * Also, this will allow to mock and thus run Action on github + **/ using namespace std; MqttBroker broker(1883); -std::map> published; // map[client_id] => map[topic] = count +std::map> published; // map[client_id] => map[topic] = count const char* lastPayload; size_t lastLength; void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) { - if (srce) - published[srce->id()][topic]++; + if (srce) + published[srce->id()][topic]++; lastPayload = payload; - lastLength = length; + lastLength = length; } test(length_decode_greater_than_127) { // TODO WRITE THIS TEST // The test should verify than a mqtt message with more than 127 bytes is correctly decoded - assertEqual(1,2); + assertEqual(1,2); } //---------------------------------------------------------------------------- // setup() and loop() void setup() { - delay(1000); - Serial.begin(115200); - while(!Serial); + delay(1000); + Serial.begin(115200); + while(!Serial); - Serial.println("=============[ NO WIFI CONNECTION TinyMqtt TESTS ]========================"); + Serial.println("=============[ NO WIFI CONNECTION TinyMqtt TESTS ]========================"); } void loop() { - aunit::TestRunner::run(); + aunit::TestRunner::run(); - if (Serial.available()) ESP.reset(); + if (Serial.available()) ESP.reset(); } diff --git a/tests/network-tests/network-tests.ino b/tests/network-tests/network-tests.ino index 8f9b0c4..72c774f 100644 --- a/tests/network-tests/network-tests.ino +++ b/tests/network-tests/network-tests.ino @@ -1,3 +1,4 @@ +// vim: ts=2 sw=2 expandtab #include #include #include @@ -10,10 +11,10 @@ /** * TinyMqtt network unit tests. - * - * No wifi connection unit tests. + * + * No wifi connection unit tests. * Checks with a local broker. Clients must connect to the local broker - **/ + **/ // if ascii_pos = 0, no ascii dump, else ascii dump starts after column ascii_pos std::string bufferToHexa(const uint8_t* buffer, size_t length, char sep = 0, size_t ascii_pos = 0) @@ -77,7 +78,7 @@ String toString(const IPAddress& ip) MqttBroker broker(1883); -std::map> published; // map[client_id] => map[topic] = count +std::map> published; // map[client_id] => map[topic] = count char* lastPayload = nullptr; size_t lastLength; @@ -96,12 +97,12 @@ void start_servers(int n, bool early_accept = true) void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) { - if (srce) - published[srce->id()][topic]++; - - if (lastPayload) free(lastPayload); + if (srce) + published[srce->id()][topic]++; + + if (lastPayload) free(lastPayload); lastPayload = strdup(payload); - lastLength = length; + lastLength = length; } test(network_single_broker_begin) @@ -263,12 +264,12 @@ test(network_one_client_one_broker_hudge_publish_and_subscribe_through_network) test(network_client_should_unregister_when_destroyed) { - assertEqual(broker.clientsCount(), (size_t)0); - { - MqttClient client(&broker); - assertEqual(broker.clientsCount(), (size_t)1); - } - assertEqual(broker.clientsCount(), (size_t)0); + assertEqual(broker.clientsCount(), (size_t)0); + { + MqttClient client(&broker); + assertEqual(broker.clientsCount(), (size_t)1); + } + assertEqual(broker.clientsCount(), (size_t)0); } @@ -277,113 +278,113 @@ test(network_client_should_unregister_when_destroyed) test(network_connect) { - assertEqual(broker.clientsCount(), (size_t)0); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient client(&broker); - assertTrue(client.connected()); - assertEqual(broker.clientsCount(), (size_t)1); + MqttClient client(&broker); + assertTrue(client.connected()); + assertEqual(broker.clientsCount(), (size_t)1); } test(network_publish_should_be_dispatched) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker); - subscriber.subscribe("a/b"); - subscriber.subscribe("a/c"); - subscriber.setCallback(onPublish); + MqttClient subscriber(&broker); + subscriber.subscribe("a/b"); + subscriber.subscribe("a/c"); + subscriber.setCallback(onPublish); - MqttClient publisher(&broker); - publisher.publish("a/b"); - publisher.publish("a/c"); - publisher.publish("a/c"); + MqttClient publisher(&broker); + publisher.publish("a/b"); + publisher.publish("a/c"); + publisher.publish("a/c"); - assertEqual(published.size(), (size_t)1); // 1 client has received something - assertEqual(published[""]["a/b"], 1); - assertEqual(published[""]["a/c"], 2); + assertEqual(published.size(), (size_t)1); // 1 client has received something + assertEqual(published[""]["a/b"], 1); + assertEqual(published[""]["a/c"], 2); } test(network_publish_should_be_dispatched_to_clients) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber_a(&broker, "A"); - subscriber_a.setCallback(onPublish); - subscriber_a.subscribe("a/b"); - subscriber_a.subscribe("a/c"); + MqttClient subscriber_a(&broker, "A"); + subscriber_a.setCallback(onPublish); + subscriber_a.subscribe("a/b"); + subscriber_a.subscribe("a/c"); - MqttClient subscriber_b(&broker, "B"); - subscriber_b.setCallback(onPublish); - subscriber_b.subscribe("a/b"); + MqttClient subscriber_b(&broker, "B"); + subscriber_b.setCallback(onPublish); + subscriber_b.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b"); // A and B should receive this - publisher.publish("a/c"); // A should receive this + MqttClient publisher(&broker); + publisher.publish("a/b"); // A and B should receive this + publisher.publish("a/c"); // A should receive this - assertEqual(published.size(), (size_t)2); // 2 clients have received something - assertEqual(published["A"]["a/b"], 1); - assertEqual(published["A"]["a/c"], 1); - assertEqual(published["B"]["a/b"], 1); - assertEqual(published["B"]["a/c"], 0); + assertEqual(published.size(), (size_t)2); // 2 clients have received something + assertEqual(published["A"]["a/b"], 1); + assertEqual(published["A"]["a/c"], 1); + assertEqual(published["B"]["a/b"], 1); + assertEqual(published["B"]["a/c"], 0); } test(network_unsubscribe) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b"); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b"); // This publish is received - subscriber.unsubscribe("a/b"); + subscriber.unsubscribe("a/b"); - publisher.publish("a/b"); // Those one, no (unsubscribed) - publisher.publish("a/b"); + publisher.publish("a/b"); // Those one, no (unsubscribed) + publisher.publish("a/b"); - assertEqual(published[""]["a/b"], 1); // Only one publish has been received + assertEqual(published[""]["a/b"], 1); // Only one publish has been received } test(network_nocallback_when_destroyed) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient publisher(&broker); + MqttClient publisher(&broker); - { - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); - publisher.publish("a/b"); - } + { + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); + publisher.publish("a/b"); + } - publisher.publish("a/b"); + publisher.publish("a/b"); - assertEqual(published.size(), (size_t)1); // Only one publish has been received + assertEqual(published.size(), (size_t)1); // Only one publish has been received } test(network_small_payload) { - published.clear(); + published.clear(); - const char* payload="abcd"; + const char* payload="abcd"; - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b", payload, strlen(payload)); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b", payload, strlen(payload)); // This publish is received // coming from MqttClient::publish(...) assertEqual(payload, lastPayload); - assertEqual(lastLength, (size_t)4); + assertEqual(lastLength, (size_t)4); } test(network_hudge_payload) @@ -394,13 +395,13 @@ test(network_hudge_payload) subscriber.setCallback(onPublish); subscriber.subscribe("a/b"); // Note -> this does not send any byte .... (nowhere to send) - MqttClient publisher(&broker); - publisher.publish("a/b", payload); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b", payload); // This publish is received // onPublish should have filled lastPayload and lastLength assertEqual(payload, lastPayload); - assertEqual(lastLength, strlen(payload)); - assertEqual(strcmp(payload, lastPayload), 0); + assertEqual(lastLength, strlen(payload)); + assertEqual(strcmp(payload, lastPayload), 0); } test(connack) @@ -447,19 +448,19 @@ test(connack) //---------------------------------------------------------------------------- // setup() and loop() void setup() { - /* delay(1000); - Serial.begin(115200); - while(!Serial); - */ + /* delay(1000); + Serial.begin(115200); + while(!Serial); + */ - Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================"); + Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================"); - WiFi.mode(WIFI_STA); - WiFi.begin("network", "password"); + WiFi.mode(WIFI_STA); + WiFi.begin("network", "password"); } void loop() { - aunit::TestRunner::run(); + aunit::TestRunner::run(); - if (Serial.available()) ESP.reset(); + if (Serial.available()) ESP.reset(); } diff --git a/tests/nowifi-tests/nowifi-tests.ino b/tests/nowifi-tests/nowifi-tests.ino index 179c4b6..1cdab29 100644 --- a/tests/nowifi-tests/nowifi-tests.ino +++ b/tests/nowifi-tests/nowifi-tests.ino @@ -1,3 +1,4 @@ +// vim: ts=2 sw=2 expandtab #include #include #include @@ -5,247 +6,247 @@ /** * TinyMqtt nowifi unit tests. - * - * No wifi connection unit tests. + * + * No wifi connection unit tests. * Checks with a local broker. Clients must connect to the local broker - **/ + **/ using namespace std; MqttBroker broker(1883); -std::map> published; // map[client_id] => map[topic] = count +std::map> published; // map[client_id] => map[topic] = count char* lastPayload = nullptr; size_t lastLength; void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) { - if (srce) - published[srce->id()][topic]++; - - if (lastPayload) free(lastPayload); + if (srce) + published[srce->id()][topic]++; + + if (lastPayload) free(lastPayload); lastPayload = strdup(payload); - lastLength = length; + lastLength = length; } test(nowifi_client_should_unregister_when_destroyed) { - assertEqual(broker.clientsCount(), (size_t)0); - { - MqttClient client(&broker); - assertEqual(broker.clientsCount(), (size_t)1); - } - assertEqual(broker.clientsCount(), (size_t)0); + assertEqual(broker.clientsCount(), (size_t)0); + { + MqttClient client(&broker); + assertEqual(broker.clientsCount(), (size_t)1); + } + assertEqual(broker.clientsCount(), (size_t)0); } test(nowifi_connect) { - assertEqual(broker.clientsCount(), (size_t)0); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient client(&broker); - assertTrue(client.connected()); - assertEqual(broker.clientsCount(), (size_t)1); + MqttClient client(&broker); + assertTrue(client.connected()); + assertEqual(broker.clientsCount(), (size_t)1); } test(nowifi_publish_should_be_dispatched) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker); - subscriber.subscribe("a/b"); - subscriber.subscribe("a/c"); - subscriber.setCallback(onPublish); + MqttClient subscriber(&broker); + subscriber.subscribe("a/b"); + subscriber.subscribe("a/c"); + subscriber.setCallback(onPublish); - MqttClient publisher(&broker); - publisher.publish("a/b"); - publisher.publish("a/c"); - publisher.publish("a/c"); + MqttClient publisher(&broker); + publisher.publish("a/b"); + publisher.publish("a/c"); + publisher.publish("a/c"); - assertEqual(published.size(), (size_t)1); // 1 client has received something - assertEqual(published[""]["a/b"], 1); - assertEqual(published[""]["a/c"], 2); + assertEqual(published.size(), (size_t)1); // 1 client has received something + assertEqual(published[""]["a/b"], 1); + assertEqual(published[""]["a/c"], 2); } test(nowifi_publish_should_be_dispatched_to_clients) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber_a(&broker, "A"); - subscriber_a.setCallback(onPublish); - subscriber_a.subscribe("a/b"); - subscriber_a.subscribe("a/c"); + MqttClient subscriber_a(&broker, "A"); + subscriber_a.setCallback(onPublish); + subscriber_a.subscribe("a/b"); + subscriber_a.subscribe("a/c"); - MqttClient subscriber_b(&broker, "B"); - subscriber_b.setCallback(onPublish); - subscriber_b.subscribe("a/b"); + MqttClient subscriber_b(&broker, "B"); + subscriber_b.setCallback(onPublish); + subscriber_b.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b"); // A and B should receive this - publisher.publish("a/c"); // A should receive this + MqttClient publisher(&broker); + publisher.publish("a/b"); // A and B should receive this + publisher.publish("a/c"); // A should receive this - assertEqual(published.size(), (size_t)2); // 2 clients have received something - assertEqual(published["A"]["a/b"], 1); - assertEqual(published["A"]["a/c"], 1); - assertEqual(published["B"]["a/b"], 1); - assertEqual(published["B"]["a/c"], 0); + assertEqual(published.size(), (size_t)2); // 2 clients have received something + assertEqual(published["A"]["a/b"], 1); + assertEqual(published["A"]["a/c"], 1); + assertEqual(published["B"]["a/b"], 1); + assertEqual(published["B"]["a/c"], 0); } test(nowifi_subscribe_with_star_wildcard) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker, "A"); - subscriber.setCallback(onPublish); - subscriber.subscribe("house/*/temp"); + MqttClient subscriber(&broker, "A"); + subscriber.setCallback(onPublish); + subscriber.subscribe("house/*/temp"); - MqttClient publisher(&broker); - publisher.publish("house/bedroom/temp"); - publisher.publish("house/kitchen/temp"); - publisher.publish("house/living_room/tv/temp"); - publisher.publish("building/location1/bedroom/temp"); + MqttClient publisher(&broker); + publisher.publish("house/bedroom/temp"); + publisher.publish("house/kitchen/temp"); + publisher.publish("house/living_room/tv/temp"); + publisher.publish("building/location1/bedroom/temp"); - assertEqual(published["A"]["house/bedroom/temp"], 1); - assertEqual(published["A"]["house/kitchen/temp"], 1); - assertEqual(published["A"]["house/living_room/tv/temp"], 1); - assertEqual(published["A"]["building/location1/bedroom/temp"], 0); + assertEqual(published["A"]["house/bedroom/temp"], 1); + assertEqual(published["A"]["house/kitchen/temp"], 1); + assertEqual(published["A"]["house/living_room/tv/temp"], 1); + assertEqual(published["A"]["building/location1/bedroom/temp"], 0); } test(nowifi_subscribe_with_plus_wildcard) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker, "A"); - subscriber.setCallback(onPublish); - subscriber.subscribe("house/+/temp"); + MqttClient subscriber(&broker, "A"); + subscriber.setCallback(onPublish); + subscriber.subscribe("house/+/temp"); - MqttClient publisher(&broker); - publisher.publish("house/bedroom/temp"); - publisher.publish("house/kitchen/temp"); - publisher.publish("house/living_room/tv/temp"); - publisher.publish("building/location1/bedroom/temp"); + MqttClient publisher(&broker); + publisher.publish("house/bedroom/temp"); + publisher.publish("house/kitchen/temp"); + publisher.publish("house/living_room/tv/temp"); + publisher.publish("building/location1/bedroom/temp"); - assertEqual(published["A"]["house/bedroom/temp"], 1); - assertEqual(published["A"]["house/kitchen/temp"], 1); - assertEqual(published["A"]["house/living_room/tv/temp"], 0); - assertEqual(published["A"]["building/location1/bedroom/temp"], 0); + assertEqual(published["A"]["house/bedroom/temp"], 1); + assertEqual(published["A"]["house/kitchen/temp"], 1); + assertEqual(published["A"]["house/living_room/tv/temp"], 0); + assertEqual(published["A"]["building/location1/bedroom/temp"], 0); } test(nowifi_should_not_receive_sys_msg) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker, "A"); - subscriber.setCallback(onPublish); - subscriber.subscribe("+/data"); + MqttClient subscriber(&broker, "A"); + subscriber.setCallback(onPublish); + subscriber.subscribe("+/data"); - MqttClient publisher(&broker); - publisher.publish("$SYS/data"); + MqttClient publisher(&broker); + publisher.publish("$SYS/data"); - assertEqual(published["A"]["$SYS/data"], 0); + assertEqual(published["A"]["$SYS/data"], 0); } test(nowifi_subscribe_with_mixed_wildcards) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker, "A"); - subscriber.setCallback(onPublish); - subscriber.subscribe("+/data/#"); + MqttClient subscriber(&broker, "A"); + subscriber.setCallback(onPublish); + subscriber.subscribe("+/data/#"); - MqttClient publisher(&broker); - publisher.publish("node1/data/update"); - publisher.publish("node2/data/delta"); - publisher.publish("node3/data"); + MqttClient publisher(&broker); + publisher.publish("node1/data/update"); + publisher.publish("node2/data/delta"); + publisher.publish("node3/data"); - assertEqual(published["A"]["node1/data/update"], 1); - assertEqual(published["A"]["node2/data/delta"], 1); - assertEqual(published["A"]["node3/data"], 1); + assertEqual(published["A"]["node1/data/update"], 1); + assertEqual(published["A"]["node2/data/delta"], 1); + assertEqual(published["A"]["node3/data"], 1); } test(nowifi_unsubscribe_with_wildcards) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker, "A"); - subscriber.setCallback(onPublish); - subscriber.subscribe("one/two/+"); - subscriber.subscribe("one/two/three"); + MqttClient subscriber(&broker, "A"); + subscriber.setCallback(onPublish); + subscriber.subscribe("one/two/+"); + subscriber.subscribe("one/two/three"); - MqttClient publisher(&broker); - publisher.publish("one/two/three"); - publisher.publish("one/two/four"); + MqttClient publisher(&broker); + publisher.publish("one/two/three"); + publisher.publish("one/two/four"); - subscriber.unsubscribe("one/two/+"); - publisher.publish("one/two/five"); + subscriber.unsubscribe("one/two/+"); + publisher.publish("one/two/five"); - assertEqual(published["A"]["one/two/three"], 1); - assertEqual(published["A"]["one/two/four"], 1); - assertEqual(published["A"]["one/two/five"], 0); + assertEqual(published["A"]["one/two/three"], 1); + assertEqual(published["A"]["one/two/four"], 1); + assertEqual(published["A"]["one/two/five"], 0); } test(nowifi_unsubscribe) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b"); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b"); // This publish is received - subscriber.unsubscribe("a/b"); + subscriber.unsubscribe("a/b"); - publisher.publish("a/b"); // Those one, no (unsubscribed) - publisher.publish("a/b"); + publisher.publish("a/b"); // Those one, no (unsubscribed) + publisher.publish("a/b"); - assertEqual(published[""]["a/b"], 1); // Only one publish has been received + assertEqual(published[""]["a/b"], 1); // Only one publish has been received } test(nowifi_nocallback_when_destroyed) { - published.clear(); - assertEqual(broker.clientsCount(), (size_t)0); + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); - MqttClient publisher(&broker); + MqttClient publisher(&broker); - { - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); - publisher.publish("a/b"); - } + { + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); + publisher.publish("a/b"); + } - publisher.publish("a/b"); + publisher.publish("a/b"); - assertEqual(published.size(), (size_t)1); // Only one publish has been received + assertEqual(published.size(), (size_t)1); // Only one publish has been received } test(nowifi_small_payload) { - published.clear(); + published.clear(); - const char* payload="abcd"; + const char* payload="abcd"; - MqttClient subscriber(&broker); - subscriber.setCallback(onPublish); - subscriber.subscribe("a/b"); + MqttClient subscriber(&broker); + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b", payload, strlen(payload)); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b", payload, strlen(payload)); // This publish is received // coming from MqttClient::publish(...) assertEqual(payload, lastPayload); - assertEqual(lastLength, (size_t)4); + assertEqual(lastLength, (size_t)4); } test(nowifi_hudge_payload) @@ -256,26 +257,26 @@ test(nowifi_hudge_payload) subscriber.setCallback(onPublish); subscriber.subscribe("a/b"); - MqttClient publisher(&broker); - publisher.publish("a/b", payload); // This publish is received + MqttClient publisher(&broker); + publisher.publish("a/b", payload); // This publish is received // onPublish should have filled lastPayload and lastLength assertEqual(payload, lastPayload); - assertEqual(lastLength, strlen(payload)); + assertEqual(lastLength, strlen(payload)); } //---------------------------------------------------------------------------- // setup() and loop() void setup() { - delay(1000); - Serial.begin(115200); - while(!Serial); + delay(1000); + Serial.begin(115200); + while(!Serial); - Serial.println("=============[ NO WIFI CONNECTION TinyMqtt TESTS ]========================"); + Serial.println("=============[ NO WIFI CONNECTION TinyMqtt TESTS ]========================"); } void loop() { - aunit::TestRunner::run(); + aunit::TestRunner::run(); - if (Serial.available()) ESP.reset(); + if (Serial.available()) ESP.reset(); } diff --git a/tests/string-indexer-tests/string-indexer-tests.ino b/tests/string-indexer-tests/string-indexer-tests.ino index 32506ef..5cb02f6 100644 --- a/tests/string-indexer-tests/string-indexer-tests.ino +++ b/tests/string-indexer-tests/string-indexer-tests.ino @@ -1,12 +1,13 @@ +// vim: ts=2 sw=2 expandtab #include #include #include #include /** - * TinyMqtt / StringIndexer unit tests. - * - **/ + * TinyMqtt / StringIndexer unit tests. + * + **/ using namespace std; @@ -18,48 +19,48 @@ test(indexer_empty) test(indexer_strings_deleted_should_empty_indexer) { assertTrue(StringIndexer::count()==0); - { - IndexedString one("one"); + { + IndexedString one("one"); assertEqual(StringIndexer::count(), 1); - IndexedString two("two"); + IndexedString two("two"); assertEqual(StringIndexer::count(), 2); - IndexedString three("three"); + IndexedString three("three"); assertEqual(StringIndexer::count(), 3); - IndexedString four("four"); + IndexedString four("four"); assertEqual(StringIndexer::count(), 4); - } + } assertEqual(StringIndexer::count(), 0); } test(indexer_same_strings_count_as_one) { - IndexedString one ("one"); - IndexedString two ("one"); - IndexedString three("one"); - IndexedString fourt("one"); + IndexedString one ("one"); + IndexedString two ("one"); + IndexedString three("one"); + IndexedString fourt("one"); - assertEqual(StringIndexer::count(), 1); + assertEqual(StringIndexer::count(), 1); } test(indexer_size_of_indexed_string) { - assertEqual(sizeof(IndexedString), (size_t)1); + assertEqual(sizeof(IndexedString), (size_t)1); } test(indexer_different_strings_are_different) { - IndexedString one("one"); - IndexedString two("two"); + IndexedString one("one"); + IndexedString two("two"); - assertFalse(one == two); + assertFalse(one == two); } test(indexer_same_strings_should_equal) { - IndexedString one("one"); - IndexedString two("one"); + IndexedString one("one"); + IndexedString two("one"); - assertTrue(one == two); + assertTrue(one == two); } test(indexer_compare_strings_with_same_beginning) @@ -72,47 +73,47 @@ test(indexer_compare_strings_with_same_beginning) test(indexer_indexed_operator_eq) { - IndexedString one("one"); - { - IndexedString same = one; - assertTrue(one == same); - assertEqual(StringIndexer::count(), 1); + IndexedString one("one"); + { + IndexedString same = one; + assertTrue(one == same); + assertEqual(StringIndexer::count(), 1); } - assertEqual(StringIndexer::count(), 1); + assertEqual(StringIndexer::count(), 1); } test(indexer_get_string) { - std::string sone("one"); - IndexedString one(sone); + std::string sone("one"); + IndexedString one(sone); assertTrue(sone==one.str()); } test(indexer_get_index) { - IndexedString one1("one"); - IndexedString one2("one"); - IndexedString two1("two"); - IndexedString two2("two"); + IndexedString one1("one"); + IndexedString one2("one"); + IndexedString two1("two"); + IndexedString two2("two"); assertTrue(one1.getIndex() == one2.getIndex()); - assertTrue(two1.getIndex() == two2.getIndex()); - assertTrue(one1.getIndex() != two1.getIndex()); + assertTrue(two1.getIndex() == two2.getIndex()); + assertTrue(one1.getIndex() != two1.getIndex()); } //---------------------------------------------------------------------------- // setup() and loop() void setup() { - delay(1000); - Serial.begin(115200); - while(!Serial); + delay(1000); + Serial.begin(115200); + while(!Serial); - Serial.println("=============[ TinyMqtt StringIndexer TESTS ]========================"); + Serial.println("=============[ TinyMqtt StringIndexer TESTS ]========================"); } void loop() { - aunit::TestRunner::run(); + aunit::TestRunner::run(); - // if (Serial.available()) ESP.reset(); + // if (Serial.available()) ESP.reset(); } diff --git a/tests/topic-tests/topic-tests.ino b/tests/topic-tests/topic-tests.ino index ecbaf68..8b3179b 100644 --- a/tests/topic-tests/topic-tests.ino +++ b/tests/topic-tests/topic-tests.ino @@ -1,3 +1,4 @@ +// vim: ts=2 sw=2 expandtab #include #include #include @@ -7,9 +8,9 @@ #define endl "\n" /** - * TinyMqtt / StringIndexer unit tests. - * - **/ + * TinyMqtt / StringIndexer unit tests. + * + **/ using namespace std; @@ -71,15 +72,15 @@ test(topic_matches) //---------------------------------------------------------------------------- // setup() and loop() void setup() { - delay(1000); - Serial.begin(115200); - while(!Serial); + delay(1000); + Serial.begin(115200); + while(!Serial); - Serial.println("=============[ TinyMqtt StringIndexer TESTS ]========================"); + Serial.println("=============[ TinyMqtt StringIndexer TESTS ]========================"); } void loop() { - aunit::TestRunner::run(); + aunit::TestRunner::run(); - // if (Serial.available()) ESP.reset(); + // if (Serial.available()) ESP.reset(); }