Main Page | Class Hierarchy | Data Structures | File List | Data Fields | Globals

clientsession.cpp

Go to the documentation of this file.
00001 /*
00002  * clientsession.cpp,v 1.33 2003/11/25 19:29:56 mattid Exp
00003  *
00004  * COBAIN - Communications API for EPOC Environments
00005  * Copyright (C) 2002-2003 Matti Dahlbom, Matti Kokkola
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * Contact: Matti Dahlbom <matti@777-team.org>
00022  *          Matti Kokkola <matti.kokkola@iki.fi>
00023  */
00024 
00025 #include <e32base.h>
00026 #include <e32math.h>
00027 
00028 #include "clientsession.h"
00029 //#include "ClientSubSession.h"
00030 #include "cobainserver.h"
00031 #include "clientservercommon.h"
00032 
00033 #ifdef __WINS__
00034 static const TUint KServerMinHeapSize =  0x1000;  //  4K
00035 static const TUint KServerMaxHeapSize = 0x10000;  // 64K
00036 #endif
00037 
00038 static TInt StartServer();
00039 static TInt CreateServerProcess();
00040 
00042 // public API methods
00044 
00045 RCobainClientSession::RCobainClientSession()
00046     : iIsConnected(EFalse)
00047 {
00048 }
00049 
00050 RCobainClientSession::~RCobainClientSession()
00051 {
00052     Close();
00053     iIsConnected = EFalse;
00054 }
00055 
00056 void RCobainClientSession::ConstructL()
00057 {
00058     CCobainLayer::Log(_L("RCobainClientSession::ConstructL()"));
00059 
00060     // connect to the server
00061     User::LeaveIfError(Connect());
00062 }
00063 
00064 // discovers the peers. asynchronously returns the number of the peers
00065 void RCobainClientSession::DiscoverPeers(TProtocol aProtocol, TUint aPort, 
00066                                          TPckgBuf<TInt> *aPeerCountBuffer, 
00067                                          TRequestStatus &aNotifyStatus)
00068 {
00069     TInt p[4];
00070 
00071     p[0] = aProtocol;
00072     p[1] = (TInt)aPeerCountBuffer;
00073     p[2] = (TInt)aPort;
00074     SendReceive(CCobainServer::EGetNumPeers, p, aNotifyStatus);
00075 }
00076 
00077 void RCobainClientSession::FetchPeerData(TInt aPeerOrdinal, TPeerDataBuf *aPeerBuffer, 
00078                                          TRequestStatus &aNotifyStatus)
00079 {
00080     TInt p[4];
00081 
00082     p[0] = aPeerOrdinal;
00083     p[1] = (TInt)aPeerBuffer;
00084     SendReceive(CCobainServer::EGetPeer, p, aNotifyStatus);
00085 }
00086 
00087 TPeerList* RCobainClientSession::DiscoverBTPeersL(TUint aServiceClassID)
00088 {
00089     TBuf8<sizeof(TInt)> sizebuf;
00090     TPeerDataBuf peerbuf;
00091     TInt p[4];
00092 
00093     // fetch the number of peers
00094     p[0] = EBluetooth;
00095     p[1] = (TInt)(&sizebuf);
00096     p[2] = (TInt)aServiceClassID;
00097     User::LeaveIfError(SendReceive(CCobainServer::EGetNumPeers, p));
00098 
00099     TInt num;
00100     Mem::Copy(&num, sizebuf.Ptr(), sizeof(TInt));
00101 
00102     TBuf<32> buf;
00103     buf.Format(_L("found %d peer(s)"), num);
00104     CCobainLayer::Log(buf);
00105 
00106     // allocate the peer list
00107     TPeerList *list = new (ELeave) TPeerList();
00108     CleanupStack::PushL(list);
00109 
00110     // fetch all the matched peers
00111     for( TInt i = 0; i < num; i++ ) {
00112         p[0] = i;
00113         p[1] = (TInt)(&peerbuf);
00114         User::LeaveIfError(SendReceive(CCobainServer::EGetPeer, p));
00115 
00116         // add peer entry
00117         TPeerData data = peerbuf();
00118         CNetworkPeer *peer = CNetworkPeer::NewL(*this, 
00119                                                 EBluetooth,
00120                                                 data.iDeviceName, 
00121                                                 data.iDeviceAddress,
00122                                                 data.iServiceID,
00123                                                 data.iPort);
00124         list->Append(peer);
00125     }
00126 
00127     CleanupStack::Pop(); // list 
00128 
00129     return list;
00130 }
00131 
00132 TInt RCobainClientSession::Connect() 
00133 {
00134     TBuf<128> logbuf;
00135 
00136     CCobainLayer::Log(_L("RCobainClientSession::Connect()"));
00137 
00138     TInt rc = ::StartServer();
00139     if( rc != KErrNone ) {
00140         logbuf.Format(_L("StartServer() error %d"), rc);
00141         CCobainLayer::Log(logbuf);
00142     }
00143 
00144     if( rc == KErrNone ) 
00145     {
00146         TVersion version(KCobainServerMajorVersion,
00147                          KCobainServerMinorVersion,
00148                          KCobainServerBuildVersion);
00149 
00150         rc = CreateSession(KCobainServerName, 
00151                            version,
00152                            KNumMessageSlots);
00153 
00154         if( rc != KErrNone ) {
00155             logbuf.Format(_L("CreateSession() error %d"), rc);
00156             CCobainLayer::Log(logbuf);
00157         } else {
00158             CCobainLayer::Log(_L("connected to server"));
00159         }
00160     }
00161 
00162     return rc;
00163 }
00164 
00165 // synchronous call to start listening on a port
00166 void RCobainClientSession::StartListening(TProtocol aProtocol, 
00167                                           TUint aPort)
00168 {
00169     TInt p[4];
00170 
00171     p[0] = (TInt)aProtocol;
00172     p[1] = (TInt)aPort;
00173     SendReceive(CCobainServer::EStartListen, p);
00174 
00175     CCobainLayer::Log(_L("StartListening() returning"));
00176 }
00177 
00178 // aborts pending listening operation
00179 void RCobainClientSession::StopListening(TProtocol aProtocol, TUint aPort)
00180 {
00181     TInt p[4];
00182 
00183     p[0] = (TInt)aProtocol;
00184     p[1] = (TInt)aPort;
00185 
00186     // synchronously call server to abort pending listen operation
00187     SendReceive(CCobainServer::EAbortListen, p);
00188 }
00189 
00190 // asynchronous call to wait for new inbound connection 
00191 void RCobainClientSession::GetIncomingSocketL(TRequestStatus &aNotifyStatus)
00192 {
00193     TInt p[4];
00194 
00195     CCobainLayer::Log(_L("GetIncomingSocketL()"));
00196 
00197     // asynchronously call server to get socket id
00198     SendReceive(CCobainServer::EGetIncomingConnection, p, aNotifyStatus);
00199 }
00200 
00201 // synchronously connects to the peer
00202 RCobainSocket* RCobainClientSession::ConnectSocketL(CNetworkPeer *aPeer)
00203 {
00204     TInt p[4];
00205     TPeerData data;
00206     TPckgBuf<TInt> id_buf;
00207 
00208     CCobainLayer::Log(_L("RCobainClientSession::ConnectSocketL()"));
00209 
00210     // copy peer data and package it for call
00211     data.iDeviceAddress.Copy(aPeer->GetDeviceAddress());
00212     data.iDeviceName.Copy(aPeer->GetDeviceName());
00213     data.iPort = aPeer->GetPort();
00214     data.iServiceID.Copy(aPeer->GetServiceID());
00215 
00216     TPeerDataBuf peer_buf(data);
00217 
00218     p[0] = aPeer->GetProtocol();
00219     p[1] = (TInt)&peer_buf;
00220     p[2] = (TInt)&id_buf;
00221     
00222     User::LeaveIfError(SendReceive(CCobainServer::EConnect, p));
00223 
00224     RCobainSocket *socket = new (ELeave) RCobainSocket(*this, id_buf());
00225 
00226     CCobainLayer::Log(_L("RCobainClientSession::ConnectSocketL() exiting.."));
00227 
00228     return socket;
00229 }
00230 
00231 // synchronously calls server to close the actual socket resource
00232 void RCobainClientSession::CloseSocket(TInt aId, TBool aImmediately)
00233 {
00234     TInt p[4];
00235 
00236     p[0] = aId;
00237     p[1] = (TInt)aImmediately;
00238     SendReceive(CCobainServer::ECloseSocket, p);
00239 }
00240 
00241 TInt RCobainClientSession::Send(TInt aSocketId, const TDesC8 *aBuf)
00242 {
00243     TInt p[4];
00244 
00245     CCobainLayer::Log(_L("Send()"));
00246 
00247     p[0] = aSocketId;
00248     p[1] = aBuf->Length();
00249     p[2] = (TInt)aBuf;
00250 
00251     return SendReceive(CCobainServer::ESend, p);
00252 
00253     CCobainLayer::Log(_L("Send() exiting.."));
00254 
00255 }
00256 
00257 void RCobainClientSession::Receive(TInt aSocketId, 
00258                                    TDes8* aBuffer,
00259                                    TRequestStatus& aStatus) 
00260 {
00261     TInt p[4];
00262 
00263     p[0] = aSocketId;
00264     p[1] = (TInt)aBuffer;
00265     SendReceive(CCobainServer::EReceive, p, aStatus);
00266 }
00267 
00268 void RCobainClientSession::CancelReceive(TInt aSocketId) 
00269 {
00270     TInt p[4];
00271 
00272     p[0] = aSocketId;
00273     SendReceive(CCobainServer::ECancelReceive, p);
00274 }
00275 
00277 // Static functions for server bootstrap 
00279 
00280 static TInt StartServer()
00281 {
00282   TInt rc = 0;
00283 
00284   TFindServer findServer(KCobainServerName);
00285   TFullName name;
00286 
00287   rc = findServer.Next(name);
00288   if (rc == KErrNone)
00289     {
00290       // Server already running
00291       return KErrNone;
00292     }
00293     
00294   RSemaphore semaphore;
00295   rc = semaphore.CreateGlobal(KCobainServerSemaphoreName, 0);
00296   if (rc != KErrNone)
00297     {
00298       return rc;
00299     }
00300 
00301   rc = CreateServerProcess();
00302   if (rc != KErrNone)
00303     {
00304       return  rc;
00305     }
00306 
00307   semaphore.Wait();
00308   semaphore.Close();       
00309 
00310   return  KErrNone;
00311 }
00312 
00313 static TInt CreateServerProcess()
00314 {
00315     TInt rc = 0;
00316 
00317     const TUidType serverUid(KNullUid, KNullUid, KCobainServerUid3);
00318 
00319 #ifdef __WINS__
00320 
00321     RLibrary lib;
00322     rc = lib.Load(KCobainServerFilename, serverUid);
00323     if( rc != KErrNone )
00324     {
00325         return  rc;
00326     }
00327 
00328     //  Get the WinsMain function
00329     TLibraryFunction functionWinsMain = lib.Lookup(1);
00330 
00331     //  Call it and cast the result to a thread function
00332     TThreadFunction serverThreadFunction = 
00333         reinterpret_cast<TThreadFunction>(functionWinsMain());
00334 
00335     TName threadName(KCobainServerName);
00336 
00337     // Append a random number to make it unique
00338     threadName.AppendNum(Math::Random(), EHex);
00339 
00340     RThread server;
00341 
00342     rc = server.Create(threadName,   // create new server thread
00343                        serverThreadFunction, // thread's main function
00344                        KDefaultStackSize,
00345                        NULL,
00346                        &lib,
00347                        NULL,
00348                        KServerMinHeapSize,
00349                        KServerMaxHeapSize,
00350                        EOwnerProcess);
00351 
00352     lib.Close();    // if successful, server thread has handle to library now
00353 
00354     if (rc != KErrNone)
00355     {
00356         return  rc;
00357     }
00358 
00359     server.SetPriority(EPriorityMore);
00360 
00361 #else
00362     RProcess server;
00363 
00364     rc = server.Create(KCobainServerFilename, 
00365                        _L(""), 
00366                        serverUid);
00367     if (rc != KErrNone)
00368     {
00369         return  rc;
00370     }
00371 
00372 #endif
00373 
00374     // Invokes ThreadFunction() function of the CobainServer
00375     server.Resume();
00376     server.Close();
00377 
00378     return  KErrNone;
00379 }
00380 
00381 // EPOC dll entry point
00382 GLDEF_C TInt E32Dll(TDllReason) {
00383     return KErrNone;
00384 }

Generated on Mon Dec 8 10:26:06 2003 for CobainAPIImplementation by doxygen 1.3.5