629 if (iOpenChannelRequestAwaitingPeerEntityConfig) |
629 if (iOpenChannelRequestAwaitingPeerEntityConfig) |
630 { |
630 { |
631 // SAP state machine requested that we open the channel before we could do it. |
631 // SAP state machine requested that we open the channel before we could do it. |
632 // We can do it now. |
632 // We can do it now. |
633 iOpenChannelRequestAwaitingPeerEntityConfig = EFalse; |
633 iOpenChannelRequestAwaitingPeerEntityConfig = EFalse; |
634 iSigState->OpenChannelRequest(*this); |
634 iSigState->OpenChannel(*this); |
635 } |
635 } |
636 } |
636 } |
637 |
637 |
638 TBool CL2CapSAPSignalHandler::DelayConfigRequest() |
638 TBool CL2CapSAPSignalHandler::DelayConfigRequest() |
639 { |
639 { |
640 LOG_FUNC |
640 LOG_FUNC |
641 iAwaitingConfigRequestDelayTimer = iSAPSignalHandlerTimerState==EConfigRequestDelayTimer; |
641 // The whole delaying of sending of ConfigRequest is basically a workaround for |
642 |
642 // certain broken carkits from a certain Swedish manufacturer at a certain stretch |
643 return iAwaitingConfigRequestDelayTimer; //true if we are delaying |
643 // of time. |
644 } |
644 // The defect was: the carkits advertised their capability to do RTM in Extended |
645 |
645 // Feature Mask, but when sent a ConfigRequest with RTM they would just panic |
|
646 // (ie. they really only did Basic mode). |
|
647 // So the workaround is to delay the sending of our Config Request such that |
|
648 // we receive the carkit's request first - we have an optimization which will |
|
649 // downgrade our requested channel mode to Basic if the remote requests it before |
|
650 // we've sent out our ConfigReq. This way we send Basic mode in our ConfigReq |
|
651 // and the carkit is happy. |
|
652 return iSAPSignalHandlerTimerState==EConfigRequestDelayTimer; |
|
653 } |
|
654 |
646 void CL2CapSAPSignalHandler::ConfigRequestDelayTimerExpiry() |
655 void CL2CapSAPSignalHandler::ConfigRequestDelayTimerExpiry() |
647 { |
656 { |
648 LOG_FUNC |
657 LOG_FUNC |
649 if(iAwaitingConfigRequestDelayTimer) |
658 // Now that ConfigReq delay timer have expired we can start the proper configuration timer. |
|
659 StartConfigurationTimer(); |
|
660 |
|
661 if (!iAwaitConfigureChannelRequest) |
650 { |
662 { |
651 iAwaitingConfigRequestDelayTimer = EFalse; |
663 ConfigureChannel(); |
652 ConfigureChannelRequest(); |
|
653 } |
664 } |
|
665 // [else]: we're in an active open scenario and SAP hasn't yet issued a ConfigureChannelRequest. |
654 } |
666 } |
655 |
667 |
656 void CL2CapSAPSignalHandler::CloseChannelRequest() |
668 void CL2CapSAPSignalHandler::CloseChannelRequest() |
657 { |
669 { |
658 LOG_FUNC |
670 LOG_FUNC |
659 iSigState->CloseChannelRequest(*this); |
671 iSigState->CloseChannel(*this); |
660 } |
672 } |
661 |
673 |
662 void CL2CapSAPSignalHandler::OpenChannelRequest() |
674 void CL2CapSAPSignalHandler::OpenChannelRequest() |
663 { |
675 { |
664 LOG_FUNC |
676 LOG_FUNC |
665 __ASSERT_DEBUG(!iOpenChannelRequestAwaitingPeerEntityConfig, |
677 __ASSERT_DEBUG(!iOpenChannelRequestAwaitingPeerEntityConfig, |
666 Panic(EL2CAPOpenChannelRequestCalledTwice)); |
678 Panic(EL2CAPOpenChannelRequestCalledTwice)); |
667 |
679 |
668 if (IsPeerInfoDefined()) |
680 if (IsPeerInfoDefined()) |
669 { |
681 { |
670 iSigState->OpenChannelRequest(*this); |
682 iSigState->OpenChannel(*this); |
671 } |
683 } |
672 else |
684 else |
673 { |
685 { |
674 iOpenChannelRequestAwaitingPeerEntityConfig = ETrue; |
686 iOpenChannelRequestAwaitingPeerEntityConfig = ETrue; |
675 // We'll realize the OpenChannelRequest as soon as we receive |
687 // We'll realize the OpenChannelRequest as soon as we receive |
705 } |
722 } |
706 |
723 |
707 void CL2CapSAPSignalHandler::StartConfigurationTimer() |
724 void CL2CapSAPSignalHandler::StartConfigurationTimer() |
708 { |
725 { |
709 LOG_FUNC |
726 LOG_FUNC |
710 switch(iSAPSignalHandlerTimerState) |
727 __ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle, |
711 { |
728 Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning)); |
712 case EConfigurationTimer: |
729 |
713 case EConfigRequestDelayTimer: |
730 TCallBack cb(TimerExpired, this); |
714 // The timer is already running. Cancel it and start it again. |
731 iSAPSignalHandlerTimerEntry.Set(cb); |
715 BTSocketTimer::Remove(iSAPSignalHandlerTimerEntry); |
732 BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, |
716 iSAPSignalHandlerTimerState = ETimerIdle; |
733 iSAPSignalHandlerTimerEntry); |
717 break; |
734 iSAPSignalHandlerTimerState = EConfigurationTimer; |
718 |
735 } |
719 case ETimerIdle: |
736 |
720 default: |
737 void CL2CapSAPSignalHandler::StartConfigRequestDelayTimer() |
721 // No timer running, nothing needs to be done. |
738 { |
722 break; |
739 LOG_FUNC |
723 }; |
740 __ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle, |
724 |
741 Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning)); |
725 if(iSAPSignalHandlerTimerState == ETimerIdle) |
742 |
726 { |
743 TCallBack cb(TimerExpired, this); |
727 TCallBack cb(TimerExpired, this); |
744 iSAPSignalHandlerTimerEntry.Set(cb); |
728 iSAPSignalHandlerTimerEntry.Set(cb); |
745 BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, |
729 BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, |
746 iSAPSignalHandlerTimerEntry); |
730 iSAPSignalHandlerTimerEntry); |
747 iSAPSignalHandlerTimerState = EConfigRequestDelayTimer; |
731 iSAPSignalHandlerTimerState = EConfigRequestDelayTimer; |
748 } |
732 } |
749 |
733 } |
|
734 |
|
735 void CL2CapSAPSignalHandler::CancelTimer() |
750 void CL2CapSAPSignalHandler::CancelTimer() |
736 { |
751 { |
737 |
|
738 LOG_FUNC |
752 LOG_FUNC |
739 if(iSAPSignalHandlerTimerState != ETimerIdle) |
753 if(iSAPSignalHandlerTimerState != ETimerIdle) |
740 { |
754 { |
741 BTSocketTimer::Remove(iSAPSignalHandlerTimerEntry); |
755 BTSocketTimer::Remove(iSAPSignalHandlerTimerEntry); |
742 iSAPSignalHandlerTimerState = ETimerIdle; |
756 iSAPSignalHandlerTimerState = ETimerIdle; |
749 switch(iSAPSignalHandlerTimerState) |
763 switch(iSAPSignalHandlerTimerState) |
750 { |
764 { |
751 case ETimerIdle: |
765 case ETimerIdle: |
752 Panic(EL2CAPSSHTimerExpiredWhileInIdleState); |
766 Panic(EL2CAPSSHTimerExpiredWhileInIdleState); |
753 break; |
767 break; |
754 |
768 |
755 case EConfigRequestDelayTimer: |
769 case EConfigRequestDelayTimer: |
756 { |
770 { |
757 TCallBack cb(TimerExpired, this); |
771 iSAPSignalHandlerTimerState = ETimerIdle; |
758 iSAPSignalHandlerTimerEntry.Set(cb); |
|
759 BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, |
|
760 iSAPSignalHandlerTimerEntry); |
|
761 iSAPSignalHandlerTimerState = EConfigurationTimer; |
|
762 ConfigRequestDelayTimerExpiry(); |
772 ConfigRequestDelayTimerExpiry(); |
763 } |
773 } |
764 break; |
774 break; |
765 |
775 |
766 case EConfigurationTimer: |
776 case EConfigurationTimer: |
767 iSAPSignalHandlerTimerState = ETimerIdle; |
777 iSAPSignalHandlerTimerState = ETimerIdle; |
768 iSigState->ConfigurationTimerExpiry(*this); |
778 iSigState->ConfigurationTimerExpiry(*this); |
769 break; |
779 break; |
770 |
780 |