DaemonConfig::DaemonConfig(std::string config_file, std::string config_defaults_file) { CSimpleIniA ini; ini.SetMultiKey(); ini.LoadFile(config_file.c_str()); CSimpleIniA defaultIni; defaultIni.SetMultiKey(); defaultIni.LoadFile(config_defaults_file.c_str()); // Stream will only be in the user override config, never in the defaults CSimpleIniA::TNamesDepend values; ini.GetAllValues("daemon", "stream", values); // sort the values into the original load order values.sort(CSimpleIniA::Entry::LoadOrder()); // output all of the items CSimpleIniA::TNamesDepend::const_iterator i; for (i = values.begin(); i != values.end(); ++i) { stream_urls.push_back(i->pItem); } country = getString(&ini, &defaultIni, "daemon", "country", "us"); topn = getInt(&ini, &defaultIni, "daemon", "topn", 20); storePlates = getBoolean(&ini, &defaultIni, "daemon", "store_plates", false); imageFolder = getString(&ini, &defaultIni, "daemon", "store_plates_location", "/tmp/"); uploadData = getBoolean(&ini, &defaultIni, "daemon", "upload_data", false); upload_url = getString(&ini, &defaultIni, "daemon", "upload_address", ""); company_id = getString(&ini, &defaultIni, "daemon", "company_id", ""); site_id = getString(&ini, &defaultIni, "daemon", "site_id", ""); pattern = getString(&ini, &defaultIni, "daemon", "pattern", ""); }
std::vector<float> getAllFloats(CSimpleIniA* ini, string section, string key) { CSimpleIniA::TNamesDepend values; ini->GetAllValues(section.c_str(), key.c_str(), values); // sort the values into the original load order values.sort(CSimpleIniA::Entry::LoadOrder()); std::vector<float> response; // output all of the items CSimpleIniA::TNamesDepend::const_iterator i; for (i = values.begin(); i != values.end(); ++i) { response.push_back(atof(i->pItem)); } return response; }
int main( int argc, const char** argv ) { daemon_active = true; bool noDaemon = false; bool clockOn = false; std::string logFile; int topn; std::string configFile; std::string country; TCLAP::CmdLine cmd("OpenAlpr Daemon", ' ', Alpr::getVersion()); TCLAP::ValueArg<std::string> countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code"); TCLAP::ValueArg<std::string> configFileArg("","config","Path to the openalpr.conf file.",false, "" ,"config_file"); TCLAP::ValueArg<int> topNArg("n","topn","Max number of possible plate numbers to return. Default=25",false, 25 ,"topN"); TCLAP::ValueArg<std::string> logFileArg("l","log","Log file to write to. Default=" + DEFAULT_LOG_FILE_PATH,false, DEFAULT_LOG_FILE_PATH ,"topN"); TCLAP::SwitchArg daemonOffSwitch("f","foreground","Set this flag for debugging. Disables forking the process as a daemon and runs in the foreground. Default=off", cmd, false); TCLAP::SwitchArg clockSwitch("","clock","Display timing information to log. Default=off", cmd, false); try { cmd.add( countryCodeArg ); cmd.add( topNArg ); cmd.add( configFileArg ); cmd.add( logFileArg ); if (cmd.parse( argc, argv ) == false) { // Error occured while parsing. Exit now. return 1; } country = countryCodeArg.getValue(); configFile = configFileArg.getValue(); logFile = logFileArg.getValue(); topn = topNArg.getValue(); noDaemon = daemonOffSwitch.getValue(); clockOn = clockSwitch.getValue(); } catch (TCLAP::ArgException &e) // catch any exceptions { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; return 1; } log4cplus::BasicConfigurator config; config.configure(); if (noDaemon == false) { // Fork off into a separate daemon daemon(0, 0); log4cplus::SharedAppenderPtr myAppender(new log4cplus::RollingFileAppender(logFile)); myAppender->setName("alprd_appender"); // Redirect std out to log file logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("alprd")); logger.addAppender(myAppender); LOG4CPLUS_INFO(logger, "Running OpenALPR daemon in daemon mode."); } else { //log4cplus::SharedAppenderPtr myAppender(new log4cplus::ConsoleAppender()); //myAppender->setName("alprd_appender"); // Redirect std out to log file logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("alprd")); //logger.addAppender(myAppender); LOG4CPLUS_INFO(logger, "Running OpenALPR daemon in the foreground."); } CSimpleIniA ini; ini.SetMultiKey(); ini.LoadFile(DAEMON_CONFIG_FILE_PATH.c_str()); std::vector<std::string> stream_urls; CSimpleIniA::TNamesDepend values; ini.GetAllValues("daemon", "stream", values); // sort the values into the original load order values.sort(CSimpleIniA::Entry::LoadOrder()); // output all of the items CSimpleIniA::TNamesDepend::const_iterator i; for (i = values.begin(); i != values.end(); ++i) { stream_urls.push_back(i->pItem); } if (stream_urls.size() == 0) { LOG4CPLUS_FATAL(logger, "No video streams defined in the configuration."); return 1; } bool storePlates = ini.GetBoolValue("daemon", "store_plates", false); std::string imageFolder = ini.GetValue("daemon", "store_plates_location", "/tmp/"); bool uploadData = ini.GetBoolValue("daemon", "upload_data", false); std::string upload_url = ini.GetValue("daemon", "upload_address", ""); std::string site_id = ini.GetValue("daemon", "site_id", ""); LOG4CPLUS_INFO(logger, "Using: " << imageFolder << " for storing valid plate images"); pid_t pid; for (int i = 0; i < stream_urls.size(); i++) { pid = fork(); if (pid == (pid_t) 0) { // This is the child process, kick off the capture data and upload threads CaptureThreadData* tdata = new CaptureThreadData(); tdata->stream_url = stream_urls[i]; tdata->camera_id = i + 1; tdata->config_file = configFile; tdata->output_images = storePlates; tdata->output_image_folder = imageFolder; tdata->country_code = country; tdata->site_id = site_id; tdata->top_n = topn; tdata->clock_on = clockOn; tthread::thread* thread_recognize = new tthread::thread(streamRecognitionThread, (void*) tdata); if (uploadData) { // Kick off the data upload thread UploadThreadData* udata = new UploadThreadData(); udata->upload_url = upload_url; tthread::thread* thread_upload = new tthread::thread(dataUploadThread, (void*) udata ); } break; } // Parent process will continue and spawn more children } while (daemon_active) { usleep(30000); } }
bool snippets( const char * a_pszFile, bool a_bIsUtf8, bool a_bUseMultiKey, bool a_bUseMultiLine ) { // LOADING DATA // load from a data file CSimpleIniA ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine); SI_Error rc = ini.LoadFile(a_pszFile); if (rc < 0) return false; // load from a string std::string strData; rc = ini.LoadData(strData.c_str(), strData.size()); if (rc < 0) return false; // GETTING SECTIONS AND KEYS // get all sections CSimpleIniA::TNamesDepend sections; ini.GetAllSections(sections); // get all keys in a section CSimpleIniA::TNamesDepend keys; ini.GetAllKeys("section-name", keys); // GETTING VALUES // get the value of a key const char * pszValue = ini.GetValue("section-name", "key-name", NULL /*default*/); // get the value of a key which may have multiple // values. If bHasMultipleValues is true, then just // one value has been returned bool bHasMultipleValues; pszValue = ini.GetValue("section-name", "key-name", NULL /*default*/, &bHasMultipleValues); // get all values of a key with multiple values CSimpleIniA::TNamesDepend values; ini.GetAllValues("section-name", "key-name", values); // sort the values into the original load order #if defined(_MSC_VER) && _MSC_VER <= 1200 /** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */ values.sort(); #else values.sort(CSimpleIniA::Entry::LoadOrder()); #endif // output all of the items CSimpleIniA::TNamesDepend::const_iterator i; for (i = values.begin(); i != values.end(); ++i) { printf("key-name = '%s'\n", i->pItem); } // MODIFYING DATA // adding a new section rc = ini.SetValue("new-section", NULL, NULL); if (rc < 0) return false; printf("section: %s\n", rc == SI_INSERTED ? "inserted" : "updated"); // adding a new key ("new-section" will be added // automatically if it doesn't already exist. rc = ini.SetValue("new-section", "new-key", "value"); if (rc < 0) return false; printf("key: %s\n", rc == SI_INSERTED ? "inserted" : "updated"); // changing the value of a key rc = ini.SetValue("section", "key", "updated-value"); if (rc < 0) return false; printf("key: %s\n", rc == SI_INSERTED ? "inserted" : "updated"); // DELETING DATA // deleting a key from a section. Optionally the entire // section may be deleted if it is now empty. ini.Delete("section-name", "key-name", true /*delete the section if empty*/); // deleting an entire section and all keys in it ini.Delete("section-name", NULL); // SAVING DATA // save the data to a string rc = ini.Save(strData); if (rc < 0) return false; // save the data back to the file rc = ini.SaveFile(a_pszFile); if (rc < 0) return false; return true; }
// ------------------------------------------------------------------------------------------------ SMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info) { using namespace SMod; // Output plug-in header puts(""); OutputMessage("------------------------------------------------------------------"); OutputMessage("Plug-in: %s", SMOD_NAME); OutputMessage("Author: %s", SMOD_AUTHOR); OutputMessage("Legal: %s", SMOD_COPYRIGHT); OutputMessage("------------------------------------------------------------------"); puts(""); // Store server proxies _Func = functions; _Clbk = callbacks; _Info = info; // Assign plug-in version _Info->pluginVersion = SMOD_VERSION; _Info->apiMajorVersion = PLUGIN_API_MAJOR; _Info->apiMinorVersion = PLUGIN_API_MINOR; // Assign the plug-in name snprintf(_Info->name, sizeof(_Info->name), "%s", SMOD_HOST_NAME); // Create the configuration loader CSimpleIniA conf(false, true, true); // Attempt to load the configurations from disk const SI_Error ini_ret = conf.LoadFile("announce.ini"); // See if the configurations could be loaded if (ini_ret < 0) { switch (ini_ret) { case SI_FAIL: OutputError("Failed to load the configuration file. Probably invalid"); case SI_NOMEM: OutputError("Run out of memory while loading the configuration file"); case SI_FILE: OutputError("Failed to load the configuration file: announce.ini"); default: OutputError("Failed to load the configuration file for some unforeseen reason"); } // Plug-in failed to load configurations return SMOD_FAILURE; } // See if the plug-in should output verbose information g_Verbose = conf.GetBoolValue("Options", "Verbose", false); // Attempt to retrieve the list of specified master-servers CSimpleIniA::TNamesDepend servers; conf.GetAllValues("Servers", "Address", servers); // See if any server address was specified if (servers.size() <= 0) { VerboseError("No master-servers specified. No reason to load the plug-in."); // No point in loading the plug-in return SMOD_FAILURE; } // Sort the list in it's original order servers.sort(CSimpleIniA::Entry::LoadOrder()); // Process each specified server addresses for (const auto & elem : servers) { // See if there's even something that could resemble a server address if (!elem.pItem) { continue; } // Attempt to extract URI information from the currently processed address URI addr(elem.pItem); // See if a valid host could be extracted if (addr.mHost.empty()) { VerboseError("Master-server '%s' is an ill formed address", elem.pItem); } // Construct a server instance using this address else { // Show which master-server is added to the list VerboseMessage("Master-server '%s' added to the announce list", addr.Full()); // Create the server instance g_Servers.emplace_back(std::move(addr)); } } // See if any server was valid if (g_Servers.size() <= 0) { VerboseError("No master-servers specified. No reason to load the plug-in."); // No point in loading the plug-in return SMOD_FAILURE; } // Bind to the server callbacks _Clbk->OnServerInitialise = OnServerInitialise; _Clbk->OnServerShutdown = OnServerShutdown; _Clbk->OnServerFrame = OnServerFrame; // Notify that the plug-in was successfully loaded VerboseMessage("Successfully loaded %s", SMOD_NAME); // Done! return SMOD_SUCCESS; }