root/trunk/libffado/src/devicemanager.cpp

Revision 1535, 39.4 kB (checked in by ppalmers, 15 years ago)

add support for the FCA-202, and possibly other Oxford FW-92x devices

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