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 #include <ctype.h>
00028 #include "ArExport.h"
00029 #include "ariaOSDef.h"
00030 #include "ArNetServer.h"
00031 #include "ArRobot.h"
00032 #include "ArLog.h"
00033 #include "ariaUtil.h"
00034 #include "ArSyncTask.h"
00035 #include "ArArgumentBuilder.h"
00036 #include "ariaInternal.h"
00037
00038 ArNetServer::ArNetServer(bool addAriaExitCB) :
00039 myTaskCB(this, &ArNetServer::runOnce),
00040 myHelpCB(this, &ArNetServer::internalHelp),
00041 myEchoCB(this, &ArNetServer::internalEcho),
00042 myQuitCB(this, &ArNetServer::internalQuit),
00043 myShutdownServerCB(this, &ArNetServer::internalShutdownServer),
00044 myAriaExitCB(this, &ArNetServer::close)
00045 {
00046 myRobot = NULL;
00047 myPort = 0;
00048 myMultipleClients = false;
00049 myOpened = false;
00050 myWantToClose = false;
00051 myLoggingDataSent = false;
00052 myLoggingDataReceived = false;
00053 mySquelchNormal = false;
00054 addCommand("help", &myHelpCB, "gives the listing of available commands");
00055 addCommand("echo", &myEchoCB, "with no args gets echo, with args sets echo");
00056 addCommand("quit", &myQuitCB, "closes this connection to the server");
00057 addCommand("shutdownServer", &myShutdownServerCB, "shuts down the server");
00058
00059 myAriaExitCB.setName("ArNetServerExit");
00060 if (addAriaExitCB)
00061 Aria::addExitCallback(&myAriaExitCB, 40);
00062 }
00063
00064 ArNetServer::~ArNetServer()
00065 {
00066 ArSyncTask *rootTask = NULL;
00067 ArSyncTask *proc = NULL;
00068
00069 if (myRobot != NULL && (rootTask = myRobot->getSyncTaskRoot()) != NULL)
00070 {
00071 proc = rootTask->findNonRecursive(&myTaskCB);
00072 if (proc != NULL)
00073 delete proc;
00074 }
00075 close();
00076 }
00077
00096 bool ArNetServer::open(ArRobot *robot, unsigned int port,
00097 const char *password, bool multipleClients)
00098 {
00099 ArSyncTask *rootTask = NULL;
00100 ArSyncTask *proc = NULL;
00101 std::string taskName;
00102
00103 if (myOpened)
00104 {
00105 ArLog::log(ArLog::Terse, "ArNetServer already inited, cannot reinit");
00106 return false;
00107 }
00108
00109 myRobot = robot;
00110 myPort = port;
00111 myPassword = password;
00112 myMultipleClients = multipleClients;
00113
00114 if (myServerSocket.open(myPort, ArSocket::TCP))
00115 {
00116 myServerSocket.setLinger(0);
00117 myServerSocket.setNonBlock();
00118 ArLog::log(ArLog::Normal, "ArNetServer opened on port %d.", myPort);
00119 myOpened = true;
00120 }
00121 else
00122 {
00123 ArLog::log(ArLog::Terse, "ArNetServer failed to open: %s",
00124 myServerSocket.getErrorStr().c_str());
00125 myOpened = false;
00126 return false;
00127 }
00128
00129
00130 if (myRobot != NULL && (rootTask = myRobot->getSyncTaskRoot()) != NULL)
00131 {
00132 proc = rootTask->findNonRecursive(&myTaskCB);
00133 if (proc == NULL)
00134 {
00135
00136 taskName = "Net Servers ";
00137 taskName += myPort;
00138 rootTask->addNewLeaf(taskName.c_str(), 60, &myTaskCB, NULL);
00139 }
00140 }
00141 return true;
00142
00143 }
00144
00150 bool ArNetServer::addCommand(const char *command,
00151 ArFunctor3<char **, int, ArSocket *> *functor,
00152 const char *help)
00153 {
00154 std::map<std::string, ArFunctor3<char **, int, ArSocket *> *, ArStrCaseCmpOp>::iterator it;
00155
00156 if ((it = myFunctorMap.find(command)) != myFunctorMap.end())
00157 {
00158 ArLog::log(ArLog::Normal, "ArNetServer::addCommand: Already a command for %s", command);
00159 return false;
00160 }
00161
00162 myFunctorMap[command] = functor;
00163 myHelpMap[command] = help;
00164 return true;
00165 }
00166
00171 bool ArNetServer::remCommand(const char *command)
00172 {
00173 if (myFunctorMap.find(command) == myFunctorMap.end())
00174 {
00175 return false;
00176 }
00177 myFunctorMap.erase(command);
00178 myHelpMap.erase(command);
00179 return true;
00180 }
00181
00182
00183 void ArNetServer::sendToAllClientsPlain(const char *str)
00184 {
00185 std::list<ArSocket *>::iterator it;
00186
00187 if (myLoggingDataSent)
00188 ArLog::log(ArLog::Terse, "ArNetServer::sendToAllClients: Sending %s", str);
00189 for (it = myConns.begin(); it != myConns.end(); ++it)
00190 {
00191 (*it)->setLogWriteStrings(false);
00192 (*it)->writeString(str);
00193 (*it)->setLogWriteStrings(myLoggingDataSent);
00194 }
00195 }
00196
00201 void ArNetServer::sendToAllClients(const char *str, ...)
00202 {
00203 char buf[2049];
00204 va_list ptr;
00205 va_start(ptr, str);
00206 vsprintf(buf, str, ptr);
00207
00208 sendToAllClientsPlain(buf);
00209
00210 va_end(ptr);
00211 }
00212
00213 bool ArNetServer::isOpen(void)
00214 {
00215 return myOpened;
00216 }
00217
00218
00223 void ArNetServer::setLoggingDataSent(bool loggingData)
00224 {
00225 myLoggingDataSent = loggingData;
00226 std::list<ArSocket *>::iterator it;
00227 for (it = myConnectingConns.begin(); it != myConnectingConns.end(); ++it)
00228 (*it)->setLogWriteStrings(loggingData);
00229 for (it = myConns.begin(); it != myConns.end(); ++it)
00230 (*it)->setLogWriteStrings(loggingData);
00231 }
00232
00237 bool ArNetServer::getLoggingDataSent(void)
00238 {
00239 return myLoggingDataSent;
00240 }
00241
00246 void ArNetServer::setLoggingDataReceived(bool loggingData)
00247 {
00248 myLoggingDataReceived = loggingData;
00249 }
00250
00255 bool ArNetServer::getLoggingDataReceived(void)
00256 {
00257 return myLoggingDataReceived;
00258 }
00259
00260
00261 void ArNetServer::runOnce(void)
00262 {
00263
00264 ArSocket acceptingSocket;
00265 ArSocket *socket;
00266 char *str;
00267 std::list<ArSocket *> removeList;
00268 std::list<ArSocket *>::iterator it;
00269 ArArgumentBuilder *args = NULL;
00270 std::string command;
00271
00272 if (!myOpened)
00273 {
00274 return;
00275 }
00276
00277 lock();
00278
00279 while (myServerSocket.accept(&acceptingSocket) && acceptingSocket.getFD() >= 0)
00280 {
00281 acceptingSocket.setNonBlock();
00282
00283 if (!myMultipleClients && (myConns.size() > 0 ||
00284 myConnectingConns.size() > 0))
00285 {
00286
00287 acceptingSocket.writeString("Conn refused.");
00288 acceptingSocket.writeString(
00289 "Only client allowed and it is already connected.");
00290 acceptingSocket.close();
00291 ArLog::log(ArLog::Terse, "ArNetServer not taking multiple clients and another client tried to connect from %s.", acceptingSocket.getIPString());
00292 }
00293 else
00294 {
00295
00296
00297 socket = new ArSocket;
00298 socket->setLogWriteStrings(myLoggingDataSent);
00299 socket->transfer(&acceptingSocket);
00300 socket->writeString("Enter password:");
00301 myConnectingConns.push_front(socket);
00302 ArLog::log(ArLog::Normal,
00303 "Client connecting from %s.",
00304 socket->getIPString());
00305 }
00306 }
00307
00308
00309
00310 for (it = myConnectingConns.begin(); it != myConnectingConns.end(); ++it)
00311 {
00312 socket = (*it);
00313
00314 if ((str = socket->readString()) != NULL)
00315 {
00316 if (str[0] == '\0')
00317 continue;
00318
00319 if (myPassword == str)
00320 {
00321 ArLog::log(ArLog::Normal,
00322 "Client from %s gave password and connected.",
00323 socket->getIPString());
00324 myConns.push_front(socket);
00325 removeList.push_front(socket);
00326 internalGreeting(socket);
00327 }
00328 else
00329 {
00330 socket->close();
00331 myDeleteList.push_front(socket);
00332 ArLog::log(ArLog::Terse,
00333 "Client from %s gave wrong password and is being disconnected.",
00334 socket->getIPString());
00335 }
00336 }
00337
00338 else
00339 {
00340 ArLog::log(ArLog::Normal,
00341 "Connection to %s lost.", socket->getIPString());
00342 socket->close();
00343 myDeleteList.push_front(socket);
00344 }
00345 }
00346
00347
00348 while ((it = removeList.begin()) != removeList.end())
00349 {
00350 socket = (*it);
00351 myConnectingConns.remove(socket);
00352 removeList.pop_front();
00353 }
00354
00355
00356
00357
00358 for (it = myConns.begin(); it != myConns.end() && myOpened; ++it)
00359 {
00360 socket = (*it);
00361
00362 while ((str = socket->readString()) != NULL)
00363 {
00364
00365 if (str[0] == '\0')
00366 break;
00367
00368
00369
00370 args = new ArArgumentBuilder;
00371 args->addPlain(str);
00372
00373 parseCommandOnSocket(args, socket);
00374 delete args;
00375 args = NULL;
00376 }
00377
00378 if (str == NULL)
00379 {
00380 ArLog::log(ArLog::Normal,
00381 "Connection to %s lost.", socket->getIPString());
00382 socket->close();
00383 myDeleteList.push_front(socket);
00384 }
00385 }
00386
00387
00388
00389 while ((it = myDeleteList.begin()) != myDeleteList.end())
00390 {
00391 socket = (*it);
00392 myConnectingConns.remove(socket);
00393 myConns.remove(socket);
00394 socket->close();
00395 delete socket;
00396 myDeleteList.pop_front();
00397 }
00398
00399 if (myWantToClose)
00400 {
00401 close();
00402 }
00403 unlock();
00404 }
00405
00406 void ArNetServer::close(void)
00407 {
00408 std::list<ArSocket *>::iterator it;
00409 ArSocket *socket;
00410
00411 if (!myOpened)
00412 return;
00413 myWantToClose = false;
00414 ArLog::log(ArLog::Normal, "ArNetServer shutting down server.");
00415 sendToAllClients("Shutting down server");
00416 for (it = myConnectingConns.begin(); it != myConnectingConns.end(); ++it)
00417 {
00418 (*it)->writeString("Shutting down server");
00419 }
00420 myOpened = false;
00421
00422 while ((it = myConnectingConns.begin())!= myConnectingConns.end())
00423 {
00424 socket = (*it);
00425 myConnectingConns.pop_front();
00426 socket->close();
00427 delete socket;
00428 }
00429 while ((it = myConns.begin()) != myConns.end())
00430 {
00431 socket = (*it);
00432 myConns.pop_front();
00433 socket->close();
00434 delete socket;
00435 }
00436 myServerSocket.close();
00437 }
00438
00439 void ArNetServer::internalGreeting(ArSocket *socket)
00440 {
00441 if (mySquelchNormal)
00442 return;
00443 socket->writeString("Welcome to the server.");
00444 socket->writeString("You can type 'help' at any time for the following help list.");
00445 internalHelp(socket);
00446 }
00447
00448 void ArNetServer::internalHelp(ArSocket *socket)
00449 {
00450 std::map<std::string, std::string, ArStrCaseCmpOp>::iterator it;
00451
00452 socket->writeString("Commands:");
00453 for (it = myHelpMap.begin(); it != myHelpMap.end(); ++it)
00454 socket->writeString("%15s%10s%s", it->first.c_str(), "",
00455 it->second.c_str());
00456 }
00457
00458 void ArNetServer::internalHelp(char **argv, int argc,
00459 ArSocket *socket)
00460 {
00461 internalHelp(socket);
00462 }
00463
00464
00465 void ArNetServer::internalEcho(char **argv, int argc,
00466 ArSocket *socket)
00467 {
00468
00469 if (argc == 1)
00470 {
00471 if (socket->getEcho())
00472 socket->writeString("Echo is on.");
00473 else
00474 socket->writeString("Echo is off.");
00475 }
00476
00477 else if (argc == 2 && strcasecmp(argv[1], "on") == 0)
00478 {
00479 socket->writeString("Echo turned on.");
00480 socket->setEcho(true);
00481 }
00482 else if (argc == 2 && strcasecmp(argv[1], "off") == 0)
00483 {
00484 socket->writeString("Echo turned off.");
00485 socket->setEcho(false);
00486 }
00487 else
00488 {
00489 socket->writeString("usage: echo <on/off>");
00490 }
00491 }
00492
00493 void ArNetServer::internalQuit(char **argv, int argc,
00494 ArSocket *socket)
00495 {
00496 socket->writeString("Closing connection");
00497
00498 myDeleteList.push_front(socket);
00499 ArLog::log(ArLog::Normal, "Client from %s quit.", socket->getIPString());
00500 }
00501
00502 void ArNetServer::internalShutdownServer(char **argv, int argc,
00503 ArSocket *socket)
00504 {
00505 sendToAllClients("Shutting down server");
00506 myWantToClose = true;
00507 if (myRobot != NULL)
00508 myRobot->stopRunning();
00509
00510 }
00511
00512 void ArNetServer::parseCommandOnSocket(ArArgumentBuilder *args,
00513 ArSocket *socket, bool allowLog)
00514 {
00515
00516 std::map<std::string, ArFunctor3<char **, int, ArSocket *> *, ArStrCaseCmpOp>::iterator fIt;
00517 char **argv;
00518 int argc;
00519
00520 if (myLoggingDataReceived && !mySquelchNormal && allowLog)
00521 ArLog::log(ArLog::Normal, "Command received from %s: %s",
00522 socket->getIPString(), args->getFullString());
00523 else if (myLoggingDataReceived && mySquelchNormal && allowLog)
00524 ArLog::log(ArLog::Normal, "%s: %s",
00525 socket->getIPString(), args->getFullString());
00526 argv = args->getArgv();
00527 argc = args->getArgc();
00528
00529 if (argc >= 1 &&
00530 (fIt = myFunctorMap.find(argv[0])) != myFunctorMap.end())
00531 {
00532 fIt->second->invoke(argv, argc, socket);
00533 }
00534
00535 else if (argc >= 1)
00536 {
00537 if (!mySquelchNormal)
00538 socket->writeString("Unknown command %s", argv[0]);
00539 }
00540 }
00541
00542 void ArNetServer::internalAddSocketToList(ArSocket *socket)
00543 {
00544 myConns.push_front(socket);
00545 }
00546
00547
00548 void ArNetServer::internalAddSocketToDeleteList(ArSocket *socket)
00549 {
00550 myDeleteList.push_front(socket);
00551 }
00552
00553 void ArNetServer::squelchNormal(void)
00554 {
00555 mySquelchNormal = true;
00556 remCommand("help");
00557 remCommand("echo");
00558 remCommand("quit");
00559 remCommand("shutdownServer");
00560
00561 }
00562
00563
00564