diff --git a/examples/tinymqtt-test/tinymqtt-test.ino b/examples/tinymqtt-test/tinymqtt-test.ino index bef55ed..bbfa7b9 100644 --- a/examples/tinymqtt-test/tinymqtt-test.ino +++ b/examples/tinymqtt-test/tinymqtt-test.ino @@ -3,7 +3,7 @@ #include /** - * Local broker that accept connections + * Console allowing to make any kind of test. * * pros - Reduces internal latency (when publish is received by the same ESP) * - Reduces wifi traffic @@ -25,11 +25,13 @@ std::string topic="sensor/temperature"; -MqttBroker broker(1883); - void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) { Serial << "--> " << srce->id().c_str() << ": ======> received " << topic.c_str() << endl; } +std::map clients; +std::map brokers; + + void setup() { Serial.begin(115200); @@ -46,7 +48,21 @@ void setup() Serial << "Connected to " << ssid << "IP address: " << WiFi.localIP() << endl; - broker.begin(); + MqttBroker* broker = new MqttBroker(1883); + broker->begin(); + brokers["broker"] = broker; +} + +int getint(std::string& str, const int if_empty=0, char sep=' ') +{ + std::string sword; + while(str.length() && str[0]!=sep) + { + sword += str[0]; str.erase(0,1); + } + while(str[0]==sep) str.erase(0,1); + if (if_empty and sword.length()==0) sword=if_empty; + return atoi(sword.c_str()); } std::string getword(std::string& str, const char* if_empty=nullptr, char sep=' ') @@ -128,7 +144,7 @@ class automatic autop->bon=false; else if (s=="interval") { - int32_t i=atol(getword(cmd).c_str()); + int32_t i=getint(cmd); if (i) autop->interval(atol(s.c_str())); else @@ -181,35 +197,12 @@ bool compare(std::string s, const char* cmd) return strncmp(cmd, s.c_str(), s.length())==0; } -std::map clients; - using ClientFunction = void(*)(std::string& cmd, MqttClient* publish); -void clientCommand(std::string& cmd, ClientFunction func, bool canBeNull=false) -{ - std::string s=getword(cmd); - bool found = clients.find(s) != clients.end(); - - if (canBeNull && found==false) - { - cmd += ' ' + s; - } - - if (found or canBeNull) - { - MqttClient* publish = publish = clients[s]; - func(cmd, publish); - } - else - { - Serial << "client not found (" << s.c_str() << ")" << endl; - cmd=""; - } -} - void loop() { - broker.loop(); + for(auto it: brokers) + it.second->loop(); for(auto it: clients) it.second->loop(); @@ -223,7 +216,7 @@ void loop() if (c==10 or c==14) { - Serial << "------------------------------------------------------" << endl; + Serial << "----------------[ " << cmd.c_str() << " ]--------------" << endl; static std::string last_cmd; if (cmd=="!") cmd=last_cmd; @@ -232,93 +225,169 @@ void loop() while(cmd.length()) { std::string s; + MqttBroker* broker = nullptr; + MqttClient* client = nullptr; // client.function notation // ("a.fun " becomes "fun a ") if (cmd.find('.') != std::string::npos) { - std::string copy(cmd); - s=getword(copy, nullptr, '.'); + s=getword(cmd, nullptr, '.'); if (clients.find(s) != clients.end()) { - std::string s2 = getword(copy); - cmd=s2+' '+s+' '+copy; + client = clients[s]; + } + else if (brokers.find(s) != brokers.end()) + { + broker = brokers[s]; } else { - Serial << "Unknown client (" << s.c_str() << ")" << endl; + Serial << "Unknown class (" << s.c_str() << ")" << endl; cmd=""; } } s = getword(cmd); - if (compare(s,"connect")) + if (broker) { - clientCommand(cmd, [](std::string& cmd, MqttClient* publish) - { publish->connect(getword(cmd,"192.168.1.40").c_str(), 1883); - Serial << (publish->connected() ? "connected." : "not connected") << endl; - }); + if (compare(s,"connect")) + { + Serial << "NYI" << endl; + } + else if (compare(s, "view")) + { + broker->dump(); + } + } + else if (client) + { + if (compare(s,"connect")) + { + client->connect(getword(cmd,"192.168.1.40").c_str(), 1883); + Serial << (client->connected() ? "connected." : "not connected") << endl; + } + else if (compare(s,"publish")) + { + client->publish(getword(cmd, topic.c_str())); + } + else if (compare(s,"subscribe")) + { + client->subscribe(getword(cmd, topic.c_str())); + } + else if (compare(s, "view")) + { + client->dump(); + } } - else if (compare(s,"publish")) + if (compare(s, "delete")) { - clientCommand(cmd, [](std::string& cmd, MqttClient* publish) - { publish->publish(getword(cmd, topic.c_str())); }); - } - else if (compare(s,"subscribe")) - { - clientCommand(cmd, [](std::string& cmd, MqttClient* publish) - { publish->subscribe(getword(cmd, topic.c_str())); }); - } - else if (compare(s, "view")) - { - clientCommand(cmd, [](std::string& cmd, MqttClient* publish) - { publish->dump(); }); + 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 + Serial << "Unable to find (" << s.c_str() << ")" << endl; + } + if (client) + { + clients.erase(s); + for (auto it: clients) + { + if (it.second != client) continue; + Serial << "deleted" << endl; + clients.erase(it.first); + break; + } + cmd += " ls"; + } + else if (broker) + { + for(auto it: brokers) + { + Serial << (int32_t)it.second << '/' << (int32_t)broker << endl; + if (broker != it.second) continue; + Serial << "deleted" << endl; + brokers.erase(it.first); + break; + } + cmd += " ls"; + } + else + Serial << "Nothing to delete" << endl; } else if (compare(s, "auto")) { - clientCommand(cmd, [](std::string& cmd, MqttClient* publish) - { automatic::command(publish, cmd); - if (publish == nullptr) - cmd.clear(); - }, true); + automatic::command(client, cmd); + if (client == nullptr) + cmd.clear(); } - else if (compare(s, "new")) + else if (compare(s, "broker")) { std::string id=getword(cmd); - if (id.length()) + if (id.length() or brokers.find(id)!=brokers.end()) { - MqttClient* client = new MqttClient(&broker); + int port=getint(cmd, 0); + if (port) + { + MqttBroker* broker = new MqttBroker(port); + broker->begin(); + + brokers[id] = broker; + Serial << "new broker (" << id.c_str() << ")" << endl; + } + else + Serial << "Missing port" << endl; + } + else + Serial << "Missing or existing broker name (" << id.c_str() << ")" << endl; + cmd+=" ls"; + } + else if (compare(s, "client")) + { + std::string id=getword(cmd); + if (id.length() or clients.find(id)!=clients.end()) + { + MqttBroker* broker = nullptr; + + // TODO cmd line broker name + if (brokers.size()==1) broker = brokers.begin()->second; + Serial << "broker=" << (int32_t)broker << endl; + delay(500); + + MqttClient* client = new MqttClient(broker); client->id(id); clients[id]=client; client->setCallback(onPublish); client->subscribe(topic); + Serial << "new client (" << id.c_str() << ")" << endl; } else - Serial << "missing id" << endl; + Serial << "Missing or existing client name" << endl; cmd+=" ls"; } - else if (compare(s, "delete")) + else if (compare(s, "ls") or compare(s, "view")) { - s = getword(cmd); - auto it=clients.find(s); - if (it != clients.end()) - { - delete it->second; - clients.erase(it); - cmd+=" ls"; - } - else - Serial << "Unknown client (" << s.c_str() << ")" << endl; - } - else if (compare(s, "ls")) - { - Serial << "main : " << clients.size() << " client/s." << endl; + Serial << "--< " << clients.size() << " client/s. >--" << endl; for(auto it: clients) { Serial << " "; it.second->dump(); } - broker.dump(); + + Serial << "--< " << brokers.size() << " brokers/s. >--" << endl; + for(auto it: brokers) + { + Serial << " ==[ Broker: " << it.first.c_str() << " ]== "; + it.second->dump(); + } } else if (compare(s, "reset")) ESP.restart(); @@ -327,11 +396,17 @@ void loop() else if (compare(s,"help")) { Serial << "syntax:" << endl; - Serial << " new/delete $id" << endl; - Serial << " connect $id [ip]" << endl; - Serial << " subscribe $id [topic]" << endl; - Serial << " publish $id [topic]" << endl; - Serial << " view $id " << endl; + Serial << " MqttBroker:" << endl; + Serial << " broker {name} {port} : create a new broker" << endl; + Serial << endl; + Serial << " MqttClient:" << endl; + Serial << " client {name} : create a client then" << endl; + Serial << " name.connect [ip]" << endl; + Serial << " name.subscribe [topic]" << endl; + Serial << " name.publish [topic]" << endl; + Serial << " name.view" << endl; + Serial << " name.delete" << endl; + automatic::help(); Serial << endl; Serial << " help" << endl; @@ -341,8 +416,6 @@ void loop() Serial << " $id : name of the client." << endl; Serial << " default topic is '" << topic.c_str() << "'" << endl; Serial << endl; - Serial << " 'function client args' can be written 'client.function args'" << endl; - Serial << endl; } else {