root/trunk/libffado/src/devicemanager.cpp

Revision 1763, 43.0 kB (checked in by ppalmers, 14 years ago)

Merged revisions 1536,1541,1544-1546,1549,1554-1562,1571,1579-1581,1618,1632,1634-1635,1661,1677-1679,1703-1704,1715,1720-1723,1743-1745,1755 via svnmerge from
svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

Also fix remaining format string warnings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "config.h"
26 #include "fbtypes.h"
27
28 #include "devicemanager.h"
29 #include "ffadodevice.h"
30 #include "DeviceStringParser.h"
31
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
34 #include "libieee1394/IsoHandlerManager.h"
35
36 #include "libstreaming/generic/StreamProcessor.h"
37 #include "libstreaming/StreamProcessorManager.h"
38
39 #include "debugmodule/debugmodule.h"
40
41 #include "libutil/PosixMutex.h"
42
43 #ifdef ENABLE_BEBOB
44 #include "bebob/bebob_avdevice.h"
45 #endif
46
47 #ifdef ENABLE_MAUDIO
48 #include "maudio/maudio_avdevice.h"
49 #endif
50
51 #ifdef ENABLE_GENERICAVC
52     #include "genericavc/avc_avdevice.h"
53 #endif
54
55 #ifdef ENABLE_FIREWORKS
56     #include "fireworks/fireworks_device.h"
57 #endif
58
59 #ifdef ENABLE_OXFORD
60     #include "oxford/oxford_device.h"
61 #endif
62
63 #ifdef ENABLE_BOUNCE
64 #include "bounce/bounce_avdevice.h"
65 #include "bounce/bounce_slave_avdevice.h"
66 #endif
67
68 #ifdef ENABLE_MOTU
69 #include "motu/motu_avdevice.h"
70 #endif
71
72 #ifdef ENABLE_RME
73 #include "rme/rme_avdevice.h"
74 #endif
75
76 #ifdef ENABLE_DICE
77 #include "dice/dice_avdevice.h"
78 #endif
79
80 #ifdef ENABLE_METRIC_HALO
81 #include "metrichalo/mh_avdevice.h"
82 #endif
83
84 #include <iostream>
85 #include <sstream>
86
87 #include <algorithm>
88
89 using namespace std;
90
91 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
92
93 DeviceManager::DeviceManager()
94     : Control::Container(NULL, "devicemanager") // this is the control root node
95     , m_DeviceListLock( new Util::PosixMutex("DEVLST") )
96     , m_BusResetLock( new Util::PosixMutex("DEVBR") )
97     , m_processorManager( new Streaming::StreamProcessorManager( *this ) )
98     , m_deviceStringParser( new DeviceStringParser() )
99     , m_configuration ( new Util::Configuration() )
100     , m_used_cache_last_time( false )
101     , m_thread_realtime( false )
102     , m_thread_priority( 0 )
103 {
104     addOption(Util::OptionContainer::Option("slaveMode", false));
105     addOption(Util::OptionContainer::Option("snoopMode", false));
106 }
107
108 DeviceManager::~DeviceManager()
109 {
110     // save configuration
111     if(!m_configuration->save()) {
112         debugWarning("could not save configuration\n");
113     }
114
115     m_BusResetLock->Lock(); // make sure we are not handling a busreset.
116     m_DeviceListLock->Lock(); // make sure nobody is using this
117     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
118           it != m_avDevices.end();
119           ++it )
120     {
121         if (!deleteElement(*it)) {
122             debugWarning("failed to remove Device from Control::Container\n");
123         }
124         delete *it;
125     }
126     m_DeviceListLock->Unlock();
127
128     // the SP's are automatically unregistered from the SPM
129     delete m_processorManager;
130
131     // the device list is empty, so wake up any waiting
132     // reset handlers
133     m_BusResetLock->Unlock();
134
135     // remove the bus-reset handlers
136     for ( FunctorVectorIterator it = m_busreset_functors.begin();
137           it != m_busreset_functors.end();
138           ++it )
139     {
140         delete *it;
141     }
142
143     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
144           it != m_1394Services.end();
145           ++it )
146     {
147         delete *it;
148     }
149
150     delete m_DeviceListLock;
151     delete m_BusResetLock;
152     delete m_deviceStringParser;
153 }
154
155 bool
156 DeviceManager::setThreadParameters(bool rt, int priority) {
157     if (!m_processorManager->setThreadParameters(rt, priority)) {
158         debugError("Could not set processor manager thread parameters\n");
159         return false;
160     }
161     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
162           it != m_1394Services.end();
163           ++it )
164     {
165         if (!(*it)->setThreadParameters(rt, priority)) {
166             debugError("Could not set 1394 service thread parameters\n");
167             return false;
168         }
169     }
170     m_thread_realtime = rt;
171     m_thread_priority = priority;
172     return true;
173 }
174
175 bool
176 DeviceManager::initialize()
177 {
178     assert(m_1394Services.size() == 0);
179     assert(m_busreset_functors.size() == 0);
180
181     m_configuration->openFile( "temporary", Util::Configuration::eFM_Temporary );
182     m_configuration->openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadWrite );
183     m_configuration->openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly );
184
185     int nb_detected_ports = Ieee1394Service::detectNbPorts();
186     if (nb_detected_ports < 0) {
187         debugFatal("Failed to detect the number of 1394 adapters. Is the IEEE1394 stack loaded (raw1394)?\n");
188         return false;
189     }
190     if (nb_detected_ports == 0) {
191         debugFatal("No firewire adapters (ports) found.\n");
192         return false;
193     }
194     debugOutput( DEBUG_LEVEL_VERBOSE, "Found %d firewire adapters (ports)\n", nb_detected_ports);
195     for (unsigned int port = 0; port < (unsigned int)nb_detected_ports; port++) {
196         Ieee1394Service* tmp1394Service = new Ieee1394Service();
197         if ( !tmp1394Service ) {
198             debugFatal( "Could not create Ieee1349Service object for port %d\n", port );
199             return false;
200         }
201         tmp1394Service->setVerboseLevel( getDebugLevel() );
202         m_1394Services.push_back(tmp1394Service);
203
204         if(!tmp1394Service->useConfiguration(m_configuration)) {
205             debugWarning("Could not load config to 1394service\n");
206         }
207
208         tmp1394Service->setThreadParameters(m_thread_realtime, m_thread_priority);
209         if ( !tmp1394Service->initialize( port ) ) {
210             debugFatal( "Could not initialize Ieee1349Service object for port %d\n", port );
211             return false;
212         }
213         // add the bus reset handler
214         Util::Functor* tmp_busreset_functor = new Util::MemberFunctor1< DeviceManager*,
215                     void (DeviceManager::*)(Ieee1394Service &), Ieee1394Service & >
216                     ( this, &DeviceManager::busresetHandler, *tmp1394Service, false );
217         if ( !tmp_busreset_functor ) {
218             debugFatal( "Could not create busreset handler for port %d\n", port );
219             return false;
220         }
221         m_busreset_functors.push_back(tmp_busreset_functor);
222
223         tmp1394Service->addBusResetHandler( tmp_busreset_functor );
224     }
225
226     return true;
227 }
228
229 bool
230 DeviceManager::addSpecString(char *s) {
231     std::string spec = s;
232     if(isSpecStringValid(spec)) {
233         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding spec string %s\n", spec.c_str());
234         assert(m_deviceStringParser);
235         m_deviceStringParser->parseString(spec);
236         return true;
237     } else {
238         debugError("Invalid spec string: %s\n", spec.c_str());
239         return false;
240     }
241 }
242
243 bool
244 DeviceManager::isSpecStringValid(std::string s) {
245     assert(m_deviceStringParser);
246     return m_deviceStringParser->isValidString(s);
247 }
248
249 void
250 DeviceManager::busresetHandler(Ieee1394Service &service)
251 {
252     // serialize bus reset handling since it can be that a new one occurs while we're
253     // doing stuff.
254     debugOutput( DEBUG_LEVEL_NORMAL, "Bus reset detected on service %p...\n", &service );
255     Util::MutexLockHelper lock(*m_BusResetLock);
256     debugOutput( DEBUG_LEVEL_NORMAL, " handling busreset...\n" );
257
258     // FIXME: what if the devices are gone? (device should detect this!)
259     // propagate the bus reset to all avDevices
260     m_DeviceListLock->Lock(); // make sure nobody is using this
261     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
262           it != m_avDevices.end();
263           ++it )
264     {
265         if(&service == &((*it)->get1394Service())) {
266             debugOutput(DEBUG_LEVEL_NORMAL,
267                         "issue busreset on device GUID %s\n",
268                         (*it)->getConfigRom().getGuidString().c_str());
269             (*it)->handleBusReset();
270         } else {
271             debugOutput(DEBUG_LEVEL_NORMAL,
272                         "skipping device GUID %s since not on service %p\n",
273                         (*it)->getConfigRom().getGuidString().c_str(), &service);
274         }
275     }
276     m_DeviceListLock->Unlock();
277
278     // now that the devices have been updates, we can request to update the iso streams
279     if(!service.getIsoHandlerManager().handleBusReset()) {
280         debugError("IsoHandlerManager failed to handle busreset\n");
281     }
282
283     // notify the streamprocessormanager of the busreset
284 //     if(m_processorManager) {
285 //         m_processorManager->handleBusReset(service);
286 //     } else {
287 //         debugWarning("No valid SPM\n");
288 //     }
289
290     // rediscover to find new devices
291     // (only for the control server ATM, streaming can't dynamically add/remove devices)
292     if(!discover(m_used_cache_last_time, true)) {
293         debugError("Could not rediscover devices\n");
294     }
295
296     // notify any clients
297     signalNotifiers(m_busResetNotifiers);
298
299     // display the new state
300     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
301         showDeviceInfo();
302     }
303 }
304
305 void
306 DeviceManager::signalNotifiers(notif_vec_t& list)
307 {
308     for ( notif_vec_t::iterator it = list.begin();
309           it != list.end();
310           ++it )
311     {
312         Util::Functor* func = *it;
313         debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
314         ( *func )();
315     }
316 }
317
318 bool
319 DeviceManager::registerNotification(notif_vec_t& list, Util::Functor *handler)
320 {
321     debugOutput( DEBUG_LEVEL_VERBOSE, "register %p...\n", handler);
322     assert(handler);
323     for ( notif_vec_t::iterator it = list.begin();
324       it != list.end();
325       ++it )
326     {
327         if ( *it == handler ) {
328             debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
329             return false;
330         }
331     }
332     list.push_back(handler);
333     return true;
334 }
335
336 bool
337 DeviceManager::unregisterNotification(notif_vec_t& list, Util::Functor *handler)
338 {
339     debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
340     assert(handler);
341
342     for ( notif_vec_t::iterator it = list.begin();
343       it != list.end();
344       ++it )
345     {
346         if ( *it == handler ) {
347             list.erase(it);
348             return true;
349         }
350     }
351     debugError("Could not find handler (%p)\n", handler);
352     return false; //not found
353 }
354
355 bool
356 DeviceManager::discover( bool useCache, bool rediscover )
357 {
358     debugOutput( DEBUG_LEVEL_NORMAL, "Starting discovery...\n" );
359     useCache = useCache && ENABLE_DISCOVERY_CACHE;
360     m_used_cache_last_time = useCache;
361     bool slaveMode=false;
362     if(!getOption("slaveMode", slaveMode)) {
363         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
364     }
365     bool snoopMode=false;
366     if(!getOption("snoopMode", snoopMode)) {
367         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
368     }
369
370     setVerboseLevel(getDebugLevel());
371
372     // FIXME: it could be that a 1394service has disappeared (cardbus)
373
374     ConfigRomVector configRoms;
375     // build a list of configroms on the bus.
376     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
377         it != m_1394Services.end();
378         ++it )
379     {
380         Ieee1394Service *portService = *it;
381         for ( fb_nodeid_t nodeId = 0;
382             nodeId < portService->getNodeCount();
383             ++nodeId )
384         {
385             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
386
387             if (nodeId == portService->getLocalNodeId()) {
388                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
389                 continue;
390             }
391
392             ConfigRom * configRom = new ConfigRom( *portService, nodeId );
393             if ( !configRom->initialize() ) {
394                 // \todo If a PHY on the bus is in power safe mode then
395                 // the config rom is missing. So this might be just
396                 // such this case and we can safely skip it. But it might
397                 // be there is a real software problem on our side.
398                 // This should be handlede more carefuly.
399                 debugOutput( DEBUG_LEVEL_NORMAL,
400                             "Could not read config rom from device (node id %d). "
401                             "Skip device discovering for this node\n",
402                             nodeId );
403                 continue;
404             }
405             configRoms.push_back(configRom);
406         }
407     }
408
409
410     // notify that we are going to manipulate the list
411     signalNotifiers(m_preUpdateNotifiers);
412     m_DeviceListLock->Lock(); // make sure nobody starts using the list
413     if(rediscover) {
414
415         FFADODeviceVector discovered_devices_on_bus;
416         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
417             it != m_avDevices.end();
418             ++it )
419         {
420             bool seen_device = false;
421             for ( ConfigRomVectorIterator it2 = configRoms.begin();
422                 it2 != configRoms.end();
423                 ++it2 )
424             {
425                 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
426             }
427
428             if(seen_device) {
429                 debugOutput( DEBUG_LEVEL_VERBOSE,
430                             "Already discovered device with GUID: %s\n",
431                             (*it)->getConfigRom().getGuidString().c_str() );
432                 // we already discovered this device, and it is still here. keep it
433                 discovered_devices_on_bus.push_back(*it);
434             } else {
435                 debugOutput( DEBUG_LEVEL_VERBOSE,
436                             "Device with GUID: %s disappeared from bus, removing...\n",
437                             (*it)->getConfigRom().getGuidString().c_str() );
438
439                 // the device has disappeared, remove it from the control tree
440                 if (!deleteElement(*it)) {
441                     debugWarning("failed to remove Device from Control::Container\n");
442                 }
443                 // delete the device
444                 // FIXME: this will mess up the any code that waits for bus resets to
445                 //        occur
446                 delete *it;
447             }
448         }
449         // prune the devices that disappeared
450         m_avDevices = discovered_devices_on_bus;
451     } else { // remove everything since we are not rediscovering
452         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
453             it != m_avDevices.end();
454             ++it )
455         {
456             if (!deleteElement(*it)) {
457                 debugWarning("failed to remove Device from Control::Container\n");
458             }
459             delete *it;
460         }
461
462         m_avDevices.clear();
463     }
464
465     // delete the config rom list entries
466     // FIXME: we should reuse it
467     for ( ConfigRomVectorIterator it = configRoms.begin();
468         it != configRoms.end();
469         ++it )
470     {
471         delete *it;
472     }
473
474     assert(m_deviceStringParser);
475     // show the spec strings we're going to use
476     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
477         m_deviceStringParser->show();
478     }
479
480     if (!slaveMode) {
481         // for the devices that are still in the list check if they require re-discovery
482         FFADODeviceVector failed_to_rediscover;
483         for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
484             it_dev != m_avDevices.end();
485             ++it_dev )
486         {
487             FFADODevice* avDevice = *it_dev;
488             if(avDevice->needsRediscovery()) {
489                 debugOutput( DEBUG_LEVEL_NORMAL,
490                              "Device with GUID %s requires rediscovery (state changed)...\n",
491                              avDevice->getConfigRom().getGuidString().c_str());
492
493                 bool isFromCache = false;
494                 if ( useCache && avDevice->loadFromCache() ) {
495                     debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
496                     isFromCache = true;
497                     // restore the debug level for everything that was loaded
498                     avDevice->setVerboseLevel( getDebugLevel() );
499                 } else if ( avDevice->discover() ) {
500                     debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
501                 } else {
502                     debugError( "could not discover device\n" );
503                     failed_to_rediscover.push_back(avDevice);
504                     continue;
505                 }
506                 if ( !isFromCache && !avDevice->saveCache() ) {
507                     debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
508                 }
509             } else {
510                 debugOutput( DEBUG_LEVEL_NORMAL,
511                              "Device with GUID %s does not require rediscovery...\n",
512                              avDevice->getConfigRom().getGuidString().c_str());
513             }
514         }
515         // remove devices that failed to rediscover
516         // FIXME: surely there has to be a better way to do this
517         FFADODeviceVector to_keep;
518         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
519             it != m_avDevices.end();
520             ++it )
521         {
522             bool keep_this_device = true;
523             for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
524                 it2 != failed_to_rediscover.end();
525                 ++it2 )
526             {
527                 if(*it == *it2) {
528                     debugOutput( DEBUG_LEVEL_NORMAL,
529                                 "Removing device with GUID %s due to failed discovery...\n",
530                                 (*it)->getConfigRom().getGuidString().c_str());
531                     keep_this_device = false;
532                     break;
533                 }
534             }
535             if(keep_this_device) {
536                 to_keep.push_back(*it);
537             }
538         }
539         for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin();
540             it2 != failed_to_rediscover.end();
541             ++it2 )
542         {
543             if (!deleteElement(*it2)) {
544                 debugWarning("failed to remove Device from Control::Container\n");
545             }
546             delete *it2;
547         }
548         m_avDevices = to_keep;
549
550         // pick up new devices
551         for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
552             it != m_1394Services.end();
553             ++it )
554         {
555             Ieee1394Service *portService = *it;
556             for ( fb_nodeid_t nodeId = 0;
557                 nodeId < portService->getNodeCount();
558                 ++nodeId )
559             {
560                 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
561    
562                 if (nodeId == portService->getLocalNodeId()) {
563                     debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
564                     continue;
565                 }
566    
567                 ConfigRom *configRom = new ConfigRom( *portService, nodeId );
568                 if ( !configRom->initialize() ) {
569                     // \todo If a PHY on the bus is in power safe mode then
570                     // the config rom is missing. So this might be just
571                     // such this case and we can safely skip it. But it might
572                     // be there is a real software problem on our side.
573                     // This should be handlede more carefuly.
574                     debugOutput( DEBUG_LEVEL_NORMAL,
575                                 "Could not read config rom from device (node id %d). "
576                                 "Skip device discovering for this node\n",
577                                 nodeId );
578                     continue;
579                 }
580
581                 bool already_in_vector = false;
582                 for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin();
583                     it_dev != m_avDevices.end();
584                     ++it_dev )
585                 {
586                     if ((*it_dev)->getConfigRom().getGuid() == configRom->getGuid()) {
587                         already_in_vector = true;
588                         break;
589                     }
590                 }
591                 if(already_in_vector) {
592                     if(!rediscover) {
593                         debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
594                                     configRom->getGuidString().c_str());
595                     }
596                     continue;
597                 }
598
599                 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
600                     configRom->printConfigRomDebug();
601                 }
602
603                 // if spec strings are given, only add those devices
604                 // that match the spec string(s).
605                 // if no (valid) spec strings are present, grab all
606                 // supported devices.
607                 if(m_deviceStringParser->countDeviceStrings() &&
608                   !m_deviceStringParser->match(*configRom)) {
609                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
610                     continue;
611                 }
612
613                 // find a driver
614                 FFADODevice* avDevice = getDriverForDevice( configRom,
615                                                             nodeId );
616
617                 if ( avDevice ) {
618                     debugOutput( DEBUG_LEVEL_NORMAL,
619                                 "driver found for device %d\n",
620                                 nodeId );
621
622                     avDevice->setVerboseLevel( getDebugLevel() );
623                     bool isFromCache = false;
624                     if ( useCache && avDevice->loadFromCache() ) {
625                         debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
626                         isFromCache = true;
627                         // restore the debug level for everything that was loaded
628                         avDevice->setVerboseLevel( getDebugLevel() );
629                     } else if ( avDevice->discover() ) {
630                         debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
631                     } else {
632                         debugError( "could not discover device\n" );
633                         delete avDevice;
634                         continue;
635                     }
636
637                     if (snoopMode) {
638                         debugOutput( DEBUG_LEVEL_VERBOSE,
639                                     "Enabling snoop mode on node %d...\n", nodeId );
640
641                         if(!avDevice->setOption("snoopMode", snoopMode)) {
642                             debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
643                             delete avDevice;
644                             continue;
645                         }
646                     }
647
648                     if ( !isFromCache && !avDevice->saveCache() ) {
649                         debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
650                     }
651                     m_avDevices.push_back( avDevice );
652
653                     if (!addElement(avDevice)) {
654                         debugWarning("failed to add Device to Control::Container\n");
655                     }
656
657                     debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
658                 } else {
659                     // we didn't get a device, hence we have to delete the configrom ptr manually
660                     delete configRom;
661                 }
662             }
663         }
664
665         debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
666         // FIXME: do better sorting
667         // sort the m_avDevices vector on their GUID
668         // then assign reassign the id's to the devices
669         // the side effect of this is that for the same set of attached devices,
670         // a device id always corresponds to the same device
671         sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
672
673         int i=0;
674         if(m_deviceStringParser->countDeviceStrings()) { // only if there are devicestrings
675             // first map the devices to a position using the device spec strings
676             std::map<fb_octlet_t, int> positionMap;
677             for ( FFADODeviceVectorIterator it = m_avDevices.begin();
678                 it != m_avDevices.end();
679                 ++it )
680             {
681                 int pos = m_deviceStringParser->matchPosition((*it)->getConfigRom());
682                 fb_octlet_t guid = (*it)->getConfigRom().getGuid();
683                 positionMap[guid] = pos;
684                 debugOutput( DEBUG_LEVEL_VERBOSE, "Mapping %s to position %d...\n", (*it)->getConfigRom().getGuidString().c_str(), pos );
685             }
686    
687             // now run over all positions, and add the devices that belong to it
688             FFADODeviceVector sorted;
689             int nbPositions = m_deviceStringParser->countDeviceStrings();
690             for (i=0; i < nbPositions; i++) {
691                 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
692                     it != m_avDevices.end();
693                     ++it )
694                 {
695                     fb_octlet_t guid = (*it)->getConfigRom().getGuid();
696                     if(positionMap[guid] == i) {
697                         sorted.push_back(*it);
698                     }
699                 }
700             }
701             // assign the new vector
702             flushDebugOutput();
703             assert(sorted.size() == m_avDevices.size());
704             m_avDevices = sorted;
705         }
706
707         // set device id's
708         i = 0;
709         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
710             it != m_avDevices.end();
711             ++it )
712         {
713             if ( !(*it)->setId( i++ ) ) {
714                 debugError( "setting Id failed\n" );
715             }
716         }
717         showDeviceInfo();
718
719     } else { // slave mode
720         // notify any clients
721         signalNotifiers(m_preUpdateNotifiers);
722         Ieee1394Service *portService = m_1394Services.at(0);
723         fb_nodeid_t nodeId = portService->getLocalNodeId();
724         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
725
726         std::auto_ptr<ConfigRom> configRom =
727             std::auto_ptr<ConfigRom>( new ConfigRom( *portService,
728                                                      nodeId ) );
729         if ( !configRom->initialize() ) {
730             // \todo If a PHY on the bus is in power safe mode then
731             // the config rom is missing. So this might be just
732             // such this case and we can safely skip it. But it might
733             // be there is a real software problem on our side.
734             // This should be handled more carefuly.
735             debugOutput( DEBUG_LEVEL_NORMAL,
736                          "Could not read config rom from device (node id %d). "
737                          "Skip device discovering for this node\n",
738                          nodeId );
739             return false;
740         }
741
742         // remove any already present devices
743         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
744             it != m_avDevices.end();
745             ++it )
746         {
747             if (!deleteElement(*it)) {
748                 debugWarning("failed to remove Device from Control::Container\n");
749             }
750             delete *it;
751         }
752
753         m_avDevices.clear();
754
755         // get the slave driver
756         FFADODevice* avDevice = getSlaveDriver( configRom );
757         if ( avDevice ) {
758             debugOutput( DEBUG_LEVEL_NORMAL,
759                          "driver found for device %d\n",
760                          nodeId );
761
762             avDevice->setVerboseLevel( getDebugLevel() );
763
764             if ( !avDevice->discover() ) {
765                 debugError( "could not discover device\n" );
766                 delete avDevice;
767                 return false;
768             }
769
770             if ( !avDevice->setId( m_avDevices.size() ) ) {
771                 debugError( "setting Id failed\n" );
772             }
773             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
774                 avDevice->showDevice();
775             }
776             m_avDevices.push_back( avDevice );
777             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
778         }
779
780         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
781     }
782
783     m_DeviceListLock->Unlock();
784     // notify any clients
785     signalNotifiers(m_postUpdateNotifiers);
786     return true;
787 }
788
789 bool
790 DeviceManager::initStreaming()
791 {
792     // iterate over the found devices
793     // add the stream processors of the devices to the managers
794     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
795         it != m_avDevices.end();
796         ++it )
797     {
798         FFADODevice *device = *it;
799         assert(device);
800
801         debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
802
803         if (!device->lock()) {
804             debugWarning("Could not lock device, skipping device (%p)!\n", device);
805             continue;
806         }
807
808         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
809                     m_processorManager->getNominalRate(), device);
810
811         // Set the device's sampling rate to that requested
812         // FIXME: does this really belong here?  If so we need to handle errors.
813         if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
814             debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
815                         m_processorManager->getNominalRate(), device);
816
817             // try again:
818             if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
819                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
820                 return false;
821             }
822         }
823         // prepare the device
824         device->prepare();
825     }
826
827     // set the sync source
828     if (!m_processorManager->setSyncSource(getSyncSource())) {
829         debugWarning("Could not set processorManager sync source (%p)\n",
830             getSyncSource());
831     }
832
833     return true;
834 }
835
836 bool
837 DeviceManager::prepareStreaming()
838 {
839     if (!m_processorManager->prepare()) {
840         debugFatal("Could not prepare streaming...\n");
841         return false;
842     }
843     return true;
844 }
845
846 bool
847 DeviceManager::finishStreaming() {
848     bool result = true;
849     // iterate over the found devices
850     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
851         it != m_avDevices.end();
852         ++it )
853     {
854         debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
855
856         if (!(*it)->unlock()) {
857             debugWarning("Could not unlock device (%p)!\n", *it);
858             result = false;
859         }
860     }
861     return result;
862 }
863
864 bool
865 DeviceManager::startStreamingOnDevice(FFADODevice *device)
866 {
867     assert(device);
868
869     int j=0;
870     bool all_streams_started = true;
871     bool device_start_failed = false;
872     for(j=0; j < device->getStreamCount(); j++) {
873         debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
874         // start the stream
875         if (!device->startStreamByIndex(j)) {
876             debugWarning("Could not start stream %d of device %p\n", j, device);
877             all_streams_started = false;
878             break;
879         }
880     }
881
882     if(!all_streams_started) {
883         // disable all streams that did start up correctly
884         for(j = j-1; j >= 0; j--) {
885             debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
886             // stop the stream
887             if (!device->stopStreamByIndex(j)) {
888                 debugWarning("Could not stop stream %d of device %p\n", j, device);
889             }
890         }
891         device_start_failed = true;
892     } else {
893         if (!device->enableStreaming()) {
894             debugWarning("Could not enable streaming on device %p!\n", device);
895             device_start_failed = true;
896         }
897     }
898     return !device_start_failed;
899 }
900
901 bool
902 DeviceManager::startStreaming() {
903     bool device_start_failed = false;
904     FFADODeviceVectorIterator it;
905
906     // create the connections for all devices
907     // iterate over the found devices
908     for ( it = m_avDevices.begin();
909         it != m_avDevices.end();
910         ++it )
911     {
912         if (!startStreamingOnDevice(*it)) {
913             debugWarning("Could not start streaming on device %p!\n", *it);
914             device_start_failed = true;
915             break;
916         }
917     }
918
919     // if one of the devices failed to start,
920     // the previous routine should have cleaned up the failing one.
921     // we still have to stop all devices that were started before this one.
922     if(device_start_failed) {
923         for (FFADODeviceVectorIterator it2 = m_avDevices.begin();
924             it2 != it;
925             ++it2 )
926         {
927             if (!stopStreamingOnDevice(*it2)) {
928                 debugWarning("Could not stop streaming on device %p!\n", *it2);
929             }
930         }
931         return false;
932     }
933
934     // start the stream processor manager to tune in to the channels
935     if(m_processorManager->start()) {
936         return true;
937     } else {
938         debugWarning("Failed to start SPM!\n");
939         for( it = m_avDevices.begin();
940              it != m_avDevices.end();
941              ++it )
942         {
943             if (!stopStreamingOnDevice(*it)) {
944                 debugWarning("Could not stop streaming on device %p!\n", *it);
945             }
946         }
947         return false;
948     }
949 }
950
951 bool
952 DeviceManager::resetStreaming() {
953     return true;
954 }
955
956 bool
957 DeviceManager::stopStreamingOnDevice(FFADODevice *device)
958 {
959     assert(device);
960     bool result = true;
961
962     if (!device->disableStreaming()) {
963         debugWarning("Could not disable streaming on device %p!\n", device);
964     }
965
966     int j=0;
967     for(j=0; j < device->getStreamCount(); j++) {
968         debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
969         // stop the stream
970         // start the stream
971         if (!device->stopStreamByIndex(j)) {
972             debugWarning("Could not stop stream %d of device %p\n", j, device);
973             result = false;
974             continue;
975         }
976     }
977     return result;
978 }
979
980 bool
981 DeviceManager::stopStreaming()
982 {
983     bool result = true;
984     m_processorManager->stop();
985
986     // create the connections for all devices
987     // iterate over the found devices
988     // add the stream processors of the devices to the managers
989     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
990         it != m_avDevices.end();
991         ++it )
992     {
993         stopStreamingOnDevice(*it);
994     }
995     return result;
996 }
997
998 enum DeviceManager::eWaitResult
999 DeviceManager::waitForPeriod() {
1000     if(m_processorManager->waitForPeriod()) {
1001         return eWR_OK;
1002     } else {
1003         if(m_processorManager->shutdownNeeded()) {
1004             debugWarning("Shutdown requested\n");
1005             return eWR_Shutdown;
1006         } else {
1007             debugWarning("XRUN detected\n");
1008             // do xrun recovery
1009             if(m_processorManager->handleXrun()) {
1010                 return eWR_Xrun;
1011             } else {
1012                 debugError("Could not handle XRUN\n");
1013                 return eWR_Error;
1014             }
1015         }
1016     }
1017 }
1018
1019 bool
1020 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
1021     m_processorManager->setPeriodSize(period);
1022     m_processorManager->setNominalRate(rate);
1023     m_processorManager->setNbBuffers(nb_buffers);
1024     return true;
1025 }
1026
1027 FFADODevice*
1028 DeviceManager::getDriverForDeviceDo( ConfigRom *configRom,
1029                                    int id, bool generic )
1030 {
1031 #ifdef ENABLE_BEBOB
1032     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
1033     if ( BeBoB::Device::probe( getConfiguration(), *configRom, generic ) ) {
1034         return BeBoB::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1035     }
1036 #endif
1037
1038 #ifdef ENABLE_FIREWORKS
1039     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
1040     if ( FireWorks::Device::probe( getConfiguration(), *configRom, generic ) ) {
1041         return FireWorks::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1042     }
1043 #endif
1044
1045 #ifdef ENABLE_OXFORD
1046     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Oxford FW90x...\n" );
1047     if ( Oxford::Device::probe( getConfiguration(), *configRom, generic ) ) {
1048         return Oxford::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1049     }
1050 #endif
1051
1052 #ifdef ENABLE_MAUDIO
1053     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
1054     if ( MAudio::Device::probe( getConfiguration(), *configRom, generic ) ) {
1055         return MAudio::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1056     }
1057 #endif
1058
1059 // we want to try the non-generic AV/C platforms before trying the generic ones
1060 #ifdef ENABLE_GENERICAVC
1061     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
1062     if ( GenericAVC::Device::probe( getConfiguration(), *configRom, generic ) ) {
1063         return GenericAVC::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1064     }
1065 #endif
1066
1067 #ifdef ENABLE_MOTU
1068     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
1069     if ( Motu::MotuDevice::probe( getConfiguration(), *configRom, generic ) ) {
1070         return Motu::MotuDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1071     }
1072 #endif
1073
1074 #ifdef ENABLE_DICE
1075     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
1076     if ( Dice::Device::probe( getConfiguration(), *configRom, generic ) ) {
1077         return Dice::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1078     }
1079 #endif
1080
1081 #ifdef ENABLE_METRIC_HALO
1082     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
1083     if ( MetricHalo::Device::probe( getConfiguration(), *configRom, generic ) ) {
1084         return MetricHalo::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1085     }
1086 #endif
1087
1088 #ifdef ENABLE_RME
1089     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
1090     if ( Rme::Device::probe( getConfiguration(), *configRom, generic ) ) {
1091         return Rme::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1092     }
1093 #endif
1094
1095 #ifdef ENABLE_BOUNCE
1096     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
1097     if ( Bounce::Device::probe( getConfiguration(), *configRom, generic ) ) {
1098         return Bounce::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) );
1099     }
1100 #endif
1101
1102     return NULL;
1103 }
1104
1105 FFADODevice*
1106 DeviceManager::getDriverForDevice( ConfigRom *configRom,
1107                                    int id )
1108 {
1109     debugOutput( DEBUG_LEVEL_VERBOSE, "Probing for supported device...\n" );
1110     FFADODevice* dev = getDriverForDeviceDo(configRom, id, false);
1111     if(dev) {
1112         debugOutput( DEBUG_LEVEL_VERBOSE, " found supported device...\n" );
1113         dev->setVerboseLevel(getDebugLevel());
1114         return dev;
1115     }
1116
1117     debugOutput( DEBUG_LEVEL_VERBOSE, " no supported device found, trying generic support...\n" );
1118     dev = getDriverForDeviceDo(configRom, id, true);
1119     if(dev) {
1120         debugOutput( DEBUG_LEVEL_VERBOSE, " found generic support for device...\n" );
1121         dev->setVerboseLevel(getDebugLevel());
1122         return dev;
1123     }
1124     debugOutput( DEBUG_LEVEL_VERBOSE, " device not supported...\n" );
1125     return NULL;
1126 }
1127
1128 FFADODevice*
1129 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
1130 {
1131 #ifdef ENABLE_BOUNCE
1132     if ( Bounce::SlaveDevice::probe( getConfiguration(), *configRom, false ) ) {
1133         return Bounce::SlaveDevice::createDevice(  *this, std::auto_ptr<ConfigRom>( configRom ) );
1134     }
1135 #endif
1136     return NULL;
1137 }
1138
1139 bool
1140 DeviceManager::isValidNode(int node)
1141 {
1142     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1143           it != m_avDevices.end();
1144           ++it )
1145     {
1146         FFADODevice* avDevice = *it;
1147
1148         if (avDevice->getConfigRom().getNodeId() == node) {
1149             return true;
1150     }
1151     }
1152     return false;
1153 }
1154
1155 int
1156 DeviceManager::getNbDevices()
1157 {
1158     return m_avDevices.size();
1159 }
1160
1161 int
1162 DeviceManager::getDeviceNodeId( int deviceNr )
1163 {
1164     if ( ! ( deviceNr < getNbDevices() ) ) {
1165         debugError( "Device number out of range (%d)\n", deviceNr );
1166         return -1;
1167     }
1168
1169     FFADODevice* avDevice = m_avDevices.at( deviceNr );
1170
1171     if ( !avDevice ) {
1172         debugError( "Could not get device at position (%d)\n",  deviceNr );
1173     }
1174
1175     return avDevice->getConfigRom().getNodeId();
1176 }
1177
1178 FFADODevice*
1179 DeviceManager::getAvDevice( int nodeId )
1180 {
1181     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1182           it != m_avDevices.end();
1183           ++it )
1184     {
1185         FFADODevice* avDevice = *it;
1186         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
1187             return avDevice;
1188         }
1189     }
1190
1191     return 0;
1192 }
1193
1194 FFADODevice*
1195 DeviceManager::getAvDeviceByIndex( int idx )
1196 {
1197     return m_avDevices.at(idx);
1198 }
1199
1200 unsigned int
1201 DeviceManager::getAvDeviceCount( )
1202 {
1203     return m_avDevices.size();
1204 }
1205
1206 /**
1207  * Return the streamprocessor that is to be used as
1208  * the sync source.
1209  *
1210  * Algorithm still to be determined
1211  *
1212  * @return StreamProcessor that is sync source
1213  */
1214 Streaming::StreamProcessor *
1215 DeviceManager::getSyncSource() {
1216     FFADODevice* device = getAvDeviceByIndex(0);
1217
1218     bool slaveMode=false;
1219     if(!getOption("slaveMode", slaveMode)) {
1220         debugOutput(DEBUG_LEVEL_NORMAL,
1221                     "Could not retrieve slaveMode parameter, defauling to false\n");
1222     }
1223     return device->getStreamProcessorByIndex(0);
1224 /*
1225     #warning TEST CODE FOR BOUNCE DEVICE !!
1226     // this makes the bounce slave use the xmit SP as sync source
1227     if (slaveMode) {
1228         return device->getStreamProcessorByIndex(1);
1229     } else {
1230         return device->getStreamProcessorByIndex(0);
1231     }*/
1232 }
1233
1234 bool
1235 DeviceManager::deinitialize()
1236 {
1237     return true;
1238 }
1239
1240 void
1241 DeviceManager::setVerboseLevel(int l)
1242 {
1243     setDebugLevel(l);
1244     Control::Element::setVerboseLevel(l);
1245     m_processorManager->setVerboseLevel(l);
1246     m_deviceStringParser->setVerboseLevel(l);
1247     m_configuration->setVerboseLevel(l);
1248     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1249           it != m_avDevices.end();
1250           ++it )
1251     {
1252         (*it)->setVerboseLevel(l);
1253     }
1254     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1255           it != m_1394Services.end();
1256           ++it )
1257     {
1258         (*it)->setVerboseLevel(l);
1259     }
1260     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1261 }
1262
1263 void
1264 DeviceManager::showDeviceInfo() {
1265     debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
1266     Control::Element::show();
1267
1268     int i=0;
1269     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
1270           it != m_1394Services.end();
1271           ++it )
1272     {
1273         debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
1274         (*it)->show();
1275     }
1276
1277     i=0;
1278     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
1279         it != m_avDevices.end();
1280         ++it )
1281     {
1282         FFADODevice* avDevice = *it;
1283         debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
1284         avDevice->showDevice();
1285
1286         debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
1287         FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
1288         for ( FFADODevice::ClockSourceVector::const_iterator it
1289                 = sources.begin();
1290             it != sources.end();
1291             ++it )
1292         {
1293             FFADODevice::ClockSource c=*it;
1294             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
1295                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
1296         }
1297     }
1298 }
1299 void
1300 DeviceManager::showStreamingInfo() {
1301     m_processorManager->dumpInfo();
1302 }
Note: See TracBrowser for help on using the browser.