1 #include <boost/bind.hpp> 2 #if BOOST_VERSION < 104400 3 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)) 4 #undef BOOST_HAS_RVALUE_REFS 7 #include <boost/thread.hpp> 8 #include <boost/asio/error.hpp> 9 #include <boost/asio/deadline_timer.hpp> 21 namespace ba = boost::asio;
22 namespace bs = boost::system;
24 using ba::deadline_timer;
42 char fReadBuffer[1000];
62 if (error && error!=ba::error::basic_errors::operation_aborted)
66 str <<
"HandleReadTimeout: " << error.message() <<
" (" << error <<
")";
67 if (error==ba::error::misc_errors::eof)
77 if (fInTimeout.expires_at() > deadline_timer::traits_type::now())
80 Error(
"fInTimeout has expired...");
88 if (bytes_received==0 || error)
92 if (error && error!=ba::error::basic_errors::not_connected)
95 str <<
"Reading from " << URL() <<
": " << error.message() <<
" (" << error <<
")";
98 PostClose(error!=ba::error::basic_errors::operation_aborted);
104 if (bytes_received==2)
106 txt = string(fReadBuffer, bytes_received);
110 fMsg() <<
"Received b=" << bytes_received <<
": " << (int)fReadBuffer[0] <<
" " << (
int)txt[0] <<
" '" << txt <<
"' " <<
" " << error.message() <<
" (" << error <<
")" << endl;
112 if (fReadBuffer[0]==
'T')
131 txt = string(fReadBuffer, bytes_received+2);
132 const int s = atoi(fReadBuffer+35);
134 Info(
"Requested time received: "+txt);
138 Out() <<
"Received b=" << bytes_received <<
": " << (int)fReadBuffer[0] <<
" " << (
int)txt[0] <<
" '" << txt <<
"' " <<
" " << error.message() <<
" (" << error <<
")" << endl;
139 memset(fReadBuffer, 0, 100);
157 memset(fReadBuffer, 0, 100);
173 Connection(ioservice, imp()), fMsg(imp), state(0)
184 kSM_Disconnected = 1,
215 c1(*this, *this), c2(*this, *this), c3(*this, *this), c4(*this, *this),
216 c5(*this, *this), c6(*this, *this), c7(*this, *this), c8(*this, *this),
217 c9(*this, *this), fTimers(out)
249 AddStateName(kSM_Disconnected,
"Disconnected");
250 AddStateName(kSM_Connecting,
"Connecting");
251 AddStateName(kSM_Connected,
"Connected");
252 AddStateName(kSM_Running,
"Running");
253 AddStateName(kSM_SomeRunning,
"SomeRunning");
254 AddStateName(kSM_Starting,
"Starting");
255 AddStateName(kSM_Stopping,
"Stopping");
257 AddEvent(kSM_Running,
"START", kSM_Connected).
259 AddEvent(kSM_Connected,
"STOP", kSM_Running);
261 AddEvent(
"TIME", kSM_Running);
262 AddEvent(
"LED", kSM_Connected);
264 T::AddEvent(
"TESTI",
"I");
265 T::AddEvent(
"TESTI2",
"I:2");
266 T::AddEvent(
"TESTIF",
"I:2;F:2");
267 T::AddEvent(
"TESTIC",
"I:2;C");
269 T::AddEvent(
"CMD",
"C").
272 AddEvent(kSM_Reconnect,
"RECONNECT");
274 AddEvent(kSM_SetUrl,
"SETURL",
"C");
281 size_t p0 = cmd.find_first_of(
' ');
282 if (p0==string::npos)
285 T::Out() <<
"\nCommand: '" << cmd.substr(0, p0) <<
"'" << cmd.substr(p0)<<
"'" << endl;
304 return T::GetCurrentState();
308 switch (evt.GetTargetState())
312 T::Out() <<
"Received Start(" << i <<
")" << endl;
316 return T::GetCurrentState();
318 return T::kSM_FatalError;
344 const int n = poll_one();
345 fTimers.
Proc(n==0 && T::IsQueueEmpty());
352 return kSM_Disconnected;
356 return kSM_Connecting;
358 if (c1.
GetState()==0 && c2.
GetState()==0 && T::GetCurrentState()!=kSM_Starting)
359 return kSM_Connected;
361 if (c1.
GetState()==1 && c2.
GetState()==1 && T::GetCurrentState()!=kSM_Stopping)
364 return kSM_SomeRunning;
372 switch (evt.GetTargetState())
375 T::Out() << evt.
GetText() << endl;
377 return T::GetCurrentState();
400 return T::GetCurrentState();
403 T::Out() <<
"Received START" << endl;
407 return T::GetCurrentState();
412 T::Out() <<
"Received STOP" << endl;
416 return T::GetCurrentState();
420 return T::kSM_FatalError;
437 return T::GetCurrentState();
462 wout <<
kRed <<
"ERROR - Couldn't open log-file " << conf.
Get<
string>(
"log") <<
": " << strerror(errno) << endl;
472 template<
class T,
class S>
475 static T shell(conf.
GetName().c_str(), conf.
Get<
int>(
"console")!=1);
482 win <<
kRed <<
"ERROR - Couldn't open log-file " << conf.
Get<
string>(
"log") <<
": " << strerror(errno) << endl;
485 shell.SetReceiver(io_service);
516 "The console connects to all available Dim Servers and allows to " 517 "easily access all of their commands.\n" 519 "Usage: test3 [-c type] [OPTIONS]\n" 520 " or: test3 [OPTIONS]\n" 523 "The following describes the available commandline options. " 524 "For further details on how command line option are parsed " 525 "and in which order which configuration sources are accessed " 526 "please refer to the class reference of the Configuration class.";
534 "The default is that the program is started without user interaction. " 535 "All actions are supposed to arrive as DimCommands. Using the -c " 536 "option, a local shell can be initialized. With h or help a short " 537 "help message about the usuage can be brought to the screen." 578 "Written by Thomas Bretz et al.\n" 583 "Copyright (C) 2011 by the FACT Collaboration.\n" 584 "This is free software; see the source for copying conditions.\n" 591 const string n = conf.
GetName()+
".log";
593 po::options_description config(
"Program options");
595 (
"dns", var<string>(
"localhost"),
"Dim nameserver host name (Overwites DIM_DNS_NODE environment variable)")
596 (
"log,l", var<string>(n),
"Write log-file")
597 (
"no-dim,d",
po_switch(),
"Disable dim services")
598 (
"console,c", var<int>(),
"Use console (0=shell, 1=simple buffered, X=simple unbuffered)")
601 conf.
AddEnv(
"dns",
"DIM_DNS_NODE");
606 int main(
int argc,
const char* argv[])
612 po::variables_map vm;
615 vm = conf.
Parse(argc, argv);
617 catch (std::exception &e)
619 #if BOOST_VERSION > 104000 620 po::multiple_occurrences *MO =
dynamic_cast<po::multiple_occurrences*
>(&e);
622 cout <<
"Error: " << e.what() <<
" of '" << MO->get_option_name() <<
"' option." << endl;
625 cout <<
"Error: " << e.what() << endl;
647 setenv(
"DIM_DNS_NODE", conf.
Get<
string>(
"dns").c_str(), 1);
652 if (!conf.
Has(
"console"))
654 if (conf.
Get<
bool>(
"no-dim"))
655 return RunDim<StateMachine>(conf);
657 return RunDim<StateMachineDim>(conf);
660 if (conf.
Get<
bool>(
"no-dim"))
662 if (conf.
Get<
int>(
"console")==0)
663 return RunShell<LocalShell, StateMachine>(conf);
665 return RunShell<LocalConsole, StateMachine>(conf);
669 if (conf.
Get<
int>(
"console")==0)
670 return RunShell<LocalShell, StateMachineDim>(conf);
672 return RunShell<LocalConsole, StateMachineDim>(conf);
675 catch (std::exception& e)
677 std::cerr <<
"Exception: " << e.what() <<
"\n";
int main(int argc, const char *argv[])
void PostMessage(const void *msg, size_t s=0)
void PrintVersion(const char *name)
#define PACKAGE_BUGREPORT
void HandleReceivedData(const bs::error_code &error, size_t bytes_received, int)
void ConnectionEstablished()
int Configure(const Event &evt)
void PostClose(bool restart=true)
A general base-class describing events issues in a state machine.
const char * GetText() const
int Transition(const Event &evt)
The base implementation of a distributed messaging system.
A C++ ostream to an ncurses window supporting attributes and colors.
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
po::typed_value< bool > * po_switch()
void AddEnv(const std::string &conf, const std::string &env)
void SetEndpoint(const std::string &addr, int port)
ConnectionFAD(ba::io_service &ioservice, MessageImp &imp)
virtual void StartConnect()
bool Has(const std::string &var)
int RunDim(Configuration &conf)
void AddOptions(const po::options_description &opt, bool visible=true)
void SetLogStream(MessageImp *log)
int Start(const EventImp &evt, int i)
std::string GetName() const
Return the stored name of the event.
Commandline parsing, resource file parsing and database access.
void Proc(bool cond, int maxwait=5000, int interval=10000)
int RunShell(Configuration &conf)
Concerete implementation of an EventImp stroring name, format, data and time.
virtual void HandleReadTimeout(const boost::system::error_code &)
int Command(const EventImp &evt)
void SetupConfiguration(Configuration &conf)
Connection(boost::asio::io_service &io_service, std::ostream &out)
void HandleReadTimeout(const bs::error_code &error)
const po::variables_map & Parse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
bool OpenLogFile(const std::string &filename, bool append=false)
Open a log-file.
const std::string & GetName() const
StateMachineFAD(const string &name="", ostream &out=cout)