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 <netcomm/fawkes/client.h>
24 #include <blackboard/remote.h>
25 #include <utils/system/argparser.h>
26 #include <utils/system/signal.h>
27 #include <core/threading/thread.h>
28 #include <netcomm/fawkes/client_handler.h>
29 
30 #include <cstring>
31 #include <cstdlib>
32 #include <cstdio>
33 #include <unistd.h>
34 #include <csignal>
35 #include <string>
36 
37 #include <readline/readline.h>
38 #include <readline/history.h>
39 
40 #include <interfaces/SkillerInterface.h>
41 
42 using namespace fawkes;
43 
44 void
45 print_usage(const char *program_name)
46 {
47  printf("Usage: %s [-h] [-r host[:port]]\n"
48  " -h This help message\n"
49  " -r host[:port] Remote host (and optionally port) to connect to\n",
50  program_name);
51 }
52 
53 static int
54 event_hook()
55 {
56  return 0;
57 }
58 
59 
60 /** Skill shell thread.
61  * This thread opens a network connection to a host and uses a RemoteBlackBoard
62  * connection to send skill strings for execution. It also shows Skiller log messages
63  * and uses the skiller network protocol.
64  * @author Tim Niemueller
65  */
67 {
68  public:
69  /** Constructor.
70  * @param argp argument parser
71  */
73  : Thread("SkillShellThread", Thread::OPMODE_CONTINUOUS)
74  {
75  this->argp = argp;
76  prompt = "-# ";
77  just_connected = true;
78  connection_died_recently = false;
79 
80  sif = NULL;
81  using_history();
82  // this is needed to get rl_done working
83  rl_event_hook = event_hook;
84 
85  continuous = false;
86 
87  char *host = (char *)"localhost";
88  unsigned short int port = 1910;
89  bool free_host = argp->parse_hostport("r", &host, &port);
90 
91  c = new FawkesNetworkClient(host, port);
92 
93  if ( free_host ) free(host);
94 
95  c->register_handler(this, FAWKES_CID_SKILLER_PLUGIN);
96  c->connect();
97  }
98 
99  /** Destructor. */
101  {
102  printf("Finalizing\n");
103 
105  sif->msgq_enqueue(rcm);
106 
107  usleep(500000);
108 
109  rbb->close(sif);
110  delete rbb;
111  rbb = NULL;
112 
113  c->deregister_handler(FAWKES_CID_SKILLER_PLUGIN);
114  c->disconnect();
115  delete c;
116  }
117 
118 
119  virtual void loop()
120  {
121  if ( c->connected() ) {
122  if ( just_connected ) {
123  just_connected = false;
124  try {
125  rbb = new RemoteBlackBoard(c);
126  sif = rbb->open_for_reading<SkillerInterface>("Skiller");
128  sif->msgq_enqueue(aqm);
129  usleep(100000);
130  } catch (Exception &e) {
131  e.print_trace();
132  return;
133  }
134  }
135 
136  if ( argp->num_items() > 0 ) {
137  std::string sks = "";
138  const std::vector< const char * > & items = argp->items();
139 
140  std::vector< const char * >::const_iterator i = items.begin();
141  sks = *i;
142  ++i;
143  for (; i != items.end(); ++i) {
144  sks += " ";
145  sks += *i;
146  }
147 
149  sif->msgq_enqueue(esm);
150 
151  usleep(100000);
152  exit();
153  } else {
154  char *line = NULL;
155 
156  line = readline(prompt);
157  if ( line ) {
158  if (strcmp(line, "") != 0) {
159 
160  if ( strcmp(line, "cont") == 0 ) {
161  printf("Switching to continuous skill execution mode\n");
162  continuous = true;
163  } else if (strcmp(line, "oneshot") == 0 ) {
164  printf("Switching to one-shot skill execution mode\n");
165  continuous = false;
166  } else if (strcmp(line, "stop") == 0 ) {
167  printf("Stopping continuous skill execution\n");
169  sif->msgq_enqueue(sm);
170  } else {
171  printf("Executing: %s\n", line);
172  if ( continuous ) {
174  sif->msgq_enqueue(escm);
175  } else {
177  sif->msgq_enqueue(esm);
178  }
179  }
180 
181  add_history(line);
182  }
183  } else {
184  if ( ! connection_died_recently ) {
185  exit();
186  }
187  }
188  }
189  } else {
190  if ( connection_died_recently ) {
191  connection_died_recently = false;
192  printf("Connection died\n");
193  c->disconnect();
194  }
195  try {
196  c->connect();
197  } catch (Exception &e) {
198  printf(".");
199  fflush(stdout);
200  sleep(1);
201  }
202  }
203  }
204 
205 
206  virtual void deregistered(unsigned int id) throw()
207  {
208  }
209 
210 
212  unsigned int id) throw()
213  {
214  }
215 
216 
217  virtual void connection_died(unsigned int id) throw()
218  {
219  prompt = "-# ";
220 
221  rbb->close(sif);
222  delete rbb;
223  rbb = NULL;
224  sif = NULL;
225 
226  connection_died_recently = true;
227 
228  //fprintf(stdin, "\n");
229  //kill(SIGINT);
230  rl_done = 1;
231  }
232 
233 
234  virtual void connection_established(unsigned int id) throw()
235  {
236  printf("Connection established\n");
237  just_connected = true;
238  prompt = "+# ";
239  }
240 
241 
242  private:
243  ArgumentParser *argp;
245  BlackBoard *rbb;
246  SkillerInterface *sif;
247  const char *prompt;
248  bool just_connected;
249  bool connection_died_recently;
250 
251  bool continuous;
252 };
253 
254 
255 /** Config tool main.
256  * @param argc argument count
257  * @param argv arguments
258  */
259 int
260 main(int argc, char **argv)
261 {
262  ArgumentParser argp(argc, argv, "hr:");
263 
264  if ( argp.has_arg("h") ) {
265  print_usage(argv[0]);
266  exit(0);
267  }
268 
269  SkillShellThread sst(&argp);
270  sst.start();
271  sst.join();
272 
273  return 0;
274 }
Message handler for FawkesNetworkClient.
SkillShellThread(ArgumentParser *argp)
Constructor.
Definition: skillet.cpp:72
virtual void deregistered(unsigned int id)
This handler has been deregistered.
Definition: skillet.cpp:206
bool parse_hostport(const char *argn, char **host, unsigned short int *port)
Parse host:port string.
Definition: argparser.cpp:231
Simple Fawkes network client.
Definition: client.h:51
Skill shell thread.
Definition: skillet.cpp:66
Fawkes library namespace.
StopExecMessage Fawkes BlackBoard Interface Message.
Representation of a message that is sent over the network.
Definition: message.h:75
Parse command line arguments.
Definition: argparser.h:66
ReleaseControlMessage Fawkes BlackBoard Interface Message.
Thread class encapsulation of pthreads.
Definition: thread.h:42
AcquireControlMessage Fawkes BlackBoard Interface Message.
Base class for exceptions in Fawkes.
Definition: exception.h:36
ExecSkillMessage Fawkes BlackBoard Interface Message.
virtual void connection_established(unsigned int id)
Client has established a connection.
Definition: skillet.cpp:234
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
virtual void loop()
Code to execute in the thread.
Definition: skillet.cpp:119
Remote BlackBoard.
Definition: remote.h:49
virtual void connection_died(unsigned int id)
Client connection died.
Definition: skillet.cpp:217
SkillerInterface Fawkes BlackBoard Interface.
The BlackBoard abstract class.
Definition: blackboard.h:49
~SkillShellThread()
Destructor.
Definition: skillet.cpp:100
ExecSkillContinuousMessage Fawkes BlackBoard Interface Message.
virtual void inbound_received(FawkesNetworkMessage *m, unsigned int id)
Called for incoming messages.
Definition: skillet.cpp:211