2 * Copyright (C) 2005-2008 by Daniel Wagner
4 * This file is part of FFADO
5 * FFADO = Free Firewire (pro-)audio drivers for linux
7 * FFADO is based upon FreeBoB
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) version 3 of the License.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "devicemanager.h"
27 #include "bebob/bebob_avdevice.h"
28 #include "bebob/bebob_avdevice_subunit.h"
29 #include "bebob/bebob_mixer.h"
31 #include "bebob/focusrite/focusrite_saffire.h"
32 #include "bebob/focusrite/focusrite_saffirepro.h"
33 #include "bebob/terratec/terratec_device.h"
34 #include "bebob/mackie/onyxmixer.h"
35 #include "bebob/edirol/edirol_fa101.h"
36 #include "bebob/edirol/edirol_fa66.h"
37 #include "bebob/esi/quatafire610.h"
39 #include "libieee1394/configrom.h"
40 #include "libieee1394/ieee1394service.h"
42 #include "libavc/general/avc_plug_info.h"
43 #include "libavc/general/avc_extended_plug_info.h"
44 #include "libavc/general/avc_subunit_info.h"
45 #include "libavc/streamformat/avc_extended_stream_format.h"
46 #include "libutil/cmd_serialize.h"
47 #include "libavc/avc_definitions.h"
49 #include "debugmodule/debugmodule.h"
62 Device::Device( DeviceManager
& d
, std::auto_ptr
< ConfigRom
>( configRom
) )
63 : GenericAVC::Device( d
, configRom
)
64 , m_last_discovery_config_id ( 0xFFFFFFFFFFFFFFFFLLU
)
67 debugOutput( DEBUG_LEVEL_VERBOSE
, "Created BeBoB::Device (NodeID %d)\n",
68 getConfigRom().getNodeId() );
77 Device::probe( Util::Configuration
& c
, ConfigRom
& configRom
, bool generic
)
80 // try a bebob-specific command to check for the firmware
81 ExtendedPlugInfoCmd
extPlugInfoCmd( configRom
.get1394Service() );
82 UnitPlugAddress
unitPlugAddress( UnitPlugAddress::ePT_PCR
,
83 configRom
.getNodeId() );
84 extPlugInfoCmd
.setPlugAddress( PlugAddress( PlugAddress::ePD_Input
,
85 PlugAddress::ePAM_Unit
,
87 extPlugInfoCmd
.setNodeId( configRom
.getNodeId() );
88 extPlugInfoCmd
.setCommandType( AVCCommand::eCT_Status
);
89 extPlugInfoCmd
.setVerbose( configRom
.getVerboseLevel() );
90 ExtendedPlugInfoInfoType
extendedPlugInfoInfoType(
91 ExtendedPlugInfoInfoType::eIT_NoOfChannels
);
92 extendedPlugInfoInfoType
.initialize();
93 extPlugInfoCmd
.setInfoType( extendedPlugInfoInfoType
);
95 if ( !extPlugInfoCmd
.fire() ) {
96 debugError( "Number of channels command failed\n" );
100 if((extPlugInfoCmd
.getResponse() != AVCCommand::eR_Implemented
)) {
101 // command not supported
105 ExtendedPlugInfoInfoType
* infoType
= extPlugInfoCmd
.getInfoType();
107 && infoType
->m_plugNrOfChns
)
113 // check if device is in supported devices list
114 unsigned int vendorId
= configRom
.getNodeVendorId();
115 unsigned int modelId
= configRom
.getModelId();
117 Util::Configuration::VendorModelEntry vme
= c
.findDeviceVME( vendorId
, modelId
);
118 return c
.isValid(vme
) && vme
.driver
== Util::Configuration::eD_BeBoB
;
123 Device::createDevice(DeviceManager
& d
, std::auto_ptr
<ConfigRom
>( configRom
))
125 unsigned int vendorId
= configRom
->getNodeVendorId();
126 unsigned int modelId
= configRom
->getModelId();
129 case FW_VENDORID_MACKIE
:
130 if (modelId
== 0x00010065 ) {
131 return new Mackie::OnyxMixerDevice(d
, configRom
);
133 case FW_VENDORID_EDIROL
:
136 return new Edirol::EdirolFa101Device(d
, configRom
);
138 return new Edirol::EdirolFa66Device(d
, configRom
);
140 return new Device(d
, configRom
);
142 case FW_VENDORID_ESI
:
143 if (modelId
== 0x00010064) {
144 return new ESI::QuataFireDevice(d
, configRom
);
147 case FW_VENDORID_TERRATEC
:
150 return new Terratec::Phase88Device(d
, configRom
);
151 default: // return a plain BeBoB device
152 return new Device(d
, configRom
);
154 case FW_VENDORID_FOCUSRITE
:
158 return new Focusrite::SaffireProDevice(d
, configRom
);
160 return new Focusrite::SaffireDevice(d
, configRom
);
161 default: // return a plain BeBoB device
162 return new Device(d
, configRom
);
165 return new Device(d
, configRom
);
170 #define BEBOB_CHECK_AND_ADD_SR(v, x) \
171 { if(supportsSamplingFrequency(x)) \
176 unsigned int vendorId
= getConfigRom().getNodeVendorId();
177 unsigned int modelId
= getConfigRom().getModelId();
179 Util::Configuration
&c
= getDeviceManager().getConfiguration();
180 Util::Configuration::VendorModelEntry vme
= c
.findDeviceVME( vendorId
, modelId
);
182 if (c
.isValid(vme
) && vme
.driver
== Util::Configuration::eD_BeBoB
) {
183 debugOutput( DEBUG_LEVEL_VERBOSE
, "found %s %s\n",
184 vme
.vendor_name
.c_str(),
185 vme
.model_name
.c_str());
187 debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n",
188 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
191 if ( !Unit::discover() ) {
192 debugError( "Could not discover unit\n" );
196 if((getAudioSubunit( 0 ) == NULL
)) {
197 debugError( "Unit doesn't have an Audio subunit.\n");
200 if((getMusicSubunit( 0 ) == NULL
)) {
201 debugError( "Unit doesn't have a Music subunit.\n");
206 debugWarning("Could not build mixer\n");
209 // keep track of the config id of this discovery
210 m_last_discovery_config_id
= getConfigurationId();
218 debugOutput(DEBUG_LEVEL_VERBOSE
, "Building a generic BeBoB mixer...\n");
220 // this removes the mixer if it already exists
221 // note: a mixer self-registers to it's parent
224 // create the mixer & register it
225 if(getAudioSubunit(0) == NULL
) {
226 debugWarning("Could not find audio subunit, mixer not available.\n");
229 m_Mixer
= new Mixer(*this);
231 if (m_Mixer
) m_Mixer
->setVerboseLevel(getDebugLevel());
232 return m_Mixer
!= NULL
;
236 Device::destroyMixer()
243 Device::setSelectorFBValue(int id
, int value
) {
244 FunctionBlockCmd
fbCmd( get1394Service(),
245 FunctionBlockCmd::eFBT_Selector
,
247 FunctionBlockCmd::eCA_Current
);
248 fbCmd
.setNodeId( getNodeId() );
249 fbCmd
.setSubunitId( 0x00 );
250 fbCmd
.setCommandType( AVCCommand::eCT_Control
);
251 fbCmd
.m_pFBSelector
->m_inputFbPlugNumber
= (value
& 0xFF);
252 fbCmd
.setVerboseLevel( getDebugLevel() );
254 if ( !fbCmd
.fire() ) {
255 debugError( "cmd failed\n" );
259 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
260 // Util::Cmd::CoutSerializer se;
261 // fbCmd.serialize( se );
264 if((fbCmd
.getResponse() != AVCCommand::eR_Accepted
)) {
265 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
268 return (fbCmd
.getResponse() == AVCCommand::eR_Accepted
);
272 Device::getSelectorFBValue(int id
) {
274 FunctionBlockCmd
fbCmd( get1394Service(),
275 FunctionBlockCmd::eFBT_Selector
,
277 FunctionBlockCmd::eCA_Current
);
278 fbCmd
.setNodeId( getNodeId() );
279 fbCmd
.setSubunitId( 0x00 );
280 fbCmd
.setCommandType( AVCCommand::eCT_Status
);
281 fbCmd
.m_pFBSelector
->m_inputFbPlugNumber
= 0xFF;
282 fbCmd
.setVerboseLevel( getDebugLevel() );
284 if ( !fbCmd
.fire() ) {
285 debugError( "cmd failed\n" );
289 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
290 // Util::Cmd::CoutSerializer se;
291 // fbCmd.serialize( se );
294 if((fbCmd
.getResponse() != AVCCommand::eR_Implemented
)) {
295 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
298 return fbCmd
.m_pFBSelector
->m_inputFbPlugNumber
;
302 Device::setFeatureFBVolumeCurrent(int id
, int channel
, int v
) {
304 FunctionBlockCmd
fbCmd( get1394Service(),
305 FunctionBlockCmd::eFBT_Feature
,
307 FunctionBlockCmd::eCA_Current
);
308 fbCmd
.setNodeId( getNodeId() );
309 fbCmd
.setSubunitId( 0x00 );
310 fbCmd
.setCommandType( AVCCommand::eCT_Control
);
311 fbCmd
.m_pFBFeature
->m_audioChannelNumber
= channel
;
312 fbCmd
.m_pFBFeature
->m_controlSelector
= FunctionBlockFeature::eCSE_Feature_Volume
;
313 AVC::FunctionBlockFeatureVolume vl
;
314 fbCmd
.m_pFBFeature
->m_pVolume
= vl
.clone();
315 fbCmd
.m_pFBFeature
->m_pVolume
->m_volume
= v
;
316 fbCmd
.setVerboseLevel( getDebugLevel() );
318 if ( !fbCmd
.fire() ) {
319 debugError( "cmd failed\n" );
323 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
324 // Util::Cmd::CoutSerializer se;
325 // fbCmd.serialize( se );
328 if((fbCmd
.getResponse() != AVCCommand::eR_Accepted
)) {
329 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
332 return (fbCmd
.getResponse() == AVCCommand::eR_Accepted
);
336 Device::getFeatureFBVolumeValue(int id
, int channel
, FunctionBlockCmd::EControlAttribute controlAttribute
)
338 FunctionBlockCmd
fbCmd( get1394Service(),
339 FunctionBlockCmd::eFBT_Feature
,
342 fbCmd
.setNodeId( getNodeId() );
343 fbCmd
.setSubunitId( 0x00 );
344 fbCmd
.setCommandType( AVCCommand::eCT_Status
);
345 fbCmd
.m_pFBFeature
->m_audioChannelNumber
= channel
;
346 fbCmd
.m_pFBFeature
->m_controlSelector
= FunctionBlockFeature::eCSE_Feature_Volume
;
347 AVC::FunctionBlockFeatureVolume vl
;
348 fbCmd
.m_pFBFeature
->m_pVolume
= vl
.clone();
349 fbCmd
.m_pFBFeature
->m_pVolume
->m_volume
= 0;
350 fbCmd
.setVerboseLevel( getDebugLevel() );
352 if ( !fbCmd
.fire() ) {
353 debugError( "cmd failed\n" );
357 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
358 // Util::Cmd::CoutSerializer se;
359 // fbCmd.serialize( se );
362 if((fbCmd
.getResponse() != AVCCommand::eR_Implemented
)) {
363 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
366 int16_t volume
=(int16_t)(fbCmd
.m_pFBFeature
->m_pVolume
->m_volume
);
372 Device::getFeatureFBVolumeMinimum(int id
, int channel
)
374 return getFeatureFBVolumeValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Minimum
);
378 Device::getFeatureFBVolumeMaximum(int id
, int channel
)
380 return getFeatureFBVolumeValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Maximum
);
384 Device::getFeatureFBVolumeCurrent(int id
, int channel
)
386 return getFeatureFBVolumeValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Current
);
390 Device::setFeatureFBLRBalanceCurrent(int id
, int channel
, int v
) {
392 FunctionBlockCmd
fbCmd( get1394Service(),
393 FunctionBlockCmd::eFBT_Feature
,
395 FunctionBlockCmd::eCA_Current
);
396 fbCmd
.setNodeId( getNodeId() );
397 fbCmd
.setSubunitId( 0x00 );
398 fbCmd
.setCommandType( AVCCommand::eCT_Control
);
399 fbCmd
.m_pFBFeature
->m_audioChannelNumber
= channel
;
400 fbCmd
.m_pFBFeature
->m_controlSelector
= FunctionBlockFeature::eCSE_Feature_LRBalance
;
401 AVC::FunctionBlockFeatureLRBalance bl
;
402 fbCmd
.m_pFBFeature
->m_pLRBalance
= bl
.clone();
403 fbCmd
.m_pFBFeature
->m_pLRBalance
->m_lrBalance
= v
;
404 fbCmd
.setVerboseLevel( getDebugLevel() );
406 if ( !fbCmd
.fire() ) {
407 debugError( "cmd failed\n" );
411 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
412 // Util::Cmd::CoutSerializer se;
413 // fbCmd.serialize( se );
416 if((fbCmd
.getResponse() != AVCCommand::eR_Accepted
)) {
417 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
420 return (fbCmd
.getResponse() == AVCCommand::eR_Accepted
);
424 Device::getFeatureFBLRBalanceValue(int id
, int channel
, FunctionBlockCmd::EControlAttribute controlAttribute
)
426 FunctionBlockCmd
fbCmd( get1394Service(),
427 FunctionBlockCmd::eFBT_Feature
,
430 fbCmd
.setNodeId( getNodeId() );
431 fbCmd
.setSubunitId( 0x00 );
432 fbCmd
.setCommandType( AVCCommand::eCT_Status
);
433 fbCmd
.m_pFBFeature
->m_audioChannelNumber
= channel
;
434 fbCmd
.m_pFBFeature
->m_controlSelector
= FunctionBlockFeature::eCSE_Feature_LRBalance
;
435 AVC::FunctionBlockFeatureLRBalance bl
;
436 fbCmd
.m_pFBFeature
->m_pLRBalance
= bl
.clone();
437 fbCmd
.m_pFBFeature
->m_pLRBalance
->m_lrBalance
= 0;
438 fbCmd
.setVerboseLevel( getDebugLevel() );
440 if ( !fbCmd
.fire() ) {
441 debugError( "cmd failed\n" );
445 // if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
446 // Util::Cmd::CoutSerializer se;
447 // fbCmd.serialize( se );
450 if((fbCmd
.getResponse() != AVCCommand::eR_Implemented
)) {
451 debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
454 int16_t balance
=(int16_t)(fbCmd
.m_pFBFeature
->m_pLRBalance
->m_lrBalance
);
460 Device::getFeatureFBLRBalanceMinimum(int id
, int channel
)
462 return getFeatureFBLRBalanceValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Minimum
);
466 Device::getFeatureFBLRBalanceMaximum(int id
, int channel
)
468 return getFeatureFBLRBalanceValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Maximum
);
472 Device::getFeatureFBLRBalanceCurrent(int id
, int channel
)
474 return getFeatureFBLRBalanceValue(id
, channel
, AVC::FunctionBlockCmd::eCA_Current
);
480 debugOutput(DEBUG_LEVEL_NORMAL
, "Device is a BeBoB device\n");
481 GenericAVC::Device::showDevice();
486 Device::setVerboseLevel(int l
)
488 if (m_Mixer
) m_Mixer
->setVerboseLevel( l
);
489 GenericAVC::Device::setVerboseLevel( l
);
490 debugOutput( DEBUG_LEVEL_VERBOSE
, "Setting verbose level to %d...\n", l
);
494 Device::createSubunit(AVC::Unit
& unit
,
495 AVC::ESubunitType type
,
498 AVC::Subunit
* s
=NULL
;
501 s
=new BeBoB::SubunitAudio(unit
, id
);
504 s
=new BeBoB::SubunitMusic(unit
, id
);
510 if(s
) s
->setVerboseLevel(getDebugLevel());
516 Device::createPlug( AVC::Unit
* unit
,
517 AVC::Subunit
* subunit
,
518 AVC::function_block_type_t functionBlockType
,
519 AVC::function_block_type_t functionBlockId
,
520 AVC::Plug::EPlugAddressType plugAddressType
,
521 AVC::Plug::EPlugDirection plugDirection
,
522 AVC::plug_id_t plugId
,
526 Plug
*p
= new BeBoB::Plug( unit
,
534 if (p
) p
->setVerboseLevel(getDebugLevel());
539 Device::propagatePlugInfo() {
540 // we don't have to propagate since we discover things
542 debugOutput(DEBUG_LEVEL_VERBOSE
, "Skip plug info propagation\n");
547 Device::getConfigurationIdSampleRate()
549 ExtendedStreamFormatCmd
extStreamFormatCmd( get1394Service() );
550 UnitPlugAddress
unitPlugAddress( UnitPlugAddress::ePT_PCR
, 0 );
551 extStreamFormatCmd
.setPlugAddress( PlugAddress( PlugAddress::ePD_Input
,
552 PlugAddress::ePAM_Unit
,
555 extStreamFormatCmd
.setNodeId( getNodeId() );
556 extStreamFormatCmd
.setCommandType( AVCCommand::eCT_Status
);
557 extStreamFormatCmd
.setVerbose( getDebugLevel() );
559 if ( !extStreamFormatCmd
.fire() ) {
560 debugError( "Stream format command failed\n" );
564 FormatInformation
* formatInfo
=
565 extStreamFormatCmd
.getFormatInformation();
566 FormatInformationStreamsCompound
* compoundStream
567 = dynamic_cast< FormatInformationStreamsCompound
* > (
568 formatInfo
->m_streams
);
569 if ( compoundStream
) {
570 debugOutput(DEBUG_LEVEL_VERBOSE
, "Sample rate 0x%02x\n",
571 compoundStream
->m_samplingFrequency
);
572 return compoundStream
->m_samplingFrequency
;
575 debugError( "Could not retrieve sample rate\n" );
580 Device::getConfigurationIdNumberOfChannel( PlugAddress::EPlugDirection ePlugDirection
)
582 ExtendedPlugInfoCmd
extPlugInfoCmd( get1394Service() );
583 UnitPlugAddress
unitPlugAddress( UnitPlugAddress::ePT_PCR
,
585 extPlugInfoCmd
.setPlugAddress( PlugAddress( ePlugDirection
,
586 PlugAddress::ePAM_Unit
,
588 extPlugInfoCmd
.setNodeId( getNodeId() );
589 extPlugInfoCmd
.setCommandType( AVCCommand::eCT_Status
);
590 extPlugInfoCmd
.setVerbose( getDebugLevel() );
591 ExtendedPlugInfoInfoType
extendedPlugInfoInfoType(
592 ExtendedPlugInfoInfoType::eIT_NoOfChannels
);
593 extendedPlugInfoInfoType
.initialize();
594 extPlugInfoCmd
.setInfoType( extendedPlugInfoInfoType
);
596 if ( !extPlugInfoCmd
.fire() ) {
597 debugError( "Number of channels command failed\n" );
601 ExtendedPlugInfoInfoType
* infoType
= extPlugInfoCmd
.getInfoType();
603 && infoType
->m_plugNrOfChns
)
605 debugOutput(DEBUG_LEVEL_VERBOSE
, "Number of channels 0x%02x\n",
606 infoType
->m_plugNrOfChns
->m_nrOfChannels
);
607 return infoType
->m_plugNrOfChns
->m_nrOfChannels
;
610 debugError( "Could not retrieve number of channels\n" );
615 Device::getConfigurationIdSyncMode()
617 SignalSourceCmd
signalSourceCmd( get1394Service() );
618 SignalUnitAddress signalUnitAddr
;
619 signalUnitAddr
.m_plugId
= 0x01;
620 signalSourceCmd
.setSignalDestination( signalUnitAddr
);
621 signalSourceCmd
.setNodeId( getNodeId() );
622 signalSourceCmd
.setSubunitType( eST_Unit
);
623 signalSourceCmd
.setSubunitId( 0xff );
624 signalSourceCmd
.setVerbose( getDebugLevel() );
626 signalSourceCmd
.setCommandType( AVCCommand::eCT_Status
);
628 if ( !signalSourceCmd
.fire() ) {
629 debugError( "Signal source command failed\n" );
633 SignalAddress
* pSyncPlugSignalAddress
= signalSourceCmd
.getSignalSource();
634 SignalSubunitAddress
* pSyncPlugSubunitAddress
635 = dynamic_cast<SignalSubunitAddress
*>( pSyncPlugSignalAddress
);
636 if ( pSyncPlugSubunitAddress
) {
637 debugOutput(DEBUG_LEVEL_VERBOSE
, "Sync mode 0x%02x\n",
638 ( pSyncPlugSubunitAddress
->m_subunitType
<< 3
639 | pSyncPlugSubunitAddress
->m_subunitId
) << 8
640 | pSyncPlugSubunitAddress
->m_plugId
);
642 return ( pSyncPlugSubunitAddress
->m_subunitType
<< 3
643 | pSyncPlugSubunitAddress
->m_subunitId
) << 8
644 | pSyncPlugSubunitAddress
->m_plugId
;
647 SignalUnitAddress
* pSyncPlugUnitAddress
648 = dynamic_cast<SignalUnitAddress
*>( pSyncPlugSignalAddress
);
649 if ( pSyncPlugUnitAddress
) {
650 debugOutput(DEBUG_LEVEL_VERBOSE
, "Sync mode 0x%02x\n",
651 0xff << 8 | pSyncPlugUnitAddress
->m_plugId
);
653 return ( 0xff << 8 | pSyncPlugUnitAddress
->m_plugId
);
656 debugError( "Could not retrieve sync mode\n" );
661 Device::needsRediscovery()
663 // require rediscovery if the config id differs from the one saved
664 // in the previous discovery
665 return getConfigurationId() != m_last_discovery_config_id
;
669 Device::getConfigurationId()
671 // create a unique configuration id.
673 id
= getConfigurationIdSampleRate();
674 id
|= getConfigurationIdNumberOfChannel( PlugAddress::ePD_Input
) << 8;
675 id
|= getConfigurationIdNumberOfChannel( PlugAddress::ePD_Output
) << 16;
676 id
|= ((uint64_t)getConfigurationIdSyncMode()) << 24;
681 Device::serialize( std::string basePath
,
682 Util::IOSerialize
& ser
) const
685 result
= GenericAVC::Device::serialize( basePath
, ser
);
690 Device::deserialize( std::string basePath
,
691 Util::IODeserialize
& deser
)
694 result
= GenericAVC::Device::deserialize( basePath
, deser
);
699 Device::getCachePath()
701 std::string cachePath
;
704 string path
= CACHEDIR
;
705 if ( path
.size() && path
[0] == '~' ) {
706 path
.erase( 0, 1 ); // remove ~
707 path
.insert( 0, getenv( "HOME" ) ); // prepend the home path
710 if ( asprintf( &pCachePath
, "%s/cache/", path
.c_str() ) < 0 ) {
711 debugError( "Could not create path string for cache pool (trying '/var/cache/libffado' instead)\n" );
712 cachePath
= "/var/cache/libffado/";
714 cachePath
= pCachePath
;
721 Device::loadFromCache()
723 std::string sDevicePath
= getCachePath() + getConfigRom().getGuidString();
726 asprintf(&configId
, "%016"PRIx64
"", getConfigurationId() );
728 debugError( "could not create id string\n" );
732 std::string sFileName
= sDevicePath
+ "/" + configId
+ ".xml";
734 debugOutput( DEBUG_LEVEL_NORMAL
, "filename %s\n", sFileName
.c_str() );
737 if ( stat( sFileName
.c_str(), &buf
) != 0 ) {
738 debugOutput( DEBUG_LEVEL_NORMAL
, "\"%s\" does not exist\n", sFileName
.c_str() );
741 if ( !S_ISREG( buf
.st_mode
) ) {
742 debugOutput( DEBUG_LEVEL_NORMAL
, "\"%s\" is not a regular file\n", sFileName
.c_str() );
747 Util::XMLDeserialize
deser( sFileName
, getDebugLevel() );
749 if (!deser
.isValid()) {
750 debugOutput( DEBUG_LEVEL_NORMAL
, "cache not valid: %s\n",
755 bool result
= deserialize( "", deser
);
757 debugOutput( DEBUG_LEVEL_NORMAL
, "could create valid bebob driver from %s\n",
771 // the path looks like this:
772 // PATH_TO_CACHE + GUID + CONFIGURATION_ID
773 string tmp_path
= getCachePath() + getConfigRom().getGuidString();
775 // the following piece should do something like
776 // 'mkdir -p some/path/with/some/dirs/which/do/not/exist'
777 vector
<string
> tokens
;
778 tokenize( tmp_path
, tokens
, "/" );
780 for ( vector
<string
>::const_iterator it
= tokens
.begin();
787 if ( stat( path
.c_str(), &buf
) == 0 ) {
788 if ( !S_ISDIR( buf
.st_mode
) ) {
789 debugError( "\"%s\" is not a directory\n", path
.c_str() );
793 if ( mkdir( path
.c_str(), S_IRWXU
| S_IRWXG
) != 0 ) {
794 debugError( "Could not create \"%s\" directory\n", path
.c_str() );
800 // come up with an unique file name for the current settings
802 asprintf(&configId
, "%016"PRIx64
"", BeBoB::Device::getConfigurationId() );
804 debugError( "Could not create id string\n" );
807 string filename
= path
+ "/" + configId
+ ".xml";
809 debugOutput( DEBUG_LEVEL_NORMAL
, "filename %s\n", filename
.c_str() );
811 Util::XMLSerialize
ser( filename
);
812 return serialize( "", ser
);
815 } // end of namespace