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

Revision 436, 16.4 kB (checked in by pieterpalmers, 17 years ago)

- fixed verbose level setting
- debugged DICE code, works with EVM

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