00001 #include "EchoBehavior.h"
00002 #include "Wireless/Wireless.h"
00003 #include "Shared/string_util.h"
00004 #include "Events/TextMsgEvent.h"
00005 #include <vector>
00006 #include <string>
00007
00008 using namespace std;
00009
00010 EchoBehavior* EchoBehavior::theOne=NULL;
00011 unsigned short EchoBehavior::port=11011;
00012 const char * const EchoBehavior::routeNames[EchoBehavior::NUM_ROUTE] =
00013 {
00014 "TCP Server", "UDP Server","TCP Client","UDP Client"
00015 };
00016
00017 void EchoBehavior::DoStart() {
00018 BehaviorBase::DoStart();
00019 setupNetwork();
00020 erouter->addListener(this,EventBase::textmsgEGID);
00021 }
00022
00023 void EchoBehavior::DoStop() {
00024 erouter->removeListener(this);
00025 teardownNetwork();
00026 BehaviorBase::DoStop();
00027 }
00028
00029 void EchoBehavior::setupNetwork() {
00030 sockets[STCP]=wireless->socket(Socket::SOCK_STREAM);
00031 sockets[SUDP]=wireless->socket(Socket::SOCK_DGRAM);
00032 socks[STCP]=sockets[STCP]->sock;
00033 socks[SUDP]=sockets[SUDP]->sock;
00034 wireless->setDaemon(sockets[STCP],true);
00035 wireless->setDaemon(sockets[SUDP],true);
00036 wireless->setReceiver(sockets[STCP]->sock, server_callbackT);
00037 wireless->setReceiver(sockets[SUDP]->sock, server_callbackU);
00038 wireless->listen(sockets[STCP]->sock, port);
00039 wireless->listen(sockets[SUDP]->sock, port);
00040 }
00041
00042 void EchoBehavior::teardownNetwork() {
00043 wireless->setDaemon(sockets[STCP],false);
00044 wireless->setDaemon(sockets[SUDP],false);
00045 wireless->close(sockets[STCP]);
00046 wireless->close(sockets[SUDP]);
00047 if(sockets[CTCP]!=NULL && wireless->isConnected(socks[CTCP]))
00048 wireless->close(sockets[CTCP]);
00049 if(sockets[CUDP]!=NULL && wireless->isConnected(socks[CUDP]))
00050 wireless->close(sockets[CUDP]);
00051 for(unsigned int i=0; i<NUM_ROUTE; i++)
00052 sockets[i]=NULL;
00053 }
00054
00055 void EchoBehavior::processEvent(const EventBase& e) {
00056
00057 for(unsigned int i=0; i<NUM_ROUTE; i++)
00058 if(sockets[i]!=NULL && !sockets[i]->getDaemon() && !wireless->isConnected(socks[i]))
00059 sockets[i]=NULL;
00060
00061
00062 if(const TextMsgEvent * msg = dynamic_cast<const TextMsgEvent*>(&e)) {
00063 vector<string> args;
00064 vector<unsigned int> offs;
00065 string_util::parseArgs(msg->getText(),args,offs);
00066 if(args.size()==0)
00067 return;
00068 if(args[0]=="open") {
00069 if(args.size()<4) {
00070 serr->printf("syntax: %s (tcp|udp) host port\n",args[0].c_str());
00071 return;
00072 }
00073 if(string_util::makeLower(args[1])=="tcp") {
00074 if(sockets[CTCP]==NULL) {
00075 sockets[CTCP]=wireless->socket(Socket::SOCK_STREAM);
00076 socks[CTCP]=sockets[CTCP]->sock;
00077 wireless->setReceiver(sockets[CTCP], client_callbackT);
00078 }
00079 wireless->connect(sockets[CTCP],args[2].c_str(),atoi(args[3].c_str()));
00080 } else if(string_util::makeLower(args[1])=="udp") {
00081 if(sockets[CUDP]==NULL) {
00082 sockets[CUDP]=wireless->socket(Socket::SOCK_DGRAM);
00083 socks[CUDP]=sockets[CUDP]->sock;
00084 wireless->setReceiver(sockets[CUDP], client_callbackU);
00085 }
00086 wireless->connect(sockets[CUDP],args[2].c_str(),atoi(args[3].c_str()));
00087 } else {
00088 serr->printf("syntax: %s (tcp|udp) host port\n",args[0].c_str());
00089 serr->printf(" first argument '%s' must be either 'tcp' or 'udp'\n",args[1].c_str());
00090 return;
00091 }
00092 } else if(args[0]=="status") {
00093 cout << "Listening on port " << port << endl;
00094 for(unsigned int i=0; i<NUM_ROUTE; i++)
00095 cout << routeNames[i] << ": " << (sockets[i]!=NULL && wireless->isConnected(socks[i]) ? "Connected" : "Not Connected") << endl;
00096 for(unsigned int i=0; i<NUM_ROUTE; i++) {
00097 cout << "Route from " << routeNames[i] << ": ";
00098 for(unsigned int j=0; j<NUM_ROUTE; j++)
00099 cout << route[i][j] << ' ';
00100 cout << endl;
00101 }
00102 } else if(args[0]=="relay" || args[0]=="unlink") {
00103 unsigned char from=(unsigned char)-1U;
00104 unsigned char to=(unsigned char)-1U;
00105 bool val = (args[0]=="relay");
00106 unsigned int i=1;
00107 for(; i<args.size(); i++) {
00108 if(string_util::makeLower(args[i])=="to")
00109 break;
00110 intersect(from,args[i]);
00111 }
00112 if(i==args.size()) {
00113 serr->printf("syntax: %s [udp|tcp|client|server]* to [udp|tcp|client|server]*\n",args[0].c_str());
00114 return;
00115 }
00116 i++;
00117 for(; i<args.size(); i++)
00118 intersect(to,args[i]);
00119 for(unsigned int r=0; r<NUM_ROUTE; r++) {
00120 if(from & (1<<r))
00121 for(unsigned int j=0; j<NUM_ROUTE; j++)
00122 if(to & (1<<j))
00123 route[r][j]=val;
00124 }
00125 } else if(args[0]=="port") {
00126 int p=atoi(args[1].c_str());
00127 if(p==0) {
00128 serr->printf("invalid port value\n");
00129 return;
00130 }
00131 port=p;
00132 teardownNetwork();
00133 setupNetwork();
00134 } else {
00135 for(unsigned int i=0; i<NUM_ROUTE; i++)
00136 if(sockets[i]!=NULL)
00137 sockets[i]->printf("%s\n",msg->getText().c_str());
00138 }
00139 } else {
00140 serr->printf("Bad event received: %s\n",e.getName().c_str());
00141 }
00142 }
00143
00144 void EchoBehavior::intersect(unsigned char& bits, std::string arg) {
00145 arg=string_util::makeLower(arg);
00146 unsigned char mask=0;
00147 if(arg=="server")
00148 mask = (1<<SUDP) | (1<<STCP) ;
00149 else if(arg=="client")
00150 mask = (1<<CUDP) | (1<<CTCP) ;
00151 else if(arg=="tcp")
00152 mask = (1<<STCP) | (1<<CTCP) ;
00153 else if(arg=="udp")
00154 mask = (1<<SUDP) | (1<<CUDP) ;
00155 else
00156 cerr << "Unknown argument '" << arg << "'" << endl;
00157 bits&=mask;
00158 }
00159
00160 void EchoBehavior::processCallback(EchoBehavior::routeIndex_t src, char *buf, int bytes) {
00161 buf[bytes]='\0';
00162 sout->printf("From %s:%d\n",sockets[src]->getPeerAddressAsString().c_str(),sockets[src]->getPeerPort());
00163 sout->printf("Message is: '%s'\n",buf);
00164
00165
00166 if(src==SUDP && sockets[SUDP]!=NULL && !wireless->isConnected(socks[SUDP])) {
00167 for(unsigned int i=0; i<NUM_ROUTE; i++)
00168 if(route[i][SUDP]) {
00169
00170 wireless->connect(sockets[SUDP],sockets[SUDP]->getPeerAddressAsString().c_str(),sockets[SUDP]->getPeerPort());
00171 break;
00172 }
00173 }
00174
00175 for(unsigned int i=0; i<NUM_ROUTE; i++) {
00176 if(route[src][i] && sockets[i]!=NULL) {
00177 if(wireless->isConnected(socks[i]))
00178 sockets[i]->write((byte*)buf,bytes);
00179 else if(!sockets[i]->getDaemon())
00180 sockets[i]=NULL;
00181 }
00182 }
00183 }
00184 int EchoBehavior::server_callbackT(char *buf, int bytes) {
00185 cout << "TCP Server received " << bytes << " bytes" << endl;
00186 theOne->processCallback(STCP,buf,bytes);
00187 return 0;
00188 }
00189 int EchoBehavior::client_callbackT(char *buf, int bytes) {
00190 cout << "TCP Client received " << bytes << " bytes" << endl;
00191 theOne->processCallback(CTCP,buf,bytes);
00192 return 0;
00193 }
00194 int EchoBehavior::server_callbackU(char *buf, int bytes) {
00195 cout << "UDP Server received " << bytes << " bytes" << endl;
00196 theOne->processCallback(SUDP,buf,bytes);
00197 return 0;
00198 }
00199 int EchoBehavior::client_callbackU(char *buf, int bytes) {
00200 cout << "UDP Client received " << bytes << " bytes" << endl;
00201 theOne->processCallback(CUDP,buf,bytes);
00202 return 0;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215