only mark a device as active source from cache if it's powered on
[deb_libcec.git] / src / lib / devices / CECDeviceMap.cpp
CommitLineData
004b8382
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; 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) any later version.
13 *
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.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
2b44051c 33#include "env.h"
004b8382 34#include "CECDeviceMap.h"
2b44051c 35
004b8382
LOK
36#include "CECAudioSystem.h"
37#include "CECPlaybackDevice.h"
38#include "CECRecordingDevice.h"
39#include "CECTuner.h"
40#include "CECTV.h"
2b44051c 41#include "lib/CECProcessor.h"
1a1e2e6c 42#include "lib/CECTypeUtils.h"
004b8382
LOK
43
44using namespace std;
45using namespace CEC;
46
47CCECDeviceMap::CCECDeviceMap(CCECProcessor *processor) :
d3caa81b
LOK
48 m_processor(processor),
49 m_iActiveSource(CEC_INVALID_PHYSICAL_ADDRESS)
004b8382
LOK
50{
51 for (uint8_t iPtr = CECDEVICE_TV; iPtr <= CECDEVICE_BROADCAST; iPtr++)
52 {
53 switch(iPtr)
54 {
55 case CECDEVICE_AUDIOSYSTEM:
56 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECAudioSystem(processor, (cec_logical_address) iPtr)));
57 break;
58 case CECDEVICE_PLAYBACKDEVICE1:
59 case CECDEVICE_PLAYBACKDEVICE2:
60 case CECDEVICE_PLAYBACKDEVICE3:
61 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECPlaybackDevice(processor, (cec_logical_address) iPtr)));
62 break;
63 case CECDEVICE_RECORDINGDEVICE1:
64 case CECDEVICE_RECORDINGDEVICE2:
65 case CECDEVICE_RECORDINGDEVICE3:
66 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECRecordingDevice(processor, (cec_logical_address) iPtr)));
67 break;
68 case CECDEVICE_TUNER1:
69 case CECDEVICE_TUNER2:
70 case CECDEVICE_TUNER3:
71 case CECDEVICE_TUNER4:
72 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECTuner(processor, (cec_logical_address) iPtr)));
73 break;
74 case CECDEVICE_TV:
75 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECTV(processor, (cec_logical_address) iPtr)));
76 break;
77 default:
78 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECBusDevice(processor, (cec_logical_address) iPtr)));
79 break;
80 }
81 }
82}
83CCECDeviceMap::~CCECDeviceMap(void)
84{
85 Clear();
86}
87
88CECDEVICEMAP::iterator CCECDeviceMap::Begin(void)
89{
90 return m_busDevices.begin();
91}
92
93CECDEVICEMAP::iterator CCECDeviceMap::End(void)
94{
95 return m_busDevices.end();
96}
97
98void CCECDeviceMap::ResetDeviceStatus(void)
99{
100 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
101 it->second->ResetDeviceStatus();
102}
103
104CCECBusDevice *CCECDeviceMap::operator[] (cec_logical_address iAddress) const
105{
106 return At(iAddress);
107}
108
109CCECBusDevice *CCECDeviceMap::operator[] (uint8_t iAddress) const
110{
111 return At(iAddress);
112}
113
114CCECBusDevice *CCECDeviceMap::At(cec_logical_address iAddress) const
115{
116 return At((uint8_t) iAddress);
117}
118
119CCECBusDevice *CCECDeviceMap::At(uint8_t iAddress) const
120{
121 CECDEVICEMAP::const_iterator it = m_busDevices.find((cec_logical_address)iAddress);
122 if (it != m_busDevices.end())
123 return it->second;
124 return NULL;
125}
126
127void CCECDeviceMap::Clear(void)
128{
129 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
130 delete it->second;
131 m_busDevices.clear();
132}
133
134CCECBusDevice *CCECDeviceMap::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress, bool bSuppressUpdate /* = true */)
135{
136 CCECBusDevice *device(NULL);
137
138 // check each device until we found a match
139 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); !device && it != m_busDevices.end(); it++)
140 {
141 if (it->second->GetPhysicalAddress(m_processor->GetLogicalAddress(), bSuppressUpdate) == iPhysicalAddress)
142 device = it->second;
143 }
144
145 return device;
146}
147
148void CCECDeviceMap::Get(CECDEVICEVEC &devices) const
149{
150 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
151 devices.push_back(it->second);
152}
153
154void CCECDeviceMap::GetByLogicalAddresses(CECDEVICEVEC &devices, const cec_logical_addresses &addresses)
155{
156 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
157 {
158 if (addresses.IsSet(it->first))
159 devices.push_back(it->second);
160 }
161}
162
163void CCECDeviceMap::GetByType(const cec_device_type type, CECDEVICEVEC &devices) const
164{
165 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
166 if (it->second->GetType() == type)
167 devices.push_back(it->second);
168}
169
170void CCECDeviceMap::GetLibCECControlled(CECDEVICEVEC &devices) const
171{
172 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
173 if (it->second->IsHandledByLibCEC())
174 devices.push_back(it->second);
175}
176
177void CCECDeviceMap::GetActive(CECDEVICEVEC &devices) const
178{
179 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
180 {
181 cec_bus_device_status status = it->second->GetStatus();
182 if (status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC ||
183 status == CEC_DEVICE_STATUS_PRESENT)
184 devices.push_back(it->second);
185 }
186}
187
188void CCECDeviceMap::GetPowerOffDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const
189{
190 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
191 {
20505741 192 if (configuration.powerOffDevices[(uint8_t)it->first])
004b8382
LOK
193 devices.push_back(it->second);
194 }
195}
196
197void CCECDeviceMap::GetWakeDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const
198{
199 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
200 {
20505741 201 if (configuration.wakeDevices[(uint8_t)it->first])
004b8382
LOK
202 devices.push_back(it->second);
203 }
204}
205
206CCECBusDevice *CCECDeviceMap::GetActiveSource(void) const
207{
208 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
209 {
d3caa81b 210 if (m_iActiveSource != CEC_INVALID_PHYSICAL_ADDRESS && !it->second->IsActiveSource() &&
4ba7bfae 211 it->second->GetCurrentPowerStatus() == CEC_POWER_STATUS_ON &&
d3caa81b
LOK
212 m_iActiveSource == it->second->GetCurrentPhysicalAddress())
213 it->second->MarkAsActiveSource();
004b8382
LOK
214 if (it->second->IsActiveSource())
215 return it->second;
216 }
217 return NULL;
218}
219
220void CCECDeviceMap::FilterLibCECControlled(CECDEVICEVEC &devices)
221{
222 CECDEVICEVEC newDevices;
223 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
224 {
225 if ((*it)->IsHandledByLibCEC())
226 newDevices.push_back(*it);
227 }
228 devices = newDevices;
229}
230
231void CCECDeviceMap::FilterActive(CECDEVICEVEC &devices)
232{
233 CECDEVICEVEC newDevices;
234 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
235 {
236 cec_bus_device_status status = (*it)->GetCurrentStatus();
237 if (status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC ||
238 status == CEC_DEVICE_STATUS_PRESENT)
239 newDevices.push_back(*it);
240 }
241 devices = newDevices;
242}
243
244void CCECDeviceMap::FilterTypes(const cec_device_type_list &types, CECDEVICEVEC &devices)
245{
c30acafa 246 cec_device_type_list t(types);//silly, but needed to retain abi
004b8382
LOK
247 CECDEVICEVEC newDevices;
248 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
249 {
c30acafa 250 if (t.IsSet((*it)->GetType()))
004b8382
LOK
251 newDevices.push_back(*it);
252 }
253 devices = newDevices;
254}
255
256void CCECDeviceMap::FilterType(const cec_device_type type, CECDEVICEVEC &devices)
257{
258 CECDEVICEVEC newDevices;
259 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
260 {
261 if ((*it)->GetType() == type)
262 newDevices.push_back(*it);
263 }
264 devices = newDevices;
265}
266
267cec_logical_addresses CCECDeviceMap::ToLogicalAddresses(const CECDEVICEVEC &devices)
268{
269 cec_logical_addresses addresses;
c30acafa 270 addresses.Clear();
004b8382
LOK
271 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
272 addresses.Set((*it)->GetLogicalAddress());
273 return addresses;
274}
1a1e2e6c
LOK
275
276void CCECDeviceMap::GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const
277{
278 devices.clear();
279 if (!device)
280 return;
281
282 uint16_t iPA = device->GetCurrentPhysicalAddress();
283
284 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
285 {
286 uint16_t iCurrentPA = it->second->GetCurrentPhysicalAddress();
287 if (CCECTypeUtils::PhysicalAddressIsIncluded(iPA, iCurrentPA))
288 devices.push_back(it->second);
289 }
290}
d3caa81b
LOK
291
292void CCECDeviceMap::SetActiveSource(uint16_t iPhysicalAddress)
293{
294 m_iActiveSource = iPhysicalAddress;
295}
296
297uint16_t CCECDeviceMap::GetActiveSourceAddress(void) const
298{
299 return m_iActiveSource;
300}
301
302void CCECDeviceMap::SignalAll(cec_opcode opcode)
303{
304 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
305 it->second->SignalOpcode(opcode);
306}