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