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

serversideasynch.cpp

Go to the documentation of this file.
00001 /*
00002  * serversideasynch.cpp,v 1.15 2004/01/06 17:05:41 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 "clientservercommon.h"
00026 #include "serversideasynch.h"
00027 #include "concreteconnection.h"
00028 #include "Log.h"
00029 
00030 // dummy RMessage used to initialize references
00031 RMessage KDummyMessage;
00032 
00034 // CAsynchBase
00036 
00037 CAsynchBase::CAsynchBase(CConcreteConnection *aConnection)
00038     : CActive(CActive::EPriorityStandard),
00039       iConnection(aConnection),
00040       iMessage(KDummyMessage)
00041 {
00042     CActiveScheduler::Add(this);
00043 }
00044 
00045 CAsynchBase::~CAsynchBase()
00046 {
00047     Log::Print(_L("~CAsynchBase()"));
00048 
00049     // cancel pending operation if any
00050     Cancel();
00051 
00052     // remove from scheduler
00053     Deque();
00054 
00055     Log::Print(_L("~CAsynchBase() exiting.."));
00056 }
00057 
00059 // CAsynchSend
00061 
00062 CAsynchSend::CAsynchSend(CConcreteConnection *aConnection)
00063     : CAsynchBase(aConnection)
00064 {
00065 }
00066 
00067 void CAsynchSend::SendL(TDesC8 *aBuf)
00068 {
00069     Log::Print(_L("CAsynchSend::SendL()"));
00070 
00071     iFragmentCount = 1;
00072     iFragments = NULL;
00073     SendFragmentL(aBuf);
00074 }
00075 
00076 // Fragment aware SendL
00077 void CAsynchSend::SendL(RPointerArray<TDesC8> *aFragments)
00078 {
00079     Log::Print(_L("CAsynchSend::SendL()"));
00080 
00081     iFragments = aFragments;
00082     iFragmentCount = iFragments->Count();
00083     SendFragmentL((*iFragments)[0]);
00084 }
00085 
00086 void CAsynchSend::SendFragmentL(TDesC8 *aBuf) 
00087 {
00088     iSendBuf = aBuf;    
00089     iConnection->GetSocket().Write(*aBuf, iStatus);
00090     SetActive();
00091 }
00092 
00093 void CAsynchSend::RunL()
00094 {
00095     Log::Print(_L("CAsynchSend::RunL()"));
00096 
00097     // fragment sent; release buffer
00098     delete iSendBuf;
00099     iSendBuf = NULL;
00100 
00101     // anymore fragments left?
00102     if (--iFragmentCount > 0) {
00103     iFragments->Remove(0);
00104     SendFragmentL((*iFragments)[0]);
00105     } else {
00106     // Last fragment sent
00107     if (iFragments != NULL) {
00108         delete iFragments;
00109         iFragments = NULL;
00110     }
00111     }
00112 }
00113 
00114 TInt CAsynchSend::RunError(TInt aError)
00115 {
00116     Log::Print(_L("CAsynchSend::RunError(): %d"), aError);
00117 
00118     iConnection->Close();
00119     CleanBuffers();
00120 
00121     return KErrNone;
00122 }
00123 
00124 // cancel pending send operation
00125 void CAsynchSend::DoCancel()
00126 {
00127     Log::Print(_L("CAsynchSend::DoCancel()"));
00128 
00129     iConnection->GetSocket().CancelSend();
00130     CleanBuffers();
00131 
00132     Log::Print(_L("CAsynchSend::DoCancel() exiting"));
00133 }
00134 
00135 void CAsynchSend::CleanBuffers()
00136 {
00137     delete iSendBuf;
00138     iSendBuf = NULL;
00139     
00140     if (iFragments != NULL) {
00141     iFragments->ResetAndDestroy();
00142     delete iFragments;
00143     iFragments = NULL;
00144     }
00145 }
00146 
00148 // CAsynchReceive
00150 
00151 CAsynchReceive::CAsynchReceive(CConcreteConnection *aConnection) 
00152   : CAsynchBase(aConnection)
00153 {
00154   // do nothing
00155 }
00156 
00157 // asynchronous call to start waiting for data
00158 void CAsynchReceive::Receive(const RMessage &aMessage) 
00159 {
00160     Log::Print(_L("CAsynchReceive::Receive()"));
00161 
00162     // store the pending message
00163     iMessage = aMessage;
00164 
00165 //    Log::Print(_L("calling RecvOneOrMore()"));
00166  //   iConnection->GetSocket().RecvOneOrMore(iRecvBuf, 0, iStatus, iRecvLen);
00167     Log::Print(_L("calling Read()"));
00168     iConnection->GetSocket().Read(iRecvBuf, iStatus);
00169 
00170 //    Log::Print(_L("calling SetActive()"));
00171     SetActive();
00172 
00173     Log::Print(_L("CAsynchReceive::Receive() exiting.."));
00174 }
00175 
00176 // new data available. writes the data into the clientside buffer and completes
00177 // the call
00178 void CAsynchReceive::RunL()
00179 {
00180     Log::Print(_L("CAsynchReceive::RunL()"));
00181 
00182     TInt status = iStatus.Int();
00183     if( status != KErrNone ) {
00184         Log::Print(_L("CAsynchReceive::RunL(): error (%d)"), status);
00185 
00186         // notify client about the error
00187         iMessage.Complete(status);
00188 
00189         return;
00190     }
00191 
00192     Log::Print(_L("received %d bytes"), iRecvBuf.Length());
00193 
00194     // write the data into the buffer of the pending message
00195     TRAPD(err, iMessage.WriteL(iMessage.Ptr1(), iRecvBuf));
00196     Log::Print(_L("WriteL() returned %d"), err);
00197 
00198     //Log::Print(_L("RECEIVE completing %d"), iMessage);
00199 
00200     // complete the pending call
00201     iMessage.Complete(err);
00202 
00203     //##TODO## remove
00204     // forget about the message
00205 //    iMessage = NULL;
00206 
00207     Log::Print(_L("CAsynchReceive::RunL() returning.."));
00208 }
00209 
00210 TInt CAsynchReceive::RunError(TInt aError)
00211 {
00212     Log::Print(_L("CAsynchReceive::RunError(): %d"), aError);
00213 
00214     //##TODO##: connection closed? close resources
00215 
00216     iMessage.Complete(aError);
00217 
00218     //##TODO## remove
00219     // forget about the message
00220 //    iMessage = NULL;
00221 
00222     return KErrNone;
00223 }
00224 
00225 // cancels pending receive operation
00226 void CAsynchReceive::DoCancel()
00227 {
00228     Log::Print(_L("CAsynchReceive::DoCancel()"));
00229 
00230     iConnection->GetSocket().CancelRecv();
00231 
00232     Log::Print(_L("completing message.."));
00233 
00234     //##TODO## use error code
00235     iMessage.Complete(KErrNone);
00236 
00237     Log::Print(_L("CAsynchReceive::DoCancel() exiting"));
00238 }
00239 
00241 // CAsynchListen
00243 
00244 CAsynchListen::CAsynchListen(CConcreteConnection *aConnection) 
00245     : CAsynchBase(aConnection)
00246 {
00247 }
00248 
00249 CAsynchListen::~CAsynchListen()
00250 {
00251     delete iIncomingSocket;
00252 }
00253 
00254 // will listen to socket from iConnection->GetSocket()
00255 void CAsynchListen::ListenL(const RMessage &aMessage)
00256 {
00257     Log::Print(_L("CAsynchListen::ListenL()"));
00258 
00259     // store the pending message
00260     iMessage = aMessage;
00261 
00262     // deallocate previous socket
00263     delete iIncomingSocket;
00264     iIncomingSocket = NULL;
00265 
00266     // allocate a blank socket 
00267     iIncomingSocket = new (ELeave) RSocket();
00268 
00269     RSocketServ &sock_serv = iConnection->GetSocketServ();
00270     User::LeaveIfError(iIncomingSocket->Open(sock_serv));
00271 
00272     // start waiting for inbound connection
00273     iConnection->GetSocket().Accept(*iIncomingSocket, iStatus);
00274 
00275     SetActive();
00276 
00277     Log::Print(_L("CAsynchListen::ListenL() returning"));
00278 }
00279 
00280 // a new inbound connection pending - estabilish connection and allocate
00281 // resources. completes the original message to allow client call to return
00282 void CAsynchListen::RunL()
00283 {
00284     CConcreteConnection *con = NULL;
00285 
00286     TInt status = iStatus.Int();
00287     if( status != KErrNone ) {
00288         Log::Print(_L("CAsynchListen::RunL() error %d"), status);
00289 
00290         iMessage.Complete(status);
00291         return;
00292     }
00293 
00294     Log::Print(_L("CAsynchListen::RunL()"));
00295     TInt mtu = CBTCommunicator::ResolveMTU(*iIncomingSocket);
00296     con = CConcreteConnection::NewL(iIncomingSocket, iConnection->GetSession(), mtu);
00297 
00298     // forget about the socket as it will be released by others
00299     iIncomingSocket = NULL;
00300 
00301     Log::Print(_L("calling AllocateConnection()"));
00302 
00303     TInt id = iConnection->GetSession().AllocateConnection(con);
00304 
00305     // complete the message with the connection id
00306     iMessage.Complete(id);
00307 }
00308 
00309 // cancel pending listen operation
00310 void CAsynchListen::DoCancel()
00311 {
00312     Log::Print(_L("CAsynchListen::DoCancel()"));
00313 
00314     iConnection->GetSocket().CancelAccept();
00315 
00316     // complete the message with the connection id
00317     //##TODO## no-no.. this wont work
00318     iMessage.Complete(iStatus.Int());
00319 
00320     Log::Print(_L("CAsynchListen::DoCancel() exiting"));
00321 }
00322 
00323 TInt CAsynchListen::RunError(TInt aError)
00324 {
00325     Log::Print(_L("CAsynchListen::RunError(): %d"), aError);
00326 
00327     //##TODO## handle the error
00328 
00329     // complete the message with the connection id
00330     //##TODO## whaat? no-no..
00331     //Log::Print(_L("COMPLETING %d"), iMessage);
00332     iMessage.Complete(iStatus.Int());
00333 
00334     return KErrNone;
00335 }
00336 
00337 

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