Go to the documentation of this file.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/control/accesscontrol.h"
00041 #include "jaus/core/events/event.h"
00042 #include "jaus/core/component.h"
00043
00044 #include <iostream>
00045 #include <tinyxml/tinyxml.h>
00046
00047 using namespace JAUS;
00048
00049 const std::string AccessControl::Name = "urn:jaus:jss:core:AccessControl";
00050
00056 AccessControl::AccessControl() : Events::Child(Service::ID(AccessControl::Name),
00057 Service::ID(Events::Name))
00058 {
00059 mControllableFlag = true;
00060 mAuthorityCode = 0;
00061 mControllerAuthorityCode = 0;
00062 mTimeoutPeriod = 5;
00063 mTimeoutThreshold = 25;
00064 }
00065
00066
00072 AccessControl::~AccessControl()
00073 {
00074 }
00075
00076
00082 bool AccessControl::AcceptCommandMessage(const Message* commandMessage) const
00083 {
00084 if(commandMessage->IsCommand())
00085 {
00086
00087
00088
00089 Mutex::ScopedLock lock(&mControlMutex);
00090 if(mControllerID.IsValid() && mControllerID != commandMessage->GetSourceID())
00091 {
00092
00093 if(commandMessage->GetMessageCode() != REQUEST_CONTROL)
00094 {
00095 return false;
00096 }
00097 }
00098 }
00099 return true;
00100 }
00101
00102
00113 bool AccessControl::LoadSettings(const std::string& filename)
00114 {
00115 TiXmlDocument xml;
00116
00117 if(xml.LoadFile(filename.c_str()) == false)
00118 {
00119 return false;
00120 }
00121 TiXmlHandle doc(&xml);
00122 TiXmlNode* node;
00123 node = doc.FirstChild("JAUS").FirstChild("AccessControl").FirstChild("Controllable").FirstChild().ToNode();
00124 if(node && node->Value())
00125 {
00126 mControllableFlag = atoi(node->Value()) > 0 ? true : false;
00127 }
00128 TiXmlElement* element = NULL;
00129 element = doc.FirstChild("JAUS").FirstChild("AccessControl").FirstChild("TimeoutSeconds").ToElement();
00130 if(element && element->FirstChild() && element->FirstChild()->Value())
00131 {
00132 mTimeoutPeriod = (Byte)atoi(element->FirstChild()->Value());
00133
00134 if(element->Attribute("threshold"))
00135 {
00136 mTimeoutThreshold = atof(element->Attribute("threshold"));
00137 if(mTimeoutThreshold < 0.5 || mTimeoutThreshold > 50.0)
00138 {
00139 mTimeoutThreshold = 5;
00140 }
00141 }
00142 }
00143 node = doc.FirstChild("JAUS").FirstChild("AccessControl").FirstChild("AuthorityLevel").FirstChild().ToNode();
00144 if(node && node->Value())
00145 {
00146 mAuthorityCode = (Byte)atoi(node->Value());
00147 }
00148
00149 return true;
00150 }
00151
00152
00158 void AccessControl::Shutdown()
00159 {
00160
00161 ReleaseComponentControl(Address());
00162
00163 if(mControllerID.IsValid())
00164 {
00165 RejectControl release(mControllerID, GetComponentID());
00166 release.SetResponseCode(RejectControl::ControlReleased);
00167 Send(&release);
00168 }
00169 }
00170
00171
00186 bool AccessControl::RequestComponentControl(const Address& id,
00187 const bool reacquire,
00188 const unsigned int waitTimeMs)
00189 {
00190 RequestControl request(id, GetComponentID());
00191 request.SetAuthorityCode(mAuthorityCode);
00192 Message::List responses;
00193 ConfirmControl confirm;
00194 RejectControl reject;
00195 responses.push_back(&confirm);
00196 responses.push_back(&reject);
00197
00198 if(Send(&request, responses, waitTimeMs) && responses.size() == 1)
00199 {
00200
00201 if(responses.front()->GetMessageCode() == CONFIRM_CONTROL)
00202 {
00203 if(confirm.GetResponseCode() == ConfirmControl::ControlAccepted)
00204 {
00205
00206
00207
00208 mControlMutex.Lock();
00209 mControlledComponents.insert(id);
00210 mMaintainFlags[id] = reacquire;
00211 mControlFlags[id] = true;
00212
00213 mControlCheckTimes[id].SetCurrentTime();
00214
00215 mControlConfirmTimes[id].SetCurrentTime();
00216
00217 mTimeoutPeriods[id] = mTimeoutPeriod;
00218
00219
00220 mControlMutex.Unlock();
00221
00222
00223 QueryTimeout query(id, GetComponentID());
00224 Send(&query);
00225
00226
00227
00228 Service::Map children = GetChildServices();
00229 Service::Map::iterator child;
00230 for(child = children.begin();
00231 child != children.end();
00232 child++)
00233 {
00234 Child* controlChild = dynamic_cast<Child *>(child->second);
00235 if(controlChild)
00236 {
00237 controlChild->ProcessAcquisitionOfControl(id);
00238 }
00239 }
00240
00241 Mutex::ScopedLock cbLock(&mCallbacksMutex);
00242 Callback::Set::iterator cb;
00243 for(cb = mCallbacks.begin();
00244 cb != mCallbacks.end();
00245 cb++)
00246 {
00247 (*cb)->ProcessAcquisitionfControl(id);
00248 }
00249
00250 return true;
00251 }
00252 }
00253 else
00254 {
00255 return false;
00256 }
00257 }
00258 return false;
00259 }
00260
00274 bool AccessControl::ReleaseComponentControl(const Address& id,
00275 const unsigned int waitTimeMs)
00276 {
00277 bool result = false;
00278
00279 if(id.IsValid() == false)
00280 {
00281 result = true;
00282 Address::Set controlled;
00283 mControlMutex.Lock();
00284 controlled = mControlledComponents;
00285 mControlMutex.Unlock();
00286 Address::Set::iterator component;
00287 for(component = controlled.begin();
00288 component != controlled.end();
00289 component++)
00290 {
00291 result &= ReleaseComponentControl(*component, waitTimeMs);
00292 }
00293 }
00294 else
00295 {
00296 std::map<Address, bool>::iterator flag;
00297 mControlMutex.Lock();
00298 flag = mControlFlags.find(id);
00299 if(flag != mControlFlags.end())
00300 {
00301
00302
00303
00304 if(flag->second == false)
00305 {
00306 result = true;
00307
00308 EraseComponentControlInfo(id);
00309 }
00310 }
00311 else
00312 {
00313
00314
00315 result = true;
00316 EraseComponentControlInfo(id);
00317 }
00318 mControlMutex.Unlock();
00319
00320 if(!result)
00321 {
00322
00323
00324 mControlMutex.Lock();
00325 mToReleaseControl.insert(id);
00326 mControlMutex.Unlock();
00327
00328 ReleaseControl release(id, GetComponentID());
00329
00330 RejectControl reject;
00331
00332 if(Send(&release, &reject, waitTimeMs))
00333 {
00334 if(reject.GetResponseCode() == RejectControl::ControlReleased)
00335 {
00336 result = true;
00337 Mutex::ScopedLock lock(&mControlMutex);
00338 EraseComponentControlInfo(id);
00339 }
00340 }
00341
00342
00343 mControlMutex.Lock();
00344 mToReleaseControl.erase(mToReleaseControl.find(id));
00345 mControlMutex.Unlock();
00346 }
00347 }
00348 return result;
00349 }
00350
00351
00361 bool AccessControl::GenerateEvent(const Events::Subscription& info) const
00362 {
00363 if(info.mpQueryMessage->GetMessageCode() == QUERY_AUTHORITY)
00364 {
00365 ReportAuthority report;
00366 report.SetAuthorityCode(mAuthorityCode);
00367 SendEvent(info, &report);
00368 return true;
00369 }
00370 else if(info.mpQueryMessage->GetMessageCode() == QUERY_CONTROL)
00371 {
00372 ReportControl report;
00373 report.SetAuthorityCode(mControllerAuthorityCode);
00374 report.SetControllingComponent(mControllerID);
00375 SendEvent(info, &report);
00376 return true;
00377 }
00378
00379 return false;
00380 }
00381
00382
00398 bool AccessControl::IsEventSupported(const Events::Type type,
00399 const double requestedPeriodicRate,
00400 const Message* queryMessage,
00401 double& confirmedPeriodicRate,
00402 std::string& errorMessage) const
00403 {
00404 bool result = false;
00405 switch(queryMessage->GetMessageCode())
00406 {
00407 case QUERY_AUTHORITY:
00408 case QUERY_CONTROL:
00409 confirmedPeriodicRate = requestedPeriodicRate;
00410 result = true;
00411 break;
00412 default:
00413 result = false;
00414 break;
00415 };
00416 return result;
00417 }
00418
00419
00428 void AccessControl::SetControllable(const bool on)
00429 {
00430 mControllableFlag = on;
00431 }
00432
00433
00445 void AccessControl::Receive(const Message* message)
00446 {
00447 if(AcceptCommandMessage(message) == false)
00448 {
00449 return;
00450 }
00451
00452 if(mControllerID == message->GetSourceID())
00453 {
00454 mControllerUpdateTime.SetCurrentTime();
00455 }
00456
00457 switch(message->GetMessageCode())
00458 {
00459 case CONFIRM_CONTROL:
00460 {
00461 const ConfirmControl* command = dynamic_cast<const ConfirmControl*>(message);
00462 if(command == NULL)
00463 return;
00464
00465 if(command->GetResponseCode() == ConfirmControl::ControlAccepted)
00466 {
00467 bool firstTime = true;
00468
00469
00470 mControlMutex.Lock();
00471
00472
00473
00474 Address::Set::iterator controlledComponent = mControlledComponents.find(message->GetSourceID());
00475 if(controlledComponent != mControlledComponents.end())
00476 {
00477
00478
00479 std::map<Address, bool>::iterator flag = mControlFlags.find(message->GetSourceID());
00480 if(flag->second == true)
00481 {
00482
00483
00484 firstTime = false;
00485 }
00486 }
00487
00488 mControlledComponents.insert(message->GetSourceID());
00489 mControlConfirmTimes[message->GetSourceID()].SetCurrentTime();
00490 mControlFlags[message->GetSourceID()] = true;
00491
00492
00493 mControlMutex.Unlock();
00494
00495 if(mDebugMessagesFlag)
00496 {
00497 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00498 if(firstTime)
00499 {
00500 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00501 << "] - Acquired Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00502 }
00503 else
00504 {
00505 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00506 << "] - Maintained Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00507 }
00508 }
00509
00510
00511 if(firstTime)
00512 {
00513 Service::Map children = GetChildServices();
00514 Service::Map::iterator child;
00515 for(child = children.begin();
00516 child != children.end();
00517 child++)
00518 {
00519 Child* controlChild = dynamic_cast<Child *>(child->second);
00520 if(controlChild)
00521 {
00522 controlChild->ProcessAcquisitionOfControl(message->GetSourceID());
00523 }
00524 }
00525
00526 Mutex::ScopedLock cbLock(&mCallbacksMutex);
00527 Callback::Set::iterator cb;
00528 for(cb = mCallbacks.begin();
00529 cb != mCallbacks.end();
00530 cb++)
00531 {
00532 (*cb)->ProcessAcquisitionfControl(message->GetSourceID());
00533 }
00534 }
00535 }
00536 else
00537 {
00538 Address::Set::iterator component;
00539
00540
00541 mControlMutex.Lock();
00542
00543 component = mControlledComponents.find(message->GetSourceID());
00544 if(component != mControlledComponents.end())
00545 {
00546 std::map<Address, bool>::iterator flag;
00547 flag = mMaintainFlags.find(message->GetSourceID());
00548 if(flag != mMaintainFlags.end())
00549 {
00550
00551
00552
00553
00554 if(flag->second == false || command->GetMessageCode() == ConfirmControl::InsufficientAuthority)
00555 {
00556 EraseComponentControlInfo(message->GetSourceID());
00557 }
00558 else
00559 {
00560 mControlFlags[message->GetSourceID()] = false;
00561 }
00562 }
00563
00564 else
00565 {
00566 EraseComponentControlInfo(message->GetSourceID());
00567 }
00568 }
00569
00570 mControlMutex.Unlock();
00571 }
00572 }
00573 break;
00574 case QUERY_AUTHORITY:
00575 {
00576 if(mShutdownServiceFlag)
00577 {
00578 break;
00579 }
00580 Mutex::ScopedLock lock(&mControlMutex);
00581 ReportAuthority report(message->GetSourceID(), GetComponentID());
00582 report.SetAuthorityCode(mAuthorityCode);
00583 Send(&report);
00584 }
00585 break;
00586 case QUERY_CONTROL:
00587 {
00588 Mutex::ScopedLock lock(&mControlMutex);
00589 ReportControl report(message->GetSourceID(), GetComponentID());
00590 report.SetAuthorityCode(mControllerAuthorityCode);
00591 report.SetControllingComponent(mControllerID);
00592 Send(&report);
00593 }
00594 break;
00595 case QUERY_TIMEOUT:
00596 {
00597 Mutex::ScopedLock lock(&mControlMutex);
00598 ReportTimeout report(message->GetSourceID(), GetComponentID());
00599 report.SetTimeoutSeconds(mTimeoutPeriod);
00600 Send(&report);
00601 }
00602 break;
00603 case REJECT_CONTROL:
00604 {
00605 const RejectControl* command = dynamic_cast<const RejectControl*>(message);
00606 if(mShutdownServiceFlag || command == NULL)
00607 return;
00608
00609 Mutex::ScopedLock lock(&mControlMutex);
00610
00611 Address::Set::iterator component;
00612 component = mControlledComponents.find(message->GetSourceID());
00613 if(component != mControlledComponents.end())
00614 {
00615 std::map<Address, bool>::iterator flag;
00616 flag = mMaintainFlags.find(message->GetSourceID());
00617 if(flag != mMaintainFlags.end())
00618 {
00619
00620
00621
00622 if(flag->second == false)
00623 {
00624 mMaintainFlags.erase(flag);
00625 mControlFlags.erase(mControlFlags.find(message->GetSourceID()));
00626 mControlConfirmTimes.erase(mControlConfirmTimes.find(message->GetSourceID()));
00627 mControlledComponents.erase(component);
00628 }
00629 else
00630 {
00631 mControlFlags[message->GetSourceID()] = false;
00632 }
00633
00634 Mutex::ScopedLock clock(&mCallbacksMutex);
00635 Callback::Set::iterator cb;
00636 for(cb = mCallbacks.begin();
00637 cb != mCallbacks.end();
00638 cb++)
00639 {
00640 (*cb)->ProcessLossOfControl(message->GetSourceID());
00641 }
00642 }
00643
00644 else
00645 {
00646 if(mControlFlags.find(*component) != mControlFlags.end())
00647 {
00648 mControlFlags.erase(*component);
00649 }
00650 mControlledComponents.erase(*component);
00651 }
00652 }
00653 if(mDebugMessagesFlag)
00654 {
00655 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00656 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00657 << "] - Lost Control of " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00658 }
00659 }
00660 break;
00661 case RELEASE_CONTROL:
00662 {
00663 const ReleaseControl* command = dynamic_cast<const ReleaseControl*>(message);
00664 if(mShutdownServiceFlag || command == NULL)
00665 return;
00666
00667 Mutex::ScopedLock lock(&mControlMutex);
00668 if(command->GetSourceID() == mControllerID)
00669 {
00670 RejectControl response(mControllerID, GetComponentID());
00671
00672 bool controlReleased = true;
00673 Service::Map children = GetChildServices();
00674 Service::Map::iterator child;
00675 for(child = children.begin();
00676 child != children.end();
00677 child++)
00678 {
00679 Child* controlChild = dynamic_cast<Child *>(child->second);
00680 if(controlChild)
00681 {
00682 if(controlChild->ReleaseControl())
00683 {
00684 controlReleased;
00685 }
00686 }
00687 }
00688 if(controlReleased)
00689 {
00690 response.SetResponseCode(RejectControl::ControlReleased);
00691 Send(&response);
00692
00693 mControllerID = Address();
00694 mControllerAuthorityCode = 0;
00695 mControllerUpdateTime.Clear();
00696 mControllerCheckTime.Clear();
00697
00698 if(mDebugMessagesFlag)
00699 {
00700 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00701 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00702 << "] - Control Released from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00703 }
00704
00705
00706 Mutex::ScopedLock clock(&mCallbacksMutex);
00707 Callback::Set::iterator cb;
00708 for(cb = mCallbacks.begin();
00709 cb != mCallbacks.end();
00710 cb++)
00711 {
00712 (*cb)->ProcessReleaseOfControl(message->GetSourceID());
00713 }
00714 SignalEvent(REPORT_CONTROL);
00715 }
00716 else
00717 {
00718 response.SetResponseCode(RejectControl::NotAvailable);
00719 Send(&response);
00720 }
00721 }
00722 }
00723 break;
00724 case REPORT_AUTHORITY:
00725 {
00726 const JAUS::ReportAuthority* report = dynamic_cast<const JAUS::ReportAuthority*>(message);
00727 if(report)
00728 {
00729
00730 try
00731 {
00732 Discovery* discovery = GetComponent()->DiscoveryService();
00733 if(discovery)
00734 {
00735 discovery->GetSubsystem(report->GetSourceID().mSubsystem)->GetComponent(report->GetSourceID())->mAuthorityLevel = (int)report->GetAuthorityCode();
00736 if( discovery->GetVehicle(report->GetSourceID().mSubsystem).IsValid() &&
00737 discovery->GetVehicle(report->GetSourceID().mSubsystem)->mAuthority < (int)report->GetAuthorityCode())
00738 {
00739 discovery->GetVehicle(report->GetSourceID().mSubsystem)->mAuthority = (int)report->GetAuthorityCode();
00740 }
00741 }
00742 }
00743 catch(Exception& e)
00744 {
00745 e.Print();
00746 }
00747 }
00748 }
00749 break;
00750 case REPORT_CONTROL:
00751
00752 break;
00753 case REPORT_TIMEOUT:
00754 {
00755 const ReportTimeout* report = dynamic_cast<const ReportTimeout*>(message);
00756 if(report == NULL)
00757 return;
00758
00759 Mutex::ScopedLock lock(&mControlMutex);
00760 mTimeoutPeriods[message->GetSourceID()] = report->GetTimeoutSeconds();
00761 if(mTimeoutPeriods[message->GetSourceID()] == 0)
00762 {
00763
00764 mTimeoutPeriods[message->GetSourceID()] = 2;
00765 }
00766 }
00767 break;
00768 case REQUEST_CONTROL:
00769 {
00770 const RequestControl* command = dynamic_cast<const RequestControl*>(message);
00771 if(mShutdownServiceFlag || command == NULL)
00772 return;
00773
00774 ConfirmControl response(message->GetSourceID(), GetComponentID());
00775
00776 Mutex::ScopedLock lock(&mControlMutex);
00777
00778
00779
00780 if(mControllableFlag &&
00781 command->GetAuthorityCode() >= mAuthorityCode &&
00782 (mControllerID == command->GetSourceID() || mControllerID.IsValid() == false || command->GetAuthorityCode() > mControllerAuthorityCode))
00783 {
00784 bool controlAccepted = true;
00785 Service::Map children = GetChildServices();
00786 Service::Map::iterator child;
00787 for(child = children.begin();
00788 child != children.end();
00789 child++)
00790 {
00791 Child* controlChild = dynamic_cast<Child *>(child->second);
00792 if(controlChild)
00793 {
00794 controlAccepted = controlChild->RequestControl();
00795 if(controlAccepted)
00796 {
00797 break;
00798 }
00799 }
00800 }
00801
00802
00803
00804 if(controlAccepted == false)
00805 {
00806 response.SetResponseCode(ConfirmControl::NotAvailable);
00807 }
00808 else
00809 {
00810 response.SetResponseCode(ConfirmControl::ControlAccepted);
00811 if(mControllerID != command->GetSourceID() && mControllerID.IsValid())
00812 {
00813
00814 RejectControl reject(mControllerID, GetComponentID());
00815 reject.SetResponseCode(RejectControl::ControlReleased);
00816 Send(&reject);
00817 }
00818 mControllerID = message->GetSourceID();
00819 mControllerAuthorityCode = command->GetAuthorityCode();
00820 mControllerCheckTime.SetCurrentTime();
00821 mControllerUpdateTime.SetCurrentTime();
00822 if(mDebugMessagesFlag)
00823 {
00824 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00825 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00826 << "] - Control Granted to " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00827 }
00828 }
00829 }
00830 else
00831 {
00832 if(mControllableFlag == false)
00833 {
00834 response.SetResponseCode(ConfirmControl::NotAvailable);
00835 }
00836 else
00837 {
00838 response.SetResponseCode(ConfirmControl::InsufficientAuthority);
00839 }
00840 if(mDebugMessagesFlag)
00841 {
00842 Mutex::ScopedLock plock(&mDebugMessagesMutex);
00843 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
00844 << "] - Control Rejected from " << message->GetSourceID().ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
00845 }
00846 }
00847 Send(&response);
00848 }
00849 break;
00850 case SET_AUTHORITY:
00851 {
00852 const SetAuthority* command = dynamic_cast<const SetAuthority*>(message);
00853 if(command == NULL)
00854 return;
00855
00856 Mutex::ScopedLock lock(&mControlMutex);
00857 mAuthorityCode = command->GetAuthorityCode();
00858 SignalEvent(REPORT_AUTHORITY);
00859
00860
00861 try
00862 {
00863 Discovery* discovery = GetComponent()->DiscoveryService();
00864 if(discovery)
00865 {
00866 discovery->GetSubsystem(command->GetDestinationID().mSubsystem)->GetComponent(command->GetDestinationID())->mAuthorityLevel = (int)command->GetAuthorityCode();
00867 if(discovery->GetVehicle(command->GetDestinationID().mSubsystem)->mAuthority < (int)command->GetAuthorityCode())
00868 {
00869 discovery->GetVehicle(command->GetDestinationID().mSubsystem)->mAuthority = (int)command->GetAuthorityCode();
00870 }
00871 }
00872 }
00873 catch(Exception& e)
00874 {
00875 e.Print();
00876 }
00877 }
00878 break;
00879 default:
00880 break;
00881 };
00882 }
00883
00884
00896 Message* AccessControl::CreateMessage(const UShort messageCode) const
00897 {
00898 Message* message;
00899 switch(messageCode)
00900 {
00901 case CONFIRM_CONTROL:
00902 message = new ConfirmControl();
00903 break;
00904 case QUERY_AUTHORITY:
00905 message = new QueryAuthority();
00906 break;
00907 case QUERY_CONTROL:
00908 message = new QueryControl();
00909 break;
00910 case QUERY_TIMEOUT:
00911 message = new QueryTimeout();
00912 break;
00913 case REJECT_CONTROL:
00914 message = new RejectControl();
00915 break;
00916 case RELEASE_CONTROL:
00917 message = new ReleaseControl();
00918 break;
00919 case REPORT_AUTHORITY:
00920 message = new ReportAuthority();
00921 break;
00922 case REPORT_CONTROL:
00923 message = new ReportControl();
00924 break;
00925 case REPORT_TIMEOUT:
00926 message = new ReportTimeout();
00927 break;
00928 case REQUEST_CONTROL:
00929 message = new RequestControl();
00930 break;
00931 case SET_AUTHORITY:
00932 message = new SetAuthority();
00933 break;
00934 default:
00935 message = NULL;
00936 break;
00937 };
00938 return message;
00939 }
00940
00941
00951 void AccessControl::SetAuthorityCode(const Byte authorityCode)
00952 {
00953 Mutex::ScopedLock lock(&mControlMutex);
00954 mAuthorityCode = authorityCode;
00955 SignalEvent(REPORT_AUTHORITY);
00956 }
00957
00958
00970 bool AccessControl::HaveControl(const Address& id) const
00971 {
00972 Mutex::ScopedLock lock(&mControlMutex);
00973
00974 if(id.IsValid() == false && mControlledComponents.size() != 0)
00975 {
00976 return true;
00977 }
00978
00979 Address::Set::const_iterator c;
00980 c = mControlledComponents.find(id);
00981 if(c != mControlledComponents.end())
00982 {
00983 return mControlFlags.find(*c)->second;
00984 }
00985 return false;
00986 }
00987
00988
00994 bool AccessControl::IsControlled() const
00995 {
00996 Mutex::ScopedLock lock(&mControlMutex);
00997 return mControllerID.IsValid();
00998 }
00999
01000
01006 void AccessControl::SetControllerID(const Address& id)
01007 {
01008 if(id.IsValid() && !id.IsBroadcast())
01009 {
01010 Mutex::ScopedLock lock(&mControlMutex);
01011 mControllerID = id;
01012 }
01013 }
01014
01015
01021 Address AccessControl::GetControllerID() const
01022 {
01023 Mutex::ScopedLock lock(&mControlMutex);
01024 return mControllerID;
01025 }
01026
01027
01033 Byte AccessControl::GetControllerAuthorityCode() const
01034 {
01035 Mutex::ScopedLock lock(&mControlMutex);
01036 return mControllerAuthorityCode;
01037 }
01038
01039
01045 Address::List AccessControl::GetControlledComponents() const
01046 {
01047 Mutex::ScopedLock lock(&mControlMutex);
01048 Address::List result;
01049 std::map<Address, bool>::const_iterator flags;
01050 for(flags = mControlFlags.begin();
01051 flags != mControlFlags.end();
01052 flags++)
01053 {
01054 if(flags->second)
01055 {
01056 result.push_back(flags->first);
01057 }
01058 }
01059 return result;
01060 }
01061
01062
01072 void AccessControl::CheckServiceStatus(const unsigned int timeSinceLastCheckMs)
01073 {
01074 RequestControl request;
01075
01076 mControlMutex.Lock();
01077
01078 request.SetSourceID(GetComponentID());
01079 request.SetAuthorityCode(mAuthorityCode);
01080
01081 Address::Set::iterator component;
01082 Time currentTime;
01083 currentTime.SetCurrentTime();
01084
01085 for(component = mControlledComponents.begin();
01086 component != mControlledComponents.end();
01087 component++)
01088 {
01089
01090 if(mToReleaseControl.find(*component) != mToReleaseControl.end())
01091 {
01092 continue;
01093 }
01094
01095
01096 double thresh = mTimeoutPeriods[*component]*mTimeoutThreshold/100.0;
01097 double checkTimeDiff = currentTime.ToSeconds() - mControlCheckTimes[*component].ToSeconds();
01098 double timeThresh = (mTimeoutPeriods[*component] - thresh);
01099 bool checkConfirmation = true;
01100 if(mTimeoutPeriods[*component] > 0 && checkTimeDiff >= thresh)
01101 {
01102 request.SetDestinationID(*component);
01103 if(Send(&request))
01104 {
01105
01106 mControlCheckTimes[*component].SetCurrentTime();
01107 checkConfirmation = false;
01108 }
01109 }
01110 double confirmTimeDiff = currentTime.ToSeconds() - mControlConfirmTimes[*component].ToSeconds();
01111 timeThresh = (mTimeoutPeriods[*component] + thresh);
01112
01113 if(checkConfirmation && confirmTimeDiff > timeThresh)
01114 {
01115 mControlFlags[*component] = false;
01116
01117 Mutex::ScopedLock clock(&mCallbacksMutex);
01118 Callback::Set::iterator cb;
01119 for(cb = mCallbacks.begin();
01120 cb != mCallbacks.end();
01121 cb++)
01122 {
01123 (*cb)->ProcessLossOfControl(*component);
01124 }
01125 }
01126 }
01127
01128 mControlMutex.Unlock();
01129
01130 mControlMutex.Lock();
01131
01132 Address controller = mControllerID;
01133 bool timeout = false;
01134 currentTime.SetCurrentTime();
01135 double timeSinceRequest = currentTime - mControllerCheckTime;
01136 if(mTimeoutPeriod > 0 &&
01137 controller.IsValid() &&
01138 timeSinceRequest >= (double)mTimeoutPeriod + mTimeoutPeriod*mTimeoutThreshold/100.0)
01139 {
01140 timeout = true;
01141
01142 RejectControl reject(controller, GetComponentID());
01143 reject.SetResponseCode(RejectControl::ControlReleased);
01144 Send(&reject);
01145 if(mDebugMessagesFlag)
01146 {
01147 Mutex::ScopedLock plock(&mDebugMessagesMutex);
01148 std::cout << "[" << GetServiceID().ToString() << "-" << mComponentID.ToString()
01149 << "] - Control Time Out From " << controller.ToString() << " at " << Time::GetUtcTime().ToString() << "\n";
01150 }
01151
01152 mControllerID.Clear();
01153 mControllerAuthorityCode = 0;
01154 mControllerCheckTime.Clear();
01155 mControllerUpdateTime.Clear();
01156 }
01157
01158 mControlMutex.Unlock();
01159
01160 if(timeout)
01161 {
01162 Callback::Set::iterator cb;
01163 for(cb = mCallbacks.begin();
01164 cb != mCallbacks.end();
01165 cb++)
01166 {
01167 (*cb)->ProcessReleaseOfControl(controller);
01168 }
01169 Service::Map children = GetChildServices();
01170 Service::Map::iterator child;
01171 for(child = children.begin();
01172 child != children.end();
01173 child++)
01174 {
01175 Child* controlChild = dynamic_cast<Child *>(child->second);
01176 if(controlChild)
01177 {
01178 controlChild->ReleaseControl();
01179 }
01180 }
01181 SignalEvent(REPORT_CONTROL);
01182 }
01183 }
01184
01185
01197 void AccessControl::SetTimeoutPeriod(const Byte timeSeconds)
01198 {
01199 Mutex::ScopedLock lock(&mControlMutex);
01200 mTimeoutPeriod = timeSeconds;
01201 }
01202
01208 Byte AccessControl::GetTimeoutPeriod() const
01209 {
01210 Mutex::ScopedLock lock(&mControlMutex);
01211 return mTimeoutPeriod;
01212 }
01213
01214
01226 void AccessControl::RegisterCallback(Callback* callback, const bool add)
01227 {
01228 Mutex::ScopedLock lock(&mCallbacksMutex);
01229 if(add)
01230 {
01231 mCallbacks.insert(callback);
01232 }
01233 else
01234 {
01235 Callback::Set::iterator cb;
01236 cb = mCallbacks.find(callback);
01237 if(cb != mCallbacks.end())
01238 {
01239 mCallbacks.erase(cb);
01240 }
01241 }
01242 }
01243
01244
01250 void AccessControl::PrintStatus() const
01251 {
01252
01253
01254 std::cout << "[" << GetServiceID().ToString() << "] - " << GetComponentID().ToString() << "\n";
01255
01256 Address controller;
01257 Byte authority;
01258 Address::Set controlled;
01259 std::map<Address, bool> flags;
01260
01261 mControlMutex.Lock();
01262 controller = mControllerID;
01263 authority = mControllerAuthorityCode;
01264 controlled = mControlledComponents;
01265 flags = mControlFlags;
01266 mControlMutex.Unlock();
01267
01268 if(controller.IsValid())
01269 {
01270 std::cout << "Controlled by: "
01271 << controller.ToString()
01272 << " Authority Code: "
01273 << (int)authority << std::endl;
01274 }
01275 if(controlled.size() > 0)
01276 {
01277 Address::Set::const_iterator c;
01278 std::cout << "In Control of the Following:\n";
01279 for(c = controlled.begin();
01280 c != controlled.end();
01281 c++)
01282 {
01283 if(flags.find(*c)->second)
01284 {
01285 std::cout << " - " << c->ToString() << std::endl;
01286 }
01287 }
01288 }
01289 }
01290
01291
01297 void AccessControl::EraseComponentControlInfo(const Address& id)
01298 {
01299 std::map<Address, Byte>::iterator tp;
01300 std::map<Address, Time>::iterator ct;
01301 std::map<Address, bool>::iterator flag;
01302 Address::Set::iterator c;
01303
01304 tp = mTimeoutPeriods.find(id);
01305 if(tp != mTimeoutPeriods.end())
01306 {
01307 mTimeoutPeriods.erase(tp);
01308 }
01309 ct = mControlCheckTimes.find(id);
01310 if(ct != mControlCheckTimes.end())
01311 {
01312 mControlCheckTimes.erase(ct);
01313 }
01314 ct = mControlConfirmTimes.find(id);
01315 if(ct != mControlConfirmTimes.end())
01316 {
01317 mControlConfirmTimes.erase(ct);
01318 }
01319
01320 flag = mMaintainFlags.find(id);
01321 if(flag != mMaintainFlags.end())
01322 {
01323 mMaintainFlags.erase(flag);
01324 }
01325 flag = mControlFlags.find(id);
01326 if(flag != mControlFlags.end())
01327 {
01328 mControlFlags.erase(flag);
01329 }
01330
01331 c = mControlledComponents.find(id);
01332 if(c != mControlledComponents.end())
01333 {
01334 mControlledComponents.erase(c);
01335 }
01336 }
01337