Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

EchoBehavior.cc

Go to the documentation of this file.
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(); // do this first (required)
00021   setupNetwork();
00022   erouter->addListener(this,EventBase::textmsgEGID);
00023 }
00024 
00025 void EchoBehavior::doStop() {
00026   erouter->removeListener(this);
00027   teardownNetwork();
00028   BehaviorBase::doStop(); // do this last (required)
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   //Check for connections which have just been closed
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   //handle the event
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'; //hack - better hope it's not a full buffer
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   //udp server doesn't automatically connect
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         //we found someone who wants to send output to the udp server, so we'd better connect it
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 /*! @file
00209  * @brief 
00210  * @author Ethan Tira-Thompson (ejt) (Creator)
00211  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3