001/**
002 * Copyright 2017-2019, 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        UNKNOWN(99, "Unknown");
051        
052        // Variables
053        private static final HashMap<Integer, XBeeProtocol> lookupTable = new HashMap<Integer, XBeeProtocol>();
054        
055        private final int id;
056        
057        private final String description;
058        
059        static {
060                for (XBeeProtocol xbeeProtocol:values())
061                        lookupTable.put(xbeeProtocol.getID(), xbeeProtocol);
062        }
063        
064        /**
065         * Class constructor. Instantiates a new {@code XBeeProtocol} enumeration 
066         * entry with the given parameters.
067         * 
068         * @param id XBee protocol ID.
069         * @param description XBee protocol description.
070         */
071        private XBeeProtocol(int id, String description) {
072                this.id = id;
073                this.description = description;
074        }
075        
076        /**
077         * Returns the XBee protocol ID.
078         * 
079         * @return XBee protocol ID.
080         */
081        public int getID() {
082                return id;
083        }
084        
085        /**
086         * Returns the XBee protocol description.
087         * 
088         * @return XBee protocol description.
089         */
090        public String getDescription() {
091                return description;
092        }
093        
094        /**
095         * Returns the {@code XBeeProtocol} associated to the given ID.
096         * 
097         * @param id The ID of the {@code XBeeProtocol} to retrieve.
098         * 
099         * @return The {@code XBeeProtocol} associated to the given ID.
100         */
101        public static XBeeProtocol get(int id) {
102                if (!lookupTable.containsKey(id))
103                        return UNKNOWN;
104                return lookupTable.get(id);
105        }
106        
107        /**
108         * Determines the XBee protocol based on the given Hardware and firmware 
109         * versions.
110         * 
111         * @param hardwareVersion The hardware version of the protocol to 
112         *                        determine.
113         * @param firmwareVersion The firmware version of the protocol to 
114         *                        determine.
115         * 
116         * @return The XBee protocol corresponding to the given hardware and 
117         *         firmware versions.
118         * 
119         * @see HardwareVersion
120         */
121        @SuppressWarnings("deprecation")
122        public static XBeeProtocol determineProtocol(HardwareVersion hardwareVersion, String firmwareVersion) {
123                if (hardwareVersion == null || firmwareVersion == null || hardwareVersion.getValue() < 0x09 
124                                || HardwareVersionEnum.get(hardwareVersion.getValue()) == null)
125                        return UNKNOWN;
126                switch (HardwareVersionEnum.get(hardwareVersion.getValue())) {
127                case XC09_009:
128                case XC09_038:
129                        return XCITE;
130                case XT09_XXX:
131                case XT09B_XXX:
132                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
133                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
134                                return XTEND_DM;
135                        return XTEND;
136                case XB24_AXX_XX:
137                case XBP24_AXX_XX:
138                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8")))
139                                return DIGI_MESH;
140                        return RAW_802_15_4;
141                case XB24_BXIX_XXX:
142                case XBP24_BXIX_XXX:
143                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("1") && firmwareVersion.endsWith("20")) 
144                                        || (firmwareVersion.length() == 4 && firmwareVersion.startsWith("2")))
145                                return ZIGBEE;
146                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
147                                return SMART_ENERGY;
148                        return ZNET;
149                case XBP09_DXIX_XXX:
150                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8") 
151                                        || (firmwareVersion.length() == 4 && firmwareVersion.charAt(1) == '8'))
152                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
153                                return DIGI_MESH;
154                        return DIGI_POINT;
155                case XBP09_XCXX_XXX:
156                        return XC;
157                case XBP08_DXXX_XXX:
158                        return DIGI_POINT;
159                case XBP24B:
160                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
161                                return SMART_ENERGY;
162                        return ZIGBEE;
163                case XB24_WF:
164                case WIFI_ATHEROS:
165                case SMT_WIFI_ATHEROS:
166                        return XBEE_WIFI;
167                case XBP24C:
168                case XB24C:
169                        if (firmwareVersion.length() == 4 && (firmwareVersion.startsWith("5") || firmwareVersion.startsWith("6")))
170                                return SMART_ENERGY;
171                        else if (firmwareVersion.startsWith("2"))
172                                return RAW_802_15_4;
173                        else if (firmwareVersion.startsWith("9"))
174                                return DIGI_MESH;
175                        return ZIGBEE;
176                case XSC_GEN3:
177                case SRD_868_GEN3:
178                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
179                                return DIGI_MESH;
180                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("1"))
181                                return DIGI_POINT;
182                        return XC;
183                case XBEE_CELL_TH:
184                        return UNKNOWN;
185                case XLR_MODULE:
186                        // This is for the old version of the XLR we have (K60), and it is 
187                        // reporting the firmware of the module (8001), this will change in 
188                        // future (after K64 integration) reporting the hardware and firmware
189                        // version of the baseboard (see the case HardwareVersionEnum.XLR_BASEBOARD).
190                        // TODO maybe this should be removed in future, since this case will never be released.
191                        if (firmwareVersion.startsWith("1"))
192                                return XLR;
193                        else
194                                return XLR_MODULE;
195                case XLR_BASEBOARD:
196                        // XLR devices with K64 will report the baseboard hardware version, 
197                        // and also firmware version (the one we have here is 1002, but this value
198                        // is not being reported since is an old K60 version, the module fw version
199                        // is reported instead).
200                        
201                        // TODO [XLR_DM] The next version of the XLR will add DigiMesh support should be added.
202                        // Probably this XLR_DM and XLR will depend on the firmware version.
203                        
204                        if (firmwareVersion.startsWith("1"))
205                                return XLR;
206                        else
207                                return XLR_MODULE;
208                case XB900HP_NZ:
209                        return DIGI_POINT;
210                case XBP24C_TH_DIP:
211                case XB24C_TH_DIP:
212                case XBP24C_S2C_SMT:
213                        if (firmwareVersion.length() == 4 && (firmwareVersion.startsWith("5") || firmwareVersion.startsWith("6")))
214                                return SMART_ENERGY;
215                        else if (firmwareVersion.startsWith("2"))
216                                return RAW_802_15_4;
217                        else if (firmwareVersion.startsWith("9"))
218                                return DIGI_MESH;
219                        return ZIGBEE;
220                case SX_PRO:
221                case SX:
222                case XTR:
223                        if (firmwareVersion.startsWith("2"))
224                                return XTEND;
225                        else if (firmwareVersion.startsWith("8"))
226                                return XTEND_DM;
227                        else
228                                return SX;
229                case S2D_SMT_PRO:
230                case S2D_SMT_REG:
231                case S2D_TH_PRO:
232                case S2D_TH_REG:
233                        if (firmwareVersion.startsWith("8"))
234                                return THREAD;
235                        else
236                                return ZIGBEE;
237                case CELLULAR:
238                case CELLULAR_CAT1_LTE_VERIZON:
239                case CELLULAR_3G:
240                case CELLULAR_LTE_VERIZON:
241                case CELLULAR_LTE_ATT:
242                case CELLULAR_NBIOT_EUROPE:
243                case CELLULAR_3_CAT1_LTE_ATT:
244                case CELLULAR_3_LTE_M_VERIZON:
245                case CELLULAR_3_LTE_M_ATT:
246                case CELLULAR_3_LTE_M_ATT_TELIT:
247                case CELLULAR_3_CAT1_LTE_VERIZON:
248                        return CELLULAR;
249                case XBEE3:
250                case XBEE3_SMT:
251                case XBEE3_TH:
252                        if (firmwareVersion.startsWith("2"))
253                                return RAW_802_15_4;
254                        else if (firmwareVersion.startsWith("3"))
255                                return DIGI_MESH;
256                        else
257                                return ZIGBEE;
258                case XB8X:
259                        return DIGI_MESH;
260                default:
261                        return ZIGBEE;
262                }
263        }
264        
265        /*
266         * (non-Javadoc)
267         * @see java.lang.Enum#toString()
268         */
269        @Override
270        public String toString() {
271                return description;
272        }
273}