Completing ZigbeeTest with doorlock test
[iot2.git] / benchmarks / other / DoorlockAndOutlet / IoTZigbee.java
1
2 // Java packages
3 import java.io.IOException;
4 import java.net.DatagramPacket;
5 import java.net.DatagramSocket;
6 import java.net.InetAddress;
7 import java.net.SocketException;
8 import java.net.UnknownHostException;
9 import java.util.concurrent.atomic.AtomicBoolean;
10 import java.util.List;
11 import java.util.ArrayList;
12 import java.util.Map;
13 import java.util.HashMap;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.Set;
16 import java.util.HashSet;
17 import java.nio.charset.StandardCharsets;
18 import java.util.concurrent.Semaphore;
19
20
21 /** Class IoTZigbee
22  *
23  * @author      Ali Younis <ayounis @ uci.edu>, Changwoo Lee <changwl2 @ uci.edu>
24  * @version     1.0
25  * @since       2016-04-12, 2016-10-28
26  */
27 public class IoTZigbee {
28
29         public final int SOCKET_SEND_BUFFER_SIZE = 1024;
30         public final int SOCKET_RECEIVE_BUFFER_SIZE = 1024;
31         public final int SHORT_ADDRESS_UPDATE_TIME_MSEC = 10000;
32         public final int SHORT_ADDRESS_UPDATE_TIME_FAST_MSEC = 500;
33         public final int RESEND_WAIT_TIME = 500;
34
35         /**
36          * IoTZigbee class properties
37          */
38
39         // UDP connection stuff
40         private final String strHostAddress;
41         private final int iSrcPort;
42         private final int iDstPort;
43         private DatagramSocket socket;  // the socket interface that we are guarding
44         private boolean didClose;                                                               // make sure that the clean up was done correctly
45
46         private final IoTZigbeeAddress zigbeeAddress;
47
48         // list that holds the callbacks
49         private List<IoTZigbeeCallback> callbackList = new ArrayList<IoTZigbeeCallback>();
50
51         /**
52          * IoTZigbee class concurrency and concurrency control
53          */
54         private Thread receiveThread = null;
55
56         private AtomicBoolean endTask = new AtomicBoolean(false);
57         private AtomicBoolean didSuccesfullySendAddress = new AtomicBoolean(false);
58
59         /**
60          * Class constructor
61          */
62         public IoTZigbee(IoTDeviceAddress iotDevAdd, IoTZigbeeAddress zigAddress) throws SocketException, IOException, InterruptedException {
63
64                 strHostAddress = iotDevAdd.getHostAddress();
65                 iSrcPort = iotDevAdd.getSourcePortNumber();
66                 iDstPort = iotDevAdd.getDestinationPortNumber();
67                 didClose = false;
68                 zigbeeAddress = zigAddress;
69
70                 socket = new DatagramSocket(iSrcPort);
71                 socket.setSendBufferSize(SOCKET_SEND_BUFFER_SIZE);
72                 socket.setReceiveBufferSize(SOCKET_RECEIVE_BUFFER_SIZE);
73
74                 receiveThread = new Thread(new Runnable() {
75                         public void run() {
76                                 receieveWorker();
77                         }
78                 });
79                 receiveThread.start();
80         }
81
82         public void init() throws IOException {
83                 while (!didSuccesfullySendAddress.get()) {
84
85                         sendDeviceAddress();
86
87                         try {
88                                 Thread.sleep(RESEND_WAIT_TIME);
89                         } catch (Exception e) {
90                                 e.printStackTrace();
91                         }
92                 }
93         }
94         //made by changwoo
95         public void sendChangeSwtichRequest(int packetId, int clusterId, int profileId, int value, int deviceEndpoint) throws IOException {
96                 String message = "type: zcl_change_switch_request\n";
97                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
98                 message += "value: " + String.format("%01x", value) + "\n";
99                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
100                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
101                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
102                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
103                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
104                 socket.send(sendPacket);
105         }
106
107         //made by Jiawei
108         public void sendLockOrUnlockDoorRequest(int packetId, int clusterId, int profileId, int deviceEndpoint, int value) throws IOException {
109                 String message = "type: zcl_lock_or_unlock_door_request\n";
110                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
111                 message += "value: " + String.format("%01x", value) + "\n";
112                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
113                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
114                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
115                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
116                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
117                 socket.send(sendPacket);
118         }
119
120         //made by Jiawei
121         public void sendReadDoorStatusRequest(int packetId, int clusterId, int profileId, int deviceEndpoint, int framecontrol, int commandframe, int attribute_id) throws IOException {
122                 String message = "type: zcl_read_door_status_request\n";
123                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
124                 message += "framecontrol: " + String.format("%02x", framecontrol) + "\n";
125                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
126                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
127                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
128                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
129                 message += "commandframe: " + String.format("%02x", commandframe) + "\n";
130                 message += "attribute_id: " + String.format("%04x", attribute_id) + "\n";
131                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
132                 socket.send(sendPacket);
133         }
134
135         //made by changwoo
136         public void sendBroadcastingRouteRecordRequest(int packetId) throws IOException {
137                 String message = "type: zdo_broadcast_route_record_request\n";
138                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
139                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
140                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
141                 socket.send(sendPacket);
142         }
143
144         //made by changwoo
145         public void sendEnrollmentResponse(int packetId, int clusterId, int profileId, int deviceEndpoint) throws IOException {
146                 String message = "type: zcl_enrollment_response\n";
147                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
148                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
149                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
150                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
151                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
152                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
153                 socket.send(sendPacket);
154         }
155
156         //made by changwoo
157         public void sendWriteAttributesCommand(int packetId, int clusterId, int profileId, int deviceEndpoint) throws IOException {
158                 String message = "type: zcl_write_attributes\n";
159                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
160                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
161                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
162                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
163                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
164                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
165                 socket.send(sendPacket);
166         }
167
168         //made by changwoo
169         public void sendManagementPermitJoiningRequest(int packetId, int clusterId, int deviceEndpoint) throws IOException {
170                 String message = "type: management_permit_joining_request\n";
171                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
172                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
173                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
174                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
175                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
176                 socket.send(sendPacket);
177         }
178
179         public void sendBindRequest(int packetId, int clusterId, int deviceEndpoint) throws IOException {
180                 String message = "type: zdo_bind_request\n";
181                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
182                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
183                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
184                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
185                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
186                 socket.send(sendPacket);
187         }
188
189         public void sendUnBindRequest(int packetId, int clusterId, int deviceEndpoint) throws IOException {
190                 String message = "type: zdo_unbind_request\n";
191                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
192                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
193                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
194                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
195                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
196                 socket.send(sendPacket);
197         }
198
199         public void sendReadAttributesCommand(int packetId, int clusterId, int profileId, int deviceEndpoint, List<Integer> attributeIds) throws IOException {
200                 String message = "type: zcl_read_attributes\n";
201                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
202                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
203                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
204                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
205                 message += "device_endpoint: " + String.format("%02x", deviceEndpoint) + "\n";
206
207                 message += "attribute_ids: ";
208
209                 for (Integer i : attributeIds) {
210                         message += String.format("%04x", i) + ",";
211                 }
212
213                 message = message.substring(0, message.length() - 1);
214                 message += "\n";
215
216                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
217                 socket.send(sendPacket);
218         }
219
220         public void sendConfigureReportingCommand(int packetId, int clusterId, int profileId, int src_endpoint, int dest_endpoint, int attributeId, int dataType, int minReportingInterval, int maxReportingInterval, byte[] reportableChange) throws IOException {
221                 String message = "type: zcl_configure_reporting\n";
222                 message += "packet_id: " + String.format("%04x", packetId) + "\n";
223                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
224                 message += "cluster_id: " + String.format("%04x", clusterId) + "\n";
225                 message += "profile_id: " + String.format("%04x", profileId) + "\n";
226                 message += "src_endpoint: " + String.format("%02x", src_endpoint) + "\n";
227                 message += "device_endpoint: " + String.format("%02x", dest_endpoint) + "\n";
228                 message += "attribute_id: " + String.format("%04x", attributeId) + "\n";
229                 message += "data_type: " + String.format("%02x", dataType) + "\n";
230                 message += "min_reporting_interval: " + String.format("%04x", minReportingInterval) + "\n";
231                 message += "max_reporting_interval: " + String.format("%04x", maxReportingInterval) + "\n";
232
233                 if (reportableChange != null) {
234                         message += "reportable_change: ";
235                         for (Byte b : reportableChange) {
236                                 message += String.format("%02x", (int)b);
237                         }
238                         message += "\n";
239                 }
240
241                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
242                 socket.send(sendPacket);
243         }
244
245         public void sendConfigureReportingCommand(int packetId, int clusterId, int profileId, int dest_endpoint, int attributeId, int dataType, int minReportingInterval, int maxReportingInterval, byte[] reportableChange) throws IOException {
246                 sendConfigureReportingCommand(packetId, clusterId, profileId, 0x00, dest_endpoint, attributeId, dataType, minReportingInterval, maxReportingInterval, reportableChange);
247         }
248
249         public void registerCallback(IoTZigbeeCallback callbackTo) {
250
251                 callbackList.add(callbackTo);
252
253         }
254
255         public void close() throws InterruptedException {
256                 endTask.set(true);
257
258                 // wait for the threads to end
259                 receiveThread.join();
260
261                 socket.close();
262                 didClose = true;
263         }
264
265         /**
266          * close() called by the garbage collector right before trashing object
267          */
268         public void Finalize() throws SocketException, InterruptedException {
269
270                 if (!didClose) {
271                         close();
272                         throw new SocketException("Socket not closed before object destruction, must call close method.");
273                 }
274         }
275
276         private void sendDeviceAddress() throws IOException {
277                 String message = "type: send_address\n";
278                 message += "packet_id: 00\n";
279                 message += "device_address_long: " + zigbeeAddress.getAddress() + "\n";
280                 System.out.println(message);
281                 DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(strHostAddress), iDstPort);
282                 socket.send(sendPacket);
283         }
284
285         private void receieveWorker() {
286                 while (!(endTask.get())) {
287
288                         byte[] recBuffer = new byte[SOCKET_RECEIVE_BUFFER_SIZE];
289                         try {
290                                 DatagramPacket recPacket = new DatagramPacket(recBuffer, recBuffer.length);
291                                 socket.receive(recPacket);
292
293                                 // Convert the UDP data into a string format
294                                 String dataString = new String(recPacket.getData());
295
296                                 // split the data by line so we can start procesisng
297                                 String[] lines = dataString.split("\n");
298
299                                 Map<String, String> packetData = new HashMap<String, String>();
300                                 for (String line : lines) {
301
302                                         // trim the line
303                                         String trimmedLine = line.trim();
304                                         // make sure this is a valid data line and not just blank
305                                         if (trimmedLine.length() == 0) {
306                                                 continue;
307                                         }
308
309                                         // Split the data into parts
310                                         String[] parts = trimmedLine.split(":");
311                                         parts[0] = parts[0].trim();
312                                         parts[1] = parts[1].trim();
313                                         packetData.put(parts[0], parts[1]);
314                                 }
315
316                                 if (packetData.get("type").equals("send_address_response")) {
317                                         didSuccesfullySendAddress.set(true);
318
319                                 } else {
320                                         IoTZigbeeMessage callbackMessage = null;
321
322 /*
323                                         // made by changwoo
324                                         if (packetData.get("type").equals("zcl_match_descriptor_response")) {
325                                                 System.out.println("zcl_match_descriptor_response message arrives");
326
327                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
328                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
329                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
330                                                 boolean successOrFail = false;
331                                                 if(packetData.get("attributes").equals("success")) successOrFail=true;
332                                                 
333                                                 callbackMessage = new IoTZigbeeMessageMatchDescriptorResponse(packetId, clusterId, profileId, successOrFail);
334
335                                         }
336 */
337
338                                         // made by changwoo
339                                         if (packetData.get("type").equals("zcl_zone_status_change_notification")){
340                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
341                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
342                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
343                                                 int status = Integer.parseInt(packetData.get("status"), 10);
344                                                 boolean successOrFail = false;
345                                                 if(packetData.get("attributes").equals("success")) successOrFail=true;
346                                                 callbackMessage = new IoTZigbeeMessageZclZoneStatusChangeNotification(packetId, clusterId, profileId, status, successOrFail);
347
348                                                 // made by yuting
349                                         }else if (packetData.get("type").equals("zcl_change_switch_response")){
350                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
351                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
352                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
353                                                 int status = Integer.parseInt(packetData.get("status"), 10);
354                                                 boolean successOrFail = false;
355                                                 if(packetData.get("attributes").equals("success")) successOrFail=true;
356                                                 callbackMessage = new IoTZigbeeMessageZclChangeSwitchResponse(packetId, clusterId, profileId, status, successOrFail);
357
358                                         //made by changwoo
359                                         } else if (packetData.get("type").equals("zcl_write_attributes_response")) {
360
361                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
362                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
363                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
364                                                 boolean successOrFail = false;
365                                                 if(packetData.get("attributes").equals("success")) successOrFail=true;
366                                                 
367                                                 callbackMessage = new IoTZigbeeMessageZclWriteAttributesResponse(packetId, clusterId, profileId, successOrFail);
368
369                                         } else if (packetData.get("type").equals("zcl_read_attributes_response")) {
370                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
371                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
372                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
373
374                                                 List<IoTZigbeeMessageZclReadAttributesResponse.Attribute> attrList = new ArrayList<IoTZigbeeMessageZclReadAttributesResponse.Attribute>();
375
376                                                 String[] attributes = packetData.get("attributes").split(";");
377                                                 for (String attr : attributes) {
378                                                         attr = attr.trim();
379                                                         String[] parts = attr.split(",");
380
381                                                         if (parts.length == 2) {
382                                                                 parts[0] = parts[0].trim();
383                                                                 parts[1] = parts[1].trim();
384
385                                                                 IoTZigbeeMessageZclReadAttributesResponse.Attribute at = new IoTZigbeeMessageZclReadAttributesResponse.Attribute(Integer.parseInt(parts[0], 16), 0, false, null);
386                                                                 attrList.add(at);
387                                                         } else {
388                                                                 parts[0] = parts[0].trim();
389                                                                 parts[1] = parts[1].trim();
390                                                                 parts[2] = parts[2].trim();
391                                                                 parts[3] = parts[3].trim();
392                                                                 IoTZigbeeMessageZclReadAttributesResponse.Attribute at = new IoTZigbeeMessageZclReadAttributesResponse.Attribute(Integer.parseInt(parts[0], 16), Integer.parseInt(parts[1], 16), true, hexStringToByteArray(parts[3]));
393                                                                 attrList.add(at);
394                                                         }
395                                                 }
396
397                                                 callbackMessage = new IoTZigbeeMessageZclReadAttributesResponse(packetId, clusterId, profileId, attrList);
398
399                                         } else if (packetData.get("type").equals("zcl_configure_reporting_response")) {
400                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
401                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
402                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
403
404                                                 if (packetData.get("attributes").equals("all_success")) {
405                                                         callbackMessage = new IoTZigbeeMessageZclConfigureReportingResponse(packetId, clusterId, profileId, true, null);
406                                                 } else {
407                                                         List<IoTZigbeeMessageZclConfigureReportingResponse.Attribute> attrList = new ArrayList<IoTZigbeeMessageZclConfigureReportingResponse.Attribute>();
408
409                                                         String[] attributes = packetData.get("attributes").split(";");
410                                                         for (String attr : attributes) {
411                                                                 attr = attr.trim();
412                                                                 String[] parts = attr.split(",");
413                                                                 parts[0] = parts[0].trim();
414                                                                 parts[1] = parts[1].trim();
415                                                                 parts[2] = parts[2].trim();
416                                                                 IoTZigbeeMessageZclConfigureReportingResponse.Attribute at = new IoTZigbeeMessageZclConfigureReportingResponse.Attribute(Integer.parseInt(parts[0], 16), parts[1].equals("success"), parts[2].equals("reported"));
417                                                                 attrList.add(at);
418                                                         }
419                                                         callbackMessage = new IoTZigbeeMessageZclConfigureReportingResponse(packetId, clusterId, profileId, false, attrList);
420                                                 }
421
422                                         } else if (packetData.get("type").equals("zcl_report_attributes")) {
423                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
424                                                 int clusterId = Integer.parseInt(packetData.get("cluster_id"), 16);
425                                                 int profileId = Integer.parseInt(packetData.get("profile_id"), 16);
426
427                                                 List<IoTZigbeeMessageZclReportAttributes.Attribute> attrList = new ArrayList<IoTZigbeeMessageZclReportAttributes.Attribute>();
428
429                                                 String[] attributes = packetData.get("attributes").split(";");
430                                                 for (String attr : attributes) {
431                                                         attr = attr.trim();
432                                                         String[] parts = attr.split(",");
433
434                                                         parts[0] = parts[0].trim();
435                                                         parts[1] = parts[1].trim();
436                                                         parts[2] = parts[2].trim();
437                                                         IoTZigbeeMessageZclReportAttributes.Attribute at = new IoTZigbeeMessageZclReportAttributes.Attribute(Integer.parseInt(parts[0], 16), Integer.parseInt(parts[1], 16), hexStringToByteArray(parts[2]));
438                                                         attrList.add(at);
439                                                 }
440
441                                                 callbackMessage = new IoTZigbeeMessageZclReportAttributes(packetId, clusterId, profileId, attrList);
442
443                                         } else if (packetData.get("type").equals("zcl_read_attributes")) {
444                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
445                                                 boolean success = packetData.get("response").equals("success");
446
447                                                 if (success) {
448                                                         callbackMessage = new IoTZigbeeMessageZclReadAttributes(packetId, success, "");
449                                                 } else {
450                                                         callbackMessage = new IoTZigbeeMessageZclReadAttributes(packetId, success, packetData.get("reason"));
451                                                 }
452
453                                         } else if (packetData.get("type").equals("zcl_configure_reporting")) {
454                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
455                                                 boolean success = packetData.get("response").equals("success");
456
457                                                 if (success) {
458                                                         callbackMessage = new IoTZigbeeMessageZclConfigureReporting(packetId, success, "");
459                                                 } else {
460                                                         callbackMessage = new IoTZigbeeMessageZclConfigureReporting(packetId, success, packetData.get("reason"));
461                                                 }
462
463                                         } else if (packetData.get("type").equals("zdo_bind_request")) {
464                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
465                                                 boolean success = packetData.get("response").equals("success");
466
467                                                 if (success) {
468                                                         callbackMessage = new IoTZigbeeMessageZdoBindResponse(packetId, success, "");
469                                                 } else {
470                                                         callbackMessage = new IoTZigbeeMessageZdoBindResponse(packetId, success, packetData.get("reason"));
471                                                 }
472                                         }
473
474                                         else if (packetData.get("type").equals("zdo_unbind_request")) {
475                                                 int packetId = Integer.parseInt(packetData.get("packet_id"), 16);
476                                                 boolean success = packetData.get("response").equals("success");
477
478                                                 if (success) {
479                                                         callbackMessage = new IoTZigbeeMessageZdoUnBindResponse(packetId, success, "");
480                                                 } else {
481                                                         callbackMessage = new IoTZigbeeMessageZdoUnBindResponse(packetId, success, packetData.get("reason"));
482                                                 }
483                                         }
484
485                                         if (callbackMessage != null) {
486                                                 for (IoTZigbeeCallback c : callbackList) {
487                                                         c.newMessageAvailable(callbackMessage);
488                                                 }
489                                         }
490                                 }
491
492
493
494                         } catch (Exception e) {
495                                 e.printStackTrace();
496                         }
497                 }
498         }
499
500         public static String changeHexEndianness(String hexData) {
501
502                 List<String> pairedValues = new ArrayList<String>();
503                 for (int i = 0; i < hexData.length(); i += 2) {
504                         String part = hexData.substring(i, Math.min(i + 2, hexData.length()));
505                         pairedValues.add(part);
506                 }
507
508                 String retString  = "";
509                 for (int i = (pairedValues.size() - 1); i >= 0; i--) {
510                         retString += pairedValues.get(i);
511                 }
512                 return retString;
513         }
514
515         // taken from: http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
516         public static byte[] hexStringToByteArray(String s) {
517                 int len = s.length();
518                 byte[] data = new byte[len / 2];
519                 for (int i = 0; i < len; i += 2) {
520                         data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
521                                               + Character.digit(s.charAt(i + 1), 16));
522                 }
523                 return data;
524         }
525
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542