2 * Copyright (C) 2005-2008 by Pieter Palmers
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/>.
24 #include "DeviceStringParser.h"
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
35 IMPL_DEBUG_MODULE( DeviceStringParser
, DeviceStringParser
, DEBUG_LEVEL_NORMAL
);
37 DeviceStringParser::DeviceString::DeviceString(DeviceStringParser
& parent
)
44 , m_debugModule( parent
.m_debugModule
)
48 DeviceStringParser::DeviceString::~DeviceString()
53 DeviceStringParser::DeviceString::parse(std::string s
)
56 debugOutput(DEBUG_LEVEL_VERBOSE
, "parse: %s\n", s
.c_str());
57 std::string prefix
= s
.substr(0,3);
59 if(s
.compare(0,3,"hw:")==0) {
61 std::string detail
= s
.substr(3);
62 std::string::size_type comma_pos
= detail
.find_first_of(",");
63 if(comma_pos
== std::string::npos
) {
64 // node is unspecified
66 std::string port
= detail
;
68 m_port
= strtol(port
.c_str(), NULL
, 0);
73 debugOutput(DEBUG_LEVEL_VERBOSE
, "failed to parse port\n");
77 std::string port
= detail
.substr(0, comma_pos
);
78 std::string node
= detail
.substr(comma_pos
+1);
80 m_port
= strtol(port
.c_str(), NULL
, 0);
85 debugOutput(DEBUG_LEVEL_VERBOSE
, "failed to parse port\n");
89 m_node
= strtol(node
.c_str(), NULL
, 0);
94 debugOutput(DEBUG_LEVEL_VERBOSE
, "failed to parse node\n");
98 } else if (s
.compare(0,5,"guid:")==0) {
99 std::string detail
= s
.substr(5);
102 m_guid
= strtoll(detail
.c_str(), NULL
, 0);
106 debugOutput(DEBUG_LEVEL_VERBOSE
, "failed to parse guid\n");
111 debugOutput(DEBUG_LEVEL_VERBOSE
, "invalid\n");
118 DeviceStringParser::DeviceString::isValidString(std::string s
)
120 std::string prefix
= s
.substr(0,3);
121 if(s
.compare(0,3,"hw:")==0) {
122 std::string detail
= s
.substr(3);
123 std::string::size_type comma_pos
= detail
.find_first_of(",");
124 if(comma_pos
== std::string::npos
) {
125 std::string port
= detail
;
127 strtol(port
.c_str(), NULL
, 0);
132 std::string port
= detail
.substr(0, comma_pos
);
133 std::string node
= detail
.substr(comma_pos
+1);
135 strtol(port
.c_str(), NULL
, 0);
140 strtol(node
.c_str(), NULL
, 0);
145 } else if (s
.compare(0,5,"guid:")==0) {
146 std::string detail
= s
.substr(5);
148 strtoll(detail
.c_str(), NULL
, 0);
159 DeviceStringParser::DeviceString::match(ConfigRom
& configRom
)
161 debugOutput(DEBUG_LEVEL_VERBOSE
, "match %p (%s)\n", &configRom
, configRom
.getGuidString().c_str());
166 debugWarning("Need at least a port spec\n");
169 match
= configRom
.get1394Service().getPort() == m_port
;
171 match
&= ((configRom
.getNodeId() & 0x3F) == m_node
);
174 debugOutput(DEBUG_LEVEL_VERBOSE
, "(eBusNode) device matches device string %s\n", m_String
.c_str());
178 //GUID should not be 0
179 match
= m_guid
&& (m_guid
== configRom
.getGuid());
181 debugOutput(DEBUG_LEVEL_VERBOSE
, "(eGUID) device matches device string %s\n", m_String
.c_str());
186 debugError("invalid DeviceString type (%d)\n", m_Type
);
193 DeviceStringParser::DeviceString::operator==(const DeviceString
& x
)
198 retval
= (m_port
== x
.m_port
) && (m_node
== x
.m_node
);
199 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "eBusNode %d,%d == %d,%d? %d\n",
200 m_port
, m_node
, x
.m_port
, x
.m_node
, retval
);
203 retval
= m_guid
&& (m_guid
== x
.m_guid
);
204 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "eGUID 0x%016"PRIX64
" == 0x%016"PRIX64
"? %d\n",
205 m_guid
, x
.m_guid
, retval
);
208 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "eInvalid \n");
215 DeviceStringParser::DeviceString::show()
217 debugOutput(DEBUG_LEVEL_INFO
, "string: %s\n", m_String
.c_str());
220 debugOutput(DEBUG_LEVEL_INFO
, "type: eBusNode\n");
221 debugOutput(DEBUG_LEVEL_INFO
, " Port: %d, Node: %d\n",
225 debugOutput(DEBUG_LEVEL_INFO
, "type: eGUID\n");
226 debugOutput(DEBUG_LEVEL_INFO
, " GUID: %016"PRIX64
"\n", m_guid
);
230 debugOutput(DEBUG_LEVEL_INFO
, "type: eInvalid\n");
235 // ------------------------
236 DeviceStringParser::DeviceStringParser()
239 DeviceStringParser::~DeviceStringParser()
241 while(m_DeviceStrings
.size()) {
242 DeviceString
*tmp
= m_DeviceStrings
.at(0);
243 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "removing device string: %p\n", tmp
);
244 m_DeviceStrings
.erase(m_DeviceStrings
.begin());
250 DeviceStringParser::parseString(std::string s
)
252 debugOutput(DEBUG_LEVEL_VERBOSE
, "parse: %s\n", s
.c_str());
254 std::string::size_type next_sep
;
257 debugOutput(DEBUG_LEVEL_VERBOSE
, " left: %s\n", tmp
.c_str());
258 next_sep
= tmp
.find_first_of(";");
259 std::string to_parse
= tmp
.substr(0, next_sep
);
260 DeviceString
*d
= new DeviceString(*this);
262 debugError("failed to allocate memory for device string\n");
265 if(d
->parse(to_parse
)) {
268 debugWarning("Failed to parse device substring: \"%s\"\n",
272 tmp
= tmp
.substr(next_sep
+1);
273 } while(tmp
.size() && next_sep
!= std::string::npos
);
281 DeviceStringParser::isValidString(std::string s
)
283 debugOutput(DEBUG_LEVEL_VERBOSE
, "isvalid? %s\n", s
.c_str());
284 return DeviceString::isValidString(s
);
288 DeviceStringParser::match(ConfigRom
& c
)
290 return matchPosition(c
) != -1;
294 DeviceStringParser::matchPosition(ConfigRom
& c
)
297 for ( DeviceStringVectorIterator it
= m_DeviceStrings
.begin();
298 it
!= m_DeviceStrings
.end();
301 if((*it
)->match(c
)) {
310 DeviceStringParser::addDeviceString(DeviceString
*o
)
312 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "adding device string: %p\n", o
);
313 if (hasDeviceString(o
)){
316 m_DeviceStrings
.push_back(o
);
321 DeviceStringParser::removeDeviceString(DeviceString
*o
)
323 debugOutput(DEBUG_LEVEL_VERY_VERBOSE
, "removing device string: %p\n", o
);
324 int i
=findDeviceString(o
);
326 debugOutput(DEBUG_LEVEL_VERBOSE
, "not found\n");
329 DeviceString
*tmp
= m_DeviceStrings
.at(i
);
330 m_DeviceStrings
.erase(m_DeviceStrings
.begin()+i
);
337 DeviceStringParser::hasDeviceString(DeviceString
*o
)
339 return (findDeviceString(o
) >= 0);
343 DeviceStringParser::findDeviceString(DeviceString
*o
)
346 for ( DeviceStringVectorIterator it
= m_DeviceStrings
.begin();
347 it
!= m_DeviceStrings
.end();
359 DeviceStringParser::pruneDuplicates()
361 DeviceStringVector duplicates
;
363 for ( DeviceStringVectorIterator it
= m_DeviceStrings
.begin();
364 it
!= m_DeviceStrings
.end();
367 for ( DeviceStringVectorIterator it2
= it
+1;
368 it2
!= m_DeviceStrings
.end();
373 duplicates
.push_back(*it2
);
379 for ( DeviceStringVectorIterator it
= duplicates
.begin();
380 it
!= duplicates
.end();
383 removeDeviceString(*it
);
388 DeviceStringParser::show()
390 debugOutput(DEBUG_LEVEL_INFO
, "DeviceStringParser: %p\n", this);
391 for ( DeviceStringVectorIterator it
= m_DeviceStrings
.begin();
392 it
!= m_DeviceStrings
.end();
400 DeviceStringParser::setVerboseLevel(int i
)