root/trunk/freebob/src/ieee1394service.cpp

Revision 24, 19.8 kB (checked in by pieterpalmers, 19 years ago)

- bugfix: descriptor was not read correctly in AvDescriptor?
- several other small bugfixes/cleanups
- fix compiler warnings
- added some extra debug statements to follow parser flow

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* ieee1394service.cpp
2  * Copyright (C) 2004 by Daniel Wagner
3  *
4  * This file is part of FreeBob.
5  *
6  * FreeBob is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBob is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBob; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include <errno.h>
22 #include <libavc1394/avc1394.h>
23 #include <libavc1394/avc1394_vcr.h>
24 #include "ieee1394service.h"
25 #include "debugmodule.h"
26
27 #include "avdevice.h"
28 #include "avdescriptor.h"
29 #include "avmusicidentifierdescriptor.h"
30 #include "avmusicstatusdescriptor.h"
31 #include "avinfoblock.h"
32 #include "avgeneralmusicstatusinfoblock.h"
33 #include "avnameinfoblock.h"
34 #include "avaudioinfoblock.h"
35 #include "avmidiinfoblock.h"
36 #include "avaudiosyncinfoblock.h"
37 #include "avsourcepluginfoblock.h"
38 #include "avoutputplugstatusinfoblock.h"
39
40 Ieee1394Service* Ieee1394Service::m_pInstance = 0;
41
42 Ieee1394Service::Ieee1394Service()
43     : m_iPort( 0 )
44     , m_bInitialised( false )
45     , m_bRHThreadRunning( false )
46     , m_iGenerationCount( 0 )
47 {
48     pthread_mutex_init( &m_mutex, NULL );
49 }
50
51 Ieee1394Service::~Ieee1394Service()
52 {
53     stopRHThread();
54
55     if ( m_rhHandle ) {
56         raw1394_destroy_handle( m_rhHandle );
57         m_rhHandle = 0;
58     }
59
60     if ( m_handle ) {
61         raw1394_destroy_handle( m_handle );
62         m_handle = 0;
63     }
64
65     m_pInstance = 0;
66 }
67
68 FBReturnCodes
69 Ieee1394Service::initialize()
70 {
71     if ( !m_bInitialised ) {
72         m_rhHandle = raw1394_new_handle();
73         m_handle = raw1394_new_handle();
74         if ( !m_rhHandle || !m_handle ) {
75             if ( !errno ) {
76                 fprintf( stderr,  "libraw1394 not compatible.\n" );
77             } else {
78                 perror ("Could not get 1394 handle");
79                 fprintf (stderr, "Is ieee1394 and raw1394 driver loaded?\n");
80             }
81             return eFBRC_Creating1394HandleFailed;
82         }
83
84         // Store this instance in the user data pointer, in order
85         // to be able to retrieve the instance in the pure C bus reset
86         // call back function.
87         raw1394_set_userdata( m_rhHandle,  this );
88
89         if ( raw1394_set_port( m_rhHandle,  m_iPort ) < 0 ) {
90             perror( "Could not set port" );
91             return eFBRC_Setting1394PortFailed;
92         }
93
94         if ( raw1394_set_port( m_handle,  m_iPort ) < 0 ) {
95             perror( "Could not set port" );
96             return eFBRC_Setting1394PortFailed;
97         }
98
99         raw1394_set_bus_reset_handler( m_rhHandle,  this->resetHandler );
100
101         startRHThread();
102
103         discoveryDevices();
104         m_bInitialised = true;
105     }
106     return eFBRC_Success;
107 }
108
109 void
110 Ieee1394Service::shutdown()
111 {
112     delete this;
113 }
114
115 Ieee1394Service*
116 Ieee1394Service::instance()
117 {
118     if ( !m_pInstance ) {
119         m_pInstance = new Ieee1394Service;
120     }
121     return m_pInstance;
122 }
123
124 FBReturnCodes
125 Ieee1394Service::discoveryDevices()
126 {
127     //scan bus
128     int iNodeCount = raw1394_get_nodecount( m_handle );
129     for ( int iNodeId = 0; iNodeId < iNodeCount; ++iNodeId ) {
130         rom1394_directory romDir;
131         rom1394_get_directory( m_handle, iNodeId, &romDir );
132         printRomDirectory( iNodeId, &romDir );
133
134         switch (rom1394_get_node_type( &romDir )) {
135         case ROM1394_NODE_TYPE_UNKNOWN:
136             debugPrint (DEBUG_LEVEL_INFO,
137                         "Node %d has node type UNKNOWN\n", iNodeId);
138             break;
139         case ROM1394_NODE_TYPE_DC:
140             debugPrint (DEBUG_LEVEL_INFO,
141                         "Node %d has node type DC\n", iNodeId);
142             break;
143         case ROM1394_NODE_TYPE_AVC:
144             debugPrint (DEBUG_LEVEL_INFO,
145                         "Node %d has node type AVC\n", iNodeId);
146             printAvcUnitInfo( iNodeId );
147
148             if ( avc1394_check_subunit_type( m_handle, iNodeId,
149                                              AVC1394_SUBUNIT_TYPE_AUDIO ) ) {
150
151                 // XXX
152                 // create avcDevice which discovers itself :)
153
154                 // PP: just a static try, don't want to mess with the device manager yet...
155                 // Remark: the AvDevice and AvDescriptor aren't debugged thouroughly yet!
156                 //         the following code is the only debug I had time for... to be continued! (later this week)
157                 debugPrint (DEBUG_LEVEL_INFO, "  Trying to create an AvDevice...\n");
158
159                 AvDevice *test=new AvDevice(m_iPort, iNodeId);
160                 debugPrint (DEBUG_LEVEL_INFO, "   Created...\n");
161                 test->Initialize();
162                 if (test->isInitialised()) {
163                         debugPrint (DEBUG_LEVEL_INFO, "   Init successfull...\n");
164                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvDescriptor...\n");
165                         AvDescriptor *testdesc=new AvDescriptor(test,AVC1394_SUBUNIT_TYPE_MUSIC | AVC1394_SUBUNIT_ID_0,0x00);
166                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
167                         debugPrint (DEBUG_LEVEL_INFO, "    Opening...\n");
168                         testdesc->OpenReadOnly();
169                        
170                         debugPrint (DEBUG_LEVEL_INFO, "    Loading...\n");
171
172                         testdesc->Load();
173                                                
174                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create another AvDescriptor...\n");
175                         AvDescriptor *testdesc2=new AvDescriptor(test,AVC1394_SUBUNIT_TYPE_MUSIC | AVC1394_SUBUNIT_ID_0,0x80);
176                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
177                         debugPrint (DEBUG_LEVEL_INFO, "    Opening...\n");
178                         testdesc2->OpenReadOnly();
179                        
180                         debugPrint (DEBUG_LEVEL_INFO, "    Loading...\n");
181
182                         testdesc2->Load();
183                        
184                         unsigned char *buff=new unsigned char[testdesc->getLength()];
185                        
186                         testdesc->readBuffer(0,testdesc->getLength(),buff);
187                         debugPrint (DEBUG_LEVEL_INFO, "    AvDescriptor 1 Contents:\n");
188                        
189                         hexDump(buff,testdesc->getLength());
190                        
191                         delete buff;
192                        
193                         buff=new unsigned char[testdesc2->getLength()];
194                        
195                         testdesc2->readBuffer(0,testdesc2->getLength(),buff);
196                        
197                         debugPrint (DEBUG_LEVEL_INFO, "    AvDescriptor 2 Contents:\n");
198                         hexDump(buff,testdesc2->getLength());
199                         delete buff;
200                        
201                        
202                         debugPrint (DEBUG_LEVEL_INFO, "    Closing AvDescriptors...\n");
203
204                         testdesc->Close();
205                         testdesc2->Close();
206                        
207                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvDescriptors...\n");
208
209                         delete testdesc;
210                         delete testdesc2;
211                        
212                         // test the AvMusicIdentifierDescriptor
213                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvMusicIdentifierDescriptor...\n");
214                         AvMusicIdentifierDescriptor *testdesc_mid=new AvMusicIdentifierDescriptor(test);
215                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
216                         testdesc_mid->printCapabilities();
217                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvMusicIdentifierDescriptor...\n");
218                         delete testdesc_mid;
219                        
220                         // test the AvMusicStatusDescriptor
221                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvMusicStatusDescriptor...\n");
222                         AvMusicStatusDescriptor *testdesc_mid2=new AvMusicStatusDescriptor(test);
223                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
224                         testdesc_mid2->printCapabilities();
225                        
226                         // test the AvInfoBlock
227                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvInfoBlock...\n");
228                        
229                         AvInfoBlock *testblock1=new AvInfoBlock(testdesc_mid2,0);
230                         debugPrint (DEBUG_LEVEL_INFO, "      Length: 0x%04X (%d)  Type: 0x%04X\n",testblock1->getLength(),testblock1->getLength(),testblock1->getType());
231                        
232                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to fetch next block...\n");
233                         // PP: might be better to have something like AvInfoBlock::moveToNextBlock();
234                         AvInfoBlock *testblock2=new AvInfoBlock(testdesc_mid2,2+testblock1->getLength());
235                        
236                         debugPrint (DEBUG_LEVEL_INFO, "      Length: 0x%04X (%d)  Type: 0x%04X\n",testblock2->getLength(),testblock2->getLength(),testblock2->getType());
237                
238                         // test the general status info block
239                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvGeneralMusicStatusInfoBlock...\n");
240                         AvGeneralMusicInfoBlock *testblock3=new AvGeneralMusicInfoBlock(testdesc_mid2,0);
241                        
242                         // PP: the next tests could fail because of the difference in hardware.
243                         // these classes are intended to be used in the parser. I use hardcoded addresses in the test code,
244                         // instead of derived addresses based on the parent descriptors.
245                         // this is only intended to debug the base classes before using them in the parser.
246                        
247                        
248                         // this one should be valid (on my config)
249                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock3->isValid()?"yes":"no"));
250                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitBlocking? %s\n",(testblock3->canTransmitBlocking()?"yes":"no"));
251                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitNonblocking? %s\n",(testblock3->canTransmitNonblocking()?"yes":"no"));
252                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveBlocking? %s\n",(testblock3->canReceiveBlocking()?"yes":"no"));
253                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveNonblocking? %s\n",(testblock3->canReceiveNonblocking()?"yes":"no"));
254                        
255                         delete testblock3;
256                         // this one shouldn't be valid
257                         testblock3=new AvGeneralMusicInfoBlock(testdesc_mid2,2+testblock1->getLength());
258                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock3->isValid()?"yes":"no"));
259                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitBlocking? %s\n",(testblock3->canTransmitBlocking()?"yes":"no"));
260                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitNonblocking? %s\n",(testblock3->canTransmitNonblocking()?"yes":"no"));
261                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveBlocking? %s\n",(testblock3->canReceiveBlocking()?"yes":"no"));
262                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveNonblocking? %s\n",(testblock3->canReceiveNonblocking()?"yes":"no"));
263                        
264                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvAudioInfoBlock...\n");
265                        
266                         AvAudioInfoBlock *testblock4=new AvAudioInfoBlock(testdesc_mid2,0x01A);
267                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock4->isValid()?"yes":"no"));
268                         debugPrint (DEBUG_LEVEL_INFO, "      Length? 0x%04X (%d)\n",testblock4->getLength(),testblock4->getLength());
269                         debugPrint (DEBUG_LEVEL_INFO, "      streams: %d\n",testblock4->getNbStreams());
270                         debugPrint (DEBUG_LEVEL_INFO, "      Name: %s\n",testblock4->getName());
271                        
272                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvMidiInfoBlock...\n");
273
274                         AvMidiInfoBlock *testblock5=new AvMidiInfoBlock(testdesc_mid2,0x099);
275                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock5->isValid()?"yes":"no"));
276                         debugPrint (DEBUG_LEVEL_INFO, "      Length? 0x%04X (%d)\n",testblock5->getLength(),testblock5->getLength());
277                         unsigned int nb_midi_streams=testblock5->getNbStreams();
278                         debugPrint (DEBUG_LEVEL_INFO, "      streams: %d\n",nb_midi_streams);
279                         for (unsigned int i=0;i<nb_midi_streams;i++) {
280                                 debugPrint (DEBUG_LEVEL_INFO, "       stream %d name: %s\n",i,testblock5->getName(i));
281                         }
282                        
283                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvAudioSyncInfoBlock...\n");
284                         AvAudioSyncInfoBlock *testblock6=new AvAudioSyncInfoBlock(testdesc_mid2,0x0262);
285                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock6->isValid()?"yes":"no"));
286                         debugPrint (DEBUG_LEVEL_INFO, "      canSyncBus? %s\n",(testblock6->canSyncBus()?"yes":"no"));
287                         debugPrint (DEBUG_LEVEL_INFO, "      canSyncExternal? %s\n",(testblock6->canSyncExternal()?"yes":"no"));
288                        
289                        
290                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvInfoBlocks...\n");
291                        
292                         delete testblock1;
293                         delete testblock2;
294                         delete testblock3;
295                         delete testblock4;
296                         delete testblock5;
297                         delete testblock6;
298                        
299                         // now try to parse a full source plug entry
300                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvSourcePlugInfoBlock...\n");
301                         AvSourcePlugInfoBlock *testblock7=new AvSourcePlugInfoBlock(testdesc_mid2,0x13);
302                        
303                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvSourcePlugInfoBlock...\n");
304                        
305                         delete testblock7;
306                        
307                         // now try to parse the full music output plug status infoblock
308                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvOutputPlugStatusInfoBlock...\n");
309                         AvOutputPlugStatusInfoBlock *testblock8=new AvOutputPlugStatusInfoBlock(testdesc_mid2,0x0C);
310                        
311                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvOutputPlugStatusInfoBlock...\n");
312                        
313                         delete testblock8;
314                        
315                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvMusicStatusDescriptor...\n");
316                         delete testdesc_mid2;                   
317                 }
318                 debugPrint (DEBUG_LEVEL_INFO, "   Deleting AvDevice...\n");
319                 delete test;
320
321             }
322             break;
323         case ROM1394_NODE_TYPE_SBP2:
324             debugPrint( DEBUG_LEVEL_INFO,
325                         "Node %d has node type SBP2\n", iNodeId);
326             break;
327         case ROM1394_NODE_TYPE_CPU:
328             debugPrint( DEBUG_LEVEL_INFO,
329                         "Node %d has node type CPU\n", iNodeId);
330             break;
331         default:
332             debugPrint( DEBUG_LEVEL_INFO,
333                         "No matching node type found for node %d\n", iNodeId);
334         }
335     }
336     return eFBRC_Success;
337 }
338
339 void
340 Ieee1394Service::printAvcUnitInfo( int iNodeId )
341 {
342     printf( "AVC: video monitor?......%s\n",
343             avc1394_check_subunit_type( m_handle, iNodeId,
344                                         AVC1394_SUBUNIT_TYPE_VIDEO_MONITOR ) ?
345             "yes":"no" );
346     printf( "AVC: audio?..............%s\n",
347             avc1394_check_subunit_type( m_handle, iNodeId,
348                                         AVC1394_SUBUNIT_TYPE_AUDIO ) ?
349             "yes":"no" );
350     printf( "AVC; printer?............%s\n",
351             avc1394_check_subunit_type( m_handle, iNodeId,
352                                         AVC1394_SUBUNIT_TYPE_PRINTER ) ?
353             "yes":"no" );
354     printf( "AVC: disk recorder?......%s\n",
355             avc1394_check_subunit_type( m_handle, iNodeId,
356                                         AVC1394_SUBUNIT_TYPE_DISC_RECORDER ) ?
357             "yes":"no" );
358     printf( "AVC: video recorder?.....%s\n",
359             avc1394_check_subunit_type( m_handle, iNodeId,
360                                         AVC1394_SUBUNIT_TYPE_TAPE_RECORDER ) ?
361             "yes":"no" );
362     printf( "AVC: vcr?................%s\n",
363             avc1394_check_subunit_type( m_handle, iNodeId,
364                                         AVC1394_SUBUNIT_TYPE_VCR ) ?
365             "yes":"no" );
366     printf( "AVC: tuner?..............%s\n",
367             avc1394_check_subunit_type( m_handle, iNodeId,
368                                         AVC1394_SUBUNIT_TYPE_TUNER ) ?
369             "yes":"no" );
370     printf( "AVC: CA?.................%s\n",
371             avc1394_check_subunit_type( m_handle, iNodeId,
372                                         AVC1394_SUBUNIT_TYPE_CA ) ?
373             "yes":"no" );
374     printf( "AVC: video camera?.......%s\n",
375             avc1394_check_subunit_type( m_handle, iNodeId,
376                                         AVC1394_SUBUNIT_TYPE_VIDEO_CAMERA ) ?
377             "yes":"no" );
378     printf( "AVC: panel?..............%s\n",
379             avc1394_check_subunit_type(m_handle, iNodeId,
380                                         AVC1394_SUBUNIT_TYPE_PANEL ) ?
381             "yes":"no" );
382     printf( "AVC: camera storage?.....%s\n",
383             avc1394_check_subunit_type( m_handle, iNodeId,
384                                         AVC1394_SUBUNIT_TYPE_CAMERA_STORAGE ) ?
385             "yes":"no" );
386     printf( "AVC: bulletin board?.....%s\n",
387             avc1394_check_subunit_type( m_handle, iNodeId,
388                                         AVC1394_SUBUNIT_TYPE_BULLETIN_BOARD ) ?
389             "yes":"no" );
390     printf( "AVC: vendor specific?....%s\n",
391             avc1394_check_subunit_type( m_handle, iNodeId,
392                                         AVC1394_SUBUNIT_TYPE_VENDOR_UNIQUE ) ?
393             "yes":"no" );
394     printf( "AVC: extended?...........%s\n",
395             avc1394_check_subunit_type( m_handle, iNodeId,
396                                         AVC1394_SUBUNIT_TYPE_EXTENDED ) ?
397             "yes":"no" );
398     printf( "AVC: unit?...............%s\n",
399             avc1394_check_subunit_type( m_handle, iNodeId,
400                                         AVC1394_SUBUNIT_TYPE_UNIT ) ?
401             "yes":"no" );
402     printf( "AVC: music?..............%s\n",
403             avc1394_check_subunit_type( m_handle, iNodeId,
404                                         AVC1394_SUBUNIT_TYPE_MUSIC ) ?
405             "yes":"no" );
406 }
407
408 void
409 Ieee1394Service::printRomDirectory( int iNodeId,  rom1394_directory* pRomDir )
410 {
411     int iBusInfoBlockLength
412         = rom1394_get_bus_info_block_length( m_handle,  iNodeId );
413     int iBusId = rom1394_get_bus_id( m_handle,  iNodeId );
414     octlet_t oGuid = rom1394_get_guid( m_handle, iNodeId );
415     rom1394_bus_options busOptions;
416     rom1394_get_bus_options( m_handle, iNodeId, &busOptions );
417
418     printf( "\nNode %d: \n", iNodeId );
419     printf( "-------------------------------------------------\n" );
420     printf( "bus info block length = %d\n", iBusInfoBlockLength);
421     printf( "bus id = 0x%08x\n", iBusId );
422     printf( "bus options:\n" );
423     printf( "    isochronous resource manager capable: %d\n", busOptions.irmc );
424     printf ("    cycle master capable                : %d\n", busOptions.cmc );
425     printf ("    isochronous capable                 : %d\n", busOptions.isc );
426     printf ("    bus manager capable                 : %d\n", busOptions.bmc );
427     printf ("    cycle master clock accuracy         : %d ppm\n", busOptions.cyc_clk_acc );
428     printf( "    maximum asynchronous record size    : %d bytes\n", busOptions.max_rec );
429     printf("GUID: 0x%08x%08x\n", (quadlet_t) (oGuid>>32),
430            (quadlet_t) (oGuid & 0xffffffff) );
431     printf( "directory:\n");
432     printf( "    node capabilities    : 0x%08x\n", pRomDir->node_capabilities );
433     printf( "    vendor id            : 0x%08x\n", pRomDir->vendor_id );
434     printf( "    unit spec id         : 0x%08x\n", pRomDir->unit_spec_id );
435     printf( "    unit software version: 0x%08x\n", pRomDir->unit_sw_version );
436     printf( "    model id             : 0x%08x\n", pRomDir->model_id );
437     printf( "    textual leaves       : %s\n",     pRomDir->label );
438 }
439
440 int
441 Ieee1394Service::resetHandler( raw1394handle_t handle,
442                                unsigned int iGeneration )
443 {
444     debugPrint( DEBUG_LEVEL_INFO,
445                 "Bus reset has occurred (generation = %d).\n", iGeneration );
446     raw1394_update_generation (handle, iGeneration);
447     Ieee1394Service* pInstance
448         = (Ieee1394Service*) raw1394_get_userdata (handle);
449     pInstance->setGenerationCount( iGeneration );
450     return 0;
451 }
452
453 bool
454 Ieee1394Service::startRHThread()
455 {
456     if ( m_bRHThreadRunning ) {
457         return true;
458     }
459     debugPrint( DEBUG_LEVEL_INFO,
460                 "Starting bus reset handler thread.\n" );
461     pthread_mutex_lock( &m_mutex );
462     pthread_create( &m_thread, NULL, rHThread, this );
463     pthread_mutex_unlock( &m_mutex );
464     m_bRHThreadRunning = true;
465     return true;
466 }
467
468 void
469 Ieee1394Service::stopRHThread()
470 {
471     if ( m_bRHThreadRunning ) {
472         debugPrint( DEBUG_LEVEL_INFO,
473                     "Stopping bus reset handler thread.\n" );
474         pthread_mutex_lock (&m_mutex);
475         pthread_cancel (m_thread);
476         pthread_join (m_thread, NULL);
477         pthread_mutex_unlock (&m_mutex);
478     }
479     m_bRHThreadRunning = false;
480 }
481
482 void*
483 Ieee1394Service::rHThread( void* arg )
484 {
485     Ieee1394Service* pIeee1394Service = (Ieee1394Service*) arg;
486
487     while (true) {
488         raw1394_loop_iterate (pIeee1394Service->m_rhHandle);
489         pthread_testcancel ();
490     }
491
492     return NULL;
493 }
494
495 void
496 Ieee1394Service::setGenerationCount( unsigned int iGeneration )
497 {
498     m_iGenerationCount = iGeneration;
499 }
500
501 unsigned int
502 Ieee1394Service::getGenerationCount()
503 {
504     return m_iGenerationCount;
505 }
Note: See TracBrowser for help on using the browser.