/**
 *	This is the function that will check for default transitions if
 *  no other transitions were satisfied. 
 */
bool LocalPoseSensorService::defaultTransitions(InternalEvent* ie)
{
   bool done = false;

   // Since this function can be called from multiple threads,
   // we use a mutex to ensure only one state transition is
   // active at a time.
   mutex.lock();

			// Invoke the FSM transition for this event.
			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == SetLocalPose::ID)
					{
						SetLocalPose msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->SetLocalPoseTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryLocalPose::ID)
					{
						QueryLocalPose msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->QueryLocalPoseTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == RequestControl::ID)
					{
						RequestControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->RequestControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == ReleaseControl::ID)
					{
						ReleaseControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->ReleaseControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryControl::ID)
					{
						QueryControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->QueryControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryAuthority::ID)
					{
						QueryAuthority msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->QueryAuthorityTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == SetAuthority::ID)
					{
						SetAuthority msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->SetAuthorityTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryTimeout::ID)
					{
						QueryTimeout msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->QueryTimeoutTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == CreateEvent::ID)
					{
						CreateEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->CreateEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == UpdateEvent::ID)
					{
						UpdateEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->UpdateEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == CancelEvent::ID)
					{
						CancelEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->CancelEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryEvents::ID)
					{
						QueryEvents msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_ReceiveFSM->context->QueryEventsTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Timeout") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Timeout* casted_ie = (Timeout*) ie;
						pLocalPoseSensor_ReceiveFSM->context->TimeoutTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("EventOccurred") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					EventOccurred* casted_ie = (EventOccurred*) ie;
						pLocalPoseSensor_ReceiveFSM->context->EventOccurredTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("EventError") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					EventError* casted_ie = (EventError*) ie;
						pLocalPoseSensor_ReceiveFSM->context->EventErrorTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Send") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					Send* casted_ie = (Send*) ie;
						pLocalPoseSensor_ReceiveFSM->context->SendTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("BroadcastLocal") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					BroadcastLocal* casted_ie = (BroadcastLocal*) ie;
						pLocalPoseSensor_ReceiveFSM->context->BroadcastLocalTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("BroadcastGlobal") == 0 && (ie->getSource().compare("LocalPoseSensor_ReceiveFSM") != 0))
				{
					BroadcastGlobal* casted_ie = (BroadcastGlobal*) ie;
						pLocalPoseSensor_ReceiveFSM->context->BroadcastGlobalTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == SetLocalPose::ID)
					{
						SetLocalPose msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->SetLocalPoseTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryLocalPose::ID)
					{
						QueryLocalPose msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->QueryLocalPoseTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == RequestControl::ID)
					{
						RequestControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->RequestControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == ReleaseControl::ID)
					{
						ReleaseControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->ReleaseControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryControl::ID)
					{
						QueryControl msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->QueryControlTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryAuthority::ID)
					{
						QueryAuthority msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->QueryAuthorityTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == SetAuthority::ID)
					{
						SetAuthority msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->SetAuthorityTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryTimeout::ID)
					{
						QueryTimeout msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->QueryTimeoutTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == CreateEvent::ID)
					{
						CreateEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->CreateEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == UpdateEvent::ID)
					{
						UpdateEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->UpdateEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == CancelEvent::ID)
					{
						CancelEvent msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->CancelEventTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Receive") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Receive* casted_ie = (Receive*) ie;
					unsigned short id = *((unsigned short*) casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
					if ( id == QueryEvents::ID)
					{
						QueryEvents msg;
						msg.decode(casted_ie->getBody()->getReceiveRec()->getMessagePayload()->getData());
						pLocalPoseSensor_SendFSM->context->QueryEventsTransition();
						done = true;
					}
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Timeout") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Timeout* casted_ie = (Timeout*) ie;
						pLocalPoseSensor_SendFSM->context->TimeoutTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("EventOccurred") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					EventOccurred* casted_ie = (EventOccurred*) ie;
						pLocalPoseSensor_SendFSM->context->EventOccurredTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("EventError") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					EventError* casted_ie = (EventError*) ie;
						pLocalPoseSensor_SendFSM->context->EventErrorTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("Send") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					Send* casted_ie = (Send*) ie;
						pLocalPoseSensor_SendFSM->context->SendTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("BroadcastLocal") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					BroadcastLocal* casted_ie = (BroadcastLocal*) ie;
						pLocalPoseSensor_SendFSM->context->BroadcastLocalTransition();
						done = true;
				}
			} catch (...) {}

			try
			{
				if ((done == false) && ie->getName().compare("BroadcastGlobal") == 0 && (ie->getSource().compare("LocalPoseSensor_SendFSM") != 0))
				{
					BroadcastGlobal* casted_ie = (BroadcastGlobal*) ie;
						pLocalPoseSensor_SendFSM->context->BroadcastGlobalTransition();
						done = true;
				}
			} catch (...) {}

	

   mutex.unlock();
   return done;
}
Example #2
0
////////////////////////////////////////////////////////////////////////////////////
///
///   \brief Method called periodically by external classes and is used to
///          verify control of components.
///
///   \param[in] timeSinceLastCheckMs Number of milliseconds since the last time
///                                   this method was called.
///
////////////////////////////////////////////////////////////////////////////////////
void AccessControl::CheckServiceStatus(const unsigned int timeSinceLastCheckMs)
{
    RequestControl request;

    mControlMutex.Lock();

    request.SetSourceID(GetComponentID());
    request.SetAuthorityCode(mAuthorityCode);

    Address::Set::iterator component;
    Time currentTime;
    currentTime.SetCurrentTime();
    
    for(component = mControlledComponents.begin();
        component != mControlledComponents.end();
        component++)
    {
        // If we are releasing control, do not check.
        if(mToReleaseControl.find(*component) != mToReleaseControl.end())
        {
            continue;
        }
        // If we have not checked within timeout - .x seconds, then re-acquire control to
        // maintain constant control of component.
        double thresh = mTimeoutPeriods[*component]*mTimeoutThreshold/100.0;
        double checkTimeDiff = currentTime.ToSeconds() - mControlCheckTimes[*component].ToSeconds();
        double timeThresh = (mTimeoutPeriods[*component] - thresh);
        bool checkConfirmation = true;
        if(mTimeoutPeriods[*component] > 0 && checkTimeDiff >= thresh)
        {
            request.SetDestinationID(*component);
            if(Send(&request))
            {
                // Update the check time.
                mControlCheckTimes[*component].SetCurrentTime();
                checkConfirmation = false;
            }
        }
        double confirmTimeDiff = currentTime.ToSeconds() - mControlConfirmTimes[*component].ToSeconds();
        timeThresh = (mTimeoutPeriods[*component] + thresh);
        // If we haven't been confirmed in this time, then we have lost control.
        if(checkConfirmation && confirmTimeDiff > timeThresh)
        {
            mControlFlags[*component] = false;
            // Generate events and callbacks.
            Mutex::ScopedLock clock(&mCallbacksMutex);
            Callback::Set::iterator cb;
            for(cb = mCallbacks.begin();
                cb != mCallbacks.end();
                cb++)
            {
                (*cb)->ProcessLossOfControl(*component);
            }
        }
    }
    
    mControlMutex.Unlock();
    // Allow control check time to update.
    mControlMutex.Lock();

    Address controller = mControllerID;
    bool timeout = false;
    currentTime.SetCurrentTime();
    double timeSinceRequest = currentTime - mControllerCheckTime;
    if(mTimeoutPeriod > 0 && 
       controller.IsValid() && 
       timeSinceRequest >= (double)mTimeoutPeriod + mTimeoutPeriod*mTimeoutThreshold/100.0)
    {
        timeout = true;
        // Release control due to timeout.
        RejectControl reject(controller, GetComponentID());
        reject.SetResponseCode(RejectControl::ControlReleased);
        Send(&reject);
        if(mDebugMessagesFlag)
        {
            Mutex::ScopedLock plock(&mDebugMessagesMutex);
            std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                      << "] - Control Time Out From " << controller.ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
        }
        // Clear values.
        mControllerID.Clear();
        mControllerAuthorityCode = 0;
        mControllerCheckTime.Clear();
        mControllerUpdateTime.Clear();
    }

    mControlMutex.Unlock();

    if(timeout)
    {
        Callback::Set::iterator cb;
        for(cb = mCallbacks.begin();
            cb != mCallbacks.end();
            cb++)
        {
            (*cb)->ProcessReleaseOfControl(controller);
        }
        Service::Map children = GetChildServices();
        Service::Map::iterator child;
        for(child = children.begin();
            child != children.end();
            child++)
        {
            Child* controlChild = dynamic_cast<Child *>(child->second);
            if(controlChild)
            {
                controlChild->ReleaseControl();
            }
        }
        SignalEvent(REPORT_CONTROL);
    }
}
Example #3
0
////////////////////////////////////////////////////////////////////////////////////
///
///   \brief Method called periodically by external classes and is used to
///          verify control of components.
///
///   \param[in] timeSinceLastCheckMs Number of milliseconds since the last time
///                                   this method was called.
///
////////////////////////////////////////////////////////////////////////////////////
void AccessControl::CheckServiceStatus(const unsigned int timeSinceLastCheckMs)
{
    RequestControl request;
    Address::Set lostComponents;
    Time currentTime;

    // Upgrade/Read lock
    {
#ifdef JAUS_USE_UPGRADE_LOCKS
        UpgradeLock uLock(mControlMutex);
#else
        WriteLock wLock(mControlMutex);
#endif

        request.SetSourceID(GetComponentID());
        request.SetAuthorityCode(mAuthorityCode);

        Address::Set::iterator component;
        
        currentTime.SetCurrentTime();
    
        for(component = mControlledComponents.begin();
            component != mControlledComponents.end();
            component++)
        {
            // If we are releasing control, do not check.
            if(mToReleaseControl.find(*component) != mToReleaseControl.end())
            {
                continue;
            }
            // If we have not checked within timeout - .x seconds, then re-acquire control to
            // maintain constant control of component.
            double thresh = mTimeoutPeriods[*component]*mTimeoutThreshold/100.0;
            double checkTimeDiff = currentTime.ToSeconds() - mControlCheckTimes[*component].ToSeconds();
            double timeThresh = (mTimeoutPeriods[*component] - thresh);
            bool checkConfirmation = true;
            if(mTimeoutPeriods[*component] > 0 && checkTimeDiff >= thresh)
            {
                request.SetDestinationID(*component);
                if(Send(&request))
                {
                    // Update the check time.
#ifdef JAUS_USE_UPGRADE_LOCKS
                    UpgradeToUniqueLock upLock(uLock);
#endif
                    mControlCheckTimes[*component].SetCurrentTime();
                    checkConfirmation = false;
                }
            }
            double confirmTimeDiff = currentTime.ToSeconds() - mControlConfirmTimes[*component].ToSeconds();
            timeThresh = (mTimeoutPeriods[*component] + thresh);
            // If we haven't been confirmed in this time, then we have lost control.
            if(checkConfirmation && confirmTimeDiff > timeThresh)
            {
                mControlFlags[*component] = false;
                lostComponents.insert(*component);
            }
        }
    
    }

    // Notify subscribers of any lost control events.
    {
        Address::Set::iterator lost;
        for(lost = lostComponents.begin();
            lost != lostComponents.end();
            lost++)
        {
            // Generate events and callbacks.
            ReadLock cbrLock(mCallbacksMutex);
            Callback::Set::iterator cb;
            for(cb = mCallbacks.begin();
                cb != mCallbacks.end();
                cb++)
            {
                (*cb)->ProcessLossOfControl(*lost);
            }
        }
    }

    Address controller; // Current controlling component. 

    bool timeout = false;
    {
#ifdef JAUS_USE_UPGRADE_LOCKS
        UpgradeLock uLock(mControlMutex);
#else
        WriteLock wLock(mControlMutex);
#endif

        controller = mControllerID;
        
        currentTime.SetCurrentTime();
        double timeSinceRequest = currentTime - mControllerCheckTime;
        if(mTimeoutPeriod > 0 && 
           controller.IsValid() && 
           timeSinceRequest >= (double)mTimeoutPeriod + mTimeoutPeriod*mTimeoutThreshold/100.0)
        {
            timeout = true;
            // Release control due to timeout.
            RejectControl reject(controller, GetComponentID());
            reject.SetResponseCode(RejectControl::ControlReleased);
            Send(&reject);
            if(DebugMessagesEnabled())
            {
                std::stringstream dMessage;
                dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                    << "] - Control Time from " << controller.ToString() << " at " << Time::GetUtcTime().ToString();
                PrintDebugMessage(dMessage.str());
            }

            {
#ifdef JAUS_USE_UPGRADE_LOCKS
                UpgradeToUniqueLock upLock(uLock);
#endif
                // Clear values.
                mControllerID.Clear();
                mControllerAuthorityCode = 0;
                mControllerCheckTime.Clear();
                mControllerUpdateTime.Clear();
            }
        }
    }

    if(timeout)
    {
        {
            ReadLock cbrLock(mCallbacksMutex);
            Callback::Set::iterator cb;
            for(cb = mCallbacks.begin();
                cb != mCallbacks.end();
                cb++)
            {
                (*cb)->ProcessReleaseOfControl(controller);
            }
        }
        Service::Map children = GetChildServices();
        Service::Map::iterator child;
        for(child = children.begin();
            child != children.end();
            child++)
        {
            Child* controlChild = dynamic_cast<Child *>(child->second);
            if(controlChild)
            {
                controlChild->ReleaseControl();
            }
        }
        SignalEvent(REPORT_CONTROL);
    }
}