root/branches/ppalmers-streaming/src/libstreaming/util/IsoHandler.cpp

Revision 719, 20.8 kB (checked in by ppalmers, 13 years ago)

backup commit

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "IsoHandler.h"
25 #include "cycletimer.h"
26 #include "../generic/IsoStream.h"
27
28 #include "libutil/TimeSource.h"
29 #include "libutil/SystemTimeSource.h"
30
31 #include <errno.h>
32 #include <netinet/in.h>
33 #include <assert.h>
34 #include <unistd.h>
35 #include <string.h>
36
37 #include <iostream>
38 using namespace std;
39
40 #define CC_SLEEP_TIME_AFTER_UPDATE    1000
41 #define CC_SLEEP_TIME_AFTER_FAILURE     10
42 #define CC_DLL_COEFF     ((0.001)*((float)(CC_SLEEP_TIME_AFTER_UPDATE/1000.0)))
43
44 #define CC_MAX_RATE_ERROR           (2.0/100.0)
45 #define CC_INIT_MAX_TRIES 10
46
47
48 namespace Streaming
49 {
50
51 IMPL_DEBUG_MODULE( IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
52
53 /* the C callbacks */
54 enum raw1394_iso_disposition
55 IsoXmitHandler::iso_transmit_handler(raw1394handle_t handle,
56         unsigned char *data, unsigned int *length,
57         unsigned char *tag, unsigned char *sy,
58         int cycle, unsigned int dropped) {
59
60     IsoXmitHandler *xmitHandler=static_cast<IsoXmitHandler *>(raw1394_get_userdata(handle));
61     assert(xmitHandler);
62
63     return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped);
64 }
65
66 enum raw1394_iso_disposition
67 IsoRecvHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
68                         unsigned int length, unsigned char channel,
69                         unsigned char tag, unsigned char sy, unsigned int cycle,
70                         unsigned int dropped) {
71
72     IsoRecvHandler *recvHandler=static_cast<IsoRecvHandler *>(raw1394_get_userdata(handle));
73     assert(recvHandler);
74
75     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped);
76 }
77
78 int IsoHandler::busreset_handler(raw1394handle_t handle, unsigned int generation)
79 {
80     debugOutput( DEBUG_LEVEL_VERBOSE, "Busreset happened, generation %d...\n", generation);
81
82     IsoHandler *handler=static_cast<IsoHandler *>(raw1394_get_userdata(handle));
83     assert(handler);
84     return handler->handleBusReset(generation);
85 }
86
87
88 /* Base class implementation */
89 IsoHandler::IsoHandler(int port)
90    :  m_handle(0), m_handle_util(0), m_port(port),
91    m_buf_packets(400), m_max_packet_size(1024), m_irq_interval(-1),
92    m_packetcount(0), m_dropped(0), m_Client(0),
93    m_State(E_Created)
94 {
95 }
96
97 IsoHandler::IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq)
98    : m_handle(0), m_port(port),
99    m_buf_packets(buf_packets), m_max_packet_size( max_packet_size),
100    m_irq_interval(irq),
101    m_packetcount(0), m_dropped(0), m_Client(0),
102    m_State(E_Created)
103 {
104 }
105
106 IsoHandler::~IsoHandler() {
107
108 // Don't call until libraw1394's raw1394_new_handle() function has been
109 // fixed to correctly initialise the iso_packet_infos field.  Bug is
110 // confirmed present in libraw1394 1.2.1.  In any case,
111 // raw1394_destroy_handle() will do any iso system shutdown required.
112 //     raw1394_iso_shutdown(m_handle);
113
114     if(m_handle) {
115         if (m_State == E_Running) {
116             stop();
117         }
118
119         raw1394_destroy_handle(m_handle);
120     }
121
122     if(m_handle_util) raw1394_destroy_handle(m_handle_util);
123
124 }
125
126 bool IsoHandler::iterate() {
127     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "IsoHandler (%p) iterate...\n",this);
128
129     if(m_handle) {
130         if(raw1394_loop_iterate(m_handle)) {
131             debugOutput( DEBUG_LEVEL_VERBOSE,
132                  "IsoHandler (%p): Failed to iterate handler: %s\n",
133                  this,strerror(errno));
134             return false;
135         } else {
136             return true;
137         }
138     } else {
139         return false;
140     }
141 }
142
143 bool
144 IsoHandler::init()
145 {
146     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) enter...\n",this);
147
148     // check the state
149     if(m_State != E_Created) {
150         debugError("Incorrect state, expected E_Created, got %d\n",(int)m_State);
151         return false;
152     }
153
154     // the main handle for the ISO traffic
155     m_handle = raw1394_new_handle_on_port( m_port );
156     if ( !m_handle ) {
157         if ( !errno ) {
158             debugError("libraw1394 not compatible\n");
159         } else {
160             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
161             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
162         }
163         return false;
164     }
165     raw1394_set_userdata(m_handle, static_cast<void *>(this));
166
167     // a second handle for utility stuff
168     m_handle_util = raw1394_new_handle_on_port( m_port );
169     if ( !m_handle_util ) {
170         if ( !errno ) {
171             debugError("libraw1394 not compatible\n");
172         } else {
173             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
174             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
175         }
176
177         raw1394_destroy_handle(m_handle);
178         return false;
179     }
180     raw1394_set_userdata(m_handle_util, static_cast<void *>(this));
181
182     // bus reset handling
183     if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) {
184         debugWarning("Could not enable busreset notification.\n");
185         debugWarning(" Error message: %s\n",strerror(errno));
186         debugWarning("Continuing without bus reset support.\n");
187     } else {
188         // apparently this cannot fail
189         raw1394_set_bus_reset_handler(m_handle, busreset_handler);
190     }
191
192     // test the cycle timer read function
193     int err;
194     uint32_t cycle_timer;
195     uint64_t local_time;
196     err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time);
197     if(err) {
198         debugError("raw1394_read_cycle_timer failed.\n");
199         debugError(" Error: %s\n", strerror(err));
200         debugError(" Your system doesn't seem to support the raw1394_read_cycle_timer call\n");
201         return false;
202     }
203
204     // update the internal state
205     m_State=E_Initialized;
206
207     return true;
208 }
209
210 bool IsoHandler::prepare()
211 {
212     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) enter...\n",this);
213
214     // check the state
215     if(m_State != E_Initialized) {
216         debugError("Incorrect state, expected E_Initialized, got %d\n",(int)m_State);
217         return false;
218     }
219
220     // Don't call until libraw1394's raw1394_new_handle() function has been
221     // fixed to correctly initialise the iso_packet_infos field.  Bug is
222     // confirmed present in libraw1394 1.2.1.
223
224 //     raw1394_iso_shutdown(m_handle);
225
226     m_State = E_Prepared;
227
228     return true;
229 }
230
231 bool IsoHandler::start(int cycle)
232 {
233     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
234
235     // check the state
236     if(m_State != E_Prepared) {
237         debugError("Incorrect state, expected E_Prepared, got %d\n",(int)m_State);
238         return false;
239     }
240
241     m_State=E_Running;
242
243     return true;
244 }
245
246 bool IsoHandler::stop()
247 {
248     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
249
250     // check state
251     if(m_State != E_Running) {
252         debugError("Incorrect state, expected E_Running, got %d\n",(int)m_State);
253         return false;
254     }
255
256     // this is put here to try and avoid the
257     // Runaway context problem
258     // don't know if it will help though.
259     raw1394_iso_xmit_sync(m_handle);
260
261     raw1394_iso_stop(m_handle);
262
263     m_State=E_Prepared;
264
265     return true;
266 }
267
268 /**
269  * Bus reset handler
270  *
271  * @return ?
272  */
273
274 int IsoHandler::handleBusReset(unsigned int generation) {
275     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n");
276
277     // do a simple read on ourself in order to update the internal structures
278     // this avoids read failures after a bus reset
279     quadlet_t buf=0;
280     raw1394_read(m_handle, raw1394_get_local_id(m_handle),
281                  CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);
282
283     return 0;
284 }
285
286 /**
287  * Returns the current value of the cycle timer (in ticks)
288  *
289  * @return the current value of the cycle timer (in ticks)
290  */
291
292 unsigned int IsoHandler::getCycleTimerTicks() {
293     // the new api should be realtime safe.
294     // it might cause a reschedule when turning preemption,
295     // back on but that won't hurt us if we have sufficient
296     // priority
297     int err;
298     uint32_t cycle_timer;
299     uint64_t local_time;
300     err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time);
301     if(err) {
302         debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err));
303     }
304     return CYCLE_TIMER_TO_TICKS(cycle_timer);
305 }
306
307 /**
308  * Returns the current value of the cycle timer (as is)
309  *
310  * @return the current value of the cycle timer (as is)
311  */
312
313 unsigned int IsoHandler::getCycleTimer() {
314     // the new api should be realtime safe.
315     // it might cause a reschedule when turning preemption,
316     // back on but that won't hurt us if we have sufficient
317     // priority
318     int err;
319     uint32_t cycle_timer;
320     uint64_t local_time;
321     err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time);
322     if(err) {
323         debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err));
324     }
325     return cycle_timer;
326 }
327
328 void IsoHandler::dumpInfo()
329 {
330
331     int channel=-1;
332     if (m_Client) channel=m_Client->getChannel();
333
334     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type    : %s\n",
335             (this->getType()==EHT_Receive ? "Receive" : "Transmit"));
336     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel   : %2d, %2d\n",
337             m_port, channel);
338     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packet count    : %10d (%5d dropped)\n",
339             this->getPacketCount(), this->getDroppedCount());
340 }
341
342 void IsoHandler::setVerboseLevel(int l)
343 {
344     setDebugLevel(l);
345 }
346
347 bool IsoHandler::registerStream(IsoStream *stream)
348 {
349     assert(stream);
350     debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream);
351
352     if (m_Client) {
353             debugFatal( "Generic IsoHandlers can have only one client\n");
354             return false;
355     }
356
357     m_Client=stream;
358
359     m_Client->setHandler(this);
360
361     return true;
362
363 }
364
365 bool IsoHandler::unregisterStream(IsoStream *stream)
366 {
367     assert(stream);
368     debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream);
369
370     if(stream != m_Client) {
371             debugFatal( "no client registered\n");
372             return false;
373     }
374
375     m_Client->clearHandler();
376
377     m_Client=0;
378     return true;
379
380 }
381
382 /* Child class implementations */
383
384 IsoRecvHandler::IsoRecvHandler(int port)
385                 : IsoHandler(port)
386 {
387     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
388 }
389 IsoRecvHandler::IsoRecvHandler(int port, unsigned int buf_packets,
390                                unsigned int max_packet_size, int irq)
391                 : IsoHandler(port, buf_packets,max_packet_size,irq)
392 {
393     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
394
395 }
396 IsoRecvHandler::~IsoRecvHandler()
397 {
398
399 }
400
401 bool
402 IsoRecvHandler::init() {
403     debugOutput( DEBUG_LEVEL_VERBOSE, "init recv handler %p\n",this);
404
405     if(!(IsoHandler::init())) {
406         return false;
407     }
408     return true;
409
410 }
411
412 enum raw1394_iso_disposition IsoRecvHandler::putPacket(
413                     unsigned char *data, unsigned int length,
414                     unsigned char channel, unsigned char tag, unsigned char sy,
415                     unsigned int cycle, unsigned int dropped) {
416
417     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
418                  "received packet: length=%d, channel=%d, cycle=%d\n",
419                  length, channel, cycle );
420     m_packetcount++;
421     m_dropped+=dropped;
422
423     if(m_Client) {
424         return m_Client->putPacket(data, length, channel, tag, sy, cycle, dropped);
425     }
426
427     return RAW1394_ISO_OK;
428 }
429
430 bool IsoRecvHandler::prepare()
431 {
432
433     // prepare the generic IsoHandler
434     if(!IsoHandler::prepare()) {
435         return false;
436     }
437
438     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso receive handler (%p)\n",this);
439     debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers         : %d \n", m_buf_packets);
440     debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n", m_max_packet_size);
441     debugOutput( DEBUG_LEVEL_VERBOSE, " Channel         : %d \n", m_Client->getChannel());
442     debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval    : %d \n", m_irq_interval);
443     debugOutput( DEBUG_LEVEL_VERBOSE, " Mode            : %s \n",
444                                (m_irq_interval > 1)?"DMA_BUFFERFILL":"PACKET_PER_BUFFER");
445
446     if(m_irq_interval > 1) {
447         if(raw1394_iso_recv_init(m_handle,
448                                 iso_receive_handler,
449                                 m_buf_packets,
450                                 m_max_packet_size,
451                                 m_Client->getChannel(),
452                                 RAW1394_DMA_BUFFERFILL,
453                                 m_irq_interval)) {
454             debugFatal("Could not do receive initialisation!\n" );
455             debugFatal("  %s\n",strerror(errno));
456
457             return false;
458         }
459     } else {
460         if(raw1394_iso_recv_init(m_handle,
461                                 iso_receive_handler,
462                                 m_buf_packets,
463                                 m_max_packet_size,
464                                 m_Client->getChannel(),
465                                 RAW1394_DMA_PACKET_PER_BUFFER,
466                                 m_irq_interval)) {
467             debugFatal("Could not do receive initialisation!\n" );
468             debugFatal("  %s\n",strerror(errno));
469
470             return false;
471         }
472     }
473     return true;
474 }
475
476 bool IsoRecvHandler::start(int cycle)
477 {
478     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle);
479
480     // start the generic IsoHandler
481     if(!IsoHandler::start(cycle)) {
482         return false;
483     }
484
485     if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) {
486         debugFatal("Could not start receive handler (%s)\n",strerror(errno));
487         return false;
488     }
489     return true;
490 }
491
492 int IsoRecvHandler::handleBusReset(unsigned int generation) {
493     debugOutput( DEBUG_LEVEL_VERBOSE, "handle bus reset...\n");
494
495     //TODO: implement busreset
496
497     // pass on the busreset signal
498     if(IsoHandler::handleBusReset(generation)) {
499         return -1;
500     }
501     return 0;
502 }
503
504 /* ----------------- XMIT --------------- */
505
506 IsoXmitHandler::IsoXmitHandler(int port)
507                 : IsoHandler(port), m_prebuffers(0)
508 {
509     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
510
511 }
512 IsoXmitHandler::IsoXmitHandler(int port, unsigned int buf_packets,
513                                unsigned int max_packet_size, int irq)
514                 : IsoHandler(port, buf_packets, max_packet_size,irq),
515                   m_speed(RAW1394_ISO_SPEED_400), m_prebuffers(0)
516 {
517     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
518
519 }
520 IsoXmitHandler::IsoXmitHandler(int port, unsigned int buf_packets,
521                                unsigned int max_packet_size, int irq,
522                                enum raw1394_iso_speed speed)
523                 : IsoHandler(port, buf_packets,max_packet_size,irq),
524                   m_speed(speed), m_prebuffers(0)
525 {
526     debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n");
527
528 }
529
530 IsoXmitHandler::~IsoXmitHandler()
531 {
532     // handle cleanup is done in the IsoHanlder destructor
533 }
534
535 bool
536 IsoXmitHandler::init() {
537
538     debugOutput( DEBUG_LEVEL_VERBOSE, "init xmit handler %p\n",this);
539
540     if(!(IsoHandler::init())) {
541         return false;
542     }
543
544     return true;
545 }
546
547 bool IsoXmitHandler::prepare()
548 {
549     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso transmit handler (%p, client=%p)\n",this,m_Client);
550
551     if(!(IsoHandler::prepare())) {
552         return false;
553     }
554
555     debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers         : %d \n",m_buf_packets);
556     debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n",m_max_packet_size);
557     debugOutput( DEBUG_LEVEL_VERBOSE, " Channel         : %d \n",m_Client->getChannel());
558     debugOutput( DEBUG_LEVEL_VERBOSE, " Speed           : %d \n",m_speed);
559     debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval    : %d \n",m_irq_interval);
560
561     if(raw1394_iso_xmit_init(m_handle,
562                              iso_transmit_handler,
563                              m_buf_packets,
564                              m_max_packet_size,
565                              m_Client->getChannel(),
566                              m_speed,
567                              m_irq_interval)) {
568         debugFatal("Could not do xmit initialisation!\n" );
569
570         return false;
571     }
572
573     return true;
574 }
575
576 bool IsoXmitHandler::start(int cycle)
577 {
578     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d, %d prebuffers\n",
579         cycle, m_prebuffers);
580
581     if(!(IsoHandler::start(cycle))) {
582         return false;
583     }
584
585     if(raw1394_iso_xmit_start(m_handle, cycle, m_prebuffers)) {
586         debugFatal("Could not start xmit handler (%s)\n",strerror(errno));
587         return false;
588     }
589     return true;
590 }
591
592 enum raw1394_iso_disposition IsoXmitHandler::getPacket(
593                     unsigned char *data, unsigned int *length,
594                     unsigned char *tag, unsigned char *sy,
595                     int cycle, unsigned int dropped) {
596
597     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
598                     "sending packet: length=%d, cycle=%d\n",
599                     *length, cycle );
600     m_packetcount++;
601     m_dropped+=dropped;
602
603     if(m_Client) {
604         return m_Client->getPacket(data, length, tag, sy, cycle, dropped, m_max_packet_size);
605     }
606
607     return RAW1394_ISO_OK;
608 }
609
610 int IsoXmitHandler::handleBusReset(unsigned int generation) {
611     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n");
612     //TODO: implement busreset
613
614     // pass on the busreset signal
615     if(IsoHandler::handleBusReset(generation)) {
616             return -1;
617     }
618
619     return 0;
620 }
621
622 }
623
624 /* multichannel receive  */
625 #if 0
626 IsoRecvHandler::IsoRecvHandler(int port)
627         : IsoHandler(port)
628 {
629     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
630 }
631 IsoRecvHandler::IsoRecvHandler(int port, unsigned int buf_packets,
632                                unsigned int max_packet_size, int irq)
633         : IsoHandler(port, buf_packets,max_packet_size,irq)
634 {
635     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
636
637 }
638 IsoRecvHandler::~IsoRecvHandler()
639 {
640 // Don't call until libraw1394's raw1394_new_handle() function has been
641 // fixed to correctly initialise the iso_packet_infos field.  Bug is
642 // confirmed present in libraw1394 1.2.1.  In any case,
643 // raw1394_destroy_handle() (in the base class destructor) will do any iso
644 // system shutdown required.
645     raw1394_iso_shutdown(m_handle);
646
647 }
648
649 bool
650 IsoRecvHandler::initialize() {
651     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
652
653     IsoHandler *base=static_cast<IsoHandler *>(this);
654
655     if(!(base->initialize())) {
656         return false;
657     }
658
659     raw1394_set_userdata(m_handle, static_cast<void *>(this));
660
661     if(raw1394_iso_multichannel_recv_init(m_handle,
662                                          iso_receive_handler,
663                                          m_buf_packets,
664                                          m_max_packet_size,
665                                          m_irq_interval)) {
666         debugFatal("Could not do multichannel receive initialisation!\n" );
667
668         return false;
669     }
670
671     return true;
672
673 }
674
675 enum raw1394_iso_disposition IsoRecvHandler::putPacket(unsigned char *data, unsigned int length,
676                       unsigned char channel, unsigned char tag, unsigned char sy,
677                       unsigned int cycle, unsigned int dropped) {
678
679     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
680                  "received packet: length=%d, channel=%d, cycle=%d\n",
681                  length, channel, cycle );
682
683     return RAW1394_ISO_OK;
684 }
685
686 // an recv handler can have multiple destination IsoStreams
687 // NOTE: this implementation even allows for already registered
688 // streams to be registered again.
689 int IsoRecvHandler::registerStream(IsoRecvStream *stream)
690 {
691     assert(stream);
692     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
693
694     m_Clients.push_back(stream);
695
696     listen(stream->getChannel());
697     return 0;
698
699 }
700
701 int IsoRecvHandler::unregisterStream(IsoRecvStream *stream)
702 {
703     assert(stream);
704     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
705
706     for ( IsoRecvStreamVectorIterator it = m_Clients.begin();
707           it != m_Clients.end();
708           ++it )
709     {
710         IsoRecvStream* s = *it;
711         if ( s == stream ) {
712             unListen(s->getChannel());
713             m_Clients.erase(it);
714             return 0;
715         }
716     }
717
718     return -1; //not found
719
720 }
721
722 void IsoRecvHandler::listen(int channel) {
723     int retval;
724     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
725
726     retval=raw1394_iso_recv_listen_channel(m_handle, channel);
727
728 }
729
730 void IsoRecvHandler::unListen(int channel) {
731     int retval;
732     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
733
734     retval=raw1394_iso_recv_unlisten_channel(m_handle, channel);
735
736 }
737
738 int IsoRecvHandler::start(int cycle)
739 {
740     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
741     return raw1394_iso_recv_start(m_handle, cycle, -1, 0);
742 }
743 #endif
Note: See TracBrowser for help on using the browser.