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) {
124 _do_tracker_report =
false;
132bool vrpn_Tracker_JsonNet::_parse(
const char* buffer,
int )
136 bool parsingSuccessful = _pJsonReader->parse( buffer, root ,
false);
137 if ( !parsingSuccessful ) {
139 fprintf(stderr,
"vrpn_Tracker_JsonNet parse error :%s\n",
140 _pJsonReader->getFormatedErrorMessages().c_str());
141 fprintf(stderr,
"%s\n",buffer);
145 const Json::Value& constRoot = root;
147 const Json::Value& type = constRoot[MSG_KEY_TYPE];
149 if (!type.empty() && type.isConvertibleTo(Json::intValue)) {
150 messageType = type.asInt();
153 fprintf(stderr,
"vrpn_Tracker_JsonNet parse error : missing message type\n");
156 switch (messageType) {
158 case MSG_TYPE_TRACKER:
159 return _parse_tracker_data(root);
161 case MSG_TYPE_BUTTON:
162 return _parse_button(root);
164 case MSG_TYPE_ANALOG:
165 return _parse_analog(root);
168 return _parse_text(root);
184bool vrpn_Tracker_JsonNet::_parse_tracker_data(
const Json::Value& root)
186 const Json::Value& constRoot = root;
189 const Json::Value& sensorId = constRoot[MSG_KEY_TRACKER_ID];
190 if (!sensorId.empty() && sensorId.isConvertibleTo(Json::intValue)){
191 this->d_sensor = sensorId.asInt();
201 const Json::Value& quatData = constRoot[MSG_KEY_TRACKER_QUAT];
202 if (!quatData.empty() && quatData.isArray() && quatData.size() == 4) {
203 this->d_quat[0] = quatData[0u].asDouble();
204 this->d_quat[1] = quatData[1].asDouble();
205 this->d_quat[2] = quatData[2].asDouble();
206 this->d_quat[3] = quatData[3].asDouble();
215 const Json::Value& posData = constRoot[MSG_KEY_TRACKER_POS];
216 if (!posData.empty() && posData.isArray() && posData.size() == 3) {
217 this->pos[0] = posData[0u].asDouble();
218 this->pos[1]= posData[1].asDouble();
219 this->pos[2]= posData[2].asDouble();
222 _do_tracker_report =
true;
234bool vrpn_Tracker_JsonNet::_parse_text(
const Json::Value& root)
236 const Json::Value& valueTextStatus = root[MSG_KEY_TEXT_DATA];
237 if (!valueTextStatus.empty() && valueTextStatus.isConvertibleTo(Json::stringValue)) {
241 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_text parse error : missing text");
252bool vrpn_Tracker_JsonNet::_parse_button(
const Json::Value& root)
254 const Json::Value& valueButtonStatus = root[MSG_KEY_BUTTON_STATUS];
256 if (!valueButtonStatus.empty() && valueButtonStatus.isConvertibleTo(Json::booleanValue)) {
257 buttonStatus = valueButtonStatus.asBool();
259 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_button parse error : missing status");
262 const Json::Value& valueButtonId = root[MSG_KEY_BUTTON_ID];
264 if (!valueButtonId.empty() && valueButtonId.isConvertibleTo(Json::intValue)) {
265 buttonId = valueButtonId.asInt();
267 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_button parse error : missing id\n");
271 if (buttonId < 0 || buttonId > num_buttons) {
272 fprintf(stderr,
"invalid button Id %d (max : %d)\n", buttonId, num_buttons);
274 buttons[buttonId] = (int)buttonStatus;
289bool vrpn_Tracker_JsonNet::_parse_analog(
const Json::Value& root)
291 const Json::Value& valueData = root[MSG_KEY_ANALOG_DATA];
293 if (!valueData.empty() && valueData.isConvertibleTo(Json::realValue)) {
294 data = valueData.asDouble();
296 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog parse error : missing status");
300 const Json::Value& channelNumberId = root[MSG_KEY_ANALOG_CHANNEL];
302 if (!channelNumberId.empty() && channelNumberId.isConvertibleTo(Json::intValue)) {
303 channelNumber = channelNumberId.asInt();
305 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog parse error : missing id\n");
309 if (channelNumber < 0 || channelNumber >= num_channel) {
310 fprintf(stderr,
"vrpn_Tracker_JsonNet::_parse_analog id out of bounds %d/%d\n", channelNumber, num_channel);
312 channel[channelNumber] = data;
322bool vrpn_Tracker_JsonNet::_network_init(
int udp_port)
328 WORD versionRequested = MAKEWORD(2,2);
331 iResult = WSAStartup(versionRequested, &wsaData);
333 printf(
"WSAStartup failed with error: %d\n", iResult);
342 _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
344 printf(
"socket failed with error: %ld\n", WSAGetLastError());
354 usock = socket(PF_INET, SOCK_DGRAM, 0);
362 struct sockaddr_in localSocketAddress;
363 memset((
void *)&localSocketAddress, 0,
sizeof(localSocketAddress));
364 localSocketAddress.sin_family = AF_INET;
365 localSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
366 localSocketAddress.sin_port = htons(udp_port);
369 iResult = bind( _socket, (
struct sockaddr*)&localSocketAddress,
sizeof(localSocketAddress));
372 printf(
"bind failed with error: %d\n", WSAGetLastError());
374 printf(
"bind failed.");
395int vrpn_Tracker_JsonNet::_network_receive(
void *buffer,
int maxlen,
int tout_us)
404 FD_SET(_socket, &set);
406 tout.tv_sec = tout_us / 1000000;
407 tout.tv_usec = tout_us % 1000000;
409 switch((err = select(FD_SETSIZE, &set, NULL, NULL, &tout))){
426 nbytes = recv(_socket, (
char *)buffer, maxlen, 0);
434 FD_SET(_socket, &set);
439 if(select(FD_SETSIZE, &set, NULL, NULL, &tout) != 1){
441 if(nbytes >= maxlen){
452void vrpn_Tracker_JsonNet::_network_release()
455 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