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.37 2004/01/10 14:27:11 mattid Exp
00003  *
00004  * COBAIN - Communications API for EPOC Environments
00005  * Copyright (C) 2002-2004 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     Log::Print(_L("~RCobainClientSession()"));
00053 
00054     if( iIsConnected ) {
00055         Close();
00056         iIsConnected = EFalse;
00057     }
00058 
00059     Log::Print(_L("~RCobainClientSession() exiting.."));
00060 }
00061 
00062 void RCobainClientSession::ConstructL()
00063 {
00064     // connect to the server
00065     User::LeaveIfError(Connect());
00066 }
00067 
00068 // discovers the peers. asynchronously returns the number of the peers
00069 void RCobainClientSession::DiscoverPeers(TProtocol aProtocol, 
00070                                          TUint aServiceID, 
00071                                          TPckgBuf<TInt> *aPeerCountBuffer, 
00072                                          TRequestStatus &aNotifyStatus)
00073 {
00074     TInt p[4];
00075 
00076     p[0] = aProtocol;
00077     p[1] = (TInt)aPeerCountBuffer;
00078     p[2] = (TInt)aServiceID;
00079     SendReceive(CCobainServer::EGetNumPeers, p, aNotifyStatus);
00080 }
00081 
00082 void RCobainClientSession::FetchPeerData(TInt aPeerOrdinal, TPeerDataBuf *aPeerBuffer, 
00083                                          TRequestStatus &aNotifyStatus)
00084 {
00085     TInt p[4];
00086 
00087     p[0] = aPeerOrdinal;
00088     p[1] = (TInt)aPeerBuffer;
00089     SendReceive(CCobainServer::EGetPeer, p, aNotifyStatus);
00090 }
00091 
00092 /*
00093 TPeerList* RCobainClientSession::DiscoverBTPeersL(TUint aServiceClassID)
00094 {
00095     TBuf8<sizeof(TInt)> sizebuf;
00096     TPeerDataBuf peerbuf;
00097     TInt p[4];
00098 
00099     // fetch the number of peers
00100     p[0] = EBluetooth;
00101     p[1] = (TInt)(&sizebuf);
00102     p[2] = (TInt)aServiceClassID;
00103     User::LeaveIfError(SendReceive(CCobainServer::EGetNumPeers, p));
00104 
00105     TInt num;
00106     Mem::Copy(&num, sizebuf.Ptr(), sizeof(TInt));
00107 
00108     TBuf<32> buf;
00109     buf.Format(_L("found %d peer(s)"), num);
00110     CCobainLayer::Log(buf);
00111 
00112     // allocate the peer list
00113     TPeerList *list = new (ELeave) TPeerList();
00114     CleanupStack::PushL(list);
00115 
00116     // fetch all the matched peers
00117     for( TInt i = 0; i < num; i++ ) {
00118         p[0] = i;
00119         p[1] = (TInt)(&peerbuf);
00120         User::LeaveIfError(SendReceive(CCobainServer::EGetPeer, p));
00121 
00122         // add peer entry
00123         TPeerData data = peerbuf();
00124         CNetworkPeer *peer = CNetworkPeer::NewL(*this, 
00125                                                 EBluetooth,
00126                                                 data);
00127         list->Append(peer);
00128     }
00129 
00130     CleanupStack::Pop(); // list 
00131 
00132     return list;
00133 }
00134 */
00135 
00136 TInt RCobainClientSession::Connect() 
00137 {
00138     TInt rc = ::StartServer();
00139 
00140     __ASSERT_ALWAYS(rc == KErrNone, 
00141         User::Panic(KCobainClientPanic, KErrCCPServerStartFailed));
00142 
00143     TVersion version(KCobainServerMajorVersion,
00144                      KCobainServerMinorVersion,
00145                      KCobainServerBuildVersion);
00146 
00147     rc = CreateSession(KCobainServerName, 
00148                        version,
00149                        KNumMessageSlots);
00150 
00151     return rc;
00152 }
00153 
00154 // synchronous call to start listening on a port
00155 void RCobainClientSession::StartListeningL(TProtocol aProtocol, 
00156                                            TUint aPort, TUint aExtraInfo)
00157 {
00158     TInt p[4];
00159 
00160     p[0] = (TInt)aProtocol;
00161     p[1] = (TInt)aPort;
00162     p[2] = (TInt)aExtraInfo;
00163     
00164     User::LeaveIfError(SendReceive(CCobainServer::EStartListen, p));
00165 }
00166 
00167 // aborts pending listening operation
00168 void RCobainClientSession::StopListening(TProtocol aProtocol, TUint aPort)
00169 {
00170     TInt p[4];
00171 
00172     p[0] = (TInt)aProtocol;
00173     p[1] = (TInt)aPort;
00174 
00175     // synchronously call server to abort pending listen operation
00176     SendReceive(CCobainServer::EAbortListen, p);
00177 }
00178 
00179 // asynchronous call to wait for new inbound connection 
00180 void RCobainClientSession::GetIncomingSocketL(TRequestStatus &aNotifyStatus)
00181 {
00182     TInt p[4];
00183 
00184     // asynchronously call server to get socket id
00185     SendReceive(CCobainServer::EGetIncomingConnection, p, aNotifyStatus);
00186 }
00187 
00188 // synchronously connects to the peer
00189 RCobainSocket* RCobainClientSession::ConnectSocketL(CNetworkPeer *aPeer)
00190 {
00191     TInt p[4];
00192     TPeerData data;
00193     TPckgBuf<TInt> id_buf;
00194 
00195     Log::Print(_L("RCobainClientSession::ConnectSocketL()"));
00196 
00197     // copy peer data and package it for call
00198     aPeer->WritePeerData(data);
00199     TPeerDataBuf peer_buf(data);
00200 
00201     p[0] = aPeer->GetProtocol();
00202     p[1] = (TInt)&peer_buf;
00203     p[2] = (TInt)&id_buf;
00204     
00205     Log::Print(_L("calling SendReceive(): EConnect"));
00206 
00207     User::LeaveIfError(SendReceive(CCobainServer::EConnect, p));
00208     
00209     RCobainSocket *socket = new (ELeave) RCobainSocket(*this, id_buf());
00210 
00211     Log::Print(_L("RCobainClientSession::ConnectSocketL() returning.."));
00212 
00213     return socket;
00214 }
00215 
00216 // synchronously calls server to close the actual socket resource
00217 void RCobainClientSession::CloseSocket(TInt aId, TBool aImmediately)
00218 {
00219     TInt p[4];
00220 
00221     p[0] = aId;
00222     p[1] = (TInt)aImmediately;
00223     SendReceive(CCobainServer::ECloseSocket, p);
00224 }
00225 
00226 TInt RCobainClientSession::Send(TInt aSocketId, const TDesC8 *aBuf)
00227 {
00228     TInt p[4];
00229 
00230     p[0] = aSocketId;
00231     p[1] = aBuf->Length();
00232     p[2] = (TInt)aBuf;
00233 
00234     return SendReceive(CCobainServer::ESend, p);
00235 }
00236 
00237 void RCobainClientSession::Receive(TInt aSocketId, 
00238                                    TDes8* aBuffer,
00239                                    TRequestStatus& aStatus) 
00240 {
00241     TInt p[4];
00242 
00243     p[0] = aSocketId;
00244     p[1] = (TInt)aBuffer;
00245     SendReceive(CCobainServer::EReceive, p, aStatus);
00246 }
00247 
00248 void RCobainClientSession::CancelReceive(TInt aSocketId) 
00249 {
00250     TInt p[4];
00251 
00252     p[0] = aSocketId;
00253     SendReceive(CCobainServer::ECancelReceive, p);
00254 }
00255 
00257 // Static functions for server bootstrap 
00259 
00260 static TInt StartServer()
00261 {
00262   TInt rc = 0;
00263 
00264   TFindServer findServer(KCobainServerName);
00265   TFullName name;
00266 
00267   rc = findServer.Next(name);
00268   if (rc == KErrNone)
00269     {
00270       // Server already running
00271       return KErrNone;
00272     }
00273     
00274   RSemaphore semaphore;
00275   rc = semaphore.CreateGlobal(KCobainServerSemaphoreName, 0);
00276   if (rc != KErrNone)
00277     {
00278       return rc;
00279     }
00280 
00281   rc = CreateServerProcess();
00282   if (rc != KErrNone)
00283     {
00284       return  rc;
00285     }
00286 
00287   semaphore.Wait();
00288   semaphore.Close();       
00289 
00290   return  KErrNone;
00291 }
00292 
00293 static TInt CreateServerProcess()
00294 {
00295     TInt rc = 0;
00296 
00297     const TUidType serverUid(KNullUid, KNullUid, KCobainServerUid3);
00298 
00299 #ifdef __WINS__
00300 
00301     RLibrary lib;
00302     rc = lib.Load(KCobainServerFilename, serverUid);
00303     if( rc != KErrNone )
00304     {
00305         return  rc;
00306     }
00307 
00308     //  Get the WinsMain function
00309     TLibraryFunction functionWinsMain = lib.Lookup(1);
00310 
00311     //  Call it and cast the result to a thread function
00312     TThreadFunction serverThreadFunction = 
00313         reinterpret_cast<TThreadFunction>(functionWinsMain());
00314 
00315     TName threadName(KCobainServerName);
00316 
00317     // Append a random number to make it unique
00318     threadName.AppendNum(Math::Random(), EHex);
00319 
00320     RThread server;
00321 
00322     rc = server.Create(threadName,   // create new server thread
00323                        serverThreadFunction, // thread's main function
00324                        KDefaultStackSize,
00325                        NULL,
00326                        &lib,
00327                        NULL,
00328                        KServerMinHeapSize,
00329                        KServerMaxHeapSize,
00330                        EOwnerProcess);
00331 
00332     lib.Close();    // if successful, server thread has handle to library now
00333 
00334     if (rc != KErrNone)
00335     {
00336         return  rc;
00337     }
00338 
00339     server.SetPriority(EPriorityMore);
00340 
00341 #else
00342     RProcess server;
00343 
00344     rc = server.Create(KCobainServerFilename, 
00345                        _L(""), 
00346                        serverUid);
00347     if (rc != KErrNone)
00348     {
00349         return  rc;
00350     }
00351 
00352 #endif
00353 
00354     // Invokes ThreadFunction() function of the CobainServer
00355     server.Resume();
00356     server.Close();
00357 
00358     return  KErrNone;
00359 }
00360 
00361 // EPOC dll entry point
00362 GLDEF_C TInt E32Dll(TDllReason) {
00363     return KErrNone;
00364 }

Generated on Tue Jan 13 15:47:07 2004 for CobainAPIImplementation by doxygen 1.3.5