]> git.basschouten.com Git - openhab-addons.git/blob
46fa30dcfbb2a705c0c8cf7fce25f780551cf5d2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.rotel.internal.communication;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.binding.rotel.internal.RotelException;
17
18 /**
19  * Class managing the mapping of message flags with indicators
20  *
21  * @author Laurent Garnier - Initial contribution
22  */
23 @NonNullByDefault
24 public class RotelFlagsMapping {
25
26     public static final RotelFlagsMapping MAPPING1 = new RotelFlagsMapping(3, 1, 5, 0, -1, -1, -1, -1, 8, 6, 8, 4, 8,
27             3);
28     public static final RotelFlagsMapping MAPPING2 = new RotelFlagsMapping(-1, -1, 4, 7, -1, -1, -1, -1, 5, 6, 5, 4, 5,
29             3);
30     public static final RotelFlagsMapping MAPPING3 = new RotelFlagsMapping(4, 7, 1, 7, 2, 7, 6, 2, 5, 6, 5, 4, 5, 3);
31     public static final RotelFlagsMapping MAPPING4 = new RotelFlagsMapping(3, 1, 1, 7, 2, 7, 6, 2, 8, 6, 8, 4, 8, 3);
32     public static final RotelFlagsMapping MAPPING5 = new RotelFlagsMapping(-1, -1, 3, 2, 4, 2, 4, 1, 5, 6, 5, 4, 5, 3);
33     public static final RotelFlagsMapping NO_MAPPING = new RotelFlagsMapping(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34             -1, -1, -1);
35
36     private int multiInputFlagNumber;
37     private int multiInputBitNumber;
38     private int zone2FlagNumber;
39     private int zone2BitNumber;
40     private int zone3FlagNumber;
41     private int zone3BitNumber;
42     private int zone4FlagNumber;
43     private int zone4BitNumber;
44     private int centerFlagNumber;
45     private int centerBitNumber;
46     private int surroundLeftFlagNumber;
47     private int surroundLeftBitNumber;
48     private int surroundRightFlagNumber;
49     private int surroundRightBitNumber;
50
51     /**
52      * Constructor
53      *
54      * For each flag number, value 1 means the first flag; a negative value is used for an undefined indicator.
55      * For each bit number, value is from 0 to 7; a negative value is used for an undefined indicator.
56      *
57      * @param multiInputFlagNumber the flag number in the standard feedback message in which to find the multi input
58      *            indicator
59      * @param multiInputBitNumber the bit number in the flag in which to find the multi input indicator
60      * @param zone2FlagNumber the flag number in the standard feedback message in which to find the zone 2 indicator
61      * @param zone2BitNumber the bit number in the flag in which to find the zone 2 indicator
62      * @param zone3FlagNumber the flag number in the standard feedback message in which to find the zone 3 indicator
63      * @param zone3BitNumber the bit number in the flag in which to find the zone 3 indicator
64      * @param zone4FlagNumber the flag number in the standard feedback message in which to find the zone 4 indicator
65      * @param zone4BitNumber the bit number in the flag in which to find the zone 4 indicator
66      * @param centerFlagNumber the flag number in the standard feedback message in which to find the center channel
67      *            indicator
68      * @param centerBitNumber the bit number in the flag in which to find the center channel indicator
69      * @param surroundLeftFlagNumber the flag number in the standard feedback message in which to find the surround left
70      *            channel indicator
71      * @param surroundLeftBitNumber the bit number in the flag in which to find the surround left channel indicator
72      * @param surroundRightFlagNumber the flag number in the standard feedback message in which to find the surround
73      *            right channel indicator
74      * @param surroundRightBitNumber the bit number in the flag in which to find the surround right channel indicator
75      */
76     private RotelFlagsMapping(int multiInputFlagNumber, int multiInputBitNumber, int zone2FlagNumber,
77             int zone2BitNumber, int zone3FlagNumber, int zone3BitNumber, int zone4FlagNumber, int zone4BitNumber,
78             int centerFlagNumber, int centerBitNumber, int surroundLeftFlagNumber, int surroundLeftBitNumber,
79             int surroundRightFlagNumber, int surroundRightBitNumber) {
80         this.multiInputFlagNumber = multiInputFlagNumber;
81         this.multiInputBitNumber = multiInputBitNumber;
82         this.zone2FlagNumber = zone2FlagNumber;
83         this.zone2BitNumber = zone2BitNumber;
84         this.zone3FlagNumber = zone3FlagNumber;
85         this.zone3BitNumber = zone3BitNumber;
86         this.zone4FlagNumber = zone4FlagNumber;
87         this.zone4BitNumber = zone4BitNumber;
88         this.centerFlagNumber = centerFlagNumber;
89         this.centerBitNumber = centerBitNumber;
90         this.surroundLeftFlagNumber = surroundLeftFlagNumber;
91         this.surroundLeftBitNumber = surroundLeftBitNumber;
92         this.surroundRightFlagNumber = surroundRightFlagNumber;
93         this.surroundRightBitNumber = surroundRightBitNumber;
94     }
95
96     /**
97      * Get the multi input indicator
98      *
99      * @param flags the table of flags
100      *
101      * @return true if the indicator is ON in the flags or false if OFF
102      *
103      * @throws RotelException in case the multi input indicator is undefined
104      */
105     public boolean isMultiInputOn(byte[] flags) throws RotelException {
106         return RotelFlagsMapping.isBitFlagOn(flags, multiInputFlagNumber, multiInputBitNumber);
107     }
108
109     /**
110      * Set the multi input indicator
111      *
112      * @param flags the table of flags
113      * @param on true to set the indicator to ON or false to set it to OFF
114      *
115      * @throws RotelException in case the multi input indicator is undefined
116      */
117     public void setMultiInput(byte[] flags, boolean on) throws RotelException {
118         RotelFlagsMapping.setBitFlag(flags, multiInputFlagNumber, multiInputBitNumber, on);
119     }
120
121     /**
122      * Get the zone 2 indicator
123      *
124      * @param flags the table of flags
125      *
126      * @return true if the indicator is ON in the flags or false if OFF
127      *
128      * @throws RotelException in case the zone 2 indicator is undefined
129      */
130     public boolean isZone2On(byte[] flags) throws RotelException {
131         return RotelFlagsMapping.isBitFlagOn(flags, zone2FlagNumber, zone2BitNumber);
132     }
133
134     /**
135      * Set the zone 2 indicator
136      *
137      * @param flags the table of flags
138      * @param on true to set the indicator to ON or false to set it to OFF
139      *
140      * @throws RotelException in case the zone 2 indicator is undefined
141      */
142     public void setZone2(byte[] flags, boolean on) throws RotelException {
143         RotelFlagsMapping.setBitFlag(flags, zone2FlagNumber, zone2BitNumber, on);
144     }
145
146     /**
147      * Get the zone 3 indicator
148      *
149      * @param flags the table of flags
150      *
151      * @return true if the indicator is ON in the flags or false if OFF
152      *
153      * @throws RotelException in case the zone 3 indicator is undefined
154      */
155     public boolean isZone3On(byte[] flags) throws RotelException {
156         return RotelFlagsMapping.isBitFlagOn(flags, zone3FlagNumber, zone3BitNumber);
157     }
158
159     /**
160      * Set the zone 3 indicator
161      *
162      * @param flags the table of flags
163      * @param on true to set the indicator to ON or false to set it to OFF
164      *
165      * @throws RotelException in case the zone 3 indicator is undefined
166      */
167     public void setZone3(byte[] flags, boolean on) throws RotelException {
168         RotelFlagsMapping.setBitFlag(flags, zone3FlagNumber, zone3BitNumber, on);
169     }
170
171     /**
172      * Get the zone 4 indicator
173      *
174      * @param flags the table of flags
175      *
176      * @return true if the indicator is ON in the flags or false if OFF
177      *
178      * @throws RotelException in case the zone 4 indicator is undefined
179      */
180     public boolean isZone4On(byte[] flags) throws RotelException {
181         return RotelFlagsMapping.isBitFlagOn(flags, zone4FlagNumber, zone4BitNumber);
182     }
183
184     /**
185      * Set the zone 4 indicator
186      *
187      * @param flags the table of flags
188      * @param on true to set the indicator to ON or false to set it to OFF
189      *
190      * @throws RotelException in case the zone 4 indicator is undefined
191      */
192     public void setZone4(byte[] flags, boolean on) throws RotelException {
193         RotelFlagsMapping.setBitFlag(flags, zone4FlagNumber, zone4BitNumber, on);
194     }
195
196     /**
197      * Check whether more than front channels are ON
198      *
199      * @param flags the table of flags
200      *
201      * @return true if the indicators show that center or surround channels are ON in the flags
202      *
203      * @throws RotelException in case the center or surround channel indicators are undefined
204      */
205     public boolean isMoreThan2Channels(byte[] flags) throws RotelException {
206         return (centerFlagNumber >= 1 && centerFlagNumber <= flags.length
207                 && RotelFlagsMapping.isBitFlagOn(flags, centerFlagNumber, centerBitNumber))
208                 || (surroundLeftFlagNumber >= 1 && surroundLeftFlagNumber <= flags.length
209                         && RotelFlagsMapping.isBitFlagOn(flags, surroundLeftFlagNumber, surroundLeftBitNumber))
210                 || (surroundRightFlagNumber >= 1 && surroundRightFlagNumber <= flags.length
211                         && RotelFlagsMapping.isBitFlagOn(flags, surroundRightFlagNumber, surroundRightBitNumber));
212     }
213
214     /**
215      * Get a bit value inside the provided table of flags
216      *
217      * @param flags the table of flags
218      * @param flagNumber the flag number to consider
219      * @param bitNumber the bit number in the flag to consider
220      *
221      * @return true if the bit value in the flag is 1 or false if 0
222      *
223      * @throws RotelException in case of out of bounds value for the flag number or the bit number
224      */
225     public static boolean isBitFlagOn(byte[] flags, int flagNumber, int bitNumber) throws RotelException {
226         if (flagNumber < 1 || flagNumber > flags.length) {
227             throw new RotelException("Flag number out of bounds");
228         }
229         if (bitNumber < 0 || bitNumber > 7) {
230             throw new RotelException("Bit number out of bounds");
231         }
232         int val = flags[flagNumber - 1] & 0x000000FF;
233         return (val & (1 << bitNumber)) != 0;
234     }
235
236     /**
237      * Set a bit value to 1 or 0 in the provided table of flags
238      *
239      * @param flags the table of flags
240      * @param flagNumber the flag number to consider
241      * @param bitNumber the bit number in the flag to consider
242      * @param on true to set the bit value to 1 or false to set it to 0
243      *
244      * @throws RotelException in case of out of bounds value for the flag number or the bit number
245      */
246     private static void setBitFlag(byte[] flags, int flagNumber, int bitNumber, boolean on) throws RotelException {
247         if (flagNumber < 1 || flagNumber > flags.length) {
248             throw new RotelException("Flag number out of bounds");
249         }
250         if (bitNumber < 0 || bitNumber > 7) {
251             throw new RotelException("Bit number out of bounds");
252         }
253         if (on) {
254             flags[flagNumber - 1] |= (1 << bitNumber);
255         } else {
256             flags[flagNumber - 1] &= ~(1 << bitNumber);
257         }
258     }
259 }