diff --git a/Controller/main.cpp b/Controller/main.cpp index 9fc46841..8c074c7e 100644 --- a/Controller/main.cpp +++ b/Controller/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -146,32 +147,64 @@ void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & c } void CheckProtocols(JSON::Value & p){ - static std::map connports; - bool seenHTTP = false; - bool seenRTMP = false; + static std::map current_connectors; + std::map new_connectors; + std::map::iterator iter; + std::string tmp; + JSON::Value counter = (long long int)0; + + //collect object type for (JSON::ObjIter jit = p.ObjBegin(); jit != p.ObjEnd(); jit++){ - if (jit->first == "HTTP"){ - tmp = (std::string)jit->second["port"]; - seenHTTP = true; - if (connports["HTTP"] != tmp){Util::Procs::Stop("HTTP");} - connports["HTTP"] = tmp; - if (!Util::Procs::isActive("HTTP")){ - Util::Procs::Start("HTTP", std::string("MistConnHTTP -n -p ")+tmp); - } + tmp = "MistConn"; + tmp += (std::string)jit->second["connector"]; + tmp += " -n -p "; + tmp += (std::string)jit->second["port"]; + if (jit->second.isMember("interface")){ + tmp += " -i "; + tmp += (std::string)jit->second["interface"]; } - if (jit->first == "RTMP"){ - tmp = (std::string)jit->second["port"]; - seenRTMP = true; - if (connports["RTMP"] != tmp){Util::Procs::Stop("RTMP");} - connports["RTMP"] = tmp; - if (!Util::Procs::isActive("RTMP")){ - Util::Procs::Start("RTMP", std::string("MistConnRTMP -n -p ")+tmp); - } + if (jit->second.isMember("username")){ + tmp += " -u "; + tmp += (std::string)jit->second["username"]; + } + counter = (long long int)counter + 1; + new_connectors[std::string("Conn")+(std::string)counter] = tmp; + } + //collect array type + for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){ + tmp = "MistConn"; + tmp += (std::string)(*ait)["connector"]; + tmp += " -n -p "; + tmp += (std::string)(*ait)["port"]; + if ((*ait).isMember("interface")){ + tmp += " -i "; + tmp += (std::string)(*ait)["interface"]; + } + if ((*ait).isMember("username")){ + tmp += " -u "; + tmp += (std::string)(*ait)["username"]; + } + counter = (long long int)counter + 1; + new_connectors[std::string("Conn")+(std::string)counter] = tmp; + } + + //shut down deleted/changed connectors + for (iter = current_connectors.begin(); iter != current_connectors.end(); iter++){ + if (new_connectors.count(iter->first) != 1 || new_connectors[iter->first] != iter->second){ + Util::Procs::Stop(iter->first); } } - if (!seenHTTP){Util::Procs::Stop("HTTP");} - if (!seenRTMP){Util::Procs::Stop("RTMP");} + + //start up new/changed connectors + for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){ + if (current_connectors.count(iter->first) != 1 || current_connectors[iter->first] != iter->second || !Util::Procs::isActive(iter->first)){ + Util::Procs::Start(iter->first, iter->second); + } + } + + //store new state + current_connectors = new_connectors; } void CheckConfig(JSON::Value & in, JSON::Value & out){ @@ -227,15 +260,15 @@ void CheckAllStreams(JSON::Value & data){ startStream(jit->first, jit->second); } if (currTime - lastBuffer[jit->first] > 5){ - if (jit->second["online"] != 0){changed = true;} + if ((long long int)jit->second["online"] != 0){changed = true;} jit->second["online"] = 0; }else{ - if (jit->second["online"] != 1){changed = true;} + if ((long long int)jit->second["online"] != 1){changed = true;} jit->second["online"] = 1; } } if (changed){ - WriteFile("/tmp/mist/streamlist", out.toString()); + WriteFile("/tmp/mist/streamlist", data.toString()); } } @@ -245,7 +278,7 @@ void CheckStreams(JSON::Value & in, JSON::Value & out){ if (out.isMember(jit->first)){ if (!streamsEqual(jit->second, out[jit->first])){ Log("STRM", std::string("Updated stream ")+jit->first); - changed = true + changed = true; Util::Procs::Stop(jit->first); startStream(jit->first, jit->second); } @@ -279,10 +312,15 @@ int main(int argc, char ** argv){ sigaction(SIGTERM, &new_action, NULL); sigaction(SIGPIPE, &new_action, NULL); + Storage = JSON::fromString(ReadFile("config.json")); Util::Config C; - C.confsection = "API"; + C.listen_port = (long long int)Storage["config"]["controller"]["port"]; + if (C.listen_port < 1){C.listen_port = 4242;} + C.interface = (std::string)Storage["config"]["controller"]["interface"]; + if (C.interface == ""){C.interface = "0.0.0.0";} + C.username = (std::string)Storage["config"]["controller"]["username"]; + if (C.username == ""){C.username = "root";} C.parseArgs(argc, argv); - C.parseFile(); time_t lastuplink = 0; time_t processchecker = 0; API_Socket = Socket::Server(C.listen_port, C.interface, true); @@ -299,7 +337,6 @@ int main(int argc, char ** argv){ JSON::Value Response; std::string jsonp; ConnectedUser * uplink = 0; - Storage = JSON::fromString(ReadFile("config.json")); while (API_Socket.connected()){ usleep(100000); //sleep for 100 ms - prevents 100% CPU time diff --git a/Makefile b/Makefile index ad0baa78..60ab6f4f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ default: client -.PHONY: client client-debug client-clean clean release-install debug-install docs +.PHONY: client client-debug client-clean clean release-install debug-install install docs prepare: mkdir -p ./bin @@ -27,17 +27,10 @@ client-release: prepare cd Controller; $(MAKE) DEBUG=0 OPTIMIZE=-O2 release: client-release release-install: client-clean client-release - cd Connector_RTMP; $(MAKE) install - cd Connector_HTTP; $(MAKE) install - cd Connector_RAW; $(MAKE) install - cd Buffer; $(MAKE) install - cd Controller; $(MAKE) install + cp ./bin/Mist* /usr/bin/ debug-install: client-clean client-debug - cd Connector_RTMP; $(MAKE) install - cd Connector_HTTP; $(MAKE) install - cd Connector_RAW; $(MAKE) install - cd Buffer; $(MAKE) install - cd Controller; $(MAKE) install + cp ./bin/Mist* /usr/bin/ +install: debug-install docs: doxygen ./Doxyfile > /dev/null diff --git a/util/json.cpp b/util/json.cpp index 7542ed37..d4b3efc4 100644 --- a/util/json.cpp +++ b/util/json.cpp @@ -254,7 +254,11 @@ JSON::Value::operator std::string(){ if (myType == STRING){ return strVal; }else{ - return toString(); + if (myType == EMPTY){ + return ""; + }else{ + return toString(); + } } } diff --git a/util/socket.cpp b/util/socket.cpp index 603075ee..4ddcfb81 100644 --- a/util/socket.cpp +++ b/util/socket.cpp @@ -454,7 +454,7 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ sock = socket(AF_INET6, SOCK_STREAM, 0); if (sock < 0){ #if DEBUG >= 1 - fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno)); + fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno)); #endif return; } @@ -468,7 +468,7 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ struct sockaddr_in6 addr; addr.sin6_family = AF_INET6; addr.sin6_port = htons(port);//set port - if (hostname == "0.0.0.0"){ + if (hostname == "0.0.0.0" || hostname.length() == 0){ addr.sin6_addr = in6addr_any; }else{ inet_pton(AF_INET6, hostname.c_str(), &addr.sin6_addr);//set interface, 0.0.0.0 (default) is all @@ -487,14 +487,14 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ } }else{ #if DEBUG >= 1 - fprintf(stderr, "Binding failed, retrying as IPv4... (%s)\n", strerror(errno)); + fprintf(stderr, "Binding %s:%i failed, retrying as IPv4... (%s)\n", hostname.c_str(), port, strerror(errno)); #endif close(); } sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0){ #if DEBUG >= 1 - fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno)); + fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno)); #endif return; } @@ -508,7 +508,7 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ struct sockaddr_in addr4; addr4.sin_family = AF_INET; addr4.sin_port = htons(port);//set port - if (hostname == "0.0.0.0"){ + if (hostname == "0.0.0.0" || hostname.length() == 0){ addr4.sin_addr.s_addr = INADDR_ANY; }else{ inet_pton(AF_INET, hostname.c_str(), &addr4.sin_addr);//set interface, 0.0.0.0 (default) is all @@ -527,7 +527,7 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ } }else{ #if DEBUG >= 1 - fprintf(stderr, "IPv4 binding also failed, giving up. (%s)\n", strerror(errno)); + fprintf(stderr, "IPv4 binding %s:%i also failed, giving up. (%s)\n", hostname.c_str(), port, strerror(errno)); #endif close(); return;