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  char *host = (char *)"localhost";
86  unsigned short int port = 1910;
87  bool free_host = argp->parse_hostport("r", &host, &port);
88 
89  c = new FawkesNetworkClient(host, port);
90 
91  if ( free_host ) free(host);
92 
93  c->register_handler(this, FAWKES_CID_SKILLER_PLUGIN);
94  c->connect();
95  }
96 
97  /** Destructor. */
99  {
100  printf("Finalizing\n");
101 
103  sif->msgq_enqueue(rcm);
104 
105  usleep(500000);
106 
107  rbb->close(sif);
108  delete rbb;
109  rbb = NULL;
110 
111  c->deregister_handler(FAWKES_CID_SKILLER_PLUGIN);
112  c->disconnect();
113  delete c;
114  }
115 
116 
117  virtual void loop()
118  {
119  if ( c->connected() ) {
120  if ( just_connected ) {
121  just_connected = false;
122  try {
123  rbb = new RemoteBlackBoard(c);
124  sif = rbb->open_for_reading<SkillerInterface>("Skiller");
126  sif->msgq_enqueue(aqm);
127  usleep(100000);
128  } catch (Exception &e) {
129  e.print_trace();
130  return;
131  }
132  }
133 
134  if ( argp->num_items() > 0 ) {
135  std::string sks = "";
136  const std::vector< const char * > & items = argp->items();
137 
138  std::vector< const char * >::const_iterator i = items.begin();
139  sks = *i;
140  ++i;
141  for (; i != items.end(); ++i) {
142  sks += " ";
143  sks += *i;
144  }
145 
147  sif->msgq_enqueue(esm);
148 
149  usleep(100000);
150  exit();
151  } else {
152  char *line = NULL;
153 
154  line = readline(prompt);
155  if ( line ) {
156  if (strcmp(line, "") != 0) {
157 
158  if (strcmp(line, "stop") == 0 ) {
159  printf("Stopping skill execution\n");
161  sif->msgq_enqueue(sm);
162  } else {
163  printf("Executing: %s\n", line);
165  sif->msgq_enqueue(esm);
166  }
167 
168  add_history(line);
169  }
170  } else {
171  if ( ! connection_died_recently ) {
172  exit();
173  }
174  }
175  }
176  } else {
177  if ( connection_died_recently ) {
178  connection_died_recently = false;
179  printf("Connection died\n");
180  c->disconnect();
181  }
182  try {
183  c->connect();
184  } catch (Exception &e) {
185  printf(".");
186  fflush(stdout);
187  sleep(1);
188  }
189  }
190  }
191 
192 
193  virtual void deregistered(unsigned int id) throw()
194  {
195  }
196 
197 
199  unsigned int id) throw()
200  {
201  }
202 
203 
204  virtual void connection_died(unsigned int id) throw()
205  {
206  prompt = "-# ";
207 
208  rbb->close(sif);
209  delete rbb;
210  rbb = NULL;
211  sif = NULL;
212 
213  connection_died_recently = true;
214 
215  //fprintf(stdin, "\n");
216  //kill(SIGINT);
217  rl_done = 1;
218  }
219 
220 
221  virtual void connection_established(unsigned int id) throw()
222  {
223  printf("Connection established\n");
224  just_connected = true;
225  prompt = "+# ";
226  }
227 
228 
229  private:
230  ArgumentParser *argp;
232  BlackBoard *rbb;
233  SkillerInterface *sif;
234  const char *prompt;
235  bool just_connected;
236  bool connection_died_recently;
237 };
238 
239 
240 /** Config tool main.
241  * @param argc argument count
242  * @param argv arguments
243  */
244 int
245 main(int argc, char **argv)
246 {
247  ArgumentParser argp(argc, argv, "hr:");
248 
249  if ( argp.has_arg("h") ) {
250  print_usage(argv[0]);
251  exit(0);
252  }
253 
254  SkillShellThread sst(&argp);
255  sst.start();
256  sst.join();
257 
258  return 0;
259 }
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:193
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:52
Skill shell thread.
Definition: skilltester.cpp:67
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:221
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
virtual void loop()
Code to execute in the thread.
Definition: skillet.cpp:117
Remote BlackBoard.
Definition: remote.h:48
virtual void connection_died(unsigned int id)
Client connection died.
Definition: skillet.cpp:204
void join()
Join the thread.
Definition: thread.cpp:610
SkillerInterface Fawkes BlackBoard Interface.
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:169
The BlackBoard abstract class.
Definition: blackboard.h:48
~SkillShellThread()
Destructor.
Definition: skillet.cpp:98
virtual void inbound_received(FawkesNetworkMessage *m, unsigned int id)
Called for incoming messages.
Definition: skillet.cpp:198
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:511