bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp
changeset 33 4e80e1b997a8
parent 0 29b1cd4cb562
child 45 99439b07e980
--- a/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp	Mon May 03 13:34:38 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp	Mon Jul 12 07:03:47 2010 +0300
@@ -631,32 +631,44 @@
  		// SAP state machine requested that we open the channel before we could do it.
  		// We can do it now.
  		iOpenChannelRequestAwaitingPeerEntityConfig = EFalse;
- 		iSigState->OpenChannelRequest(*this);
+ 		iSigState->OpenChannel(*this);
  		}
  	}
 
 TBool CL2CapSAPSignalHandler::DelayConfigRequest()
 	{
 	LOG_FUNC
-	iAwaitingConfigRequestDelayTimer = iSAPSignalHandlerTimerState==EConfigRequestDelayTimer;
+	// The whole delaying of sending of ConfigRequest is basically a workaround for
+	// certain broken carkits from a certain Swedish manufacturer at a certain stretch
+	// of time.
+	// The defect was: the carkits advertised their capability to do RTM in Extended
+	// Feature Mask, but when sent a ConfigRequest with RTM they would just panic
+	// (ie. they really only did Basic mode). 
+	// So the workaround is to delay the sending of our Config Request such that
+	// we receive the carkit's request first - we have an optimization which will
+	// downgrade our requested channel mode to Basic if the remote requests it before
+	// we've sent out our ConfigReq. This way we send Basic mode in our ConfigReq
+	// and the carkit is happy.
+	return iSAPSignalHandlerTimerState==EConfigRequestDelayTimer;
+	}
 
-	return iAwaitingConfigRequestDelayTimer; //true if we are delaying
-	}
-				
 void CL2CapSAPSignalHandler::ConfigRequestDelayTimerExpiry()	
  	{
  	LOG_FUNC
- 	if(iAwaitingConfigRequestDelayTimer)
+ 	// Now that ConfigReq delay timer have expired we can start the proper configuration timer.
+ 	StartConfigurationTimer();
+
+ 	if (!iAwaitConfigureChannelRequest)
  		{
- 		iAwaitingConfigRequestDelayTimer = EFalse;
-		ConfigureChannelRequest();
+		ConfigureChannel();
  		}
+ 	// [else]: we're in an active open scenario and SAP hasn't yet issued a ConfigureChannelRequest.
  	}
 
 void CL2CapSAPSignalHandler::CloseChannelRequest()
 	{
 	LOG_FUNC
-	iSigState->CloseChannelRequest(*this);
+	iSigState->CloseChannel(*this);
 	}
 
 void CL2CapSAPSignalHandler::OpenChannelRequest()
@@ -667,7 +679,7 @@
 
 	if (IsPeerInfoDefined())
 		{
-		iSigState->OpenChannelRequest(*this);
+		iSigState->OpenChannel(*this);
 		}
 	else
 		{
@@ -686,7 +698,12 @@
 void CL2CapSAPSignalHandler::ConfigureChannelRequest()
 	{
 	LOG_FUNC
-	iSigState->ConfigureChannelRequest(*this);
+	iAwaitConfigureChannelRequest = EFalse;
+
+	if (iSAPSignalHandlerTimerState != EConfigRequestDelayTimer)
+		{
+		ConfigureChannel();
+		}
 	}
 
 void CL2CapSAPSignalHandler::PendingCommandsDrained()
@@ -707,34 +724,31 @@
 void CL2CapSAPSignalHandler::StartConfigurationTimer()
 	{
 	LOG_FUNC
-	switch(iSAPSignalHandlerTimerState)
-		{
-		case EConfigurationTimer:
-		case EConfigRequestDelayTimer:
-			// The timer is already running. Cancel it and start it again.
-			BTSocketTimer::Remove(iSAPSignalHandlerTimerEntry);
-			iSAPSignalHandlerTimerState = ETimerIdle;
-			break;
-					
-		case ETimerIdle:
-		default:
-			// No timer running, nothing needs to be done.
-			break;
-		};
+	__ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle,
+				   Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning));
+
+	TCallBack cb(TimerExpired, this);
+	iSAPSignalHandlerTimerEntry.Set(cb);
+	BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, 
+	                     iSAPSignalHandlerTimerEntry);
+	iSAPSignalHandlerTimerState = EConfigurationTimer;
+	}
 
-	if(iSAPSignalHandlerTimerState == ETimerIdle)
-		{
-		TCallBack cb(TimerExpired, this);
-		iSAPSignalHandlerTimerEntry.Set(cb);
-		BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, 
-		                     iSAPSignalHandlerTimerEntry);
-		iSAPSignalHandlerTimerState = EConfigRequestDelayTimer;
-		}
+void CL2CapSAPSignalHandler::StartConfigRequestDelayTimer()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle,
+				   Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning));
+
+	TCallBack cb(TimerExpired, this);
+	iSAPSignalHandlerTimerEntry.Set(cb);
+	BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, 
+						 iSAPSignalHandlerTimerEntry);
+	iSAPSignalHandlerTimerState = EConfigRequestDelayTimer;
 	}
-	
+
 void CL2CapSAPSignalHandler::CancelTimer()
 	{
-
 	LOG_FUNC
 	if(iSAPSignalHandlerTimerState != ETimerIdle)
 		{
@@ -751,18 +765,14 @@
 		case ETimerIdle:
 			Panic(EL2CAPSSHTimerExpiredWhileInIdleState);
 			break;
-			
+	
 		case EConfigRequestDelayTimer:
 			{
-			TCallBack cb(TimerExpired, this);
-			iSAPSignalHandlerTimerEntry.Set(cb);
-			BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, 
-			                     iSAPSignalHandlerTimerEntry);
-			iSAPSignalHandlerTimerState = EConfigurationTimer;
+			iSAPSignalHandlerTimerState = ETimerIdle;
 			ConfigRequestDelayTimerExpiry();
 			}
 			break;
-			
+
 		case EConfigurationTimer:
 			iSAPSignalHandlerTimerState = ETimerIdle;
 			iSigState->ConfigurationTimerExpiry(*this);