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