Esempio n. 1
0
////////////////////////////////////////////////////////////////////////////////////
///
///   \brief Processes message received by the Service.  If not supported, then
///          message is passed to inheriting services depending on what
///          type of control has been established for the component.
///
///   This Service supports AccessControl related messages only.
///
///   \param[in] message Message data to process.
///
////////////////////////////////////////////////////////////////////////////////////
void AccessControl::Receive(const Message* message)
{
    if(AcceptCommandMessage(message) == false)
    {
        return;
    }

    if(mControllerID == message->GetSourceID())
    {
        mControllerUpdateTime.SetCurrentTime();
    }

    switch(message->GetMessageCode())
    {
    case CONFIRM_CONTROL:
        {
            const ConfirmControl* command = dynamic_cast<const ConfirmControl*>(message);
            if(command == NULL)
                return;
            
            if(command->GetResponseCode() == ConfirmControl::ControlAccepted)
            {
                bool firstTime = true;

                // Lock data.
                mControlMutex.Lock();
                // See if we already had control, and if not, then
                // we re-acquired control of this component and must
                // signal via callbacks, etc. of this event.
                Address::Set::iterator controlledComponent = mControlledComponents.find(message->GetSourceID());
                if(controlledComponent != mControlledComponents.end())
                {
                    // If we get here, we have been trying to control this
                    // component. Check the control status flag.
                    std::map<Address, bool>::iterator flag = mControlFlags.find(message->GetSourceID());
                    if(flag->second == true)
                    {
                        // We already had control, nothing new here.
                        // So don't trigger events.
                        firstTime = false;
                    }
                }

                mControlledComponents.insert(message->GetSourceID());
                mControlConfirmTimes[message->GetSourceID()].SetCurrentTime();
                mControlFlags[message->GetSourceID()] = true;

                // Unlock data.
                mControlMutex.Unlock();

                if(mDebugMessagesFlag)
                {
                    Mutex::ScopedLock plock(&mDebugMessagesMutex);
                    if(firstTime)
                    {
                        std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                  << "] - Acquired Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
                    }
                    else
                    {
                        std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                  << "] - Maintained Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
                    }
                }

                // Trigger callbacks if needed.
                if(firstTime)
                {
                    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->ProcessAcquisitionOfControl(message->GetSourceID());
                        }
                    }

                    Mutex::ScopedLock cbLock(&mCallbacksMutex);
                    Callback::Set::iterator cb;
                    for(cb = mCallbacks.begin();
                        cb != mCallbacks.end();
                        cb++)
                    {
                        (*cb)->ProcessAcquisitionfControl(message->GetSourceID());
                    }
                }
            }
            else
            {
                Address::Set::iterator component;

                // Lock data.
                mControlMutex.Lock();

                component = mControlledComponents.find(message->GetSourceID());
                if(component != mControlledComponents.end())
                {                    
                    std::map<Address, bool>::iterator flag;
                    flag = mMaintainFlags.find(message->GetSourceID());
                    if(flag != mMaintainFlags.end())
                    {
                        // If we didn't get control, and we are not
                        // trying to maintain control, remove the component
                        // from our lists. If we don't have high enough authority
                        // then don't bother trying to re-acquire control.
                        if(flag->second == false || command->GetMessageCode() == ConfirmControl::InsufficientAuthority)
                        {
                            EraseComponentControlInfo(message->GetSourceID());
                        }
                        else // Update control status
                        {
                            mControlFlags[message->GetSourceID()] = false;
                        }
                    }
                    // Delete junk data.
                    else
                    {
                        EraseComponentControlInfo(message->GetSourceID());
                    }
                }
                // Unlock data.
                mControlMutex.Unlock();
            }
        }
        break;
    case QUERY_AUTHORITY:
        {
            if(mShutdownServiceFlag)
            {
                break;
            }
            Mutex::ScopedLock lock(&mControlMutex);
            ReportAuthority report(message->GetSourceID(), GetComponentID());
            report.SetAuthorityCode(mAuthorityCode);
            Send(&report);
        }
        break;
    case QUERY_CONTROL:
        {
            Mutex::ScopedLock lock(&mControlMutex);
            ReportControl report(message->GetSourceID(), GetComponentID());
            report.SetAuthorityCode(mControllerAuthorityCode);
            report.SetControllingComponent(mControllerID);
            Send(&report);
        } 
        break;
    case QUERY_TIMEOUT:
        {
            Mutex::ScopedLock lock(&mControlMutex);
            ReportTimeout report(message->GetSourceID(), GetComponentID());
            report.SetTimeoutSeconds(mTimeoutPeriod);
            Send(&report);
        }
        break;
    case REJECT_CONTROL:
        {
            const RejectControl* command = dynamic_cast<const RejectControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;

            Mutex::ScopedLock lock(&mControlMutex);

            Address::Set::iterator component;
            component = mControlledComponents.find(message->GetSourceID());
            if(component != mControlledComponents.end())
            {                
                std::map<Address, bool>::iterator flag;
                flag = mMaintainFlags.find(message->GetSourceID());
                if(flag != mMaintainFlags.end())
                {
                    // If we lost control, and we are not
                    // trying to maintain control, remove the component
                    // from our lists.
                    if(flag->second == false)
                    {
                        mMaintainFlags.erase(flag);
                        mControlFlags.erase(mControlFlags.find(message->GetSourceID()));
                        mControlConfirmTimes.erase(mControlConfirmTimes.find(message->GetSourceID()));
                        mControlledComponents.erase(component);
                    }
                    else // Update control status
                    {
                        mControlFlags[message->GetSourceID()] = false;
                    }
                    // Generate events and callbacks.
                    Mutex::ScopedLock clock(&mCallbacksMutex);
                    Callback::Set::iterator cb;
                    for(cb = mCallbacks.begin();
                        cb != mCallbacks.end();
                        cb++)
                    {
                        (*cb)->ProcessLossOfControl(message->GetSourceID());
                    }
                }
                // Delete junk data.
                else
                {
                    if(mControlFlags.find(*component) != mControlFlags.end())
                    {
                        mControlFlags.erase(*component);
                    }
                    mControlledComponents.erase(*component);
                }
            }
            if(mDebugMessagesFlag)
            {
                Mutex::ScopedLock plock(&mDebugMessagesMutex);
                std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                          << "] - Lost Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
            }
        }
        break;
    case RELEASE_CONTROL:
        {
            const ReleaseControl* command = dynamic_cast<const ReleaseControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;
            
            Mutex::ScopedLock lock(&mControlMutex);
            if(command->GetSourceID() == mControllerID)
            {
                RejectControl response(mControllerID, GetComponentID());

                bool controlReleased = true;
                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)
                    {
                        if(controlChild->ReleaseControl())
                        {
                            controlReleased;
                        }
                    }
                }
                if(controlReleased)
                {
                    response.SetResponseCode(RejectControl::ControlReleased);
                    Send(&response);

                    mControllerID = Address();
                    mControllerAuthorityCode = 0;
                    mControllerUpdateTime.Clear();
                    mControllerCheckTime.Clear();

                    if(mDebugMessagesFlag)
                    {
                        Mutex::ScopedLock plock(&mDebugMessagesMutex);
                        std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                  << "] - Control Released from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
                    }

                    // Generate events and callbacks.
                    Mutex::ScopedLock clock(&mCallbacksMutex);
                    Callback::Set::iterator cb;
                    for(cb = mCallbacks.begin();
                        cb != mCallbacks.end();
                        cb++)
                    {
                        (*cb)->ProcessReleaseOfControl(message->GetSourceID());
                    }
                    SignalEvent(REPORT_CONTROL);
                }
                else
                {
                    response.SetResponseCode(RejectControl::NotAvailable);
                    Send(&response);
                }
            }
        }
        break;
    case REPORT_AUTHORITY:
        {
            const JAUS::ReportAuthority* report = dynamic_cast<const JAUS::ReportAuthority*>(message);
            if(report)
            {
                // Update Discovery Contents.
                try
                {
                    Discovery* discovery = GetComponent()->DiscoveryService();
                    if(discovery)
                    {
                        discovery->GetSubsystem(report->GetSourceID().mSubsystem)->GetComponent(report->GetSourceID())->mAuthorityLevel = (int)report->GetAuthorityCode();
                        if( discovery->GetVehicle(report->GetSourceID().mSubsystem).IsValid() && 
                            discovery->GetVehicle(report->GetSourceID().mSubsystem)->mAuthority < (int)report->GetAuthorityCode())
                        {
                            discovery->GetVehicle(report->GetSourceID().mSubsystem)->mAuthority = (int)report->GetAuthorityCode();
                        }
                    }
                }
                catch(Exception& e)
                {
                    e.Print();
                }
            }
        }
        break;
    case REPORT_CONTROL:
        // Not used.
        break;
    case REPORT_TIMEOUT:
        {
            const ReportTimeout* report = dynamic_cast<const ReportTimeout*>(message);
            if(report == NULL)
                return;

            Mutex::ScopedLock lock(&mControlMutex);
            mTimeoutPeriods[message->GetSourceID()] = report->GetTimeoutSeconds();
            if(mTimeoutPeriods[message->GetSourceID()] == 0)
            {
                // We always want to check for control.
                mTimeoutPeriods[message->GetSourceID()] = 2;
            }
        }
        break;
    case REQUEST_CONTROL:
        {
            const RequestControl* command = dynamic_cast<const RequestControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;
            
            ConfirmControl response(message->GetSourceID(), GetComponentID());

            Mutex::ScopedLock lock(&mControlMutex);
            // If they have minimum authority and we are
            // not under control or component has greater authority than
            // the current controller, accept.
            if(mControllableFlag && 
               command->GetAuthorityCode() >= mAuthorityCode &&
               (mControllerID == command->GetSourceID() || mControllerID.IsValid() == false || command->GetAuthorityCode() > mControllerAuthorityCode))
            {
                bool controlAccepted = true;
                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)
                    {
                        controlAccepted = controlChild->RequestControl();
                        if(controlAccepted)
                        {
                            break;
                        }
                    }
                }
                // This check is needed in case any child
                // service (Management) is in an Emergency state
                // and cannot transition.
                if(controlAccepted == false)
                {
                    response.SetResponseCode(ConfirmControl::NotAvailable);
                }
                else
                {
                    response.SetResponseCode(ConfirmControl::ControlAccepted);
                    if(mControllerID != command->GetSourceID() && mControllerID.IsValid())
                    {
                        // Notify controller that they have lost control.
                        RejectControl reject(mControllerID, GetComponentID());
                        reject.SetResponseCode(RejectControl::ControlReleased);
                        Send(&reject);
                    }
                    mControllerID = message->GetSourceID();
                    mControllerAuthorityCode = command->GetAuthorityCode();
                    mControllerCheckTime.SetCurrentTime();
                    mControllerUpdateTime.SetCurrentTime();
                    if(mDebugMessagesFlag)
                    {
                        Mutex::ScopedLock plock(&mDebugMessagesMutex);
                        std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                            << "] - Control Granted to " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
                    }
                }
            }
            else
            {    
                if(mControllableFlag == false)
                {
                    response.SetResponseCode(ConfirmControl::NotAvailable);
                }
                else
                {                    
                    response.SetResponseCode(ConfirmControl::InsufficientAuthority);
                }      
                if(mDebugMessagesFlag)
                {
                    Mutex::ScopedLock plock(&mDebugMessagesMutex);
                    std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                              << "] - Control Rejected from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
                }
            }
            Send(&response);
        }
        break;
    case SET_AUTHORITY:
        {
            const SetAuthority* command = dynamic_cast<const SetAuthority*>(message);
            if(command == NULL)
                return;
            
            Mutex::ScopedLock lock(&mControlMutex);
            mAuthorityCode = command->GetAuthorityCode();
            SignalEvent(REPORT_AUTHORITY);

            // Update Discovery Contents.
            try
            {
                Discovery* discovery = GetComponent()->DiscoveryService();
                if(discovery)
                {
                    discovery->GetSubsystem(command->GetDestinationID().mSubsystem)->GetComponent(command->GetDestinationID())->mAuthorityLevel = (int)command->GetAuthorityCode();
                    if(discovery->GetVehicle(command->GetDestinationID().mSubsystem)->mAuthority < (int)command->GetAuthorityCode())
                    {
                        discovery->GetVehicle(command->GetDestinationID().mSubsystem)->mAuthority = (int)command->GetAuthorityCode();
                    }
                }
            }
            catch(Exception& e)
            {
                e.Print();
            }
        }
        break;
    default:
        break;
    };
}
Esempio n. 2
0
////////////////////////////////////////////////////////////////////////////////////
///
///   \brief Processes message received by the Service.  If not supported, then
///          message is passed to inheriting services depending on what
///          type of control has been established for the component.
///
///   This Service supports AccessControl related messages only.
///
///   \param[in] message Message data to process.
///
////////////////////////////////////////////////////////////////////////////////////
void AccessControl::Receive(const Message* message)
{
    if(AcceptCommandMessage(message) == false)
    {
        return;
    }

    if(mControllerID == message->GetSourceID())
    {
        mControllerUpdateTime.SetCurrentTime();
    }

    switch(message->GetMessageCode())
    {
    case CONFIRM_CONTROL:
        {
            const ConfirmControl* command = static_cast<const ConfirmControl*>(message);
            if(command == NULL)
                return;
            
            if(command->GetResponseCode() == ConfirmControl::ControlAccepted)
            {
                bool firstTime = true;

                    // Lock data.
                {
                    WriteLock wLock(mControlMutex);

                    // See if we already had control, and if not, then
                    // we re-acquired control of this component and must
                    // signal via callbacks, etc. of this event.
                    Address::Set::iterator controlledComponent = mControlledComponents.find(message->GetSourceID());
                    if(controlledComponent != mControlledComponents.end())
                    {
                        // If we get here, we have been trying to control this
                        // component. Check the control status flag.
                        std::map<Address, bool>::iterator flag = mControlFlags.find(message->GetSourceID());
                        if(flag->second == true)
                        {
                            // We already had control, nothing new here.
                            // So don't trigger events.
                            firstTime = false;
                        }
                    }

                    mControlledComponents.insert(message->GetSourceID());
                    mControlConfirmTimes[message->GetSourceID()].SetCurrentTime();
                    mControlFlags[message->GetSourceID()] = true;

                }
                if(DebugMessagesEnabled())
                {
                    if(firstTime)
                    {
                        std::stringstream dMessage;
                        dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                    << "] - Acquired Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                        PrintDebugMessage(dMessage.str());
                    }
                    else
                    {
                        std::stringstream dMessage;
                        dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                    << "] - Maintained Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                        PrintDebugMessage(dMessage.str());
                    }
                }

                // Trigger callbacks if needed.
                if(firstTime)
                {
                    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->ProcessAcquisitionOfControl(message->GetSourceID());
                        }
                    }
                    {
                        ReadLock cbrLock(mCallbacksMutex);
                        Callback::Set::iterator cb;
                        for(cb = mCallbacks.begin();
                            cb != mCallbacks.end();
                            cb++)
                        {
                            (*cb)->ProcessAcquisitionfControl(message->GetSourceID());
                        }
                    }
                }
            }
            else
            {
                Address::Set::iterator component;

                // Lock data.
                WriteLock wLock(mControlMutex);

                component = mControlledComponents.find(message->GetSourceID());
                if(component != mControlledComponents.end())
                {                    
                    std::map<Address, bool>::iterator flag;
                    flag = mMaintainFlags.find(message->GetSourceID());
                    if(flag != mMaintainFlags.end())
                    {
                        // If we didn't get control, and we are not
                        // trying to maintain control, remove the component
                        // from our lists. If we don't have high enough authority
                        // then don't bother trying to re-acquire control.
                        if(flag->second == false || command->GetMessageCode() == ConfirmControl::InsufficientAuthority)
                        {
                            EraseComponentControlInfo(message->GetSourceID());
                        }
                        else // Update control status
                        {
                            mControlFlags[message->GetSourceID()] = false;
                        }
                    }
                    // Delete junk data.
                    else
                    {
                        EraseComponentControlInfo(message->GetSourceID());
                    }
                }
            }
        }
        break;
    case QUERY_AUTHORITY:
        {
            if(mShutdownServiceFlag)
            {
                break;
            }
            
            ReportAuthority report(message->GetSourceID(), GetComponentID());
            {
                ReadLock rLock(mControlMutex);
                report.SetAuthorityCode(mAuthorityCode);
            }
            Send(&report);
        }
        break;
    case QUERY_CONTROL:
        {
            ReportControl report(message->GetSourceID(), GetComponentID());
            {
                ReadLock rLock(mControlMutex);
                report.SetAuthorityCode(mAuthorityCode);
                report.SetControllingComponent(mControllerID);
            }
            Send(&report);
        } 
        break;
    case QUERY_TIMEOUT:
        {
            ReportTimeout report(message->GetSourceID(), GetComponentID());
            {
                ReadLock rLock(mControlMutex);
                report.SetTimeoutSeconds(mTimeoutPeriod);
            }
            Send(&report);
        }
        break;
    case REJECT_CONTROL:
        {
            const RejectControl* command = static_cast<const RejectControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;

            bool signalCallbacks = false;
            {
                WriteLock wLock(mControlMutex);
                // Update state of controlled components.
                Address::Set::iterator component;
                component = mControlledComponents.find(message->GetSourceID());
                if(component != mControlledComponents.end())
                {                
                    std::map<Address, bool>::iterator flag;
                    flag = mMaintainFlags.find(message->GetSourceID());
                    if(flag != mMaintainFlags.end())
                    {
                        // If we lost control, and we are not
                        // trying to maintain control, remove the component
                        // from our lists.
                        if(flag->second == false)
                        {
                            mMaintainFlags.erase(flag);
                            mControlFlags.erase(mControlFlags.find(message->GetSourceID()));
                            mControlConfirmTimes.erase(mControlConfirmTimes.find(message->GetSourceID()));
                            mControlledComponents.erase(component);
                        }
                        else // Update control status
                        {
                            mControlFlags[message->GetSourceID()] = false;
                        }
                        signalCallbacks = true;
                    }
                    // Delete junk data.
                    else
                    {
                        if(mControlFlags.find(*component) != mControlFlags.end())
                        {
                            mControlFlags.erase(*component);
                        }
                        mControlledComponents.erase(*component);
                    }
                }
            }
            if(signalCallbacks)
            {
                // Generate events and callbacks.
                ReadLock cbrLock(mCallbacksMutex);
                Callback::Set::iterator cb;
                for(cb = mCallbacks.begin();
                    cb != mCallbacks.end();
                    cb++)
                {
                    (*cb)->ProcessLossOfControl(message->GetSourceID());
                }
            }
            
            if(DebugMessagesEnabled())
            {
                std::stringstream dMessage;
                dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                          << "] - Lost Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                PrintDebugMessage(dMessage.str());
            }
        }
        break;
    case RELEASE_CONTROL:
        {
            const ReleaseControl* command = static_cast<const ReleaseControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;

            if(command->GetSourceID() == mControllerID)
            {
                RejectControl response(mControllerID, GetComponentID());

                bool controlReleased = true;
                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)
                    {
                        if(controlChild->ReleaseControl())
                        {
                            controlReleased;
                        }
                    }
                }
                if(controlReleased)
                {
                    response.SetResponseCode(RejectControl::ControlReleased);
                    Send(&response);

                    // Update data members of who was in control to nobody!
                    {
                        WriteLock wLock(mControlMutex);
                        mControllerID = Address();
                        mControllerAuthorityCode = 0;
                        mControllerUpdateTime.Clear();
                        mControllerCheckTime.Clear();
                    }
                    if(DebugMessagesEnabled())
                    {
                        std::stringstream dMessage;
                        dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                 << "] - Control Released from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                        PrintDebugMessage(dMessage.str());
                    }

                    // Signal a change in control event
                    SignalEvent(REPORT_CONTROL);

                    // Notify children of control release.
                    {
                        // Generate events and callbacks.
                        ReadLock cbrLock(mCallbacksMutex);
                        Callback::Set::iterator cb;
                        for(cb = mCallbacks.begin();
                            cb != mCallbacks.end();
                            cb++)
                        {
                            (*cb)->ProcessReleaseOfControl(message->GetSourceID());
                        }
                    }
                }
                else
                {
                    response.SetResponseCode(RejectControl::NotAvailable);
                    Send(&response);
                }
            }
        }
        break;
    case REPORT_AUTHORITY:
        {
            const JAUS::ReportAuthority* report = static_cast<const JAUS::ReportAuthority*>(message);
            if(report)
            {
                // Used by Discovery service to keep track of information
                // about components on the netework
            }
        }
        break;
    case REPORT_CONTROL:
        // Not used.
        break;
    case REPORT_TIMEOUT:
        {
            const ReportTimeout* report = static_cast<const ReportTimeout*>(message);
            if(report == NULL)
                return;

            WriteLock wLock(mControlMutex);
            mTimeoutPeriods[message->GetSourceID()] = report->GetTimeoutSeconds();
            if(mTimeoutPeriods[message->GetSourceID()] == 0)
            {
                // We always want to check for control.
                mTimeoutPeriods[message->GetSourceID()] = 2;
            }
        }
        break;
    case REQUEST_CONTROL:
        {
            const RequestControl* command = static_cast<const RequestControl*>(message);
            if(mShutdownServiceFlag || command == NULL)
                return;
            
            ConfirmControl response(message->GetSourceID(), GetComponentID());
#ifdef JAUS_USE_UPGRADE_LOCKS
            UpgradeLock upLock(mControlMutex);
#else
            WriteLock wLock(mControlMutex);
#endif
            // If they have minimum authority and we are
            // not under control or component has greater authority than
            // the current controller, accept.
            if(mControllableFlag && 
               command->GetAuthorityCode() >= mAuthorityCode &&
               (mControllerID == command->GetSourceID() || mControllerID.IsValid() == false || command->GetAuthorityCode() > mControllerAuthorityCode))
            {
                bool controlAccepted = true;
                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)
                    {
                        controlAccepted = controlChild->RequestControl();
                        if(controlAccepted)
                        {
                            break;
                        }
                    }
                }
                // This check is needed in case any child
                // service (Management) is in an Emergency state
                // and cannot transition.
                if(controlAccepted == false)
                {
                    response.SetResponseCode(ConfirmControl::NotAvailable);
                }
                else
                {
                    response.SetResponseCode(ConfirmControl::ControlAccepted);
                    if(mControllerID != command->GetSourceID() && mControllerID.IsValid())
                    {
                        // Notify controller that they have lost control.
                        RejectControl reject(mControllerID, GetComponentID());
                        reject.SetResponseCode(RejectControl::ControlReleased);
                        Send(&reject);
                    }
                    {
#ifdef JAUS_USE_UPGRADE_LOCKS
                        UpgradeToUniqueLock uniqueLock(upLock);
#endif
                        mControllerID = message->GetSourceID();
                        mControllerAuthorityCode = command->GetAuthorityCode();
                        mControllerCheckTime.SetCurrentTime();
                        mControllerUpdateTime.SetCurrentTime();
                    }
                    if(DebugMessagesEnabled())
                    {
                        std::stringstream dMessage;
                        dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                                 << "] - Control Granted to " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                        PrintDebugMessage(dMessage.str());
                    }
                }
            }
            else
            {    
                if(mControllableFlag == false)
                {
                    response.SetResponseCode(ConfirmControl::NotAvailable);
                }
                else
                {                    
                    response.SetResponseCode(ConfirmControl::InsufficientAuthority);
                }
                if(DebugMessagesEnabled())
                {
                    std::stringstream dMessage;
                    dMessage << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString() 
                        << "] - Control Rejected from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString();
                    PrintDebugMessage(dMessage.str());
                }
            }
            Send(&response);
        }
        break;
    case SET_AUTHORITY:
        {
            const SetAuthority* command = static_cast<const SetAuthority*>(message);
            if(command == NULL)
                return;
            
            SetAuthorityCode(command->GetAuthorityCode());
        }
        break;
    default:
        break;
    };
}