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

Revision 384, 12.7 kB (checked in by pieterpalmers, 17 years ago)

- temporary commit as backup measure
- rewrote synchronisation code
- receive streaming based on SYT works
- transmit streaming synced to received stream sort of works, still

have to iron out some issues.

NOTE: all devices but the bebob's are disabled in this code,

because they still have to be ported to the new sync
mechanism.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1  /* devicemanager.cpp
2  * Copyright (C) 2005,06,07 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "fbtypes.h"
22
23 #include "devicemanager.h"
24 #include "iavdevice.h"
25 #include "configrom.h"
26
27 #include "libfreebobavc/ieee1394service.h"
28 #include "debugmodule/debugmodule.h"
29 #include "bebob/bebob_avdevice.h"
30 #include "bounce/bounce_avdevice.h"
31 #include "motu/motu_avdevice.h"
32 #include "rme/rme_avdevice.h"
33 #include "maudio/maudio_avdevice.h"
34
35 #include <iostream>
36 #include <sstream>
37
38 #include <unistd.h>
39
40 using namespace std;
41
42 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
43
44 DeviceManager::DeviceManager()
45     : m_1394Service( 0 )
46 {
47
48 }
49
50 DeviceManager::~DeviceManager()
51 {
52     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
53           it != m_avDevices.end();
54           ++it )
55     {
56         delete *it;
57     }
58
59     delete m_1394Service;
60 }
61
62 bool
63 DeviceManager::initialize( int port )
64 {
65     m_1394Service = new Ieee1394Service();
66     if ( !m_1394Service ) {
67         debugFatal( "Could not create Ieee1349Service object\n" );
68         return false;
69     }
70
71     if ( !m_1394Service->initialize( port ) ) {
72         debugFatal( "Could not initialize Ieee1349Service object\n" );
73         delete m_1394Service;
74         m_1394Service = 0;
75         return false;
76     }
77
78     return true;
79 }
80
81 bool
82 DeviceManager::discover( int verboseLevel )
83 {
84
85     setDebugLevel( verboseLevel );
86     m_1394Service->setVerbose( verboseLevel );
87
88     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
89           it != m_avDevices.end();
90           ++it )
91     {
92         delete *it;
93     }
94     m_avDevices.clear();
95
96     for ( fb_nodeid_t nodeId = 0;
97           nodeId < m_1394Service->getNodeCount();
98           ++nodeId )
99     {
100         debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
101
102         std::auto_ptr<ConfigRom> configRom =
103             std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
104                                                      nodeId ) );
105         if ( !configRom->initialize() ) {
106             // \todo If a PHY on the bus is in power safe mode then
107             // the config rom is missing. So this might be just
108             // such this case and we can safely skip it. But it might
109             // be there is a real software problem on our side.
110             // This should be handled more carefuly.
111             debugOutput( DEBUG_LEVEL_NORMAL,
112                          "Could not read config rom from device (node id %d). "
113                          "Skip device discovering for this node\n",
114                          nodeId );
115             continue;
116         }
117
118         IAvDevice* avDevice = getDriverForDevice( configRom,
119                                                   nodeId,
120                                                   verboseLevel );
121         if ( avDevice ) {
122             debugOutput( DEBUG_LEVEL_NORMAL,
123                          "discover: driver found for device %d\n",
124                          nodeId );
125
126             if ( !avDevice->discover() ) {
127                 debugError( "discover: could not discover device\n" );
128                 delete avDevice;
129                 continue;
130             }
131
132             if ( !avDevice->setId( m_avDevices.size() ) ) {
133                 debugError( "setting Id failed\n" );
134             }
135             if ( verboseLevel ) {
136                 avDevice->showDevice();
137             }
138
139             m_avDevices.push_back( avDevice );
140         }
141     }
142
143     return true;
144 }
145
146
147 IAvDevice*
148 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
149                                    int id,  int level )
150 {
151     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
152         return new BeBoB::AvDevice( configRom, *m_1394Service, id, level );
153     }
154
155 #ifdef ENABLE_MOTU
156     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
157         return new MAudio::AvDevice( configRom, *m_1394Service, id, level );
158     }
159
160
161     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
162         return new Motu::MotuDevice( configRom, *m_1394Service, id, level );
163     }
164
165     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
166         return new Rme::RmeDevice( configRom, *m_1394Service, id, level );
167     }
168
169     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
170         return new Bounce::BounceDevice( configRom, *m_1394Service, id, level );
171     }
172 #endif
173
174     return 0;
175 }
176
177 bool
178 DeviceManager::isValidNode(int node)
179 {
180     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
181           it != m_avDevices.end();
182           ++it )
183     {
184         IAvDevice* avDevice = *it;
185
186         if (avDevice->getConfigRom().getNodeId() == node) {
187                 return true;
188         }
189     }
190     return false;
191 }
192
193 int
194 DeviceManager::getNbDevices()
195 {
196     return m_avDevices.size();
197 }
198
199 int
200 DeviceManager::getDeviceNodeId( int deviceNr )
201 {
202     if ( ! ( deviceNr < getNbDevices() ) ) {
203         debugError( "Device number out of range (%d)\n", deviceNr );
204         return -1;
205     }
206
207     IAvDevice* avDevice = m_avDevices.at( deviceNr );
208
209     if ( !avDevice ) {
210         debugError( "Could not get device at position (%d)\n",  deviceNr );
211     }
212
213     return avDevice->getConfigRom().getNodeId();
214 }
215
216 IAvDevice*
217 DeviceManager::getAvDevice( int nodeId )
218 {
219     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
220           it != m_avDevices.end();
221           ++it )
222     {
223         IAvDevice* avDevice = *it;
224         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
225             return avDevice;
226         }
227     }
228
229     return 0;
230 }
231
232 IAvDevice*
233 DeviceManager::getAvDeviceByIndex( int idx )
234 {
235         return m_avDevices.at(idx);
236 }
237
238 unsigned int
239 DeviceManager::getAvDeviceCount( )
240 {
241         return m_avDevices.size();
242 }
243
244 xmlDocPtr
245 DeviceManager::getXmlDescription()
246 {
247     xmlDocPtr doc = xmlNewDoc( BAD_CAST "1.0" );
248     if ( !doc ) {
249         debugError( "Couldn't create new xml doc\n" );
250         return 0;
251     }
252
253     xmlNodePtr rootNode = xmlNewNode( 0,  BAD_CAST "FreeBoBConnectionInfo" );
254     if ( !rootNode ) {
255         debugError( "Couldn't create root node\n" );
256         xmlFreeDoc( doc );
257         xmlCleanupParser();
258         return 0;
259     }
260     xmlDocSetRootElement( doc, rootNode );
261
262     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
263           it != m_avDevices.end();
264           ++it )
265     {
266         IAvDevice* avDevice = *it;
267
268         xmlNodePtr deviceNode = xmlNewChild( rootNode, 0,
269                                              BAD_CAST "Device", 0 );
270         if ( !deviceNode ) {
271             debugError( "Couldn't create device node\n" );
272             xmlFreeDoc( doc );
273             xmlCleanupParser();
274             return 0;
275         }
276
277         char* result;
278         asprintf( &result, "%d", avDevice->getConfigRom().getNodeId() );
279         if ( !xmlNewChild( deviceNode,  0,
280                            BAD_CAST "NodeId",  BAD_CAST result ) )
281         {
282             debugError( "Couldn't create 'NodeId' node" );
283             free(result);
284             return 0;
285         }
286         free( result );
287
288         std::string res = "Connection Information for "
289                           + avDevice->getConfigRom().getVendorName()
290                           +", "
291                           + avDevice->getConfigRom().getModelName()
292                           + " configuration";
293         if ( !xmlNewChild( deviceNode,
294                            0,
295                            BAD_CAST "Comment",
296                            BAD_CAST res.c_str() ) ) {
297             debugError( "Couldn't create comment node\n" );
298             xmlFreeDoc( doc );
299             xmlCleanupParser();
300             free(result);
301             return 0;
302         }
303
304         res = avDevice->getConfigRom().getVendorName();
305
306         if ( !xmlNewChild( deviceNode,
307                            0,
308                            BAD_CAST "Vendor",
309                            BAD_CAST res.c_str() ) ) {
310             debugError( "Couldn't create vendor node\n" );
311             xmlFreeDoc( doc );
312             xmlCleanupParser();
313             free(result);
314             return 0;
315         }
316
317         res = avDevice->getConfigRom().getModelName();
318
319         if ( !xmlNewChild( deviceNode,
320                            0,
321                            BAD_CAST "Model",
322                            BAD_CAST res.c_str() ) ) {
323             debugError( "Couldn't create model node\n" );
324             xmlFreeDoc( doc );
325             xmlCleanupParser();
326             free(result);
327             return 0;
328         }
329
330         asprintf( &result, "%08x%08x",
331                   ( quadlet_t )( avDevice->getConfigRom().getGuid() >> 32 ),
332                   ( quadlet_t )( avDevice->getConfigRom().getGuid() & 0xfffffff ) );
333         if ( !xmlNewChild( deviceNode,  0,
334                            BAD_CAST "GUID",  BAD_CAST result ) ) {
335             debugError( "Couldn't create 'GUID' node\n" );
336             xmlFreeDoc( doc );
337             xmlCleanupParser();
338
339             free(result);
340             return 0;
341         }
342         free( result );
343
344
345         if ( !avDevice->addXmlDescription( deviceNode ) ) {
346             debugError( "Adding XML description failed\n" );
347             xmlFreeDoc( doc );
348             xmlCleanupParser();
349             free(result);
350             return 0;
351         }
352
353         free(result);
354     }
355
356     return doc;
357 }
358
359 bool
360 DeviceManager::deinitialize()
361 {
362     return true;
363 }
364
365 bool
366 DeviceManager::saveCache( Glib::ustring fileName )
367 {
368     int i = 0;
369     for ( IAvDeviceVectorIterator it = m_avDevices.begin();
370           it != m_avDevices.end();
371           ++it )
372     {
373         IAvDevice* pAvDevice = *it;
374         BeBoB::AvDevice* pBeBoBDevice = reinterpret_cast< BeBoB::AvDevice* >( pAvDevice );
375         if ( pBeBoBDevice ) {
376             // Let's use a very simple path to find the devices later.
377             // Since under hood there will an xml node name this should
378             // adhere the needed naming rules. Of course we could give it
379             // a good node name and add an attribute but that would mean
380             // we have to expose a bigger interface from IOSerialize/IODesialize,
381             // which is just not needed. KISS.
382             ostringstream strstrm;
383             strstrm << "id" << i;
384             Glib::ustring basePath = "BeBoB/" + strstrm.str() + "/";
385
386             Util::XMLSerialize ser( fileName );
387             pBeBoBDevice->serialize( basePath, ser );
388
389             i++;
390             std::cout << "a bebob device serialized" << std::endl;
391         }
392     }
393     return true;
394 }
395
396 bool
397 DeviceManager::loadCache( Glib::ustring fileName )
398 {
399     Util::XMLDeserialize deser( fileName );
400     BeBoB::AvDevice* pBeBoBDevice = 0;
401     int i = 0;
402
403     typedef std::vector<ConfigRom*> ConfigRomVector;
404     ConfigRomVector configRoms;
405
406     for ( fb_nodeid_t nodeId = 0;
407           nodeId < m_1394Service->getNodeCount();
408           ++nodeId )
409     {
410         ConfigRom* pConfigRom  =  new ConfigRom( *m_1394Service, nodeId );
411         if ( !pConfigRom->initialize() ) {
412             // \todo If a PHY on the bus is in power safe mode then
413             // the config rom is missing. So this might be just
414             // such this case and we can safely skip it. But it might
415             // be there is a real software problem on our side.
416             // This should be handled more carefuly.
417             debugOutput( DEBUG_LEVEL_NORMAL,
418                          "Could not read config rom from device (node id %d). "
419                          "Skip device discovering for this node\n",
420                          nodeId );
421             delete pConfigRom;
422             continue;
423         }
424         configRoms.push_back( pConfigRom );
425     }
426
427     do {
428         ostringstream strstrm;
429         strstrm << "id" << i;
430         pBeBoBDevice = BeBoB::AvDevice::deserialize(
431             "BeBoB/" + strstrm.str() + "/",
432             deser,
433             *m_1394Service );
434
435         ++i;
436         if ( pBeBoBDevice ) {
437             for (ConfigRomVector::iterator it = configRoms.begin();
438                  it != configRoms.end();
439                  ++it )
440             {
441                 ConfigRom* pConfigRom = *it;
442
443                 if ( pBeBoBDevice->getConfigRom() == *pConfigRom ) {
444                     pBeBoBDevice->getConfigRom().setNodeId( pConfigRom->getNodeId() );
445                     // m_avDevices.push_back( pBeBoBDevice );
446
447                 }
448             }
449         }
450     } while ( pBeBoBDevice );
451
452     return true;
453 }
Note: See TracBrowser for help on using the browser.