1 /* 2 * Copyright (c) 2011-2014, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <cassert> 31 #include "ConfigurableDomains.h" 32 #include "ConfigurableDomain.h" 33 #include "ConfigurableElement.h" 34 #include "BinaryStream.h" 35 #include "AutoLog.h" 36 37 #define base CBinarySerializableElement 38 39 using std::string; 40 41 CConfigurableDomains::CConfigurableDomains() 42 { 43 } 44 45 string CConfigurableDomains::getKind() const 46 { 47 return "ConfigurableDomains"; 48 } 49 50 bool CConfigurableDomains::childrenAreDynamic() const 51 { 52 return true; 53 } 54 55 // Ensure validity on whole domains from main blackboard 56 void CConfigurableDomains::validate(const CParameterBlackboard* pMainBlackboard) 57 { 58 // Delegate to domains 59 size_t uiChild; 60 size_t uiNbConfigurableDomains = getNbChildren(); 61 62 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 63 64 CConfigurableDomain* pChildConfigurableDomain = static_cast<CConfigurableDomain*>(getChild(uiChild)); 65 66 pChildConfigurableDomain->validate(pMainBlackboard); 67 } 68 } 69 70 // Configuration application if required 71 void CConfigurableDomains::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet& syncerSet, bool bForce) const 72 { 73 CAutoLog autoLog(this, "Applying configurations"); 74 75 /// Delegate to domains 76 77 // Start with domains that can be synchronized all at once (with passed syncer set) 78 size_t uiChild; 79 size_t uiNbConfigurableDomains = getNbChildren(); 80 81 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 82 83 const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); 84 85 // Apply and collect syncers when relevant 86 pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce); 87 } 88 // Synchronize those collected syncers 89 syncerSet.sync(*pParameterBlackboard, false, NULL); 90 91 // Then deal with domains that need to synchronize along apply 92 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 93 94 const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); 95 96 // Apply and synchronize when relevant 97 pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce); 98 } 99 } 100 101 // From IXmlSource 102 void CConfigurableDomains::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const 103 { 104 // Set attribute 105 xmlElement.setAttributeString("SystemClassName", getName()); 106 107 base::childrenToXml(xmlElement, serializingContext); 108 } 109 110 // Configuration/Domains handling 111 /// Domains 112 bool CConfigurableDomains::createDomain(const string& strName, string& strError) 113 { 114 // Already exists? 115 if (findChild(strName)) { 116 117 strError = "Already existing configurable domain"; 118 119 return false; 120 } 121 122 log_info("Creating configurable domain \"%s\"", strName.c_str()); 123 124 // Creation/Hierarchy 125 addChild(new CConfigurableDomain(strName)); 126 127 return true; 128 } 129 130 bool CConfigurableDomains::addDomain(CConfigurableDomain& domain, bool bOverwrite, 131 string& strError) 132 { 133 string strErrorDrop; 134 135 string strDomainName(domain.getName()); 136 CConfigurableDomain* pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop); 137 138 if (pExistingDomain) { 139 if (!bOverwrite) { 140 strError = "Can't add domain \"" + strDomainName + 141 "\" because it already exists and overwrite was not requested."; 142 return false; 143 } 144 145 deleteDomain(*pExistingDomain); 146 } 147 148 log_info("Adding configurable domain \"%s\"", strDomainName.c_str()); 149 150 addChild(&domain); 151 152 return true; 153 } 154 155 void CConfigurableDomains::deleteDomain(CConfigurableDomain& configurableDomain) 156 { 157 log_info("Deleting configurable domain \"%s\"", configurableDomain.getName().c_str() ); 158 159 removeChild(&configurableDomain); 160 161 delete &configurableDomain; 162 } 163 164 bool CConfigurableDomains::deleteDomain(const string& strName, string& strError) 165 { 166 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError); 167 168 if (pConfigurableDomain) { 169 deleteDomain(*pConfigurableDomain); 170 return true; 171 } 172 173 return false; 174 } 175 176 void CConfigurableDomains::deleteAllDomains() 177 { 178 log_info("Deleting all configurable domains"); 179 180 //remove Children 181 clean(); 182 } 183 184 bool CConfigurableDomains::renameDomain(const string& strName, const string& strNewName, string& strError) 185 { 186 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError); 187 188 if (!pConfigurableDomain) { 189 190 return false; 191 } 192 193 log_info("Renaming configurable domain \"%s\" to \"%s\"", strName.c_str(), strNewName.c_str()); 194 195 // Rename 196 return pConfigurableDomain->rename(strNewName, strError); 197 } 198 199 bool CConfigurableDomains::setSequenceAwareness(const string& strDomain, bool bSequenceAware, string& strError) 200 { 201 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 202 203 if (!pConfigurableDomain) { 204 205 return false; 206 } 207 208 pConfigurableDomain->setSequenceAwareness(bSequenceAware); 209 210 return true; 211 } 212 213 bool CConfigurableDomains::getSequenceAwareness(const string& strDomain, bool& bSequenceAware, string& strError) const 214 { 215 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 216 217 if (!pConfigurableDomain) { 218 219 return false; 220 } 221 222 bSequenceAware = pConfigurableDomain->getSequenceAwareness(); 223 224 return true; 225 } 226 227 /// Configurations 228 bool CConfigurableDomains::listConfigurations(const string& strDomain, string& strResult) const 229 { 230 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); 231 232 if (!pConfigurableDomain) { 233 234 return false; 235 } 236 // delegate 237 pConfigurableDomain->listChildren(strResult); 238 239 return true; 240 } 241 242 bool CConfigurableDomains::createConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError) 243 { 244 // Find domain 245 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 246 247 if (!pConfigurableDomain) { 248 249 return false; 250 } 251 // Delegate 252 return pConfigurableDomain->createConfiguration(strConfiguration, pMainBlackboard, strError); 253 } 254 255 bool CConfigurableDomains::deleteConfiguration(const string& strDomain, const string& strConfiguration, string& strError) 256 { 257 // Find domain 258 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 259 260 if (!pConfigurableDomain) { 261 262 return false; 263 } 264 // Delegate 265 return pConfigurableDomain->deleteConfiguration(strConfiguration, strError); 266 } 267 268 bool CConfigurableDomains::renameConfiguration(const string& strDomain, const string& strConfigurationName, const string& strNewConfigurationName, string& strError) 269 { 270 // Find domain 271 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 272 273 if (!pConfigurableDomain) { 274 275 return false; 276 } 277 // Delegate 278 return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName, strError); 279 } 280 281 bool CConfigurableDomains::listDomainElements(const string& strDomain, string& strResult) const 282 { 283 // Find domain 284 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); 285 286 if (!pConfigurableDomain) { 287 288 return false; 289 } 290 // Delegate 291 pConfigurableDomain->listAssociatedToElements(strResult); 292 293 return true; 294 } 295 296 bool CConfigurableDomains::split(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError) 297 { 298 // Find domain 299 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 300 301 if (!pConfigurableDomain) { 302 303 return false; 304 } 305 // Delegate 306 pConfigurableDomain->split(pConfigurableElement, strError); 307 308 return true; 309 } 310 311 void CConfigurableDomains::listAssociatedElements(string& strResult) const 312 { 313 strResult = "\n"; 314 315 std::set<const CConfigurableElement*> configurableElementSet; 316 317 // Get all owned configurable elements 318 gatherAllOwnedConfigurableElements(configurableElementSet); 319 320 // Fill result 321 std::set<const CConfigurableElement*>::const_iterator it; 322 323 for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) { 324 325 const CConfigurableElement* pConfigurableElement = *it; 326 327 string strAssociatedDomainList; 328 329 pConfigurableElement->listAssociatedDomains(strAssociatedDomainList, false); 330 331 strResult += pConfigurableElement->getPath() + " [" + strAssociatedDomainList + "]\n"; 332 } 333 } 334 335 void CConfigurableDomains::listConflictingElements(string& strResult) const 336 { 337 strResult = "\n"; 338 339 std::set<const CConfigurableElement*> configurableElementSet; 340 341 // Get all owned configurable elements 342 gatherAllOwnedConfigurableElements(configurableElementSet); 343 344 // Fill result 345 std::set<const CConfigurableElement*>::const_iterator it; 346 347 for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) { 348 349 const CConfigurableElement* pConfigurableElement = *it; 350 351 if (pConfigurableElement->getBelongingDomainCount() > 1) { 352 353 string strBelongingDomainList; 354 355 pConfigurableElement->listBelongingDomains(strBelongingDomainList, false); 356 357 strResult += pConfigurableElement->getPath() + " contained in multiple domains: " + strBelongingDomainList + "\n"; 358 } 359 } 360 } 361 362 void CConfigurableDomains::listDomains(string& strResult) const 363 { 364 strResult = "\n"; 365 366 // List domains 367 size_t uiChild; 368 size_t uiNbConfigurableDomains = getNbChildren(); 369 370 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 371 372 const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); 373 374 // Name 375 strResult += pChildConfigurableDomain->getName(); 376 377 // Sequence awareness 378 if (pChildConfigurableDomain->getSequenceAwareness()) { 379 380 strResult += " [sequence aware]"; 381 } 382 strResult += "\n"; 383 } 384 } 385 386 // Gather configurable elements owned by any domain 387 void CConfigurableDomains::gatherAllOwnedConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const 388 { 389 // Delegate to domains 390 size_t uiChild; 391 size_t uiNbConfigurableDomains = getNbChildren(); 392 393 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 394 395 const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); 396 397 pChildConfigurableDomain->gatherConfigurableElements(configurableElementSet); 398 } 399 } 400 401 // Config restore 402 bool CConfigurableDomains::restoreConfiguration(const string& strDomain, const string& strConfiguration, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const 403 { 404 string strError; 405 // Find domain 406 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 407 408 if (!pConfigurableDomain) { 409 410 lstrError.push_back(strError); 411 return false; 412 } 413 // Delegate 414 return pConfigurableDomain->restoreConfiguration(strConfiguration, pMainBlackboard, bAutoSync, lstrError); 415 } 416 417 // Config save 418 bool CConfigurableDomains::saveConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError) 419 { 420 // Find domain 421 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 422 423 if (!pConfigurableDomain) { 424 425 return false; 426 } 427 // Delegate 428 return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError); 429 } 430 431 bool CConfigurableDomains::setElementSequence(const string& strDomain, const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError) 432 { 433 // Find domain 434 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 435 436 if (!pConfigurableDomain) { 437 438 return false; 439 } 440 441 // Delegate to domain 442 return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence, strError); 443 } 444 445 bool CConfigurableDomains::getElementSequence(const string& strDomain, const string& strConfiguration, string& strResult) const 446 { 447 // Find domain 448 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); 449 450 if (!pConfigurableDomain) { 451 452 return false; 453 } 454 // Delegate to domain 455 return pConfigurableDomain->getElementSequence(strConfiguration, strResult); 456 } 457 458 bool CConfigurableDomains::setApplicationRule(const string& strDomain, const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError) 459 { 460 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 461 462 if (!pConfigurableDomain) { 463 464 return false; 465 } 466 467 // Delegate to domain 468 return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule, pSelectionCriteriaDefinition, strError); 469 } 470 471 bool CConfigurableDomains::clearApplicationRule(const string& strDomain, const string& strConfiguration, string& strError) 472 { 473 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 474 475 if (!pConfigurableDomain) { 476 477 return false; 478 } 479 480 // Delegate to domain 481 return pConfigurableDomain->clearApplicationRule(strConfiguration, strError); 482 } 483 484 bool CConfigurableDomains::getApplicationRule(const string& strDomain, const string& strConfiguration, string& strResult) const 485 { 486 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); 487 488 if (!pConfigurableDomain) { 489 490 return false; 491 } 492 493 // Delegate to domain 494 return pConfigurableDomain->getApplicationRule(strConfiguration, strResult); 495 } 496 497 // Last applied configurations 498 void CConfigurableDomains::listLastAppliedConfigurations(string& strResult) const 499 { 500 // Browse domains 501 size_t uiChild; 502 size_t uiNbConfigurableDomains = getNbChildren(); 503 504 for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { 505 506 const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); 507 508 strResult += pChildConfigurableDomain->getName() + ": " + pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" + pChildConfigurableDomain->getPendingConfigurationName() + "]\n"; 509 } 510 } 511 512 // Configurable element - domain association 513 bool CConfigurableDomains::addConfigurableElementToDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError) 514 { 515 // Find domain 516 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 517 518 if (!pConfigurableDomain) { 519 520 return false; 521 } 522 // Delegate 523 return pConfigurableDomain->addConfigurableElement(pConfigurableElement, pMainBlackboard, strError); 524 } 525 526 bool CConfigurableDomains::removeConfigurableElementFromDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError) 527 { 528 // Find domain 529 CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 530 531 if (!pConfigurableDomain) { 532 533 return false; 534 } 535 // Delegate 536 return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError); 537 } 538 539 CParameterBlackboard* CConfigurableDomains::findConfigurationBlackboard(const string& strDomain, 540 const string& strConfiguration, 541 const CConfigurableElement* pConfigurableElement, 542 uint32_t& uiBaseOffset, 543 bool& bIsLastApplied, 544 string& strError) const 545 { 546 log_info("Find configuration blackboard for Domain:%s, Configuration:%s, Element:%s", 547 strDomain.c_str(), strConfiguration.c_str(), pConfigurableElement->getPath().c_str()); 548 549 // Find domain 550 const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); 551 552 if (!pConfigurableDomain) { 553 554 return NULL; 555 } 556 557 // Check that element belongs to the domain 558 if (!pConfigurableElement->belongsTo(pConfigurableDomain)) { 559 560 strError = "Element \"" + pConfigurableElement->getPath() + "\" does not belong to domain \"" + strDomain + "\""; 561 562 return NULL; 563 } 564 565 // Find Configuration Blackboard and Base Offset 566 return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement, uiBaseOffset, bIsLastApplied, strError); 567 } 568 569 // Binary settings load/store 570 bool CConfigurableDomains::serializeSettings(const string& strBinarySettingsFilePath, bool bOut, uint8_t uiStructureChecksum, string& strError) 571 { 572 // Instantiate byte stream 573 CBinaryStream binarySettingsStream(strBinarySettingsFilePath, bOut, getDataSize(), uiStructureChecksum); 574 575 // Open file 576 if (!binarySettingsStream.open(strError)) { 577 578 strError = "Unable to open binary settings file " + strBinarySettingsFilePath + ": " + strError; 579 580 return false; 581 } 582 583 // Serialize 584 binarySerialize(binarySettingsStream); 585 586 // Close stream 587 binarySettingsStream.close(); 588 589 return true; 590 } 591 592 // Domain retrieval 593 CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError) 594 { 595 // Call the const equivalent 596 return const_cast<CConfigurableDomain*>( 597 static_cast<const CConfigurableDomains*>(this)->findConfigurableDomain(strDomain, strError) 598 ); 599 } 600 601 const CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError) const 602 { 603 // Find domain 604 const CConfigurableDomain* pConfigurableDomain = static_cast<const CConfigurableDomain*>(findChild(strDomain)); 605 606 if (!pConfigurableDomain) { 607 608 strError = "Configurable domain " + strDomain + " not found"; 609 610 return NULL; 611 } 612 613 return pConfigurableDomain; 614 } 615