View Javadoc
1   package net.sf.mbus4j.json;
2   
3   /*
4    * #%L
5    * mbus4j-core
6    * %%
7    * Copyright (C) 2009 - 2014 MBus4J
8    * %%
9    * mbus4j - Drivers for the M-Bus protocol - http://mbus4j.sourceforge.net/
10   * Copyright (C) 2009-2014, mbus4j.sf.net, and individual contributors as indicated
11   * by the @authors tag. See the copyright.txt in the distribution for a
12   * full listing of individual contributors.
13   * 
14   * This is free software; you can redistribute it and/or modify it
15   * under the terms of the GNU General Public License as
16   * published by the Free Software Foundation; either version 3 of
17   * the License, or (at your option) any later version.
18   * 
19   * This software is distributed in the hope that it will be useful,
20   * but WITHOUT ANY WARRANTY; without even the implied warranty of
21   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22   * Lesser General Public License for more details.
23   * 
24   * You should have received a copy of the GNU Lesser General Public
25   * License along with this software; if not, write to the Free
26   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
28   * #L%
29   */
30  import net.sf.json.JSONArray;
31  import net.sf.json.JSONObject;
32  import net.sf.mbus4j.dataframes.ApplicationReset;
33  import net.sf.mbus4j.dataframes.Frame;
34  import net.sf.mbus4j.dataframes.Frame.ControlCode;
35  import net.sf.mbus4j.dataframes.GeneralApplicationError;
36  import net.sf.mbus4j.dataframes.LongFrame;
37  import net.sf.mbus4j.dataframes.RequestClassXData;
38  import net.sf.mbus4j.dataframes.SendUserData;
39  import net.sf.mbus4j.dataframes.SetBaudrate;
40  import net.sf.mbus4j.dataframes.SynchronizeAction;
41  import net.sf.mbus4j.dataframes.UserDataResponse;
42  import net.sf.mbus4j.dataframes.datablocks.DataBlock;
43  import net.sf.mbus4j.dataframes.datablocks.dif.DataFieldCode;
44  import net.sf.mbus4j.dataframes.datablocks.dif.VariableLengthType;
45  import net.sf.mbus4j.dataframes.datablocks.vif.Vif;
46  import net.sf.mbus4j.dataframes.datablocks.vif.Vife;
47  
48  /**
49   *
50   * @author aploese
51   */
52  public class JSONFactory {
53  
54      public static String encodeHexByteArray(byte[] value) {
55          StringBuilder sb = new StringBuilder();
56          sb.append("0x[");
57          if (value != null) {
58              for (byte b : value) {
59                  sb.append(String.format("%02X", b));
60              }
61          }
62          sb.append("]");
63          return sb.toString();
64      }
65  
66      public static byte[] decodeHexByteArray(String value) {
67          byte[] result = new byte[(value.length() - 4) / 2];
68          int resIndex = 0;
69          for (int i = 3; i < value.length() - 1; i += 2) {
70              result[resIndex++] = (byte) Short.parseShort(value.substring(i, i + 2), 16);
71          }
72          return result;
73      }
74  
75      public static String encodeHexByte(byte b) {
76          return String.format("0x%02x", b & 0xFF);
77      }
78  
79      public static String encodeHexShort(short s) {
80          return String.format("0x%04x", s & 0xFF);
81      }
82  
83      public static byte decodeHexByte(JSONObject json, String key, byte defaultValue) {
84          return json.containsKey(key) ? (byte) Short.parseShort(json.getString(key).substring(2), 16) : defaultValue;
85      }
86  
87      public static short decodeHexShort(JSONObject json, String key, short defaultValue) {
88          return json.containsKey(key) ? (short) Short.parseShort(json.getString(key).substring(2), 16) : defaultValue;
89      }
90  
91      public static Frame createFrame(JSONObject json) {
92          if (json.containsKey("controlCode")) {
93              final ControlCode cc = ControlCode.valueOf(json.getString("controlCode"));
94              final String sendUsedDataSubtype = json.containsKey("subType") ? json.getString("subType") : null;
95              switch (cc) {
96                  case RSP_UD:
97                      if (GeneralApplicationError.RSP_UD_SUBTYPE.equals(sendUsedDataSubtype)) {
98                          return new GeneralApplicationError();
99                      } else {
100                         return new UserDataResponse();
101                     }
102                 case SND_UD:
103                     switch (sendUsedDataSubtype) {
104                         case SendUserData.SEND_USER_DATA_SUBTYPE:
105                             return new SendUserData();
106                         case ApplicationReset.SEND_USER_DATA_SUBTYPE:
107                             return new ApplicationReset();
108                         case SynchronizeAction.SEND_USER_DATA_SUBTYPE:
109                             return new SynchronizeAction();
110                         case SetBaudrate.SEND_USER_DATA_SUBTYPE:
111                             return new SetBaudrate();
112                         default:
113                             throw new UnsupportedOperationException("Unknown Send User Data Subcode: " + sendUsedDataSubtype);
114                     }
115                 case REQ_UD1:
116                     return new RequestClassXData(ControlCode.REQ_UD1);
117                 case REQ_UD2:
118                     return new RequestClassXData(ControlCode.REQ_UD2);
119                 default:
120                     throw new UnsupportedOperationException("Unknown ControlCode: " + cc);
121 
122             }
123         }
124         throw new UnsupportedOperationException("Unknown Class");
125     }
126 
127     public static Class<? extends DataBlock> getDataBlockClass(JSONObject json) {
128         JSONObject drh = json.getJSONObject("drh");
129         JSONObject dib = drh.getJSONObject("dib");
130         VariableLengthType variableLengthType = null;
131         if (dib.containsKey("variableLengthType")) {
132             variableLengthType = VariableLengthType.fromLabel(dib.getString("variableLengthType"));
133         }
134         DataFieldCode dfc = DataFieldCode.fromLabel(dib.getString("dataFieldCode"));
135         JSONObject vib = drh.getJSONObject("vib");
136         Vife[] vifes = null;
137         Vif vif = null;
138         if (!vib.isNullObject()) {
139             vif = DataBlock.vifFromJSON(vib.getJSONObject("vif"));
140             if (vib.containsKey("vifes")) {
141                 vifes = DataBlock.vifesFromJSON(vif.getVifType(), vib.getJSONArray("vifes"));
142             }
143         }
144         return DataBlock.getDataBlockClass(vif, vifes, dfc, variableLengthType);
145     }
146 
147     public static boolean getBoolean(JSONObject json, String key, boolean defaultValue) {
148         return json.containsKey(key) ? json.getBoolean(key) : defaultValue;
149     }
150 
151     public static short getShort(JSONObject json, String key, short defaultValue) {
152         return json.containsKey(key) ? (short) json.getInt(key) : defaultValue;
153     }
154 
155     public static void readDataBlocks(LongFrame longFrame, JSONObject json) {
156         JSONArray jsonDataBlocks = json.getJSONArray("dataBlocks");
157 
158         for (int i = 0; i < jsonDataBlocks.size(); i++) {
159             DataBlock db;
160             try {
161                 db = JSONFactory.getDataBlockClass(jsonDataBlocks.getJSONObject(i)).newInstance();
162             } catch (IllegalAccessException ex) {
163                 throw new RuntimeException(ex);
164             } catch (InstantiationException ex) {
165                 throw new RuntimeException(ex);
166             }
167             db.fromJSON(jsonDataBlocks.getJSONObject(i));
168             longFrame.addDataBlock(db);
169         }
170     }
171 }