vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Analog_Output.C
Go to the documentation of this file.
1 #include "vrpn_Analog_Output.h"
2 #include <stdio.h>
3 
5  : vrpn_BaseClass(name, c)
6  , o_num_channel(0)
7 {
8  int i;
9 
10  // Call the base class' init routine
12 
13  // Set the time to 0 just to have something there.
14  o_timestamp.tv_usec = o_timestamp.tv_sec = 0;
15  // Initialize the values in the channels,
16  // gets rid of uninitialized memory read error in Purify
17  // and makes sure any initial value change gets reported.
18  for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
19  o_channel[i] = 0;
20  }
21 }
22 
24 {
26  "vrpn_Analog_Output Change_request");
28  "vrpn_Analog_Output Change_Channels_request");
30  "vrpn_Analog_Output Num_Channels_report");
33  if ((request_m_id == -1) || (request_channels_m_id == -1) ||
34  (report_num_channels_m_id == -1) || (got_connection_m_id == -1)) {
35  return -1;
36  }
37  else {
38  return 0;
39  }
40 }
41 
43 {
44  printf("Analog_Output Report: ");
45  for (vrpn_int32 i = 0; i < o_num_channel; i++) {
46  // printf("Channel[%d]= %f\t", i, o_channel[i]);
47  printf("%f\t", o_channel[i]);
48  }
49  printf("\n");
50 }
51 
53  vrpn_Connection* c,
54  vrpn_int32 numChannels)
55  : vrpn_Analog_Output(name, c)
56 {
57  this->setNumChannels(numChannels);
58 
59  // Check if we have a connection
60  if (d_connection == NULL) {
61  fprintf(stderr, "vrpn_Analog_Output: Can't get connection!\n");
62  }
63 
64  // Register a handler for the request channel change message
66  d_sender_id)) {
67  fprintf(stderr, "vrpn_Analog_Output_Server: can't register change "
68  "channel request handler\n");
69  d_connection = NULL;
70  }
71 
72  // Register a handler for the request channels change message
75  d_sender_id)) {
76  fprintf(stderr, "vrpn_Analog_Output_Server: can't register change "
77  "channels request handler\n");
78  d_connection = NULL;
79  }
80 
81  // Register a handler for vrpn_got_connection, so we can tell the
82  // client how many channels are active
84  this)) {
85  fprintf(stderr, "vrpn_Analog_Output_Server: can't register new "
86  "connection handler\n");
87  d_connection = NULL;
88  }
89 }
90 
91 // virtual
93 
94 vrpn_int32 vrpn_Analog_Output_Server::setNumChannels(vrpn_int32 sizeRequested)
95 {
96  if (sizeRequested < 0) sizeRequested = 0;
97  if (sizeRequested > vrpn_CHANNEL_MAX) sizeRequested = vrpn_CHANNEL_MAX;
98 
99  o_num_channel = sizeRequested;
100 
101  return o_num_channel;
102 }
103 
104 /* static */
107 {
108  const char* bufptr = p.buffer;
109  vrpn_int32 chan_num;
110  vrpn_int32 pad;
111  vrpn_float64 value;
113 
114  // Read the parameters from the buffer
115  vrpn_unbuffer(&bufptr, &chan_num);
116  vrpn_unbuffer(&bufptr, &pad);
117  vrpn_unbuffer(&bufptr, &value);
118 
119  // Set the appropriate value, if the channel number is in the
120  // range of the ones we have.
121  if ((chan_num < 0) || (chan_num >= me->o_num_channel)) {
122  fprintf(stderr, "vrpn_Analog_Output_Server::handle_request_message(): "
123  "Index out of bounds\n");
124  char msg[1024];
125  sprintf(msg, "Error: (handle_request_message): channel %d is not "
126  "active. Squelching.",
127  chan_num);
129  return 0;
130  }
131  me->o_channel[chan_num] = value;
132 
133  return 0;
134 }
135 
136 /* static */
138  void* userdata, vrpn_HANDLERPARAM p)
139 {
140  int i;
141  const char* bufptr = p.buffer;
142  vrpn_int32 num;
143  vrpn_int32 pad;
145 
146  // Read the values from the buffer
147  vrpn_unbuffer(&bufptr, &num);
148  vrpn_unbuffer(&bufptr, &pad);
149  if (num > me->o_num_channel) {
150  char msg[1024];
151  sprintf(msg, "Error: (handle_request_channels_message): channels "
152  "above %d not active; "
153  "bad request up to channel %d. Squelching.",
154  me->o_num_channel, num);
156  num = me->o_num_channel;
157  }
158  if (num < 0) {
159  char msg[1024];
160  sprintf(msg, "Error: (handle_request_channels_message): invalid "
161  "channel %d. Squelching.",
162  num);
164  return 0;
165  }
166  for (i = 0; i < num; i++) {
167  vrpn_unbuffer(&bufptr, &(me->o_channel[i]));
168  }
169 
170  return 0;
171 }
172 
173 /* static */
176 {
178  if (me->report_num_channels() == false) {
179  fprintf(stderr, "Error: failed sending active channels to client.\n");
180  }
181  return 0;
182 }
183 
185  vrpn_uint32 class_of_service)
186 {
187  char msgbuf[sizeof(vrpn_int32)];
188  vrpn_int32 len = sizeof(vrpn_int32);
189  ;
190 
191  encode_num_channels_to(msgbuf, this->o_num_channel);
193  if (d_connection &&
195  d_sender_id, msgbuf, class_of_service)) {
196  fprintf(stderr, "vrpn_Analog_Output_Server (report_num_channels): "
197  "cannot write message: tossing\n");
198  return false;
199  }
200  return true;
201 }
202 
204  vrpn_int32 num)
205 {
206  // Message includes: int32 number of active channels
207  int buflen = sizeof(vrpn_int32);
208 
209  vrpn_buffer(&buf, &buflen, num);
210  return sizeof(vrpn_int32);
211 }
212 
214  const char* name, vrpn_Connection* c, vrpn_int32 numChannels)
215  : vrpn_Analog_Output_Server(name, c, numChannels)
216 {
217  // Register a handler for the request channel change message. This will go
218  // in the list AFTER the one for the base class, so the values will already
219  // have been filled in. So we just need to call the user-level callbacks
220  // and pass them a pointer to the data values.
222  d_sender_id)) {
223  fprintf(stderr, "vrpn_Analog_Output_Callback_Server: can't register "
224  "change channel request handler\n");
225  d_connection = NULL;
226  }
227 
228  // Register a handler for the request channels change message. This will go
229  // in the list AFTER the one for the base class, so the values will already
230  // have been filled in. So we just need to call the user-level callbacks
231  // and pass them a pointer to the data values.
234  fprintf(stderr, "vrpn_Analog_Output_Callback_Server: can't register "
235  "change channels request handler\n");
236  d_connection = NULL;
237  }
238 }
239 
240 // virtual
242 
243 /* static */
244 // This is inserted into the list AFTER the
246  void* userdata, vrpn_HANDLERPARAM p)
247 {
250  vrpn_ANALOGOUTPUTCB callback_data;
251 
252  callback_data.msg_time = p.msg_time;
253  callback_data.num_channel = me->getNumChannels();
254  callback_data.channel = me->o_channels();
255  me->d_callback_list.call_handlers(callback_data);
256 
257  return 0;
258 }
259 
261  vrpn_Connection* c)
262  : vrpn_Analog_Output(name, c)
263 {
264  vrpn_int32 i;
265 
267  for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
268  o_channel[i] = 0;
269  }
271 
272  // Register a handler for the report number of active channels message
275  d_sender_id)) {
276  fprintf(stderr, "vrpn_Analog_Output_Remote: can't register active "
277  "channel report handler\n");
278  d_connection = NULL;
279  }
280 }
281 
282 // virtual
284 
286 {
287  if (d_connection) {
289  client_mainloop();
290  }
291 }
292 
293 /* static */
296 {
297  const char* bufptr = p.buffer;
298  vrpn_int32 num;
300 
301  // Read the parameters from the buffer
302  vrpn_unbuffer(&bufptr, &num);
303 
304  if (num >= 0 && num <= vrpn_CHANNEL_MAX) {
305  me->o_num_channel = num;
306  }
307  else {
308  fprintf(
309  stderr,
310  "vrpn_Analog_Output_Remote::handle_report_num_channels_message: "
311  "Someone sent us a bogus number of channels: %d.\n",
312  num);
313  }
314  return 0;
315 }
316 
318  unsigned int chan, vrpn_float64 val, vrpn_uint32 class_of_service)
319 {
320  // msgbuf must be float64-aligned!
321  vrpn_float64 fbuf[2];
322  char* msgbuf = (char*)fbuf;
323 
324  vrpn_int32 len;
325 
327  len = encode_change_to(msgbuf, chan, val);
328  if (d_connection &&
330  msgbuf, class_of_service)) {
331  fprintf(stderr,
332  "vrpn_Analog_Output_Remote: cannot write message: tossing\n");
333  return false;
334  }
335 
336  return true;
337 }
338 
340  int num, vrpn_float64* vals, vrpn_uint32 class_of_service)
341 {
342  if (num < 0 || num > vrpn_CHANNEL_MAX) {
343  fprintf(stderr, "vrpn_Analog_Output_Remote: cannot change channels: "
344  "number of channels out of range\n");
345  return false;
346  }
347 
348  vrpn_float64 fbuf[1 + vrpn_CHANNEL_MAX];
349  char* msgbuf = (char*)fbuf;
350  vrpn_int32 len;
351 
353  len = encode_change_channels_to(msgbuf, num, vals);
354  if (d_connection &&
356  d_sender_id, msgbuf, class_of_service)) {
357  fprintf(stderr,
358  "vrpn_Analog_Output_Remote: cannot write message: tossing\n");
359  return false;
360  }
361  return true;
362 }
363 
365  vrpn_int32 chan,
366  vrpn_float64 val)
367 {
368  // Message includes: int32 channel_number, int32 padding, float64
369  // request_value
370  // Byte order of each needs to be reversed to match network standard
371 
372  vrpn_int32 pad = 0;
373  int buflen = 2 * sizeof(vrpn_int32) + sizeof(vrpn_float64);
374 
375  vrpn_buffer(&buf, &buflen, chan);
376  vrpn_buffer(&buf, &buflen, pad);
377  vrpn_buffer(&buf, &buflen, val);
378 
379  return 2 * sizeof(vrpn_int32) + sizeof(vrpn_float64);
380 }
381 
382 vrpn_int32
384  vrpn_float64* vals)
385 {
386  int i;
387  vrpn_int32 pad = 0;
388  int buflen = 2 * sizeof(vrpn_int32) + num * sizeof(vrpn_float64);
389 
390  vrpn_buffer(&buf, &buflen, num);
391  vrpn_buffer(&buf, &buflen, pad);
392  for (i = 0; i < num; i++) {
393  vrpn_buffer(&buf, &buflen, vals[i]);
394  }
395 
396  return 2 * sizeof(vrpn_int32) + num * sizeof(vrpn_float64);
397 }
vrpn_BaseClassUnique::register_autodeleted_handler
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
Definition: vrpn_BaseClass.C:503
vrpn_Connection::pack_message
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
Definition: vrpn_Connection.C:4632
vrpn_BaseClassUnique::client_mainloop
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
Definition: vrpn_BaseClass.C:637
vrpn_Analog_Output_Remote::mainloop
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Analog_Output.C:285
vrpn_Analog_Output_Server::o_channels
const vrpn_float64 * o_channels(void) const
Exposes an array of values for the user to read from.
Definition: vrpn_Analog_Output.h:70
vrpn_Analog_Output_Remote::request_change_channels
virtual bool request_change_channels(int num, vrpn_float64 *vals, vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Analog_Output.C:339
vrpn_got_connection
const char * vrpn_got_connection
Definition: vrpn_Connection.C:185
vrpn_Analog_Output_Callback_Server::vrpn_Analog_Output_Callback_Server
vrpn_Analog_Output_Callback_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
Definition: vrpn_Analog_Output.C:213
vrpn_Analog_Output_Server::handle_request_channels_message
static int VRPN_CALLBACK handle_request_channels_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change a number of channels Derived class must either install handlers for t...
Definition: vrpn_Analog_Output.C:137
vrpn_Analog_Output.h
vrpn_Analog_Output_Server::handle_request_message
static int VRPN_CALLBACK handle_request_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change one of the values by setting the channel to that value....
Definition: vrpn_Analog_Output.C:105
vrpn_BaseClassUnique::userdata
void * userdata
Definition: vrpn_BaseClass.h:287
vrpn_Analog_Output_Server::encode_num_channels_to
virtual vrpn_int32 encode_num_channels_to(char *buf, vrpn_int32 num)
Definition: vrpn_Analog_Output.C:203
vrpn_Analog_Output::o_num_channel
vrpn_int32 o_num_channel
Definition: vrpn_Analog_Output.h:37
vrpn_Analog_Output
Definition: vrpn_Analog_Output.h:26
vrpn_CHANNEL_MAX
#define vrpn_CHANNEL_MAX
Definition: vrpn_Analog.h:16
vrpn_Analog_Output_Remote::vrpn_Analog_Output_Remote
vrpn_Analog_Output_Remote(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Analog_Output.C:260
vrpn_unbuffer
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
vrpn_Analog_Output::vrpn_Analog_Output
vrpn_Analog_Output(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Analog_Output.C:4
vrpn_BaseClassUnique::d_connection
vrpn_Connection * d_connection
Connection that this object talks to.
Definition: vrpn_BaseClass.h:224
vrpn_HANDLERPARAM::buffer
const char * buffer
Definition: vrpn_Connection.h:49
vrpn_Connection::register_message_type
virtual vrpn_int32 register_message_type(const char *name)
Definition: vrpn_Connection.C:5074
vrpn_Analog_Output::got_connection_m_id
vrpn_int32 got_connection_m_id
Definition: vrpn_Analog_Output.h:44
vrpn_Analog_Output_Remote::encode_change_channels_to
virtual vrpn_int32 encode_change_channels_to(char *buf, vrpn_int32 num, vrpn_float64 *vals)
Definition: vrpn_Analog_Output.C:383
vrpn_TEXT_ERROR
@ vrpn_TEXT_ERROR
Definition: vrpn_BaseClass.h:103
vrpn_Analog_Output::getNumChannels
vrpn_int32 getNumChannels() const
Definition: vrpn_Analog_Output.h:33
vrpn_Analog_Output_Callback_Server
Definition: vrpn_Analog_Output.h:113
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Analog_Output_Callback_Server::d_callback_list
vrpn_Callback_List< vrpn_ANALOGOUTPUTCB > d_callback_list
List of user-level routines that need to be called back to let them know that the values have changed...
Definition: vrpn_Analog_Output.h:148
vrpn_BaseClassUnique::d_sender_id
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Definition: vrpn_BaseClass.h:228
vrpn_Analog_Output::register_types
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
Definition: vrpn_Analog_Output.C:23
vrpn_Analog_Output_Remote::request_change_channel_value
virtual bool request_change_channel_value(unsigned int chan, vrpn_float64 val, vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Analog_Output.C:317
vrpn_Analog_Output_Remote::~vrpn_Analog_Output_Remote
virtual ~vrpn_Analog_Output_Remote(void)
Definition: vrpn_Analog_Output.C:283
vrpn_Analog_Output_Server::setNumChannels
vrpn_int32 setNumChannels(vrpn_int32 sizeRequested)
Sets the size of the array; returns the size actually set. (May be clamped to vrpn_CHANNEL_MAX) This ...
Definition: vrpn_Analog_Output.C:94
vrpn_Connection::mainloop
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
vrpn_HANDLERPARAM::msg_time
struct timeval msg_time
Definition: vrpn_Connection.h:47
vrpn_Analog_Output_Server::vrpn_Analog_Output_Server
vrpn_Analog_Output_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
Definition: vrpn_Analog_Output.C:52
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Analog_Output_Server
Definition: vrpn_Analog_Output.h:56
vrpn_Analog_Output::o_timestamp
struct timeval o_timestamp
Definition: vrpn_Analog_Output.h:38
vrpn_Analog_Output_Server::~vrpn_Analog_Output_Server
virtual ~vrpn_Analog_Output_Server(void)
Definition: vrpn_Analog_Output.C:92
vrpn_BaseClass::init
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
Definition: vrpn_BaseClass.C:363
vrpn_Analog_Output::o_channel
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog_Output.h:36
vrpn_buffer
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
Definition: vrpn_Shared.C:241
vrpn_Analog_Output_Callback_Server::~vrpn_Analog_Output_Callback_Server
virtual ~vrpn_Analog_Output_Callback_Server(void)
Definition: vrpn_Analog_Output.C:241
vrpn_Analog_Output_Server::handle_got_connection
static int VRPN_CALLBACK handle_got_connection(void *userdata, vrpn_HANDLERPARAM p)
Used to notify us when a new connection is requested, so that we can let the client know how many cha...
Definition: vrpn_Analog_Output.C:174
vrpn_Analog_Output_Server::report_num_channels
virtual bool report_num_channels(vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Analog_Output.C:184
vrpn_Analog_Output_Callback_Server::handle_change_message
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p)
Handles BOTH types of changes messages, and will be called after the vrpn_Analog_Output_Server class ...
Definition: vrpn_Analog_Output.C:245
vrpn_Analog_Output_Remote
Definition: vrpn_Analog_Output.h:154
vrpn_BaseClassUnique::send_text_message
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
Definition: vrpn_BaseClass.C:568
vrpn_Analog_Output_Remote::encode_change_to
virtual vrpn_int32 encode_change_to(char *buf, vrpn_int32 chan, vrpn_float64 val)
Definition: vrpn_Analog_Output.C:364
vrpn_Callback_List::call_handlers
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Definition: vrpn_BaseClass.h:451
vrpn_Analog_Output::request_channels_m_id
vrpn_int32 request_channels_m_id
Definition: vrpn_Analog_Output.h:40
vrpn_Analog_Output::request_m_id
vrpn_int32 request_m_id
Definition: vrpn_Analog_Output.h:39
vrpn_Analog_Output_Remote::handle_report_num_channels
static int VRPN_CALLBACK handle_report_num_channels(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Analog_Output.C:294
vrpn_BaseClass
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
Definition: vrpn_BaseClass.h:313
vrpn_Analog_Output::report_num_channels_m_id
vrpn_int32 report_num_channels_m_id
Definition: vrpn_Analog_Output.h:42
vrpn_Analog_Output::o_print
void o_print(void)
Definition: vrpn_Analog_Output.C:42