Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

XFuInetNetwork.cpp

Go to the documentation of this file.
00001 /*!
00002  * \file
00003  * X-Forge Engine <br>
00004  * Copyright 2000-2002 Fathammer Ltd
00005  *
00006  * \brief Default implementation for a inet communication manager.
00007  *
00008  * $Id: XFuInetNetwork.cpp,v 1.3 2003/10/08 11:08:34 slehti Exp $
00009  * $Date: 2003/10/08 11:08:34 $
00010  * $Revision: 1.3 $
00011  */
00012 
00013 #include <xforge.h>
00014 
00015 #include <xfcore/net/XFcInetHandler.h>
00016 #include <xfcore/net/XFcInetClientWin.h>
00017 #include <xfcore/net/XFcObjectDataFrame.h>
00018 #include <xfcore/net/XFcCommunicationScheduler.h>
00019 #include <xfcore/net/XFcCommunicationConstants.h>
00020 #include <xfcore/net/socket/XFcSocketConstants.h>
00021 #include <xfcore/net/XFcUnknownSender.h>
00022 #include <xfcore/net/XFcClientLost.h>
00023 #include <xfcore/net/XFcDataReceiver.h>
00024 #include <xfcore/net/XFcObjectDataFrame.h>
00025 #include <xfcore/net/socket/XFcInetHostEntry.h>
00026 #include <xfcore/net/socket/XFcInetHostResolver.h>
00027 #include <xfcore/net/socket/XFcInetAdvertiser.h>
00028 #include <xfcore/net/XFcUdpEngine.h>
00029 #include <xfcore/net/socket/XFcInetCommService.h>
00030 
00031 #include <xfutil/XFuSerializable.h>
00032 #include <xfutil/XFuNetwork.h>
00033 #include <xfutil/XFuNetworkEventHandler.h>
00034 #include <xfutil/XFuInetNetwork.h>
00035 
00036 
00037 //! Static constructor
00038 XFuInetNetwork * XFuInetNetwork::create()
00039 {
00040     XFuInetNetwork * manager = new XFuInetNetwork;
00041     if (manager != NULL && !manager->init())
00042     {
00043         delete manager;
00044         return NULL;
00045     }
00046     return manager;
00047 }
00048 
00049 
00050 //! Protected constructor
00051 XFuInetNetwork::XFuInetNetwork()
00052 {
00053     mNetworkEventHandlers = NULL;
00054     mCommunicationScheduler = NULL;
00055     mCommunicationHandler = NULL;
00056 
00057     mAdvertiserStatus = 0;
00058 
00059     mHostResolver = NULL;
00060     mMaxClients = -1;
00061     mAcceptGameToken = 0;
00062 
00063     mCommunicationHandlerId = -1;
00064 
00065     mCommService = NULL;
00066 
00067 }
00068 
00069 
00070 //! Destructor
00071 XFuInetNetwork::~XFuInetNetwork()
00072 {
00073     closeService();
00074     deleteAllClients();
00075     removeAllEventHandlers();
00076 
00077     delete mHostResolver;
00078     delete mNetworkEventHandlers;
00079     delete mCommunicationHandler;
00080     delete mCommService;
00081 
00082 }
00083 
00084 
00085 //! Initializes default communication manager specific items that would normally be in the constructor
00086 INT XFuInetNetwork::init()
00087 {
00088 
00089     mCommunicationScheduler = (XFcCommunicationScheduler *)XFcCore::getCommunicationScheduler();
00090     if (mNetworkEventHandlers == NULL)
00091         mNetworkEventHandlers = XFuDynamicArray<XFuNetworkEventHandler*>::create(5);
00092 
00093     if (mCommunicationScheduler == NULL ||
00094         mNetworkEventHandlers == NULL) return 0;
00095 
00096     return 1;
00097 
00098 }
00099 
00100 
00101 //! Runs the communication scheduler
00102 void XFuInetNetwork::runCommunicationScheduler()
00103 {
00104     mCommunicationScheduler->runScheduler();
00105 }
00106 
00107 
00108 //! Resets the communication manager
00109 void XFuInetNetwork::reset()
00110 {
00111     closeService();
00112     removeAllClients();
00113     removeAllEventHandlers();
00114     mMaxClients = -1;
00115     mAcceptGameToken = 0;
00116     init();
00117 }
00118 
00119 
00120 
00121 //! Enables the inet communication handler and opens it for service. Use port 0 for random port.
00122 //! Default speed is one of the XFCNET_CONNECTION_SPEED values (see XFcClientCommWin.h)
00123 INT XFuInetNetwork::enableService(INT32 aMaxClients, UINT16 aPort, INT32 aDefaultSpeed)
00124 {
00125     closeService();
00126     removeAllClients();
00127     
00128 
00129     mCommunicationHandler = XFcInetHandler::create();
00130     mCommService = XFcInetCommService::create();
00131 
00132     if (mCommunicationHandler && mCommService)
00133     {
00134 
00135         if (aPort != 0)
00136             mCommunicationHandler->setPort(aPort);
00137 
00138         mGamePort = aPort;
00139 
00140         mCommunicationHandler->setConnectionSpeed(aDefaultSpeed);
00141         mCommunicationHandler->setUnknownSenderHandler(this);
00142         mCommunicationHandler->setClientLost(this);
00143         mCommunicationHandler->setMaxClientCount(aMaxClients);
00144 
00145         initClients(aMaxClients);
00146 
00147         mCommunicationHandlerId = mCommunicationScheduler->addCommunicationHandler(mCommunicationHandler);
00148         mCommunicationHandler->openService();
00149 
00150         if (mCommunicationHandler->getLastError() != XFcUdpEngine::XFCNET_UDP_CLOSE)
00151             return 1;
00152     }
00153     return 0;
00154 }
00155 
00156 
00157 //! Closes the currently active service (communication handler)
00158 void XFuInetNetwork::closeService()
00159 {
00160 
00161     stopAdvertiser();
00162     stopServerDiscovery();
00163 
00164     if (mCommunicationHandler)
00165     {
00166         mCommunicationHandler->closeService();
00167         mCommunicationScheduler->removeCommunicationHandler(mCommunicationHandlerId);
00168         delete mCommunicationHandler;
00169         mCommunicationHandler = NULL;
00170     }
00171 
00172     delete mHostResolver;
00173     mHostResolver = NULL;
00174     delete mCommService;
00175     mCommService = NULL;
00176 
00177 }
00178 
00179 
00180 //! Returns the game token that is checked before new clients are allowed to connect
00181 UINT32 XFuInetNetwork::getAcceptGameToken()
00182 {
00183     return mAcceptGameToken;
00184 }
00185 
00186 //! Sets the game token that is checked before new clients are allowed to connect
00187 void XFuInetNetwork::setAcceptGameToken(UINT32 aAcceptGameToken)
00188 {
00189     mAcceptGameToken = aAcceptGameToken;
00190 }
00191 
00192 
00193 //! Sends a game connection packet
00194 void XFuInetNetwork::sendGameConnectPacket(INT32 aClientId, UINT32 aGameToken)
00195 {
00196     XFcObjectDataFrame *frame = getPacketFrame(aClientId, XFCNET_NONGUARANTEED);
00197     if (frame)
00198     {
00199 
00200         frame->setReceiverId(0);
00201         void *buffer = frame->lock();
00202         if (buffer)
00203         {
00204             memcpy(buffer, &aGameToken, 4);
00205             frame->setPacketSize(4);
00206         }
00207         frame->unlock();
00208     }
00209 
00210 }
00211 
00212 
00213 //! Reserves memory for the client array (mClients) and initializes all the client
00214 //! pointers to NULL
00215 void XFuInetNetwork::initClients(INT32 aMaxClients)
00216 {
00217     mMaxClients = aMaxClients;
00218 }
00219 
00220 
00221 //! Cleanup of all clients
00222 void XFuInetNetwork::deleteAllClients()
00223 {
00224 
00225     XFcHashtableIterator<UINT32, XFcInetClientWin *> itClient;
00226 
00227      while (mClients.size() > 0)
00228      {
00229          itClient = mClients.begin();
00230          INT32 key = itClient.getKey();
00231          XFcClientCommWin *base_client = getClient(key);
00232          mCommunicationScheduler->removeClient(key);
00233          base_client->deinitializeClient();
00234          mClients.remove(key);
00235          delete base_client;
00236      }
00237 }
00238 
00239 //! Removes all clients and frees the memory reserved by the clients and the client array  (mClients)
00240 void XFuInetNetwork::removeAllClients()
00241 {
00242 
00243     XFcHashtableIterator<UINT32, XFcInetClientWin *> itClient;
00244 
00245     if (!mCommunicationHandler)
00246         return;
00247 
00248     while (mClients.size() > 0)
00249     {
00250         itClient = mClients.begin();
00251         INT32 key = itClient.getKey();
00252         removeClient(key);
00253     }
00254 }
00255 
00256 
00257 //! Returns a pointer to the default data receiver
00258 XFcDataReceiver * XFuInetNetwork::getDefaultDataReceiver()
00259 {
00260     return mDefaultDataReceiver;
00261 }
00262 
00263 
00264 //! Sets the default data receiver
00265 void XFuInetNetwork::setDefaultDataReceiver(XFcDataReceiver *aReceiver)
00266 {
00267     mDefaultDataReceiver = aReceiver;
00268     mCommunicationScheduler->setDataReceiver(aReceiver);
00269 }
00270 
00271 
00272 //! Returns the specified data receiver
00273 XFcDataReceiver * XFuInetNetwork::getDataReceiver(UINT32 aId)
00274 {
00275     return mCommunicationScheduler->getDataReceiver(aId);
00276 }
00277 
00278 
00279 //! Adds a new data receiver
00280 INT XFuInetNetwork::addDataReceiver(UINT32 aId, XFcDataReceiver *aReceiver)
00281 {
00282     return mCommunicationScheduler->addDataReceiver(aId, aReceiver);
00283 }
00284 
00285 
00286 //! Removes a data receiver
00287 XFcDataReceiver * XFuInetNetwork::removeDataReceiver(UINT32 aId)
00288 {
00289     return mCommunicationScheduler->removeDataReceiver(aId);
00290 }
00291 
00292 
00293 //! Adds a communication event handler
00294 void XFuInetNetwork::addEventHandler(XFuNetworkEventHandler *aHandler)
00295 {
00296     mNetworkEventHandlers->put(aHandler);
00297 }
00298 
00299 
00300 //! Removes a communication event handler
00301 void XFuInetNetwork::removeEventHandler(XFuNetworkEventHandler *aHandler)
00302 {
00303     mNetworkEventHandlers->remove(aHandler);
00304 }
00305 
00306 
00307 //! Removes all communication event handlers
00308 void XFuInetNetwork::removeAllEventHandlers()
00309 {
00310     while (!mNetworkEventHandlers->isEmpty()) mNetworkEventHandlers->remove();
00311 }
00312 
00313 
00314 //! Returns the specified client
00315 XFcClientCommWin * XFuInetNetwork::getClient(INT32 aClientId)
00316 {
00317     XFcHashtable<UINT32, XFcInetClientWin *>::iterator it;
00318     XFcClientCommWin * value = NULL;
00319 
00320     it = mClients.find(aClientId);
00321 
00322     if(it.isValid())
00323     {
00324         value = it.getValue();
00325     }
00326 
00327     return value;
00328 
00329 }
00330 
00331 
00332 //! Adds a client with the specific address. Returns the client id or XFCNET_CLIENTADD_ERROR if failed
00333 INT32 XFuInetNetwork::addClient(XFcAddress *aAddress, INT32 aTimeoutTime)
00334 {
00335     XFcInetClientWin *client = NULL;
00336     INT32 clientId = -1;
00337 
00338     if (aAddress->getType() != (INT32)XFCNET_AFINET)
00339         return 0;
00340 
00341     if ((client = XFcInetClientWin::create()) != NULL)
00342     {
00343         client->setAddress(*aAddress);
00344         client->setConnectionTimeout(aTimeoutTime);
00345 
00346         if (((clientId = mCommunicationScheduler->addClient(client)) != XFCNET_CLIENTADD_ERROR &&
00347              clientId != XFCNET_ERROR) &&
00348             mClients.put(clientId, client))
00349         {
00350              return clientId;
00351         }
00352     }
00353     delete client;
00354     return 0;
00355 }
00356 
00357 
00358 //! Removes the specified client
00359 void XFuInetNetwork::removeClient(INT32 aClientId)
00360 {
00361     if (!mCommunicationHandler)
00362         return;
00363 
00364     XFcClientCommWin *client = NULL;
00365 
00366     if ((client = getClient(aClientId)) != NULL)
00367     {
00368         mCommunicationScheduler->removeClient(aClientId);
00369         mClients.remove(aClientId);
00370         delete client;
00371     }
00372 }
00373 
00374 
00375 //! Returns the round trip time for the specified client
00376 INT32 XFuInetNetwork::getRoundTripTime(INT32 aClientId)
00377 {
00378     return mCommunicationScheduler->getRoundTripTime(aClientId);
00379 }
00380 
00381 
00382 //! Get packet frame
00383 XFcObjectDataFrame * XFuInetNetwork::getPacketFrame(INT32 aClientId, XFCNET_MESSAGE_SLOT aSlot)
00384 {
00385     return mCommunicationScheduler->getPacketFrame(aClientId, aSlot);
00386 }
00387 
00388 
00389 //! Get recent state frame
00390 XFcObjectDataFrame * XFuInetNetwork::getRecentStateFrame(INT32 aClientId, INT32 aRecentId)
00391 {
00392     return mCommunicationScheduler->getRecentStateFrame(aClientId, aRecentId);
00393 }
00394 
00395 
00396 //! Remove recent state frame
00397 void XFuInetNetwork::removeRecentStateFrame(INT32 aClientId, INT32 aRecentId)
00398 {
00399     mCommunicationScheduler->removeRecentStateFrame(aClientId, aRecentId);
00400 }
00401 
00402 
00403 //! Sends a serializable object to the specified client
00404 INT32 XFuInetNetwork::send(INT32 aClientId, UINT32 aReceiverId, XFCNET_MESSAGE_SLOT aSlot, XFuSerializable *aSerializable)
00405 {
00406     INT32 size = -1;
00407     XFcObjectDataFrame *frame = getPacketFrame(aClientId, aSlot);
00408     if (frame)
00409     {
00410         void *buffer = frame->lock();
00411         if (buffer)
00412         {
00413             size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer());
00414             frame->setPacketSize(size);
00415             frame->setReceiverId(aReceiverId);
00416 
00417         }
00418         frame->unlock();
00419     }
00420     return size;
00421 }
00422 
00423 
00424 //! Sends a serializable object to the specified client as a recent state packet
00425 INT32 XFuInetNetwork::sendRecentState(INT32 aClientId, UINT32 aReceiverId, INT32 aRecentId, XFuSerializable *aSerializable)
00426 {
00427     INT32 size = -1;
00428     XFcObjectDataFrame *frame = getRecentStateFrame(aClientId, aRecentId);
00429     if (frame)
00430     {
00431         void *buffer = frame->lock();
00432         if (buffer)
00433         {
00434             size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer());
00435             frame->setPacketSize(size);
00436             frame->setReceiverId(aReceiverId);
00437         }
00438         frame->unlock();
00439     }
00440     return size;
00441 }
00442 
00443 
00444 //! Connection lost handler (XFuClientLost)
00445 void XFuInetNetwork::clientLost(INT32 aClientId)
00446 {
00447     removeClient(aClientId);
00448     INT32 handlersNum = mNetworkEventHandlers->size();
00449     INT32 i;
00450     for (i = 0; i < handlersNum; i++)
00451     {
00452         mNetworkEventHandlers->get(i)->handleClientLost(aClientId);
00453     }
00454 }
00455 
00456 
00457 //! Handle data from an unknown client
00458 INT XFuInetNetwork::handleSender(const void *aAddress, const CHAR8 *aData, INT32 aLen)
00459 {
00460 
00461     UINT32 gameToken;
00462 
00463     if (((XFcAddress *)aAddress)->getType() != (INT32)XFCNET_AFINET)
00464         return 0;
00465 
00466     if (aLen == 4)
00467     {
00468         memcpy(&gameToken, aData, 4);
00469 
00470         if (gameToken == mAcceptGameToken)
00471         {
00472             INT32 clientId = addClient((XFcAddress*)aAddress);
00473             if (clientId != XFCNET_CLIENTADD_ERROR)
00474             {
00475                 INT32 handlersNum = mNetworkEventHandlers->size();
00476                 INT32 i;
00477                 for (i = 0; i < handlersNum; i++)
00478                 {
00479                     mNetworkEventHandlers->get(i)->handleClientAccepted(clientId);
00480                 }
00481             }
00482         }
00483     }
00484     return 0;
00485 }
00486 
00487 
00488 INT XFuInetNetwork::startServerDiscovery(const CHAR8 *aMessage, UINT16 aAdvertisePort)
00489 {
00490 
00491     INT retValue = 0;
00492     if (!mCommService)
00493         return 0;
00494 
00495     XFcInetAdvertiser *inetAdvertise = NULL;
00496 
00497     if (aMessage)
00498         inetAdvertise = XFcInetAdvertiser::create(aMessage, strlen(aMessage));
00499     else
00500     {
00501         CHAR8 *string = "X-Forge server query";
00502         inetAdvertise = XFcInetAdvertiser::create(string, 20);
00503     }
00504 
00505     if (inetAdvertise)
00506     {
00507         inetAdvertise->setAdvertisePort(aAdvertisePort);
00508         retValue = mCommService->inquiry(*inetAdvertise, this);
00509     }
00510 
00511     delete inetAdvertise;
00512 
00513     return (retValue != XFCNET_ERROR) ? 1 : 0;
00514 }
00515 
00516 void XFuInetNetwork::stopServerDiscovery()
00517 {
00518     if (!mCommService)
00519         return;
00520     mCommService->cancelInquiry();
00521 }
00522 
00523 INT XFuInetNetwork::startAdvertiser(const CHAR8 *aMessage, UINT16 aAdvertisePort)
00524 {
00525     INT retVal = XFCNET_ERROR;
00526 
00527     if (!mCommService)
00528         return 0;
00529 
00530     XFcInetAdvertiser *advertise = NULL;
00531 
00532     if ((advertise = XFcInetAdvertiser::create()) != NULL)
00533     {
00534         if (aMessage == NULL)
00535             advertise->setMessageHeader("X-Forge server", 14);
00536         else
00537             advertise->setMessageHeader(aMessage, strlen(aMessage));
00538 
00539         advertise->setGamePort(mGamePort);
00540         advertise->setAdvertisePort(aAdvertisePort);
00541 
00542         retVal = mCommService->advertise(*advertise);
00543         delete advertise;
00544     }
00545     return (retVal != XFCNET_ERROR) ? 1 : 0;
00546 }
00547 
00548 
00549 void XFuInetNetwork::stopAdvertiser()
00550 {
00551      if (!mCommService)
00552         return;
00553 
00554     mCommService->cancelAdvertise();
00555 }
00556 
00557 
00558 void XFuInetNetwork::deviceDiscovery(const XFcLinkedList<XFcAdvertiser *> &aAdvertiser)
00559 {
00560     XFcLinkedList<XFcAdvertiser *>::forwardIterator it;
00561     INT32 handlersNum = mNetworkEventHandlers->size();
00562     INT32 i;
00563 
00564     if (aAdvertiser.size() != 0)
00565     {
00566         for (it = aAdvertiser.forwardBegin(); it != aAdvertiser.forwardEnd(); it++)
00567         {
00568             for (i = 0; i < handlersNum; i++)
00569                 mNetworkEventHandlers->get(i)->handleAdvertiseDiscovered(it.getData());
00570         }
00571     }
00572     else
00573     {
00574         for (i = 0; i < handlersNum; i++)
00575         {
00576             mNetworkEventHandlers->get(i)->handleAdvertiseDiscovered(NULL);
00577         }
00578     }
00579 }
00580 
00581 
00582 INT XFuInetNetwork::deviceLocalName(XFcName &aName)
00583 {
00584     // Delete host resolver
00585     if (!mHostResolver)
00586         mHostResolver = XFcInetHostResolver::create();
00587 
00588     // Do the device discovery, async found devices are returned througth deviceDiscovery callback.
00589     if (mHostResolver)
00590     {
00591         INT error = mHostResolver->localName(aName);
00592 
00593         if (error != XFCNET_ERROR)
00594         {
00595             if (aName.mLen < 0x40)
00596                 aName.mName[aName.mLen] = '\0';
00597 
00598             return 1;
00599         }
00600     }
00601     return 0;
00602 }
00603 

   
X-Forge Documentation
Confidential
Copyright © 2002-2003 Fathammer
   
Documentation generated
with doxygen
by Dimitri van Heesch