001/**
002 * Copyright (c) 2014 Digi International Inc.,
003 * All rights not expressly granted are reserved.
004 *
005 * This Source Code Form is subject to the terms of the Mozilla Public
006 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
007 * You can obtain one at http://mozilla.org/MPL/2.0/.
008 *
009 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
010 * =======================================================================
011 */
012package com.digi.xbee.api.models;
013
014import java.util.HashMap;
015
016/**
017 * Enumerates the available XBee protocols. The XBee protocol is determined 
018 * by the combination of hardware and firmware of an XBee device.
019 */
020public enum XBeeProtocol {
021        
022        // Enumeration entries
023        ZIGBEE(0, "ZigBee"),
024        RAW_802_15_4(1, "802.15.4"),
025        XBEE_WIFI(2, "Wi-Fi"),
026        DIGI_MESH(3, "DigiMesh"),
027        XCITE(4, "XCite"),
028        XTEND(5, "XTend (Legacy)"),
029        XTEND_DM(6, "XTend (DigiMesh)"),
030        SMART_ENERGY(7, "Smart Energy"),
031        DIGI_POINT(8, "Point-to-multipoint"),
032        ZNET(9, "ZNet 2.5"),
033        XC(10, "XSC"),
034        XLR(11, "XLR"),
035        XLR_DM(12, "XLR"), // TODO [XLR_DM] XLR device with DigiMesh support.
036        UNKNOWN(99, "Unknown");
037        
038        // Variables
039        private static final HashMap<Integer, XBeeProtocol> lookupTable = new HashMap<Integer, XBeeProtocol>();
040        
041        private final int id;
042        
043        private final String description;
044        
045        static {
046                for (XBeeProtocol xbeeProtocol:values())
047                        lookupTable.put(xbeeProtocol.getID(), xbeeProtocol);
048        }
049        
050        /**
051         * Class constructor. Instantiates a new {@code XBeeProtocol} enumeration 
052         * entry with the given parameters.
053         * 
054         * @param id XBee protocol ID.
055         * @param description XBee protocol description.
056         */
057        private XBeeProtocol(int id, String description) {
058                this.id = id;
059                this.description = description;
060        }
061        
062        /**
063         * Returns the XBee protocol ID.
064         * 
065         * @return XBee protocol ID.
066         */
067        public int getID() {
068                return id;
069        }
070        
071        /**
072         * Returns the XBee protocol description.
073         * 
074         * @return XBee protocol description.
075         */
076        public String getDescription() {
077                return description;
078        }
079        
080        /**
081         * Returns the {@code XBeeProtocol} associated to the given ID.
082         * 
083         * @param id The ID of the {@code XBeeProtocol} to retrieve.
084         * 
085         * @return The {@code XBeeProtocol} associated to the given ID.
086         */
087        public static XBeeProtocol get(int id) {
088                if (!lookupTable.containsKey(id))
089                        return UNKNOWN;
090                return lookupTable.get(id);
091        }
092        
093        /**
094         * Determines the XBee protocol based on the given Hardware and firmware 
095         * versions.
096         * 
097         * @param hardwareVersion The hardware version of the protocol to 
098         *                        determine.
099         * @param firmwareVersion The firmware version of the protocol to 
100         *                        determine.
101         * 
102         * @return The XBee protocol corresponding to the given hardware and 
103         *         firmware versions.
104         * 
105         * @see HardwareVersion
106         */
107        public static XBeeProtocol determineProtocol(HardwareVersion hardwareVersion, String firmwareVersion) {
108                if (hardwareVersion == null || firmwareVersion == null || hardwareVersion.getValue() < 0x09)
109                        return UNKNOWN;
110                else if (hardwareVersion.getValue() == HardwareVersionEnum.XC09_009.getValue() 
111                                || hardwareVersion.getValue() == HardwareVersionEnum.XC09_038.getValue())
112                        return XCITE;
113                else if (hardwareVersion.getValue() == HardwareVersionEnum.XT09_XXX.getValue()) {
114                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
115                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
116                                return XTEND_DM;
117                        return XTEND;
118                }
119                else if (hardwareVersion.getValue() == HardwareVersionEnum.XB24_AXX_XX.getValue() 
120                                || hardwareVersion.getValue() == HardwareVersionEnum.XBP24_AXX_XX.getValue()) {
121                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8")))
122                                        return DIGI_MESH;
123                        return RAW_802_15_4;
124                }
125                else if (hardwareVersion.getValue() == HardwareVersionEnum.XB24_BXIX_XXX.getValue() 
126                                || hardwareVersion.getValue() == HardwareVersionEnum.XBP24_BXIX_XXX.getValue()) {
127                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("1") && firmwareVersion.endsWith("20")) 
128                                        || (firmwareVersion.length() == 4 && firmwareVersion.startsWith("2")))
129                                return ZIGBEE;
130                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
131                                return SMART_ENERGY;
132                        return ZNET;
133                }
134                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBP09_DXIX_XXX.getValue()) {
135                        if ((firmwareVersion.length() == 4 && firmwareVersion.startsWith("8") 
136                                        || (firmwareVersion.length() == 4 && firmwareVersion.charAt(1) == '8'))
137                                        || (firmwareVersion.length() == 5 && firmwareVersion.charAt(1) == '8'))
138                                return DIGI_MESH;
139                        return DIGI_POINT;
140                }
141                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBP09_XCXX_XXX.getValue())
142                        return XC;
143                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBP08_DXXX_XXX.getValue())
144                        return DIGI_POINT;
145                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBP24B.getValue()) {
146                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("3"))
147                                return SMART_ENERGY;
148                        return ZIGBEE;
149                }
150                else if (hardwareVersion.getValue() == HardwareVersionEnum.XB24_WF.getValue() 
151                                        || hardwareVersion.getValue() == HardwareVersionEnum.WIFI_ATHEROS.getValue() 
152                                        || hardwareVersion.getValue() == HardwareVersionEnum.SMT_WIFI_ATHEROS.getValue())
153                        return XBEE_WIFI;
154                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBP24C.getValue() 
155                                        || hardwareVersion.getValue() == HardwareVersionEnum.XB24C.getValue()) {
156                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("5"))
157                                return SMART_ENERGY;
158                        return ZIGBEE;
159                }
160                else if (hardwareVersion.getValue() == HardwareVersionEnum.XSC_GEN3.getValue() 
161                                        || hardwareVersion.getValue() == HardwareVersionEnum.SRD_868_GEN3.getValue()) {
162                        if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("8"))
163                                return DIGI_MESH;
164                        else if (firmwareVersion.length() == 4 && firmwareVersion.startsWith("1"))
165                                return DIGI_POINT;
166                        return XC;
167                }
168                else if (hardwareVersion.getValue() == HardwareVersionEnum.XBEE_CELL_TH.getValue()) {
169                        return UNKNOWN;
170                }
171                else if (hardwareVersion.getValue() == HardwareVersionEnum.XLR_MODULE.getValue()) {
172                        // This is for the old version of the XLR we have (K60), and it is 
173                        // reporting the firmware of the module (8001), this will change in 
174                        // future (after K64 integration) reporting the hardware and firmware
175                        // version of the baseboard (see the case HardwareVersionEnum.XLR_BASEBOARD).
176                        // TODO maybe this should be removed in future, since this case will never be released.
177                        return XLR;
178                }
179                else if (hardwareVersion.getValue() == HardwareVersionEnum.XLR_BASEBOARD.getValue()) {
180                        // XLR devices with K64 will report the baseboard hardware version, 
181                        // and also firmware version (the one we have here is 1002, but this value
182                        // is not being reported since is an old K60 version, the module fw version
183                        // is reported instead).
184                        
185                        // TODO [XLR_DM] The next version of the XLR will add DigiMesh support should be added.
186                        // Probably this XLR_DM and XLR will depend on the firmware version.
187                        
188                        return XLR;
189                }
190                else if (hardwareVersion.getValue() == HardwareVersionEnum.XB900HP_NZ.getValue()) {
191                        return DIGI_POINT;
192                }
193                // If the hardware is not in the list, lets return Generic, at least 
194                // the configuration can be done and the console open.
195                else if (HardwareVersionEnum.get(hardwareVersion.getValue()) == null) {
196                        return UNKNOWN;
197                }
198                
199                // TODO: Logic protocol goes here.
200                return ZIGBEE;
201        }
202        
203        /*
204         * (non-Javadoc)
205         * @see java.lang.Enum#toString()
206         */
207        @Override
208        public String toString() {
209                return description;
210        }
211}