Imported Upstream version 2.2.0
[deb_libcec.git] / src / lib / devices / CECDeviceMap.cpp
CommitLineData
cbbe90dd
JB
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2013 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
33#include "env.h"
34#include "CECDeviceMap.h"
35
36#include "CECAudioSystem.h"
37#include "CECPlaybackDevice.h"
38#include "CECRecordingDevice.h"
39#include "CECTuner.h"
40#include "CECTV.h"
41#include "lib/CECProcessor.h"
42#include "lib/CECTypeUtils.h"
43
44using namespace std;
45using namespace CEC;
46
47CCECDeviceMap::CCECDeviceMap(CCECProcessor *processor) :
48 m_processor(processor)
49{
50 for (uint8_t iPtr = CECDEVICE_TV; iPtr <= CECDEVICE_BROADCAST; iPtr++)
51 {
52 switch(iPtr)
53 {
54 case CECDEVICE_AUDIOSYSTEM:
55 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECAudioSystem(processor, (cec_logical_address) iPtr)));
56 break;
57 case CECDEVICE_PLAYBACKDEVICE1:
58 case CECDEVICE_PLAYBACKDEVICE2:
59 case CECDEVICE_PLAYBACKDEVICE3:
60 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECPlaybackDevice(processor, (cec_logical_address) iPtr)));
61 break;
62 case CECDEVICE_RECORDINGDEVICE1:
63 case CECDEVICE_RECORDINGDEVICE2:
64 case CECDEVICE_RECORDINGDEVICE3:
65 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECRecordingDevice(processor, (cec_logical_address) iPtr)));
66 break;
67 case CECDEVICE_TUNER1:
68 case CECDEVICE_TUNER2:
69 case CECDEVICE_TUNER3:
70 case CECDEVICE_TUNER4:
71 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECTuner(processor, (cec_logical_address) iPtr)));
72 break;
73 case CECDEVICE_TV:
74 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECTV(processor, (cec_logical_address) iPtr)));
75 break;
76 default:
77 m_busDevices.insert(make_pair<cec_logical_address, CCECBusDevice *>((cec_logical_address)iPtr, new CCECBusDevice(processor, (cec_logical_address) iPtr)));
78 break;
79 }
80 }
81}
82CCECDeviceMap::~CCECDeviceMap(void)
83{
84 Clear();
85}
86
87CECDEVICEMAP::iterator CCECDeviceMap::Begin(void)
88{
89 return m_busDevices.begin();
90}
91
92CECDEVICEMAP::iterator CCECDeviceMap::End(void)
93{
94 return m_busDevices.end();
95}
96
97void CCECDeviceMap::ResetDeviceStatus(void)
98{
99 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
100 it->second->ResetDeviceStatus();
101}
102
103CCECBusDevice *CCECDeviceMap::operator[] (cec_logical_address iAddress) const
104{
105 return At(iAddress);
106}
107
108CCECBusDevice *CCECDeviceMap::operator[] (uint8_t iAddress) const
109{
110 return At(iAddress);
111}
112
113CCECBusDevice *CCECDeviceMap::At(cec_logical_address iAddress) const
114{
115 return At((uint8_t) iAddress);
116}
117
118CCECBusDevice *CCECDeviceMap::At(uint8_t iAddress) const
119{
120 CECDEVICEMAP::const_iterator it = m_busDevices.find((cec_logical_address)iAddress);
121 if (it != m_busDevices.end())
122 return it->second;
123 return NULL;
124}
125
126void CCECDeviceMap::Clear(void)
127{
128 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
129 delete it->second;
130 m_busDevices.clear();
131}
132
133CCECBusDevice *CCECDeviceMap::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress, bool bSuppressUpdate /* = true */)
134{
135 CCECBusDevice *device(NULL);
136
137 // check each device until we found a match
138 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); !device && it != m_busDevices.end(); it++)
139 {
140 if (it->second->GetPhysicalAddress(m_processor->GetLogicalAddress(), bSuppressUpdate) == iPhysicalAddress)
141 device = it->second;
142 }
143
144 return device;
145}
146
147void CCECDeviceMap::Get(CECDEVICEVEC &devices) const
148{
149 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
150 devices.push_back(it->second);
151}
152
153void CCECDeviceMap::GetByLogicalAddresses(CECDEVICEVEC &devices, const cec_logical_addresses &addresses)
154{
155 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
156 {
157 if (addresses.IsSet(it->first))
158 devices.push_back(it->second);
159 }
160}
161
162void CCECDeviceMap::GetByType(const cec_device_type type, CECDEVICEVEC &devices) const
163{
164 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
165 if (it->second->GetType() == type)
166 devices.push_back(it->second);
167}
168
169void CCECDeviceMap::GetLibCECControlled(CECDEVICEVEC &devices) const
170{
171 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
172 if (it->second->IsHandledByLibCEC())
173 devices.push_back(it->second);
174}
175
176void CCECDeviceMap::GetActive(CECDEVICEVEC &devices) const
177{
178 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
179 {
180 cec_bus_device_status status = it->second->GetStatus();
181 if (status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC ||
182 status == CEC_DEVICE_STATUS_PRESENT)
183 devices.push_back(it->second);
184 }
185}
186
187void CCECDeviceMap::GetPowerOffDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const
188{
189 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
190 {
191 if (configuration.powerOffDevices[(uint8_t)it->first])
192 devices.push_back(it->second);
193 }
194}
195
196void CCECDeviceMap::GetWakeDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const
197{
198 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
199 {
200 if (configuration.wakeDevices[(uint8_t)it->first])
201 devices.push_back(it->second);
202 }
203}
204
205CCECBusDevice *CCECDeviceMap::GetActiveSource(void) const
206{
207 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
208 {
209 if (it->second->IsActiveSource())
210 return it->second;
211 }
212 return NULL;
213}
214
215void CCECDeviceMap::FilterLibCECControlled(CECDEVICEVEC &devices)
216{
217 CECDEVICEVEC newDevices;
218 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
219 {
220 if ((*it)->IsHandledByLibCEC())
221 newDevices.push_back(*it);
222 }
223 devices = newDevices;
224}
225
226void CCECDeviceMap::FilterActive(CECDEVICEVEC &devices)
227{
228 CECDEVICEVEC newDevices;
229 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
230 {
231 cec_bus_device_status status = (*it)->GetCurrentStatus();
232 if (status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC ||
233 status == CEC_DEVICE_STATUS_PRESENT)
234 newDevices.push_back(*it);
235 }
236 devices = newDevices;
237}
238
239void CCECDeviceMap::FilterTypes(const cec_device_type_list &types, CECDEVICEVEC &devices)
240{
241 cec_device_type_list t(types);//silly, but needed to retain abi
242 CECDEVICEVEC newDevices;
243 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
244 {
245 if (t.IsSet((*it)->GetType()))
246 newDevices.push_back(*it);
247 }
248 devices = newDevices;
249}
250
251void CCECDeviceMap::FilterType(const cec_device_type type, CECDEVICEVEC &devices)
252{
253 CECDEVICEVEC newDevices;
254 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
255 {
256 if ((*it)->GetType() == type)
257 newDevices.push_back(*it);
258 }
259 devices = newDevices;
260}
261
262cec_logical_addresses CCECDeviceMap::ToLogicalAddresses(const CECDEVICEVEC &devices)
263{
264 cec_logical_addresses addresses;
265 addresses.Clear();
266 for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++)
267 addresses.Set((*it)->GetLogicalAddress());
268 return addresses;
269}
270
271void CCECDeviceMap::GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const
272{
273 devices.clear();
274 if (!device)
275 return;
276
277 uint16_t iPA = device->GetCurrentPhysicalAddress();
278
279 for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
280 {
281 uint16_t iCurrentPA = it->second->GetCurrentPhysicalAddress();
282 if (CCECTypeUtils::PhysicalAddressIsIncluded(iPA, iCurrentPA))
283 devices.push_back(it->second);
284 }
285}
286
287void CCECDeviceMap::SignalAll(cec_opcode opcode)
288{
289 for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
290 it->second->SignalOpcode(opcode);
291}