root/branches/streaming-rework/src/devicemanager.cpp

Revision 368, 12.6 kB (checked in by wagi, 17 years ago)

ConfigRom::serialize: no prefix needed for member
ConfigRom::deserialize: ieee1394service argument

no prefix needed for member
return 0 if deserializing fails

AvDevice::AvDevice?: new ctor
vDevice::serialize: comment removed
AvDevice::deserialize: config rom deserializing code added

  • 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,07 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 <sstream>
37
38 #include <unistd.h>
39
40 using namespace std;
41
42 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
43
44 DeviceManager::DeviceManager()
45     : m_1394Service( 0 )
46 {
47
48 }
49
50 DeviceManager::~DeviceManager()
51 {
52     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
53           it != m_avDevices.end();
54           ++it )
55     {
56         delete *it;
57     }
58
59     delete m_1394Service;
60 }
61
62 bool
63 DeviceManager::initialize( int port )
64 {
65     m_1394Service = new Ieee1394Service();
66     if ( !m_1394Service ) {
67         debugFatal( "Could not create Ieee1349Service object\n" );
68         return false;
69     }
70
71     if ( !m_1394Service->initialize( port ) ) {
72         debugFatal( "Could not initialize Ieee1349Service object\n" );
73         delete m_1394Service;
74         m_1394Service = 0;
75         return false;
76     }
77
78     return true;
79 }
80
81 bool
82 DeviceManager::discover( int verboseLevel )
83 {
84
85     setDebugLevel( verboseLevel );
86     m_1394Service->setVerbose( verboseLevel );
87
88     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
89           it != m_avDevices.end();
90           ++it )
91     {
92         delete *it;
93     }
94     m_avDevices.clear();
95
96     for ( fb_nodeid_t nodeId = 0;
97           nodeId < m_1394Service->getNodeCount();
98           ++nodeId )
99     {
100         debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
101
102         std::auto_ptr<ConfigRom> configRom =
103             std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
104                                                      nodeId ) );
105         if ( !configRom->initialize() ) {
106             // \todo If a PHY on the bus is in power safe mode then
107             // the config rom is missing. So this might be just
108             // such this case and we can safely skip it. But it might
109             // be there is a real software problem on our side.
110             // This should be handled more carefuly.
111             debugOutput( DEBUG_LEVEL_NORMAL,
112                          "Could not read config rom from device (node id %d). "
113                          "Skip device discovering for this node\n",
114                          nodeId );
115             continue;
116         }
117
118         IAvDevice* avDevice = getDriverForDevice( configRom,
119                                                   nodeId,
120                                                   verboseLevel );
121         if ( avDevice ) {
122             debugOutput( DEBUG_LEVEL_NORMAL,
123                          "discover: driver found for device %d\n",
124                          nodeId );
125
126             if ( !avDevice->discover() ) {
127                 debugError( "discover: could not discover device\n" );
128                 delete avDevice;
129                 continue;
130             }
131
132             if ( !avDevice->setId( m_avDevices.size() ) ) {
133                 debugError( "setting Id failed\n" );
134             }
135             if ( verboseLevel ) {
136                 avDevice->showDevice();
137             }
138
139             m_avDevices.push_back( avDevice );
140         }
141     }
142
143     return true;
144 }
145
146
147 IAvDevice*
148 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
149                                    int id,  int level )
150 {
151     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
152         return new BeBoB::AvDevice( configRom, *m_1394Service, id, level );
153     }
154
155     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
156         return new MAudio::AvDevice( configRom, *m_1394Service, id, level );
157     }
158
159     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
160         return new Motu::MotuDevice( configRom, *m_1394Service, id, level );
161     }
162
163     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
164         return new Rme::RmeDevice( configRom, *m_1394Service, id, level );
165     }
166
167     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
168         return new Bounce::BounceDevice( configRom, *m_1394Service, id, level );
169     }
170
171     return 0;
172 }
173
174 bool
175 DeviceManager::isValidNode(int node)
176 {
177     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
178           it != m_avDevices.end();
179           ++it )
180     {
181         IAvDevice* avDevice = *it;
182
183         if (avDevice->getConfigRom().getNodeId() == node) {
184                 return true;
185         }
186     }
187     return false;
188 }
189
190 int
191 DeviceManager::getNbDevices()
192 {
193     return m_avDevices.size();
194 }
195
196 int
197 DeviceManager::getDeviceNodeId( int deviceNr )
198 {
199     if ( ! ( deviceNr < getNbDevices() ) ) {
200         debugError( "Device number out of range (%d)\n", deviceNr );
201         return -1;
202     }
203
204     IAvDevice* avDevice = m_avDevices.at( deviceNr );
205
206     if ( !avDevice ) {
207         debugError( "Could not get device at position (%d)\n",  deviceNr );
208     }
209
210     return avDevice->getConfigRom().getNodeId();
211 }
212
213 IAvDevice*
214 DeviceManager::getAvDevice( int nodeId )
215 {
216     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
217           it != m_avDevices.end();
218           ++it )
219     {
220         IAvDevice* avDevice = *it;
221         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
222             return avDevice;
223         }
224     }
225
226     return 0;
227 }
228
229 IAvDevice*
230 DeviceManager::getAvDeviceByIndex( int idx )
231 {
232         return m_avDevices.at(idx);
233 }
234
235 unsigned int
236 DeviceManager::getAvDeviceCount( )
237 {
238         return m_avDevices.size();
239 }
240
241 xmlDocPtr
242 DeviceManager::getXmlDescription()
243 {
244     xmlDocPtr doc = xmlNewDoc( BAD_CAST "1.0" );
245     if ( !doc ) {
246         debugError( "Couldn't create new xml doc\n" );
247         return 0;
248     }
249
250     xmlNodePtr rootNode = xmlNewNode( 0,  BAD_CAST "FreeBoBConnectionInfo" );
251     if ( !rootNode ) {
252         debugError( "Couldn't create root node\n" );
253         xmlFreeDoc( doc );
254         xmlCleanupParser();
255         return 0;
256     }
257     xmlDocSetRootElement( doc, rootNode );
258
259     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
260           it != m_avDevices.end();
261           ++it )
262     {
263         IAvDevice* avDevice = *it;
264
265         xmlNodePtr deviceNode = xmlNewChild( rootNode, 0,
266                                              BAD_CAST "Device", 0 );
267         if ( !deviceNode ) {
268             debugError( "Couldn't create device node\n" );
269             xmlFreeDoc( doc );
270             xmlCleanupParser();
271             return 0;
272         }
273
274         char* result;
275         asprintf( &result, "%d", avDevice->getConfigRom().getNodeId() );
276         if ( !xmlNewChild( deviceNode,  0,
277                            BAD_CAST "NodeId",  BAD_CAST result ) )
278         {
279             debugError( "Couldn't create 'NodeId' node" );
280             free(result);
281             return 0;
282         }
283         free( result );
284
285         std::string res = "Connection Information for "
286                           + avDevice->getConfigRom().getVendorName()
287                           +", "
288                           + avDevice->getConfigRom().getModelName()
289                           + " configuration";
290         if ( !xmlNewChild( deviceNode,
291                            0,
292                            BAD_CAST "Comment",
293                            BAD_CAST res.c_str() ) ) {
294             debugError( "Couldn't create comment node\n" );
295             xmlFreeDoc( doc );
296             xmlCleanupParser();
297             free(result);
298             return 0;
299         }
300
301         res = avDevice->getConfigRom().getVendorName();
302
303         if ( !xmlNewChild( deviceNode,
304                            0,
305                            BAD_CAST "Vendor",
306                            BAD_CAST res.c_str() ) ) {
307             debugError( "Couldn't create vendor node\n" );
308             xmlFreeDoc( doc );
309             xmlCleanupParser();
310             free(result);
311             return 0;
312         }
313
314         res = avDevice->getConfigRom().getModelName();
315
316         if ( !xmlNewChild( deviceNode,
317                            0,
318                            BAD_CAST "Model",
319                            BAD_CAST res.c_str() ) ) {
320             debugError( "Couldn't create model node\n" );
321             xmlFreeDoc( doc );
322             xmlCleanupParser();
323             free(result);
324             return 0;
325         }
326
327         asprintf( &result, "%08x%08x",
328                   ( quadlet_t )( avDevice->getConfigRom().getGuid() >> 32 ),
329                   ( quadlet_t )( avDevice->getConfigRom().getGuid() & 0xfffffff ) );
330         if ( !xmlNewChild( deviceNode,  0,
331                            BAD_CAST "GUID",  BAD_CAST result ) ) {
332             debugError( "Couldn't create 'GUID' node\n" );
333             xmlFreeDoc( doc );
334             xmlCleanupParser();
335
336             free(result);
337             return 0;
338         }
339         free( result );
340
341
342         if ( !avDevice->addXmlDescription( deviceNode ) ) {
343             debugError( "Adding XML description failed\n" );
344             xmlFreeDoc( doc );
345             xmlCleanupParser();
346             free(result);
347             return 0;
348         }
349
350         free(result);
351     }
352
353     return doc;
354 }
355
356 bool
357 DeviceManager::deinitialize()
358 {
359     return true;
360 }
361
362 bool
363 DeviceManager::saveCache( Glib::ustring fileName )
364 {
365     int i = 0;
366     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
367           it != m_avDevices.end();
368           ++it )
369     {
370         IAvDevice* pAvDevice = *it;
371         BeBoB::AvDevice* pBeBoBDevice = reinterpret_cast< BeBoB::AvDevice* >( pAvDevice );
372         if ( pBeBoBDevice ) {
373             // Let's use a very simple path to find the devices later.
374             // Since under hood there will an xml node name this should
375             // adhere the needed naming rules. Of course we could give it
376             // a good node name and add an attribute but that would mean
377             // we have to expose a bigger interface from IOSerialize/IODesialize,
378             // which is just not needed. KISS.
379             ostringstream strstrm;
380             strstrm << "id" << i;
381             Glib::ustring basePath = "BeBoB/" + strstrm.str() + "/";
382
383             Util::XMLSerialize ser( fileName );
384             pBeBoBDevice->serialize( basePath, ser );
385
386             i++;
387             std::cout << "a bebob device serialized" << std::endl;
388         }
389     }
390     return true;
391 }
392
393 bool
394 DeviceManager::loadCache( Glib::ustring fileName )
395 {
396     Util::XMLDeserialize deser( fileName );
397     BeBoB::AvDevice* pBeBoBDevice = 0;
398     int i = 0;
399
400     typedef std::vector<ConfigRom*> ConfigRomVector;
401     ConfigRomVector configRoms;
402
403     for ( fb_nodeid_t nodeId = 0;
404           nodeId < m_1394Service->getNodeCount();
405           ++nodeId )
406     {
407         ConfigRom* pConfigRom  =  new ConfigRom( *m_1394Service, nodeId );
408         if ( !pConfigRom->initialize() ) {
409             // \todo If a PHY on the bus is in power safe mode then
410             // the config rom is missing. So this might be just
411             // such this case and we can safely skip it. But it might
412             // be there is a real software problem on our side.
413             // This should be handled more carefuly.
414             debugOutput( DEBUG_LEVEL_NORMAL,
415                          "Could not read config rom from device (node id %d). "
416                          "Skip device discovering for this node\n",
417                          nodeId );
418             delete pConfigRom;
419             continue;
420         }
421         configRoms.push_back( pConfigRom );
422     }
423
424     do {
425         ostringstream strstrm;
426         strstrm << "id" << i;
427         pBeBoBDevice = BeBoB::AvDevice::deserialize(
428             "BeBoB/" + strstrm.str() + "/",
429             deser,
430             *m_1394Service );
431
432         ++i;
433         if ( pBeBoBDevice ) {
434             for (ConfigRomVector::iterator it = configRoms.begin();
435                  it != configRoms.end();
436                  ++it )
437             {
438                 ConfigRom* pConfigRom = *it;
439
440                 if ( pBeBoBDevice->getConfigRom() == *pConfigRom ) {
441                     pBeBoBDevice->getConfigRom().setNodeId( pConfigRom->getNodeId() );
442                     // m_avDevices.push_back( pBeBoBDevice );
443
444                 }
445             }
446         }
447     } while ( pBeBoBDevice );
448
449     return true;
450 }
Note: See TracBrowser for help on using the browser.