42 #include "DTrackSDK.hpp" 43 #include "DTrackParse.hpp" 49 #if ! defined( _MSC_VER ) 50 #define strcpy_s( a, b, c ) strcpy( a, c ) // map 'strcpy_s' if not Visual Studio 62 std::vector< std::string > args;
66 size_t ind1 = connection.find_first_of(
':', ind );
67 if ( ind1 == std::string::npos )
69 args.push_back( connection.substr( ind ) );
74 args.push_back( connection.substr( ind, ind1 - ind ) );
77 if ( ind >= connection.length() )
79 args.push_back( std::string() );
84 if ( ( args.size() == 0 ) || ( args.size() > 3 ) )
return;
87 std::istringstream portstream;
90 if ( args.size() == 1 )
92 portstream.str( args[ 0 ] );
97 portstream.str( args[ 1 ] );
99 if ( args.size() == 3 )
101 if ( args[ 2 ].compare(
"fw" ) != 0 )
return;
109 if ( portstream.fail() || ( ! portstream.eof() ) )
return;
113 init(
"", 0, port, SYS_DTRACK_UNKNOWN );
119 init(
"", 0, port, SYS_DTRACK_UNKNOWN );
121 d_udpSenderIp = ip_name2ip( host.c_str() );
123 sendStatefulFirewallPacket();
127 init( host, 0, port, SYS_DTRACK_2 );
159 if ( server_port == DTRACK2_PORT_COMMAND )
165 init( server_host, server_port, data_port,
SYS_DTRACK );
174 RemoteSystemType remote_type,
int data_bufsize,
int data_timeout_us,
int srv_timeout_us)
177 init( server_host, server_port, data_port, remote_type );
188 void DTrackSDK::init(
const std::string& server_host,
unsigned short server_port,
unsigned short data_port,
189 RemoteSystemType remote_type )
191 setlocale( LC_NUMERIC,
"C" );
193 rsType = remote_type;
202 setLastDTrackError();
211 d_udpSenderPort = DTRACK2_PORT_UDPSENDER;
216 unsigned int remoteIp = 0;
217 if ( ! server_host.empty() )
218 remoteIp = ip_name2ip( server_host.c_str() );
220 bool isMulticast =
false;
221 if ( ( remoteIp & 0xf0000000 ) == 0xe0000000 )
238 if ( ( remoteIp != 0 ) && ( ! isMulticast ) )
240 d_remoteIp = remoteIp;
241 d_udpSenderIp = remoteIp;
245 d_remoteDT1Port = server_port;
256 d_remoteDT1Port = server_port;
264 sendStatefulFirewallPacket();
268 d_message_origin =
"";
269 d_message_status =
"";
270 d_message_framenr = 0;
271 d_message_errorid = 0;
312 if ( d_udp == NULL )
return false;
332 if ( d_tcp == NULL )
return false;
346 bool isOk =
getParam(
"system",
"access", par );
347 if ( ( ! isOk ) || ( par.compare(
"full" ) != 0 ) )
return false;
369 d_udptimeout_us = DEFAULT_UDP_TIMEOUT;
373 d_udptimeout_us = timeout;
386 d_tcptimeout_us = DEFAULT_TCP_TIMEOUT;
390 d_tcptimeout_us = timeout;
404 newBufSize = DEFAULT_UDP_BUFSIZE;
408 newBufSize = bufSize;
411 if ( newBufSize != d_udpbufsize )
415 d_udpbufsize = newBufSize;
416 d_udpbuf = (
char *)malloc( d_udpbufsize );
418 return ( d_udpbuf != NULL );
427 if ( ! senderHost.empty() )
428 d_udpSenderIp = ip_name2ip( senderHost.c_str() );
430 d_udpSenderPort = senderPort;
432 sendStatefulFirewallPacket();
434 return ( d_udpSenderIp != 0 );
459 len = d_udp->
receive( d_udpbuf, d_udpbufsize - 1, d_udptimeout_us );
480 s = string_nextline( d_udpbuf, s, d_udpbufsize );
481 }
while ( s != NULL );
504 if ( data.length() == 0 )
510 sBuf = (
char *)malloc( data.length() + 1 );
511 if ( sBuf == NULL )
return false;
513 strcpy_s( sBuf, data.length() + 1, data.c_str() );
524 s = string_nextline( sBuf, s, static_cast< int >( data.length() ) );
525 }
while( s != NULL );
539 if ( d_udpbuf == NULL )
540 return std::string(
"" );
542 return std::string( d_udpbuf );
551 return lastDataError;
560 return lastServerError;
569 return lastDTrackError;
578 return lastDTrackErrorString;
585 void DTrackSDK::setLastDTrackError(
int newError,
const std::string& newErrorString)
587 lastDTrackError = newError;
588 lastDTrackErrorString = newErrorString;
605 sendStatefulFirewallPacket();
644 if (0 == strncmp(command.c_str(),
"dtrack ", 7)) {
645 std::string c = command.substr(7);
647 if (0 == strncmp(c.c_str(),
"10 3",4)) {
651 if ( (0 == strncmp(c.c_str(),
"10 0",4))
652 || (0 == strncmp(c.c_str(),
"10 1",4)))
661 if ( ( d_remoteIp == 0 ) || ( d_remoteDT1Port == 0 ) )
664 err = d_udp->
send( (
void* )command.c_str(), ( int )command.length() + 1, d_remoteIp, d_remoteDT1Port, d_udptimeout_us );
670 if (strcmp(command.c_str(),
"dtrack 10 3") == 0) {
692 setLastDTrackError();
708 if ( d_tcp->
send( command.c_str(),
static_cast< int >( command.length() ) + 1, d_tcptimeout_us ) != 0 )
740 if (0 == strcmp(ans,
"dtrack2 ok"))
744 if (0 == strncmp(ans,
"dtrack2 err ", 12)) {
749 s = string_get_i( (
char *)s, &i );
752 setLastDTrackError(-1100,
"SDK error -1100");
759 s = string_get_quoted_text( (
char *)s, lastDTrackErrorString );
762 setLastDTrackError(-1100,
"SDK error -1100");
782 bool DTrackSDK::sendStatefulFirewallPacket()
789 if ( d_udpSenderIp == 0 )
return false;
791 const char* txt =
"fw4dtsdkc";
793 err = d_udp->
send( (
void* )txt, (
int )strlen( txt ) + 1, d_udpSenderIp, d_udpSenderPort, d_udptimeout_us );
809 return setParam(category +
" " + name +
" " + value);
828 return getParam(category +
" " + name, value);
842 if ( res.compare( 0, 12,
"dtrack2 set " ) != 0 )
848 size_t pos = string_cmp_parameter( res, 12, parameter );
849 if ( pos == std::string::npos )
856 value = res.substr( pos );
876 if (0 != strncmp(res.c_str(),
"dtrack2 msg ", 12))
880 d_message_origin = d_message_msg = d_message_status =
"";
881 d_message_framenr = d_message_errorid = 0;
884 const char* s = res.c_str() + 12;
886 s = string_get_word( (
char *)s, d_message_origin );
891 s = string_get_word( (
char *)s, d_message_status );
897 s = string_get_ui( (
char *)s, &ui );
901 d_message_framenr = ui;
904 s = string_get_ui( (
char *)s, &ui );
908 d_message_errorid = ui;
911 s = string_get_quoted_text( (
char *)s, d_message_msg );
924 return d_message_framenr;
933 return d_message_errorid;
942 return d_message_origin;
951 return d_message_status;
960 return d_message_msg;
969 setLastDTrackError();
971 if ( strength > 1.0 || strength < 0.0 )
977 std::ostringstream os;
978 os <<
"tfb 1 [" << handId <<
" " << fingerId <<
" 1.0 " << strength <<
"]";
980 return sendFeedbackCommand( os.str() );
989 setLastDTrackError();
991 std::ostringstream os;
992 os <<
"tfb " << strength.size() <<
" ";
994 for (
size_t i = 0; i < strength.size(); i++ )
996 if ( strength[ i ] > 1.0 || strength[ i ] < 0.0 )
1002 os <<
"[" << handId <<
" " << i <<
" 1.0 " << strength[ i ] <<
"]";
1005 return sendFeedbackCommand( os.str() );
1014 setLastDTrackError();
1016 std::vector< double > strength( numFinger, 0.0 );
1027 setLastDTrackError();
1029 std::ostringstream os;
1031 os <<
"[" << flystickId <<
" " << ( int )durationMs <<
" " << (
int )frequencyHz <<
" 0 0][]";
1033 return sendFeedbackCommand( os.str() );
1042 setLastDTrackError();
1044 std::ostringstream os;
1046 os <<
"[" << flystickId <<
" 0 0 " << vibrationPattern <<
" 0][]";
1048 return sendFeedbackCommand( os.str() );
1055 bool DTrackSDK::sendFeedbackCommand(
const std::string& command )
1062 unsigned int ip = d_remoteIp;
1071 err = d_udp->
send( (
void* )command.c_str(), ( int )command.length() + 1, ip, DTRACK2_PORT_FEEDBACK, d_udptimeout_us );
bool setDataBufferSize(int bufSize)
Set UDP buffer size for receiving tracking data.
std::string getBuf() const
Get content of the UDP buffer.
int send(const void *buffer, int len, unsigned int ip, unsigned short port, int toutUs)
Send UDP data.
bool receive()
Receive and process one tracking data packet.
unsigned short getDataPort() const
Get UDP data port where tracking data is received.
bool isCommandInterfaceFullAccess()
Returns if TCP connection has full access for DTrack2/DTRACK3 commands.
bool setParam(const std::string &category, const std::string &name, const std::string &value)
Set DTrack2/DTRACK3 parameter.
std::string getMessageOrigin() const
Get origin of last DTrack2/DTRACK3 event message.
DTrackSDK(const std::string &connection)
Universal constructor. Can be used for any mode. Recommended for new applications.
bool enableStatefulFirewallConnection(const std::string &senderHost, unsigned short senderPort=DTRACK2_PORT_UDPSENDER)
Enable UDP connection through a stateful firewall.
bool setDataTimeoutUS(int timeout)
Set UDP timeout for receiving tracking data.
unsigned short getPort()
Get UDP data port where data is received.
std::string getLastDTrackErrorDescription() const
Get last DTrack2/DTRACK3 command error description.
unsigned int getMessageErrorId() const
Get error id of last DTrack2/DTRACK3 event message.
RemoteSystemType getRemoteSystemType() const
Get current remote system type (e.g. DTrack1, DTrack2/DTRACK3).
bool tactileFinger(int handId, int fingerId, double strength)
Send tactile FINGERTRACKING command to set feedback on a specific finger of a specific hand...
int receive(void *buffer, int maxLen, int toutUs)
Receive TCP data.
int receive(void *buffer, int maxLen, int toutUs)
Receive UDP data.
bool getParam(const std::string &category, const std::string &name, std::string &value)
Get DTrack2/DTRACK3 parameter.
unsigned int getMessageFrameNr() const
Get frame counter of last DTrack2/DTRACK3 event message.
unsigned int getRemoteIp()
Get IP address of sender of latest received data.
std::string getMessageStatus() const
Get status of last DTrack2/DTRACK3 event message.
bool processPacket(const std::string &data)
Process one tracking packet manually.
static const int DTRACK2_PROT_MAXLEN
max. length of 'dtrack2' command
Errors getLastServerError() const
Get last error at exchanging commands with Controller (command transmission).
bool isCommandInterfaceValid() const
Returns if TCP connection for DTrack2/DTRACK3 commands is active.
bool flystickVibration(int flystickId, int vibrationPattern)
Send Flystick feedback command to start a vibration pattern on a specific Flystick.
bool sendDTrack1Command(const std::string &command)
Send DTrack1 command via UDP.
std::string getMessageMsg() const
Get message text of last DTrack2/DTRACK3 event message.
bool flystickBeep(int flystickId, double durationMs, double frequencyHz)
Send Flystick feedback command to start a beep on a specific Flystick.
RemoteSystemType
Compatibility modes for older DTrack systems.
Error while parsing command.
bool isDataInterfaceValid() const
Returns if UDP socket is open to receive tracking data on local machine.
bool getMessage()
Get DTrack2/DTRACK3 event message from the Controller.
Errors getLastDataError() const
Get last error at receiving tracking data (data transmission).
bool tactileHandOff(int handId, int numFinger)
Send tactile FINGERTRACKING command to turn off tactile feedback on all fingers of a specific hand...
bool stopMeasurement()
Stop measurement.
bool startMeasurement()
Start measurement.
bool parseLine(char **line)
Parses a single line of data in one tracking data packet.
bool isValid()
Returns if UDP socket is open to receive data.
void startFrame()
Set default values at start of a new frame.
int send(const void *buffer, int len, int toutUs)
Send TCP data.
int getLastDTrackError() const
Get last DTrack2/DTRACK3 command error code.
bool isValid()
Returns if TCP connection is active.
bool setCommandTimeoutUS(int timeout)
Set TCP timeout for exchanging commands with Controller.
int sendDTrack2Command(const std::string &command, std::string *answer=NULL)
Send DTrack2/DTRACK3 command to DTrack and receive answer (TCP command interface).
bool isValid()
Returns if constructor was successful due to the wanted mode.
void endFrame()
Final adjustments after processing all data for a frame.
bool tactileHand(int handId, const std::vector< double > &strength)
Send tactile FINGERTRACKING command to set tactile feedback on all fingers of a specific hand...