00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <cstdlib>
00025 #include <cstring>
00026 #include <iostream>
00027 #include <sstream>
00028 #include <set>
00029 #include <valarray>
00030 #include <vector>
00031 #include <iterator>
00032 #include "switch.h"
00033 #include "../common/consts.h"
00034 #include "../common/types.h"
00035 #include "../utils/utils.h"
00036 #include "../msg/msg.h"
00037
00038 namespace Aseba
00039 {
00040 using namespace std;
00041 using namespace Dashel;
00042
00045
00047 Switch::Switch(unsigned port, bool verbose, bool dump, bool forward, bool rawTime) :
00048 #ifdef DASHEL_VERSION_INT
00049 Dashel::Hub(verbose || dump),
00050 #endif
00051 verbose(verbose),
00052 dump(dump),
00053 forward(forward),
00054 rawTime(rawTime)
00055 {
00056 ostringstream oss;
00057 oss << "tcpin:port=" << port;
00058 connect(oss.str());
00059 }
00060
00061 void Switch::connectionCreated(Stream *stream)
00062 {
00063 if (verbose)
00064 {
00065 dumpTime(cout, rawTime);
00066 cout << "Incoming connection from " << stream->getTargetName() << endl;
00067 }
00068 }
00069
00070 void Switch::incomingData(Stream *stream)
00071 {
00072
00073
00074
00075 uint16 len;
00076
00077
00078 stream->read(&len, 2);
00079
00080
00081 std::valarray<uint8> readbuff((uint8)0, len + 4);
00082 stream->read(&readbuff[0], len + 4);
00083
00084 if (dump)
00085 {
00086 dumpTime(cout, rawTime);
00087 std::cout << "Read " << std::dec << len + 4 << " on stream " << stream << " : ";
00088 for(unsigned int i = 0; i < readbuff.size(); i++)
00089 std::cout << std::hex << (unsigned)readbuff[i] << " ";
00090 std::cout << std::endl;
00091 }
00092
00093
00094 for (StreamsSet::iterator it = dataStreams.begin(); it != dataStreams.end();++it)
00095 {
00096 Stream* destStream = *it;
00097
00098 if ((forward) && (destStream == stream))
00099 continue;
00100
00101 try
00102 {
00103 destStream->write(&len, 2);
00104 destStream->write(&readbuff[0], len + 4);
00105 destStream->flush();
00106 }
00107 catch (DashelException e)
00108 {
00109
00110 std::cerr << "error while writing" << std::endl;
00111 }
00112 }
00113 }
00114
00115 void Switch::connectionClosed(Stream *stream, bool abnormal)
00116 {
00117 if (verbose)
00118 {
00119 dumpTime(cout);
00120 if (abnormal)
00121 cout << "Abnormal connection closed to " << stream->getTargetName() << " : " << stream->getFailReason() << endl;
00122 else
00123 cout << "Normal connection closed to " << stream->getTargetName() << endl;
00124 }
00125 }
00126
00127 void Switch::broadcastDummyUserMessage()
00128 {
00129 Aseba::UserMessage uMsg;
00130 uMsg.type = 0;
00131
00132 for (StreamsSet::iterator it = dataStreams.begin(); it != dataStreams.end();++it)
00133 {
00134 uMsg.serialize(*it);
00135 (*it)->flush();
00136 }
00137 }
00138
00140 };
00141
00143 void dumpHelp(std::ostream &stream, const char *programName)
00144 {
00145 stream << "Aseba switch, connects aseba components together, usage:\n";
00146 stream << programName << " [options] [additional targets]*\n";
00147 stream << "Options:\n";
00148 stream << "-v, --verbose : makes the switch verbose\n";
00149 stream << "-d, --dump : makes the switch dump all data\n";
00150 stream << "-l, --loop : makes the switch transmit messages back to the send, not only forward them.\n";
00151 stream << "-p port : listens to incoming connection on this port\n";
00152 stream << "--rawtime : shows time in the form of sec:usec since 1970\n";
00153 stream << "-h, --help : shows this help\n";
00154 stream << "Additional targets are any valid Dashel targets." << std::endl;
00155 }
00156
00157 int main(int argc, char *argv[])
00158 {
00159 unsigned port = ASEBA_DEFAULT_PORT;
00160 bool verbose = false;
00161 bool dump = false;
00162 bool forward = true;
00163 bool rawTime = false;
00164 std::vector<std::string> additionalTargets;
00165
00166 int argCounter = 1;
00167
00168 while (argCounter < argc)
00169 {
00170 const char *arg = argv[argCounter];
00171
00172 if ((strcmp(arg, "-v") == 0) || (strcmp(arg, "--verbose") == 0))
00173 {
00174 verbose = true;
00175 }
00176 else if ((strcmp(arg, "-d") == 0) || (strcmp(arg, "--dump") == 0))
00177 {
00178 dump = true;
00179 }
00180 else if ((strcmp(arg, "-l") == 0) || (strcmp(arg, "--loop") == 0))
00181 {
00182 forward = false;
00183 }
00184 else if (strcmp(arg, "-p") == 0)
00185 {
00186 arg = argv[++argCounter];
00187 port = atoi(arg);
00188 }
00189 else if (strcmp(arg, "--rawtime") == 0)
00190 {
00191 rawTime = true;
00192 }
00193 else if ((strcmp(arg, "-h") == 0) || (strcmp(arg, "--help") == 0))
00194 {
00195 dumpHelp(std::cout, argv[0]);
00196 return 0;
00197 }
00198 else
00199 {
00200 additionalTargets.push_back(argv[argCounter]);
00201 }
00202 argCounter++;
00203 }
00204
00205 try
00206 {
00207 Aseba::Switch aswitch(port, verbose, dump, forward, rawTime);
00208 for (size_t i = 0; i < additionalTargets.size(); i++)
00209 aswitch.connect(additionalTargets[i]);
00210
00211
00212
00213
00214
00215
00216
00217 aswitch.run();
00218 }
00219 catch(Dashel::DashelException e)
00220 {
00221 std::cerr << e.what() << std::endl;
00222 }
00223
00224 return 0;
00225 }
00226
00227