tcpiputils/dhcp/src/DHCPStates.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-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 // Implements the DHCPv4 States representing each interface
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file DHCPStates.cpp
       
    20  @internalTechnology
       
    21 */
       
    22 
       
    23 #include "DHCPStates.h"
       
    24 #ifdef _DEBUG
       
    25 #include "DHCPServer.h"
       
    26 #endif
       
    27 #ifdef SYMBIAN_ESOCK_V3
       
    28 #include <networking/ipeventtypes.h>
       
    29 #include <comms-infras/netsignalevent.h>
       
    30 #endif
       
    31 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
    32 #include "DHCPAuthentication.h"  //DHCPv4::KReqMaxRetry is defined in this file
       
    33 #endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS			
       
    34 #include "DHCPStatesDebug.h"
       
    35 
       
    36 CDHCPState::~CDHCPState()
       
    37 /**
       
    38   * Destructor for this state base class
       
    39   *
       
    40   * @internalTechnology
       
    41   */
       
    42 	{
       
    43 	delete iNext;
       
    44 	}
       
    45 
       
    46 CDHCPState* CDHCPState::ProcessAckNakL(TRequestStatus* aStatus)
       
    47 /**
       
    48   * Handle acknowledgement and negative acknowlegements
       
    49   *
       
    50   * @internalTechnology
       
    51   */
       
    52 	{
       
    53 	CDHCPStateMachine& rDHCP = Dhcp();
       
    54 	return rDHCP.HandleReplyL( aStatus );
       
    55 	}
       
    56 
       
    57 void CDHCPState::Cancel()
       
    58 /**
       
    59   * Cancel any pending outstanding request
       
    60   *
       
    61   * @internalTechnology
       
    62   */
       
    63 	{
       
    64 	}
       
    65 	
       
    66 		
       
    67 
       
    68 #ifdef SYMBIAN_ESOCK_V3
       
    69 SFactoryChannel::~SFactoryChannel()
       
    70 	{
       
    71 	if ( iC32Root.Handle() )
       
    72 		{
       
    73 		iC32Root.Close();
       
    74 		}
       
    75 	}
       
    76 
       
    77 void SFactoryChannel::SendMessageL( NetMessages::CMessage& aQuery )
       
    78 	{
       
    79 	//connect to root server and find an instance
       
    80 	if ( !iC32Root.Handle() )
       
    81 		{
       
    82 		User::LeaveIfError(iC32Root.Connect());
       
    83 		}
       
    84 	//send a message to find a channel instance
       
    85 	TInt nLen = aQuery.Length();
       
    86 	iBuf.Close();
       
    87 	iBuf.CreateL( nLen );
       
    88 	TPtr8 ptr( const_cast<TUint8*>(iBuf.Ptr()), iBuf.MaxLength() );
       
    89 	User::LeaveIfError( aQuery.Store( ptr ) );
       
    90 	iBuf.SetLength( ptr.Length() );
       
    91 	//this should be very quick so we can afford to hold different interfaces up for a while
       
    92 	//we should really have a solution for servers running each session in a different thread
       
    93 	User::LeaveIfError( iC32Root.SendMessage( iModule, CommsFW::EFactoryMsg, ptr ) );
       
    94 	TPtrC8 ptrC( ptr );
       
    95 	User::LeaveIfError( aQuery.GetTypeId().Check( ptrC ) );
       
    96 	User::LeaveIfError( aQuery.Load( ptrC ) );
       
    97 	}
       
    98 
       
    99 SDhcpSignal::~SDhcpSignal()
       
   100 	{
       
   101 	delete iQuery;
       
   102 	delete iNetSubscribe;
       
   103 	}
       
   104 
       
   105 void SDhcpSignal::SubscribeL(const TName& aInterfaceName, TInt aEventId, NetSubscribe::TEvent& aEvent )
       
   106 	{
       
   107 	iModule.Copy( _L( "ESock_DIP" ) );
       
   108 	if ( !iQuery )
       
   109 		{
       
   110 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("SDhcpSignal::SubscribeL NetMessages::CTypeIdQuery::NewL")));
       
   111 		iQuery = NetMessages::CTypeIdQuery::NewL();
       
   112 		iQuery->iUid = IPEvent::KFactoryImplementationUid;
       
   113 		iQuery->iTypeId = IPEvent::KProtocolId;
       
   114 		iQuery->iHandle = NULL;
       
   115 		iQuery->iOid.Copy( aInterfaceName.Left( iQuery->iOid.MaxLength() ) );
       
   116 		}
       
   117 	if ( !iQuery->iHandle )
       
   118 		{
       
   119 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("SDhcpSignal::SubscribeL handle = 0")));
       
   120 		SFactoryChannel::SendMessageL( *iQuery );
       
   121 
       
   122 		STypeId typeId = STypeId::CreateSTypeId( NetSubscribe::KTransportUid, NetSubscribe::EPublishSubscribe );
       
   123 		ASSERT( !iNetSubscribe );
       
   124 		iNetSubscribe = NetSubscribe::CNetSubscribe::NewL( typeId );
       
   125 
       
   126 		NetSubscribe::SSignalId signalId( IPEvent::KEventImplementationUid, aEventId, iQuery->iHandle );
       
   127 		aEvent.SubscribeL(*iNetSubscribe, signalId);
       
   128 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("SDhcpSignal::SubscribeL registered for signal handle = %d"), iQuery->iHandle));
       
   129 		//and wait for the signal
       
   130 		}
       
   131 	else
       
   132 		{//deregister & release the handle
       
   133 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("SDhcpSignal::SubscribeL deregister & release the handle")));
       
   134 		aEvent.Cancel(*iNetSubscribe);
       
   135 		SFactoryChannel::SendMessageL( *iQuery );
       
   136 		}
       
   137 	}
       
   138 #endif
       
   139 
       
   140 CAsynchEvent* CDHCPAddressAcquisition::ProcessL(TRequestStatus& aStatus)
       
   141 /**
       
   142   * Interface function, execute state machine
       
   143   *
       
   144   * @internalTechnology
       
   145   */
       
   146 	{
       
   147     DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPIPAddressAcquisition);
       
   148 	CDHCPStateMachine& rDHCP = Dhcp();
       
   149 	rDHCP.InitialiseSocketL();
       
   150 
       
   151 	rDHCP.CreateDiscoverMsgL();
       
   152 
       
   153 	// one second retransmit passed to CloseNsendMsgL
       
   154 	rDHCP.CloseNSendMsgL(KOneSecond,rDHCP.iMaxRetryCount,CDHCPStateMachine::EAllAvailableServers);
       
   155 	TRequestStatus* p = &aStatus;
       
   156 	User::RequestComplete(p, KErrNone); //move to the next state
       
   157 	return iNext;
       
   158 	}
       
   159 
       
   160 CAsynchEvent* CDHCPSelect::ProcessL(TRequestStatus& aStatus)
       
   161 /**
       
   162   * Interface function, execute state machine
       
   163   *
       
   164   * @internalTechnology
       
   165   */
       
   166 	{
       
   167 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPSelect);
       
   168 	CDHCPStateMachine& rDHCP = Dhcp();
       
   169 	rDHCP.iReceiving = EFalse;
       
   170 	rDHCP.HandleOfferL();
       
   171 	rDHCP.CreateOfferAcceptanceRequestMsgL();
       
   172 	// one second initial retransmit passed to CloseNsendMsgL
       
   173 	rDHCP.CloseNSendMsgL(KOneSecond, rDHCP.iMaxRetryCount, CDHCPStateMachine::EAllAvailableServers);
       
   174 	TRequestStatus* p = &aStatus;
       
   175 	User::RequestComplete(p, KErrNone); //move to the next state
       
   176 	
       
   177 	return iNext;
       
   178 	}
       
   179 
       
   180 CAsynchEvent* CDHCPInformationConfig::ProcessL(TRequestStatus& aStatus)
       
   181 /**
       
   182   * Interface function, execute state machine
       
   183   *
       
   184   * @internalTechnology
       
   185   */
       
   186 	{
       
   187 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPInformationConfig);
       
   188 	CDHCPStateMachine& rDHCP = Dhcp();
       
   189 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS	
       
   190 	if (rDHCP.iDhcpInformAckPending)
       
   191 		{
       
   192 		rDHCP.BindSocketForUnicastL();
       
   193 		}
       
   194 	else
       
   195 		{
       
   196 #endif// SYMBIAN_NETWORKING_DHCP_MSG_HEADERS		
       
   197 	rDHCP.InitialiseSocketL();
       
   198 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS	
       
   199 		}
       
   200 #endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS			
       
   201 	rDHCP.CreateInformMsgL();
       
   202 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS	
       
   203 	if (rDHCP.iDhcpInformAckPending) //new condition added for dynamic dhcp inform message-For IPv4 only
       
   204 		{
       
   205 		rDHCP.CloseNSendMsgL(KOneSecond, DHCPv4::KReqMaxRetry,CDHCPStateMachine::EUnicast);
       
   206 		}
       
   207 	else
       
   208 		{
       
   209 #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS		
       
   210 		// one second initial retransmit passed to CloseNsendMsgL
       
   211 		rDHCP.CloseNSendMsgL(KOneSecond, rDHCP.iMaxRetryCount,CDHCPStateMachine::EAllAvailableServers);
       
   212 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   213 		}	
       
   214 #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS		
       
   215 	TRequestStatus* p = &aStatus;
       
   216 	User::RequestComplete(p, KErrNone); //move to the next state
       
   217 	return iNext;
       
   218 	}
       
   219 
       
   220 CAsynchEvent* CDHCPRebootConfirm::ProcessL(TRequestStatus& aStatus)
       
   221 /**
       
   222   * Interface function, execute state machine
       
   223   *
       
   224   * @internalTechnology
       
   225   */
       
   226 	{
       
   227 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPRebootConfirm);
       
   228 	CDHCPStateMachine& rDHCP = Dhcp();
       
   229 	rDHCP.InitialiseSocketL();
       
   230 	rDHCP.CreateRebootRequestMsgL();
       
   231 	// one second retransmit passed to CloseNsendMsgL
       
   232 	rDHCP.CloseNSendMsgL(KOneSecond, rDHCP.iMaxRetryCount,CDHCPStateMachine::EAllAvailableServers);
       
   233 	TRequestStatus* p = &aStatus;
       
   234 	User::RequestComplete(p, KErrNone); //move to the next state
       
   235 	return iNext;
       
   236 	}
       
   237 
       
   238 CAsynchEvent* CDHCPRequest::ProcessL(TRequestStatus& aStatus)
       
   239 /**
       
   240   * Interface function, execute state machine
       
   241   *
       
   242   * @internalTechnology
       
   243   */	
       
   244 	{
       
   245 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPRequest);
       
   246 	CDHCPStateMachine& rDHCP = Dhcp();
       
   247 	if (!rDHCP.iReceiving)
       
   248 		{
       
   249 		return rDHCP.ReceiveL(&aStatus);
       
   250 		}
       
   251 	return ProcessAckNakL(&aStatus);
       
   252 	}
       
   253 
       
   254 CAsynchEvent* CDHCPRebind::ProcessL(TRequestStatus& aStatus)
       
   255 /**
       
   256   * Interface function, execute state machine
       
   257   *
       
   258   * @internalTechnology
       
   259   */
       
   260 	{
       
   261 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPRebind::ProcessL")));
       
   262 	
       
   263 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPRebind);
       
   264 	CDHCPStateMachine& rDHCP = Dhcp();
       
   265 	if (!rDHCP.iReceiving)
       
   266 		{
       
   267 		rDHCP.CreateRebindRequestMsgL();
       
   268 		// the socket will be closed so as to free up resources...
       
   269 		// therefore we will have to set it up again...
       
   270 		rDHCP.InitialiseSocketL();
       
   271 		// 10 second initial retransmit passed to CloseNsendMsgL
       
   272 		rDHCP.CloseNSendMsgL(KOneSecond * 10/*10 secs*/,rDHCP.iMaxRetryCount, CDHCPStateMachine::EAllAvailableServers);
       
   273 //		rDHCPIPv4.StartDeltaTimer(iTimeToWait, *this);
       
   274 		return rDHCP.ReceiveL(&aStatus);
       
   275 		}
       
   276 	return ProcessAckNakL(&aStatus);
       
   277 	}
       
   278 
       
   279 void CDHCPWaitForDADBind::Cancel()
       
   280 	{
       
   281 	CDHCPStateMachine& rDHCP = Dhcp();
       
   282 	rDHCP.CancelTimer();
       
   283 	
       
   284 	TRequestStatus* p = &iStateMachine->iStatus;
       
   285 	User::RequestComplete(p, KErrCancel); 
       
   286 	rDHCP.SetAsyncCancelHandler(NULL);
       
   287 	}
       
   288 	
       
   289 CAsynchEvent* CDHCPWaitForDADBind::ProcessL(TRequestStatus& aStatus)
       
   290 /**
       
   291   * Interface function, execute state machine
       
   292   *
       
   293   * @internalTechnology
       
   294   */
       
   295 	{
       
   296 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPWaitForDADBind);
       
   297 	CDHCPStateMachine& rDHCP = Dhcp();
       
   298 	aStatus = KRequestPending;
       
   299 	rDHCP.SetAsyncCancelHandler(this);
       
   300 	rDHCP.CancelMessageSender();
       
   301 	iBoundAt.HomeTime();
       
   302 	rDHCP.StartTimer(TTimeIntervalMicroSeconds32(KHalfSecondInMicroSeconds), *this); // 0.5 sec to wait for TCP/IP6 stack to complete DAD
       
   303 	rDHCP.UpdateHistory(EBinding);
       
   304 	iErr = KErrNone;
       
   305 	return NULL; //no matter what that's the end
       
   306 	}
       
   307 
       
   308 void CDHCPWaitForDADBind::TimerExpired()
       
   309 /**
       
   310   * Interface function, called by timer when timer has popped
       
   311   * in this case we try to bind a socket to the source address
       
   312   * to check that DAD has been resolved by the TCP/IP6 stack.
       
   313   * If it hasn't then we have to wait for another 2 seconds, 
       
   314   * up to a maximum of 30 seconds...
       
   315   * There is an improvement to this, by checking the status
       
   316   * of the route for the interface...no time to implement this
       
   317   * improvement, but it would be more robust to have it as
       
   318   * this would enable differentiation between when DAD has not been
       
   319   * resolved and when it has found a duplicate address...which the 
       
   320   * current method does not allow, as the bind will only return KErrNotFound
       
   321   * if the source address is not recognised...would still have to poll though...
       
   322   *
       
   323   * @internalTechnology
       
   324   */
       
   325 	{
       
   326 	CDHCPStateMachine& rDHCP = Dhcp();
       
   327 
       
   328 
       
   329 #ifdef _DEBUG
       
   330 	if (CDHCPServer::DebugFlags() & KDHCP_Dad)
       
   331 		{
       
   332 		iErr = KErrNotFound;	// simulate a duplicate address	
       
   333 		// but we only want to do this once...
       
   334 		// so reset the debug flag
       
   335 		CDHCPServer::DebugFlags() &= ~KDHCP_Dad;
       
   336 		}
       
   337 	else
       
   338 #endif
       
   339 		{
       
   340 		iErr = rDHCP.BindToSource();
       
   341 		if (iErr!=KErrNone)
       
   342 			{
       
   343 			TTime now;
       
   344 			now.HomeTime();
       
   345 			TTimeIntervalSeconds thirtySeconds(30);
       
   346 			if ((now-thirtySeconds)<iBoundAt)
       
   347 				{
       
   348 				rDHCP.StartTimer(TTimeIntervalMicroSeconds32(KHalfSecondInMicroSeconds), *this); //another 0.5 secs
       
   349 				return; //wait
       
   350 				}
       
   351 			}
       
   352 		}
       
   353 	}
       
   354 
       
   355 #if 0
       
   356 void CDHCPWaitForDADIPNotifier::TimerExpired()
       
   357 	{
       
   358 	//finish => something's gone wrong => no response from IP notifier
       
   359 	TRequestStatus* p = &iStateMachine->iStatus;
       
   360 	User::RequestComplete(p, KErrTimedOut); 
       
   361 	}
       
   362 #endif
       
   363 
       
   364 CAsynchEvent* CDHCPRenew::ProcessL(TRequestStatus& aStatus)
       
   365 /**
       
   366   * Interface function, execute state machine
       
   367   *
       
   368   * @internalTechnology
       
   369   */
       
   370 	{
       
   371 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPRenew);
       
   372 	CDHCPStateMachine& rDHCP = Dhcp();
       
   373 	if (!rDHCP.iReceiving)
       
   374 		{
       
   375 		rDHCP.CreateRenewRequestMsgL();
       
   376 		// the socket will be closed so as to free up resources...
       
   377 		// therefore we will have to set it up again...
       
   378 		rDHCP.BindSocketForUnicastL();
       
   379 		// 10 second initial retransmit passed to CloseNsendMsgL
       
   380 		rDHCP.CloseNSendMsgL(KOneSecond * 10/*10 secs*/, rDHCP.iMaxRetryCount, CDHCPStateMachine::EUnicast);
       
   381 		return rDHCP.ReceiveL(&aStatus);
       
   382 		}
       
   383 	return ProcessAckNakL(&aStatus);
       
   384 	}
       
   385 
       
   386 CAsynchEvent* CDHCPRelease::ProcessL(TRequestStatus& aStatus)
       
   387 /**
       
   388   * Interface function, execute state machine
       
   389   *
       
   390   * @internalTechnology
       
   391   */
       
   392 	{
       
   393 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPRelease);
       
   394 	CDHCPStateMachine& rDHCP = Dhcp();
       
   395 	rDHCP.CreateReleaseMsgL();
       
   396 	rDHCP.InitialiseSocketL();
       
   397 	// the socket will be closed so as to free up resources...
       
   398 	// therefore we will have to set it up again...
       
   399 	rDHCP.BindSocketForUnicastL();
       
   400 	rDHCP.CloseNSendMsgL( aStatus, CDHCPStateMachine::EUnicast);
       
   401 	return iNext;
       
   402 	}
       
   403 
       
   404 
       
   405 
       
   406 CAsynchEvent* CDHCPDecline::ProcessL(TRequestStatus& aStatus)
       
   407 /**
       
   408   * Interface function, execute state machine
       
   409   *
       
   410   * @internalTechnology
       
   411   */
       
   412 	{
       
   413 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPDecline);
       
   414 	CDHCPStateMachine& rDHCP = Dhcp();
       
   415 	rDHCP.CreateDeclineMsgL();
       
   416 	// need to open a new socket to broadcast a decline
       
   417 	// as the old socket has been closed and then used to
       
   418 	// try to bind to source address...
       
   419 	rDHCP.InitialiseSocketL();
       
   420 	rDHCP.CloseNSendMsgL(aStatus, CDHCPStateMachine::EAllAvailableServers);
       
   421 	return iNext;
       
   422 	}
       
   423 
       
   424 #ifdef SYMBIAN_NETWORKING_DHCPSERVER	
       
   425 CAsynchEvent* CDHCPWaitForClientMsgs::ProcessL(TRequestStatus& aStatus)
       
   426 /**
       
   427   * Interface function, execute state machine
       
   428   *
       
   429   * @internalTechnology
       
   430   */
       
   431 	{
       
   432 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPWaitForClientMsgs::ProcessL")));
       
   433 	
       
   434 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPWaitForClientMsgs);
       
   435 	CDHCPStateMachine& rDHCP = Dhcp();
       
   436 	rDHCP.iReceiving = EFalse;
       
   437 	rDHCP.InitialiseServerSocketL();
       
   438 	rDHCP.ReceiveOnPort67L(&aStatus);
       
   439 
       
   440 	return iNext;
       
   441 	}
       
   442 	
       
   443 	
       
   444 CAsynchEvent* CDHCPHandleClientMsgs::ProcessL(TRequestStatus&/* aStatus*/)
       
   445 /**
       
   446   * Interface function, execute state machine
       
   447   *
       
   448   * @internalTechnology
       
   449   */
       
   450 	{
       
   451 	return iNext;
       
   452 	}	
       
   453 	
       
   454 
       
   455 CAsynchEvent* CDHCPProvideOffer::ProcessL(TRequestStatus& aStatus)
       
   456 /**
       
   457   * Interface function, execute state machine
       
   458   *
       
   459   * @internalTechnology
       
   460   */
       
   461 	{
       
   462 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPProvideOffer);
       
   463 	CDHCPStateMachine& rDHCP = Dhcp();
       
   464 	rDHCP.CreateOfferMsgL();
       
   465 	rDHCP.CloseNSendServerMsgL(aStatus, CDHCPStateMachine::EAllAvailableServers);
       
   466 	return iNext;
       
   467 	}
       
   468 	
       
   469 CAsynchEvent* CDHCPSendRequestResponse::ProcessL(TRequestStatus& aStatus)
       
   470 /**
       
   471   * Interface function, execute state machine
       
   472   *
       
   473   * @internalTechnology
       
   474   */
       
   475 	{
       
   476 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPSendAckNak);
       
   477 	CDHCPStateMachine& rDHCP = Dhcp();
       
   478 	rDHCP.HandleRequestMsgL();
       
   479 	rDHCP.InitialiseServerSocketL();
       
   480 
       
   481 	if(rDHCP.IsClientIdentified())
       
   482 		{
       
   483 		rDHCP.CloseNSendServerMsgL(aStatus, CDHCPStateMachine::EUnicast);
       
   484 		rDHCP.iSvrSpecificState = ESvrRenewInProgress;		
       
   485 		}
       
   486 	else
       
   487 		{
       
   488 		rDHCP.CloseNSendServerMsgL(aStatus, CDHCPStateMachine::EAllAvailableServers);
       
   489 		rDHCP.iSvrSpecificState = ESvrDiscoverInProgress;		
       
   490 		}
       
   491 	
       
   492 	rDHCP.SetClientIdentified(ETrue);
       
   493 	return iNext;
       
   494 	}		
       
   495 	
       
   496 CAsynchEvent* CDHCPSendInformResponse::ProcessL(TRequestStatus& aStatus)
       
   497 /**
       
   498   * Interface function, execute state machine
       
   499   *
       
   500   * @internalTechnology
       
   501   */
       
   502 	{
       
   503 	DHCP_DEBUG_PUBLISH_STATE(DHCPDebug::EDHCPSendAckNak);
       
   504 	CDHCPStateMachine& rDHCP = Dhcp();
       
   505 
       
   506 	rDHCP.HandleInformMsgL();
       
   507 	rDHCP.InitialiseServerSocketL();
       
   508 
       
   509     //Sends DHCPAck only the Client NetworkId is same as the Server's NetworkId
       
   510 	if(rDHCP.CheckNetworkId())
       
   511 		{
       
   512 		rDHCP.CloseNSendServerMsgL(aStatus, CDHCPStateMachine::EUnicast);
       
   513 		rDHCP.SetClientIdentified(ETrue);	
       
   514 		rDHCP.iSvrSpecificState = ESvrInformInProgress;	
       
   515 		}
       
   516 	else
       
   517 		{
       
   518 		TRequestStatus* p = &aStatus;
       
   519 		User::RequestComplete(p, KErrNone);
       
   520 		}	
       
   521 	return iNext;
       
   522 	}
       
   523 	
       
   524 CAsynchEvent* CDHCPHandleRelease::ProcessL(TRequestStatus& aStatus)
       
   525 /**
       
   526   * Interface function, execute state machine
       
   527   *
       
   528   * @internalTechnology
       
   529   */
       
   530 	{
       
   531 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ProcessReleaseL")));
       
   532 	CDHCPStateMachine& rDHCP = Dhcp();
       
   533 	
       
   534 	rDHCP.SetClientIdentified(EFalse);
       
   535 	rDHCP.iSvrSpecificState = ESvrReleaseInProgress;	
       
   536 	
       
   537 	TRequestStatus* p = &aStatus;
       
   538 	User::RequestComplete(p, KErrNone); 
       
   539 	return iNext;
       
   540 	}
       
   541 	
       
   542 CAsynchEvent* CDHCPHandleDecline::ProcessL(TRequestStatus& aStatus)
       
   543 /**
       
   544   * Interface function, execute state machine
       
   545   *
       
   546   * @internalTechnology
       
   547   */
       
   548 	{
       
   549 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ProcessReleaseL")));
       
   550 	CDHCPStateMachine& rDHCP = Dhcp();
       
   551 	rDHCP.SetClientIdentified(EFalse);
       
   552 	TRequestStatus* p = &aStatus;
       
   553 	User::RequestComplete(p, KErrNone); 
       
   554 	return iNext;
       
   555 	}			
       
   556 
       
   557 void CDHCPBindServer::Cancel()
       
   558 	{
       
   559 	CDHCPStateMachine& rDHCP = Dhcp();
       
   560 	rDHCP.CancelTimer();
       
   561 	
       
   562 	TRequestStatus* p = &iStateMachine->iStatus;
       
   563 	User::RequestComplete(p, KErrCancel); 
       
   564 	rDHCP.SetAsyncCancelHandler(NULL);
       
   565 	}	
       
   566 
       
   567 CAsynchEvent* CDHCPBindServer::ProcessL(TRequestStatus& aStatus)
       
   568 /**
       
   569   * Interface function, execute state machine
       
   570   *
       
   571   * @internalTechnology
       
   572   */
       
   573 	{
       
   574 	CDHCPStateMachine& rDHCP = Dhcp();
       
   575 	aStatus = KRequestPending;
       
   576 	rDHCP.SetAsyncCancelHandler(this);
       
   577 	rDHCP.CancelMessageSender();
       
   578 
       
   579 	TInt err = rDHCP.BindServerInterface();
       
   580 	if(KErrNone == err)
       
   581 		{
       
   582 		TRequestStatus* p = &aStatus;
       
   583 		User::RequestComplete(p, KErrNone);
       
   584 		rDHCP.SetAsyncCancelHandler(NULL);
       
   585 		}
       
   586 	else
       
   587 		rDHCP.StartTimer(TTimeIntervalMicroSeconds32(KHalfSecondInMicroSeconds), *this); // 0.5 sec to wait for TCP/IP6 stack to complete Bind
       
   588 
       
   589 	iErr = KErrNone;
       
   590 	return NULL; //no matter what that's the end
       
   591 	}
       
   592 
       
   593 void CDHCPBindServer::TimerExpired()
       
   594 /**
       
   595   * Interface function, called by timer when timer has popped
       
   596   * in this case we try to bind the server socket to the static IP address from comms database.
       
   597   * If the bind fails then we have to wait for another 2 seconds, 
       
   598   * up to a maximu of 30 seconds...
       
   599   *
       
   600   * @internalTechnology
       
   601   */
       
   602 	{
       
   603 	CDHCPStateMachine& rDHCP = Dhcp();
       
   604 	iErr = rDHCP.BindServerInterface();
       
   605 	
       
   606 	if(iErr != KErrNone)
       
   607 		{
       
   608 		rDHCP.StartTimer(TTimeIntervalMicroSeconds32(KHalfSecondInMicroSeconds), *this); // 0.5 sec to wait for TCP/IP6 stack to complete Bind
       
   609 		}
       
   610 	}
       
   611 	
       
   612 #endif // SYMBIAN_NETWORKING_DHCPSERVER