00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00025
00026 #ifndef RemoteConnection_H
00027 #define RemoteConnection_H
00028
00029
00030 #include "H3DNetworkingUtils/Config.h"
00031 #include <H3D/Group.h>
00032 #include <H3DUtil/Threads.h>
00033 #include "H3DNetworkingUtils/RemoteField.h"
00034 #include "H3DNetworkingUtils/sockwrap.h"
00035 #include "H3DNetworkingUtils/lockwrap.h"
00036 #include "H3DNetworkingUtils/threadwrap.h"
00037 #include "H3DNetworkingUtils/PacketSequenceChecker.h"
00038 #include "H3DNetworkingUtils/Packet.h"
00039 #include <queue>
00040 #include "H3DNetworkingUtils/BufferedSField.h"
00041 #include "H3DNetworkingUtils/RemoteSync.h"
00042
00043 namespace H3D {
00044 H3D_VALUE_EXCEPTION( int, RemoteFieldIDTooLarge );
00045 }
00046
00047 namespace H3DNetworkingUtils {
00048
00077
00078 class H3D_NETWORKING_UTILS_DLL_SPEC RemoteConnection : public H3D::Group {
00079 public:
00080
00081 static H3D::H3DNodeDatabase database;
00082
00083 virtual ~RemoteConnection();
00084 virtual void initialize();
00085
00086 class H3D_NETWORKING_UTILS_DLL_SPEC MFRemoteField : public H3D::TypedMFNode< RemoteField >{
00087 public:
00088 virtual void onAdd(H3D::Node * nodeP);
00089 RemoteConnection * conP;
00090 };
00091
00092 typedef H3D::TypedSFNode<RemoteSync> SFRemoteSync;
00093
00094
00095
00101 auto_ptr<H3D::SFString > errorMessage;
00102
00109 auto_ptr<H3D::SFString > infoMessage;
00110
00119 auto_ptr<H3D::SFFloat > simulatedLatency;
00120
00121 auto_ptr<MFRemoteField > remoteFields;
00122
00132 auto_ptr<H3D::SFBool > periodicSend;
00133
00138 auto_ptr<H3D::SFFloat > periodicSendRate;
00139
00144 auto_ptr<SFRemoteSync > remoteSync;
00145
00150 auto_ptr<BufferedSField<H3D::SFBool> > isConnected;
00151
00152
00153 typedef void (* CallbackFn)(void *);
00154
00156 void setOpenCommsCallbackFn(CallbackFn fn, void * client_data) {
00157 open_comms_cb_fn = fn;
00158 open_comms_cb_data = client_data;
00159 }
00160
00162 void setCloseCommsCallbackFn(CallbackFn fn, void * client_data) {
00163 close_comms_cb_fn = fn;
00164 close_comms_cb_data = client_data;
00165 }
00166
00168 virtual void requestClose();
00169
00171 bool closeRequested() const {return close_requested;}
00172
00174 void read(char * data, int num_bytes) {read_packet.read(data, num_bytes);}
00175
00178 void write(const char * data, int num_bytes) {write_packet.write((void*)data, num_bytes);}
00179
00181 bool hasSock() const {return sockP != 0;}
00182
00186 virtual void showError(const char * msg);
00187
00190 virtual void showInfo(const char * msg);
00191
00194 virtual void showInfo(const string msg) {showInfo(msg.data());}
00195
00197 void writeFieldHeader(int fld_id, bool with_timestamp);
00198
00200 double readDouble();
00201
00203 void writeDouble(const double & val);
00204
00206 float readFloat();
00207
00209 void writeFloat(const float & val);
00210
00212 H3D::H3DFloat readH3DFloat() {return (H3D::H3DFloat)readDouble();}
00213
00215 void writeH3DFloat(const H3D::H3DFloat & val) {writeDouble(val);}
00216
00222 virtual void sendPacket();
00223
00226 void lockWriteThread() {write_lock.lock();}
00227
00229 void unlockWriteThread() {write_lock.unlock();}
00230
00231
00232
00233 protected:
00234
00235 virtual void traverseSG( H3D::TraverseInfo &ti );
00236
00237 RemoteConnection( H3D::Inst<H3D::SFString > _errorMessage = 0,
00238 H3D::Inst<H3D::SFString > _infoMessage = 0,
00239 H3D::Inst<H3D::SFFloat > _simulatedLatency = 0,
00240 H3D::Inst<MFRemoteField > _remoteFields = 0,
00241 H3D::Inst<H3D::SFBool > _periodicSend = 0,
00242 H3D::Inst<H3D::SFFloat > _periodicSendRate = 0,
00243 H3D::Inst<SFRemoteSync > _remoteSync = 0,
00244 H3D::Inst<BufferedSField<H3D::SFBool> > _isConnected = 0);
00245
00246
00247
00248
00249
00250 static void receivingLoopTH(void * client_data) {
00251 static_cast<RemoteConnection*>(client_data)->receiveLoop();
00252 }
00253
00254 virtual void receiveLoop();
00255
00256
00257 virtual bool doClosedActions() {return false;}
00258
00259
00260
00261
00262
00263
00264 virtual bool receivePacket();
00265
00266
00267
00268 virtual void sendThisPacket(Packet & packet);
00269
00270
00271 virtual void readPacket();
00272
00273
00274 virtual void readField(int field_id);
00275
00276
00277 static void sendLoopTH(void * client_data) {
00278 RemoteConnection * objP = static_cast<RemoteConnection* >(client_data);
00279 objP->sendLoop();
00280 }
00281 virtual void sendLoop();
00282
00283
00284 void setConnected(bool val) {
00285 connected = val;
00286 isConnected->setValue(val, id);
00287 }
00288
00289 virtual void setSendTimeout(InetSock * sockP, int millisecs);
00290
00291
00292 virtual void sendFields(bool first_connection);
00293
00294
00295
00296
00297
00298 virtual void doGraphicsLoopActions();
00299
00300
00301
00302
00303 void requestOpenComms() {
00304 comms_lock.lock();
00305 comms_open_requested = true;
00306 comms_lock.unlock();
00307 }
00308
00309 bool commsOpenRequested() const {
00310 comms_lock.lock();
00311 bool ret = comms_open_requested;
00312 comms_lock.unlock();
00313 return ret;
00314 }
00315
00316 virtual void close();
00317
00318
00319
00320
00321
00322 bool isShuttingDown();
00323 void setShuttingDown(bool v);
00324
00325 bool receiveLoopRunning();
00326 void setReceiveLoopRunning(bool v);
00327
00328 bool sendLoopRunning();
00329 void setSendLoopRunning(bool v);
00330
00331 InetSock * sockP;
00332 bool close_requested;
00333 Thread * receive_loop_threadP;
00334 Thread * send_loop_threadP;
00335 bool use_seq_numbers;
00336 Packet write_packet;
00337 Packet read_packet;
00338 bool initialized;
00339 double period;
00340 double last_send_time;
00341 double last_try_time;
00342 CallbackFn open_comms_cb_fn;
00343 void * open_comms_cb_data;
00344 CallbackFn close_comms_cb_fn;
00345 void * close_comms_cb_data;
00346 Mutex sock_lock;
00347 Semaphore connected_sem;
00348 InetAddr remote_end;
00349
00350 private:
00351 bool comms_open_requested;
00352 mutable Mutex comms_lock;
00353 mutable Mutex msg_lock;
00354 Mutex write_lock;
00355 PacketSequenceChecker::u_int16 seq_number;
00356 PacketSequenceChecker seq_checker;
00357 static const int MAX_PACKET_SIZE;
00358 std::queue<Packet*> sim_latency_buffer;
00359 bool sim_latency;
00360 unsigned int max_sim_latency_buf_size;
00361 bool little_endian;
00362 static const int MAX_ID;
00363 bool error_msg_waiting;
00364 bool info_msg_waiting;
00365 char * error_msg;
00366 char * info_msg;
00367 char * remote_client_addr;
00368 bool connected;
00369
00370
00371 bool shutting_down;
00372 Mutex shutdown_lock;
00373 bool receive_loop_running;
00374 Mutex receive_loop_lock;
00375 bool send_loop_running;
00376 Mutex send_loop_lock;
00377 };
00378
00379 }
00380
00381 #endif