1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Sound Channel Process Functions
4 Copyright 2006-2010 Pierre Ossman <ossman@cendio.se> for Cendio AB
5 Copyright 2009-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6 Copyright 2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
7 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
8 Copyright (C) GuoJunBo <guojunbo@ict.ac.cn> 2003
9 Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include <assert.h>
26
27 #include "rdesktop.h"
28 #include "rdpsnd.h"
29 #include "rdpsnd_dsp.h"
30
31 #define SNDC_CLOSE 0x01
32 #define SNDC_WAVE 0x02
33 #define SNDC_SETVOLUME 0x03
34 #define SNDC_SETPITCH 0x04
35 #define SNDC_WAVECONFIRM 0x05
36 #define SNDC_TRAINING 0x06
37 #define SNDC_FORMATS 0x07
38 #define SNDC_CRYPTKEY 0x08
39 #define SNDC_WAVEENCRYPT 0x09
40 #define SNDC_UDPWAVE 0x0A
41 #define SNDC_UDPWAVELAST 0x0B
42 #define SNDC_QUALITYMODE 0x0C
43 #define SNDC_WAVE2 0x0D
44
45 #define MAX_FORMATS 10
46 #define MAX_QUEUE 50
47
48 extern RD_BOOL g_rdpsnd;
49
50 static VCHANNEL *rdpsnd_channel;
51 static VCHANNEL *rdpsnddbg_channel;
52 static struct audio_driver *drivers = NULL;
53 struct audio_driver *current_driver = NULL;
54
55 static RD_BOOL rdpsnd_negotiated;
56
57 static RD_BOOL device_open;
58
59 static RD_WAVEFORMATEX formats[MAX_FORMATS];
60 static unsigned int format_count;
61 static unsigned int current_format;
62
63 unsigned int queue_hi, queue_lo, queue_pending;
64 struct audio_packet packet_queue[MAX_QUEUE];
65
66 static uint8 packet_opcode;
67 static size_t packet_len;
68 static struct stream packet;
69
70 void (*wave_out_play) (void);
71
72 static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
73 static void rdpsnd_queue_init(void);
74 static void rdpsnd_queue_clear(void);
75 static void rdpsnd_queue_complete_pending(void);
76 static long rdpsnd_queue_next_completion(void);
77
78 static STREAM
rdpsnd_init_packet(uint8 type,uint16 size)79 rdpsnd_init_packet(uint8 type, uint16 size)
80 {
81 STREAM s;
82
83 s = channel_init(rdpsnd_channel, size + 4);
84 out_uint8(s, type);
85 out_uint8(s, 0); /* protocol-mandated padding */
86 out_uint16_le(s, size);
87 return s;
88 }
89
90 static void
rdpsnd_send(STREAM s)91 rdpsnd_send(STREAM s)
92 {
93 channel_send(s, rdpsnd_channel);
94 }
95
96 static void
rdpsnd_send_waveconfirm(uint16 tick,uint8 packet_index)97 rdpsnd_send_waveconfirm(uint16 tick, uint8 packet_index)
98 {
99 STREAM s;
100
101 s = rdpsnd_init_packet(SNDC_WAVECONFIRM, 4);
102 out_uint16_le(s, tick);
103 out_uint8(s, packet_index);
104 out_uint8(s, 0);
105 s_mark_end(s);
106 rdpsnd_send(s);
107 s_free(s);
108
109 logger(Sound, Debug, "rdpsnd_send_waveconfirm(), tick=%u, index=%u",
110 (unsigned) tick, (unsigned) packet_index);
111 }
112
113 void
rdpsnd_record(const void * data,unsigned int size)114 rdpsnd_record(const void *data, unsigned int size)
115 {
116 UNUSED(data);
117 UNUSED(size);
118 /* TODO: Send audio over RDP */
119 }
120
121 static RD_BOOL
rdpsnd_auto_select(void)122 rdpsnd_auto_select(void)
123 {
124 static RD_BOOL failed = False;
125
126 if (!failed)
127 {
128 current_driver = drivers;
129 while (current_driver != NULL)
130 {
131 logger(Sound, Debug, "rdpsnd_auto_select(), trying driver '%s'",
132 current_driver->name);
133 if (current_driver->wave_out_open())
134 {
135 logger(Sound, Verbose, "rdpsnd_auto_select(), using driver '%s'",
136 current_driver->name);
137 current_driver->wave_out_close();
138 return True;
139 }
140 current_driver = current_driver->next;
141 }
142
143 logger(Sound, Debug, "no working audio-driver found");
144 failed = True;
145 current_driver = NULL;
146 }
147
148 return False;
149 }
150
151 static void
rdpsnd_process_negotiate(STREAM in)152 rdpsnd_process_negotiate(STREAM in)
153 {
154 uint16 in_format_count, i;
155 uint8 pad;
156 uint16 version;
157 RD_WAVEFORMATEX *format;
158 STREAM out;
159 RD_BOOL device_available = False;
160 int readcnt;
161 int discardcnt;
162
163 in_uint8s(in, 14); /* initial bytes not valid from server */
164 in_uint16_le(in, in_format_count);
165 in_uint8(in, pad);
166 in_uint16_le(in, version);
167 in_uint8s(in, 1); /* padding */
168
169 logger(Sound, Debug,
170 "rdpsnd_process_negotiate(), formats = %d, pad = 0x%02x, version = 0x%x",
171 (int) in_format_count, (unsigned) pad, (unsigned) version);
172
173 if (rdpsnd_negotiated)
174 {
175 /* Do a complete reset of the sound state */
176 rdpsnd_reset_state();
177 }
178
179 if (!current_driver && g_rdpsnd)
180 device_available = rdpsnd_auto_select();
181
182 if (current_driver && !device_available && current_driver->wave_out_open())
183 {
184 current_driver->wave_out_close();
185 device_available = True;
186 }
187
188 format_count = 0;
189 if (s_check_rem(in, 18 * in_format_count))
190 {
191 for (i = 0; i < in_format_count; i++)
192 {
193 format = &formats[format_count];
194 in_uint16_le(in, format->wFormatTag);
195 in_uint16_le(in, format->nChannels);
196 in_uint32_le(in, format->nSamplesPerSec);
197 in_uint32_le(in, format->nAvgBytesPerSec);
198 in_uint16_le(in, format->nBlockAlign);
199 in_uint16_le(in, format->wBitsPerSample);
200 in_uint16_le(in, format->cbSize);
201
202 /* read in the buffer of unknown use */
203 readcnt = format->cbSize;
204 discardcnt = 0;
205 if (format->cbSize > MAX_CBSIZE)
206 {
207 logger(Sound, Debug,
208 "rdpsnd_process_negotiate(), cbSize too large for buffer: %d",
209 format->cbSize);
210 readcnt = MAX_CBSIZE;
211 discardcnt = format->cbSize - MAX_CBSIZE;
212 }
213 in_uint8a(in, format->cb, readcnt);
214 in_uint8s(in, discardcnt);
215
216 if (current_driver && current_driver->wave_out_format_supported(format))
217 {
218 format_count++;
219 if (format_count == MAX_FORMATS)
220 break;
221 }
222 }
223 }
224
225 out = rdpsnd_init_packet(SNDC_FORMATS, 20 + 18 * format_count);
226
227 uint32 flags = TSSNDCAPS_VOLUME;
228
229 /* if sound is enabled, set snd caps to alive to enable
230 transmission of audio from server */
231 if (g_rdpsnd)
232 {
233 flags |= TSSNDCAPS_ALIVE;
234 }
235 out_uint32_le(out, flags); /* TSSNDCAPS flags */
236
237 out_uint32(out, 0xffffffff); /* volume */
238 out_uint32(out, 0); /* pitch */
239 out_uint16(out, 0); /* UDP port */
240
241 out_uint16_le(out, format_count);
242 out_uint8(out, 0); /* padding */
243 out_uint16_le(out, 2); /* version */
244 out_uint8(out, 0); /* padding */
245
246 for (i = 0; i < format_count; i++)
247 {
248 format = &formats[i];
249 out_uint16_le(out, format->wFormatTag);
250 out_uint16_le(out, format->nChannels);
251 out_uint32_le(out, format->nSamplesPerSec);
252 out_uint32_le(out, format->nAvgBytesPerSec);
253 out_uint16_le(out, format->nBlockAlign);
254 out_uint16_le(out, format->wBitsPerSample);
255 out_uint16(out, 0); /* cbSize */
256 }
257
258 s_mark_end(out);
259
260 logger(Sound, Debug, "rdpsnd_process_negotiate(), %d formats available",
261 (int) format_count);
262
263 rdpsnd_send(out);
264 s_free(out);
265
266 rdpsnd_negotiated = True;
267 }
268
269 static void
rdpsnd_process_training(STREAM in)270 rdpsnd_process_training(STREAM in)
271 {
272 uint16 tick;
273 uint16 packsize;
274 STREAM out;
275 struct stream packet = *in;
276
277 if (!s_check_rem(in, 4))
278 {
279 rdp_protocol_error("consume of training data from stream would overrun", &packet);
280 }
281
282 in_uint16_le(in, tick);
283 in_uint16_le(in, packsize);
284
285 logger(Sound, Debug, "rdpsnd_process_training(), tick=0x%04x", (unsigned) tick);
286
287 out = rdpsnd_init_packet(SNDC_TRAINING, 4);
288 out_uint16_le(out, tick);
289 out_uint16_le(out, packsize);
290 s_mark_end(out);
291 rdpsnd_send(out);
292 s_free(out);
293 }
294
295 static void
rdpsnd_process_packet(uint8 opcode,STREAM s)296 rdpsnd_process_packet(uint8 opcode, STREAM s)
297 {
298 uint16 vol_left, vol_right;
299
300 uint16 tick, format;
301 uint8 packet_index;
302 unsigned int size;
303 unsigned char *data;
304
305 switch (opcode)
306 {
307 case SNDC_WAVE:
308 in_uint16_le(s, tick);
309 in_uint16_le(s, format);
310 in_uint8(s, packet_index);
311 in_uint8s(s, 3);
312 logger(Sound, Debug,
313 "rdpsnd_process_packet(), RDPSND_WRITE(tick: %u, format: %u, index: %u, data: %u bytes)\n",
314 (unsigned) tick, (unsigned) format, (unsigned) packet_index,
315 (unsigned) s->size - 8);
316
317 if (format >= MAX_FORMATS)
318 {
319 logger(Sound, Error,
320 "rdpsnd_process_packet(), invalid format index");
321 break;
322 }
323
324 if (!device_open || (format != current_format))
325 {
326 /*
327 * If we haven't selected a device by now, then either
328 * we've failed to find a working device, or the server
329 * is sending bogus SNDC_WAVE.
330 */
331 if (!current_driver)
332 {
333 rdpsnd_send_waveconfirm(tick, packet_index);
334 break;
335 }
336 if (!device_open && !current_driver->wave_out_open())
337 {
338 rdpsnd_send_waveconfirm(tick, packet_index);
339 break;
340 }
341 if (!current_driver->wave_out_set_format(&formats[format]))
342 {
343 rdpsnd_send_waveconfirm(tick, packet_index);
344 current_driver->wave_out_close();
345 device_open = False;
346 break;
347 }
348 device_open = True;
349 current_format = format;
350 }
351
352 size = s_remaining(s);
353 in_uint8p(s, data, size);
354 rdpsnd_queue_write(rdpsnd_dsp_process(data, size,
355 current_driver,
356 &formats[current_format]),
357 tick, packet_index);
358 return;
359 break;
360 case SNDC_CLOSE:
361 logger(Sound, Debug, "rdpsnd_process_packet(), SNDC_CLOSE()");
362 if (device_open)
363 current_driver->wave_out_close();
364 device_open = False;
365 break;
366 case SNDC_FORMATS:
367 rdpsnd_process_negotiate(s);
368 break;
369 case SNDC_TRAINING:
370 rdpsnd_process_training(s);
371 break;
372 case SNDC_SETVOLUME:
373 in_uint16_le(s, vol_left);
374 in_uint16_le(s, vol_right);
375 logger(Sound, Debug,
376 "rdpsnd_process_packet(), SNDC_SETVOLUME(left: 0x%04x (%u %%), right: 0x%04x (%u %%))",
377 (unsigned) vol_left, (unsigned) vol_left / 655, (unsigned) vol_right,
378 (unsigned) vol_right / 655);
379 if (device_open)
380 current_driver->wave_out_volume(vol_left, vol_right);
381 break;
382 default:
383 logger(Sound, Warning, "rdpsnd_process_packet(), Unhandled opcode 0x%x",
384 opcode);
385 break;
386 }
387 }
388
389 static void
rdpsnd_process(STREAM s)390 rdpsnd_process(STREAM s)
391 {
392 while (!s_check_end(s))
393 {
394 /* New packet */
395 if (packet_len == 0)
396 {
397 if (!s_check_rem(s, 4))
398 {
399 logger(Sound, Error,
400 "rdpsnd_process(), split at packet header, things will go south from here...");
401 return;
402 }
403 in_uint8(s, packet_opcode);
404 in_uint8s(s, 1); /* Padding */
405 in_uint16_le(s, packet_len);
406
407 logger(Sound, Debug, "rdpsnd_process(), Opcode = 0x%x Length= %d",
408 (int) packet_opcode, (int) packet_len);
409 }
410 else
411 {
412 uint16 len;
413
414 len = MIN(s_remaining(s), packet_len - s_length(&packet));
415
416 /* Microsoft's server is so broken it's not even funny... */
417 if (packet_opcode == SNDC_WAVE)
418 {
419 if (s_length(&packet) < 12)
420 len = MIN(len, 12 - s_length(&packet));
421 else if (s_length(&packet) == 12)
422 {
423 logger(Sound, Debug,
424 "rdpsnd_process(), eating 4 bytes of %d bytes...",
425 len);
426 in_uint8s(s, 4);
427 len -= 4;
428 }
429 }
430
431 in_uint8stream(s, &packet, len);
432 /* Always end it so s_length() works */
433 s_mark_end(&packet);
434 }
435
436 /* Packet fully assembled */
437 if (s_length(&packet) == packet_len)
438 {
439 s_seek(&packet, 0);
440 rdpsnd_process_packet(packet_opcode, &packet);
441 packet_len = 0;
442 s_reset(&packet);
443 }
444 }
445 }
446
447 static RD_BOOL
rdpsnddbg_line_handler(const char * line,void * data)448 rdpsnddbg_line_handler(const char *line, void *data)
449 {
450 UNUSED(data);
451 logger(Sound, Debug, "rdpsnddbg_line_handler(), \"%s\"", line);
452 return True;
453 }
454
455 static void
rdpsnddbg_process(STREAM s)456 rdpsnddbg_process(STREAM s)
457 {
458 unsigned int pkglen;
459 static char *rest = NULL;
460 char *buf;
461
462 pkglen = s_remaining(s);
463 /* str_handle_lines requires null terminated strings */
464 buf = (char *) xmalloc(pkglen + 1);
465 in_uint8a(s, buf, pkglen);
466 buf[pkglen] = '\0';
467
468 str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);
469
470 xfree(buf);
471 }
472
473 static void
rdpsnd_register_drivers(char * options)474 rdpsnd_register_drivers(char *options)
475 {
476 struct audio_driver **reg;
477
478 /* The order of registrations define the probe-order
479 when opening the device for the first time */
480 reg = &drivers;
481 #if defined(RDPSND_PULSE)
482 *reg = pulse_register(options);
483 assert(*reg);
484 reg = &((*reg)->next);
485 #endif
486 #if defined(RDPSND_ALSA)
487 *reg = alsa_register(options);
488 assert(*reg);
489 reg = &((*reg)->next);
490 #endif
491 #if defined(RDPSND_SUN)
492 *reg = sun_register(options);
493 assert(*reg);
494 reg = &((*reg)->next);
495 #endif
496 #if defined(RDPSND_OSS)
497 *reg = oss_register(options);
498 assert(*reg);
499 reg = &((*reg)->next);
500 #endif
501 #if defined(RDPSND_SGI)
502 *reg = sgi_register(options);
503 assert(*reg);
504 reg = &((*reg)->next);
505 #endif
506 #if defined(RDPSND_LIBAO)
507 *reg = libao_register(options);
508 assert(*reg);
509 reg = &((*reg)->next);
510 #endif
511 *reg = NULL;
512 }
513
514 RD_BOOL
rdpsnd_init(char * optarg)515 rdpsnd_init(char *optarg)
516 {
517 struct audio_driver *pos;
518 char *driver = NULL, *options = NULL;
519
520 drivers = NULL;
521
522 s_realloc(&packet, 65536);
523
524 rdpsnd_channel =
525 channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
526 rdpsnd_process);
527
528 rdpsnddbg_channel =
529 channel_register("snddbg", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
530 rdpsnddbg_process);
531
532 if ((rdpsnd_channel == NULL) || (rdpsnddbg_channel == NULL))
533 {
534 logger(Sound, Error,
535 "rdpsnd_init(), failed to register rdpsnd / snddbg virtual channels");
536 return False;
537 }
538
539 rdpsnd_queue_init();
540
541 if (optarg != NULL && strlen(optarg) > 0)
542 {
543 driver = options = optarg;
544
545 while (*options != '\0' && *options != ':')
546 options++;
547
548 if (*options == ':')
549 {
550 *options = '\0';
551 options++;
552 }
553
554 if (*options == '\0')
555 options = NULL;
556 }
557
558 rdpsnd_register_drivers(options);
559
560 if (!driver)
561 return True;
562
563 pos = drivers;
564 while (pos != NULL)
565 {
566 if (!strcmp(pos->name, driver))
567 {
568 logger(Sound, Debug, "rdpsnd_init(), using driver '%s'", pos->name);
569 current_driver = pos;
570 return True;
571 }
572 pos = pos->next;
573 }
574 return False;
575 }
576
577 void
rdpsnd_reset_state(void)578 rdpsnd_reset_state(void)
579 {
580 if (device_open)
581 current_driver->wave_out_close();
582 device_open = False;
583 rdpsnd_queue_clear();
584 rdpsnd_negotiated = False;
585 }
586
587
588 void
rdpsnd_show_help(void)589 rdpsnd_show_help(void)
590 {
591 struct audio_driver *pos;
592
593 rdpsnd_register_drivers(NULL);
594
595 pos = drivers;
596 while (pos != NULL)
597 {
598 fprintf(stderr, " %s:\t%s\n", pos->name, pos->description);
599 pos = pos->next;
600 }
601 }
602
603 void
rdpsnd_add_fds(int * n,fd_set * rfds,fd_set * wfds,struct timeval * tv)604 rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
605 {
606 long next_pending;
607
608 if (device_open)
609 current_driver->add_fds(n, rfds, wfds, tv);
610
611 next_pending = rdpsnd_queue_next_completion();
612 if (next_pending >= 0)
613 {
614 long cur_timeout;
615
616 cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
617 if (cur_timeout > next_pending)
618 {
619 tv->tv_sec = next_pending / 1000000;
620 tv->tv_usec = next_pending % 1000000;
621 }
622 }
623 }
624
625 void
rdpsnd_check_fds(fd_set * rfds,fd_set * wfds)626 rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
627 {
628 rdpsnd_queue_complete_pending();
629
630 if (device_open)
631 current_driver->check_fds(rfds, wfds);
632 }
633
634 static void
rdpsnd_queue_write(STREAM s,uint16 tick,uint8 index)635 rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
636 {
637 struct audio_packet *packet = &packet_queue[queue_hi];
638 unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
639
640 if (next_hi == queue_pending)
641 {
642 logger(Sound, Error, "rdpsnd_queue_write(), no space to queue audio packet");
643 return;
644 }
645
646 queue_hi = next_hi;
647
648 packet->s = s;
649 packet->tick = tick;
650 packet->index = index;
651
652 gettimeofday(&packet->arrive_tv, NULL);
653 }
654
655 struct audio_packet *
rdpsnd_queue_current_packet(void)656 rdpsnd_queue_current_packet(void)
657 {
658 return &packet_queue[queue_lo];
659 }
660
661 RD_BOOL
rdpsnd_queue_empty(void)662 rdpsnd_queue_empty(void)
663 {
664 return (queue_lo == queue_hi);
665 }
666
667 static void
rdpsnd_queue_init(void)668 rdpsnd_queue_init(void)
669 {
670 queue_pending = queue_lo = queue_hi = 0;
671 }
672
673 static void
rdpsnd_queue_clear(void)674 rdpsnd_queue_clear(void)
675 {
676 struct audio_packet *packet;
677
678 /* Go through everything, not just the pending packets */
679 while (queue_pending != queue_hi)
680 {
681 packet = &packet_queue[queue_pending];
682 s_free(packet->s);
683 queue_pending = (queue_pending + 1) % MAX_QUEUE;
684 }
685
686 /* Reset everything back to the initial state */
687 queue_pending = queue_lo = queue_hi = 0;
688 }
689
690 void
rdpsnd_queue_next(unsigned long completed_in_us)691 rdpsnd_queue_next(unsigned long completed_in_us)
692 {
693 struct audio_packet *packet;
694
695 assert(!rdpsnd_queue_empty());
696
697 packet = &packet_queue[queue_lo];
698
699 gettimeofday(&packet->completion_tv, NULL);
700
701 packet->completion_tv.tv_usec += completed_in_us;
702 packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
703 packet->completion_tv.tv_usec %= 1000000;
704
705 queue_lo = (queue_lo + 1) % MAX_QUEUE;
706
707 rdpsnd_queue_complete_pending();
708 }
709
710 int
rdpsnd_queue_next_tick(void)711 rdpsnd_queue_next_tick(void)
712 {
713 if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
714 {
715 return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
716 }
717 else
718 {
719 return (packet_queue[queue_lo].tick + 65535) % 65536;
720 }
721 }
722
723 static void
rdpsnd_queue_complete_pending(void)724 rdpsnd_queue_complete_pending(void)
725 {
726 struct timeval now;
727 long elapsed;
728 struct audio_packet *packet;
729
730 gettimeofday(&now, NULL);
731
732 while (queue_pending != queue_lo)
733 {
734 packet = &packet_queue[queue_pending];
735
736 if (now.tv_sec < packet->completion_tv.tv_sec)
737 break;
738
739 if ((now.tv_sec == packet->completion_tv.tv_sec) &&
740 (now.tv_usec < packet->completion_tv.tv_usec))
741 break;
742
743 elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
744 (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
745 elapsed /= 1000;
746
747 s_free(packet->s);
748 rdpsnd_send_waveconfirm((packet->tick + elapsed) % 65536, packet->index);
749 queue_pending = (queue_pending + 1) % MAX_QUEUE;
750 }
751 }
752
753 static long
rdpsnd_queue_next_completion(void)754 rdpsnd_queue_next_completion(void)
755 {
756 struct audio_packet *packet;
757 long remaining;
758 struct timeval now;
759
760 if (queue_pending == queue_lo)
761 return -1;
762
763 gettimeofday(&now, NULL);
764
765 packet = &packet_queue[queue_pending];
766
767 remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
768 (packet->completion_tv.tv_usec - now.tv_usec);
769
770 if (remaining < 0)
771 return 0;
772
773 return remaining;
774 }
775