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

nudpconnection.cpp

Go to the documentation of this file.
00001 /*
00002  * nudpconnection.cpp,v 1.1 2003/12/27 19:46:23 matti 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 <e32svr.h>
00027 // #include <es_sock.h>
00028 
00029 #include "serversideasynch.h"
00030 #include "nudpconnection.h"
00031 #include "Log.h"
00032 
00033 // constructs a 'normal' connection
00034 CNUDPConnection * CNUDPConnection::NewL(RSocket *aSocket,
00035                     CServerSession &aSession,
00036                     TInt aMtu)
00037 {
00038     CNUDPConnection *con = new (ELeave) CNUDPConnection(aSocket, 
00039                             NULL,
00040                             aSession,
00041                             aMtu);
00042     CleanupStack::PushL(con);
00043     con->ConstructL(EFalse);
00044     CleanupStack::Pop(); // con
00045     return con;
00046 }
00047 
00048 // constructs a listening connection
00049 CNUDPConnection * CNUDPConnection::NewListeningL(RSocket *aSocket,
00050                          RSocketServ *aSocketServ,
00051                          CServerSession &aSession)
00052 {
00053     CNUDPConnection *con = new (ELeave) CNUDPConnection(aSocket, 
00054                             aSocketServ,
00055                             aSession,
00056                             128);  // ##TODO## MTU?
00057     CleanupStack::PushL(con);
00058     con->ConstructL(ETrue);
00059     CleanupStack::Pop(); // con
00060 
00061     return con;
00062 }
00063 
00064 CNUDPConnection::CNUDPConnection(RSocket* aSocket, 
00065                  RSocketServ *aSocketServ,
00066                  CServerSession &aSession,
00067                  TInt aMtu)
00068     : CConcreteConnection(aSocket, aSocketServ, aSession, aMtu)
00069 {
00070     // ##TODO## Get port values somewhere...
00071     iSrcPort = 123;
00072     iDstPort = 124;
00073 }
00074 
00075 CNUDPConnection::~CNUDPConnection()
00076 {
00077     // ##TODO## Reset the state machine?
00078 }
00079 
00080 // sending is asynchronous - possible failure is handled by closing the socket
00081 // the client call will be completed immediately after 
00082 // initiating the send operation
00083 void CNUDPConnection::SendL(TDesC8 *aBuf)
00084 {
00085     Log::Print(_L("CNUDPConnection::SendL()"));
00086 
00087     TInt maxPayload = GetMTU() - KNUDPHeaderSize;
00088     
00089     if (aBuf->Length() > maxPayload) {
00090     // The data must be fragmented
00091     TInt fragmentCount = (aBuf->Length() / maxPayload) + 
00092         (aBuf->Length() % maxPayload > 0 ? 1 : 0);
00093     RPointerArray<TDesC8> *fragments = 
00094         new (ELeave) RPointerArray<TDesC8>(fragmentCount);
00095 
00096     // Constrcuts fragments
00097     TInt pos = 0;
00098     TInt packet = 0;
00099     while (packet++ < fragmentCount) {
00100         if (packet == 1) {
00101         // First packet
00102         fragments->Append(CreateFrame(&(aBuf->Mid(0, maxPayload)),
00103                           KFirstFragment, 
00104                           aBuf->Length()));
00105         } else if (packet == fragmentCount) {
00106         // Last packet
00107         fragments->Append(CreateFrame(&(aBuf->Right(pos)), 
00108                           KLastFragment,
00109                           aBuf->Length() - pos));
00110         } else {
00111         // Middle packet
00112         fragments->Append(CreateFrame(&(aBuf->Mid(pos, maxPayload)),
00113                           KFirstFragment | KLastFragment, 
00114                           aBuf->Length()));
00115         }
00116         pos += maxPayload;
00117     }
00118     iSender->SendL(fragments);
00119     
00120     } else {
00121     // Single fragment
00122     iSender->SendL(CreateFrame(aBuf, 
00123                    KFirstFragment | KLastFragment, 
00124                    aBuf->Length()));
00125     }
00126 }
00127 
00128 void CNUDPConnection::ReceiveL(const RMessage &aMessage) 
00129 {
00130     Log::Print(_L("CNUDPConnection::Receive()"));
00131 
00132     // ##TODO## dum-dum... pitäisi purkaa frame jotenkin ja passata
00133     // vasta sitten data clientille... ongelmia...
00134     // Tehdään oma nudp-spesifinen asynchreceive-luokka, joka hoitaa tämän
00135     // connectionin avulla vastaanottamisen tilakoneen...
00136     // miten mahtaa toimia homma useamman clientin kanssa?
00137     // pidetään tallessa pendaavia rmessageita porttinumeron perusteella
00138     // kun tulee kamaa sisään, haetaan siltä porttinumeron pohjalta
00139     // oikea rmessage ja lopetetaan pendaus
00140 
00141     // dispatch receive. the client call will be completed upon receiving data
00142     iReceiver->Receive(aMessage);
00143 }
00144 
00145 TDesC8 *CNUDPConnection::CreateFrame(TDesC8 *aBuf, TUint8 aFlags, 
00146                      TUint16 aLen)
00147 {
00148     HBufC8 *buf = HBufC8::NewL(aBuf->Length() + KNUDPHeaderSize);
00149     TPtr8 ptr = buf->Des();
00150     // Constructs header
00151     ptr.Append(aFlags);
00152     ptr.Append(aLen);
00153     ptr.Append(iSrcPort);
00154     ptr.Append(iDstPort);
00155     // Adds payload
00156     ptr.Append(*aBuf);
00157 
00158     // ##TODO## Should we delete the aBuf?
00159     return buf;
00160 }

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