00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "jaus/core/management/management.h"
00041 #include "jaus/core/component.h"
00042 #include <iostream>
00043
00044 using namespace JAUS;
00045
00046 const std::string Management::Name = "urn:jaus:jss:core:Management";
00047
00048
00064 bool Management::Child::RequestComponentControl(const Address &id,
00065 const bool sendResumeCommand,
00066 const bool reacquire,
00067 const unsigned int waitTimeMs)
00068 {
00069 if(GetComponent() == NULL)
00070 {
00071 return false;
00072 }
00073 if(!GetComponent()->AccessControlService()->HaveControl(id))
00074 {
00075 if(GetComponent()->AccessControlService()->RequestComponentControl(id, reacquire, waitTimeMs))
00076 {
00077 if(sendResumeCommand)
00078 {
00079 return GetComponent()->ManagementService()->Resume(id, waitTimeMs);
00080 }
00081 return true;
00082 }
00083
00084 return false;
00085 }
00086 else if(sendResumeCommand)
00087 {
00088 return GetComponent()->ManagementService()->Resume(id, waitTimeMs);
00089 }
00090
00091 return true;
00092 }
00093
00094
00111 bool Management::Child::ReleaseComponentControl(const Address &id,
00112 const bool sendStandbyCommand,
00113 const unsigned int waitTimeMs)
00114 {
00115 if(GetComponent())
00116 {
00117 if(sendStandbyCommand)
00118 {
00119 if(GetComponent()->ManagementService()->Standby(id, waitTimeMs) &&
00120 GetComponent()->AccessControlService()->ReleaseComponentControl(id, waitTimeMs))
00121 {
00122 return true;
00123 }
00124 }
00125 else if(GetComponent()->AccessControlService()->ReleaseComponentControl(id, waitTimeMs))
00126 {
00127 return true;
00128 }
00129 }
00130
00131 return false;
00132 }
00133
00134
00140 Management::Management() : AccessControl::Child(Service::ID(Management::Name),
00141 Service::ID(AccessControl::Name))
00142 {
00143 mStatus = Status::Initialized;
00144 }
00145
00146
00152 Management::~Management()
00153 {
00154 }
00155
00156
00171 bool Management::Resume(const Address& id,
00172 const unsigned int waitTimeMs)
00173 {
00174 if(id.mSubsystem == GetComponentID().mSubsystem)
00175 {
00176 if(GetComponentStatus(id) == (int)Status::Ready)
00177 {
00178 return true;
00179 }
00180 }
00181 JAUS::Resume resume(id, GetComponentID());
00182 if(Send(&resume))
00183 {
00184 if(waitTimeMs > 0)
00185 {
00186 CxUtils::SleepMs(10);
00187 QueryStatus query(id, GetComponentID());
00188 ReportStatus response;
00189 if(Send(&query, &response, waitTimeMs) && response.GetStatus() == Status::Ready)
00190 {
00191 return true;
00192 }
00193 if(GetComponentStatus(id) == (int)Status::Ready)
00194 {
00195 return true;
00196 }
00197 }
00198 else
00199 {
00200 return true;
00201 }
00202 }
00203 return false;
00204 }
00205
00206
00226 bool Management::Standby(const Address& id,
00227 const unsigned int waitTimeMs)
00228 {
00229 if(id.IsValid() == false)
00230 {
00231 Address::List inControl = GetComponent()->AccessControlService()->GetControlledComponents();
00232 Address::List::iterator c;
00233 bool result = true;
00234 for(c = inControl.begin(); c != inControl.end(); c++)
00235 {
00236 result &= Standby(*c, waitTimeMs);
00237 }
00238 return result;
00239 }
00240
00241 if(id.mSubsystem == GetComponentID().mSubsystem)
00242 {
00243 if(GetComponentStatus(id) == (int)Status::Standby)
00244 {
00245 return true;
00246 }
00247 }
00248
00249 JAUS::Standby standby(id, GetComponentID());
00250 if(Send(&standby))
00251 {
00252 if(waitTimeMs > 0)
00253 {
00254 QueryStatus query(id, GetComponentID());
00255 ReportStatus response;
00256 if(Send(&query, &response, waitTimeMs) && response.GetStatus() == Status::Standby)
00257 {
00258 return true;
00259 }
00260 }
00261 else
00262 {
00263 return true;
00264 }
00265 }
00266 return false;
00267 }
00268
00269
00284 bool Management::SetEmergency(const Address& id,
00285 const unsigned int waitTimeMs)
00286 {
00287 JAUS::SetEmergency setEmergency(id, GetComponentID());
00288 setEmergency.SetEmergencyCode(1);
00289 if(Send(&setEmergency))
00290 {
00291 if(waitTimeMs > 0)
00292 {
00293 QueryStatus query(id, GetComponentID());
00294 ReportStatus response;
00295 if(Send(&query, &response, waitTimeMs) && response.GetStatus() == Status::Emergency)
00296 {
00297 return true;
00298 }
00299 }
00300 else
00301 {
00302 return true;
00303 }
00304 }
00305 return false;
00306 }
00307
00308
00323 bool Management::ClearEmergency(const Address& id,
00324 const unsigned int waitTimeMs)
00325 {
00326 JAUS::ClearEmergency clearEmergency(id, GetComponentID());
00327 clearEmergency.SetEmergencyCode(1);
00328 if(Send(&clearEmergency))
00329 {
00330 if(waitTimeMs > 0)
00331 {
00332 QueryStatus query(id, GetComponentID());
00333 ReportStatus response;
00334 if(Send(&query, &response, waitTimeMs) && response.GetStatus() != Status::Emergency)
00335 {
00336 return true;
00337 }
00338 }
00339 else
00340 {
00341 return true;
00342 }
00343 }
00344 return false;
00345 }
00346
00347
00359 bool Management::Shutdown(const Address& id)
00360 {
00361 if(id.IsValid() == false)
00362 {
00363 Address::List inControl = GetComponent()->AccessControlService()->GetControlledComponents();
00364 Address::List::iterator c;
00365 bool result = true;
00366 for(c = inControl.begin(); c != inControl.end(); c++)
00367 {
00368 result &= Shutdown(*c);
00369 }
00370 return result;
00371 }
00372
00373 JAUS::Shutdown shutdown(id, GetComponentID());
00374 if(Send(&shutdown))
00375 {
00376 return true;
00377 }
00378 return false;
00379 }
00380
00381
00387 void Management::Initialize()
00388 {
00389 mStatus = Management::Status::Initialized;
00390 SetStatus(mStatus);
00391 }
00392
00393
00399 void Management::Shutdown()
00400 {
00401 mStatus = Status::Shutdown;
00402 }
00403
00404
00414 bool Management::GenerateEvent(const Events::Subscription& info) const
00415 {
00416 if(info.mpQueryMessage->GetMessageCode() == QUERY_STATUS)
00417 {
00418 JAUS::ReportStatus report;
00419 report.SetStatus(mStatus);
00420 SendEvent(info, &report);
00421 return true;
00422 }
00423 return false;
00424 }
00425
00426
00442 bool Management::IsEventSupported(const Events::Type type,
00443 const double requestedPeriodicRate,
00444 const Message* queryMessage,
00445 double& confirmedPeriodicRate,
00446 std::string& errorMessage) const
00447 {
00448 bool result = false;
00449 switch(queryMessage->GetMessageCode())
00450 {
00451 case QUERY_STATUS:
00452 confirmedPeriodicRate = requestedPeriodicRate;
00453 result = true;
00454 break;
00455 default:
00456 result = false;
00457 break;
00458 };
00459 return result;
00460 }
00461
00462
00474 void Management::Receive(const Message* message)
00475 {
00476 switch(message->GetMessageCode())
00477 {
00478 case CLEAR_EMERGENCY:
00479 {
00480
00481 if(mStatus == Status::Emergency)
00482 {
00483 Service::Map children = GetChildServices();
00484 Service::Map::iterator i;
00485 for(i = children.begin();
00486 i != children.end();
00487 i++)
00488 {
00489 Management::Child* child = dynamic_cast<Management::Child*>(i->second);
00490 if(child)
00491 {
00492 child->ClearEmergency();
00493 child->mStatus = mStatus;
00494 }
00495 }
00496
00497 SetStatus(Status::Standby);
00498 }
00499 }
00500 break;
00501 case QUERY_STATUS:
00502 {
00503
00504 JAUS::ReportStatus report(message->GetSourceID(), GetComponentID());
00505 report.SetStatus(mStatus);
00506 Send(&report);
00507 if(mDebugMessagesFlag)
00508 {
00509 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00510 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00511 << "] - " << report.GetDestinationID().ToString() << " Requested Status at " << Time::GetUtcTime().ToString() << "\n";
00512 }
00513 }
00514 break;
00515 case REPORT_STATUS:
00516 {
00517 const JAUS::ReportStatus* report = dynamic_cast<const JAUS::ReportStatus*>(message);
00518 if(report)
00519 {
00520 if(report->GetSourceID().mSubsystem == GetComponentID().mSubsystem)
00521 {
00522 Mutex::ScopedLock lock(&mStatesMutex);
00523 mSubsystemStates[report->GetSourceID()] = (int)report->GetStatus();
00524 }
00525 else
00526 {
00527 try
00528 {
00529
00530 Discovery* discovery = GetComponent()->DiscoveryService();
00531 if(discovery)
00532 {
00533 discovery->GetSubsystem(report->GetSourceID().mSubsystem)->GetComponent(report->GetSourceID())->mStatus = (int)report->GetStatus();
00534 }
00535 }
00536 catch(Exception& e)
00537 {
00538 e.Print();
00539 }
00540 }
00541 }
00542 }
00543 break;
00544 case RESET:
00545 {
00546 if(mDebugMessagesFlag)
00547 {
00548 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00549 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00550 << "] - " << GetComponent()->AccessControlService()->GetControllerID().ToString() << " Sent Reset at " << Time::GetUtcTime().ToString() << "\n";
00551 }
00552
00553 if(mStatus != Status::Initialized)
00554 {
00555 SetStatus(Status::Standby);
00556 }
00557 }
00558 break;
00559 case RESUME:
00560 {
00561 if(mDebugMessagesFlag)
00562 {
00563 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00564 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00565 << "] - " << GetComponent()->AccessControlService()->GetControllerID().ToString() << " Sent Resume at " << Time::GetUtcTime().ToString() << "\n";
00566 }
00567
00568 if(mStatus == Status::Standby || mStatus == Status::Initialized)
00569 {
00570 SetStatus(Status::Ready);
00571 }
00572 }
00573 break;
00574 case SET_EMERGENCY:
00575 {
00576 if(mDebugMessagesFlag)
00577 {
00578 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00579 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00580 << "] - " << GetComponent()->AccessControlService()->GetControllerID().ToString() << " Sent Emergency at " << Time::GetUtcTime().ToString() << "\n";
00581 }
00582 SetStatus(Status::Emergency);
00583 }
00584 break;
00585 case SHUTDOWN:
00586 {
00587 mStatus = Status::Shutdown;
00588 if(mDebugMessagesFlag)
00589 {
00590 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00591 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00592 << "] - " << GetComponent()->AccessControlService()->GetControllerID().ToString() << " Sent Shutdown at " << Time::GetUtcTime().ToString() << "\n";
00593 }
00594
00595
00596 if(GetComponent())
00597 {
00598 Service::Map children = GetChildServices();
00599 Service::Map::iterator i;
00600 for(i = children.begin();
00601 i != children.end();
00602 i++)
00603 {
00604 Management::Child* child = dynamic_cast<Management::Child*>(i->second);
00605 if(child)
00606 {
00607 child->mStatus = mStatus;
00608 }
00609 }
00610
00611
00612 }
00613 }
00614 break;
00615 case STANDBY:
00616 {
00617 if(mDebugMessagesFlag)
00618 {
00619 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00620 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00621 << "] - " << GetComponent()->AccessControlService()->GetControllerID().ToString() << " Sent Standby at " << Time::GetUtcTime().ToString() << "\n";
00622 }
00623
00624 if(mStatus == Status::Ready || mStatus == Status::Initialized)
00625 {
00626 SetStatus(Status::Standby);
00627 }
00628 }
00629 default:
00630 break;
00631 };
00632 }
00633
00634
00646 Message* Management::CreateMessage(const UShort messageCode) const
00647 {
00648 Message* message;
00649 switch(messageCode)
00650 {
00651 case CLEAR_EMERGENCY:
00652 message = new JAUS::ClearEmergency();
00653 break;
00654 case QUERY_STATUS:
00655 message = new JAUS::QueryStatus();
00656 break;
00657 case REPORT_STATUS:
00658 message = new JAUS::ReportStatus();
00659 break;
00660 case RESET:
00661 message = new JAUS::Reset();
00662 break;
00663 case RESUME:
00664 message = new JAUS::Resume();
00665 break;
00666 case SET_EMERGENCY:
00667 message = new JAUS::SetEmergency();
00668 break;
00669 case SHUTDOWN:
00670 message = new JAUS::Shutdown();
00671 break;
00672 case STANDBY:
00673 message = new JAUS::Standby();
00674 break;
00675 default:
00676 message = NULL;
00677 break;
00678 };
00679 return message;
00680 }
00681
00682
00692 bool Management::SetStatus(const Byte state)
00693 {
00694
00695 if(state <= Status::Emergency)
00696 {
00697 mStatus = state;
00698
00699
00700 try
00701 {
00702 Discovery* discovery = GetComponent()->DiscoveryService();
00703 if(discovery)
00704 {
00705 discovery->GetSubsystem(GetComponentID().mSubsystem)->GetComponent(GetComponentID())->mStatus = (int)mStatus;
00706 }
00707 }
00708 catch(Exception& e)
00709 {
00710 e.Print();
00711 }
00712
00713 Service::Map children = GetChildServices();
00714 Service::Map::iterator i;
00715 for(i = children.begin();
00716 i != children.end();
00717 i++)
00718 {
00719 Management::Child* child = dynamic_cast<Management::Child*>(i->second);
00720 if(child)
00721 {
00722 switch(mStatus)
00723 {
00724 case Status::Ready:
00725 child->Resume();
00726 break;
00727 case Status::Standby:
00728 child->Standby();
00729 break;
00730 case Status::Emergency:
00731 child->SetEmergency();
00732 break;
00733 default:
00734
00735 break;
00736 }
00737 child->mStatus = mStatus;
00738 }
00739 }
00740
00741 SignalEvent(REPORT_STATUS);
00742 return true;
00743 }
00744 return false;
00745 }
00746
00747
00754 bool Management::ReleaseControl()
00755 {
00756 return SetStatus(Status::Standby);
00757 }
00758
00759
00776 int Management::GetComponentStatus(const Address& id, const unsigned int waitTimeMs) const
00777 {
00778 int result = -1;
00779 if(id.mSubsystem == GetComponentID().mSubsystem)
00780 {
00781
00782 std::map<Address, int>::const_iterator s;
00783 mStatesMutex.Lock();
00784 s = mSubsystemStates.find(id);
00785 if(s != mSubsystemStates.end())
00786 {
00787 result = (int)s->second;
00788 }
00789 mStatesMutex.Unlock();
00790 }
00791
00792 if(result == -1)
00793 {
00794 JAUS::QueryStatus query(id, GetComponentID());
00795 JAUS::ReportStatus report;
00796 if(Send(&query, &report, waitTimeMs))
00797 {
00798 result = (int)report.GetStatus();
00799
00800 if(id.mSubsystem == GetComponentID().mSubsystem)
00801 {
00802 Send(&query);
00803 }
00804 }
00805 }
00806
00807 return result;
00808 }
00809
00810
00816 void Management::PrintStatus() const
00817 {
00818 std::cout << "[" << GetServiceID().ToString() << "] - " << GetComponentID().ToString() << " Status: ";
00819 switch(mStatus)
00820 {
00821 case Status::Ready:
00822 std::cout << "Ready\n";
00823 break;
00824 case Status::Standby:
00825 std::cout << "Standby\n";
00826 break;
00827 case Status::Shutdown:
00828 std::cout << "Shutdown\n";
00829 break;
00830 case Status::Failure:
00831 std::cout << "Failure\n";
00832 break;
00833 case Status::Emergency:
00834 std::cout << "Emergency\n";
00835 break;
00836 default:
00837 std::cout << "Intialized\n";
00838 break;
00839 }
00840 }
00841
00842
00851 void Management::PrintStatus(const bool allData) const
00852 {
00853 std::cout << "[" << GetServiceID().ToString() << "] - " << GetComponentID().ToString() << " Status: ";
00854 switch(mStatus)
00855 {
00856 case Status::Ready:
00857 std::cout << "Ready\n";
00858 break;
00859 case Status::Standby:
00860 std::cout << "Standby\n";
00861 break;
00862 case Status::Shutdown:
00863 std::cout << "Shutdown\n";
00864 break;
00865 case Status::Failure:
00866 std::cout << "Failure\n";
00867 break;
00868 case Status::Emergency:
00869 std::cout << "Emergency\n";
00870 break;
00871 default:
00872 std::cout << "Intialized\n";
00873 break;
00874 }
00875
00876 if(allData)
00877 {
00878 std::cout << "State of Subsystem Components:\n";
00879 Mutex::ScopedLock lock(&mStatesMutex);
00880 std::map<Address, int>::const_iterator s;
00881 for(s = mSubsystemStates.begin();
00882 s != mSubsystemStates.end();
00883 s++)
00884 {
00885 std::cout << " " << s->first.ToString() << " - ";
00886 switch(s->second)
00887 {
00888 case (int)Status::Ready:
00889 std::cout << "Ready\n";
00890 break;
00891 case (int)Status::Standby:
00892 std::cout << "Standby\n";
00893 break;
00894 case (int)Status::Shutdown:
00895 std::cout << "Shutdown\n";
00896 break;
00897 case (int)Status::Initialized:
00898 std::cout << "Initialized\n";
00899 break;
00900 case (int)Status::Emergency:
00901 std::cout << "Emergency\n";
00902 break;
00903 default:
00904 std::cout << "Unknown\n";
00905 break;
00906 }
00907 }
00908 }
00909 }
00910
00911
00921 void Management::CheckServiceStatus(const unsigned int timeSinceLastCheckMs)
00922 {
00923 if(mShutdownServiceFlag)
00924 {
00925 return;
00926 }
00927 if(Time::GetUtcTimeMs() - mCheckStatusTimeMs >= 2000)
00928 {
00929
00930 Service::Map children = GetChildServices();
00931 Service::Map::iterator i;
00932 for(i = children.begin();
00933 i != children.end();
00934 i++)
00935 {
00936 Management::Child* child = dynamic_cast<Management::Child*>(i->second);
00937 if(child)
00938 {
00939 child->mStatus = mStatus;
00940 }
00941 }
00942
00943
00944 Address::List components = GetComponent()->DiscoveryService()->GetSubsystem(GetComponentID().mSubsystem)->GetAddressList();
00945 Address::List::iterator c;
00946
00947 mStatesMutex.Lock();
00948 std::map<Address, int> states;
00949
00950 states[GetComponentID()] = mStatus;
00951
00952
00953 for(c = components.begin();
00954 c != components.end();
00955 c++)
00956 {
00957 if(*c != GetComponentID())
00958 {
00959 if(mSubsystemStates.find(*c) != mSubsystemStates.end())
00960 {
00961 states[*c] = mSubsystemStates[*c];
00962 }
00963 else
00964 {
00965 states[*c] = -1;
00966 }
00967 }
00968 }
00969 mSubsystemStates = states;
00970
00971 mStatesMutex.Unlock();
00972
00973
00974 QueryStatus query(Address(), GetComponentID());
00975 for(c = components.begin();
00976 c != components.end() && mShutdownServiceFlag == false;
00977 c++)
00978 {
00979 if(*c != GetComponentID())
00980 {
00981 query.SetDestinationID(*c);
00982 if(!GetComponent()->EventsService()->HaveSubscription(REPORT_STATUS, *c))
00983 {
00984 if(GetComponent()->EventsService()->RequestPeriodicEvent(*c, &query, 0.5, 0.25) == false)
00985 {
00986
00987 Send(&query);
00988 }
00989 }
00990 }
00991 }
00992
00993 Subsystem::Map subsystems;
00994 Subsystem::Map::iterator ss;
00995 GetComponent()->DiscoveryService()->GetSubsystems(subsystems);
00996 for(ss = subsystems.begin();
00997 ss != subsystems.end();
00998 ss++)
00999 {
01000 components = ss->second->GetComponentsWithService(Management::Name);
01001 for(c = components.begin();
01002 c != components.end() && mShutdownServiceFlag == false;
01003 c++)
01004 {
01005 if(*c != GetComponentID())
01006 {
01007 query.SetDestinationID(*c);
01008 if(ss->second->GetComponent(*c)->mStatus < 0)
01009 {
01010 Send(&query);
01011 }
01012 }
01013 }
01014 }
01015
01016 Subsystem::DeleteSubsystemMap(subsystems);
01017
01018 mCheckStatusTimeMs = Time::GetUtcTimeMs();
01019 }
01020 }
01021
01022