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.12 2003/11/20 07:52:22 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     iSendBuf = aBuf;
00072 
00073     iConnection->GetSocket().Write(*aBuf, iStatus);
00074     SetActive();
00075 }
00076 
00077 void CAsynchSend::RunL()
00078 {
00079     Log::Print(_L("CAsynchSend::RunL()"));
00080 
00081     // data sent; release buffer
00082     delete iSendBuf;
00083     iSendBuf = NULL;
00084 }
00085 
00086 TInt CAsynchSend::RunError(TInt aError)
00087 {
00088     Log::Print(_L("CAsynchSend::RunError(): %d"), aError);
00089 
00090     iConnection->Close();
00091 
00092     // must deallocate send buffer
00093     delete iSendBuf;
00094     iSendBuf = NULL;
00095 
00096     return KErrNone;
00097 }
00098 
00099 // cancel pending send operation
00100 void CAsynchSend::DoCancel()
00101 {
00102     Log::Print(_L("CAsynchSend::DoCancel()"));
00103 
00104     iConnection->GetSocket().CancelSend();
00105 
00106     // must deallocate send buffer
00107     delete iSendBuf;
00108     iSendBuf = NULL;
00109 
00110     Log::Print(_L("CAsynchSend::DoCancel() exiting"));
00111 }
00112 
00114 // CAsynchReceive
00116 
00117 CAsynchReceive::CAsynchReceive(CConcreteConnection *aConnection) 
00118   : CAsynchBase(aConnection)
00119 {
00120   // do nothing
00121 }
00122 /*
00123 CAsynchReceive::~CAsynchReceive()
00124 {
00125     Log::Print(_L("~CAsynchReceive()"));
00126 
00127     // cancel pending operation if any
00128 //    Cancel();
00129 
00130     // remove from scheduler
00131   //  Deque();
00132 
00133     Log::Print(_L("~CAsynchReceive() exiting.."));
00134 }
00135 */
00136 // asynchronous call to start waiting for data
00137 void CAsynchReceive::Receive(const RMessage &aMessage) 
00138 {
00139     Log::Print(_L("CAsynchReceive::Receive()"));
00140 
00141     // store the pending message
00142     iMessage = aMessage;
00143 
00144 //    Log::Print(_L("calling RecvOneOrMore()"));
00145  //   iConnection->GetSocket().RecvOneOrMore(iRecvBuf, 0, iStatus, iRecvLen);
00146     iConnection->GetSocket().Read(iRecvBuf, iStatus);
00147 
00148 //    Log::Print(_L("calling SetActive()"));
00149     SetActive();
00150 
00151     Log::Print(_L("CAsynchReceive::Receive() exiting.."));
00152 }
00153 
00154 // new data available. writes the data into the clientside buffer and completes
00155 // the call
00156 void CAsynchReceive::RunL()
00157 {
00158     Log::Print(_L("CAsynchReceive::RunL()"));
00159 
00160     TInt status = iStatus.Int();
00161     if( status != KErrNone ) {
00162         Log::Print(_L("CAsynchReceive::RunL(): error (%d)"), status);
00163 
00164         // cancel the receiver
00165      //   Cancel();
00166 
00167         // notify client about the error
00168         iMessage.Complete(status);
00169 
00170         return;
00171     }
00172 
00173     Log::Print(_L("received %d bytes"), iRecvBuf.Length());
00174 
00175     // write the data into the buffer of the pending message
00176     TRAPD(err, iMessage.WriteL(iMessage.Ptr1(), iRecvBuf));
00177     Log::Print(_L("WriteL() returned %d"), err);
00178 
00179     //Log::Print(_L("RECEIVE completing %d"), iMessage);
00180 
00181     // complete the pending call
00182     iMessage.Complete(err);
00183 
00184     //##TODO## remove
00185     // forget about the message
00186 //    iMessage = NULL;
00187 
00188     Log::Print(_L("CAsynchReceive::RunL() returning.."));
00189 }
00190 
00191 TInt CAsynchReceive::RunError(TInt aError)
00192 {
00193     Log::Print(_L("CAsynchReceive::RunError(): %d"), aError);
00194 
00195     //##TODO##: connection closed? close resources
00196 
00197     iMessage.Complete(aError);
00198 
00199     //##TODO## remove
00200     // forget about the message
00201 //    iMessage = NULL;
00202 
00203     return KErrNone;
00204 }
00205 
00206 // cancels pending receive operation
00207 void CAsynchReceive::DoCancel()
00208 {
00209     Log::Print(_L("CAsynchReceive::DoCancel()"));
00210 
00211     iConnection->GetSocket().CancelRecv();
00212 
00213     Log::Print(_L("completing message.."));
00214 
00215     //##TODO## use error code
00216     iMessage.Complete(KErrNone);
00217 
00218     Log::Print(_L("CAsynchReceive::DoCancel() exiting"));
00219 }
00220 
00222 // CAsynchListen
00224 
00225 CAsynchListen::CAsynchListen(CConcreteConnection *aConnection) 
00226     : CAsynchBase(aConnection)
00227 {
00228 }
00229 
00230 CAsynchListen::~CAsynchListen()
00231 {
00232     delete iIncomingSocket;
00233 }
00234 
00235 // will listen to socket from iConnection->GetSocket()
00236 void CAsynchListen::ListenL(const RMessage &aMessage)
00237 {
00238     Log::Print(_L("CAsynchListen::ListenL()"));
00239 
00240     // store the pending message
00241     iMessage = aMessage;
00242 
00243     // deallocate previous socket
00244     delete iIncomingSocket;
00245     iIncomingSocket = NULL;
00246 
00247     // allocate a blank socket 
00248     iIncomingSocket = new (ELeave) RSocket();
00249 
00250     RSocketServ &sock_serv = iConnection->GetSocketServ();
00251     User::LeaveIfError(iIncomingSocket->Open(sock_serv));
00252 
00253     // start waiting for inbound connection
00254     iConnection->GetSocket().Accept(*iIncomingSocket, iStatus);
00255 
00256     SetActive();
00257 
00258     Log::Print(_L("CAsynchListen::ListenL() returning"));
00259 }
00260 
00261 // a new inbound connection pending - estabilish connection and allocate
00262 // resources. completes the original message to allow client call to return
00263 void CAsynchListen::RunL()
00264 {
00265     CConcreteConnection *con = NULL;
00266 
00267     TInt status = iStatus.Int();
00268     if( status != KErrNone ) {
00269         Log::Print(_L("CAsynchListen::RunL() error %d"), status);
00270 
00271         iMessage.Complete(status);
00272         return;
00273     }
00274 
00275     Log::Print(_L("CAsynchListen::RunL()"));
00276 
00277     // allocate new CConcreteConnection for the inbound connection
00278     con = CConcreteConnection::NewL(iIncomingSocket, iConnection->GetSession());
00279 
00280     // forget about the socket as it will be released by others
00281     iIncomingSocket = NULL;
00282 
00283     Log::Print(_L("calling AllocateConnection()"));
00284 
00285     TInt id = iConnection->GetSession().AllocateConnection(con);
00286 
00287     // complete the message with the connection id
00288     iMessage.Complete(id);
00289 }
00290 
00291 // cancel pending listen operation
00292 void CAsynchListen::DoCancel()
00293 {
00294     Log::Print(_L("CAsynchListen::DoCancel()"));
00295 
00296     iConnection->GetSocket().CancelAccept();
00297 
00298     // complete the message with the connection id
00299     //##TODO## no-no.. this wont work
00300     iMessage.Complete(iStatus.Int());
00301 
00302     Log::Print(_L("CAsynchListen::DoCancel() exiting"));
00303 }
00304 
00305 TInt CAsynchListen::RunError(TInt aError)
00306 {
00307     Log::Print(_L("CAsynchListen::RunError(): %d"), aError);
00308 
00309     //##TODO## handle the error
00310 
00311     // complete the message with the connection id
00312     //##TODO## whaat? no-no..
00313     //Log::Print(_L("COMPLETING %d"), iMessage);
00314     iMessage.Complete(iStatus.Int());
00315 
00316     return KErrNone;
00317 }
00318 
00319 

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