diff --git a/src/connectors/conn_http.cpp b/src/connectors/conn_http.cpp index 5dcdc87f..d8ef2986 100644 --- a/src/connectors/conn_http.cpp +++ b/src/connectors/conn_http.cpp @@ -597,8 +597,16 @@ namespace Connector_HTTP { int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(8080); + JSON::Value capa; + capa["desc"] = "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything."; + capa["deps"] = ""; + conf.addConnectorOptions(8080, capa); conf.parseArgs(argc, argv); + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_http_dynamic.cpp b/src/connectors/conn_http_dynamic.cpp index 7af677a0..46010c8d 100644 --- a/src/connectors/conn_http_dynamic.cpp +++ b/src/connectors/conn_http_dynamic.cpp @@ -338,8 +338,17 @@ namespace Connector_HTTP { ///\brief The standard process-spawning main function. int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(1935); + JSON::Value capa; + capa["desc"] = "Enables HTTP protocol Adobe-specific dynamic streaming (also known as HDS)."; + capa["deps"] = "HTTP"; + conf.addBasicConnectorOptions(capa); conf.parseArgs(argc, argv); + + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server("/tmp/mist/http_dynamic"); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_http_live.cpp b/src/connectors/conn_http_live.cpp index fbb827b4..b4ece795 100644 --- a/src/connectors/conn_http_live.cpp +++ b/src/connectors/conn_http_live.cpp @@ -357,8 +357,17 @@ namespace Connector_HTTP { ///\brief The standard process-spawning main function. int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(1935); + JSON::Value capa; + capa["desc"] = "Enables HTTP protocol Apple-specific streaming (also known as HLS)."; + capa["deps"] = "HTTP"; + conf.addBasicConnectorOptions(capa); conf.parseArgs(argc, argv); + + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server("/tmp/mist/http_live"); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_http_progressive.cpp b/src/connectors/conn_http_progressive.cpp index 4987a76b..85dd8e7a 100644 --- a/src/connectors/conn_http_progressive.cpp +++ b/src/connectors/conn_http_progressive.cpp @@ -216,8 +216,17 @@ namespace Connector_HTTP { ///\brief The standard process-spawning main function. int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(1935); + JSON::Value capa; + capa["desc"] = "Enables HTTP protocol progressive streaming."; + capa["deps"] = "HTTP"; + conf.addBasicConnectorOptions(capa); conf.parseArgs(argc, argv); + + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server("/tmp/mist/http_progressive"); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_http_smooth.cpp b/src/connectors/conn_http_smooth.cpp index 3624bf44..9af0bed2 100644 --- a/src/connectors/conn_http_smooth.cpp +++ b/src/connectors/conn_http_smooth.cpp @@ -473,8 +473,17 @@ namespace Connector_HTTP { ///\brief The standard process-spawning main function. int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(1935); + JSON::Value capa; + capa["desc"] = "Enables HTTP protocol Microsoft-specific smooth streaming through silverlight (also known as HSS)."; + capa["deps"] = "HTTP"; + conf.addBasicConnectorOptions(capa); conf.parseArgs(argc, argv); + + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server("/tmp/mist/http_smooth"); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_rtmp.cpp b/src/connectors/conn_rtmp.cpp index 36bb9303..a7ae12a2 100644 --- a/src/connectors/conn_rtmp.cpp +++ b/src/connectors/conn_rtmp.cpp @@ -661,8 +661,16 @@ namespace Connector_RTMP { ///\brief The standard process-spawning main function. int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); - conf.addConnectorOptions(1935); + JSON::Value capa; + capa["desc"] = "Enables the RTMP protocol which is used by Adobe Flash Player."; + capa["deps"] = ""; + conf.addConnectorOptions(1935, capa); conf.parseArgs(argc, argv); + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); if ( !server_socket.connected()){ return 1; diff --git a/src/connectors/conn_ts.cpp b/src/connectors/conn_ts.cpp index 9472e4d2..9b429ce3 100644 --- a/src/connectors/conn_ts.cpp +++ b/src/connectors/conn_ts.cpp @@ -200,12 +200,31 @@ namespace Connector_TS { int main(int argc, char ** argv){ Util::Config conf(argv[0], PACKAGE_VERSION); + JSON::Value capa; + capa["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP."; + capa["deps"] = ""; + capa["required"]["args"]["name"] = "Stream"; + capa["required"]["args"]["help"] = "What streamname to serve. For multiple streams, add this protocol multiple times using different ports."; + capa["required"]["args"]["type"] = "str"; + capa["optional"]["tracks"]["name"] = "Tracks"; + capa["optional"]["tracks"]["help"] = "The track IDs of the stream that this connector will transmit separated by spaces"; + capa["optional"]["tracks"]["type"] = "str"; conf.addOption("streamname", JSON::fromString("{\"arg\":\"string\",\"arg_num\":1,\"help\":\"The name of the stream that this connector will transmit.\"}")); conf.addOption("tracks", JSON::fromString("{\"arg\":\"string\",\"default\":\"\",\"short\": \"t\",\"long\":\"tracks\",\"help\":\"The track IDs of the stream that this connector will transmit separated by spaces.\"}")); - conf.addConnectorOptions(8888); - conf.parseArgs(argc, argv); + conf.addConnectorOptions(8888, capa); + bool ret = conf.parseArgs(argc, argv); + if (conf.getBool("json")){ + std::cout << capa.toString() << std::endl; + return -1; + } + if (!ret){ + std::cerr << "Usage error: missing argument(s)." << std::endl; + conf.printHelp(std::cout); + return 1; + } + Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); if ( !server_socket.connected()){ return 1; diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index 3b85f22c..7417629d 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -221,8 +221,8 @@ int main(int argc, char ** argv){ //Input custom config here Controller::Storage = JSON::fromFile(conf.getString("configFile")); + //check for port, interface and username in arguments - //if they are not there, take them from config file, if there if (conf.getOption("listen_port", true).size() <= 1){ if (Controller::Storage["config"]["controller"]["port"]){ @@ -240,6 +240,28 @@ int main(int argc, char ** argv){ } } + + JSON::Value capabilities; + //list available protocols and report about them + std::deque execs; + Util::getMyExec(execs); + std::string arg_one; + char const * conn_args[] = {0, "-j", 0}; + for (std::deque::iterator it = execs.begin(); it != execs.end(); it++){ + if ((*it).substr(0, 8) == "MistConn"){ + std::cout << "Exec: '" << (*it) << "'" << std::endl; + arg_one = Util::getMyPath() + (*it); + conn_args[0] = arg_one.c_str(); + capabilities["connectors"][(*it).substr(8)] = JSON::fromString(Util::Procs::getOutputOf((char**)conn_args)); + if (capabilities["connectors"][(*it).substr(8)].size() < 1){ + capabilities["connectors"].removeMember((*it).substr(8)); + } + } + } + std::cout << capabilities.toPrettyString() << std::endl; + + + createAccount(conf.getString("account")); /// User friendliness input added at this line @@ -272,7 +294,13 @@ int main(int argc, char ** argv){ std::getline(std::cin, in_string); if (yna(in_string) == 'y'){ //create protocols - Controller::Storage["config"]["protocols"] = JSON::fromString( "[{\"connector\":\"HTTP\",\"interface\":\"\",\"online\":1,\"port\":\"0\",\"username\":\"\"},{\"connector\":\"HTTPDynamic\",\"online\":1,\"username\":\"\"},{\"connector\":\"HTTPLive\",\"online\":1,\"username\":\"\"},{\"connector\":\"HTTPProgressive\",\"online\":1,\"username\":\"\"},{\"connector\":\"HTTPSmooth\",\"online\":1,\"username\":\"\"},{\"connector\":\"RTMP\",\"interface\":\"\",\"online\":1,\"port\":\"0\",\"username\":\"\"}]"); + for (JSON::ObjIter it = capabilities["connectors"].ObjBegin(); it != capabilities["connectors"].ObjEnd(); it++){ + if ( !it->second.isMember("required")){ + JSON::Value newProtocol; + newProtocol["connector"] = it->first; + Controller::Storage["config"]["protocols"].append(newProtocol); + } + } }else if(yna(in_string) == 'a'){ //abort controller startup return 0; @@ -475,7 +503,8 @@ int main(int argc, char ** argv){ Response["log"] = Controller::Storage["log"]; Response["statistics"] = Controller::Storage["statistics"]; Response["authorize"]["username"] = conf.getString("uplink-name"); - Controller::checkCapable(Response["capabilities"]); + Controller::checkCapable(capabilities); + Response["capabilities"] = capabilities; Controller::Log("UPLK", "Responding to login challenge: " + Request["authorize"]["challenge"].asString()); Response["authorize"]["password"] = Secure::md5(conf.getString("uplink-pass") + Request["authorize"]["challenge"].asString()); it->H.Clean(); @@ -523,7 +552,8 @@ int main(int argc, char ** argv){ Controller::CheckAllStreams(Controller::Storage["streams"]); } if (Request.isMember("capabilities")){ - Controller::checkCapable(Response["capabilities"]); + Controller::checkCapable(capabilities); + Response["capabilities"] = capabilities; } if (Request.isMember("conversion")){ if (Request["conversion"].isMember("encoders")){ diff --git a/src/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index 5efd8bb9..71ce79d1 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -52,7 +52,8 @@ namespace Controller { ///\brief Checks the capabilities of the system. ///\param capa The location to store the capabilities. void checkCapable(JSON::Value & capa){ - capa.null(); + //capa.null(); + capa.removeMember("cpu"); std::ifstream cpuinfo("/proc/cpuinfo"); if (cpuinfo){ std::map cpus; @@ -157,73 +158,6 @@ namespace Controller { } } - //list available protocols and report about them - capa["connectors"]["RTMP"]["desc"] = "Enables the RTMP protocol which is used by Adobe Flash Player."; - capa["connectors"]["RTMP"]["deps"] = ""; - capa["connectors"]["RTMP"]["optional"]["port"]["name"] = "TCP port"; - capa["connectors"]["RTMP"]["optional"]["port"]["help"] = "TCP port to listen on - default if unprovided is 1935"; - capa["connectors"]["RTMP"]["optional"]["port"]["type"] = "uint"; - capa["connectors"]["RTMP"]["optional"]["interface"]["name"] = "Interface"; - capa["connectors"]["RTMP"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; - capa["connectors"]["RTMP"]["optional"]["interface"]["type"] = "str"; - capa["connectors"]["RTMP"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["RTMP"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["RTMP"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["TS"]["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP."; - capa["connectors"]["TS"]["deps"] = ""; - capa["connectors"]["TS"]["required"]["port"]["name"] = "TCP port"; - capa["connectors"]["TS"]["required"]["port"]["help"] = "TCP port to listen on"; - capa["connectors"]["TS"]["required"]["port"]["type"] = "uint"; - capa["connectors"]["TS"]["required"]["args"]["name"] = "Stream"; - capa["connectors"]["TS"]["required"]["args"]["help"] = "What streamname to serve - for multiple streams, add this protocol multiple times."; - capa["connectors"]["TS"]["required"]["args"]["type"] = "str"; - capa["connectors"]["TS"]["optional"]["interface"]["name"] = "Interface"; - capa["connectors"]["TS"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; - capa["connectors"]["TS"]["optional"]["interface"]["type"] = "str"; - capa["connectors"]["TS"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["TS"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["TS"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["TS"]["optional"]["tracks"]["name"] = "Tracks"; - capa["connectors"]["TS"]["optional"]["tracks"]["help"] = "The track IDs of the stream that this connector will transmit separated by spaces"; - capa["connectors"]["TS"]["optional"]["tracks"]["type"] = "str"; - capa["connectors"]["HTTP"]["desc"] = - "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything."; - capa["connectors"]["HTTP"]["deps"] = ""; - capa["connectors"]["HTTP"]["optional"]["port"]["name"] = "TCP port"; - capa["connectors"]["HTTP"]["optional"]["port"]["help"] = "TCP port to listen on - default if unprovided is 8080"; - capa["connectors"]["HTTP"]["optional"]["port"]["type"] = "uint"; - capa["connectors"]["HTTP"]["optional"]["interface"]["name"] = "Interface"; - capa["connectors"]["HTTP"]["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; - capa["connectors"]["HTTP"]["optional"]["interface"]["type"] = "str"; - capa["connectors"]["HTTP"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTP"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["HTTP"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["HTTPProgressive"]["desc"] = "Enables HTTP protocol progressive streaming."; - capa["connectors"]["HTTPProgressive"]["deps"] = "HTTP"; - capa["connectors"]["HTTPProgressive"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPProgressive"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["HTTPProgressive"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["HTTPDynamic"]["desc"] = "Enables HTTP protocol Adobe-specific dynamic streaming (aka HDS)."; - capa["connectors"]["HTTPDynamic"]["deps"] = "HTTP"; - capa["connectors"]["HTTPDynamic"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPDynamic"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["HTTPDynamic"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["HTTPSmooth"]["desc"] = "Enables HTTP protocol MicroSoft-specific smooth streaming through silverlight."; - capa["connectors"]["HTTPSmooth"]["deps"] = "HTTP"; - capa["connectors"]["HTTPSmooth"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPSmooth"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["HTTPSmooth"]["optional"]["username"]["type"] = "str"; - capa["connectors"]["HTTPLive"]["desc"] = "Enables HTTP protocol Apple-style live streaming."; - capa["connectors"]["HTTPLive"]["deps"] = "HTTP"; - capa["connectors"]["HTTPLive"]["optional"]["username"]["name"] = "Username"; - capa["connectors"]["HTTPLive"]["optional"]["username"]["help"] = - "Username to drop privileges to - default if unprovided means do not drop privileges"; - capa["connectors"]["HTTPLive"]["optional"]["username"]["type"] = "str"; } }