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

Revision 419, 14.3 kB (checked in by pieterpalmers, 17 years ago)

namespace simplification

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