00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <netcomm/fawkes/client.h>
00024 #include <blackboard/remote.h>
00025 #include <utils/system/argparser.h>
00026 #include <utils/system/signal.h>
00027 #include <core/threading/thread.h>
00028 #include <netcomm/fawkes/client_handler.h>
00029
00030 #include <cstring>
00031 #include <cstdlib>
00032 #include <cstdio>
00033 #include <unistd.h>
00034 #include <csignal>
00035 #include <string>
00036
00037 #include <readline/readline.h>
00038 #include <readline/history.h>
00039
00040 #include <interfaces/SkillerInterface.h>
00041
00042 using namespace fawkes;
00043
00044 void
00045 print_usage(const char *program_name)
00046 {
00047 printf("Usage: %s [-h] [-r host[:port]]\n"
00048 " -h This help message\n"
00049 " -r host[:port] Remote host (and optionally port) to connect to\n",
00050 program_name);
00051 }
00052
00053 static int
00054 event_hook()
00055 {
00056 return 0;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 class SkillShellThread : public Thread, public FawkesNetworkClientHandler
00067 {
00068 public:
00069
00070
00071
00072 SkillShellThread(ArgumentParser *argp)
00073 : Thread("SkillShellThread", Thread::OPMODE_CONTINUOUS)
00074 {
00075 this->argp = argp;
00076 prompt = "-# ";
00077 just_connected = true;
00078 connection_died_recently = false;
00079
00080 sif = NULL;
00081 using_history();
00082
00083 rl_event_hook = event_hook;
00084
00085 continuous = false;
00086
00087 char *host = (char *)"localhost";
00088 unsigned short int port = 1910;
00089 bool free_host = argp->parse_hostport("r", &host, &port);
00090
00091 c = new FawkesNetworkClient(host, port);
00092
00093 if ( free_host ) free(host);
00094
00095 c->register_handler(this, FAWKES_CID_SKILLER_PLUGIN);
00096 c->connect();
00097 }
00098
00099
00100 ~SkillShellThread()
00101 {
00102 printf("Finalizing\n");
00103
00104 SkillerInterface::ReleaseControlMessage *rcm = new SkillerInterface::ReleaseControlMessage();
00105 sif->msgq_enqueue(rcm);
00106
00107 usleep(500000);
00108
00109 rbb->close(sif);
00110 delete rbb;
00111 rbb = NULL;
00112
00113 c->deregister_handler(FAWKES_CID_SKILLER_PLUGIN);
00114 c->disconnect();
00115 delete c;
00116 }
00117
00118
00119 virtual void loop()
00120 {
00121 if ( c->connected() ) {
00122 if ( just_connected ) {
00123 just_connected = false;
00124 try {
00125 rbb = new RemoteBlackBoard(c);
00126 sif = rbb->open_for_reading<SkillerInterface>("Skiller");
00127 SkillerInterface::AcquireControlMessage *aqm = new SkillerInterface::AcquireControlMessage();
00128 sif->msgq_enqueue(aqm);
00129 usleep(100000);
00130 } catch (Exception &e) {
00131 e.print_trace();
00132 return;
00133 }
00134 }
00135
00136 if ( argp->num_items() > 0 ) {
00137 std::string sks = "";
00138 const std::vector< const char * > & items = argp->items();
00139
00140 std::vector< const char * >::const_iterator i = items.begin();
00141 sks = *i;
00142 ++i;
00143 for (; i != items.end(); ++i) {
00144 sks += " ";
00145 sks += *i;
00146 }
00147
00148 SkillerInterface::ExecSkillMessage *esm = new SkillerInterface::ExecSkillMessage(sks.c_str());
00149 sif->msgq_enqueue(esm);
00150
00151 usleep(100000);
00152 exit();
00153 } else {
00154 char *line = NULL;
00155
00156 line = readline(prompt);
00157 if ( line ) {
00158 if (strcmp(line, "") != 0) {
00159
00160 if ( strcmp(line, "cont") == 0 ) {
00161 printf("Switching to continuous skill execution mode\n");
00162 continuous = true;
00163 } else if (strcmp(line, "oneshot") == 0 ) {
00164 printf("Switching to one-shot skill execution mode\n");
00165 continuous = false;
00166 } else if (strcmp(line, "stop") == 0 ) {
00167 printf("Stopping continuous skill execution\n");
00168 SkillerInterface::StopExecMessage *sm = new SkillerInterface::StopExecMessage();
00169 sif->msgq_enqueue(sm);
00170 } else {
00171 printf("Executing: %s\n", line);
00172 if ( continuous ) {
00173 SkillerInterface::ExecSkillContinuousMessage *escm = new SkillerInterface::ExecSkillContinuousMessage(line);
00174 sif->msgq_enqueue(escm);
00175 } else {
00176 SkillerInterface::ExecSkillMessage *esm = new SkillerInterface::ExecSkillMessage(line);
00177 sif->msgq_enqueue(esm);
00178 }
00179 }
00180
00181 add_history(line);
00182 }
00183 } else {
00184 if ( ! connection_died_recently ) {
00185 exit();
00186 }
00187 }
00188 }
00189 } else {
00190 if ( connection_died_recently ) {
00191 connection_died_recently = false;
00192 printf("Connection died\n");
00193 c->disconnect();
00194 }
00195 try {
00196 c->connect();
00197 } catch (Exception &e) {
00198 printf(".");
00199 fflush(stdout);
00200 sleep(1);
00201 }
00202 }
00203 }
00204
00205
00206 virtual void deregistered(unsigned int id) throw()
00207 {
00208 }
00209
00210
00211 virtual void inbound_received(FawkesNetworkMessage *m,
00212 unsigned int id) throw()
00213 {
00214 }
00215
00216
00217 virtual void connection_died(unsigned int id) throw()
00218 {
00219 prompt = "-# ";
00220
00221 rbb->close(sif);
00222 delete rbb;
00223 rbb = NULL;
00224 sif = NULL;
00225
00226 connection_died_recently = true;
00227
00228
00229
00230 rl_done = 1;
00231 }
00232
00233
00234 virtual void connection_established(unsigned int id) throw()
00235 {
00236 printf("Connection established\n");
00237 just_connected = true;
00238 prompt = "+# ";
00239 }
00240
00241
00242 private:
00243 ArgumentParser *argp;
00244 FawkesNetworkClient *c;
00245 BlackBoard *rbb;
00246 SkillerInterface *sif;
00247 const char *prompt;
00248 bool just_connected;
00249 bool connection_died_recently;
00250
00251 bool continuous;
00252 };
00253
00254
00255
00256
00257
00258
00259 int
00260 main(int argc, char **argv)
00261 {
00262 ArgumentParser argp(argc, argv, "hr:");
00263
00264 if ( argp.has_arg("h") ) {
00265 print_usage(argv[0]);
00266 exit(0);
00267 }
00268
00269 SkillShellThread sst(&argp);
00270 sst.start();
00271 sst.join();
00272
00273 return 0;
00274 }