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 #ifndef NLCLIENTBASE_H
00027 #define NLCLIENTBASE_H
00028
00029 #include "Aria.h"
00030 #include "ArNetPacket.h"
00031 #include "ArNetPacketSenderTcp.h"
00032 #include "ArNetPacketReceiverTcp.h"
00033 #include "ArNetPacketReceiverUdp.h"
00034 #include "ArClientData.h"
00035
00060 class ArClientBase : public ArASyncTask
00061 {
00062 public:
00063
00065 enum ClientState {
00066 STATE_NO_CONNECTION,
00067 STATE_FAILED_CONNECTION,
00068 STATE_OPENED_SOCKET,
00069 STATE_EXCHANGED_INTROS,
00070 STATE_REJECTED,
00071 STATE_WAITING_LIST,
00072 STATE_CONNECTED,
00073 STATE_LOST_CONNECTION
00074 };
00075
00076 enum {
00077 CLIENT_KEY_LENGTH = 16
00078 };
00079
00081 AREXPORT ArClientBase();
00083 AREXPORT virtual ~ArClientBase();
00084
00086 AREXPORT virtual void setRobotName(const char *name);
00087
00089 AREXPORT virtual const char *getRobotName() const;
00090
00091
00093 AREXPORT bool blockingConnect(const char *host, int port, bool print = true,
00094 const char *user = NULL,
00095 const char *password = NULL);
00096
00098
00101 AREXPORT bool disconnect(void);
00102
00104
00110 AREXPORT bool startNonBlockingDisconnect();
00111
00113
00118 AREXPORT void finishNonBlockingDisconnect();
00119
00120
00122 AREXPORT bool isConnected(void) { return myState == STATE_CONNECTED;}
00123
00125 AREXPORT bool wasRejected(void) { return myState == STATE_REJECTED; }
00126
00128 AREXPORT bool addHandler(const char *name,
00129 ArFunctor1 <ArNetPacket *> *functor);
00130
00132 AREXPORT bool remHandler(const char *name, ArFunctor1<ArNetPacket *> *functor);
00133
00135 AREXPORT bool request(const char *name, long mSec,
00136 ArNetPacket *packet = NULL);
00137
00139 AREXPORT bool requestStop(const char *name);
00140
00142 AREXPORT bool requestOnce(const char *name,
00143 ArNetPacket *packet = NULL,
00144 bool quiet = false);
00145
00147 AREXPORT bool requestOnceUdp(const char *name,
00148 ArNetPacket *packet = NULL);
00149
00151 AREXPORT bool requestOnceWithString(const char *name, const char *str);
00152
00154 AREXPORT bool dataExists(const char *name);
00155
00157 AREXPORT const char *getHost(void);
00158
00159
00161 AREXPORT void setServerKey(const char *serverKey, bool print = true);
00162
00164 AREXPORT ArTime getLastPacketReceived(void);
00165
00167 AREXPORT virtual void run(void);
00168
00170 AREXPORT virtual void runAsync(void);
00171
00173 AREXPORT void logDataList(void);
00174
00176 AREXPORT void addCycleCallback(ArFunctor *functor);
00177
00179 AREXPORT void remCycleCallback(ArFunctor *functor);
00180
00182 AREXPORT bool sendPacketTcp(ArNetPacket *packet);
00184 AREXPORT bool sendPacketUdp(ArNetPacket *packet);
00185
00187 AREXPORT void setConnectTimeoutTime(int sec);
00188
00190 AREXPORT int getConnectTimeoutTime(void);
00191
00193 AREXPORT void logTracking(bool terse);
00194
00196 AREXPORT void resetTracking(void);
00197
00199 AREXPORT void addServerShutdownCB(ArFunctor *functor,
00200 ArListPos::Pos position = ArListPos::LAST);
00201
00203 AREXPORT void remServerShutdownCB(ArFunctor *functor);
00204
00206 AREXPORT void addDisconnectOnErrorCB(ArFunctor *functor,
00207 ArListPos::Pos position = ArListPos::LAST);
00208
00210 AREXPORT void remDisconnectOnErrorCB(ArFunctor *functor);
00211
00213 AREXPORT void loopOnce(void);
00214
00216 AREXPORT void processPacket(ArNetPacket *packet, bool tcp);
00217
00219 AREXPORT void processPacketUdp(ArNetPacket *packet,
00220 struct sockaddr_in *sin);
00221
00223 AREXPORT void setTcpOnlyFromServer(void);
00225 AREXPORT void setTcpOnlyToServer(void);
00226
00228 AREXPORT bool isTcpOnlyFromServer(void);
00230 AREXPORT bool isTcpOnlyToServer(void);
00232 AREXPORT void getClientKey(unsigned char key[CLIENT_KEY_LENGTH]);
00233
00235 AREXPORT const char *getName(ArNetPacket *packet, bool internalCall = false);
00237 AREXPORT const char *getName(unsigned int command, bool internalCall = false);
00238
00239 AREXPORT virtual void * runThread(void *arg);
00241 AREXPORT struct in_addr *getTcpAddr(void) { return myTcpSocket.inAddr(); }
00243 AREXPORT bool internalBlockingConnect(
00244 const char *host, int port, bool print, const char *user,
00245 const char *password, ArSocket *tcpSocket);
00247 AREXPORT ArSocket *getTcpSocket(void) { return &myTcpSocket; }
00249 AREXPORT ArSocket *getUdpSocket(void) { return &myUdpSocket; }
00251 AREXPORT const std::map<unsigned int, ArClientData *> *getDataMap(void)
00252 { return &myIntDataMap; }
00254 AREXPORT unsigned int findCommandFromName(const char *name);
00256 AREXPORT bool requestByCommand(unsigned int command, long mSec,
00257 ArNetPacket *packet = NULL);
00259 AREXPORT bool requestStopByCommand(unsigned int command);
00260
00262 AREXPORT bool requestOnceByCommand(unsigned int command,
00263 ArNetPacket *packet = NULL);
00265 AREXPORT bool requestOnceByCommandUdp(unsigned int command,
00266 ArNetPacket *packet = NULL);
00268 bool getReceivedDataList(void) { return myReceivedDataList; }
00270 bool getReceivedArgRetList(void) { return myReceivedArgRetList; }
00272 bool getReceivedGroupAndFlagsList(void) { return myReceivedGroupAndFlagsList; }
00274 int getRejected(void) { return myRejected; }
00276 const char *getRejectedString(void) { return myRejectedString; }
00277 protected:
00278
00280 std::string myRobotName;
00282 std::string myLogPrefix;
00283
00284 AREXPORT bool setupPacket(ArNetPacket *packet);
00285 ArTime myLastPacketReceived;
00286 std::list<ArFunctor *> myServerShutdownCBList;
00287 std::list<ArFunctor *> myDisconnectOnErrorCBList;
00288 std::list<ArFunctor *> myCycleCallbacks;
00289 void clear(void);
00290
00291 bool internalConnect(const char *host, int port, bool obsolete);
00292 void internalStartUdp(void);
00293 void buildList(ArNetPacket *packet);
00294 void internalSwitchState(ClientState state);
00295 bool myReceivedDataList;
00296 bool myReceivedArgRetList;
00297 bool myReceivedGroupAndFlagsList;
00298 ClientState myState;
00299 ArTime myStateStarted;
00300 bool myUdpConfirmedFrom;
00301 bool myUdpConfirmedTo;
00302
00303 bool myTcpOnlyTo;
00304
00305 bool myTcpOnlyFrom;
00306
00307 bool myQuiet;
00308 std::string myHost;
00309 std::string myUser;
00310 std::string myPassword;
00311
00312 int myTimeoutTime;
00313
00314 ArTime myStartedConnection;
00315
00316 ArMutex myDataMutex;
00317 ArMutex myClientMutex;
00318 ArMutex myMapsMutex;
00319 ArMutex myStateMutex;
00320 ArMutex myCallbackMutex;
00321 ArMutex myCycleCallbackMutex;
00322 ArMutex myPacketTrackingMutex;
00323
00324 std::map<std::string, unsigned int> myNameIntMap;
00325
00326 std::map<unsigned int, ArClientData *> myIntDataMap;
00327
00328 struct sockaddr_in myUdpSin;
00329 bool myUdpSinValid;
00330
00331 unsigned int myServerReportedUdpPort;
00332
00333 unsigned int myServerSentUdpPort;
00334 unsigned int myUdpPort;
00335 long myAuthKey;
00336 long myIntroKey;
00337 std::string myServerKey;
00338
00339 unsigned char myClientKey[16];
00340 ArNetPacketSenderTcp myTcpSender;
00341 ArNetPacketReceiverTcp myTcpReceiver;
00342 ArNetPacketReceiverUdp myUdpReceiver;
00343 ArSocket myTcpSocket;
00344 ArSocket myUdpSocket;
00345 ArFunctor2C<ArClientBase, ArNetPacket *, bool> myProcessPacketCB;
00346 ArFunctor2C<ArClientBase, ArNetPacket *, struct sockaddr_in *> myProcessPacketUdpCB;
00347
00348 int myRejected;
00349 char myRejectedString[32000];
00350
00351 ArTime myTrackingStarted;
00352 class Tracker
00353 {
00354 public:
00355 Tracker() { reset(); }
00356 virtual ~Tracker() {}
00357 void reset(void)
00358 { myPacketsTcp = 0; myBytesTcp = 0; myPacketsUdp = 0; myBytesUdp = 0; }
00359 long myPacketsTcp;
00360 long myBytesTcp;
00361 long myPacketsUdp;
00362 long myBytesUdp;
00363 };
00364 AREXPORT void trackPacketSent(ArNetPacket *packet, bool tcp);
00365 AREXPORT void trackPacketReceived(ArNetPacket *packet, bool tcp);
00366 std::map<unsigned int, Tracker *> myTrackingSentMap;
00367 std::map<unsigned int, Tracker *> myTrackingReceivedMap;
00368
00369 };
00370
00371 #endif // NLCLIENTBASE_H