root/branches/libfreebob-2.0/src/devicemanager.cpp

Revision 341, 10.0 kB (checked in by pieterpalmers, 17 years ago)

- changed bebob avdevice to use debugmodule instead of printf/cout
- fixed some minor merge side-effects
- implement a RT safe mechanism to obtain the cycle counter.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1  /* devicemanager.cpp
2  * Copyright (C) 2005,06 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 "fbtypes.h"
22
23 #include "devicemanager.h"
24 #include "iavdevice.h"
25 #include "configrom.h"
26
27 #include "libfreebobavc/ieee1394service.h"
28 #include "debugmodule/debugmodule.h"
29 #include "bebob/bebob_avdevice.h"
30 #include "bounce/bounce_avdevice.h"
31 #include "motu/motu_avdevice.h"
32 #include "rme/rme_avdevice.h"
33 #include "maudio/maudio_avdevice.h"
34
35 #include <iostream>
36 #include <unistd.h>
37
38 // Unit directory SpecifierID/Version identifying a true Bebob AVC device
39 #define BEBOB_AVCDEVICE_UNIT_SPECIFIER   0x0000a02d
40 #define BEBOB_AVCDEVICE_UNIT_VERSION     0x10001
41
42 // The vendor ID for MOTU devices
43 #define MOTU_VENDOR_ID                   0x000001f2
44
45 // The vendor ID for RME devices
46 #define RME_VENDOR_ID                    0x00000a35
47
48 using namespace std;
49
50 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
51
52 DeviceManager::DeviceManager()
53     : m_1394Service( 0 )
54 {
55
56 }
57
58 DeviceManager::~DeviceManager()
59 {
60     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
61           it != m_avDevices.end();
62           ++it )
63     {
64         delete *it;
65     }
66
67     delete m_1394Service;
68 }
69
70 bool
71 DeviceManager::initialize( int port )
72 {
73     m_1394Service = new Ieee1394Service();
74     if ( !m_1394Service ) {
75         debugFatal( "Could not create Ieee1349Service object\n" );
76         return false;
77     }
78
79     if ( !m_1394Service->initialize( port ) ) {
80         debugFatal( "Could not initialize Ieee1349Service object\n" );
81         delete m_1394Service;
82         m_1394Service = 0;
83         return false;
84     }
85
86     return true;
87 }
88
89 bool
90 DeviceManager::discover( int verboseLevel )
91 {
92
93     setDebugLevel( verboseLevel );
94     m_1394Service->setVerbose( verboseLevel );
95
96     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
97           it != m_avDevices.end();
98           ++it )
99     {
100         delete *it;
101     }
102     m_avDevices.clear();
103
104     for ( fb_nodeid_t nodeId = 0;
105           nodeId < m_1394Service->getNodeCount();
106           ++nodeId )
107     {
108         debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
109        
110         std::auto_ptr<ConfigRom> configRom =
111             std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
112                                                      nodeId ) );
113         if ( !configRom->initialize() ) {
114             // \todo If a PHY on the bus is in power safe mode then
115             // the config rom is missing. So this might be just
116             // such this case and we can safely skip it. But it might
117             // be there is a real software problem on our side.
118             // This should be handled more carefuly.
119             debugOutput( DEBUG_LEVEL_NORMAL,
120                          "Could not read config rom from device (node id %d). "
121                          "Skip device discovering for this node\n",
122                          nodeId );
123             continue;
124         }
125
126         IAvDevice* avDevice = getDriverForDevice( configRom,
127                                                   nodeId,
128                                                   verboseLevel );
129         if ( avDevice ) {
130             debugOutput( DEBUG_LEVEL_NORMAL,
131                          "discover: driver found for device %d\n",
132                          nodeId );
133
134             if ( !avDevice->discover() ) {
135                 debugError( "discover: could not discover device\n" );
136                 delete avDevice;
137                 continue;
138             }
139
140             if ( !avDevice->setId( m_avDevices.size() ) ) {
141                 debugError( "setting Id failed\n" );
142             }
143             if ( verboseLevel ) {
144                 avDevice->showDevice();
145             }
146
147             m_avDevices.push_back( avDevice );
148         }
149     }
150
151     return true;
152 }
153
154
155 IAvDevice*
156 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
157                                    int id,  int level )
158 {
159     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
160         return new BeBoB::AvDevice( configRom, *m_1394Service, id, level );
161     }
162
163     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
164         return new MAudio::AvDevice( configRom, *m_1394Service, id, level );
165     }
166
167     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
168         return new Motu::MotuDevice( configRom, *m_1394Service, id, level );
169     }
170
171     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
172         return new Rme::RmeDevice( configRom, *m_1394Service, id, level );
173     }
174
175     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
176         return new Bounce::BounceDevice( configRom, *m_1394Service, id, level );
177     }
178
179     return 0;
180 }
181
182 bool
183 DeviceManager::isValidNode(int node)
184 {
185     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
186           it != m_avDevices.end();
187           ++it )
188     {
189         IAvDevice* avDevice = *it;
190
191         if (avDevice->getConfigRom().getNodeId() == node) {
192                 return true;
193         }
194     }
195     return false;
196 }
197
198 int
199 DeviceManager::getNbDevices()
200 {
201     return m_avDevices.size();
202 }
203
204 int
205 DeviceManager::getDeviceNodeId( int deviceNr )
206 {
207     if ( ! ( deviceNr < getNbDevices() ) ) {
208         debugError( "Device number out of range (%d)\n", deviceNr );
209         return -1;
210     }
211
212     IAvDevice* avDevice = m_avDevices.at( deviceNr );
213
214     if ( !avDevice ) {
215         debugError( "Could not get device at position (%d)\n",  deviceNr );
216     }
217
218     return avDevice->getConfigRom().getNodeId();
219 }
220
221 IAvDevice*
222 DeviceManager::getAvDevice( int nodeId )
223 {
224     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
225           it != m_avDevices.end();
226           ++it )
227     {
228         IAvDevice* avDevice = *it;
229         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
230             return avDevice;
231         }
232     }
233
234     return 0;
235 }
236
237 IAvDevice*
238 DeviceManager::getAvDeviceByIndex( int idx )
239 {
240         return m_avDevices.at(idx);
241 }
242
243 unsigned int
244 DeviceManager::getAvDeviceCount( )
245 {
246         return m_avDevices.size();
247 }
248
249 xmlDocPtr
250 DeviceManager::getXmlDescription()
251 {
252     xmlDocPtr doc = xmlNewDoc( BAD_CAST "1.0" );
253     if ( !doc ) {
254         debugError( "Couldn't create new xml doc\n" );
255         return 0;
256     }
257
258     xmlNodePtr rootNode = xmlNewNode( 0,  BAD_CAST "FreeBoBConnectionInfo" );
259     if ( !rootNode ) {
260         debugError( "Couldn't create root node\n" );
261         xmlFreeDoc( doc );
262         xmlCleanupParser();
263         return 0;
264     }
265     xmlDocSetRootElement( doc, rootNode );
266
267     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
268           it != m_avDevices.end();
269           ++it )
270     {
271         IAvDevice* avDevice = *it;
272
273         xmlNodePtr deviceNode = xmlNewChild( rootNode, 0,
274                                              BAD_CAST "Device", 0 );
275         if ( !deviceNode ) {
276             debugError( "Couldn't create device node\n" );
277             xmlFreeDoc( doc );
278             xmlCleanupParser();
279             return 0;
280         }
281
282         char* result;
283         asprintf( &result, "%d", avDevice->getConfigRom().getNodeId() );
284         if ( !xmlNewChild( deviceNode,  0,
285                            BAD_CAST "NodeId",  BAD_CAST result ) )
286         {
287             debugError( "Couldn't create 'NodeId' node" );
288             free(result);
289             return 0;
290         }
291         free( result );
292
293         std::string res = "Connection Information for "
294                           + avDevice->getConfigRom().getVendorName()
295                           +", "
296                           + avDevice->getConfigRom().getModelName()
297                           + " configuration";
298         if ( !xmlNewChild( deviceNode,
299                            0,
300                            BAD_CAST "Comment",
301                            BAD_CAST res.c_str() ) ) {
302             debugError( "Couldn't create comment node\n" );
303             xmlFreeDoc( doc );
304             xmlCleanupParser();
305             free(result);
306             return 0;
307         }
308
309         res = avDevice->getConfigRom().getVendorName();
310
311         if ( !xmlNewChild( deviceNode,
312                            0,
313                            BAD_CAST "Vendor",
314                            BAD_CAST res.c_str() ) ) {
315             debugError( "Couldn't create vendor node\n" );
316             xmlFreeDoc( doc );
317             xmlCleanupParser();
318             free(result);
319             return 0;
320         }
321
322         res = avDevice->getConfigRom().getModelName();
323
324         if ( !xmlNewChild( deviceNode,
325                            0,
326                            BAD_CAST "Model",
327                            BAD_CAST res.c_str() ) ) {
328             debugError( "Couldn't create model node\n" );
329             xmlFreeDoc( doc );
330             xmlCleanupParser();
331             free(result);
332             return 0;
333         }
334
335         asprintf( &result, "%08x%08x",
336                   ( quadlet_t )( avDevice->getConfigRom().getGuid() >> 32 ),
337                   ( quadlet_t )( avDevice->getConfigRom().getGuid() & 0xfffffff ) );
338         if ( !xmlNewChild( deviceNode,  0,
339                            BAD_CAST "GUID",  BAD_CAST result ) ) {
340             debugError( "Couldn't create 'GUID' node\n" );
341             xmlFreeDoc( doc );
342             xmlCleanupParser();
343            
344             free(result);
345             return 0;
346         }
347         free( result );
348
349
350         if ( !avDevice->addXmlDescription( deviceNode ) ) {
351             debugError( "Adding XML description failed\n" );
352             xmlFreeDoc( doc );
353             xmlCleanupParser();
354             free(result);
355             return 0;
356         }
357        
358         free(result);
359     }
360
361     return doc;
362 }
363
364 bool
365 DeviceManager::deinitialize()
366 {
367     return true;
368 }
369
Note: See TracBrowser for help on using the browser.