Fawkes API  Fawkes Development Version
skillet.cpp
1 
2 /***************************************************************************
3  * skillet.cpp - Skiller console tool
4  *
5  * Created: Sat Mar 15 13:57:22 2008
6  * Copyright 2006-2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include <blackboard/remote.h>
24 #include <core/threading/thread.h>
25 #include <interfaces/SkillerInterface.h>
26 #include <netcomm/fawkes/client.h>
27 #include <netcomm/fawkes/client_handler.h>
28 #include <readline/history.h>
29 #include <readline/readline.h>
30 #include <utils/system/argparser.h>
31 #include <utils/system/signal.h>
32 
33 #include <csignal>
34 #include <cstdio>
35 #include <cstdlib>
36 #include <cstring>
37 #include <string>
38 #include <unistd.h>
39 
40 using namespace fawkes;
41 
42 void
43 print_usage(const char *program_name)
44 {
45  printf("Usage: %s [-h] [-r host[:port]]\n"
46  " -h This help message\n"
47  " -r host[:port] Remote host (and optionally port) to connect to\n",
48  program_name);
49 }
50 
51 static int
52 event_hook()
53 {
54  return 0;
55 }
56 
57 /** Skill shell thread.
58  * This thread opens a network connection to a host and uses a RemoteBlackBoard
59  * connection to send skill strings for execution. It also shows Skiller log messages
60  * and uses the skiller network protocol.
61  * @author Tim Niemueller
62  */
64 {
65 public:
66  /** Constructor.
67  * @param argp argument parser
68  */
69  explicit SkillShellThread(ArgumentParser *argp)
70  : Thread("SkillShellThread", Thread::OPMODE_CONTINUOUS)
71  {
72  this->argp = argp;
73  prompt = "-# ";
74  just_connected = true;
75  connection_died_recently = false;
76 
77  sif = NULL;
78  using_history();
79  // this is needed to get rl_done working
80  rl_event_hook = event_hook;
81 
82  char * host = (char *)"localhost";
83  unsigned short int port = 1910;
84  bool free_host = argp->parse_hostport("r", &host, &port);
85 
86  c = new FawkesNetworkClient(host, port);
87 
88  if (free_host)
89  free(host);
90 
91  c->register_handler(this, FAWKES_CID_SKILLER_PLUGIN);
92  c->connect();
93  }
94 
95  /** Destructor. */
97  {
98  printf("Finalizing\n");
99 
101  sif->msgq_enqueue(rcm);
102 
103  usleep(500000);
104 
105  rbb->close(sif);
106  delete rbb;
107  rbb = NULL;
108 
109  c->deregister_handler(FAWKES_CID_SKILLER_PLUGIN);
110  c->disconnect();
111  delete c;
112  }
113 
114  virtual void
115  loop()
116  {
117  if (c->connected()) {
118  if (just_connected) {
119  just_connected = false;
120  try {
121  rbb = new RemoteBlackBoard(c);
122  sif = rbb->open_for_reading<SkillerInterface>("Skiller");
125  sif->msgq_enqueue(aqm);
126  usleep(100000);
127  } catch (Exception &e) {
128  e.print_trace();
129  return;
130  }
131  }
132 
133  if (argp->num_items() > 0) {
134  std::string sks;
135  const std::vector<const char *> &items = argp->items();
136 
137  std::vector<const char *>::const_iterator i = items.begin();
138  sks = *i;
139  ++i;
140  for (; i != items.end(); ++i) {
141  sks += " ";
142  sks += *i;
143  }
144 
146  new SkillerInterface::ExecSkillMessage(sks.c_str());
147  sif->msgq_enqueue(esm);
148 
149  usleep(100000);
150  exit();
151  } else {
152  char *line = readline(prompt);
153  if (line) {
154  if (strcmp(line, "") != 0) {
155  if (strcmp(line, "stop") == 0) {
156  printf("Stopping skill execution\n");
158  sif->msgq_enqueue(sm);
159  } else {
160  printf("Executing: %s\n", line);
163  sif->msgq_enqueue(esm);
164  }
165 
166  add_history(line);
167  }
168  } else {
169  if (!connection_died_recently) {
170  exit();
171  }
172  }
173  }
174  } else {
175  if (connection_died_recently) {
176  connection_died_recently = false;
177  printf("Connection died\n");
178  c->disconnect();
179  }
180  try {
181  c->connect();
182  } catch (Exception &e) {
183  printf(".");
184  fflush(stdout);
185  sleep(1);
186  }
187  }
188  }
189 
190  virtual void
191  deregistered(unsigned int id) throw()
192  {
193  }
194 
195  virtual void
196  inbound_received(FawkesNetworkMessage *m, unsigned int id) throw()
197  {
198  }
199 
200  virtual void
201  connection_died(unsigned int id) throw()
202  {
203  prompt = "-# ";
204 
205  rbb->close(sif);
206  delete rbb;
207  rbb = NULL;
208  sif = NULL;
209 
210  connection_died_recently = true;
211 
212  //fprintf(stdin, "\n");
213  //kill(SIGINT);
214  rl_done = 1;
215  }
216 
217  virtual void
218  connection_established(unsigned int id) throw()
219  {
220  printf("Connection established\n");
221  just_connected = true;
222  prompt = "+# ";
223  }
224 
225 private:
226  ArgumentParser * argp;
228  BlackBoard * rbb;
229  SkillerInterface * sif;
230  const char * prompt;
231  bool just_connected;
232  bool connection_died_recently;
233 };
234 
235 /** Config tool main.
236  * @param argc argument count
237  * @param argv arguments
238  */
239 int
240 main(int argc, char **argv)
241 {
242  ArgumentParser argp(argc, argv, "hr:");
243 
244  if (argp.has_arg("h")) {
245  print_usage(argv[0]);
246  exit(0);
247  }
248 
249  SkillShellThread sst(&argp);
250  sst.start();
251  sst.join();
252 
253  return 0;
254 }
fawkes::ArgumentParser::parse_hostport
bool parse_hostport(const char *argn, char **host, unsigned short int *port)
Parse host:port string.
Definition: argparser.cpp:228
fawkes::SkillerInterface::ReleaseControlMessage
Definition: SkillerInterface.h:194
fawkes::BlackBoard
Definition: blackboard.h:48
fawkes::RemoteBlackBoard
Definition: remote.h:51
fawkes::SkillerInterface::AcquireControlMessage
Definition: SkillerInterface.h:163
fawkes::SkillerInterface::ExecSkillMessage
Definition: SkillerInterface.h:92
fawkes::SkillerInterface::StopExecMessage
Definition: SkillerInterface.h:142
fawkes::FawkesNetworkClientHandler
Definition: client_handler.h:35
fawkes
fawkes::ArgumentParser
Definition: argparser.h:67
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:600
fawkes::SkillerInterface
Definition: SkillerInterface.h:37
fawkes::Thread
Definition: thread.h:44
SkillShellThread
Skill shell thread.
Definition: skilltester.cpp:63
fawkes::FawkesNetworkMessage
Definition: message.h:80
fawkes::FawkesNetworkClient
Definition: client.h:55
fawkes::Exception
Definition: exception.h:39