root/trunk/freebob/src/ieee1394service.cpp

Revision 40, 12.5 kB (checked in by pieterpalmers, 19 years ago)

Added:
- Information retrieval functions for several infoblocks
- Status printing functions for several infoblocks
- debugPrintShort to print debug comments without leading context info
- optional ANSI colored output of debug commands (see debugmodule.h)
- optional colored HTML output of debug commands for e.g. printouts (see debugmodule.h)
- AvDeviceSubunit?->Reserve() / unReserve() / isReserved()
- AvDevice::[set|get][Input|Output]PlugSignalFormat? functions (incomplete)
- added preliminary detection of internal connections

Changed:
- removed a lot of obsolete test code from ieee1394service.cpp
- added some other test code to ieee1394service.cpp

Bugfixes:
- Corrected bug in AvClusterInfoBlock?. This originated from an error in the spec.

  • 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 <libiec61883/iec61883.h>
25
26
27 #include "ieee1394service.h"
28 #include "debugmodule.h"
29
30 #include "avdevice.h"
31 #include "avdescriptor.h"
32 #include "avmusicidentifierdescriptor.h"
33 #include "avmusicstatusdescriptor.h"
34 #include "avinfoblock.h"
35 #include "avgeneralmusicstatusinfoblock.h"
36 #include "avnameinfoblock.h"
37 #include "avaudioinfoblock.h"
38 #include "avmidiinfoblock.h"
39 #include "avaudiosyncinfoblock.h"
40 #include "avsourcepluginfoblock.h"
41 #include "avoutputplugstatusinfoblock.h"
42
43 Ieee1394Service* Ieee1394Service::m_pInstance = 0;
44
45 Ieee1394Service::Ieee1394Service()
46     : m_iPort( 0 )
47     , m_bInitialised( false )
48     , m_bRHThreadRunning( false )
49     , m_iGenerationCount( 0 )
50 {
51     pthread_mutex_init( &m_mutex, NULL );
52 }
53
54 Ieee1394Service::~Ieee1394Service()
55 {
56     stopRHThread();
57
58     if ( m_rhHandle ) {
59         raw1394_destroy_handle( m_rhHandle );
60         m_rhHandle = 0;
61     }
62
63     if ( m_handle ) {
64         raw1394_destroy_handle( m_handle );
65         m_handle = 0;
66     }
67
68     m_pInstance = 0;
69 }
70
71 FBReturnCodes
72 Ieee1394Service::initialize()
73 {
74     if ( !m_bInitialised ) {
75         m_rhHandle = raw1394_new_handle();
76         m_handle = raw1394_new_handle();
77         if ( !m_rhHandle || !m_handle ) {
78             if ( !errno ) {
79                 fprintf( stderr,  "libraw1394 not compatible.\n" );
80             } else {
81                 perror ("Could not get 1394 handle");
82                 fprintf (stderr, "Is ieee1394 and raw1394 driver loaded?\n");
83             }
84             return eFBRC_Creating1394HandleFailed;
85         }
86
87         // Store this instance in the user data pointer, in order
88         // to be able to retrieve the instance in the pure C bus reset
89         // call back function.
90         raw1394_set_userdata( m_rhHandle,  this );
91
92         if ( raw1394_set_port( m_rhHandle,  m_iPort ) < 0 ) {
93             perror( "Could not set port" );
94             return eFBRC_Setting1394PortFailed;
95         }
96
97         if ( raw1394_set_port( m_handle,  m_iPort ) < 0 ) {
98             perror( "Could not set port" );
99             return eFBRC_Setting1394PortFailed;
100         }
101
102         raw1394_set_bus_reset_handler( m_rhHandle,  this->resetHandler );
103
104         startRHThread();
105
106         discoveryDevices();
107         m_bInitialised = true;
108     }
109     return eFBRC_Success;
110 }
111
112 void
113 Ieee1394Service::shutdown()
114 {
115     delete this;
116 }
117
118 Ieee1394Service*
119 Ieee1394Service::instance()
120 {
121     if ( !m_pInstance ) {
122         m_pInstance = new Ieee1394Service;
123     }
124     return m_pInstance;
125 }
126
127 FBReturnCodes
128 Ieee1394Service::discoveryDevices()
129 {
130     //scan bus
131     int iNodeCount = raw1394_get_nodecount( m_handle );
132     for ( int iNodeId = 0; iNodeId < iNodeCount; ++iNodeId ) {
133         rom1394_directory romDir;
134         rom1394_get_directory( m_handle, iNodeId, &romDir );
135         printRomDirectory( iNodeId, &romDir );
136
137         switch (rom1394_get_node_type( &romDir )) {
138         case ROM1394_NODE_TYPE_UNKNOWN:
139             debugPrint (DEBUG_LEVEL_INFO,
140                         "Node %d has node type UNKNOWN\n", iNodeId);
141             break;
142         case ROM1394_NODE_TYPE_DC:
143             debugPrint (DEBUG_LEVEL_INFO,
144                         "Node %d has node type DC\n", iNodeId);
145             break;
146         case ROM1394_NODE_TYPE_AVC:
147             debugPrint (DEBUG_LEVEL_INFO,
148                         "Node %d has node type AVC\n", iNodeId);
149             printAvcUnitInfo( iNodeId );
150
151             if ( avc1394_check_subunit_type( m_handle, iNodeId,
152                                              AVC1394_SUBUNIT_TYPE_AUDIO ) ) {
153
154                 // XXX
155                 // create avcDevice which discovers itself :)
156
157                 // PP: just a static try, don't want to mess with the device manager yet...
158                 // Remark: the AvDevice and AvDescriptor aren't debugged thouroughly yet!
159                 //         the following code is the only debug I had time for... to be continued! (later this week)
160                 debugPrint (DEBUG_LEVEL_INFO, "  Trying to create an AvDevice...\n");
161
162                 AvDevice *test=new AvDevice(m_iPort, iNodeId);
163                 debugPrint (DEBUG_LEVEL_INFO, "   Created...\n");
164                 test->Initialize();
165                 if (test->isInitialised()) {
166                         unsigned char fmt;
167                         quadlet_t fdf;
168                         test->getInputPlugSignalFormat(0,&fmt,&fdf);
169                         debugPrint (DEBUG_LEVEL_INFO, "   fmt=%02X fdf=%08X\n",fmt,fdf);
170                         test->getInputPlugSignalFormat(1,&fmt,&fdf);
171                         debugPrint (DEBUG_LEVEL_INFO, "   fmt=%02X fdf=%08X\n",fmt,fdf);
172                         test->getOutputPlugSignalFormat(0,&fmt,&fdf);
173                         debugPrint (DEBUG_LEVEL_INFO, "   fmt=%02X fdf=%08X\n",fmt,fdf);
174                         test->getOutputPlugSignalFormat(1,&fmt,&fdf);
175                         debugPrint (DEBUG_LEVEL_INFO, "   fmt=%02X fdf=%08X\n",fmt,fdf);
176                         test->printConnections();
177                 }
178                
179                 debugPrint (DEBUG_LEVEL_INFO, "   Deleting AvDevice...\n");
180                 delete test;
181
182             }
183             break;
184         case ROM1394_NODE_TYPE_SBP2:
185             debugPrint( DEBUG_LEVEL_INFO,
186                         "Node %d has node type SBP2\n", iNodeId);
187             break;
188         case ROM1394_NODE_TYPE_CPU:
189             debugPrint( DEBUG_LEVEL_INFO,
190                         "Node %d has node type CPU\n", iNodeId);
191             break;
192         default:
193             debugPrint( DEBUG_LEVEL_INFO,
194                         "No matching node type found for node %d\n", iNodeId);
195         }
196     }
197     return eFBRC_Success;
198 }
199
200 void
201 Ieee1394Service::printAvcUnitInfo( int iNodeId )
202 {
203     printf( "AVC: video monitor?......%s\n",
204             avc1394_check_subunit_type( m_handle, iNodeId,
205                                         AVC1394_SUBUNIT_TYPE_VIDEO_MONITOR ) ?
206             "yes":"no" );
207     printf( "AVC: audio?..............%s\n",
208             avc1394_check_subunit_type( m_handle, iNodeId,
209                                         AVC1394_SUBUNIT_TYPE_AUDIO ) ?
210             "yes":"no" );
211     printf( "AVC; printer?............%s\n",
212             avc1394_check_subunit_type( m_handle, iNodeId,
213                                         AVC1394_SUBUNIT_TYPE_PRINTER ) ?
214             "yes":"no" );
215     printf( "AVC: disk recorder?......%s\n",
216             avc1394_check_subunit_type( m_handle, iNodeId,
217                                         AVC1394_SUBUNIT_TYPE_DISC_RECORDER ) ?
218             "yes":"no" );
219     printf( "AVC: video recorder?.....%s\n",
220             avc1394_check_subunit_type( m_handle, iNodeId,
221                                         AVC1394_SUBUNIT_TYPE_TAPE_RECORDER ) ?
222             "yes":"no" );
223     printf( "AVC: vcr?................%s\n",
224             avc1394_check_subunit_type( m_handle, iNodeId,
225                                         AVC1394_SUBUNIT_TYPE_VCR ) ?
226             "yes":"no" );
227     printf( "AVC: tuner?..............%s\n",
228             avc1394_check_subunit_type( m_handle, iNodeId,
229                                         AVC1394_SUBUNIT_TYPE_TUNER ) ?
230             "yes":"no" );
231     printf( "AVC: CA?.................%s\n",
232             avc1394_check_subunit_type( m_handle, iNodeId,
233                                         AVC1394_SUBUNIT_TYPE_CA ) ?
234             "yes":"no" );
235     printf( "AVC: video camera?.......%s\n",
236             avc1394_check_subunit_type( m_handle, iNodeId,
237                                         AVC1394_SUBUNIT_TYPE_VIDEO_CAMERA ) ?
238             "yes":"no" );
239     printf( "AVC: panel?..............%s\n",
240             avc1394_check_subunit_type(m_handle, iNodeId,
241                                         AVC1394_SUBUNIT_TYPE_PANEL ) ?
242             "yes":"no" );
243     printf( "AVC: camera storage?.....%s\n",
244             avc1394_check_subunit_type( m_handle, iNodeId,
245                                         AVC1394_SUBUNIT_TYPE_CAMERA_STORAGE ) ?
246             "yes":"no" );
247     printf( "AVC: bulletin board?.....%s\n",
248             avc1394_check_subunit_type( m_handle, iNodeId,
249                                         AVC1394_SUBUNIT_TYPE_BULLETIN_BOARD ) ?
250             "yes":"no" );
251     printf( "AVC: vendor specific?....%s\n",
252             avc1394_check_subunit_type( m_handle, iNodeId,
253                                         AVC1394_SUBUNIT_TYPE_VENDOR_UNIQUE ) ?
254             "yes":"no" );
255     printf( "AVC: extended?...........%s\n",
256             avc1394_check_subunit_type( m_handle, iNodeId,
257                                         AVC1394_SUBUNIT_TYPE_EXTENDED ) ?
258             "yes":"no" );
259     printf( "AVC: unit?...............%s\n",
260             avc1394_check_subunit_type( m_handle, iNodeId,
261                                         AVC1394_SUBUNIT_TYPE_UNIT ) ?
262             "yes":"no" );
263     printf( "AVC: music?..............%s\n",
264             avc1394_check_subunit_type( m_handle, iNodeId,
265                                         AVC1394_SUBUNIT_TYPE_MUSIC ) ?
266             "yes":"no" );
267 }
268
269 void
270 Ieee1394Service::printRomDirectory( int iNodeId,  rom1394_directory* pRomDir )
271 {
272     int iBusInfoBlockLength
273         = rom1394_get_bus_info_block_length( m_handle,  iNodeId );
274     int iBusId = rom1394_get_bus_id( m_handle,  iNodeId );
275     octlet_t oGuid = rom1394_get_guid( m_handle, iNodeId );
276     rom1394_bus_options busOptions;
277     rom1394_get_bus_options( m_handle, iNodeId, &busOptions );
278
279     printf( "\nNode %d: \n", iNodeId );
280     printf( "-------------------------------------------------\n" );
281     printf( "bus info block length = %d\n", iBusInfoBlockLength);
282     printf( "bus id = 0x%08x\n", iBusId );
283     printf( "bus options:\n" );
284     printf( "    isochronous resource manager capable: %d\n", busOptions.irmc );
285     printf ("    cycle master capable                : %d\n", busOptions.cmc );
286     printf ("    isochronous capable                 : %d\n", busOptions.isc );
287     printf ("    bus manager capable                 : %d\n", busOptions.bmc );
288     printf ("    cycle master clock accuracy         : %d ppm\n", busOptions.cyc_clk_acc );
289     printf( "    maximum asynchronous record size    : %d bytes\n", busOptions.max_rec );
290     printf("GUID: 0x%08x%08x\n", (quadlet_t) (oGuid>>32),
291            (quadlet_t) (oGuid & 0xffffffff) );
292     printf( "directory:\n");
293     printf( "    node capabilities    : 0x%08x\n", pRomDir->node_capabilities );
294     printf( "    vendor id            : 0x%08x\n", pRomDir->vendor_id );
295     printf( "    unit spec id         : 0x%08x\n", pRomDir->unit_spec_id );
296     printf( "    unit software version: 0x%08x\n", pRomDir->unit_sw_version );
297     printf( "    model id             : 0x%08x\n", pRomDir->model_id );
298     printf( "    textual leaves       : %s\n",     pRomDir->label );
299 }
300
301 int
302 Ieee1394Service::resetHandler( raw1394handle_t handle,
303                                unsigned int iGeneration )
304 {
305     debugPrint( DEBUG_LEVEL_INFO,
306                 "Bus reset has occurred (generation = %d).\n", iGeneration );
307     raw1394_update_generation (handle, iGeneration);
308     Ieee1394Service* pInstance
309         = (Ieee1394Service*) raw1394_get_userdata (handle);
310     pInstance->setGenerationCount( iGeneration );
311     return 0;
312 }
313
314 bool
315 Ieee1394Service::startRHThread()
316 {
317     if ( m_bRHThreadRunning ) {
318         return true;
319     }
320     debugPrint( DEBUG_LEVEL_INFO,
321                 "Starting bus reset handler thread.\n" );
322     pthread_mutex_lock( &m_mutex );
323     pthread_create( &m_thread, NULL, rHThread, this );
324     pthread_mutex_unlock( &m_mutex );
325     m_bRHThreadRunning = true;
326     return true;
327 }
328
329 void
330 Ieee1394Service::stopRHThread()
331 {
332     if ( m_bRHThreadRunning ) {
333         debugPrint( DEBUG_LEVEL_INFO,
334                     "Stopping bus reset handler thread.\n" );
335         pthread_mutex_lock (&m_mutex);
336         pthread_cancel (m_thread);
337         pthread_join (m_thread, NULL);
338         pthread_mutex_unlock (&m_mutex);
339     }
340     m_bRHThreadRunning = false;
341 }
342
343 void*
344 Ieee1394Service::rHThread( void* arg )
345 {
346     Ieee1394Service* pIeee1394Service = (Ieee1394Service*) arg;
347
348     while (true) {
349         raw1394_loop_iterate (pIeee1394Service->m_rhHandle);
350         pthread_testcancel ();
351     }
352
353     return NULL;
354 }
355
356 void
357 Ieee1394Service::setGenerationCount( unsigned int iGeneration )
358 {
359     m_iGenerationCount = iGeneration;
360 }
361
362 unsigned int
363 Ieee1394Service::getGenerationCount()
364 {
365     return m_iGenerationCount;
366 }
Note: See TracBrowser for help on using the browser.