root/branches/libffado-2.0/src/devicemanager.cpp

Revision 1561, 40.6 kB (checked in by ppalmers, 3 years ago)

fixes #211

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