Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

RemoteRouter.cc

Go to the documentation of this file.
00001 #include "Events/RemoteRouter.h"
00002 #include "Events/EventRouter.h"
00003 
00004 #include "Events/TextMsgEvent.h"
00005 #include "Events/TimerEvent.h"
00006 #include "Events/FilterBankEvent.h"
00007 #include "Events/LocomotionEvent.h"
00008 #include "Events/LookoutEvents.h"
00009 #include "Events/PitchEvent.h"
00010 #include "Events/VisionObjectEvent.h"
00011 #include "Events/Kodu/KoduEventBase.h"
00012 #include "Shared/string_util.h"
00013 
00014 using namespace std;
00015 
00016 RemoteRouter::RemoteRouter(int host) : RemoteEvents(),
00017                      rstate(NULL), waitingForPort(true),
00018                      requestQueue(),
00019                      timerActive(false), waitTime(0),
00020                      remoteHost(0) {
00021   rstate = new RemoteState(this);
00022   
00023   remoteHost = host;
00024   
00025   connect(EventRouter::defaultPort);
00026   erouter->addTimer(this, 1, 500, true);
00027 }
00028 
00029 RemoteRouter::~RemoteRouter() {
00030   delete rstate;
00031   
00032   wireless->close(sck);
00033 }
00034 
00035 void RemoteRouter::forwardEvent(std::vector<char> &evec) {
00036   //Decode the event from the buffer and send it
00037 
00038   unsigned int size = evec.size();
00039   char *buf = &evec[0];
00040   EventBase etest, *event = NULL;
00041   
00042   if (!etest.checkInc((int)etest.loadBinaryBuffer(buf, size), buf, size)) {
00043     cout << "Error: Received event is not a subclass of EventBase" << endl;
00044     return;
00045   }
00046   
00047   //If there are bytes left, it's not just an EventBase
00048   if (size) {
00049 
00050     if (etest.checkCreator("EventBase::TextMsgEvent",
00051                  buf, size, false)) {
00052       event = new TextMsgEvent();
00053     } else if (etest.checkCreator("EventBase::TimerEvent",
00054                     buf, size, false)) {
00055       event = new TimerEvent();
00056     } else if (etest.checkCreator("EventBase::LocomotionEvent",
00057                     buf, size, false)) {
00058       event = new LocomotionEvent();
00059     } else if (etest.checkCreator("EventBase::VisionObjectEvent",
00060                     buf, size, false)) {
00061       event = new VisionObjectEvent();
00062     } else if (etest.checkCreator(KoduEventBase::classID, buf, size, false)) {
00063             event = KoduEventBase::getInstance(&evec[0], evec.size());
00064             if (event == NULL) {
00065                 // Could not read the event
00066                 return;
00067             }
00068     } else {
00069       cout << "Buffer isn't a recognized event type. " << endl;
00070     }
00071     
00072   } else {
00073     event = new EventBase();
00074   }
00075 
00076   //Load the buffer
00077   if (event) {
00078     if (!event->loadBinaryBuffer(&evec[0], evec.size())) {
00079       cout << "Error loading from buffer" << endl;
00080     } else {
00081       // cout << "Created event object successfully. Posting event from host "
00082       //   << string_util::intToStringIP(remoteHost) << endl;
00083       event->setHostID(remoteHost);
00084       erouter->postEvent(*event);
00085       delete event;
00086     }
00087   }
00088 }
00089 
00090 void RemoteRouter::connect(int port) {
00091   std::string ip = string_util::intToStringIP(remoteHost);
00092   cout << "RemoteRouter: Connecting to " << ip << " on port "
00093      << port << endl;
00094   sck = wireless->socket(Socket::SOCK_STREAM);
00095   wireless->setReceiver(sck, this);
00096   if (wireless->connect(sck, ip.c_str(), port)) {
00097     cout << "RemoteRouter: error connecting to remote host" << endl;
00098   }
00099 }
00100 
00101 int RemoteRouter::processData(char *data, int bytes) {
00102   if (waitingForPort) {
00103     if (bytes != sizeof(int)) {
00104       cout << "RemoteRouter: unexpected data" << endl;
00105       return -1;
00106     }
00107 
00108     wireless->close(sck);
00109     int port = *(int *)data;
00110     connect(port);
00111     waitingForPort = false;
00112     return 0;
00113   }
00114   
00115   while (bytes) {
00116     if (bufType == Invalid) {
00117       //Get the buffer type
00118       if (!readType(data, bytes))
00119         cout << "Error reading buffer type" << endl;
00120 
00121     } else if (!sizeLeft) {
00122       //Get the size
00123       if (!readSize(data, bytes))
00124         cout << "Error reading buffer size" << endl;
00125         
00126     } else {
00127       //Read some data
00128       if (readData(data, bytes)) {
00129         //Dispatch the chunk of data
00130         switch(bufType) {
00131         case EventData:
00132           forwardEvent(vecbuf);
00133           break;
00134         case StateData:
00135           rstate->update(&vecbuf[0]);
00136           break;
00137         case Invalid:
00138           cout << "Error: invalid data. This should never happen." << endl;
00139           return -1;
00140         default:
00141           cout << "Error: data came in that wasn't expected" << endl;
00142           return -1;
00143         }
00144         bufType = Invalid;
00145       }
00146     }
00147     
00148   }
00149 
00150   return 0;
00151 }
00152 
00153 void RemoteRouter::requestStateUpdates(RemoteState::StateType type,
00154                        unsigned int interval) {
00155   RemoteRequest info;
00156   info.type = StateUpdateRequest;
00157   info.sType = type;
00158   info.interval = interval;
00159   sendRemoteRequest(info);
00160 }
00161 
00162 void RemoteRouter::stopStateUpdates(RemoteState::StateType type) {
00163   RemoteRequest info;
00164   info.type = StopStateUpdateRequest;
00165   info.sType = type;
00166   sendRemoteRequest(info);
00167 }
00168 
00169 void RemoteRouter::addListener(EventBase::EventGeneratorID_t egid) {
00170   RemoteRequest info;
00171   info.type = EventListenerRequest;
00172   info.numElements = 1;
00173   info.egid = egid;
00174   sendRemoteRequest(info);
00175 }
00176 
00177 void RemoteRouter::addListener(EventBase::EventGeneratorID_t egid,
00178                  size_t sid) {
00179   RemoteRequest info;
00180   info.type = EventListenerRequest;
00181   info.numElements = 2;
00182   info.egid = egid;
00183   info.sid = sid;
00184   sendRemoteRequest(info);
00185 }
00186 
00187 void RemoteRouter::addListener(EventBase::EventGeneratorID_t egid,
00188                  size_t sid,
00189                  EventBase::EventTypeID_t etid) {
00190   RemoteRequest info;
00191   info.type = EventListenerRequest;
00192   info.numElements = 3;
00193   info.egid = egid;
00194   info.sid = sid;
00195   info.etid = etid;
00196   sendRemoteRequest(info);
00197 }
00198 
00199 void RemoteRouter::removeListener(EventBase::EventGeneratorID_t egid) {
00200   RemoteRequest info;
00201   info.type = RemoveEventListenerRequest;
00202   info.numElements = 1;
00203   info.egid = egid;
00204   sendRemoteRequest(info);
00205 }
00206 
00207 void RemoteRouter::removeListener(EventBase::EventGeneratorID_t egid,
00208                   size_t sid) {
00209   RemoteRequest info;
00210   info.type = RemoveEventListenerRequest;
00211   info.numElements = 2;
00212   info.egid = egid;
00213   info.sid = sid;
00214   sendRemoteRequest(info);
00215 }
00216 
00217 void RemoteRouter::removeListener(EventBase::EventGeneratorID_t egid,
00218                   size_t sid,
00219                   EventBase::EventTypeID_t etid) {
00220   RemoteRequest info;
00221   info.type = RemoveEventListenerRequest;
00222   info.numElements = 3;
00223   info.egid = egid;
00224   info.sid = sid;
00225   info.etid = etid;
00226   sendRemoteRequest(info);
00227 }
00228 
00229 void RemoteRouter::processEvent(const EventBase& event) {
00230   if (event.getGeneratorID() == EventBase::timerEGID ) {
00231     switch(event.getSourceID()) {
00232     case 0:
00233       if (isReady()) {
00234         cout << "Connected! Sending queue of requests" << endl;
00235         while (requestQueue.size()) {
00236           sendRemoteRequest(requestQueue.front());
00237           requestQueue.pop_front();
00238         }
00239         
00240         erouter->removeTimer(this, 0);
00241         timerActive = false;
00242       } else {
00243         waitTime += 500;
00244         if (waitTime == 5000) {
00245           cout << "RemoteRouter has been waiting for 5 seconds to connect, "
00246              << "are you sure you specified the right host?" << endl;
00247         }
00248       }
00249       break;
00250 
00251     case 1:
00252       if (isConnected()) {
00253         int foo = 0;
00254         sck->write((byte *)&foo, sizeof(int));
00255         erouter->removeTimer(this, 1);
00256       }
00257       break;
00258 
00259     default:
00260       cout << "RemoteRouter got unknown timer event" << endl;
00261     }
00262   }
00263 }
00264 
00265 void RemoteRouter::sendRemoteRequest(RemoteRequest &info) {
00266   if (!isReady()) {
00267     cout << "Tried to send remote request but not connected! Queuing RemoteRequest..." << endl;
00268 
00269     requestQueue.push_back(info);
00270     if (!timerActive) {
00271       erouter->addTimer(this, 0, 500, true);
00272       timerActive = true;
00273       waitTime = 0;
00274     }
00275     return;
00276   }
00277 
00278   NetworkBuffer nBuf;
00279 
00280   nBuf.addItem(RequestData);
00281   int const remoteRequestSize = sizeof(RemoteRequest); // sizeof(...) returns a long; we require an int for addItem
00282   nBuf.addItem(remoteRequestSize);
00283   nBuf.addItem(info);
00284 
00285   if (!nBuf.send(sck)) {
00286     cout << "Error sending remote request" << endl;
00287     return;
00288   } 
00289 }

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