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