datacommsserver/esockserver/ssock/ss_sap.cpp
changeset 0 dfb7c4ff071f
child 9 77effd21b2c9
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file SS_SAP.CPP
       
    18 */
       
    19 
       
    20 #define SYMBIAN_NETWORKING_UPS
       
    21 
       
    22 #include <ss_std.h>
       
    23 #include <ss_glob.h>
       
    24 #include <comms-infras/ss_roles.h>
       
    25 #include <comms-infras/ss_log.h>
       
    26 #include <comms-infras/ss_subconnflow.h>
       
    27 #include <ss_protprov.h>
       
    28 #include <comms-infras/es_sap.h>
       
    29 #include <ss_sock.h>
       
    30 #include <comms-infras/ss_nodemessages_dataclient.h>
       
    31 
       
    32 #include <elements/nm_signatures.h>
       
    33 
       
    34 
       
    35 #ifdef _DEBUG
       
    36 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    37 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    38 _LIT(KSpecAssert_ESockSSockss_sp, "ESockSSockss_sp.");
       
    39 #endif
       
    40 
       
    41 using namespace ESock;
       
    42 using namespace Messages;
       
    43 
       
    44 
       
    45 EXPORT_C CNetworkFlow::CNetworkFlow(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
    46 	: CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf)
       
    47 	{
       
    48 	}
       
    49 
       
    50 EXPORT_C CNetworkFlow::~CNetworkFlow()
       
    51 	{
       
    52 	if (iLowerFlow)
       
    53 		{
       
    54 		iLowerFlow->Unbind(NULL,NULL);
       
    55 		}
       
    56 	}
       
    57 void
       
    58 CNetworkFlow::SetLocalName(TSockAddr& anAddr)
       
    59 /** Sets the local name (address) of the socket service provider entity. The format
       
    60 of the data in the TSockAddr object is defined by individual protocols.
       
    61 
       
    62 @param anAddr The address
       
    63 @return Returns KErrNone if the local name is correctly set or, if this is
       
    64 not the case, an informative error number. */
       
    65 	{
       
    66 	iLocalAddressSet = ETrue;
       
    67 	iLocalAddress = anAddr;
       
    68 	
       
    69 	}
       
    70 
       
    71 TInt CNetworkFlow::SetRemName(TSockAddr& anAddr)
       
    72 /** Sets the remote name (address) of the socket service provider entity. The format
       
    73 of the data in the TSockAddr object is defined by individual protocols.
       
    74 
       
    75 @param anAddr The address
       
    76 @return Returns KErrNone if the remote name is correctly set or, if this is
       
    77 not the case, an informative error number. */
       
    78 	{
       
    79 	iRemoteAddressSet = ETrue;
       
    80 	iRemoteAddress = anAddr;
       
    81 	return KErrNone;
       
    82 	}
       
    83 
       
    84 void CNetworkFlow::UpdateDestinationAddress(const TSockAddr& aDest)
       
    85 	{
       
    86 	iRemoteAddress = aDest;
       
    87 	iRemoteAddressSet = ETrue;
       
    88 	}
       
    89 
       
    90 TUint CNetworkFlow::Write(const TDesC8& /*aDesc*/, TUint /*aOptions*/, TSockAddr* anAddr)
       
    91 /** Sends data onto the network via the protocol.
       
    92 
       
    93 Connection-oriented sockets must be in a connected state (that is ConnectComplete() has
       
    94 been called on their MSocketNotify before Write() is called).
       
    95 
       
    96 The socket server keeps track of how much data is waiting and then tries to send it all
       
    97 until the protocol tells it to hold off by returning 0 (datagram sockets) or 'less than
       
    98 all data consumed' (stream sockets) to Write(). The protocol should call CanSend() when it
       
    99 is ready to send more data.
       
   100 
       
   101 anAddr is the address to write the data to.	Connection oriented sockets always use the
       
   102 default value.
       
   103 
       
   104 @param aDesc The data to be sent.
       
   105 @param aOptions Protocol specific options.
       
   106 @param anAddr Address to write the data to.
       
   107 
       
   108 @returns For stream-oriented protocols the return value is the number of bytes actually written.
       
   109 If this is less than the length of the descriptor then the protocol should call CanSend()
       
   110 when it is ready to send more data. For datagram-oriented protocols, the write should return
       
   111 either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds -
       
   112 no other values are valid. If the Write() must return 0, then it should call CanSend() when it is
       
   113 ready to send more data. If the Write() fails due to some error, then it should call Error() with
       
   114 an informative error number.
       
   115 */
       
   116 	{
       
   117 	if (anAddr)
       
   118 		{
       
   119 		UpdateDestinationAddress(*anAddr);
       
   120 		}
       
   121 	return KErrNone;
       
   122 	}
       
   123 
       
   124 TInt CNetworkFlow::Write(RMBufChain& /*aData*/, TUint /*aOptions*/, TSockAddr* anAddr)
       
   125 /** Sends data onto the network via the protocol.
       
   126 
       
   127 Connection-oriented sockets must be in a connected state (that is ConnectComplete() has
       
   128 been called on their MSocketNotify before Write() is called).
       
   129 
       
   130 The socket server keeps track of how much data is waiting and then tries to send it all
       
   131 until the protocol tells it to hold off by returning 0 (datagram sockets) or 'less than
       
   132 all data consumed' (stream sockets) to Write(). The protocol should call CanSend() when it
       
   133 is ready to send more data.
       
   134 
       
   135 anAddr is the address to write the data to.	Connection oriented sockets always use the
       
   136 default value.
       
   137 
       
   138 @param aData The data to be sent.
       
   139 @param aOptions Protocol specific options.
       
   140 @param anAddr Address to write the data to.
       
   141 
       
   142 @returns For stream-oriented protocols the return value is the number of bytes actually written.
       
   143 If this is less than the length of the descriptor then the protocol should call CanSend()
       
   144 when it is ready to send more data. For datagram-oriented protocols, the write should return
       
   145 either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds -
       
   146 no other values are valid. If the Write() must return 0, then it should call CanSend() when it is
       
   147 ready to send more data. If the Write() fails due to some error, then it should call Error() with
       
   148 an informative error number.
       
   149 */
       
   150 	{
       
   151 	if (anAddr)
       
   152 		{
       
   153 		UpdateDestinationAddress(*anAddr);
       
   154 		}
       
   155 	return KErrNone;
       
   156 	}
       
   157 
       
   158 
       
   159 
       
   160 void CNetworkFlow::BindToL(const TCFDataClient::TBindTo& aBindTo)
       
   161 /**
       
   162 Request from control side (at network layer) to indicate that the SubConnection is
       
   163 up and running and that we should bind to a Flow below.
       
   164 
       
   165 @param aLowerFlow Flow below to bind to.
       
   166 */
       
   167 	{
       
   168 	LOG( ESockLog::Printf(_L("CNetworkFlow %08x:\tBindTo()"), this) );
       
   169 
       
   170 	const TNodeId& commsId = aBindTo.iNodeId;
       
   171 #if defined(__GCCXML__)
       
   172     CSubConnectionFlowBase* flow = reinterpret_cast<CSubConnectionFlowBase*>(reinterpret_cast<Messages::ANode*>(commsId.Ptr()));
       
   173 #else
       
   174     CSubConnectionFlowBase* flow = mcfnode_cast<CSubConnectionFlowBase>(reinterpret_cast<Messages::ANode*>(commsId.Ptr()));
       
   175 #endif
       
   176 
       
   177     if (flow==NULL)
       
   178         {
       
   179         __ASSERT_DEBUG(!commsId.IsNull(), User::Panic(KSpecAssert_ESockSSockss_sp, 1));
       
   180         iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(KErrDisconnected).CRef());
       
   181         }
       
   182 
       
   183     //flows can only be directly bound when running in the same thread
       
   184     //Are we in the same thread?
       
   185     __ASSERT_DEBUG(commsId.Thread() == Id().Thread(), User::Panic(KSpecAssert_ESockSSockss_sp, 2));
       
   186 
       
   187 	if (iLowerFlow && iLowerFlow->Flow() != flow )
       
   188     	{
       
   189     	//already bound -> unbind first.
       
   190     	iLowerFlow->Unbind(NULL,NULL);
       
   191     	iLowerFlow = NULL;
       
   192     	iLowerControl = NULL;
       
   193     	}
       
   194     	
       
   195     if (iLowerFlow == NULL && flow != NULL)
       
   196         {
       
   197         iLowerFlow = flow->GetBinderControlL();
       
   198     	iLowerControl = iLowerFlow->GetControlL(KNullDesC8);
       
   199     	iLowerFlow->BindL(KNullDesC8, NULL,NULL);
       
   200         }
       
   201 	}
       
   202 
       
   203 MSessionControl* CNetworkFlow::GetControlL(TInt /*aSessionType*/,MSessionControlNotify& aSessionControlNotify)
       
   204     {
       
   205 	__ASSERT_DEBUG(iSessionControlNotify == NULL, User::Panic(KSpecAssert_ESockSSockss_sp, 3));
       
   206 	iSessionControlNotify = &aSessionControlNotify;
       
   207 	return this;
       
   208     }
       
   209 
       
   210 MSessionData* CNetworkFlow::BindL(MSessionDataNotify& aNotify)
       
   211     {
       
   212 	__ASSERT_DEBUG(iSessionDataNotify == NULL, User::Panic(KSpecAssert_ESockSSockss_sp, 4));
       
   213 	iSessionDataNotify = &aNotify;
       
   214 	iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TActive().CRef());
       
   215 	return this;
       
   216     }
       
   217 
       
   218 void CNetworkFlow::Unbind()
       
   219     {
       
   220     if (iSessionDataNotify)			// if not already unbound
       
   221     	{
       
   222     	iSessionControlNotify = NULL;
       
   223 		iSessionDataNotify = NULL;
       
   224 		if(iSubConnectionProvider.IsOpen())
       
   225 			{
       
   226 			if(iDCIdle < EIdle)
       
   227 				{
       
   228 				iDCIdle = EIdle;
       
   229 		    	ProcessDCIdleState();
       
   230 				}
       
   231 			}
       
   232 		else
       
   233 			{
       
   234 			// Legacy flows lack a SCPR to look after their destruction so need to suicide
       
   235 			delete this;
       
   236 			}
       
   237     	}
       
   238     }
       
   239 
       
   240 CSubConnectionFlowBase* CNetworkFlow::Flow()
       
   241     {
       
   242     return this;
       
   243     }
       
   244 
       
   245 MFlowBinderControl* CNetworkFlow::DoGetBinderControlL()
       
   246 	{
       
   247 	return this;
       
   248 	}
       
   249 
       
   250 void CNetworkFlow::ProcessDCIdleState()
       
   251 	{
       
   252 #ifdef SYMBIAN_NETWORKING_UPS
       
   253 	if(iDCIdle == EIdle && !ActivityRunning())
       
   254 #else
       
   255 	if(iDCIdle == EIdle && !iNoBearerRunning)
       
   256 #endif
       
   257 		{
       
   258 		iDCIdle = EIdleSent;
       
   259 		iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
   260 		}
       
   261 	}
       
   262 
       
   263 
       
   264