Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

ArServerClient.cpp

Go to the documentation of this file.
00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerClient.h"
00029 #include "ArServerCommands.h"
00030 #include "ArClientCommands.h"
00031 #include "ArServerData.h"
00032 #include "ArServerUserInfo.h"
00033 
00068 AREXPORT ArServerClient::ArServerClient(
00069         ArSocket *tcpSocket, unsigned int udpPort, long authKey,
00070         long introKey,  ArRetFunctor2<bool, ArNetPacket *, 
00071         struct sockaddr_in *> *sendUdpCallback,
00072         std::map<unsigned int, ArServerData *> *dataMap,
00073         const char *passwordKey, const char *serverKey,
00074         const ArServerUserInfo *userInfo, int rejecting, 
00075         const char *rejectingString) :
00076   myProcessPacketCB(this, &ArServerClient::processPacket, NULL, true)
00077 {
00078   ArNetPacket packet;
00079 
00080   // set our default to no command
00081   pushCommand(0);
00082 
00083   myAuthKey = authKey;
00084   myIntroKey = introKey;
00085   myTcpSocket.transfer(tcpSocket);
00086   myTcpSocket.setCloseCallback(tcpSocket->getCloseCallback());
00087   myTcpSocket.setNonBlock();
00088   myTcpReceiver.setSocket(&myTcpSocket);
00089   myTcpReceiver.setProcessPacketCB(&myProcessPacketCB);
00090   myTcpSender.setSocket(&myTcpSocket);
00091   mySendUdpCB = sendUdpCallback;
00092   myDataMap = dataMap;
00093   myTcpOnly = false;
00094   myUserInfo = userInfo;
00095   myPasswordKey = passwordKey;
00096   myServerKey = serverKey;
00097   myRejecting = rejecting;
00098   if (rejectingString != NULL)
00099     myRejectingString = rejectingString;
00100 
00101   packet.empty();
00102   packet.setCommand(ArServerCommands::INTRODUCTION);
00103   packet.strToBuf("alpha");
00104   packet.uByte2ToBuf(udpPort);
00105   packet.uByte4ToBuf(myAuthKey);
00106   packet.uByte4ToBuf(myIntroKey);
00107   packet.strToBuf(myPasswordKey.c_str());
00108   sendPacketTcp(&packet);
00109 
00110   resetTracking();
00111   
00112   internalSwitchState(STATE_SENT_INTRO);
00113 }
00114 
00115 AREXPORT ArServerClient::~ArServerClient()
00116 {
00117   myTcpReceiver.setSocket(NULL);
00118   myTcpReceiver.setProcessPacketCB(NULL);
00119   myTcpSocket.close();
00120   
00122   // new way to get the request change functor called
00123   std::list<ArServerClientData *>::iterator it;
00124   ArServerClientData *data;
00125   ArServerData *serverData;
00126   while ((it = myRequested.begin()) != myRequested.end())
00127   {
00128     data = (*it);
00129     serverData = (*it)->getServerData();
00130     myRequested.pop_front();
00131     delete data;
00132     serverData->callRequestChangedFunctor();
00133   }
00134   /* old way
00135   ArUtil::deleteSet(myRequested.begin(), myRequested.end());
00136   myRequested.clear();
00137   */
00138   ArUtil::deleteSetPairs(myTrackingSentMap.begin(), 
00139                          myTrackingSentMap.end());
00140   myTrackingSentMap.clear();
00141 
00142   ArUtil::deleteSetPairs(myTrackingReceivedMap.begin(), 
00143                          myTrackingReceivedMap.end());
00144   myTrackingReceivedMap.clear();
00145 }
00146 
00147 void ArServerClient::internalSwitchState(ServerState state)
00148 {
00149   myState = state;
00150   myStateStart.setToNow();
00151 }
00152 
00153 AREXPORT bool ArServerClient::tcpCallback(void)
00154 {
00155   if (myState == STATE_REJECTED)
00156   {
00157     myTcpSender.sendData();
00158     ArUtil::sleep(10);
00159     return false;
00160   }
00161 
00162   if (myState == STATE_DISCONNECTED)
00163     return false;
00164 
00165   if (!myTcpReceiver.readData())
00166   {
00167     ArLog::log(ArLog::Verbose, "Trouble receiving tcp data from %s",
00168                myTcpSocket.getIPString());
00169     return false;
00170   }
00171   if (!myTcpSender.sendData())
00172   {
00173     ArLog::log(ArLog::Verbose, "Trouble sending tcp data to %s", myTcpSocket.getIPString());
00174     return false;
00175   }
00176   return true;
00177 }
00178 
00179 AREXPORT void ArServerClient::handleRequests(void)
00180 {
00181   std::list<ArServerClientData *>::iterator it;
00182   ArServerClientData *data;  
00183   ArServerData *serverData;
00184   ArTime lastSent;
00185   
00186   // walk through our list
00187   for (it = myRequested.begin(); it != myRequested.end(); ++it)
00188   {
00189     data = (*it);
00190     lastSent = data->getLastSent();
00191     // see if this needs to be called
00192     if (data->getMSec() != -1 && 
00193         (data->getMSec() == 0 || lastSent.mSecSince() > data->getMSec()))
00194     {
00195       serverData = data->getServerData();
00196       // call it, then set it so we know we did
00197       pushCommand(serverData->getCommand());
00198       if (serverData->getFunctor() != NULL)
00199         serverData->getFunctor()->invoke(this, data->getPacket());
00200       popCommand();
00201       data->setLastSentToNow();
00202     }
00203   }
00204 }
00205 
00206 
00207 void ArServerClient::sendListPacket(void)
00208 {
00209   ArNetPacket packet;
00210   std::map<unsigned int, ArServerData *>::iterator it;
00211   unsigned int count;
00212   unsigned int shortLen;
00213   unsigned int longLen;
00214   ArServerData *serverData;
00215 
00216   // First we send a list of numbers, names and descriptions
00217   packet.setCommand(ArServerCommands::LIST);
00218   
00219   // number of entries (we'll overwrite it later with the right number)
00220   shortLen = packet.getLength();
00221   packet.uByte2ToBuf(0);
00222   // loop through the data to build the packet
00223   for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++)
00224   {
00225     serverData = (*it).second;
00226     if (myUserInfo == NULL || 
00227         serverData->getCommandGroup() == NULL || 
00228         serverData->getCommandGroup()[0] == '\0' || 
00229         myGroups.count(serverData->getCommandGroup()) != 0 || 
00230         myGroups.count("all") != 0)
00231     {
00232       count++;
00233       packet.uByte2ToBuf(serverData->getCommand());
00234       packet.strToBuf(serverData->getName());
00235       packet.strToBuf(serverData->getDescription());
00236     }
00237   }
00238   // put the real number of entries in the right spot 
00239   longLen = packet.getLength();
00240   packet.setLength(shortLen);
00241   packet.uByte2ToBuf(count);
00242   packet.setLength(longLen);
00243 
00244   sendPacketTcp(&packet);
00245 
00246   // then we send a list of the arguments and returns... they aren't
00247   // combined so that the packet structure doesn't need to change
00248   packet.empty();
00249   packet.setCommand(ArServerCommands::LISTARGRET);
00250   
00251   // number of entries (we'll overwrite it later with the right number)
00252   shortLen = packet.getLength();
00253   packet.uByte2ToBuf(0);
00254   
00255   // loop through the data to build the packet
00256   for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++)
00257   {
00258     serverData = (*it).second;
00259     if (myUserInfo == NULL || 
00260         serverData->getCommandGroup() == NULL || 
00261         serverData->getCommandGroup()[0] == '\0' || 
00262         myGroups.count(serverData->getCommandGroup()) != 0 || 
00263         myGroups.count("all") != 0)
00264     {
00265       count++;
00266       packet.uByte2ToBuf(serverData->getCommand());
00267       packet.strToBuf(serverData->getArgumentDescription());
00268       packet.strToBuf(serverData->getReturnDescription());
00269     }
00270 
00271   }
00272   // put the real number of entries in the right spot
00273   longLen = packet.getLength();
00274   packet.setLength(shortLen);
00275   packet.uByte2ToBuf(count);
00276   packet.setLength(longLen);
00277   sendPacketTcp(&packet);
00278 
00279 
00280   // then we send a list of command groups... they aren't
00281   // combined so that the packet structure doesn't need to change
00282   packet.empty();
00283   packet.setCommand(ArServerCommands::LISTGROUPANDFLAGS);
00284   
00285   // number of entries (we'll overwrite it later with the right number)
00286   shortLen = packet.getLength();
00287   packet.uByte2ToBuf(0);
00288   
00289   // loop through the data to build the packet
00290   for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++)
00291   {
00292     serverData = (*it).second;
00293     if (myUserInfo == NULL || 
00294         serverData->getCommandGroup() == NULL || 
00295         serverData->getCommandGroup()[0] == '\0' || 
00296         myGroups.count(serverData->getCommandGroup()) != 0 || 
00297         myGroups.count("all") != 0)
00298     {
00299       count++;
00300       packet.uByte2ToBuf(serverData->getCommand());
00301       packet.strToBuf(serverData->getCommandGroup());
00302       packet.strToBuf(serverData->getDataFlagsString());
00303     }
00304 
00305   }
00306   // put the real number of entries in the right spot
00307   longLen = packet.getLength();
00308   packet.setLength(shortLen);
00309   packet.uByte2ToBuf(count);
00310   packet.setLength(longLen);
00311   sendPacketTcp(&packet);
00312 }
00313 
00314 AREXPORT void ArServerClient::processPacket(ArNetPacket *packet, bool tcp)
00315 {
00316   std::string str;
00317   struct sockaddr_in sin;
00318   unsigned int clientUdpPort;
00319   ArNetPacket retPacket;
00320 
00321   //printf("Command number %d\n", packet->getCommand());
00322   // if we're in intro mode and received back the intro
00323   if (myState == STATE_SENT_INTRO && 
00324       packet->getCommand() == ArClientCommands::INTRODUCTION)
00325   {
00326     char user[512];
00327     unsigned char password[16];
00328     clientUdpPort = packet->bufToUByte2();
00329     packet->bufToStr(user, sizeof(user));
00330     packet->bufToData((char *)password, 16);
00331 
00332     if (myRejecting != 0)
00333     {
00334       retPacket.empty();
00335       retPacket.setCommand(ArServerCommands::REJECTED);
00336       retPacket.byte2ToBuf(myRejecting);
00337       retPacket.strToBuf(myRejectingString.c_str());
00338       sendPacketTcp(&retPacket);
00339       if (myRejecting == 2)
00340         ArLog::log(ArLog::Normal, 
00341    "Rejected connection from %s since we're using a central server at %s",
00342                    myTcpSocket.getIPString(), myRejectingString.c_str());
00343       internalSwitchState(STATE_REJECTED);
00344       return;
00345     }
00346 
00347     // if user info is NULL we're not checking passwords
00348     if (myUserInfo != NULL && 
00349         !myUserInfo->matchUserPassword(user, password, myPasswordKey.c_str(),
00350                                        myServerKey.c_str()))
00351     {
00352       retPacket.empty();
00353       retPacket.setCommand(ArServerCommands::REJECTED);
00354       retPacket.byte2ToBuf(1);
00355       retPacket.strToBuf("");
00356       sendPacketTcp(&retPacket);
00357       ArLog::log(ArLog::Normal, "Rejected user '%s' or password from %s",
00358                  user, myTcpSocket.getIPString());
00359       internalSwitchState(STATE_REJECTED);
00360       return;
00361     }
00362     if (myUserInfo != NULL)
00363       myGroups = myUserInfo->getUsersGroups(user);
00364     else
00365       myGroups.clear();
00366     sin.sin_family = AF_INET;
00367     sin.sin_addr = *myTcpSocket.inAddr();
00368     sin.sin_port = ArSocket::hostToNetOrder(clientUdpPort);
00369     if (myUserInfo != NULL)
00370       ArLog::log(ArLog::Normal, 
00371                  "Client connected from %s with user %s", 
00372                  myTcpSocket.getIPString(), user);
00373     else
00374       ArLog::log(ArLog::Normal, 
00375                  "Client connected from %s", myTcpSocket.getIPString());
00376 
00377     setUdpAddress(&sin);
00378     // send that we've connected
00379     retPacket.empty();
00380     retPacket.setCommand(ArServerCommands::CONNECTED);
00381     sendPacketTcp(&retPacket);
00382     // note that we're connected
00383     internalSwitchState(STATE_CONNECTED);
00384 
00385     // send them the list
00386     sendListPacket();
00387     // send the udp introduction
00388     retPacket.empty();
00389     retPacket.setCommand(ArServerCommands::UDP_INTRODUCTION);
00390     retPacket.byte4ToBuf(myIntroKey);
00391     sendPacketUdp(&retPacket);
00392   }
00393   // if we aren't in intro mode and got an intro somethings wrong
00394   else if (packet->getCommand() == ArClientCommands::INTRODUCTION)
00395   {
00396     ArLog::log(ArLog::Terse, 
00397                "ArServerClient: Received introduction when not in intro mode");
00398     return;
00399   }
00400   // if we got this over tcp then they only want tcp
00401   else if (packet->getCommand() == ArClientCommands::UDP_INTRODUCTION)
00402   {
00403     if (!myTcpOnly)
00404     {
00405       ArLog::log(ArLog::Normal, "ArServerClient: Got UDP introduction over tcp, assuming client only wants tcp data.");
00406       myTcpOnly = true;
00407     }
00408     return;
00409   }
00410   // if we're connected and got a udp confirmation
00411   else if ((myState == STATE_CONNECTED || 
00412             myState == STATE_SENT_INTRO) && 
00413            packet->getCommand() == ArClientCommands::UDP_CONFIRMATION)
00414   {
00415     myUdpConfirmedTo = true;
00416     ArLog::log(ArLog::Verbose, "Server's udp connection to client confirmed.");
00417     return;
00418   }
00419   // if we're not connected (or close) and got a confirmation
00420   else if (packet->getCommand() == ArClientCommands::UDP_CONFIRMATION)
00421   {
00422     ArLog::log(ArLog::Normal, "ArServerClient: Received udp confirmation when not connected.");
00423     return;
00424   }
00425   else if (packet->getCommand() == ArClientCommands::TCP_ONLY)
00426   {
00427     ArLog::log(ArLog::Verbose, "ArServerClient: Client only wants tcp data.");
00428     myTcpOnly = true;
00429     return;
00430   }
00431   else if (packet->getCommand() == ArClientCommands::SHUTDOWN)
00432   {
00433     ArLog::log(ArLog::Normal, "Client from %s has disconnected.",
00434                myTcpSocket.getIPString());
00435     internalSwitchState(STATE_DISCONNECTED);
00436     return;
00437   }
00438   // if we're connected its a request, then set all that up
00439   else if (myState == STATE_CONNECTED && 
00440            packet->getCommand() == ArClientCommands::REQUEST)
00441   {
00442     std::list<ArServerClientData *>::iterator it;
00443     ArServerClientData *data;
00444     ArServerData *serverData;
00445     unsigned int command;
00446     long mSec;
00447     // see which one they requested
00448     command = packet->bufToUByte2();
00449     mSec = packet->bufToByte4();
00450 
00451     // first we see if we already have this one
00452     for (it = myRequested.begin(); it != myRequested.end(); ++it)
00453     {
00454       data = (*it);
00455       serverData = data->getServerData();
00456       if (serverData->getCommand() == command)
00457       {
00458         trackPacketReceived(packet, command, true);
00459         data->setMSec(mSec);
00460         data->setPacket(packet);
00461         data->getPacket()->setCommand(command);
00462         serverData->callRequestChangedFunctor();
00463         ArLog::log(ArLog::Verbose, "ArServerClient: revised request for command %d to %d mSec with new argument", serverData->getCommand(), mSec);
00464         return;
00465       }
00466     }
00467     // we didn't have it, so make a new one
00468     std::map<unsigned int, ArServerData *>::iterator sdit;
00469     if ((sdit = myDataMap->find(command)) == myDataMap->end())
00470     {
00471       ArLog::log(ArLog::Terse, 
00472               "ArServerClient got request for command %d which doesn't exist", 
00473                  command);
00474       return;
00475     }
00476     serverData = (*sdit).second;
00477     if (serverData == NULL) 
00478     {
00479       ArLog::log(ArLog::Terse, "ArServerClient::processPackets request handler has NULL serverData\n");
00480     }
00481     if (myUserInfo != NULL && 
00482         serverData->getCommandGroup() != NULL &&
00483         serverData->getCommandGroup()[0] != '\0' &&
00484         myGroups.count(serverData->getCommandGroup()) == 0 &&
00485         myGroups.count("all") == 0)
00486     {
00487       ArLog::log(ArLog::Normal, 
00488                  "ArServerClient: %s tried to request command '%s' but it doesn't have access to that command", 
00489                  myTcpSocket.getIPString(), 
00490                  serverData->getName());
00491       return;
00492     }
00493     trackPacketReceived(packet, command, true);
00494     data = new ArServerClientData(serverData, mSec, packet);
00495     data->getPacket()->setCommand(command);
00496     ArLog::log(ArLog::Verbose, "ArServerClient: added request for command %s every %d mSec", serverData->getName(), mSec);
00497     if (mSec == 0)
00498       ArLog::log(ArLog::Normal, "ArServerClient: client from %s requested command %s every at 0 msec", myTcpSocket.getIPString(), serverData->getName());
00499     myRequested.push_front(data);
00500     serverData->callRequestChangedFunctor();
00501     pushCommand(command);
00502     if (serverData->getFunctor() != NULL)
00503       serverData->getFunctor()->invoke(this, data->getPacket());
00504     popCommand();
00505     return;
00506   }
00507   // if we got a request when we're not connected
00508   else if (packet->getCommand() == ArClientCommands::REQUEST)
00509   {
00510     ArLog::log(ArLog::Normal, 
00511                "ArServerClient got a request while not connected.\n");
00512     return;
00513   }
00514   // if we're connected its a requestStop, then set all that up
00515   else if (myState == STATE_CONNECTED && 
00516            packet->getCommand() == ArClientCommands::REQUESTSTOP)
00517   {
00518     std::list<ArServerClientData *>::iterator it;
00519     ArServerClientData *data;
00520     ArServerData *serverData;
00521     unsigned int command;
00522     // see which one they requested
00523     command = packet->bufToUByte2();
00524 
00525     // first we see if we have this one
00526     for (it = myRequested.begin(); it != myRequested.end(); ++it)
00527     {
00528       data = (*it);
00529       serverData = data->getServerData();
00530       // we have a match, so set the new params then return
00531       if (data->getServerData()->getCommand() == command)
00532       {
00533         trackPacketReceived(packet, command, true);
00534         myRequested.erase(it);
00535         ArLog::log(ArLog::Verbose, "ArServerClient: stopped request for command %d", serverData->getCommand());
00536         delete data;
00537         serverData->callRequestChangedFunctor();
00538         return;
00539       }
00540     }
00541     // if we don't have it... that means that it wasn't here
00542     
00543     // find out what to call it
00544     std::map<unsigned int, ArServerData *>::iterator sdit;
00545     if ((sdit = myDataMap->find(command)) == myDataMap->end())
00546     {
00547       ArLog::log(ArLog::Terse, 
00548               "ArServerClient got a requeststop for command %d which doesn't exist", 
00549                  command);
00550       return;
00551     }
00552     trackPacketReceived(packet, command, true);
00553     serverData = (*sdit).second;
00554     if (serverData == NULL) 
00555       ArLog::log(ArLog::Terse, "ArServerClient::processPackets requeststop handler has NULL serverData on back command %d", command);
00556     else
00557       ArLog::log(ArLog::Normal, "ArServerClient: got a stop request for command %s that isn't requested", serverData->getName());
00558     return;
00559   }
00560   // if we got a requestStop when we're not connected
00561   else if (packet->getCommand() == ArClientCommands::REQUESTSTOP)
00562   {
00563     ArLog::log(ArLog::Normal, 
00564                "ArServerClient got a requeststop while not connected.\n");
00565     return;
00566   }
00567   // if we're connected and its a command to execute just once
00568   else if (myState == STATE_CONNECTED)
00569   {
00570     unsigned int command;
00571     std::map<unsigned int, ArServerData *>::iterator it;
00572     ArServerData *serverData;
00573 
00574     command = packet->getCommand();
00575     if ((it = myDataMap->find(command)) == myDataMap->end())
00576     {
00577       ArLog::log(ArLog::Terse, 
00578               "ArServerClient got request for command %d which doesn't exist", 
00579                  command);
00580       return;
00581     }
00582     serverData = (*it).second;
00583     if (myUserInfo != NULL && 
00584         serverData->getCommandGroup() != NULL &&
00585         serverData->getCommandGroup()[0] != '\0' &&
00586         myGroups.count(serverData->getCommandGroup()) == 0 &&
00587         myGroups.count("all") == 0)
00588     {
00589       ArLog::log(ArLog::Normal, 
00590                  "ArServerClient: %s tried to request command '%s' once but it doesn't have access to that command", 
00591                  myTcpSocket.getIPString(), 
00592                  serverData->getName());
00593       return;
00594     }
00595     trackPacketReceived(packet, command, true);
00596     ArLog::log(ArLog::Verbose, "ArServerClient got command %s", (*it).second->getName());
00597     pushCommand(command);
00598     if (serverData->getFunctor() != NULL)
00599       serverData->getFunctor()->invoke(this, packet);
00600     if (serverData->getRequestOnceFunctor() != NULL)
00601       serverData->getRequestOnceFunctor()->invoke(this, packet);
00602     popCommand();
00603     return;
00604   }
00605   else
00606   {
00607     ArLog::log(ArLog::Terse, 
00608                "ArServerClient: rogue packet command %u in state %d", 
00609                packet->getCommand(), myState);
00610   }
00611 }
00612 
00613 AREXPORT void ArServerClient::forceDisconnect(bool quiet)
00614 {
00615   if (!quiet)
00616     ArLog::log(ArLog::Normal, "Client from %s has been forcibly disconnected.",
00617                myTcpSocket.getIPString());
00618   internalSwitchState(STATE_DISCONNECTED);
00619 }
00620 
00621 AREXPORT void ArServerClient::processAuthPacket(ArNetPacket *packet, 
00622                                        struct sockaddr_in *sin)
00623 {
00624   ArNetPacket retPacket;
00625   long authKey;
00626   // check the auth key again, just in case
00627 
00628   authKey = packet->bufToUByte4();
00629   if (authKey != myAuthKey)
00630   {
00631     ArLog::log(ArLog::Terse, "ArServerClient: authKey given does not match actual authKey, horrible error.");
00632     return;
00633   }
00634   
00635   if (mySin.sin_port != sin->sin_port)
00636   {
00637     ArLog::log(ArLog::Verbose, 
00638                "Client says it is using port %u but is using port %u\n", 
00639                ArSocket::netToHostOrder(mySin.sin_port),
00640                ArSocket::netToHostOrder(sin->sin_port));
00641   }
00642   myUdpConfirmedFrom = true;
00643   mySin.sin_port = sin->sin_port;
00644   ArLog::log(ArLog::Verbose, "Client connected to server on udp port %u", 
00645              ArSocket::netToHostOrder(mySin.sin_port));
00646   // TODO put some state info here to note that its fully udp connected
00647   retPacket.empty();
00648   retPacket.setCommand(ArServerCommands::UDP_INTRODUCTION);
00649   retPacket.byte4ToBuf(myIntroKey);
00650   sendPacketUdp(&retPacket);
00651   retPacket.empty();
00652   retPacket.setCommand(ArServerCommands::UDP_CONFIRMATION);
00653   sendPacketTcp(&retPacket);
00654 }
00655 
00656 AREXPORT void ArServerClient::broadcastPacketTcp(ArNetPacket *packet)
00657 {
00658   std::list<ArServerClientData *>::iterator it;
00659   ArServerClientData *data;  
00660   ArServerData *serverData;
00661   ArTime lastSent;
00662 
00663   // walk through our list
00664   for (it = myRequested.begin(); it != myRequested.end(); ++it)
00665   {
00666     data = (*it);
00667     serverData = data->getServerData();
00668     // see if this is our data, if it is send the packet
00669     if (serverData->getCommand() == packet->getCommand())
00670     {
00671       sendPacketTcp(packet);
00672       return;
00673     }
00674   }
00675   // we didn't have the data to send
00676 }
00677 
00678 AREXPORT void ArServerClient::broadcastPacketUdp(ArNetPacket *packet)
00679 {
00680   std::list<ArServerClientData *>::iterator it;
00681   ArServerClientData *data;  
00682   ArServerData *serverData;
00683   ArTime lastSent;
00684   
00685   // walk through our list
00686   for (it = myRequested.begin(); it != myRequested.end(); ++it)
00687   {
00688     data = (*it);
00689     serverData = data->getServerData();
00690     // see if this is our data, if it is send the packet
00691     if (serverData->getCommand() == packet->getCommand())
00692     {
00693       sendPacketUdp(packet);
00694       return;
00695     }
00696   }
00697   // we didn't have the data to send
00698 }
00699 
00700 AREXPORT bool ArServerClient::sendPacketTcp(ArNetPacket *packet)
00701 {
00702   if (!setupPacket(packet))
00703     return false;
00704   else
00705   {
00706     trackPacketSent(packet, true);
00707     myTcpSender.sendPacket(packet);
00708     return true;
00709   }
00710 }
00711 
00712 AREXPORT bool ArServerClient::sendPacketUdp(ArNetPacket *packet)
00713 {
00714   if (myTcpOnly)
00715     return sendPacketTcp(packet);
00716   
00717   if (!setupPacket(packet))
00718     return false;
00719   else if (mySendUdpCB != NULL)
00720   {
00721     trackPacketSent(packet, false);
00722     return mySendUdpCB->invokeR(packet, &mySin);
00723   }
00724   else
00725     return false;
00726 }
00727 
00728 AREXPORT  bool ArServerClient::setupPacket(ArNetPacket *packet)
00729 {
00730   if (myState == STATE_DISCONNECTED)
00731     return false;
00732 
00733   if (packet->getCommand() == 0)
00734   {
00735    if (getCommand() != 0)
00736      packet->setCommand(getCommand());
00737    else
00738      ArLog::log(ArLog::Terse, "ArServerClient::sendPacket: packet to send has no command and we have no command in the stack");
00739   }
00740   packet->finalizePacket();
00741   return true;
00742 } 
00743 
00744 
00745 AREXPORT void ArServerClient::setUdpAddress(struct sockaddr_in *sin)
00746 {
00747   mySin = *sin;
00748 }
00749 
00750 AREXPORT struct sockaddr_in *ArServerClient::getUdpAddress(void)
00751 {
00752   return &mySin;
00753 }
00754 
00755 AREXPORT long ArServerClient::getAuthKey(void)
00756 {
00757   return myAuthKey;
00758 }
00759 
00760 unsigned int ArServerClient::getCommand(void)
00761 {
00762   return myCommandStack.front();
00763 }
00764 
00765 void ArServerClient::pushCommand(unsigned int command)
00766 {
00767   myCommandStack.push_front(command);
00768 }
00769 
00770 void ArServerClient::popCommand(void)
00771 {
00772   if (myCommandStack.size() == 0)
00773   {
00774     ArLog::log(ArLog::Terse, 
00775       "ArServerClient::popCommand: popCommand tried to be called when stack empty.");
00776   }
00777   myCommandStack.pop_front();
00778 }
00779 
00780 AREXPORT void ArServerClient::shutdown(void)
00781 {
00782   ArNetPacket packet;
00783   
00784   packet.setCommand(ArServerCommands::SHUTDOWN);
00785   sendPacketTcp(&packet);
00786   myTcpSender.sendData();
00787 }
00788 
00789 AREXPORT const char *ArServerClient::getIPString(void) const
00790 {
00791   return myTcpSocket.getIPString();
00792 }
00793 
00794 void ArServerClient::trackPacketSent(ArNetPacket *packet, bool tcp)
00795 {
00796   if (myTrackingSentMap.find(packet->getCommand()) == myTrackingSentMap.end())
00797     myTrackingSentMap[packet->getCommand()] = new Tracker;
00798 
00799   if (tcp)
00800   {
00801     myTrackingSentMap[packet->getCommand()]->myPacketsTcp++;
00802     myTrackingSentMap[packet->getCommand()]->myBytesTcp += packet->getLength();
00803   }
00804   else
00805   {
00806     myTrackingSentMap[packet->getCommand()]->myPacketsUdp++;
00807     myTrackingSentMap[packet->getCommand()]->myBytesUdp += packet->getLength();
00808   }
00809 }
00810 
00811 void ArServerClient::trackPacketReceived(ArNetPacket *packet, ArTypes::UByte2 command, bool tcp)
00812 {
00813   if (myTrackingReceivedMap.find(command) == myTrackingReceivedMap.end())
00814     myTrackingReceivedMap[command] = new Tracker;
00815 
00816   if (tcp)
00817   {
00818     myTrackingReceivedMap[command]->myPacketsTcp++;
00819     myTrackingReceivedMap[command]->myBytesTcp += packet->getLength();
00820   }
00821   else
00822   {
00823     myTrackingReceivedMap[command]->myPacketsUdp++;
00824     myTrackingReceivedMap[command]->myBytesUdp += packet->getLength();
00825   }
00826 }
00827 
00828 AREXPORT void ArServerClient::logTracking(bool terse)
00829 {
00830   std::map<ArTypes::UByte2, Tracker *>::iterator it;
00831 
00832   ArTypes::UByte2 command;
00833   Tracker *tracker = NULL;
00834   long seconds;
00835 
00836   seconds = myTrackingStarted.secSince();
00837   if (seconds == 0)
00838     seconds = 1;
00839 
00840   char name[512];
00841 
00842   long packetsReceivedTcp = 0;
00843   long bytesReceivedTcp = 0;
00844   long packetsReceivedUdp = 0;
00845   long bytesReceivedUdp = 0;
00846 
00847   ArLog::log(ArLog::Terse, "");
00848   ArLog::log(ArLog::Terse, "Received tracking for %s (active %d seconds):", 
00849              getIPString(), seconds);
00850   for (it = myTrackingReceivedMap.begin(); it != myTrackingReceivedMap.end(); it++)
00851   {
00852     command = (*it).first;
00853     tracker = (*it).second;
00854 
00855     packetsReceivedTcp += tracker->myPacketsTcp;
00856     bytesReceivedTcp += tracker->myBytesTcp;
00857     packetsReceivedUdp += tracker->myPacketsUdp;
00858     bytesReceivedUdp += tracker->myBytesUdp;
00859 
00860     std::map<unsigned int, ArServerData *>::iterator nameIt;
00861     if ((nameIt = myDataMap->find(command)) != myDataMap->end())
00862       snprintf(name, sizeof(name), "%s", (*nameIt).second->getName());
00863     // if we're command 255 or less and there's no name its probably
00864     // one of the server commands we don't really need to track
00865     else if (command <= 255)
00866       continue;
00867     // we should know what the name of everything other then the
00868     // server command is, but print if we don't, just in case
00869     else
00870       snprintf(name, sizeof(name), "#%d", command);
00871     if (terse)
00872     {
00873       ArLog::log(ArLog::Terse, 
00874                  "%35s %7ld pkts %10ld B %7ld B/sec", 
00875                  name, tracker->myPacketsTcp + tracker->myPacketsUdp, 
00876                  tracker->myBytesTcp + tracker->myBytesUdp,
00877                  ((tracker->myBytesTcp + tracker->myBytesUdp)/
00878                   seconds));
00879     }
00880     else
00881     {
00882       ArLog::log(ArLog::Terse, 
00883          "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", 
00884                  name, tracker->myPacketsTcp, tracker->myBytesTcp, 
00885                  tracker->myBytesTcp/seconds,
00886                  tracker->myPacketsUdp, tracker->myBytesUdp,
00887                  tracker->myBytesUdp/seconds);
00888     }
00889   }
00890   
00891   ArLog::log(ArLog::Terse, "");
00892   if (terse)
00893   {
00894     ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", 
00895                "Total Received", packetsReceivedTcp + packetsReceivedUdp, 
00896                bytesReceivedTcp + bytesReceivedUdp,
00897                (bytesReceivedTcp + bytesReceivedUdp) / seconds);
00898   }
00899   else
00900   {
00901     ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec",  
00902                "Total Received", packetsReceivedTcp, bytesReceivedTcp, 
00903                bytesReceivedTcp/seconds, packetsReceivedUdp, bytesReceivedUdp, 
00904                bytesReceivedUdp/seconds);
00905     ArLog::log(ArLog::Terse, "%-35s %7ld tcp rcvs %10ld tcp B %7ld tcp B/S",
00906                "Low level TCP Received", myTcpSocket.getRecvs(), 
00907                myTcpSocket.getBytesRecvd(), 
00908                myTcpSocket.getBytesRecvd()/seconds);
00909   }
00910 
00911   long packetsSentTcp = 0;
00912   long bytesSentTcp = 0;
00913   long packetsSentUdp = 0;
00914   long bytesSentUdp = 0;
00915 
00916   ArLog::log(ArLog::Terse, "");
00917   ArLog::log(ArLog::Terse, "Sent tracking for %s (active %d seconds):", 
00918              getIPString(), seconds);
00919   for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++)
00920   {
00921     command = (*it).first;
00922     tracker = (*it).second;
00923 
00924     packetsSentTcp += tracker->myPacketsTcp;
00925     bytesSentTcp += tracker->myBytesTcp;
00926     packetsSentUdp += tracker->myPacketsUdp;
00927     bytesSentUdp += tracker->myBytesUdp;
00928 
00929     std::map<unsigned int, ArServerData *>::iterator nameIt;
00930     if ((nameIt = myDataMap->find(command)) != myDataMap->end())
00931       snprintf(name, sizeof(name), "%s", (*nameIt).second->getName());
00932     // if we're command 255 or less and there's no name its probably
00933     // one of the server commands we don't really need to track
00934     else if (command <= 255)
00935       continue;
00936     // we should know what the name of everything other then the
00937     // server command is, but print if we don't, just in case
00938     else
00939       snprintf(name, sizeof(name), "#%d", command);
00940     if (terse)
00941     {
00942       ArLog::log(ArLog::Terse, 
00943                  "%35s %7ld pkts %10ld B %7ld B/sec", 
00944                  name, tracker->myPacketsTcp + tracker->myPacketsUdp, 
00945                  tracker->myBytesTcp + tracker->myBytesUdp,
00946                  ((tracker->myBytesTcp + tracker->myBytesUdp)/
00947                   seconds));
00948     }
00949     else
00950     {
00951       ArLog::log(ArLog::Terse, 
00952          "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", 
00953                  name, tracker->myPacketsTcp, tracker->myBytesTcp, 
00954                  tracker->myBytesTcp/seconds,
00955                  tracker->myPacketsUdp, tracker->myBytesUdp,
00956                  tracker->myBytesUdp/seconds);
00957     }
00958   }
00959 
00960   ArLog::log(ArLog::Terse, "");
00961   if (terse)
00962   {
00963     ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", 
00964                "Total Sent", packetsSentTcp + packetsSentUdp, 
00965                bytesSentTcp + bytesSentUdp,
00966                (bytesSentTcp + bytesSentUdp) / seconds);    
00967     ArLog::log(ArLog::Terse, "");
00968     ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", 
00969                "Total Sent and Received", 
00970                (packetsSentTcp + packetsSentUdp + 
00971                 packetsReceivedTcp + packetsReceivedUdp),
00972                (bytesSentTcp + bytesSentUdp + 
00973                 bytesReceivedTcp + bytesReceivedUdp),
00974                (bytesSentTcp + bytesSentUdp + 
00975                 bytesReceivedTcp + bytesReceivedUdp) / seconds);
00976   }
00977   else
00978   {
00979     ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec",  
00980                "Total Sent", packetsSentTcp, bytesSentTcp, 
00981                bytesSentTcp / seconds,
00982                packetsSentUdp, bytesSentUdp, bytesSentUdp / seconds);
00983     ArLog::log(ArLog::Terse, "%-35s %7ld tcp snds %10ld tcp B %7ld tcp B/S",
00984                "Low level TCP Sent", myTcpSocket.getSends(), 
00985                myTcpSocket.getBytesSent(), 
00986                myTcpSocket.getBytesSent() / seconds);
00987 
00988     ArLog::log(ArLog::Terse, "");
00989     ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec",  
00990                "Total Sent and Received", packetsSentTcp = packetsReceivedTcp, 
00991                bytesSentTcp + bytesReceivedTcp, 
00992                (bytesSentTcp + bytesReceivedTcp) / seconds,
00993                packetsSentUdp + packetsReceivedUdp, 
00994                bytesSentUdp + bytesReceivedUdp, 
00995                (bytesSentUdp + bytesReceivedUdp) / seconds);
00996   }
00997 
00998   ArLog::log(ArLog::Terse, "");
00999 }
01000 
01001 
01002 AREXPORT void ArServerClient::resetTracking(void)
01003 {
01004   std::map<ArTypes::UByte2, Tracker *>::iterator it;
01005 
01006   myTrackingStarted.setToNow();
01007 
01008   for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++)
01009     (*it).second->reset();
01010 
01011   for (it = myTrackingReceivedMap.begin(); 
01012        it != myTrackingReceivedMap.end(); 
01013        it++)
01014     (*it).second->reset();
01015 
01016   myTcpSocket.resetTracking();
01017 }
01018 
01019 AREXPORT bool ArServerClient::hasGroupAccess(const char *group)
01020 {
01021   if (myUserInfo == NULL || group == NULL || group[0] == '\0' || 
01022       myGroups.count(group) > 0 || myGroups.count("all") > 0)
01023     return true;
01024   else
01025     return false;  
01026 }
01027 
01037 AREXPORT long ArServerClient::getFrequency(ArTypes::UByte2 command)
01038 {
01039   std::list<ArServerClientData *>::iterator it;
01040   ArServerClientData *data;  
01041   ArServerData *serverData;
01042   
01043   // walk through our list
01044   for (it = myRequested.begin(); it != myRequested.end(); ++it)
01045   {
01046     data = (*it);
01047     serverData = data->getServerData();
01048     // see if this is our data, if it is send the packet
01049     if (serverData->getCommand() == command)
01050     {
01051       if (data->getMSec() >= 0)
01052         return data->getMSec();
01053       else
01054         return -1;
01055     }
01056   }
01057   return -2;
01058 }

Generated on Tue Feb 20 10:51:50 2007 for ArNetworking by  doxygen 1.4.0