2 * Copyright (C) 2005-2011 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program 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.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "PeripheralBus.h"
23 #include "peripherals/Peripherals.h"
24 #include "utils/Variant.h"
25 #include "utils/log.h"
29 using namespace PERIPHERALS;
31 #define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000
33 bool PeripheralScanResult::operator ==(const PeripheralScanResult &right) const
35 return m_iVendorId == right.m_iVendorId &&
36 m_iProductId == right.m_iProductId &&
37 m_type == right.m_type &&
38 m_strLocation.Equals(right.m_strLocation);
41 bool PeripheralScanResult::operator !=(const PeripheralScanResult &right) const
43 return !(*this == right);
46 bool PeripheralScanResult::operator ==(const CPeripheral &right) const
48 return m_iVendorId == right.VendorId() &&
49 m_iProductId == right.ProductId() &&
50 m_type == right.Type() &&
51 m_strLocation.Equals(right.Location());
54 bool PeripheralScanResult::operator !=(const CPeripheral &right) const
56 return !(*this == right);
59 bool PeripheralScanResults::GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const
63 for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++)
65 if (m_results.at(iDevicePtr).m_strLocation == strLocation)
67 *result = m_results.at(iDevicePtr);
76 bool PeripheralScanResults::ContainsResult(const PeripheralScanResult &result) const
80 for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++)
82 if (m_results.at(iDevicePtr) == result)
92 CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) :
93 CThread("XBMC Peripherals"),
94 m_iRescanTime(PERIPHERAL_DEFAULT_RESCAN_INTERVAL),
95 m_bInitialised(false),
97 m_bNeedsPolling(true),
104 void CPeripheralBus::OnDeviceAdded(const CStdString &strLocation)
109 void CPeripheralBus::OnDeviceChanged(const CStdString &strLocation)
114 void CPeripheralBus::OnDeviceRemoved(const CStdString &strLocation)
119 void CPeripheralBus::Clear(void)
124 m_triggerEvent.Set();
128 CSingleLock lock(m_critSection);
129 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
130 delete m_peripherals.at(iPeripheralPtr);
131 m_peripherals.clear();
134 void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
136 CSingleLock lock(m_critSection);
137 for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--)
139 CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
140 PeripheralScanResult updatedDevice;
141 if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) ||
142 updatedDevice != *peripheral)
145 if (peripheral->Type() != PERIPHERAL_UNKNOWN)
146 CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
147 m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
150 m_manager->OnDeviceDeleted(*this, peripheral->FileLocation());
156 void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results)
158 CSingleLock lock(m_critSection);
159 for (unsigned int iResultPtr = 0; iResultPtr < results.m_results.size(); iResultPtr++)
161 PeripheralScanResult result = results.m_results.at(iResultPtr);
162 if (!HasPeripheral(result.m_strLocation) && result.m_type != PERIPHERAL_UNKNOWN)
163 g_peripherals.CreatePeripheral(*this, result.m_type, result.m_strLocation, result.m_iVendorId, result.m_iProductId);
167 bool CPeripheralBus::ScanForDevices(void)
171 PeripheralScanResults results;
172 if (PerformDeviceScan(results))
174 UnregisterRemovedDevices(results);
175 RegisterNewDevices(results);
180 m_bInitialised = true;
184 bool CPeripheralBus::HasFeature(const PeripheralFeature feature) const
187 CSingleLock lock(m_critSection);
188 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
190 if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature))
199 void CPeripheralBus::GetFeatures(std::vector<PeripheralFeature> &features) const
201 CSingleLock lock(m_critSection);
202 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
203 m_peripherals.at(iPeripheralPtr)->GetFeatures(features);
206 CPeripheral *CPeripheralBus::GetPeripheral(const CStdString &strLocation) const
208 CPeripheral *peripheral(NULL);
209 CSingleLock lock(m_critSection);
210 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
212 if (m_peripherals.at(iPeripheralPtr)->Location() == strLocation)
214 peripheral = m_peripherals.at(iPeripheralPtr);
221 int CPeripheralBus::GetPeripheralsWithFeature(vector<CPeripheral *> &results, const PeripheralFeature feature) const
224 CSingleLock lock(m_critSection);
225 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
227 if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature))
229 results.push_back(m_peripherals.at(iPeripheralPtr));
237 void CPeripheralBus::Process(void)
241 m_triggerEvent.Reset();
243 if (!ScanForDevices())
247 m_triggerEvent.WaitMSec(m_iRescanTime);
250 m_bIsStarted = false;
253 bool CPeripheralBus::Initialise(void)
255 CSingleLock lock(m_critSection);
258 /* do an initial scan of the bus */
259 m_bIsStarted = ScanForDevices();
261 if (m_bIsStarted && m_bNeedsPolling)
264 m_triggerEvent.Reset();
273 void CPeripheralBus::Register(CPeripheral *peripheral)
278 CSingleLock lock(m_critSection);
279 if (!HasPeripheral(peripheral->Location()))
281 m_peripherals.push_back(peripheral);
282 CLog::Log(LOGNOTICE, "%s - new %s device registered on %s->%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), PeripheralTypeTranslator::BusTypeToString(m_type), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
285 m_manager->OnDeviceAdded(*this, peripheral->FileLocation());
289 void CPeripheralBus::TriggerDeviceScan(void)
291 CSingleLock lock(m_critSection);
295 m_triggerEvent.Set();
304 bool CPeripheralBus::HasPeripheral(const CStdString &strLocation) const
306 return (GetPeripheral(strLocation) != NULL);
309 void CPeripheralBus::GetDirectory(const CStdString &strPath, CFileItemList &items) const
311 CStdString strDevPath;
312 CSingleLock lock(m_critSection);
313 for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++)
315 const CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
316 if (peripheral->IsHidden())
319 CFileItemPtr peripheralFile(new CFileItem(peripheral->DeviceName()));
320 peripheralFile->SetPath(peripheral->FileLocation());
321 peripheralFile->SetProperty("vendor", peripheral->VendorIdAsString());
322 peripheralFile->SetProperty("product", peripheral->ProductIdAsString());
323 peripheralFile->SetProperty("bus", PeripheralTypeTranslator::BusTypeToString(peripheral->GetBusType()));
324 peripheralFile->SetProperty("location", peripheral->Location());
325 peripheralFile->SetProperty("class", PeripheralTypeTranslator::TypeToString(peripheral->Type()));
326 items.Add(peripheralFile);
330 CPeripheral *CPeripheralBus::GetByPath(const CStdString &strPath) const
332 CStdString strDevPath;
333 CSingleLock lock(m_critSection);
334 for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++)
336 if (strPath.Equals(m_peripherals.at(iDevicePtr)->FileLocation()))
337 return m_peripherals.at(iDevicePtr);