root/trunk/freebob/src/ieee1394service.cpp

Revision 26, 19.9 kB (checked in by pieterpalmers, 19 years ago)

- Added subunit abstraction classes
- Implemented Audio & Music subunit detection in the AvDevice?
- Changed the debugPrint routine to be able to control debug output more granulary:

Debug output is now printed based upon the presence of a certain bit-flag.

- Various fixes

  • 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 #if 0   // the commented out code enables some tests of the several decriptor/infoblock classes
164                         debugPrint (DEBUG_LEVEL_INFO, "   Init successfull...\n");
165                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvDescriptor...\n");
166                         AvDescriptor *testdesc=new AvDescriptor(test,AVC1394_SUBUNIT_TYPE_MUSIC | AVC1394_SUBUNIT_ID_0,0x00);
167                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
168                         debugPrint (DEBUG_LEVEL_INFO, "    Opening...\n");
169                         testdesc->OpenReadOnly();
170                        
171                         debugPrint (DEBUG_LEVEL_INFO, "    Loading...\n");
172
173                         testdesc->Load();
174                                                
175                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create another AvDescriptor...\n");
176                         AvDescriptor *testdesc2=new AvDescriptor(test,AVC1394_SUBUNIT_TYPE_MUSIC | AVC1394_SUBUNIT_ID_0,0x80);
177                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
178                         debugPrint (DEBUG_LEVEL_INFO, "    Opening...\n");
179                         testdesc2->OpenReadOnly();
180                        
181                         debugPrint (DEBUG_LEVEL_INFO, "    Loading...\n");
182
183                         testdesc2->Load();
184                        
185                         unsigned char *buff=new unsigned char[testdesc->getLength()];
186                        
187                         testdesc->readBuffer(0,testdesc->getLength(),buff);
188                         debugPrint (DEBUG_LEVEL_INFO, "    AvDescriptor 1 Contents:\n");
189                        
190                         hexDump(buff,testdesc->getLength());
191                        
192                         delete buff;
193                        
194                         buff=new unsigned char[testdesc2->getLength()];
195                        
196                         testdesc2->readBuffer(0,testdesc2->getLength(),buff);
197                        
198                         debugPrint (DEBUG_LEVEL_INFO, "    AvDescriptor 2 Contents:\n");
199                         hexDump(buff,testdesc2->getLength());
200                         delete buff;
201                        
202                        
203                         debugPrint (DEBUG_LEVEL_INFO, "    Closing AvDescriptors...\n");
204
205                         testdesc->Close();
206                         testdesc2->Close();
207                        
208                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvDescriptors...\n");
209
210                         delete testdesc;
211                         delete testdesc2;
212                        
213                         // test the AvMusicIdentifierDescriptor
214                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvMusicIdentifierDescriptor...\n");
215                         AvMusicIdentifierDescriptor *testdesc_mid=new AvMusicIdentifierDescriptor(test,0x00);
216                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
217                         testdesc_mid->printCapabilities();
218                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvMusicIdentifierDescriptor...\n");
219                         delete testdesc_mid;
220                        
221                         // test the AvMusicStatusDescriptor
222                         debugPrint (DEBUG_LEVEL_INFO, "   Trying to create an AvMusicStatusDescriptor...\n");
223                         AvMusicStatusDescriptor *testdesc_mid2=new AvMusicStatusDescriptor(test,0x00);
224                         debugPrint (DEBUG_LEVEL_INFO, "    Created...\n");
225                         testdesc_mid2->printCapabilities();
226                        
227                         // test the AvInfoBlock
228                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvInfoBlock...\n");
229                        
230                         AvInfoBlock *testblock1=new AvInfoBlock(testdesc_mid2,0);
231                         debugPrint (DEBUG_LEVEL_INFO, "      Length: 0x%04X (%d)  Type: 0x%04X\n",testblock1->getLength(),testblock1->getLength(),testblock1->getType());
232                        
233                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to fetch next block...\n");
234                         // PP: might be better to have something like AvInfoBlock::moveToNextBlock();
235                         AvInfoBlock *testblock2=new AvInfoBlock(testdesc_mid2,2+testblock1->getLength());
236                        
237                         debugPrint (DEBUG_LEVEL_INFO, "      Length: 0x%04X (%d)  Type: 0x%04X\n",testblock2->getLength(),testblock2->getLength(),testblock2->getType());
238                
239                         // test the general status info block
240                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvGeneralMusicStatusInfoBlock...\n");
241                         AvGeneralMusicInfoBlock *testblock3=new AvGeneralMusicInfoBlock(testdesc_mid2,0);
242                        
243                         // PP: the next tests could fail because of the difference in hardware.
244                         // these classes are intended to be used in the parser. I use hardcoded addresses in the test code,
245                         // instead of derived addresses based on the parent descriptors.
246                         // this is only intended to debug the base classes before using them in the parser.
247                        
248                        
249                         // this one should be valid (on my config)
250                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock3->isValid()?"yes":"no"));
251                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitBlocking? %s\n",(testblock3->canTransmitBlocking()?"yes":"no"));
252                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitNonblocking? %s\n",(testblock3->canTransmitNonblocking()?"yes":"no"));
253                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveBlocking? %s\n",(testblock3->canReceiveBlocking()?"yes":"no"));
254                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveNonblocking? %s\n",(testblock3->canReceiveNonblocking()?"yes":"no"));
255                        
256                         delete testblock3;
257                         // this one shouldn't be valid
258                         testblock3=new AvGeneralMusicInfoBlock(testdesc_mid2,2+testblock1->getLength());
259                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock3->isValid()?"yes":"no"));
260                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitBlocking? %s\n",(testblock3->canTransmitBlocking()?"yes":"no"));
261                         debugPrint (DEBUG_LEVEL_INFO, "      canTransmitNonblocking? %s\n",(testblock3->canTransmitNonblocking()?"yes":"no"));
262                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveBlocking? %s\n",(testblock3->canReceiveBlocking()?"yes":"no"));
263                         debugPrint (DEBUG_LEVEL_INFO, "      canReceiveNonblocking? %s\n",(testblock3->canReceiveNonblocking()?"yes":"no"));
264                        
265                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvAudioInfoBlock...\n");
266                        
267                         AvAudioInfoBlock *testblock4=new AvAudioInfoBlock(testdesc_mid2,0x01A);
268                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock4->isValid()?"yes":"no"));
269                         debugPrint (DEBUG_LEVEL_INFO, "      Length? 0x%04X (%d)\n",testblock4->getLength(),testblock4->getLength());
270                         debugPrint (DEBUG_LEVEL_INFO, "      streams: %d\n",testblock4->getNbStreams());
271                         debugPrint (DEBUG_LEVEL_INFO, "      Name: %s\n",testblock4->getName());
272                        
273                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvMidiInfoBlock...\n");
274
275                         AvMidiInfoBlock *testblock5=new AvMidiInfoBlock(testdesc_mid2,0x099);
276                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock5->isValid()?"yes":"no"));
277                         debugPrint (DEBUG_LEVEL_INFO, "      Length? 0x%04X (%d)\n",testblock5->getLength(),testblock5->getLength());
278                         unsigned int nb_midi_streams=testblock5->getNbStreams();
279                         debugPrint (DEBUG_LEVEL_INFO, "      streams: %d\n",nb_midi_streams);
280                         for (unsigned int i=0;i<nb_midi_streams;i++) {
281                                 debugPrint (DEBUG_LEVEL_INFO, "       stream %d name: %s\n",i,testblock5->getName(i));
282                         }
283                        
284                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvAudioSyncInfoBlock...\n");
285                         AvAudioSyncInfoBlock *testblock6=new AvAudioSyncInfoBlock(testdesc_mid2,0x0262);
286                         debugPrint (DEBUG_LEVEL_INFO, "     isValid? %s\n",(testblock6->isValid()?"yes":"no"));
287                         debugPrint (DEBUG_LEVEL_INFO, "      canSyncBus? %s\n",(testblock6->canSyncBus()?"yes":"no"));
288                         debugPrint (DEBUG_LEVEL_INFO, "      canSyncExternal? %s\n",(testblock6->canSyncExternal()?"yes":"no"));
289                        
290                        
291                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvInfoBlocks...\n");
292                        
293                         delete testblock1;
294                         delete testblock2;
295                         delete testblock3;
296                         delete testblock4;
297                         delete testblock5;
298                         delete testblock6;
299                        
300                         // now try to parse a full source plug entry
301                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvSourcePlugInfoBlock...\n");
302                         AvSourcePlugInfoBlock *testblock7=new AvSourcePlugInfoBlock(testdesc_mid2,0x13);
303                        
304                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvSourcePlugInfoBlock...\n");
305                        
306                         delete testblock7;
307                        
308                         // now try to parse the full music output plug status infoblock
309                         debugPrint (DEBUG_LEVEL_INFO, "    Trying to create an AvOutputPlugStatusInfoBlock...\n");
310                         AvOutputPlugStatusInfoBlock *testblock8=new AvOutputPlugStatusInfoBlock(testdesc_mid2,0x0C);
311                        
312                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvOutputPlugStatusInfoBlock...\n");
313                        
314                         delete testblock8;
315                         debugPrint (DEBUG_LEVEL_INFO, "    Deleting AvMusicStatusDescriptor...\n");
316                         delete testdesc_mid2;                   
317 #endif                 
318                 }
319                 debugPrint (DEBUG_LEVEL_INFO, "   Deleting AvDevice...\n");
320                 delete test;
321
322             }
323             break;
324         case ROM1394_NODE_TYPE_SBP2:
325             debugPrint( DEBUG_LEVEL_INFO,
326                         "Node %d has node type SBP2\n", iNodeId);
327             break;
328         case ROM1394_NODE_TYPE_CPU:
329             debugPrint( DEBUG_LEVEL_INFO,
330                         "Node %d has node type CPU\n", iNodeId);
331             break;
332         default:
333             debugPrint( DEBUG_LEVEL_INFO,
334                         "No matching node type found for node %d\n", iNodeId);
335         }
336     }
337     return eFBRC_Success;
338 }
339
340 void
341 Ieee1394Service::printAvcUnitInfo( int iNodeId )
342 {
343     printf( "AVC: video monitor?......%s\n",
344             avc1394_check_subunit_type( m_handle, iNodeId,
345                                         AVC1394_SUBUNIT_TYPE_VIDEO_MONITOR ) ?
346             "yes":"no" );
347     printf( "AVC: audio?..............%s\n",
348             avc1394_check_subunit_type( m_handle, iNodeId,
349                                         AVC1394_SUBUNIT_TYPE_AUDIO ) ?
350             "yes":"no" );
351     printf( "AVC; printer?............%s\n",
352             avc1394_check_subunit_type( m_handle, iNodeId,
353                                         AVC1394_SUBUNIT_TYPE_PRINTER ) ?
354             "yes":"no" );
355     printf( "AVC: disk recorder?......%s\n",
356             avc1394_check_subunit_type( m_handle, iNodeId,
357                                         AVC1394_SUBUNIT_TYPE_DISC_RECORDER ) ?
358             "yes":"no" );
359     printf( "AVC: video recorder?.....%s\n",
360             avc1394_check_subunit_type( m_handle, iNodeId,
361                                         AVC1394_SUBUNIT_TYPE_TAPE_RECORDER ) ?
362             "yes":"no" );
363     printf( "AVC: vcr?................%s\n",
364             avc1394_check_subunit_type( m_handle, iNodeId,
365                                         AVC1394_SUBUNIT_TYPE_VCR ) ?
366             "yes":"no" );
367     printf( "AVC: tuner?..............%s\n",
368             avc1394_check_subunit_type( m_handle, iNodeId,
369                                         AVC1394_SUBUNIT_TYPE_TUNER ) ?
370             "yes":"no" );
371     printf( "AVC: CA?.................%s\n",
372             avc1394_check_subunit_type( m_handle, iNodeId,
373                                         AVC1394_SUBUNIT_TYPE_CA ) ?
374             "yes":"no" );
375     printf( "AVC: video camera?.......%s\n",
376             avc1394_check_subunit_type( m_handle, iNodeId,
377                                         AVC1394_SUBUNIT_TYPE_VIDEO_CAMERA ) ?
378             "yes":"no" );
379     printf( "AVC: panel?..............%s\n",
380             avc1394_check_subunit_type(m_handle, iNodeId,
381                                         AVC1394_SUBUNIT_TYPE_PANEL ) ?
382             "yes":"no" );
383     printf( "AVC: camera storage?.....%s\n",
384             avc1394_check_subunit_type( m_handle, iNodeId,
385                                         AVC1394_SUBUNIT_TYPE_CAMERA_STORAGE ) ?
386             "yes":"no" );
387     printf( "AVC: bulletin board?.....%s\n",
388             avc1394_check_subunit_type( m_handle, iNodeId,
389                                         AVC1394_SUBUNIT_TYPE_BULLETIN_BOARD ) ?
390             "yes":"no" );
391     printf( "AVC: vendor specific?....%s\n",
392             avc1394_check_subunit_type( m_handle, iNodeId,
393                                         AVC1394_SUBUNIT_TYPE_VENDOR_UNIQUE ) ?
394             "yes":"no" );
395     printf( "AVC: extended?...........%s\n",
396             avc1394_check_subunit_type( m_handle, iNodeId,
397                                         AVC1394_SUBUNIT_TYPE_EXTENDED ) ?
398             "yes":"no" );
399     printf( "AVC: unit?...............%s\n",
400             avc1394_check_subunit_type( m_handle, iNodeId,
401                                         AVC1394_SUBUNIT_TYPE_UNIT ) ?
402             "yes":"no" );
403     printf( "AVC: music?..............%s\n",
404             avc1394_check_subunit_type( m_handle, iNodeId,
405                                         AVC1394_SUBUNIT_TYPE_MUSIC ) ?
406             "yes":"no" );
407 }
408
409 void
410 Ieee1394Service::printRomDirectory( int iNodeId,  rom1394_directory* pRomDir )
411 {
412     int iBusInfoBlockLength
413         = rom1394_get_bus_info_block_length( m_handle,  iNodeId );
414     int iBusId = rom1394_get_bus_id( m_handle,  iNodeId );
415     octlet_t oGuid = rom1394_get_guid( m_handle, iNodeId );
416     rom1394_bus_options busOptions;
417     rom1394_get_bus_options( m_handle, iNodeId, &busOptions );
418
419     printf( "\nNode %d: \n", iNodeId );
420     printf( "-------------------------------------------------\n" );
421     printf( "bus info block length = %d\n", iBusInfoBlockLength);
422     printf( "bus id = 0x%08x\n", iBusId );
423     printf( "bus options:\n" );
424     printf( "    isochronous resource manager capable: %d\n", busOptions.irmc );
425     printf ("    cycle master capable                : %d\n", busOptions.cmc );
426     printf ("    isochronous capable                 : %d\n", busOptions.isc );
427     printf ("    bus manager capable                 : %d\n", busOptions.bmc );
428     printf ("    cycle master clock accuracy         : %d ppm\n", busOptions.cyc_clk_acc );
429     printf( "    maximum asynchronous record size    : %d bytes\n", busOptions.max_rec );
430     printf("GUID: 0x%08x%08x\n", (quadlet_t) (oGuid>>32),
431            (quadlet_t) (oGuid & 0xffffffff) );
432     printf( "directory:\n");
433     printf( "    node capabilities    : 0x%08x\n", pRomDir->node_capabilities );
434     printf( "    vendor id            : 0x%08x\n", pRomDir->vendor_id );
435     printf( "    unit spec id         : 0x%08x\n", pRomDir->unit_spec_id );
436     printf( "    unit software version: 0x%08x\n", pRomDir->unit_sw_version );
437     printf( "    model id             : 0x%08x\n", pRomDir->model_id );
438     printf( "    textual leaves       : %s\n",     pRomDir->label );
439 }
440
441 int
442 Ieee1394Service::resetHandler( raw1394handle_t handle,
443                                unsigned int iGeneration )
444 {
445     debugPrint( DEBUG_LEVEL_INFO,
446                 "Bus reset has occurred (generation = %d).\n", iGeneration );
447     raw1394_update_generation (handle, iGeneration);
448     Ieee1394Service* pInstance
449         = (Ieee1394Service*) raw1394_get_userdata (handle);
450     pInstance->setGenerationCount( iGeneration );
451     return 0;
452 }
453
454 bool
455 Ieee1394Service::startRHThread()
456 {
457     if ( m_bRHThreadRunning ) {
458         return true;
459     }
460     debugPrint( DEBUG_LEVEL_INFO,
461                 "Starting bus reset handler thread.\n" );
462     pthread_mutex_lock( &m_mutex );
463     pthread_create( &m_thread, NULL, rHThread, this );
464     pthread_mutex_unlock( &m_mutex );
465     m_bRHThreadRunning = true;
466     return true;
467 }
468
469 void
470 Ieee1394Service::stopRHThread()
471 {
472     if ( m_bRHThreadRunning ) {
473         debugPrint( DEBUG_LEVEL_INFO,
474                     "Stopping bus reset handler thread.\n" );
475         pthread_mutex_lock (&m_mutex);
476         pthread_cancel (m_thread);
477         pthread_join (m_thread, NULL);
478         pthread_mutex_unlock (&m_mutex);
479     }
480     m_bRHThreadRunning = false;
481 }
482
483 void*
484 Ieee1394Service::rHThread( void* arg )
485 {
486     Ieee1394Service* pIeee1394Service = (Ieee1394Service*) arg;
487
488     while (true) {
489         raw1394_loop_iterate (pIeee1394Service->m_rhHandle);
490         pthread_testcancel ();
491     }
492
493     return NULL;
494 }
495
496 void
497 Ieee1394Service::setGenerationCount( unsigned int iGeneration )
498 {
499     m_iGenerationCount = iGeneration;
500 }
501
502 unsigned int
503 Ieee1394Service::getGenerationCount()
504 {
505     return m_iGenerationCount;
506 }
Note: See TracBrowser for help on using the browser.