vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Analog_Output.C
Go to the documentation of this file.
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) ||
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
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
94vrpn_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
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
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) {
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
382vrpn_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_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...
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 ...
vrpn_Analog_Output_Callback_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
virtual ~vrpn_Analog_Output_Remote(void)
virtual bool request_change_channel_value(unsigned int chan, vrpn_float64 val, vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
virtual vrpn_int32 encode_change_channels_to(char *buf, vrpn_int32 num, vrpn_float64 *vals)
static int VRPN_CALLBACK handle_report_num_channels(void *userdata, vrpn_HANDLERPARAM p)
virtual bool request_change_channels(int num, vrpn_float64 *vals, vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
virtual vrpn_int32 encode_change_to(char *buf, vrpn_int32 chan, vrpn_float64 val)
vrpn_Analog_Output_Remote(const char *name, vrpn_Connection *c=NULL)
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...
virtual bool report_num_channels(vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
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...
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 ...
virtual vrpn_int32 encode_num_channels_to(char *buf, vrpn_int32 num)
virtual ~vrpn_Analog_Output_Server(void)
const vrpn_float64 * o_channels(void) const
Exposes an array of values for the user to read from.
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....
vrpn_Analog_Output_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
vrpn_int32 got_connection_m_id
vrpn_int32 report_num_channels_m_id
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
vrpn_int32 request_channels_m_id
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
vrpn_int32 getNumChannels() const
struct timeval o_timestamp
vrpn_Analog_Output(const char *name, vrpn_Connection *c=NULL)
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.
vrpn_Connection * d_connection
Connection that this object talks to.
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
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.
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Generic connection class not specific to the transport mechanism.
virtual vrpn_int32 register_message_type(const char *name)
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...
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...
const vrpn_float64 * channel
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
#define vrpn_CHANNEL_MAX
Definition: vrpn_Analog.h:16
@ vrpn_TEXT_ERROR
const char * vrpn_got_connection
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:321
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:250
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:99