root/trunk/libffado/src/devicemanager.cpp

Revision 557, 14.5 kB (checked in by wagi, 17 years ago)

moved&renamed configparser from bebob to genericavc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1  /*
2  * Copyright (C) 2005-2007 by Daniel Wagner
3  * Copyright (C) 2005-2007 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
23  */
24
25 #include "fbtypes.h"
26
27 #include "devicemanager.h"
28 #include "ffadodevice.h"
29
30 #include "libieee1394/configrom.h"
31 #include "libieee1394/ieee1394service.h"
32
33 #include "libstreaming/StreamProcessor.h"
34
35 #include "debugmodule/debugmodule.h"
36
37 #ifdef ENABLE_BEBOB
38 #include "bebob/bebob_avdevice.h"
39 #include "maudio/maudio_avdevice.h"
40 #endif
41
42 #ifdef ENABLE_GENERICAVC
43     #include "genericavc/avc_avdevice.h"
44 #endif
45
46 #ifdef ENABLE_BOUNCE
47 #include "bounce/bounce_avdevice.h"
48 #include "bounce/bounce_slave_avdevice.h"
49 #endif
50
51 #ifdef ENABLE_MOTU
52 #include "motu/motu_avdevice.h"
53 #endif
54
55 #ifdef ENABLE_RME
56 #include "rme/rme_avdevice.h"
57 #endif
58
59 #ifdef ENABLE_DICE
60 #include "dice/dice_avdevice.h"
61 #endif
62
63 #ifdef ENABLE_METRIC_HALO
64 #include "metrichalo/mh_avdevice.h"
65 #endif
66
67 #include <iostream>
68 #include <sstream>
69
70 using namespace std;
71
72 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
73
74 DeviceManager::DeviceManager()
75     : OscNode("devicemanager")
76     , m_1394Service( 0 )
77     , m_oscServer( NULL )
78 {
79     addOption(Util::OptionContainer::Option("slaveMode",false));
80     addOption(Util::OptionContainer::Option("snoopMode",false));
81 }
82
83 DeviceManager::~DeviceManager()
84 {
85     if (m_oscServer) {
86         m_oscServer->stop();
87         delete m_oscServer;
88     }
89
90     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
91           it != m_avDevices.end();
92           ++it )
93     {
94         delete *it;
95     }
96
97     delete m_1394Service;
98 }
99
100 void
101 DeviceManager::setVerboseLevel(int l)
102 {
103     debugOutput( DEBUG_LEVEL_NORMAL, "Setting verbose level to %d...\n", l );
104     setDebugLevel(l);
105
106     if (m_1394Service) m_1394Service->setVerboseLevel(l);
107     if (m_oscServer) m_oscServer->setVerboseLevel(l);
108     OscNode::setVerboseLevel(l);
109
110     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
111           it != m_avDevices.end();
112           ++it )
113     {
114         (*it)->setVerboseLevel(l);
115     }
116 }
117
118 bool
119 DeviceManager::initialize( int port )
120 {
121     m_1394Service = new Ieee1394Service();
122     if ( !m_1394Service ) {
123         debugFatal( "Could not create Ieee1349Service object\n" );
124         return false;
125     }
126
127     if ( !m_1394Service->initialize( port ) ) {
128         debugFatal( "Could not initialize Ieee1349Service object\n" );
129         delete m_1394Service;
130         m_1394Service = 0;
131         return false;
132     }
133
134 //     m_oscServer = new OSC::OscServer("17820");
135 //
136 //     if (!m_oscServer) {
137 //         debugFatal("failed to create osc server\n");
138 //         delete m_1394Service;
139 //         m_1394Service = 0;
140 //         return false;
141 //     }
142 //
143 //     if (!m_oscServer->init()) {
144 //         debugFatal("failed to init osc server\n");
145 //         delete m_oscServer;
146 //         m_oscServer = NULL;
147 //         delete m_1394Service;
148 //         m_1394Service = 0;
149 //         return false;
150 //     }
151 //
152 //     if (!m_oscServer->registerAtRootNode(this)) {
153 //         debugFatal("failed to register devicemanager at server\n");
154 //         delete m_oscServer;
155 //         m_oscServer = NULL;
156 //         delete m_1394Service;
157 //         m_1394Service = 0;
158 //         return false;
159 //     }
160 //
161 //     if (!m_oscServer->start()) {
162 //         debugFatal("failed to start osc server\n");
163 //         delete m_oscServer;
164 //         m_oscServer = NULL;
165 //         delete m_1394Service;
166 //         m_1394Service = 0;
167 //         return false;
168 //     }
169
170     setVerboseLevel(getDebugLevel());
171     return true;
172 }
173
174 bool
175 DeviceManager::discover( )
176 {
177     bool slaveMode=false;
178     if(!getOption("slaveMode", slaveMode)) {
179         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
180     }
181     bool snoopMode=false;
182     if(!getOption("snoopMode", snoopMode)) {
183         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
184     }
185
186     setVerboseLevel(getDebugLevel());
187
188     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
189           it != m_avDevices.end();
190           ++it )
191     {
192         if (!removeChildOscNode(*it)) {
193             debugWarning("failed to unregister AvDevice from OSC server\n");
194         }
195         delete *it;
196     }
197     m_avDevices.clear();
198
199     if (!slaveMode) {
200         for ( fb_nodeid_t nodeId = 0;
201               nodeId < m_1394Service->getNodeCount();
202               ++nodeId )
203         {
204             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
205
206             if (nodeId == m_1394Service->getLocalNodeId()) {
207                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
208                 continue;
209             }
210
211             std::auto_ptr<ConfigRom> configRom =
212                 std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
213                                                          nodeId ) );
214             if ( !configRom->initialize() ) {
215                 // \todo If a PHY on the bus is in power safe mode then
216                 // the config rom is missing. So this might be just
217                 // such this case and we can safely skip it. But it might
218                 // be there is a real software problem on our side.
219                 // This should be handlede more carefuly.
220                 debugOutput( DEBUG_LEVEL_NORMAL,
221                              "Could not read config rom from device (node id %d). "
222                              "Skip device discovering for this node\n",
223                              nodeId );
224                 continue;
225             }
226
227             FFADODevice* avDevice = getDriverForDevice( configRom,
228                                                         nodeId );
229
230             if ( avDevice ) {
231                 debugOutput( DEBUG_LEVEL_NORMAL,
232                              "driver found for device %d\n",
233                              nodeId );
234
235                 bool isFromCache = false;
236                 if ( avDevice->loadFromCache() ) {
237                     debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
238                     isFromCache = true;
239                 } else if ( avDevice->discover() ) {
240                     debugOutput( DEBUG_LEVEL_VERBOSE, "discovering successful\n" );
241                     avDevice->setVerboseLevel( getDebugLevel() );
242                 } else {
243                     debugError( "could not discover device\n" );
244                     delete avDevice;
245                     continue;
246                 }
247
248                 if ( !avDevice->setId( m_avDevices.size() ) ) {
249                     debugError( "setting Id failed\n" );
250                 }
251
252                 if (snoopMode) {
253                     debugOutput( DEBUG_LEVEL_VERBOSE,
254                                  "Enabling snoop mode on node %d...\n", nodeId );
255
256                     if(!avDevice->setOption("snoopMode", snoopMode)) {
257                         debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
258                         delete avDevice;
259                         continue;
260                     }
261                 }
262
263                 if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
264                     avDevice->showDevice();
265                 }
266
267                 if ( !isFromCache && !avDevice->saveCache() ) {
268                     debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
269                 }
270
271                 m_avDevices.push_back( avDevice );
272
273                 if (!addChildOscNode(avDevice)) {
274                     debugWarning("failed to register AvDevice at OSC server\n");
275                 }
276                
277                 debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId );
278
279             }
280         }
281
282         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
283
284         return true;
285
286     } else { // slave mode
287         fb_nodeid_t nodeId = m_1394Service->getLocalNodeId();
288         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
289
290         std::auto_ptr<ConfigRom> configRom =
291             std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
292                                                      nodeId ) );
293         if ( !configRom->initialize() ) {
294             // \todo If a PHY on the bus is in power safe mode then
295             // the config rom is missing. So this might be just
296             // such this case and we can safely skip it. But it might
297             // be there is a real software problem on our side.
298             // This should be handled more carefuly.
299             debugOutput( DEBUG_LEVEL_NORMAL,
300                          "Could not read config rom from device (node id %d). "
301                          "Skip device discovering for this node\n",
302                          nodeId );
303             return false;
304         }
305
306         FFADODevice* avDevice = getSlaveDriver( configRom );
307         if ( avDevice ) {
308             debugOutput( DEBUG_LEVEL_NORMAL,
309                          "driver found for device %d\n",
310                          nodeId );
311
312             avDevice->setVerboseLevel( getDebugLevel() );
313
314             if ( !avDevice->discover() ) {
315                 debugError( "could not discover device\n" );
316                 delete avDevice;
317                 return false;
318             }
319
320             if ( !avDevice->setId( m_avDevices.size() ) ) {
321                 debugError( "setting Id failed\n" );
322             }
323             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
324                 avDevice->showDevice();
325             }
326
327             m_avDevices.push_back( avDevice );
328
329             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId );
330         }
331
332         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
333
334         return true;
335     }
336 }
337
338
339 FFADODevice*
340 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
341                                    int id )
342 {
343 #ifdef ENABLE_BEBOB
344     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
345     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
346         return new BeBoB::AvDevice( configRom, *m_1394Service, id );
347     }
348 #endif
349
350 #ifdef ENABLE_GENERICAVC
351     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
352     if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) {
353         return new GenericAVC::AvDevice( configRom, *m_1394Service, id );
354     }
355 #endif
356
357 #ifdef ENABLE_BEBOB
358     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
359     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
360         return new MAudio::AvDevice( configRom, *m_1394Service, id );
361     }
362 #endif
363
364 #ifdef ENABLE_MOTU
365     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
366     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
367         return new Motu::MotuDevice( configRom, *m_1394Service, id );
368     }
369 #endif
370
371 #ifdef ENABLE_DICE
372     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
373     if ( Dice::DiceAvDevice::probe( *configRom.get() ) ) {
374         return new Dice::DiceAvDevice( configRom, *m_1394Service, id );
375     }
376 #endif
377
378 #ifdef ENABLE_METRIC_HALO
379     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
380     if ( MetricHalo::MHAvDevice::probe( *configRom.get() ) ) {
381         return new MetricHalo::MHAvDevice( configRom, *m_1394Service, id );
382     }
383 #endif
384
385 #ifdef ENABLE_RME
386     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
387     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
388         return new Rme::RmeDevice( configRom, *m_1394Service, id );
389     }
390 #endif
391
392 #ifdef ENABLE_BOUNCE
393     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
394     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
395         return new Bounce::BounceDevice( configRom, *m_1394Service, id );
396     }
397 #endif
398
399     return 0;
400 }
401
402 FFADODevice*
403 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
404 {
405
406 #ifdef ENABLE_BOUNCE
407     if ( Bounce::BounceSlaveDevice::probe( *configRom.get() ) ) {
408         return new Bounce::BounceSlaveDevice( configRom, *m_1394Service );
409     }
410 #endif
411
412     return 0;
413 }
414
415 bool
416 DeviceManager::isValidNode(int node)
417 {
418     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
419           it != m_avDevices.end();
420           ++it )
421     {
422         FFADODevice* avDevice = *it;
423
424         if (avDevice->getConfigRom().getNodeId() == node) {
425             return true;
426     }
427     }
428     return false;
429 }
430
431 int
432 DeviceManager::getNbDevices()
433 {
434     return m_avDevices.size();
435 }
436
437 int
438 DeviceManager::getDeviceNodeId( int deviceNr )
439 {
440     if ( ! ( deviceNr < getNbDevices() ) ) {
441         debugError( "Device number out of range (%d)\n", deviceNr );
442         return -1;
443     }
444
445     FFADODevice* avDevice = m_avDevices.at( deviceNr );
446
447     if ( !avDevice ) {
448         debugError( "Could not get device at position (%d)\n",  deviceNr );
449     }
450
451     return avDevice->getConfigRom().getNodeId();
452 }
453
454 FFADODevice*
455 DeviceManager::getAvDevice( int nodeId )
456 {
457     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
458           it != m_avDevices.end();
459           ++it )
460     {
461         FFADODevice* avDevice = *it;
462         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
463             return avDevice;
464         }
465     }
466
467     return 0;
468 }
469
470 FFADODevice*
471 DeviceManager::getAvDeviceByIndex( int idx )
472 {
473     return m_avDevices.at(idx);
474 }
475
476 unsigned int
477 DeviceManager::getAvDeviceCount( )
478 {
479     return m_avDevices.size();
480 }
481
482 /**
483  * Return the streamprocessor that is to be used as
484  * the sync source.
485  *
486  * Algorithm still to be determined
487  *
488  * @return StreamProcessor that is sync source
489  */
490 Streaming::StreamProcessor *
491 DeviceManager::getSyncSource() {
492     FFADODevice* device = getAvDeviceByIndex(0);
493
494     bool slaveMode=false;
495     if(!getOption("slaveMode", slaveMode)) {
496         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
497     }
498
499     #warning TEST CODE FOR BOUNCE DEVICE !!
500     // this makes the bounce slave use the xmit SP as sync source
501     if (slaveMode) {
502         return device->getStreamProcessorByIndex(1);
503     } else {
504         return device->getStreamProcessorByIndex(0);
505     }
506 }
507
508 bool
509 DeviceManager::deinitialize()
510 {
511     return true;
512 }
Note: See TracBrowser for help on using the browser.