2 * Copyright (C) 2005-2013 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, see
17 * <http://www.gnu.org/licenses/>.
21 #include "PeripheralBus.h"
22 #include "peripherals/Peripherals.h"
23 #include "utils/Variant.h"
24 #include "utils/log.h"
28 using namespace PERIPHERALS;
30 #define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000
32 bool PeripheralScanResult::operator ==(const PeripheralScanResult &right) const
34 return m_iVendorId == right.m_iVendorId &&
35 m_iProductId == right.m_iProductId &&
36 m_type == right.m_type &&
37 m_strLocation.Equals(right.m_strLocation);
40 bool PeripheralScanResult::operator !=(const PeripheralScanResult &right) const
42 return !(*this == right);
45 bool PeripheralScanResult::operator ==(const CPeripheral &right) const
47 return m_iVendorId == right.VendorId() &&
48 m_iProductId == right.ProductId() &&
49 m_type == right.Type() &&
50 m_strLocation.Equals(right.Location());
53 bool PeripheralScanResult::operator !=(const CPeripheral &right) const
55 return !(*this == right);
58 bool PeripheralScanResults::GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const
62 for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++)
64 if (m_results.at(iDevicePtr).m_strLocation == strLocation)
66 *result = m_results.at(iDevicePtr);
75 bool PeripheralScanResults::ContainsResult(const PeripheralScanResult &result) const
79 for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++)
81 if (m_results.at(iDevicePtr) == result)
91 CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) :
92 CThread("XBMC Peripherals"),
93 m_iRescanTime(PERIPHERAL_DEFAULT_RESCAN_INTERVAL),
94 m_bInitialised(false),
96 m_bNeedsPolling(true),
103 void CPeripheralBus::OnDeviceAdded(const CStdString &strLocation)
108 void CPeripheralBus::OnDeviceChanged(const CStdString &strLocation)
113 void CPeripheralBus::OnDeviceRemoved(const CStdString &strLocation)
118 void CPeripheralBus::Clear(void)
123 m_triggerEvent.Set();
127 CSingleLock lock(m_critSection);
128 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
129 delete m_peripherals.at(iPeripheralPtr);
130 m_peripherals.clear();
133 void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
135 CSingleLock lock(m_critSection);
136 vector<CPeripheral *> removedPeripherals;
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 removedPeripherals.push_back(peripheral);
146 m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
151 for (unsigned int iDevicePtr = 0; iDevicePtr < removedPeripherals.size(); iDevicePtr++)
153 CPeripheral *peripheral = removedPeripherals.at(iDevicePtr);
154 vector<PeripheralFeature> features;
155 peripheral->GetFeatures(features);
156 bool peripheralHasFeatures = features.size() > 1 || (features.size() == 1 && features.at(0) != FEATURE_UNKNOWN);
157 if (peripheral->Type() != PERIPHERAL_UNKNOWN || peripheralHasFeatures)
159 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());
160 peripheral->OnDeviceRemoved();
163 m_manager->OnDeviceDeleted(*this, *peripheral);
168 void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results)
170 CSingleLock lock(m_critSection);
171 for (unsigned int iResultPtr = 0; iResultPtr < results.m_results.size(); iResultPtr++)
173 PeripheralScanResult result = results.m_results.at(iResultPtr);
174 if (!HasPeripheral(result.m_strLocation))
175 g_peripherals.CreatePeripheral(*this, result.m_type, result.m_strLocation, result.m_iVendorId, result.m_iProductId);
179 bool CPeripheralBus::ScanForDevices(void)
183 PeripheralScanResults results;
184 if (PerformDeviceScan(results))
186 UnregisterRemovedDevices(results);
187 RegisterNewDevices(results);
192 m_bInitialised = true;
196 bool CPeripheralBus::HasFeature(const PeripheralFeature feature) const
199 CSingleLock lock(m_critSection);
200 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
202 if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature))
211 void CPeripheralBus::GetFeatures(std::vector<PeripheralFeature> &features) const
213 CSingleLock lock(m_critSection);
214 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
215 m_peripherals.at(iPeripheralPtr)->GetFeatures(features);
218 CPeripheral *CPeripheralBus::GetPeripheral(const CStdString &strLocation) const
220 CPeripheral *peripheral(NULL);
221 CSingleLock lock(m_critSection);
222 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
224 if (m_peripherals.at(iPeripheralPtr)->Location() == strLocation)
226 peripheral = m_peripherals.at(iPeripheralPtr);
233 int CPeripheralBus::GetPeripheralsWithFeature(vector<CPeripheral *> &results, const PeripheralFeature feature) const
236 CSingleLock lock(m_critSection);
237 for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++)
239 if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature))
241 results.push_back(m_peripherals.at(iPeripheralPtr));
249 void CPeripheralBus::Process(void)
253 m_triggerEvent.Reset();
255 if (!ScanForDevices())
259 m_triggerEvent.WaitMSec(m_iRescanTime);
262 m_bIsStarted = false;
265 bool CPeripheralBus::Initialise(void)
267 CSingleLock lock(m_critSection);
270 /* do an initial scan of the bus */
271 m_bIsStarted = ScanForDevices();
273 if (m_bIsStarted && m_bNeedsPolling)
276 m_triggerEvent.Reset();
285 void CPeripheralBus::Register(CPeripheral *peripheral)
290 CSingleLock lock(m_critSection);
291 if (!HasPeripheral(peripheral->Location()))
293 m_peripherals.push_back(peripheral);
294 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());
297 m_manager->OnDeviceAdded(*this, *peripheral);
301 void CPeripheralBus::TriggerDeviceScan(void)
303 CSingleLock lock(m_critSection);
307 m_triggerEvent.Set();
316 bool CPeripheralBus::HasPeripheral(const CStdString &strLocation) const
318 return (GetPeripheral(strLocation) != NULL);
321 void CPeripheralBus::GetDirectory(const CStdString &strPath, CFileItemList &items) const
323 CStdString strDevPath;
324 CSingleLock lock(m_critSection);
325 for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++)
327 const CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
328 if (peripheral->IsHidden())
331 CFileItemPtr peripheralFile(new CFileItem(peripheral->DeviceName()));
332 peripheralFile->SetPath(peripheral->FileLocation());
333 peripheralFile->SetProperty("vendor", peripheral->VendorIdAsString());
334 peripheralFile->SetProperty("product", peripheral->ProductIdAsString());
335 peripheralFile->SetProperty("bus", PeripheralTypeTranslator::BusTypeToString(peripheral->GetBusType()));
336 peripheralFile->SetProperty("location", peripheral->Location());
337 peripheralFile->SetProperty("class", PeripheralTypeTranslator::TypeToString(peripheral->Type()));
338 peripheralFile->SetProperty("version", peripheral->GetVersionInfo());
339 items.Add(peripheralFile);
343 CPeripheral *CPeripheralBus::GetByPath(const CStdString &strPath) const
345 CStdString strDevPath;
346 CSingleLock lock(m_critSection);
347 for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++)
349 if (strPath.Equals(m_peripherals.at(iDevicePtr)->FileLocation()))
350 return m_peripherals.at(iDevicePtr);
356 size_t CPeripheralBus::GetNumberOfPeripherals() const
358 return m_peripherals.size();