Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

ArServerHandlerCameraCollection.cpp

Go to the documentation of this file.
00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerHandlerCameraCollection.h"
00029 
00030 
00031 #include <ArConfigArg.h>
00032 #include "ArClientArgUtils.h"
00033 
00034 AREXPORT const char *ArServerHandlerCameraCollection::GET_COLLECTION_PACKET_NAME =
00035                         "getCameraList";
00036 AREXPORT const char *ArServerHandlerCameraCollection::COLLECTION_UPDATED_PACKET_NAME = 
00037                         "cameraListUpdated";
00038 AREXPORT const char *ArServerHandlerCameraCollection::SET_PARAMS_PACKET_NAME =
00039                         "setCameraParams";
00040 AREXPORT const char *ArServerHandlerCameraCollection::PARAMS_UPDATED_PACKET_NAME = 
00041                         "cameraParamUpdated";
00042 
00043 AREXPORT const char *ArServerHandlerCameraCollection::COMMAND_GROUP =
00044                         "CameraInfo"; // ??
00045 
00046 
00047 AREXPORT ArServerHandlerCameraCollection::ArServerHandlerCameraCollection
00048                                                                                         (ArServerBase *server, 
00049                                                                                          ArCameraCollection *cameraCollection) :
00050   myServer(server),
00051   myCameraCollection(cameraCollection),
00052   myGetCameraListCB(NULL),
00053   mySetParamCB(NULL),
00054   myCollectionModifiedCB(NULL)
00055 {
00056   if (myServer != NULL)
00057   {
00058     myGetCameraListCB = new ArFunctor2C<ArServerHandlerCameraCollection,
00059                                         ArServerClient *, 
00060                                         ArNetPacket *>
00061                                   (this,
00062                                    &ArServerHandlerCameraCollection::getCameraList);
00063 
00064     myServer->addData(GET_COLLECTION_PACKET_NAME, 
00065                                   "Gets information about the robot's cameras.",
00066                                   myGetCameraListCB, 
00067                                   "none", 
00068                       "byte2: numCameras, repeating for numCameras: { string: cameraName, string: cameraType, string: displayName, string: displayType, byte2: numCommands, repeating for numCommands: {string: command, string: cameraCommandName byte4: requestInterval } byte2: numParams, repeating for numParams: {see ArConfigArg format}}",
00069                                   COMMAND_GROUP, "RETURN_SINGLE"); // ???
00070 
00071 
00072     mySetParamCB = new ArFunctor2C<ArServerHandlerCameraCollection,
00073                                         ArServerClient *, 
00074                                         ArNetPacket *>
00075                                   (this,
00076                                    &ArServerHandlerCameraCollection::setParams);
00077 
00078     myServer->addData(SET_PARAMS_PACKET_NAME, 
00079                                   "Sets the specified camera parameters.",
00080                                   mySetParamCB, 
00081                       "string: cameraName, repeating for each param: { string: paramName, <param value - see ArConfigArg format> }, empty paramName terminates list",
00082                       "string: cameraName, repeating for each modified param: { string: paramName, <param value - see ArConfigArg format> }, empty paramName terminates list",
00083                                   COMMAND_GROUP, "RETURN_SINGLE"); // ???
00084 
00085 
00086     myServer->addData(COLLECTION_UPDATED_PACKET_NAME, 
00087                                   "Single packet is sent when the camera collection has been modified.",
00088                                   NULL, 
00089                                   "none", 
00090                                   "none",
00091                       COMMAND_GROUP, "RETURN_SINGLE");
00092 
00093     myServer->addData(PARAMS_UPDATED_PACKET_NAME, 
00094                                   "Packet is sent when the camera parameters have been modified.",
00095                                   NULL, 
00096                                   "none", 
00097                       "string: cameraName, repeating for each modified param: { string: paramName, <param value - see ArConfigArg format> }, empty paramName terminates list",
00098                                   COMMAND_GROUP, "RETURN_SINGLE"); // ???
00099 
00100   } // end if server 
00101 
00102   if (myCameraCollection != NULL) {
00103 
00104     myCollectionModifiedCB = new ArFunctorC<ArServerHandlerCameraCollection>
00105                                    (this,
00106                                     &ArServerHandlerCameraCollection::handleCameraCollectionModified);
00107 
00108     myCameraCollection->addModifiedCB(myCollectionModifiedCB);
00109 
00110   } // end if camera collection
00111 
00112 } // end ctor
00113                                                           
00114 AREXPORT ArServerHandlerCameraCollection::~ArServerHandlerCameraCollection()
00115 {
00116   if ((myCameraCollection != NULL) &&
00117       (myCollectionModifiedCB != NULL)) {
00118 
00119     myCameraCollection->removeModifiedCB(myCollectionModifiedCB);
00120     delete myCollectionModifiedCB;
00121     myCollectionModifiedCB = NULL;
00122 
00123   } // end if camera collection
00124 
00125   // TODO remove and delete server CB
00126 
00127 } // end dtor
00128 
00129 
00130 AREXPORT void ArServerHandlerCameraCollection::getCameraList(ArServerClient *client, 
00131                                                                                                                                                  ArNetPacket *packet)
00132 {
00133   if (client == NULL) {
00134     return; // Something very bad has happened...
00135   }
00136 
00137   ArNetPacket sendPacket;
00138 
00139   if (myCameraCollection == NULL) {
00140     sendPacket.byte2ToBuf(0);
00141     client->sendPacketTcp(&sendPacket);
00142   }
00143 
00144   // This lack of recursive locks is troublesome... Data might
00145   // change between calls...
00146 
00147   std::list<std::string> cameraNames;
00148   myCameraCollection->getCameraNames(cameraNames);
00149   
00150   sendPacket.byte2ToBuf(cameraNames.size());
00151 
00152   for (std::list<std::string>::iterator iter = cameraNames.begin();
00153        iter != cameraNames.end();
00154        iter++) {
00155   
00156     const char *curName = iter->c_str();
00157 
00158     sendPacket.strToBuf(curName);
00159      
00160     // TODO: ArNetPacket will NOT behave correctly if the given str is NULL
00161     // Fix this somehow...
00162 
00163     sendPacket.strToBuf(myCameraCollection->getCameraType(curName));
00164     sendPacket.strToBuf(myCameraCollection->getDisplayName(curName));
00165     sendPacket.strToBuf(myCameraCollection->getDisplayType(curName));
00166 
00167     // Send commands...
00168 
00169     std::list<std::string> commands;
00170     myCameraCollection->getCameraCommands(curName, commands);
00171   
00172     sendPacket.byte2ToBuf(commands.size());
00173 
00174     for (std::list<std::string>::iterator comIter = commands.begin();
00175          comIter != commands.end();
00176          comIter++) {
00177   
00178       const char *curCommand = comIter->c_str();
00179      
00180       sendPacket.strToBuf(curCommand);
00181       sendPacket.strToBuf(myCameraCollection->getCommandName(curName, curCommand));
00182       sendPacket.byte4ToBuf(myCameraCollection->getRequestInterval(curName, curCommand));
00183 
00184     } // end for each command
00185     
00186     // Send parameters...
00187 
00188     std::list<std::string> params;
00189     myCameraCollection->getParameterNames(curName, params);
00190   
00191     sendPacket.byte2ToBuf(params.size());
00192 
00193     ArConfigArg arg;
00194     ArClientArg clientArg;
00195 
00196     bool isSuccess = true;
00197 
00198     for (std::list<std::string>::iterator paramIter = params.begin();
00199          paramIter != params.end();
00200          paramIter++) {
00201   
00202       const char *paramName = paramIter->c_str();
00203       
00204       isSuccess = myCameraCollection->getParameter(curName,
00205                                                    paramName,
00206                                                    arg);
00207       if (!isSuccess) {
00208         ArLog::log(ArLog::Normal, 
00209                    "ArServerHandlerCameraCollection::getCameraList() could not find param %s", paramName);
00210         continue;
00211       }
00212 
00213       // Add the current parameter to the packet
00214       isSuccess = clientArg.createPacket(arg, &sendPacket);
00215 
00216     } // end for each parameter
00217 
00218   } // end for each camera
00219 
00220   client->sendPacketTcp(&sendPacket);
00221 
00222 } // end method getCameraList
00223   
00224 
00225 
00226 AREXPORT void ArServerHandlerCameraCollection::setParams(ArServerClient *client, 
00227                                                          ArNetPacket *packet)
00228 {
00229   if ((packet == NULL) || (myCameraCollection == NULL)) {
00230     return;
00231   }
00232   char buffer[512];
00233 
00234   packet->bufToStr(buffer, sizeof(buffer));
00235   std::string cameraName = buffer;
00236   
00237   ArNetPacket paramUpdatedPacket;
00238   paramUpdatedPacket.strToBuf(cameraName.c_str());
00239 
00240   ArConfigArg arg;
00241   ArClientArg clientArg;
00242   bool isSuccess = true;
00243   bool isParamUpdated = false;
00244 
00245   bool isDone = false;
00246 
00247   while (!isDone) {
00248 
00249     packet->bufToStr(buffer, sizeof(buffer));
00250     std::string paramName = buffer;
00251 
00252     if (paramName.empty()) {
00253       isDone = true;
00254       break;
00255     }
00256 
00257     isSuccess = myCameraCollection->getParameter(cameraName.c_str(),
00258                                                  paramName.c_str(),
00259                                                  arg);
00260 
00261     if (!isSuccess) {
00262       ArLog::log(ArLog::Verbose, 
00263                  "ArServerHandlerCameraCollection::setParams() could not find camera %s, param %s", 
00264                  cameraName.c_str(), paramName.c_str());
00265       continue;
00266     }
00267 
00268     isSuccess = clientArg.bufToArgValue(packet, arg);
00269 
00270     if (!isSuccess) {
00271       continue;
00272     }
00273 
00274     isSuccess = myCameraCollection->setParameter(cameraName.c_str(), arg);
00275 
00276     if (!isSuccess) {
00277       continue;
00278     }
00279 
00280     paramUpdatedPacket.strToBuf(arg.getName());
00281     clientArg.argValueToBuf(arg, &paramUpdatedPacket);
00282     isParamUpdated = true;
00283 
00284   } // end for each param
00285 
00286   // TODO Send a confirmation back, or just use the broadcast packet?  (If a, then add
00287   // client to broadcast)
00288 
00289   // Add an empty string to indicate the last parameter...
00290   paramUpdatedPacket.strToBuf("");
00291 
00292   // Haven't quite decided whether to send the update packet, or a success/error notice...
00293   client->sendPacketTcp(&paramUpdatedPacket);
00294 
00295 
00296   if (isParamUpdated) {
00297     // NOT_EXCLUDING this used to not send it to the client, but no
00298     // longer has that behavior since it causes problems with the
00299     // central server
00300     myServer->broadcastPacketTcp(&paramUpdatedPacket, 
00301                                  PARAMS_UPDATED_PACKET_NAME);
00302   }
00303    
00311 } // end method setParams
00312 
00313 
00314 AREXPORT void ArServerHandlerCameraCollection::handleCameraCollectionModified()
00315 {
00316   if (myServer == NULL) {
00317     return;
00318   }
00319   ArNetPacket emptyPacket;
00320   myServer->broadcastPacketTcp(&emptyPacket, COLLECTION_UPDATED_PACKET_NAME);
00321 
00322 } // end method handleCameraCollectionModified
00323 
00324 
00325 

Generated on Tue Feb 20 10:51:50 2007 for ArNetworking by  doxygen 1.4.0