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 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArClientHandlerConfig.h"
00029 #include "ArClientArgUtils.h"
00030
00031 #define ARDEBUG_CLIENTHANDLERCONFIG
00032
00033 #if (defined(_DEBUG) && defined(ARDEBUG_CLIENTHANDLERCONFIG))
00034 #define IFDEBUG(code) {code;}
00035 #else
00036 #define IFDEBUG(code)
00037 #endif
00038
00043 AREXPORT ArClientHandlerConfig::ArClientHandlerConfig(ArClientBase *client,
00044 bool ignoreBounds,
00045 const char *robotName) :
00046 myRobotName((robotName != NULL) ? robotName : ""),
00047 myLogPrefix(),
00048
00049 myConfig(NULL, false, ignoreBounds),
00050 myDefaultConfig(NULL),
00051
00052 myHandleGetConfigBySectionsCB(this, &ArClientHandlerConfig::handleGetConfigBySections),
00053 myHandleGetConfigCB(this, &ArClientHandlerConfig::handleGetConfig),
00054 myHandleSetConfigCB(this, &ArClientHandlerConfig::handleSetConfig),
00055 myHandleGetConfigDefaultsCB(this,
00056 &ArClientHandlerConfig::handleGetConfigDefaults),
00057 myHandleGetConfigSectionFlagsCB(this,
00058 &ArClientHandlerConfig::handleGetConfigSectionFlags)
00059 {
00060 myClient = client;
00061 myHaveGottenConfig = false;
00062 myHaveRequestedDefaults = false;
00063 myHaveGottenDefaults = false;
00064 myHaveRequestedDefaultCopy = false;
00065
00066 if (!myRobotName.empty()) {
00067 myLogPrefix = myRobotName + ": ";
00068 }
00069
00070 myConfig.setConfigName("Server", myRobotName.c_str());
00071
00072 }
00073
00074 AREXPORT ArClientHandlerConfig::~ArClientHandlerConfig()
00075 {
00076
00077 }
00078
00083 AREXPORT void ArClientHandlerConfig::requestConfigFromServer(void)
00084 {
00085 myDataMutex.lock();
00086
00087 char *getConfigPacketName = "getConfigBySections";
00088 ArFunctor1C<ArClientHandlerConfig, ArNetPacket *> *getConfigCB = &myHandleGetConfigBySectionsCB;
00089
00090 if (!myClient->dataExists(getConfigPacketName)) {
00091 getConfigPacketName = "getConfig";
00092 getConfigCB = &myHandleGetConfigCB;
00093 }
00094
00095 myConfig.clearSections();
00096
00097 myClient->remHandler(getConfigPacketName, getConfigCB);
00098 myClient->addHandler(getConfigPacketName, getConfigCB);
00099 myClient->remHandler("setConfig", &myHandleSetConfigCB);
00100 myClient->addHandler("setConfig", &myHandleSetConfigCB);
00101
00102 if (myClient->dataExists("getConfigDefaults")) {
00103 myClient->remHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB);
00104 myClient->addHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB);
00105 }
00106 if (myClient->dataExists("getConfigSectionFlags"))
00107 {
00108 myClient->remHandler("getConfigSectionFlags",
00109 &myHandleGetConfigSectionFlagsCB);
00110 myClient->addHandler("getConfigSectionFlags",
00111 &myHandleGetConfigSectionFlagsCB);
00112 myClient->requestOnce("getConfigSectionFlags");
00113 }
00114 myClient->requestOnce(getConfigPacketName);
00115 myHaveGottenConfig = false;
00116
00117
00118 myDataMutex.unlock();
00119 }
00120
00121 AREXPORT void ArClientHandlerConfig::handleGetConfigBySections(ArNetPacket *packet)
00122 {
00123 handleGetConfigData(packet, true);
00124 }
00125
00126 AREXPORT void ArClientHandlerConfig::handleGetConfig(ArNetPacket *packet)
00127 {
00128 handleGetConfigData(packet, false);
00129 }
00130
00131 AREXPORT void ArClientHandlerConfig::handleGetConfigData(ArNetPacket *packet,
00132 bool isMultiplePackets)
00133 {
00134 char name[32000];
00135 char comment[32000];
00136 char type;
00137 std::string section;
00138
00139
00140
00141 ArClientArg clientArg(isMultiplePackets);
00142 bool isEmptyPacket = true;
00143
00144 myDataMutex.lock();
00145
00146 while (packet->getDataReadLength() < packet->getDataLength())
00147 {
00148 isEmptyPacket = false;
00149
00150 type = packet->bufToByte();
00151
00152 if (type == 'S')
00153 {
00154 packet->bufToStr(name, sizeof(name));
00155 packet->bufToStr(comment, sizeof(name));
00156
00157
00158 ArLog::log(ArLog::Verbose, "%sReceiving config section %s...",
00159 myLogPrefix.c_str(), name);
00160
00161 section = name;
00162 myConfig.setSectionComment(name, comment);
00163 }
00164 else if (type == 'P')
00165 {
00166 ArConfigArg configArg;
00167
00168 bool isSuccess = clientArg.createArg(packet,
00169 configArg);
00170 if (isSuccess) {
00171
00172 myConfig.addParam(configArg,
00173 section.c_str(),
00174 configArg.getConfigPriority(),
00175 configArg.getDisplayHint());
00176 }
00177 else
00178 {
00179 ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown param type");
00180 }
00181 }
00182 else
00183 {
00184 ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown type");
00185 }
00186
00187 }
00188
00189 if (!isMultiplePackets || isEmptyPacket) {
00190
00191 ArLog::log(ArLog::Normal, "%sGot config from server.", myLogPrefix.c_str());
00192 IFDEBUG(myConfig.log());
00193
00194 myHaveGottenConfig = true;
00195 }
00196
00197 myDataMutex.unlock();
00198
00199
00200
00201 if (myHaveGottenConfig) {
00202
00203 myCallbackMutex.lock();
00204
00205 for (std::list<ArFunctor *>::iterator it = myGotConfigCBList.begin();
00206 it != myGotConfigCBList.end();
00207 it++) {
00208 (*it)->invoke();
00209 }
00210 myCallbackMutex.unlock();
00211
00212 }
00213
00214 }
00215
00216 AREXPORT void ArClientHandlerConfig::handleGetConfigSectionFlags(
00217 ArNetPacket *packet)
00218 {
00219 int numSections = packet->bufToByte4();
00220
00221 int i;
00222
00223 char section[32000];
00224 char flags[32000];
00225
00226 myDataMutex.lock();
00227 for (i = 0; i < numSections; i++)
00228 {
00229 packet->bufToStr(section, sizeof(section));
00230 packet->bufToStr(flags, sizeof(flags));
00231 myConfig.addSectionFlags(section, flags);
00232 }
00233 myDataMutex.unlock();
00234 }
00235
00236 AREXPORT void ArClientHandlerConfig::saveConfigToServer(void)
00237 {
00238 saveConfigToServer(&myConfig);
00239 }
00240
00241 AREXPORT void ArClientHandlerConfig::saveConfigToServer(
00242 ArConfig *config,
00243 const std::set<std::string, ArStrCaseCmpOp> *ignoreTheseSections)
00244 {
00245
00246 ArClientArg clientArg;
00247
00248 ArNetPacket sending;
00249 ArLog::log(ArLog::Normal, "%sSaving config to server", myLogPrefix.c_str());
00250
00251 myDataMutex.lock();
00252 std::list<ArConfigSection *> *sections = config->getSections();
00253 for (std::list<ArConfigSection *>::iterator sIt = sections->begin();
00254 sIt != sections->end();
00255 sIt++)
00256 {
00257 ArConfigSection *section = (*sIt);
00258
00259
00260 if (ignoreTheseSections != NULL &&
00261 (ignoreTheseSections->find(section->getName()) !=
00262 ignoreTheseSections->end()))
00263 {
00264 ArLog::log(ArLog::Verbose, "Not sending section %s",
00265 section->getName());
00266 continue;
00267 }
00268 sending.strToBuf("Section");
00269 sending.strToBuf(section->getName());
00270 std::list<ArConfigArg> *params = section->getParams();
00271
00272 for (std::list<ArConfigArg>::iterator pIt = params->begin();
00273 pIt != params->end();
00274 pIt++)
00275 {
00276 ArConfigArg ¶m = (*pIt);
00277
00278 if (!clientArg.isSendableParamType(param)) {
00279 continue;
00280 }
00281
00282 sending.strToBuf(param.getName());
00283
00284 clientArg.argTextToBuf(param, &sending);
00285
00286 }
00287 }
00288
00289 myDataMutex.unlock();
00290 myClient->requestOnce("setConfig", &sending);
00291 }
00292
00293 AREXPORT void ArClientHandlerConfig::handleSetConfig(ArNetPacket *packet)
00294 {
00295
00296 char buffer[1024];
00297 packet->bufToStr(buffer, sizeof(buffer));
00298
00299 myCallbackMutex.lock();
00300 if (buffer[0] == '\0')
00301 {
00302 ArLog::log(ArLog::Normal, "%sSaved config to server successfully", myLogPrefix.c_str());
00303 std::list<ArFunctor *>::iterator it;
00304 for (it = mySaveConfigSucceededCBList.begin();
00305 it != mySaveConfigSucceededCBList.end();
00306 it++)
00307 (*it)->invoke();
00308 }
00309 else
00310 {
00311 ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), buffer);
00312 std::list<ArFunctor1<const char *> *>::iterator it;
00313 for (it = mySaveConfigFailedCBList.begin();
00314 it != mySaveConfigFailedCBList.end();
00315 it++)
00316 (*it)->invoke(buffer);
00317 }
00318 myCallbackMutex.unlock();
00319 }
00320
00321 AREXPORT void ArClientHandlerConfig::reloadConfigOnServer(void)
00322 {
00323 myClient->requestOnce("reloadConfig");
00324 }
00325
00330 AREXPORT ArConfig *ArClientHandlerConfig::getConfig(void)
00331 {
00332 return &myConfig;
00333 }
00334
00342 AREXPORT ArConfig *ArClientHandlerConfig::getDefaultConfig(void)
00343 {
00344 return myDefaultConfig;
00345 }
00346
00351 AREXPORT ArConfig ArClientHandlerConfig::getConfigCopy(void)
00352 {
00353 ArConfig copy;
00354 myDataMutex.lock();
00355 copy = myConfig;
00356 myDataMutex.unlock();
00357 return copy;
00358 }
00359
00360 AREXPORT int ArClientHandlerConfig::lock(void)
00361 {
00362 return myDataMutex.lock();
00363 }
00364
00365 AREXPORT int ArClientHandlerConfig::tryLock(void)
00366 {
00367 return myDataMutex.tryLock();
00368 }
00369
00370 AREXPORT int ArClientHandlerConfig::unlock(void)
00371 {
00372 return myDataMutex.unlock();
00373 }
00374
00375 AREXPORT bool ArClientHandlerConfig::haveGottenConfig(void)
00376 {
00377 bool ret;
00378 myDataMutex.lock();
00379 ret = myHaveGottenConfig;
00380 myDataMutex.unlock();
00381 return ret;
00382 }
00383
00384 AREXPORT void ArClientHandlerConfig::addGotConfigCB(ArFunctor *functor,
00385 ArListPos::Pos position)
00386 {
00387 myCallbackMutex.lock();
00388 if (position == ArListPos::FIRST)
00389 myGotConfigCBList.push_front(functor);
00390 else if (position == ArListPos::LAST)
00391 myGotConfigCBList.push_back(functor);
00392 else
00393 ArLog::log(ArLog::Terse,
00394 "ArClientHandlerConfig::addGotConfigCB: Invalid position.");
00395 myCallbackMutex.unlock();
00396 }
00397
00398 AREXPORT void ArClientHandlerConfig::remGotConfigCB(ArFunctor *functor)
00399 {
00400 myCallbackMutex.lock();
00401 myGotConfigCBList.remove(functor);
00402 myCallbackMutex.unlock();
00403 }
00404
00405 AREXPORT void ArClientHandlerConfig::addSaveConfigSucceededCB(
00406 ArFunctor *functor, ArListPos::Pos position)
00407 {
00408 myCallbackMutex.lock();
00409 if (position == ArListPos::FIRST)
00410 mySaveConfigSucceededCBList.push_front(functor);
00411 else if (position == ArListPos::LAST)
00412 mySaveConfigSucceededCBList.push_back(functor);
00413 else
00414 ArLog::log(ArLog::Terse,
00415 "ArClientHandlerConfig::addSaveConfigSucceededCB: Invalid position.");
00416 myCallbackMutex.unlock();
00417 }
00418
00419 AREXPORT void ArClientHandlerConfig::remSaveConfigSucceededCB(ArFunctor *functor)
00420 {
00421 myCallbackMutex.lock();
00422 mySaveConfigSucceededCBList.remove(functor);
00423 myCallbackMutex.unlock();
00424 }
00425
00426
00427 AREXPORT void ArClientHandlerConfig::addSaveConfigFailedCB(
00428 ArFunctor1<const char *> *functor, ArListPos::Pos position)
00429 {
00430 myCallbackMutex.lock();
00431 if (position == ArListPos::FIRST)
00432 mySaveConfigFailedCBList.push_front(functor);
00433 else if (position == ArListPos::LAST)
00434 mySaveConfigFailedCBList.push_back(functor);
00435 else
00436 ArLog::log(ArLog::Terse,
00437 "ArClientHandlerConfig::addSaveConfigFailedCB: Invalid position.");
00438 myCallbackMutex.unlock();
00439 }
00440
00441 AREXPORT void ArClientHandlerConfig::remSaveConfigFailedCB(ArFunctor1<const char *> *functor)
00442 {
00443 myCallbackMutex.lock();
00444 mySaveConfigFailedCBList.remove(functor);
00445 myCallbackMutex.unlock();
00446 }
00447
00448
00449 AREXPORT void ArClientHandlerConfig::addGotConfigDefaultsCB(
00450 ArFunctor *functor, ArListPos::Pos position)
00451 {
00452 myCallbackMutex.lock();
00453 if (position == ArListPos::FIRST)
00454 myGotConfigDefaultsCBList.push_front(functor);
00455 else if (position == ArListPos::LAST)
00456 myGotConfigDefaultsCBList.push_back(functor);
00457 else
00458 ArLog::log(ArLog::Terse,
00459 "ArClientHandlerConfig::addGotConfigDefaultsCB: Invalid position.");
00460 myCallbackMutex.unlock();
00461 }
00462
00463 AREXPORT void ArClientHandlerConfig::remGotConfigDefaultsCB(ArFunctor *functor)
00464 {
00465 myCallbackMutex.lock();
00466 myGotConfigDefaultsCBList.remove(functor);
00467 myCallbackMutex.unlock();
00468 }
00469
00470 AREXPORT bool ArClientHandlerConfig::haveRequestedDefaults(void)
00471 {
00472 bool ret;
00473 myDataMutex.lock();
00474 ret = myHaveRequestedDefaults || myHaveRequestedDefaultCopy;
00475 myDataMutex.unlock();
00476 return ret;
00477 }
00478
00479 AREXPORT bool ArClientHandlerConfig::haveGottenDefaults(void)
00480 {
00481 bool ret;
00482 myDataMutex.lock();
00483 ret = myHaveGottenDefaults;
00484 myDataMutex.unlock();
00485 return ret;
00486 }
00487
00488 AREXPORT bool ArClientHandlerConfig::canRequestDefaults(void)
00489 {
00490 return myClient->dataExists("getConfigDefaults");
00491 }
00492
00493 AREXPORT bool ArClientHandlerConfig::requestConfigDefaults(void)
00494 {
00495 if (haveRequestedDefaults())
00496 {
00497 ArLog::log(ArLog::Normal,
00498 "%sRequestConfigDefaults: Cannot request defaults as there are already some being requested",
00499 myLogPrefix.c_str());
00500 return false;
00501 }
00502 if (!canRequestDefaults())
00503 {
00504 ArLog::log(ArLog::Normal,
00505 "%sRequestConfigDefaults: Defaults requested but not available",
00506 myLogPrefix.c_str());
00507 return false;
00508 }
00509
00510 ArLog::log(ArLog::Normal,
00511 "%sRequesting config reset to default",
00512 myLogPrefix.c_str());
00513
00514 myDataMutex.lock();
00515 myHaveRequestedDefaults = true;
00516 myHaveGottenDefaults = false;
00517 myHaveRequestedDefaultCopy = false;
00518 myDataMutex.unlock();
00519
00520 myClient->requestOnce("getConfigDefaults");
00521 return true;
00522 }
00523
00524 AREXPORT bool ArClientHandlerConfig::requestDefaultConfigFromServer(void)
00525 {
00526 if (haveRequestedDefaults())
00527 {
00528 ArLog::log(ArLog::Normal,
00529 "%sRequestConfigDefaults: Cannot request defaults as there are already some being requested",
00530 myLogPrefix.c_str());
00531 return false;
00532 }
00533 if (!canRequestDefaults())
00534 {
00535 ArLog::log(ArLog::Normal,
00536 "%sRequestConfigDefaults: Defaults requested but not available",
00537 myLogPrefix.c_str());
00538 return false;
00539 }
00540
00541
00542 myDataMutex.lock();
00543
00544 myHaveRequestedDefaults = false;
00545 myHaveGottenDefaults = false;
00546 myHaveRequestedDefaultCopy = true;
00547 myDataMutex.unlock();
00548
00549 myClient->requestOnce("getConfigDefaults");
00550 return true;
00551 }
00552
00553 AREXPORT bool ArClientHandlerConfig::requestSectionDefaults(
00554 const char *section)
00555 {
00556 if (haveRequestedDefaults())
00557 {
00558 ArLog::log(ArLog::Normal,
00559 "RequestSectionDefaults: Cannot request defaults as there are already some being requested");
00560 return false;
00561 }
00562 if (!canRequestDefaults())
00563 {
00564 ArLog::log(ArLog::Normal,
00565 "%sRequestSectionDefaults: Defaults requested but not available",
00566 myLogPrefix.c_str());
00567 return false;
00568 }
00569 myDataMutex.lock();
00570 if (myConfig.findSection(section) == NULL)
00571 {
00572 ArLog::log(ArLog::Normal,
00573 "%sRequestSectionDefaults: Section '%s' requested but doesn't exist",
00574 myLogPrefix.c_str(), section);
00575 myDataMutex.unlock();
00576 return false;
00577 }
00578
00579 ArLog::log(ArLog::Normal,
00580 "%sRequesting config section %s reset to default",
00581 myLogPrefix.c_str(),
00582 section);
00583
00584 myHaveRequestedDefaults = true;
00585 myHaveGottenDefaults = false;
00586 myHaveRequestedDefaultCopy = false;
00587 myDataMutex.unlock();
00588 myClient->requestOnceWithString("getConfigDefaults", section);
00589 return true;
00590 }
00591
00592
00593
00594 AREXPORT void ArClientHandlerConfig::handleGetConfigDefaults(
00595 ArNetPacket *packet)
00596 {
00597 ArLog::log(ArLog::Normal, "%sreceived default config %s",
00598 myLogPrefix.c_str(),
00599 ((myHaveRequestedDefaultCopy) ? "(copy)" : "(reset)"));
00600
00601 char param[1024];
00602 char argument[1024];
00603 char errorBuffer[1024];
00604
00605 myDataMutex.lock();
00606
00607 ArConfig *config = NULL;
00608
00609
00610
00611
00612 bool isClearUnsetValues = false;
00613
00614 if (myHaveRequestedDefaults) {
00615
00616 config = &myConfig;
00617 }
00618 else if (myHaveRequestedDefaultCopy) {
00619
00620
00621
00622
00623
00624 isClearUnsetValues = true;
00625
00626
00627
00628
00629
00630 if (myDefaultConfig == NULL) {
00631 myDefaultConfig = new ArConfig(myConfig);
00632 myDefaultConfig->setConfigName("Default", myRobotName.c_str());
00633 }
00634 else {
00635 *myDefaultConfig = myConfig;
00636 }
00637
00638
00639 config = myDefaultConfig;
00640 }
00641
00642
00643 else
00644 {
00645 myDataMutex.unlock();
00646 return;
00647 }
00648
00649 if (config == NULL) {
00650 ArLog::log(ArLog::Normal,
00651 "ArClientHandlerConfig error determining config to populate with default values");
00652 myDataMutex.unlock();
00653 return;
00654 }
00655
00656 ArArgumentBuilder *builder = NULL;
00657 ArLog::log(ArLog::Normal, "Got defaults");
00658 errorBuffer[0] = '\0';
00659
00660
00661 if (isClearUnsetValues) {
00662 config->clearAllValueSet();
00663 }
00664
00665 while (packet->getDataReadLength() < packet->getDataLength())
00666 {
00667 packet->bufToStr(param, sizeof(param));
00668 packet->bufToStr(argument, sizeof(argument));
00669
00670
00671 builder = new ArArgumentBuilder;
00672 builder->setExtraString(param);
00673 builder->add(argument);
00674
00675 if ((strcasecmp(param, "Section") == 0 &&
00676 !config->parseSection(builder, errorBuffer, sizeof(errorBuffer))) ||
00677 (strcasecmp(param, "Section") != 0 &&
00678 !config->parseArgument(builder, errorBuffer, sizeof(errorBuffer))))
00679 {
00680 ArLog::log(ArLog::Terse, "%sArClientHandlerConfig::handleGetConfigDefaults: Hideous problem getting defaults, couldn't parse '%s %s'",
00681 myLogPrefix.c_str(), param, argument);
00682 }
00683 else {
00684 IFDEBUG(if (strlen(param) > 0) {
00685 ArLog::log(ArLog::Normal, "%sArClientHandlerConfig::handleGetConfigDefaults: added default '%s %s'",
00686 myLogPrefix.c_str(), param, argument); } );
00687 }
00688 delete builder;
00689 builder = NULL;
00690 }
00691 myHaveRequestedDefaults = false;
00692 myHaveRequestedDefaultCopy = false;
00693 myHaveGottenDefaults = true;
00694
00695 if (isClearUnsetValues) {
00696 config->removeAllUnsetValues();
00697 }
00698
00699 IFDEBUG(config->log());
00700
00701 myDataMutex.unlock();
00702
00703 myCallbackMutex.lock();
00704 std::list<ArFunctor *>::iterator it;
00705 for (it = myGotConfigDefaultsCBList.begin();
00706 it != myGotConfigDefaultsCBList.end();
00707 it++)
00708 (*it)->invoke();
00709 myCallbackMutex.unlock();
00710 }
00711