001/**
002 * Copyright 2017-2024, Digi International Inc.
003 *
004 * This Source Code Form is subject to the terms of the Mozilla Public
005 * License, v. 2.0. If a copy of the MPL was not distributed with this
006 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
007 *
008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
015 */
016package com.digi.xbee.api.models;
017
018import java.util.HashMap;
019
020/**
021 * Enumerates the available XBee protocols. The XBee protocol is determined 
022 * by the combination of hardware and firmware of an XBee device.
023 */
024public enum XBeeProtocol {
025        
026        // Enumeration entries
027        ZIGBEE(0, "ZigBee"),
028        RAW_802_15_4(1, "802.15.4"),
029        XBEE_WIFI(2, "Wi-Fi"),
030        DIGI_MESH(3, "DigiMesh"),
031        XCITE(4, "XCite"),
032        XTEND(5, "XTend (Legacy)"),
033        XTEND_DM(6, "XTend (DigiMesh)"),
034        SMART_ENERGY(7, "Smart Energy"),
035        DIGI_POINT(8, "Point-to-multipoint"),
036        ZNET(9, "ZNet 2.5"),
037        XC(10, "XSC"),
038        XLR(11, "XLR"),
039        XLR_DM(12, "XLR"), // TODO [XLR_DM] XLR device with DigiMesh support.
040        SX(13, "XBee SX"),
041        XLR_MODULE(14, "XLR Module"),
042        /** @since 1.2.0 */
043        CELLULAR(15, "Cellular"),
044        /**
045         * @deprecated Use {@link #CELLULAR} instead. 
046         * @since 1.2.1 */
047        CELLULAR_NBIOT(16, "Cellular NB-IoT"),
048        /** @since 1.2.1 */
049        THREAD(17, "Thread"),
050        /** @since 1.3.2 */
051        BLUETOOTH(18, "Bluetooth"),
052        UNKNOWN(99, "Unknown");
053        
054        // Variables
055        private static final HashMap<Integer, XBeeProtocol> lookupTable = new HashMap<Integer, XBeeProtocol>();
056        
057        private final int id;
058        
059        private final String description;
060        
061        static {
062                for (XBeeProtocol xbeeProtocol:values())
063                        lookupTable.put(xbeeProtocol.getID(), xbeeProtocol);
064        }
065        
066        /**
067         * Class constructor. Instantiates a new {@code XBeeProtocol} enumeration 
068         * entry with the given parameters.
069         * 
070         * @param id XBee protocol ID.
071         * @param description XBee protocol description.
072         */
073        private XBeeProtocol(int id, String description) {
074                this.id = id;
075                this.description = description;
076        }
077        
078        /**
079         * Returns the XBee protocol ID.
080         * 
081         * @return XBee protocol ID.
082         */
083        public int getID() {
084                return id;
085        }
086        
087        /**
088         * Returns the XBee protocol description.
089         * 
090         * @return XBee protocol description.
091         */
092        public String getDescription() {
093                return description;
094        }
095        
096        /**
097         * Returns the {@code XBeeProtocol} associated to the given ID.
098         * 
099         * @param id The ID of the {@code XBeeProtocol} to retrieve.
100         * 
101         * @return The {@code XBeeProtocol} associated to the given ID.
102         */
103        public static XBeeProtocol get(int id) {
104                if (!lookupTable.containsKey(id))
105                        return UNKNOWN;
106                return lookupTable.get(id);
107        }
108        
109        /**
110         * Determines the XBee protocol based on the given Hardware and firmware 
111         * versions.
112         * 
113         * @param hardwareVersion The hardware version of the protocol to 
114         *                        determine.
115         * @param firmwareVersion The firmware version of the protocol to 
116         *                        determine.
117         * 
118         * @return The XBee protocol corresponding to the given hardware and 
119         *         firmware versions.
120         * 
121         * @see HardwareVersion
122         */
123        @SuppressWarnings("deprecation")
124        public static XBeeProtocol determineProtocol(HardwareVersion hardwareVersion, String firmwareVersion) {
125                if (hardwareVersion == null || firmwareVersion == null || hardwareVersion.getValue() < 0x09 
126                                || HardwareVersionEnum.get(hardwareVersion.getValue()) == null)
127                        return UNKNOWN;
128                switch (HardwareVersionEnum.get(hardwareVersion.getValue())) {
129                case XC09_009:
130                case XC09_038:
131                        return XCITE;
132                case XT09_XXX:
133                case XT09B_XXX:
134                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
135                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
136                                return XTEND_DM;
137                        return XTEND;
138                case XB24_AXX_XX:
139                case XBP24_AXX_XX:
140                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8")))
141                                return DIGI_MESH;
142                        return RAW_802_15_4;
143                case XB24_BXIX_XXX:
144                case XBP24_BXIX_XXX:
145                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("1") && firmwareVersion.endsWith("20")) 
146                                        || (firmwareVersion.length() == 4 && firmwareVersion.startsWith("2")))
147                                return ZIGBEE;
148                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
149                                return SMART_ENERGY;
150                        return ZNET;
151                case XBP09_DXIX_XXX:
152                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8") 
153                                        || (firmwareVersion.length() == 4 && firmwareVersion.charAt(1) == '8'))
154                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
155                                return DIGI_MESH;
156                        return DIGI_POINT;
157                case XBP09_XCXX_XXX:
158                        return XC;
159                case XBP08_DXXX_XXX:
160                        return DIGI_POINT;
161                case XBP24B:
162                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
163                                return SMART_ENERGY;
164                        return ZIGBEE;
165                case XB24_WF:
166                case WIFI_ATHEROS:
167                case SMT_WIFI_ATHEROS:
168                        return XBEE_WIFI;
169                case XBP24C:
170                case XB24C:
171                        if (firmwareVersion.length() == 4 && (firmwareVersion.startsWith("5") || firmwareVersion.startsWith("6")))
172                                return SMART_ENERGY;
173                        else if (firmwareVersion.startsWith("2"))
174                                return RAW_802_15_4;
175                        else if (firmwareVersion.startsWith("9"))
176                                return DIGI_MESH;
177                        return ZIGBEE;
178                case XSC_GEN3:
179                case SRD_868_GEN3:
180                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
181                                return DIGI_MESH;
182                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("1"))
183                                return DIGI_POINT;
184                        return XC;
185                case XBEE_CELL_TH:
186                        return UNKNOWN;
187                case XLR_MODULE:
188                        // This is for the old version of the XLR we have (K60), and it is 
189                        // reporting the firmware of the module (8001), this will change in 
190                        // future (after K64 integration) reporting the hardware and firmware
191                        // version of the baseboard (see the case HardwareVersionEnum.XLR_BASEBOARD).
192                        // TODO maybe this should be removed in future, since this case will never be released.
193                        if (firmwareVersion.startsWith("1"))
194                                return XLR;
195                        else
196                                return XLR_MODULE;
197                case XLR_BASEBOARD:
198                        // XLR devices with K64 will report the baseboard hardware version, 
199                        // and also firmware version (the one we have here is 1002, but this value
200                        // is not being reported since is an old K60 version, the module fw version
201                        // is reported instead).
202                        
203                        // TODO [XLR_DM] The next version of the XLR will add DigiMesh support should be added.
204                        // Probably this XLR_DM and XLR will depend on the firmware version.
205                        
206                        if (firmwareVersion.startsWith("1"))
207                                return XLR;
208                        else
209                                return XLR_MODULE;
210                case XB900HP_NZ:
211                        return DIGI_POINT;
212                case XBP24C_TH_DIP:
213                case XB24C_TH_DIP:
214                case XBP24C_S2C_SMT:
215                        if (firmwareVersion.length() == 4 && (firmwareVersion.startsWith("5") || firmwareVersion.startsWith("6")))
216                                return SMART_ENERGY;
217                        else if (firmwareVersion.startsWith("2"))
218                                return RAW_802_15_4;
219                        else if (firmwareVersion.startsWith("9"))
220                                return DIGI_MESH;
221                        return ZIGBEE;
222                case SX_PRO:
223                case SX:
224                case XTR:
225                        if (firmwareVersion.startsWith("2"))
226                                return XTEND;
227                        else if (firmwareVersion.startsWith("8"))
228                                return XTEND_DM;
229                        else
230                                return SX;
231                case S2D_SMT_PRO:
232                case S2D_SMT_REG:
233                case S2D_TH_PRO:
234                case S2D_TH_REG:
235                        if (firmwareVersion.startsWith("8"))
236                                return THREAD;
237                        else
238                                return ZIGBEE;
239                case CELLULAR:
240                case CELLULAR_CAT1_LTE_VERIZON:
241                case CELLULAR_3G:
242                case CELLULAR_LTE_VERIZON:
243                case CELLULAR_LTE_ATT:
244                case CELLULAR_NBIOT_EUROPE:
245                case CELLULAR_3_CAT1_LTE_ATT:
246                case CELLULAR_3_LTE_M_VERIZON:
247                case CELLULAR_3_LTE_M_ATT:
248                case CELLULAR_3_LTE_M_ATT_TELIT:
249                case CELLULAR_3_CAT1_LTE_VERIZON:
250                case CELLULAR_3_LTE_M_TELIT:
251                case CELLULAR_3_GLOBAL_LTE_CAT1:
252                case CELLULAR_3_NA_LTE_CAT1:
253                case CELLULAR_3_LTE_M_LOW_POWER:
254                case CELLULAR_3_GLOBAL_CAT4:
255                case CELLULAR_3_NA_CAT4:
256                        return CELLULAR;
257                case XBEE3:
258                case XBEE3_SMT:
259                case XBEE3_TH:
260                case XBEE3_RR:
261                case XBEE3_RR_TH:
262                        if (firmwareVersion.startsWith("2"))
263                                return RAW_802_15_4;
264                        else if (firmwareVersion.startsWith("3"))
265                                return DIGI_MESH;
266                        else
267                                return ZIGBEE;
268                case XB8X:
269                        return DIGI_MESH;
270                case XBEE3_DM_LR:
271                case XBEE3_DM_LR_868:
272                case XBEE_XR_900_TH:
273                case XBEE_XR_868_TH:
274                        return DIGI_MESH;
275                case S2C_P5:
276                        if (firmwareVersion.toLowerCase().startsWith("b"))
277                                return DIGI_MESH;
278                        else if (firmwareVersion.toLowerCase().startsWith("c"))
279                                return RAW_802_15_4;
280                        return ZIGBEE;
281                case XBEE_BLU_MICRO_SMT:
282                case XBEE_BLU_TH:
283                        return BLUETOOTH;
284                default:
285                        return ZIGBEE;
286                }
287        }
288        
289        /*
290         * (non-Javadoc)
291         * @see java.lang.Enum#toString()
292         */
293        @Override
294        public String toString() {
295                return description;
296        }
297}