3#if defined(VRPN_USE_JSONNET)
6 #ifdef VRPN_USE_WINSOCK2
12 #include <sys/socket.h>
14 #include <netinet/in.h>
16 #define INVALID_SOCKET -1
28static const char*
const MSG_KEY_TYPE =
"type";
32static const char*
const MSG_KEY_TRACKER_ID =
"id";
33static const char*
const MSG_KEY_TRACKER_QUAT =
"quat";
34static const char*
const MSG_KEY_TRACKER_POS =
"pos";
36static const char*
const MSG_KEY_BUTTON_ID =
"button";
37static const char*
const MSG_KEY_BUTTON_STATUS =
"state";
39static const char*
const MSG_KEY_ANALOG_CHANNEL =
"num";
40static const char*
const MSG_KEY_ANALOG_DATA =
"data";
42static const char*
const MSG_KEY_TEXT_DATA =
"data";
45static const int MSG_TYPE_TRACKER = 1;
46static const int MSG_TYPE_BUTTON = 2;
47static const int MSG_TYPE_ANALOG = 3;
48static const int MSG_TYPE_TEXT = 4;
50vrpn_Tracker_JsonNet::vrpn_Tracker_JsonNet(
const char* name,
vrpn_Connection* c,
int udp_port) :
56 _do_tracker_report(false),
59 fprintf(stderr,
"vrpn_Tracker_JsonNet : Device %s listen on port udp port %d\n", name, udp_port);
60 if (! _network_init(udp_port)) {
69 _pJsonReader =
new Json::Reader();
72vrpn_Tracker_JsonNet::~vrpn_Tracker_JsonNet(
void)
74 if (_pJsonReader != 0) {
78 fprintf(stderr,
"vrpn_Tracker_JsonNet::~vrpn_Tracker_JsonNet(): delete failed\n");
87void vrpn_Tracker_JsonNet::mainloop()
97 const int timeout_us = 10 * 1000;
98 int received_length = _network_receive(_network_buffer, _NETWORK_BUFFER_SIZE, timeout_us);
100 if (received_length < 0) {
104 _network_buffer[received_length] =
'\0';
106 if (!_parse(_network_buffer, received_length)) {
117 if (d_connection && _do_tracker_report) {
125 _do_tracker_report =
false;
133bool vrpn_Tracker_JsonNet::_parse(
const char* buffer,
int )
137 bool parsingSuccessful = _pJsonReader->parse( buffer, root ,
false);
138 if ( !parsingSuccessful ) {
140 fprintf(stderr,
"vrpn_Tracker_JsonNet parse error :%s\n",
141 _pJsonReader->getFormatedErrorMessages().c_str());
142 fprintf(stderr,
"%s\n",buffer);
146 const Json::Value& constRoot = root;
148 const Json::Value& type = constRoot[MSG_KEY_TYPE];
150 if (!type.empty() && type.isConvertibleTo(Json::intValue)) {
151 messageType = type.asInt();
154 fprintf(stderr,
"vrpn_Tracker_JsonNet parse error : missing message type\n");
157 switch (messageType) {
159 case MSG_TYPE_TRACKER:
160 return _parse_tracker_data(root);
162 case MSG_TYPE_BUTTON:
163 return _parse_button(root);
165 case MSG_TYPE_ANALOG:
166 return _parse_analog(root);
169 return _parse_text(root);
185bool vrpn_Tracker_JsonNet::_parse_tracker_data(
const Json::Value& root)
187 const Json::Value& constRoot = root;
190 const Json::Value& sensorId = constRoot[MSG_KEY_TRACKER_ID];
191 if (!sensorId.empty() && sensorId.isConvertibleTo(Json::intValue)){
192 this->d_sensor = sensorId.asInt();
202 const Json::Value& quatData = constRoot[MSG_KEY_TRACKER_QUAT];
203 if (!quatData.empty() && quatData.isArray() && quatData.size() == 4) {
204 this->d_quat[0] = quatData[0u].asDouble();
205 this->d_quat[1] = quatData[1].asDouble();
206 this->d_quat[2] = quatData[2].asDouble();
207 this->d_quat[3] = quatData[3].asDouble();
216 const Json::Value& posData = constRoot[MSG_KEY_TRACKER_POS];
217 if (!posData.empty() && posData.isArray() && posData.size() == 3) {
218 this->pos[0] = posData[0u].asDouble();
219 this->pos[1]= posData[1].asDouble();
220 this->pos[2]= posData[2].asDouble();
223 _do_tracker_report =
true;
235bool vrpn_Tracker_JsonNet::_parse_text(
const Json::Value& root)
237 const Json::Value& valueTextStatus = root[MSG_KEY_TEXT_DATA];
238 if (!valueTextStatus.empty() && valueTextStatus.isConvertibleTo(Json::stringValue)) {
242 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_text parse error : missing text");
253bool vrpn_Tracker_JsonNet::_parse_button(
const Json::Value& root)
255 const Json::Value& valueButtonStatus = root[MSG_KEY_BUTTON_STATUS];
257 if (!valueButtonStatus.empty() && valueButtonStatus.isConvertibleTo(Json::booleanValue)) {
258 buttonStatus = valueButtonStatus.asBool();
260 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_button parse error : missing status");
263 const Json::Value& valueButtonId = root[MSG_KEY_BUTTON_ID];
265 if (!valueButtonId.empty() && valueButtonId.isConvertibleTo(Json::intValue)) {
266 buttonId = valueButtonId.asInt();
268 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_button parse error : missing id\n");
272 if (buttonId < 0 || buttonId > num_buttons) {
273 fprintf(stderr,
"invalid button Id %d (max : %d)\n", buttonId, num_buttons);
275 buttons[buttonId] = (int)buttonStatus;
290bool vrpn_Tracker_JsonNet::_parse_analog(
const Json::Value& root)
292 const Json::Value& valueData = root[MSG_KEY_ANALOG_DATA];
294 if (!valueData.empty() && valueData.isConvertibleTo(Json::realValue)) {
295 data = valueData.asDouble();
297 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog parse error : missing status");
301 const Json::Value& channelNumberId = root[MSG_KEY_ANALOG_CHANNEL];
303 if (!channelNumberId.empty() && channelNumberId.isConvertibleTo(Json::intValue)) {
304 channelNumber = channelNumberId.asInt();
306 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog parse error : missing id\n");
310 if (channelNumber < 0 || channelNumber >= num_channel) {
311 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog id out of bounds %d/%d\n", channelNumber, num_channel);
313 channel[channelNumber] = data;
323bool vrpn_Tracker_JsonNet::_network_init(
int udp_port)
329 WORD versionRequested = MAKEWORD(2,2);
332 iResult = WSAStartup(versionRequested, &wsaData);
334 printf(
"WSAStartup failed with error: %d\n", iResult);
343 _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
345 printf(
"socket failed with error: %ld\n", WSAGetLastError());
355 usock = socket(PF_INET, SOCK_DGRAM, 0);
363 struct sockaddr_in localSocketAddress;
364 memset((
void *)&localSocketAddress, 0,
sizeof(localSocketAddress));
365 localSocketAddress.sin_family = AF_INET;
366 localSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
367 localSocketAddress.sin_port = htons(udp_port);
370 iResult = bind( _socket, (
struct sockaddr*)&localSocketAddress,
sizeof(localSocketAddress));
373 printf(
"bind failed with error: %d\n", WSAGetLastError());
375 printf(
"bind failed.");
396int vrpn_Tracker_JsonNet::_network_receive(
void *buffer,
int maxlen,
int tout_us)
405 FD_SET(_socket, &set);
407 tout.tv_sec = tout_us / 1000000;
408 tout.tv_usec = tout_us % 1000000;
410 switch((err = select(FD_SETSIZE, &set, NULL, NULL, &tout))){
427 nbytes = recv(_socket, (
char *)buffer, maxlen, 0);
435 FD_SET(_socket, &set);
440 if(select(FD_SETSIZE, &set, NULL, NULL, &tout) != 1){
442 if(nbytes >= maxlen){
453void vrpn_Tracker_JsonNet::_network_release()
456 closesocket(_socket);
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Generic connection class not specific to the transport mechanism.
Allows a user to send text messages from a device (usually,.
virtual int encode_to(char *buf)
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
Header allowing use of a output stream-style method of sending text messages from devices.
#define vrpn_gettimeofday