sdkcreationmw/sdkruntimes/wsock/src/WinsockInterface.cpp
changeset 0 b26acd06ea60
child 1 ac50fd48361b
equal deleted inserted replaced
-1:000000000000 0:b26acd06ea60
       
     1 /*
       
     2 * Copyright (c) 2004-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #define TRACE_PREFIX "WSOCK: Interface: "
       
    20 #include "wsock.h"
       
    21 #include "WinsockInterface.h"
       
    22 #include "WinsockProtocolFamily.h"
       
    23 
       
    24 const TInt KWinsockSubConnectionId = 1;
       
    25 const TConnectionType EWinsockConnectionType = EConnectionEthernet;
       
    26 #define super CNifIfLink 
       
    27 
       
    28 // CWinsockInterface::CallbackQueueEntry
       
    29 class CWinsockInterface::CallbackQueueEntry
       
    30 {
       
    31 private:
       
    32     CWinsockInterface* iInterface;
       
    33     CallbackMethod iMethod;
       
    34     TInt iParam1;
       
    35     TInt iParam2;
       
    36 public:
       
    37     TSglQueLink iLink;
       
    38     CallbackQueueEntry(CWinsockInterface* aInterface, CallbackMethod aMethod,
       
    39         TInt aParam1, TInt aParam2) : iInterface(aInterface), 
       
    40         iMethod(aMethod), iParam1(aParam1), iParam2(aParam2) {}
       
    41     void Invoke() { (iInterface->*iMethod)(iParam1, iParam2); }
       
    42 };
       
    43 
       
    44 // CWinsockInterface
       
    45 CWinsockInterface::CWinsockInterface(CNifIfFactory* aFactory, 
       
    46                                      MNifIfNotify* aNotify) : 
       
    47 super(*aFactory),
       
    48 iSignature(KWinsockInterfaceSignature),
       
    49 iCallbackQueue(_FOFF(CallbackQueueEntry,iLink)),
       
    50 iCallback(TCallBack(AsyncCallbackProc,this),CActive::EPriorityStandard)
       
    51 {
       
    52     iNotify = aNotify;
       
    53     iTimeStarted.HomeTime();
       
    54     TRACE1("created [%08X]",this);
       
    55 }
       
    56 
       
    57 CWinsockInterface::~CWinsockInterface()
       
    58 {
       
    59     CancelOutstandingCallbacks();
       
    60     TRACE1("destroyed [%08X]",this);
       
    61 }
       
    62 
       
    63 TInt CWinsockInterface::Signature() const
       
    64 {
       
    65     return KWinsockInterfaceSignature;
       
    66 }
       
    67 
       
    68 TInt CWinsockInterface::AsyncCallbackProc(TAny* aPtr)
       
    69 {
       
    70     CWinsockInterface* self = (CWinsockInterface*)aPtr;
       
    71     self->HandleAsyncCallback();
       
    72     return KErrNone;
       
    73 }
       
    74 
       
    75 void CWinsockInterface::HandleAsyncCallback()
       
    76 {
       
    77     // Invoke the first callback in the queue
       
    78     if (!iCallbackQueue.IsEmpty()) {
       
    79         CallbackQueueEntry* entry = iCallbackQueue.First();
       
    80         iCallbackQueue.Remove(*entry);
       
    81         entry->Invoke();
       
    82         delete entry;
       
    83 
       
    84         // Schedule the next one
       
    85         if (!iCallbackQueue.IsEmpty()) {
       
    86             iCallback.CallBack();
       
    87         }
       
    88     }
       
    89 }
       
    90 
       
    91 void CWinsockInterface::ScheduleAsyncCallback(CallbackMethod aMethod,
       
    92                                               TInt aP1, TInt aP2)
       
    93 {
       
    94     CallbackQueueEntry* entry = new CallbackQueueEntry(this,aMethod,aP1,aP2);
       
    95     if (entry) {
       
    96         iCallbackQueue.AddLast(*entry);
       
    97         iCallback.Cancel();
       
    98         iCallback.CallBack();
       
    99     }
       
   100 }
       
   101 
       
   102 void CWinsockInterface::CancelOutstandingCallbacks()
       
   103 {
       
   104     iCallback.Cancel();
       
   105     while (!iCallbackQueue.IsEmpty()) {
       
   106         CallbackQueueEntry* entry = iCallbackQueue.First();
       
   107         iCallbackQueue.Remove(*entry);
       
   108         delete entry;
       
   109     }
       
   110 }
       
   111 
       
   112 void CWinsockInterface::NotifyLinkLayerUp(TInt, TInt)
       
   113 {
       
   114     ScheduleAsyncCallback(NotifySubConnectionOpened);
       
   115     TRACE("firing LinkLayerUp event");
       
   116     iNotify->LinkLayerUp();
       
   117 }
       
   118 
       
   119 void CWinsockInterface::NotifyLinkLayerOpen(TInt, TInt)
       
   120 {
       
   121     TRACE("firing LinkLayerOpen event");
       
   122     iNotify->IfProgress(KLinkLayerOpen, KErrNone);
       
   123 }
       
   124 
       
   125 // Sends a subconnection opened event for the entire connection
       
   126 void CWinsockInterface::NotifySubConnectionOpened(TInt, TInt)
       
   127 {
       
   128     ScheduleAsyncCallback(NotifyLinkLayerOpen);
       
   129 
       
   130     TRACE("firing TSubConnectionOpenedEvent");
       
   131     TSubConnectionOpenedEvent event;
       
   132     event.iSubConnectionUniqueId = KNifEntireConnectionSubConnectionId;
       
   133     TPckg<TSubConnectionOpenedEvent> eventPtr(event);
       
   134     iNotify->NifEvent(ESubConnectionEvent, ESubConnectionOpened, eventPtr); 
       
   135 }
       
   136 
       
   137 // Sends a subconnection Closed event for the entire connection
       
   138 void CWinsockInterface::NotifySubConnectionClosed(TInt aReason, TInt)
       
   139 {
       
   140     ScheduleAsyncCallback(NotifyLinkLayerClosed, aReason);
       
   141 
       
   142     TRACE("firing TSubConnectionClosedEvent");
       
   143     TSubConnectionClosedEvent event;
       
   144     event.iSubConnectionUniqueId = KNifEntireConnectionSubConnectionId;
       
   145     event.iTotalUplinkDataVolume = iBytesReceived;
       
   146     event.iTotalDownlinkDataVolume = iBytesSent;
       
   147     event.iTimeClosed.UniversalTime();
       
   148     TPckg<TSubConnectionClosedEvent> eventPtr(event);
       
   149     iNotify->NifEvent(ESubConnectionEvent, ESubConnectionClosed, eventPtr);
       
   150 }
       
   151 
       
   152 void CWinsockInterface::NotifyLinkLayerDown(TInt aReason, TInt aAction)
       
   153 {
       
   154     ScheduleAsyncCallback(NotifySubConnectionClosed, aReason);
       
   155     TRACE("firing LinkLayerDown event");
       
   156     iNotify->LinkLayerDown(aReason, (MNifIfNotify::TAction)aAction);
       
   157 }
       
   158 
       
   159 void CWinsockInterface::NotifyLinkLayerClosed(TInt aReason, TInt)
       
   160 {
       
   161     TRACE("firing LinkLayerClosed event");
       
   162     iNotify->IfProgress(KLinkLayerClosed, aReason);
       
   163 }
       
   164 
       
   165 void CWinsockInterface::DataSent(TUint aBytes)
       
   166 {
       
   167     // Handle rollover?
       
   168     iBytesSent += aBytes;
       
   169     if (iBytesSentGranularity)
       
   170     {
       
   171         TUint delta = iBytesSent - iBytesSentMark;
       
   172         if (delta >= iBytesSentGranularity)
       
   173         {
       
   174             int chunks = delta/iBytesSentGranularity;
       
   175             iBytesSentMark += chunks*iBytesSentGranularity;
       
   176             iNotify->NotifyDataSent(KWinsockSubConnectionId,
       
   177                 delta*iBytesSentGranularity);
       
   178         }
       
   179     }
       
   180 }
       
   181 
       
   182 void CWinsockInterface::DataReceived(TUint aBytes)
       
   183 {
       
   184     // Handle rollover?
       
   185     iBytesReceived += aBytes;
       
   186     if (iBytesReceivedGranularity)
       
   187     {
       
   188         TUint delta = iBytesReceived - iBytesReceivedMark;
       
   189         if (delta >= iBytesReceivedGranularity)
       
   190         {
       
   191             int chunks = delta/iBytesReceivedGranularity;
       
   192             iBytesReceivedMark += chunks*iBytesReceivedGranularity;
       
   193             iNotify->NotifyDataReceived(KWinsockSubConnectionId,
       
   194                 delta*iBytesReceivedGranularity);
       
   195         }
       
   196     }
       
   197 }
       
   198 
       
   199 // CNifIfBase
       
   200 void CWinsockInterface::Info(TNifIfInfo& aInfo) const
       
   201 {
       
   202     aInfo.iName = KWinsockInterface;
       
   203     aInfo.iVersion = TVersion(1,0,0);
       
   204     aInfo.iFlags = KNifIfIsBase | KNifIfIsLink | KNifIfUsesNotify | KNifIfCreatedByFactory;
       
   205     aInfo.iProtocolSupported = 0;
       
   206     for (TInt i=0; i<CWinsockProtocolFamily::ProtocolCount(); i++)
       
   207     {
       
   208         const TServerProtocolDesc* p = CWinsockProtocolFamily::ProtocolDesc(i);
       
   209         aInfo.iProtocolSupported |= p->iProtocol;
       
   210     }
       
   211 }
       
   212 
       
   213 TInt CWinsockInterface::Send(RMBufChain& /*aPdu*/, TAny* /*aSource*/)
       
   214 {
       
   215     TRACE("Send()");
       
   216     return KErrNotSupported;
       
   217 }
       
   218 
       
   219 TInt CWinsockInterface::Notification(TAgentToNifEventType DEBUG_ONLY(aEvent),
       
   220                                      TAny* /*aInfo*/)
       
   221 {
       
   222     TRACE1("Notification(%d)",aEvent);
       
   223     return KErrNotSupported;
       
   224 }
       
   225 
       
   226 // CNifIfLink
       
   227 TInt CWinsockInterface::Start()
       
   228 {
       
   229     TRACE("Start()");
       
   230     ScheduleAsyncCallback(NotifyLinkLayerUp);
       
   231     return KErrNone;
       
   232 }
       
   233 
       
   234 void CWinsockInterface::Stop(TInt aReason, MNifIfNotify::TAction aAction)
       
   235 {
       
   236     TRACE2("Stop(%d,%d)",aReason, aAction);
       
   237     CancelOutstandingCallbacks();
       
   238     ScheduleAsyncCallback(NotifyLinkLayerDown, aReason, aAction);
       
   239 }
       
   240 
       
   241 CNifIfBase* CWinsockInterface::GetBinderL(const TDesC& DEBUG_ONLY(aName))
       
   242 {
       
   243     TRACE1("GetBinderL(%S)",&aName);
       
   244     return this;
       
   245 }
       
   246 
       
   247 TInt CWinsockInterface::Control(TUint aLevel,TUint aName,TDes8& aOption, 
       
   248                                 TAny* aSource)
       
   249 {
       
   250     TRACE3("Control(%d,%08X), %d bytes",aLevel,aName,aOption.Length());
       
   251 	switch (aLevel)
       
   252     {
       
   253     case KCOLInterface:
       
   254         switch (aName)
       
   255         {
       
   256         case KCOGetNifEMIPtr:
       
   257         default:
       
   258             {
       
   259                 MNifIfExtendedManagementInterface** that = 
       
   260                     (MNifIfExtendedManagementInterface**)aOption.Ptr();
       
   261                 if (aOption.Length() == sizeof(*that))
       
   262                 {
       
   263                     MNifIfExtendedManagementInterface* This = this;
       
   264                     TRACE1("MNifIfExtendedManagementInterface = %08X",This);
       
   265                     *that = This;
       
   266                     return KErrNone;
       
   267                 }
       
   268                 else
       
   269                 {
       
   270                     return KErrArgument;
       
   271                 }
       
   272             }
       
   273             break;
       
   274         }
       
   275         break;
       
   276 
       
   277     case KCOLAgent:
       
   278         switch (aName)
       
   279         {
       
   280         case KCOGetAgentEMIPtr:
       
   281             {
       
   282                 MNifAgentExtendedManagementInterface** that = 
       
   283                     (MNifAgentExtendedManagementInterface**)aOption.Ptr();
       
   284                 if (aOption.Length() == sizeof(*that))
       
   285                 {
       
   286                     MNifAgentExtendedManagementInterface* This = this;
       
   287                     TRACE1("MNifAgentExtendedManagementInterface = %08X",This);
       
   288                     *that = This;
       
   289                     return KErrNone;
       
   290                 }
       
   291                 else
       
   292                 {
       
   293                     return KErrArgument;
       
   294                 }
       
   295             }
       
   296         default:
       
   297             break;
       
   298         }
       
   299         break;
       
   300 
       
   301     default:
       
   302         break;
       
   303     }
       
   304     return super::Control(aLevel, aName, aOption, aSource);
       
   305 }
       
   306 
       
   307 // MNifIfExtendedManagementInterface
       
   308 TInt CWinsockInterface::Stop(TSubConnectionUniqueId aId, 
       
   309                              TInt DEBUG_ONLY(aReason))
       
   310 {
       
   311     TRACE2("Stop(%d,%d)", aId, aReason);
       
   312     switch (aId)
       
   313     {
       
   314     case KNifEntireConnectionSubConnectionId:
       
   315     case KWinsockSubConnectionId:
       
   316         return KErrNone;
       
   317     default:
       
   318         return KErrNotFound;
       
   319     }
       
   320 }
       
   321 
       
   322 TInt CWinsockInterface::GetDataTransferred(TSubConnectionUniqueId aId, 
       
   323                                            TUint& aSentBytes, 
       
   324                                            TUint& aReceivedBytes)
       
   325 {
       
   326     TRACE1("GetDataTransferred(%d)", aId);
       
   327     switch (aId)
       
   328     {
       
   329     case KNifEntireConnectionSubConnectionId:
       
   330     case KWinsockSubConnectionId:
       
   331         aSentBytes = iBytesSent;
       
   332         aReceivedBytes = iBytesReceived;
       
   333         return KErrNone;
       
   334     default:
       
   335         return KErrNotFound;
       
   336     }
       
   337 }
       
   338 
       
   339 TInt CWinsockInterface::SetDataSentNotificationGranularity(TSubConnectionUniqueId aId, 
       
   340                                                            TUint aGranularity)
       
   341 {
       
   342     TRACE2("SetDataSentNotificationGranularity(%d,%d)", aId, aGranularity);
       
   343     switch (aId)
       
   344     {
       
   345     case KNifEntireConnectionSubConnectionId:
       
   346     case KWinsockSubConnectionId:
       
   347         iBytesSentGranularity = aGranularity;
       
   348         return KErrNone;
       
   349     default:
       
   350         return KErrNotFound;
       
   351     }
       
   352 }
       
   353 
       
   354 TInt CWinsockInterface::CancelDataSentNotification(TSubConnectionUniqueId aId)
       
   355 {
       
   356     TRACE1("CancelDataSentNotification(%d)", aId);
       
   357     switch (aId)
       
   358     {
       
   359     case KNifEntireConnectionSubConnectionId:
       
   360     case KWinsockSubConnectionId:
       
   361         iBytesSentGranularity = 0;
       
   362         return KErrNone;
       
   363     default:
       
   364         return KErrNotFound;
       
   365     }
       
   366 }
       
   367 
       
   368 TInt CWinsockInterface::SetDataReceivedNotificationGranularity(TSubConnectionUniqueId aId, 
       
   369                                                                TUint aGranularity)
       
   370 {
       
   371     TRACE2("SetDataReceivedNotificationGranularity(%d,%d)", aId, aGranularity);
       
   372     switch (aId)
       
   373     {
       
   374     case KNifEntireConnectionSubConnectionId:
       
   375     case KWinsockSubConnectionId:
       
   376         iBytesReceivedGranularity = aGranularity;
       
   377         return KErrNone;
       
   378     default:
       
   379         return KErrNotFound;
       
   380     }
       
   381 }
       
   382 
       
   383 TInt CWinsockInterface::CancelDataReceivedNotification(TSubConnectionUniqueId aId)
       
   384 {
       
   385     TRACE1("CancelDataReceivedNotification(%d)", aId);
       
   386     switch (aId)
       
   387     {
       
   388     case KNifEntireConnectionSubConnectionId:
       
   389     case KWinsockSubConnectionId:
       
   390         iBytesReceivedGranularity = 0;
       
   391         return KErrNone;
       
   392     default:
       
   393         return KErrNotFound;
       
   394     }
       
   395 }
       
   396 
       
   397 // MNifAgentExtendedManagementInterface
       
   398 TInt CWinsockInterface::GetInterfaceType(TConnectionType& aConnectionType)
       
   399 {
       
   400     aConnectionType = EWinsockConnectionType;
       
   401     return KErrNone;
       
   402 }
       
   403 
       
   404 TInt CWinsockInterface::EnumerateSubConnections(TUint& aCount)
       
   405 {
       
   406     aCount = 1;
       
   407     return KErrNone;
       
   408 }
       
   409 
       
   410 TInt CWinsockInterface::GetSubConnectionInfo(TUint aIndex, 
       
   411                                              TDes8& aInfo)
       
   412 {
       
   413     if (aInfo.Length() != sizeof(TSubConnectionInfo))
       
   414     {
       
   415         return KErrArgument;
       
   416     }
       
   417 
       
   418     TSubConnectionInfo* info = (TSubConnectionInfo*)aInfo.Ptr();
       
   419     switch (aIndex)
       
   420     {
       
   421     case KNifEntireConnectionSubConnectionId:
       
   422     case KWinsockSubConnectionId:
       
   423         info->iConnectionType = EWinsockConnectionType;
       
   424         info->iSubConnectionUniqueId = aIndex;
       
   425         info->iTimeStarted = iTimeStarted;
       
   426         return KErrNone;
       
   427     default:
       
   428         return KErrNotFound;
       
   429     }
       
   430 }
       
   431 
       
   432 TInt CWinsockInterface::GetSubConnectionInfo(TDes8& aInfo)
       
   433 {
       
   434     if (aInfo.Length() != sizeof(TSubConnectionInfo))
       
   435     {
       
   436         return KErrArgument;
       
   437     }
       
   438 
       
   439     TSubConnectionInfo* info = (TSubConnectionInfo*)aInfo.Ptr();
       
   440     return GetSubConnectionInfo(info->iSubConnectionUniqueId, aInfo);
       
   441 }