2 * jsonserver.c: A plugin for the Video Disk Recorder
4 * See the README file for copyright information and how to reach the author.
7 // Log docs: https://github.com/gabime/spdlog
8 #include <spdlog/spdlog.h>
9 namespace spd = spdlog;
19 #include <vdr/plugin.h>
22 // Config docs: http://www.hyperrealm.com/libconfig/libconfig_manual.html#The-C_002b_002b-API
23 #include <libconfig.h++>
28 static const char *VERSION = "0.0.1";
29 static const char *DESCRIPTION = "JSON data server plugin for VDR";
30 static const char *MAINMENUENTRY = "Jsonserver";
32 class cPluginJsonserver : public cPlugin {
34 // Add any member variables or functions you may need here.
35 struct mg_context *mg;
36 std::shared_ptr<spd::logger> logger;
37 libconfig::Config config;
40 cPluginJsonserver(void);
41 virtual ~cPluginJsonserver();
42 virtual const char *Version(void) { return VERSION; }
43 virtual const char *Description(void) { return DESCRIPTION; }
44 virtual const char *CommandLineHelp(void);
45 virtual bool ProcessArgs(int argc, char *argv[]);
46 virtual bool Initialize(void);
47 virtual bool Start(void);
48 virtual void Stop(void);
49 virtual void Housekeeping(void);
50 virtual void MainThreadHook(void);
51 virtual cString Active(void);
52 virtual time_t WakeupTime(void);
53 virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
54 virtual cOsdObject *MainMenuAction(void);
55 virtual cMenuSetupPage *SetupMenu(void);
56 virtual bool SetupParse(const char *Name, const char *Value);
57 virtual bool Service(const char *Id, void *Data = NULL);
58 virtual const char **SVDRPHelpPages(void);
59 virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
62 cPluginJsonserver::cPluginJsonserver(void)
64 // Initialize any member variables here.
65 // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
66 // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
71 cPluginJsonserver::~cPluginJsonserver()
73 // Clean up after yourself!
77 const char *cPluginJsonserver::CommandLineHelp(void)
79 // Return a string that describes all known command line options.
83 bool cPluginJsonserver::ProcessArgs(int argc, char *argv[])
85 // Implement command line argument processing here if applicable.
89 bool cPluginJsonserver::Initialize(void)
91 // Initialize any background activities the plugin shall perform.
95 bool cPluginJsonserver::Start(void)
97 // Start any background activities the plugin shall perform.
98 const char* configDir = cPlugin::ConfigDirectory("jsonserver");
101 dsyslog("jsonserver: Error: Could not get config dir from VDR");
105 std::string configFile(std::string(configDir) + std::string("/server.conf"));
106 dsyslog("%s", configFile.c_str());
109 config.readFile(configFile.c_str());
111 catch (const libconfig::FileIOException &fioex)
113 dsyslog("jsonserver: Failed to read config file");
116 catch(const libconfig::ParseException &pex)
118 dsyslog("jsonserver: Config parse error at %s: %i - %s", pex.getFile(), pex.getLine(), pex.getError());
122 std::string cfgLogFilename;
123 if (config.lookupValue("log-file", cfgLogFilename))
127 logger = spd::basic_logger_mt("jsonserver_spdlog", cfgLogFilename);
129 catch (const spd::spdlog_ex& ex)
131 dsyslog("jsonserver: Failed to initialise log object: %s", ex.what());
134 logger->set_pattern("[%Y-%m-%d %T.%f] [%t] [%l] %v");
135 logger->set_level(spd::level::trace); //Set global log level to info
136 logger->flush_on(spd::level::debug); // FIXME Change this!!
138 logger->info("Main: Logging started");
142 dsyslog("jsonserver: Logging disabled");
145 std::string cfgDocRoot;
146 if (!config.lookupValue("doc-root", cfgDocRoot))
148 logger->critical("Main: Failed to load doc-root from config");
149 dsyslog("jsonserver: Could not load JS App Dir from plugin config file");
155 if (!config.lookupValue("http-port", cfgPort))
157 logger->critical("Main: Failed to load http-port from config");
158 dsyslog("jsonserver: Could not load http-port from plugin config file");
163 std::string cfgSSLFilename;
164 if (!config.lookupValue("ssl-pem-file", cfgSSLFilename))
166 logger->critical("Main: Failed to load ssl-pem-file from config");
167 dsyslog("jsonserver: Could not load ssl-pem-file from plugin config file");
172 // Make Mongoose options
173 const char *options[] =
175 "document_root", cfgDocRoot.c_str(),
176 "listening_ports", cfgPort.c_str(),
178 "ssl_certificate", cfgSSLFilename.c_str(),
182 // Prepare callbacks structure. We have only one callback, the rest are NULL.
183 struct mg_callbacks callbacks;
184 memset(&callbacks, 0, sizeof(callbacks));
185 callbacks.begin_request = jsonserver_request_handler;
187 mg = mg_start(&callbacks, NULL, options);
188 logger->info("Main: Mongoose started");
193 void cPluginJsonserver::Stop(void)
195 // Stop any background activities the plugin is performing.
196 if (mgRunning) mg_stop(mg);
200 void cPluginJsonserver::Housekeeping(void)
202 // Perform any cleanup or other regular tasks.
205 void cPluginJsonserver::MainThreadHook(void)
207 // Perform actions in the context of the main program thread.
208 // WARNING: Use with great care - see PLUGINS.html!
211 cString cPluginJsonserver::Active(void)
213 // Return a message string if shutdown should be postponed
217 time_t cPluginJsonserver::WakeupTime(void)
219 // Return custom wakeup time for shutdown script
223 cOsdObject *cPluginJsonserver::MainMenuAction(void)
225 // Perform the action when selected from the main VDR menu.
229 cMenuSetupPage *cPluginJsonserver::SetupMenu(void)
231 // Return a setup menu in case the plugin supports one.
235 bool cPluginJsonserver::SetupParse(const char *Name, const char *Value)
237 // Parse your own setup parameters and store their values.
241 bool cPluginJsonserver::Service(const char *Id, void *Data)
243 // Handle custom service requests from other plugins
247 const char **cPluginJsonserver::SVDRPHelpPages(void)
249 // Return help text for SVDRP commands this plugin implements
253 cString cPluginJsonserver::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
255 // Process SVDRP commands this plugin implements
259 VDRPLUGINCREATOR(cPluginJsonserver); // Don't touch this!