Merging multiple versions of Xbee python driver
authorrtrimana <rtrimana@uci.edu>
Fri, 17 Feb 2017 19:57:55 +0000 (11:57 -0800)
committerrtrimana <rtrimana@uci.edu>
Fri, 17 Feb 2017 19:57:55 +0000 (11:57 -0800)
benchmarks/other/XbeePythonDriver/xbee_driver.py
benchmarks/other/XbeePythonDriver/xbee_driver_smartthings.py [deleted file]

index 84e7a0b0ac3ac63351dcda7132599be0a5be5c1c..99e93ae948319a18c75e861be05737f96033e139 100644 (file)
@@ -16,16 +16,18 @@ import threading
 # -----------------------------------------------------------------------------
 UDP_RECEIVE_PORT = 5005        # port used for incoming UDP data
 UDP_RECEIVE_BUFFER_SIZE = 4096  # max buffer size of an incoming UDP packet
-SYSTEM_MASTER_ADDRESS = ("192.168.2.108", 12345) # ip address and portof the system master node computer ip addr running java
+SYSTEM_MASTER_ADDRESS = ("192.168.2.108", 12345) # ip address and portof the system master node
 
 # time for messages to wait for a response before the system clears away that 
 # sequence identifier
 ZIGBEE_SEQUENCE_NUMBER_CLEAR_TIME_SEC = 5 
 
-ZIGBEE_SERIAL_PORT = "/dev/cu.usbserial-DN01DJIP"  # USB-Serial port of local radio
+#ZIGBEE_SERIAL_PORT = "/dev/cu.usbserial-DN01DCRH"  # USB-Serial port of local radio
+ZIGBEE_SERIAL_PORT = "/dev/ttyUSB0"
 ZIGBEE_SERIAL_BAUD = 115200                       # Baud rate for above port
 
 # address of our local zigbee radio
+#ZIGBEE_DEVICE_ADDRESS = "0013a20040d99cb4"
 ZIGBEE_DEVICE_ADDRESS = "xxxxxxxxxxxxxxxx"
 
 # -----------------------------------------------------------------------------
@@ -40,6 +42,11 @@ didGetLocalRadioLowAddress = False;
 zigbeeConnection = None
 zigbeeConnectionMutex = Lock()
 
+#singleton mabe by changwoo
+matchDescriptorReqSingleton = True
+deviceAnnouncementSingleton = True
+ManagementPermitJoiningReqSuccess = False
+
 # zigbee mapping from long to short object dict
 zigbeeLongShortAddr = dict()
 zigbeeLongShortAddrMutex = Lock()
@@ -72,14 +79,18 @@ doEndFlag = False
 sendSoceket = socket(AF_INET, SOCK_DGRAM)
 receiveSoceket = socket(AF_INET, SOCK_DGRAM)
 
-
 # zigbee address authority list
 zigbeeAddressAuthorityDict = dict()
 
+# made by changwoo
+seqNumberForNotification = dict()
+
 # -----------------------------------------------------------------------------
 # Helper Methods
 # -----------------------------------------------------------------------------
-
+def reverseShortAddress(shortAddr):
+    result = shortAddr[len(shortAddr)/2:]+shortAddr[0:len(shortAddr)/2]
+    return result
 
 def parseCommandLineArgs(argv):
     global ZIGBEE_SERIAL_PORT
@@ -358,7 +369,7 @@ def getConnectedRadioLongAddress():
         zigbeeConnection.send('at', command="SL")
         
         # sleep for a bit to give the radio time to respond before we check again
-        time.sleep(0.5)
+        time.sleep(2)
 
 def addressUpdateWorkerMethod():
     ''' Method to keep refreshing the short addresses of the known zigbee devices'''
@@ -397,6 +408,7 @@ def addressUpdateWorkerMethod():
 
             # create and send binding command
             zigbeeConnectionMutex.acquire()
+           
             zigbeeConnection.send('tx_explicit',
                                 frame_id='\x01',
                                 dest_addr_long=hexStringToZigbeeHexString(ad),
@@ -409,7 +421,7 @@ def addressUpdateWorkerMethod():
                                 )
             zigbeeConnectionMutex.release()
 
-        time.sleep(1)
+        time.sleep(8)
 
 
 # -------------
@@ -540,13 +552,8 @@ def processUdpSendAddressMessage(parsedData, addr):
     global zigbeeUnregisteredAddressesMutex
     global sendSoceket
 
-    if(zigbeeAddressAuthorityDict.has_key(addr)):
-        l = zigbeeAddressAuthorityDict[addr]
-        if(parsedData['device_address_long'] not in l):
-            return
-    else:
-        return
-
+    print "process send address"
+    
 
     # construct success message
     message = "type: send_address_response\n"
@@ -555,7 +562,8 @@ def processUdpSendAddressMessage(parsedData, addr):
 
     # tell client that we got their request
     sendSoceket.sendto(message,addr)
-
+    print "responding", message
+    
     # construct 
     zigbeeLongShortAddrMutex.acquire()
     doesHaveKey = zigbeeLongShortAddr.has_key(parsedData['device_address_long'])
@@ -570,6 +578,355 @@ def processUdpSendAddressMessage(parsedData, addr):
     zigbeeUnregisteredAddresses.append(parsedData['device_address_long'])
     zigbeeUnregisteredAddressesMutex.release()
 
+#made by changwoo
+def processUdpEnrollmentResponse(parsedData, addr):
+
+    global zigbeeLongShortAddr
+    global zigbeeLongShortAddrMutex
+    global zigeeBindRequestMutex
+    global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    shortAddr = None
+
+    # get the short address for this device long address if possible
+    zigbeeLongShortAddrMutex.acquire()
+    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
+        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
+    zigbeeLongShortAddrMutex.release()
+
+
+    # if there is a short address than we can send the message
+    # if there is not one then we cannot since we need both the short and
+    # the long address
+    if(shortAddr != None):
+
+        # get a request number
+        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
+        
+        # send back failure
+        if(seqNumber == -1):
+
+            # send an error message, could not get a sequence number to use at this time
+            sendUdpSuccessFail(addr, 'zcl_enrollment_response', parsedData['packet_id'], False, 'out_of_space')
+            return
+
+        # get the info for sending
+        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
+        destShortAddr = hexStringToZigbeeHexString(shortAddr)
+        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
+        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
+       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
+
+        # create the payload data
+        payloadData = ""
+        payloadData += '\x01'
+        payloadData += chr(seqNumber)
+        payloadData += '\x00'
+        payloadData += '\x00\x00'
+
+        # create and send binding command
+        zigbeeConnectionMutex.acquire()
+        zigbeeConnection.send('tx_explicit',
+                            frame_id='\x40',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=destLongAddr,
+                            dest_addr=destShortAddr,
+                            src_endpoint='\x01',
+                            dest_endpoint=dstEndpoint,
+                            cluster=clusterId,  
+                            profile=profileId,
+                            data=payloadData
+                            )
+       print '> EnrollmentResponse is sent'
+        zigbeeConnectionMutex.release()
+
+
+    else:
+        # send a fail response
+        sendUdpSuccessFail(addr, 'zcl_enrollment_response', parsedData['packet_id'], False, 'short_address_unknown')
+        pass
+
+
+
+
+#made by changwoo
+def processUdpZclWriteAttributesMessage(parsedData, addr):
+
+    global zigbeeLongShortAddr
+    global zigbeeLongShortAddrMutex
+    global zigeeBindRequestMutex
+    global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    shortAddr = None
+
+    # get the short address for this device long address if possible
+    zigbeeLongShortAddrMutex.acquire()
+    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
+        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
+    zigbeeLongShortAddrMutex.release()
+
+    # if there is a short address than we can send the message
+    # if there is not one then we cannot since we need both the short and
+    # the long address
+    if(shortAddr != None):
+        # get a request number
+        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
+        
+        # send back failure
+        if(seqNumber == -1):
+
+            # send an error message, could not get a sequence number to use at this time
+            sendUdpSuccessFail(addr, 'zcl_write_attributes', parsedData['packet_id'], False, 'out_of_space')
+            return
+
+        # get the info for sending
+        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
+        destShortAddr = hexStringToZigbeeHexString(shortAddr)
+        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
+       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
+        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
+
+        # create the payload data
+        payloadData = ""
+        payloadData += '\x00'
+        payloadData += chr(seqNumber)
+        payloadData += '\x02'
+        payloadData += '\x10\x00'
+        payloadData += '\xF0'
+#        payloadData += '\xDA\x9A\xD9\x40\x00\xA2\x13\x00'
+        payloadData += hexStringToZigbeeHexString(changeEndian(ZIGBEE_DEVICE_ADDRESS))
+
+        zigbeeConnectionMutex.acquire()
+        zigbeeConnection.send('tx_explicit',
+                            frame_id='\x08',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=destLongAddr,
+                            dest_addr=destShortAddr,
+                            src_endpoint='\x01',
+                            dest_endpoint=dstEndpoint,
+                            cluster=clusterId,
+                            profile=profileId,
+                            data=payloadData
+                            )
+
+       print ''
+       print '> WriteAttributesReq is sent : '+str(shortAddr)
+        zigbeeConnectionMutex.release()
+
+
+    else:
+        # send a fail response
+        sendUdpSuccessFail(addr, 'zcl_write_attributes', parsedData['packet_id'], False, 'short_address_unknown')
+        pass
+
+#made by changwoo
+def processUdpZclChangeSwitchReqMessage(parsedData, addr):
+
+    global zigbeeLongShortAddr
+    global zigbeeLongShortAddrMutex
+    global zigeeBindRequestMutex
+    global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    shortAddr = None
+
+    # get the short address for this device long address if possible
+    zigbeeLongShortAddrMutex.acquire()
+    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
+        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
+    zigbeeLongShortAddrMutex.release()
+
+
+    # if there is a short address than we can send the message
+    # if there is not one then we cannot since we need both the short and
+    # the long address
+    if(shortAddr != None):
+
+        # get a request number
+        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
+
+        # send back failure
+        if(seqNumber == -1):
+
+            # send an error message, could not get a sequence number to use at this time
+            sendUdpSuccessFail(addr, 'change_switch_request', parsedData['packet_id'], False, 'out_of_space')
+            return
+
+        # get the info for sending
+        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
+        destShortAddr = hexStringToZigbeeHexString(shortAddr)
+        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
+       clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
+       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
+       value = hexStringToZigbeeHexString(parsedData['value'])
+
+        # create and send binding command
+        zigbeeConnectionMutex.acquire()
+
+        zigbeeConnection.send('tx_explicit',
+                            frame_id='\x40',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=destLongAddr,
+                            dest_addr=destShortAddr,
+                            src_endpoint='\x01',
+                            dest_endpoint=dstEndpoint,
+                            cluster=clusterId,  
+                            profile=profileId,
+                            data='\x01'+chr(seqNumber)+value
+                            )
+        time.sleep(1)
+       if parsedData['value']==1:
+               print '> The outlet sensor turned on'
+       else :
+               print '> The outlet sensor turned off'
+
+        zigbeeConnectionMutex.release()
+
+
+    else:
+        # send a fail response
+        sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
+        pass
+
+
+
+# made by changwoo
+def processUdpBroadcastingRouteRecordReqMessage(parsedData, addr):
+
+    global zigbeeLongShortAddr
+    global zigbeeLongShortAddrMutex
+    global zigeeBindRequestMutex
+    global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    shortAddr = None
+
+    # get the short address for this device long address if possible
+    zigbeeLongShortAddrMutex.acquire()
+    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
+        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
+    zigbeeLongShortAddrMutex.release()
+
+
+    # if there is a short address than we can send the message
+    # if there is not one then we cannot since we need both the short and
+    # the long address
+    if(shortAddr != None):
+
+        # get a request number
+        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
+
+        # send back failure
+        if(seqNumber == -1):
+
+            # send an error message, could not get a sequence number to use at this time
+            sendUdpSuccessFail(addr, 'broadcast_route_record_request', parsedData['packet_id'], False, 'out_of_space')
+            return
+
+        # get the info for sending
+        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
+        destShortAddr = hexStringToZigbeeHexString(shortAddr)
+        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
+
+        # create and send binding command
+        zigbeeConnectionMutex.acquire()
+
+        zigbeeConnection.send('tx_explicit',
+                            frame_id='\x01',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long='\x00\x00\x00\x00\x00\x00\xff\xff',
+                            dest_addr='\xff\xfe',
+                            src_endpoint='\x00',
+                            dest_endpoint=dstEndpoint,
+                            cluster='\x00\x32',  
+                            profile='\x00\x00',
+                            data='\x12'+'\x01'
+                            )
+        time.sleep(1)
+       print '> BroadcastingRouteRecordReq is sent'
+
+        zigbeeConnectionMutex.release()
+
+
+    else:
+        # send a fail response
+        sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
+        pass
+
+
+#made by changwoo
+def processUdpManagementPermitJoiningReqMessage(parsedData, addr):
+
+    global zigbeeLongShortAddr
+    global zigbeeLongShortAddrMutex
+    global zigeeBindRequestMutex
+    global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    global matchDescriptorReqSingleton
+    shortAddr = None
+
+    # get the short address for this device long address if possible
+    zigbeeLongShortAddrMutex.acquire()
+    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
+        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
+    zigbeeLongShortAddrMutex.release()
+
+
+    # if there is a short address than we can send the message
+    # if there is not one then we cannot since we need both the short and
+    # the long address
+    if(shortAddr != None):
+
+        # get a request number
+        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
+        
+        # send back failure
+        if(seqNumber == -1):
+
+            # send an error message, could not get a sequence number to use at this time
+            sendUdpSuccessFail(addr, 'management_permit_joining_request', parsedData['packet_id'], False, 'out_of_space')
+            return
+
+        # get the info for sending
+        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
+        destShortAddr = hexStringToZigbeeHexString(shortAddr)
+        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
+
+        # create the payload data
+        payloadData = ""
+        payloadData += chr(seqNumber)
+        payloadData += '\x5a'
+        payloadData += '\x00'
+
+        # create and send binding command
+        zigbeeConnectionMutex.acquire()
+        zigbeeConnection.send('tx_explicit',
+                            frame_id='\x01',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=destLongAddr,
+                            dest_addr=destShortAddr,
+                            src_endpoint='\x00',
+                            dest_endpoint='\x00',
+                            cluster=clusterId,  
+                            profile='\x00\x00',
+                            data=payloadData
+                            )
+       print '> ManagementPermitJoiningReq is sent'
+
+       #stop answering 0x6
+       matchDescriptorReqSingleton= False
+        zigbeeConnectionMutex.release()
+
+
+    else:
+        # send a fail response
+        sendUdpSuccessFail(addr, 'management_permit_joining_request', parsedData['packet_id'], False, 'short_address_unknown')
+        pass
+
+
 def processUdpZclReadAttributesMessage(parsedData, addr):
     ''' Method handle a ZCL read attribute command
 
@@ -585,6 +942,7 @@ def processUdpZclReadAttributesMessage(parsedData, addr):
     global zigbeeConnection
 
 
+
     if(zigbeeAddressAuthorityDict.has_key(addr)):
         l = zigbeeAddressAuthorityDict[addr]
         if(parsedData['device_address_long'] not in l):
@@ -674,7 +1032,6 @@ def processUdpZclConfigureReportingMessage(parsedData, addr):
     global zigbeeConnectionMutex
     global zigbeeConnection
 
-
     if(zigbeeAddressAuthorityDict.has_key(addr)):
         l = zigbeeAddressAuthorityDict[addr]
         if(parsedData['device_address_long'] not in l):
@@ -682,6 +1039,7 @@ def processUdpZclConfigureReportingMessage(parsedData, addr):
     else:
         return
 
+
     shortAddr = None
 
     # get the short address for this device long address if possible
@@ -744,6 +1102,7 @@ def processUdpZclConfigureReportingMessage(parsedData, addr):
         sendUdpSuccessFail(addr, 'zcl_configure_reporting', parsedData['packet_id'], False, 'short_address_unknown')
         pass
 
+
 def processUdpPolicySet(parsedData, addr):
     ''' Method handle a policy set message
 
@@ -752,15 +1111,20 @@ def processUdpPolicySet(parsedData, addr):
     '''
     print "=================================================================="
     print "Policy set: ", parsedData
-    
+    print 'addr : ', addr
+
+
     # do nothing if wrong source
-    if addr == SYSTEM_MASTER_ADDRESS:
+    #if addr == SYSTEM_MASTER_ADDRESS or addr == SYSTEM_MASTER_ADDRESS2 or addr == SYSTEM_MASTER_ADDRESS3 :
+    #if addr == SYSTEM_MASTER_ADDRESS :
+    if addr[0] == SYSTEM_MASTER_ADDRESS[0]:
         key = (parsedData['ip_address'], int(parsedData['port']))
         if (zigbeeAddressAuthorityDict.has_key(key)):
             zigbeeAddressAuthorityDict[key].append(parsedData['device_address_long'])
         else:
             zigbeeAddressAuthorityDict[key] = [parsedData['device_address_long']]
 
+
 def processUdpPolicyClear(parsedData, addr):
     ''' Method handle a policy set message
 
@@ -771,9 +1135,11 @@ def processUdpPolicyClear(parsedData, addr):
     print "Clear policy: ", parsedData
     
     # do nothing if wrong source
-    if addr == SYSTEM_MASTER_ADDRESS:
+    #if addr == SYSTEM_MASTER_ADDRESS or addr == SYSTEM_MASTER_ADDRESS2 or addr == SYSTEM_MASTER_ADDRESS3:
+    if addr == SYSTEM_MASTER_ADDRESS :
         zigbeeAddressAuthorityDict.clear()
 
+
 # -------------
 # Zigbee 
 # -------------
@@ -820,11 +1186,14 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
     '''
     global zigeeBindRequestMutex
     global zigeeBindRequest
+    global zigbeeConnectionMutex
+    global zigbeeConnection
+    global ManagementPermitJoiningReqSuccess
 
     # get the long and short addresses from the message payload since we can 
     # use these to update the short addresses since this short address is fresh
     longAddr = zigbeeHexStringToHexString(parsedData['source_addr_long'])
-    shortAddr = zigbeeHexStringToHexString( parsedData['source_addr'])
+    shortAddr = zigbeeHexStringToHexString(parsedData['source_addr'])
 
     # check if this short address is for a device that has yet to be 
     # registered
@@ -838,13 +1207,53 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
     zigbeeLongShortAddr[longAddr] = shortAddr
     zigbeeLongShortAddrMutex.release()
 
+    global matchDescriptorReqSingleton
+    global deviceAnnouncementSingleton
+    global seqNumberForNotification
 
     # if this is a ZDO message/response
+    #print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+    #print parsedData
+    #print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
     if(parsedData['profile'] == '\x00\x00'):
 
+       # made by changwoo
+        # if this is a Match Descriptor Request so we need to answer.
+        if(parsedData['cluster'] == '\x00\x06' and matchDescriptorReqSingleton):
+            zigbeeConnectionMutex.acquire()
+            zigbeeConnection.send('tx_explicit',
+                            frame_id='\x08',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=parsedData['source_addr_long'],
+                            dest_addr=parsedData['source_addr'],
+                            src_endpoint='\x00',
+                            dest_endpoint='\x00',
+                            cluster='\x00\x06',
+                            profile='\x00\x00',
+                            data=parsedData['rf_data']
+                            )
+            time.sleep(1)
+            zigbeeConnection.send('tx_explicit',
+                            frame_id='\x40',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=parsedData['source_addr_long'],
+                            dest_addr=parsedData['source_addr'],
+                            src_endpoint='\x00',
+                            dest_endpoint='\x00',
+                            cluster='\x80\x06',
+                            profile='\x00\x00',
+                            data=parsedData['rf_data'][0]+ '\x00\x00\x00' + '\x01\x01'
+                            )
+            time.sleep(1)
+            print ''
+            print '[ 0x0006 ] Match Descriptor Request - answered'
+            print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+            zigbeeConnectionMutex.release()
+
+
         # if this is a device announcement so we can get some useful data from it
-        if(parsedData['cluster'] == '\x00\x13'):
-            
+        elif(parsedData['cluster'] == '\x00\x13' and deviceAnnouncementSingleton):
+            #print parsedData
             # pick out the correct parts of the payload
             longAddr = zigbeeHexStringToHexString(parsedData['rf_data'][3:11])
             shortAddr = zigbeeHexStringToHexString(parsedData['rf_data'][1:3])
@@ -865,12 +1274,34 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
                 zigbeeUnregisteredAddresses.remove(longAddr)
             zigbeeUnregisteredAddressesMutex.release()
 
+
+           # made by changwoo
+            zigbeeConnectionMutex.acquire()
+            zigbeeConnection.send('tx_explicit',
+                            frame_id='\x08',
+                            # frame_id=chr(seqNumber),
+                            dest_addr_long=parsedData['source_addr_long'],
+                            dest_addr=parsedData['source_addr'],
+                            src_endpoint='\x00',
+                            dest_endpoint='\x00',
+                            cluster='\x00\x13',
+                            profile='\x00\x00',
+                            data=parsedData['rf_data']
+                            )
+           print ''
+           print '[ 0x0013 ] device announcement - answered'
+           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+           deviceAnnouncementSingleton = False
+            zigbeeConnectionMutex.release()
+
+
         # if this is a response to a zdo bind_req message
         elif(parsedData['cluster'] == '\x80\x21'):
 
             # get the status and sequence number from the message
             seqNumber = parsedData['rf_data'][0]
             statusCode = parsedData['rf_data'][1]
+            print ">response to a zdo bind_req message parsedData>"
 
             # get the bind tuple information
             # for this specific bind request
@@ -915,6 +1346,7 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
 
         # if this is a response to a short address query
         elif(parsedData['cluster'] == '\x80\x00'):
+            print ">response to a short address query 0x8000"
             
             # get a status code
             statusCode = parsedData['rf_data'][0]
@@ -939,6 +1371,27 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
             zigbeeLongShortAddr[longAddr] = shortAddr
             zigbeeLongShortAddrMutex.release()
 
+       #made by changwoo
+        elif(parsedData['cluster'] == '\x80\x06'):
+           print ''
+           print '[ 0x8006 ] get Match Descriptor Response'
+           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+       #made by changwoo
+        elif(parsedData['cluster'] == '\x80\x36'):
+           print ''
+           print '[ 0x8036 ] get Management Permit Joining Response'
+           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+           ManagementPermitJoiningReqSuccess = True
+
+       #made by changwoo
+        else :
+           print ''
+           print '[ '+zigbeeHexStringToHexString(parsedData['cluster'])+' ] ...'
+           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+
     # if this is a home automation zcl message/response
     elif (parsedData['profile'] == '\x01\x04'):
 
@@ -946,9 +1399,45 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
         zclFrameControl = parsedData['rf_data'][0]
         zclSeqNumber = parsedData['rf_data'][1]
         zclCommand = parsedData['rf_data'][2]
+       zclStatus = parsedData['rf_data'][3]
+
+       #made by changwoo
+        if(zclCommand == '\x00'):
+           print ''
+           print '> ('+zigbeeHexStringToHexString(zclStatus)+') notification! : '+ zigbeeHexStringToHexString( parsedData['rf_data'] )
+           
+           # find who to send response 
+           tup = None
+            zigbeeSeqNumberToClientMutex.acquire()
+
+           if(longAddr in seqNumberForNotification):
+               key = longAddr
+                if(zigbeeSeqNumberToClient.has_key(seqNumberForNotification[key])):
+                    tup = zigbeeSeqNumberToClient[seqNumberForNotification[key]]
+                    #del zigbeeSeqNumberToClient[seqNumberForNotification] # don't delete.
+            zigbeeSeqNumberToClientMutex.release()
+
+            # no one to send the response to so just move on
+            if(tup == None):
+                # cant really do anything here
+                return
+            # create the response message
+            packetId = tup[2]
+            message = "type : zcl_zone_status_change_notification\n"
+            message += "packet_id: " + packetId + "\n"
+            message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
+            message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
+            message += "status: " + zigbeeHexStringToHexString(zclStatus) + "\n"
+            message += "attributes: success"
+            message += "\n"
+            # send the socket
+            sendSoceket.sendto(message,tup[0])
+           print(">port : ", tup[0][1])
+
+
 
         # this is a zcl read attribute response
-        if(zclCommand == '\x01'):
+        elif(zclCommand == '\x01'):
 
             # get the zcl payload
             zclPayload = parsedData['rf_data'][3:]
@@ -1037,10 +1526,55 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
 
             message = message[0:len(message) - 1]
             message += "\n"
-
             # send the socket
             sendSoceket.sendto(message,tup[0])
 
+
+
+
+       # made by changwoo
+        # this is a zcl write attribute response
+       elif(zclCommand == '\x04'):
+
+            # get the zcl payload
+            zclPayload = parsedData['rf_data'][3]
+           # the response is '70' which means already resister the mac address or 'success', then let JAVA knows it
+           if(zclStatus == '\x70' or zclPayload == '\x00'):
+
+                # find who to send response to 
+                tup = None
+                zigbeeSeqNumberToClientMutex.acquire()
+                if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))):
+                    tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)]
+                   seqNumberForNotification[longAddr] = ord(zclSeqNumber)
+                    #del zigbeeSeqNumberToClient[ord(zclSeqNumber)]
+                zigbeeSeqNumberToClientMutex.release()
+                # no one to send the response to so just move on
+                if(tup == None):
+                    # cant really do anything here
+                    return
+            
+                # create the response message
+                packetId = tup[2]
+                message = "type : zcl_write_attributes_response\n"
+                message += "packet_id: " + packetId + "\n"
+                message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
+                message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
+                message += "attributes: success"
+                message += "\n"
+                # send the socket
+                sendSoceket.sendto(message,tup[0])
+               print ''
+               print '[ 0x0500 ] get Write Attribute Response success'
+               print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+           else:
+               print ''
+               print '[ 0x0500 ] get Write Attribute Response'
+               print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+
+
         # this is a zcl configure attribute response
         elif(zclCommand == '\x07'):
 
@@ -1114,7 +1648,7 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
 
         # this is a zcl report attribute message
         elif(zclCommand == '\x0a'):
-
+           print "get Report attribute "
             # get teh zcl payload
             zclPayload = parsedData['rf_data'][3:]
             attibuteResponseList = []
@@ -1177,7 +1711,8 @@ def processZigbeeRxExplicitCommandMessage(parsedData):
 
             message = message[0:len(message) - 1]
             message += "\n"
-
+           print "Sending", message
+           
             # send to all client that want this callback
             for ra in retAddr:
                 sendSoceket.sendto(message,ra)
@@ -1190,22 +1725,24 @@ def handleNewZigbeeMessage(parsedData):
 
         parsedData -- Pre-parsed (into a dict) data from message.
     '''
-    print "=================================================================="
+    #print "=================================================================="
+    #print ''
     print "New Zigbee Message"
-    # printMessageData(parsedData)
+    #printMessageData(parsedData)
 
     # dispatch to the correct zigbee handler
     if (parsedData['id'] == 'at_response'):
+        print "parsedDataID : at_response"
         processZigbeeATCommandMessage(parsedData)
 
     elif (parsedData['id'] == 'rx_explicit'):
-        #printMessageData(parsedData)
+        print "parsedDataID : rx_explicit"
         processZigbeeRxExplicitCommandMessage(parsedData)
 
     else:
         print "Unknown API format"
 
-    print "=================================================================="
+    #print "=================================================================="
 
 def handleNewUdpPacket(data, addr):
     ''' Method to parse and handle an incoming UDP packet.
@@ -1213,10 +1750,12 @@ def handleNewUdpPacket(data, addr):
         data -- Data that was in the UDP packet.
         addr -- Address (IP and Port) of the UDP packet origin.
     '''
+    global ManagementPermitJoiningReqSuccess
 
-    print "=================================================================="
-    print "Got New UDP packet..."
-    # print data
+    #print "=================================================================="
+    #print ''
+    #print "Got New UDP packet..."
+    #print data
 
 
     # data comes in as 'key: value\n key: value...' string and so needs to be
@@ -1236,26 +1775,40 @@ def handleNewUdpPacket(data, addr):
             # from improper packing on the sender side
             parsedData[fields[0].strip()] = fields[1].strip()
 
+
     # wrap in try statement just in case there is an improperly formated packet we
     # can deal with it
     try:
         # dispatch to the correct process method
         if(parsedData["type"] == "zdo_bind_request"):
+            print "> processUdpZdoBindReqMessage call"
             processUdpZdoBindReqMessage(parsedData, addr)
         elif(parsedData["type"] == "zdo_unbind_request"):
             processUdpZdoUnBindReqMessage(parsedData, addr)
         elif(parsedData["type"] == "send_address"):
+            print "> processUdpSendAddressMessage call"
             processUdpSendAddressMessage(parsedData, addr)
         elif(parsedData["type"] == "zcl_read_attributes"):
             processUdpZclReadAttributesMessage(parsedData, addr)
         elif(parsedData["type"] == "zcl_configure_reporting"):
+            print "> zcl_configure_reporting call"
             processUdpZclConfigureReportingMessage(parsedData, addr)
         elif(parsedData["type"] == "policy_set"):
             processUdpPolicySet(parsedData, addr)
         elif(parsedData["type"] == "policy_clear"):
             processUdpPolicyClear(parsedData, addr)
+       elif(parsedData["type"] == "management_permit_joining_request"): #made by changwoo
+           processUdpManagementPermitJoiningReqMessage(parsedData, addr)
+       elif(parsedData["type"] == "zcl_write_attributes" and ManagementPermitJoiningReqSuccess): #made by changwoo
+            processUdpZclWriteAttributesMessage(parsedData, addr)
+       elif(parsedData["type"] == "zcl_enrollment_response"): #made by changwoo
+           processUdpEnrollmentResponse(parsedData, addr)
+       elif(parsedData["type"] == "zdo_broadcast_route_record_request"): #made by changwoo
+           processUdpBroadcastingRouteRecordReqMessage(parsedData, addr)
+       elif(parsedData["type"] == "zcl_change_switch_request"): #made by changwoo
+           processUdpZclChangeSwitchReqMessage(parsedData, addr)
         else:
-            #print "unknown Packet: " + parsedData["type"]
+            print "unknown Packet: " + parsedData["type"]
             pass
     except:
         # if we ever get here then something went wrong and so just ignore this
@@ -1263,7 +1816,7 @@ def handleNewUdpPacket(data, addr):
         print "I didn't expect this error:", sys.exc_info()[0]
         traceback.print_exc()
 
-    print "=================================================================="
+    #print "=================================================================="
 
 
 # -----------------------------------------------------------------------------
@@ -1297,7 +1850,8 @@ def main():
 
     # setup incoming UDP socket and bind it to self and specified UDP port
     # sending socket does not need to be bound to anything
-    receiveSoceket.bind(('127.0.0.1', UDP_RECEIVE_PORT))
+    #receiveSoceket.bind(('192.168.2.227', UDP_RECEIVE_PORT))
+    receiveSoceket.bind(('192.168.2.192', UDP_RECEIVE_PORT))
 
     # create the thread that does short address lookups
     addressUpdateWorkerThread = threading.Thread(target=addressUpdateWorkerMethod)
@@ -1307,7 +1861,8 @@ def main():
         # Main running loop
         while(True):
             print "=================================================================="
-            print "Waiting..."
+            print ''
+           print "Waiting..."
             print "=================================================================="
 
             # wait for an incoming UDP packet
diff --git a/benchmarks/other/XbeePythonDriver/xbee_driver_smartthings.py b/benchmarks/other/XbeePythonDriver/xbee_driver_smartthings.py
deleted file mode 100644 (file)
index ea13855..0000000
+++ /dev/null
@@ -1,1889 +0,0 @@
-from xbee import ZigBee
-import serial
-import time
-import collections
-import sys
-import getopt
-from socket import *
-import traceback
-from threading import Thread, Lock
-import random
-import threading
-
-
-# -----------------------------------------------------------------------------
-# Constants ans Pseudo-Constants
-# -----------------------------------------------------------------------------
-UDP_RECEIVE_PORT = 5005        # port used for incoming UDP data
-UDP_RECEIVE_BUFFER_SIZE = 4096  # max buffer size of an incoming UDP packet
-SYSTEM_MASTER_ADDRESS = ("127.0.0.1", 12345) # ip address and portof the system master node
-#SYSTEM_MASTER_ADDRESS = ("127.0.0.1", 22222) # ip address and portof the system master node
-#SYSTEM_MASTER_ADDRESS2 = ("127.0.0.1", 11111)
-#SYSTEM_MASTER_ADDRESS3 = ("127.0.0.1", 11222)
-
-# time for messages to wait for a response before the system clears away that 
-# sequence identifier
-ZIGBEE_SEQUENCE_NUMBER_CLEAR_TIME_SEC = 5 
-
-#ZIGBEE_SERIAL_PORT = "/dev/cu.usbserial-DN01DCRH"  # USB-Serial port of local radio
-ZIGBEE_SERIAL_PORT = "/dev/ttyUSB0"
-ZIGBEE_SERIAL_BAUD = 115200                       # Baud rate for above port
-
-# address of our local zigbee radio
-ZIGBEE_DEVICE_ADDRESS = "0013a20040d99cb4"
-
-# -----------------------------------------------------------------------------
-# Global Variables and Objects
-# -----------------------------------------------------------------------------
-
-# signals to see if a request needs to be made
-didGetLocalRadioHighAddress = False;
-didGetLocalRadioLowAddress = False;
-
-# zigbee communications object and its mutex
-zigbeeConnection = None
-zigbeeConnectionMutex = Lock()
-
-#singleton mabe by changwoo
-matchDescriptorReqSingleton = True
-deviceAnnouncementSingleton = True
-ManagementPermitJoiningReqSuccess = False
-
-# zigbee mapping from long to short object dict
-zigbeeLongShortAddr = dict()
-zigbeeLongShortAddrMutex = Lock()
-
-# zigbee mapping from a sequence number to a client 
-# for correct response handling
-zigbeeSeqNumberToClient = dict()
-zigbeeSeqNumberToClientMutex = Lock()
-
-zigeeBindRequest = dict()
-zigeeBindRequestMutex = Lock()
-
-# Keeps record of where to send callbacks to when an HA message is received
-zibeeHACallback = dict()
-zibeeHACallbackMutex = Lock()
-
-
-# Keeps a record of device addresses whose short addresses have not been 
-# determined yet
-zigbeeUnregisteredAddresses = []
-zigbeeUnregisteredAddressesMutex = Lock()
-
-# used to signal all threads to end
-doEndFlag = False
-
-
-# 2 sockets, one for sending (not bound to a port manually)
-# and one for receiving, known port binding by application
-# both UDP sockets
-sendSoceket = socket(AF_INET, SOCK_DGRAM)
-receiveSoceket = socket(AF_INET, SOCK_DGRAM)
-
-
-# zigbee address authority list
-zigbeeAddressAuthorityDict = dict()
-
-# made by changwoo
-seqNumberForNotification = dict()
-
-# -----------------------------------------------------------------------------
-# Helper Methods
-# -----------------------------------------------------------------------------
-def reverseShortAddress(shortAddr):
-    result = shortAddr[len(shortAddr)/2:]+shortAddr[0:len(shortAddr)/2]
-    return result
-
-def parseCommandLineArgs(argv):
-    global ZIGBEE_SERIAL_PORT
-    global ZIGBEE_SERIAL_BAUD
-    try:
-        opts, args = getopt.getopt(
-            argv, "hp:b:u:", ["port=", "baud=", "udpport="])
-
-    except getopt.GetoptError:
-        print 'test.py -p <serial_port> -b <baud_rate> -u <udp_port>'
-        sys.exit(2)
-
-    for opt, arg in opts:
-        if opt == '-h':
-            print 'test.py -p <serial_port> -b <baud_rate> -u <udp_port>'
-            sys.exit()
-
-        elif opt in ("-p", "--port"):
-            ZIGBEE_SERIAL_PORT = arg
-
-        elif opt in ("-b", "--baud"):
-            try:
-                ZIGBEE_SERIAL_BAUD = int(arg)
-            except ValueError:
-                print "Buad rate must be an integer"
-                sys.exit()
-
-
-# -------------
-# Convenience (Stateless)
-# -------------
-
-def hexListToChar(hexList):
-    ''' Method to convert a list/string of characters into their corresponding values
-
-        hexList -- list or string of hex characters
-    '''
-    retString = ""
-    for h in hexList:
-        retString += chr(int(h, 16))
-    return retString
-
-def splitByN(seq, n):
-    ''' Method to split a string into groups of n characters
-
-        seq -- string
-        n -- group by number
-    '''
-    return [seq[i:i+n] for i in range(0, len(seq), n)]
-
-def changeEndian(hexString):
-    ''' Method to change endian of a hex string
-
-        hexList -- string of hex characters
-    '''
-    split = splitByN(hexString, 2) # get each byte
-    split.reverse();               # reverse ordering of the bytes
-
-    # reconstruct 
-    retString = ''
-    for s in split:
-        retString += s
-    return retString
-
-def printMessageData(data):
-    ''' Method to print a zigbee message to the console
-
-        data -- pre-parsed zigbee message
-    '''
-    for d in data:
-        print d, ' : ',
-        for e in data[d]:
-            print "{0:02x}".format(ord(e)),
-        if (d == 'id'):
-            print "({})".format(data[d]),
-        print
-
-def hexStringToZigbeeHexString(hexString):
-    ''' Method to change a hex string to a string of characters with the hex values
-
-        hexList -- string of hex characters
-    '''
-    return hexListToChar(splitByN(hexString, 2))
-
-def zigbeeHexStringToHexString(zigbeeHexString):
-    ''' Method to change string of characters with the hex values to a hex string
-
-        hexList -- string of characters with hex values
-    '''
-
-    retString = ''
-    for e in zigbeeHexString:
-        retString += "{0:02x}".format(ord(e))
-    return retString
-
-def zclDataTypeToBytes(zclPayload):
-    ''' Method to determine data length of a zcl attribute
-
-        zclPayload -- ZCL payload data, must have dataType as first byte
-    '''
-    attrType = ord(zclPayload[0])
-
-    if(attrType == 0x00):
-        return 0
-    elif (attrType == 0x08):
-        return 1
-    elif (attrType == 0x09):
-        return 2
-    elif (attrType == 0x0a):
-        return 3
-    elif (attrType == 0x0b):
-        return 4
-    elif (attrType == 0x0c):
-        return 5
-    elif (attrType == 0x0d):
-        return 6
-    elif (attrType == 0x0e):
-        return 7
-    elif (attrType == 0x0f):
-        return 8
-    elif (attrType == 0x10):
-        return 1
-    elif (attrType == 0x18):
-        return 1
-    elif (attrType == 0x19):
-        return 2
-    elif (attrType == 0x1a):
-        return 3
-    elif (attrType == 0x1b):
-        return 4
-    elif (attrType == 0x1c):
-        return 5
-    elif (attrType == 0x1d):
-        return 6
-    elif (attrType == 0x1e):
-        return 7
-    elif (attrType == 0x1f):
-        return 8
-    elif (attrType == 0x20):
-        return 1
-    elif (attrType == 0x21):
-        return 2
-    elif (attrType == 0x22):
-        return 3
-    elif (attrType == 0x23):
-        return 4
-    elif (attrType == 0x24):
-        return 5
-    elif (attrType == 0x25):
-        return 6
-    elif (attrType == 0x26):
-        return 7
-    elif (attrType == 0x27):
-        return 8
-    elif (attrType == 0x28):
-        return 1
-    elif (attrType == 0x29):
-        return 2
-    elif (attrType == 0x2a):
-        return 3
-    elif (attrType == 0x2b):
-        return 4
-    elif (attrType == 0x2c):
-        return 5
-    elif (attrType == 0x2d):
-        return 6
-    elif (attrType == 0x2e):
-        return 7
-    elif (attrType == 0x2f):
-        return 8
-    elif (attrType == 0x30):
-        return 1
-    elif (attrType == 0x31):
-        return 2
-    elif (attrType == 0x38):
-        return 2
-    elif (attrType == 0x39):
-        return 4
-    elif (attrType == 0x3a):
-        return 8
-    elif (attrType == 0x41):
-        return ord(zclPayload[1])
-    elif (attrType == 0x42):
-        return ord(zclPayload[1])
-    elif (attrType == 0x43):
-        return ord(zclPayload[1]) + (256 * ord(zclPayload[2]))
-    elif (attrType == 0x44):
-        return ord(zclPayload[1]) + (256 * ord(zclPayload[2]))
-    elif (attrType == 0xe0):
-        return 4
-    elif (attrType == 0xe1):
-        return 4
-    elif (attrType == 0xe2):
-        return 4
-    elif (attrType == 0xe8):
-        return 2
-    elif (attrType == 0xe9):
-        return 2
-    elif (attrType == 0xea):
-        return 4
-    elif (attrType == 0xf0):
-        return 8
-    elif (attrType == 0xf1):
-        return 16
-    elif (attrType == 0xff):
-        return 0
-
-# -------------
-# Other
-# -------------
-
-def createSequenceNumberForClient(addr, packetId):
-    ''' Method to get and store a sequence number with a specific client 
-        for a specific message.
-
-        addr -- UDP address of the client to associate with the seq. number
-        packetId -- packet id from the UDP packet
-    '''
-    # keep trying to find a number to return
-    while(True):
-
-        # get the current time
-        epoch_time = int(time.time())
-
-        # get the current list of used numbers
-        zigbeeSeqNumberToClientMutex.acquire()
-        keysList = zigbeeSeqNumberToClient.keys()
-        zigbeeSeqNumberToClientMutex.release()
-    
-        # if all the numbers are already used
-        if(len(keysList) == 256):
-
-            # get a list of all the items
-            zigbeeSeqNumberToClientMutex.acquire()
-            itemsList = zigbeeSeqNumberToClient.items()
-            zigbeeSeqNumberToClientMutex.release()
-
-            # search for a number that is old enough to get rid of otherwise use -1
-            seqNum = -1
-            for item in itemsList:
-                if((epoch_time - item[1][1]) > ZIGBEE_SEQUENCE_NUMBER_CLEAR_TIME_SEC):
-                    seqNumber = item[0]
-                    break
-
-            if(seqNum != -1):
-                # replace the record with new data if we found one to replace
-                zigbeeSeqNumberToClientMutex.acquire()
-                zigbeeSeqNumberToClient[seqNumber] = (addr, epoch_time, packetId)
-                zigbeeSeqNumberToClientMutex.release()
-
-            return seqNumber
-            
-        else:
-            # not all numbers used yet so pick one randomly
-            randNum = random.randrange(0,256)
-
-            # check if we are using the number yet
-            if(randNum not in keysList):
-
-                # we are not so insert to keep track who this number is for and return it
-                zigbeeSeqNumberToClientMutex.acquire()
-                zigbeeSeqNumberToClient[randNum] = (addr, epoch_time, packetId)
-                zigbeeSeqNumberToClientMutex.release()
-                return randNum
-
-def getConnectedRadioLongAddress():
-    """ Method to make sure we get the MAC address of our local radio"""
-    global zigbeeConnection
-    global zigbeeMutex
-
-    # keep looping until we get both the MSBs and the LSBs
-    while ((not didGetLocalRadioHighAddress) or (not didGetLocalRadioLowAddress)):
-
-        # reissue requests
-        zigbeeConnection.send('at', command="SH")
-        zigbeeConnection.send('at', command="SL")
-        
-        # sleep for a bit to give the radio time to respond before we check again
-        time.sleep(2)
-
-def addressUpdateWorkerMethod():
-    ''' Method to keep refreshing the short addresses of the known zigbee devices'''
-    global doEndFlag
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigbeeUnregisteredAddresses
-    global zigbeeUnregisteredAddressesMutex
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-
-    # keep looping until signaled to quit
-    while(not doEndFlag):
-
-        addrList = []
-
-        # add unregistered (short addresses unknown) devices so
-        # that we can look them up
-        zigbeeUnregisteredAddressesMutex.acquire()
-        addrList.extend(zigbeeUnregisteredAddresses)
-        zigbeeUnregisteredAddressesMutex.release()
-
-        # add the devices that we have short addresses for so we can 
-        # get their most recent short addresses
-        zigbeeLongShortAddrMutex.acquire()
-        addrList.extend(zigbeeLongShortAddr.keys())
-        zigbeeLongShortAddrMutex.release()
-
-        # Loop through all the addresses and send messages for each address
-        for ad in addrList:
-
-            # create payload for a query on the network for a short address
-            payload = '\x00'
-            payload += hexStringToZigbeeHexString(changeEndian(ad))
-            payload += '\x00'
-
-            # create and send binding command
-            zigbeeConnectionMutex.acquire()
-           
-            zigbeeConnection.send('tx_explicit',
-                                frame_id='\x01',
-                                dest_addr_long=hexStringToZigbeeHexString(ad),
-                                dest_addr='\xff\xfd',
-                                src_endpoint='\x00',
-                                dest_endpoint='\x00',
-                                cluster='\x00\x00',  
-                                profile='\x00\x00',
-                                data=payload
-                                )
-            zigbeeConnectionMutex.release()
-
-        time.sleep(8)
-
-
-# -------------
-# UDP 
-# -------------
-
-def sendUdpSuccessFail(addr, packetTypeStr, packetIdStr, sucOrFail, reason=None):
-    ''' Method to send a success or fail back to a client.
-
-        addr -- UDP address to send packet to
-        packetTypeStr -- name of this specific packet
-        packetIdStr -- packet id to send
-        sucOrFail -- whether this is a success or fail message (True = success)
-        reason -- reason of failure (if needed, default is None)
-
-    '''
-
-    global sendSoceket
-
-    # construct the message
-    message = "type: " + packetTypeStr.strip() + "\n"
-    message += "packet_id: " + packetIdStr + "\n"
-
-    if(sucOrFail):
-        message += "response: success \n"
-    else:
-        message += "response: fail \n"
-        message += "reason: " + reason + "\n"
-
-    # send message in a UDP packet
-    sendSoceket.sendto(message,addr)
-
-def processUdpZdoBindReqMessage(parsedData, addr):
-
-    shortAddr = None
-
-    if(zigbeeAddressAuthorityDict.has_key(addr)):
-        l = zigbeeAddressAuthorityDict[addr]
-        if(parsedData['device_address_long'] not in l):
-            return
-    else:
-        return
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'zdo_bind_request', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # a bind request was made so must store and wait for response 
-        # before we setup callbacks, so keep just the data we need to create the callback
-        zigeeBindRequestMutex.acquire()
-        zigeeBindRequest[seqNumber] = (parsedData['device_address_long'],
-                                        parsedData['cluster_id'], 
-                                        parsedData['packet_id'], 
-                                        addr)
-        zigeeBindRequestMutex.release()
-
-        # construct the short and long addresses of the message for sending
-        # make sure they are in the correct format
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-
-        # create the payload data
-        payloadData = ""
-        payloadData += chr(seqNumber)
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['device_address_long']))
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['device_endpoint']))
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['cluster_id'])) 
-        payloadData += '\x03' 
-        payloadData += hexStringToZigbeeHexString(changeEndian(ZIGBEE_DEVICE_ADDRESS))
-        payloadData += '\x00'
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x01',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x00',
-                            dest_endpoint='\x00',
-                            cluster='\x00\x21',  
-                            profile='\x00\x00',
-                            data=payloadData
-                            )
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a failure packet since there is no short address available
-        sendUdpSuccessFail(addr, 'zdo_bind_request', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-def processUdpZdoUnBindReqMessage(parsedData, addr):
-    zibeeHACallbackMutex.acquire();
-    if(zibeeHACallback.has_key(parsedData['device_address_long'], parsedData['cluster_id'])):
-        zibeeHACallback(parsedData['device_address_long'], parsedData['cluster_id']).remove(addr)
-    zibeeHACallbackMutex.release()
-    sendUdpSuccessFail(addr, 'zdo_unbind_request', parsedData['packet_id'], True)
-
-
-
-def processUdpSendAddressMessage(parsedData, addr):
-    ''' Method handle a send address command
-
-        parsedData -- Pre-parsed Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigbeeUnregisteredAddresses
-    global zigbeeUnregisteredAddressesMutex
-    global sendSoceket
-
-    print "process send address"
-    
-
-    # construct success message
-    message = "type: send_address_response\n"
-    message += "packet_id: " + parsedData['packet_id'] + "\n"
-    message += "response: success\n"
-
-    # tell client that we got their request
-    sendSoceket.sendto(message,addr)
-    print "responding", message
-    
-    # construct 
-    zigbeeLongShortAddrMutex.acquire()
-    doesHaveKey = zigbeeLongShortAddr.has_key(parsedData['device_address_long'])
-    zigbeeLongShortAddrMutex.release()
-
-    if(doesHaveKey):
-        # long address is already registered with the system so no need to do anything
-        return
-
-    # long address not registered so add it for short address lookup
-    zigbeeUnregisteredAddressesMutex.acquire()
-    zigbeeUnregisteredAddresses.append(parsedData['device_address_long'])
-    zigbeeUnregisteredAddressesMutex.release()
-
-
-
-#made by changwoo
-def processUdpEnrollmentResponse(parsedData, addr):
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'zcl_enrollment_response', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
-
-        # create the payload data
-        payloadData = ""
-        payloadData += '\x01'
-        payloadData += chr(seqNumber)
-        payloadData += '\x00'
-        payloadData += '\x00\x00'
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x40',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x01',
-                            dest_endpoint=dstEndpoint,
-                            cluster=clusterId,  
-                            profile=profileId,
-                            data=payloadData
-                            )
-       print '> EnrollmentResponse is sent'
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'zcl_enrollment_response', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-
-
-
-#made by changwoo
-def processUdpZclWriteAttributesMessage(parsedData, addr):
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'zcl_write_attributes', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-
-        # create the payload data
-        payloadData = ""
-        payloadData += '\x00'
-        payloadData += chr(seqNumber)
-        payloadData += '\x02'
-        payloadData += '\x10\x00'
-        payloadData += '\xF0'
-#        payloadData += '\xDA\x9A\xD9\x40\x00\xA2\x13\x00'
-        payloadData += hexStringToZigbeeHexString(changeEndian(ZIGBEE_DEVICE_ADDRESS))
-
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x08',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x01',
-                            dest_endpoint=dstEndpoint,
-                            cluster=clusterId,
-                            profile=profileId,
-                            data=payloadData
-                            )
-
-       print ''
-       print '> WriteAttributesReq is sent : '+str(shortAddr)
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'zcl_write_attributes', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-#made by changwoo
-def processUdpZclChangeSwitchReqMessage(parsedData, addr):
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'change_switch_request', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-       clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-       profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
-       value = hexStringToZigbeeHexString(parsedData['value'])
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x40',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x01',
-                            dest_endpoint=dstEndpoint,
-                            cluster=clusterId,  
-                            profile=profileId,
-                            data='\x01'+chr(seqNumber)+value
-                            )
-        time.sleep(1)
-       if parsedData['value']==1:
-               print '> The outlet sensor turned on'
-       else :
-               print '> The outlet sensor turned off'
-
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-
-
-# made by changwoo
-def processUdpBroadcastingRouteRecordReqMessage(parsedData, addr):
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'broadcast_route_record_request', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x01',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long='\x00\x00\x00\x00\x00\x00\xff\xff',
-                            dest_addr='\xff\xfe',
-                            src_endpoint='\x00',
-                            dest_endpoint=dstEndpoint,
-                            cluster='\x00\x32',  
-                            profile='\x00\x00',
-                            data='\x12'+'\x01'
-                            )
-        time.sleep(1)
-       print '> BroadcastingRouteRecordReq is sent'
-
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-
-#made by changwoo
-def processUdpManagementPermitJoiningReqMessage(parsedData, addr):
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    global matchDescriptorReqSingleton
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'management_permit_joining_request', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-
-        # create the payload data
-        payloadData = ""
-        payloadData += chr(seqNumber)
-        payloadData += '\x5a'
-        payloadData += '\x00'
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x01',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x00',
-                            dest_endpoint='\x00',
-                            cluster=clusterId,  
-                            profile='\x00\x00',
-                            data=payloadData
-                            )
-       print '> ManagementPermitJoiningReq is sent'
-
-       #stop answering 0x6
-       matchDescriptorReqSingleton= False
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'management_permit_joining_request', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-
-def processUdpZclReadAttributesMessage(parsedData, addr):
-    ''' Method handle a ZCL read attribute command
-
-        parsedData -- Pre-parsed Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-
-
-
-    if(zigbeeAddressAuthorityDict.has_key(addr)):
-        l = zigbeeAddressAuthorityDict[addr]
-        if(parsedData['device_address_long'] not in l):
-            return
-    else:
-        return
-
-
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-
-            # send an error message, could not get a sequence number to use at this time
-            sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        # get the info for sending
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
-        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-
-        # get all the attributes
-        attributeIds = parsedData['attribute_ids'].split(',')
-
-        # create the payload data
-        payloadData = ""
-        payloadData += '\x00'
-        payloadData += chr(seqNumber)
-        payloadData += '\x00'
-
-        # make all the attributes payloads
-        for attr in attributeIds:
-            attr = attr.strip()
-            attr = changeEndian(attr)
-            payloadData += hexStringToZigbeeHexString(attr)
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x01',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x00',
-                            dest_endpoint=dstEndpoint,
-                            cluster=clusterId,  
-                            profile=profileId,
-                            data=payloadData
-                            )
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        # send a fail response
-        sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-def processUdpZclConfigureReportingMessage(parsedData, addr):
-    ''' Method handle a zcl configure reporting message
-
-        parsedData -- Pre-parsed Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-
-    global zigbeeLongShortAddr
-    global zigbeeLongShortAddrMutex
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-
-    if(zigbeeAddressAuthorityDict.has_key(addr)):
-        l = zigbeeAddressAuthorityDict[addr]
-        if(parsedData['device_address_long'] not in l):
-            return
-    else:
-        return
-
-
-    shortAddr = None
-
-    # get the short address for this device long address if possible
-    zigbeeLongShortAddrMutex.acquire()
-    if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])):
-        shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']]
-    zigbeeLongShortAddrMutex.release()
-
-    # if there is a short address than we can send the message
-    # if there is not one then we cannot since we need both the short and
-    # the long address
-    if(shortAddr != None):
-
-        # get a request number
-        seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id'])
-        
-        # send back failure
-        if(seqNumber == -1):
-            sendUdpSuccessFail(addr, 'zcl_configure_reporting', parsedData['packet_id'], False, 'out_of_space')
-            return
-
-        destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long'])
-        destShortAddr = hexStringToZigbeeHexString(shortAddr)
-        profileId = hexStringToZigbeeHexString(parsedData['profile_id'])
-        clusterId = hexStringToZigbeeHexString(parsedData['cluster_id'])
-        dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint'])
-
-        # create the payload data
-        payloadData = ""
-        payloadData += '\x00'
-        payloadData += chr(seqNumber)
-        payloadData += '\x06'
-        payloadData += '\x00'
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['attribute_id']))
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['data_type']))
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['min_reporting_interval']))
-        payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['max_reporting_interval']))
-
-        if(parsedData.has_key('reportable_change')):
-            payloadData += hexStringToZigbeeHexString(changeEndian(parsedData['reportable_change']))
-
-
-        # create and send binding command
-        zigbeeConnectionMutex.acquire()
-        zigbeeConnection.send('tx_explicit',
-                            frame_id='\x01',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=destLongAddr,
-                            dest_addr=destShortAddr,
-                            src_endpoint='\x00',
-                            dest_endpoint=dstEndpoint,
-                            cluster=clusterId,  
-                            profile=profileId,
-                            data=payloadData
-                            )
-        zigbeeConnectionMutex.release()
-
-
-    else:
-        sendUdpSuccessFail(addr, 'zcl_configure_reporting', parsedData['packet_id'], False, 'short_address_unknown')
-        pass
-
-def processUdpPolicySet(parsedData, addr):
-    ''' Method handle a policy set message
-
-        parsedData -- Pre-parsed Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-    print "=================================================================="
-    print "Policy set: ", parsedData
-    print 'addr : ', addr
-
-
-    # do nothing if wrong source
-    if addr == SYSTEM_MASTER_ADDRESS : #or addr == SYSTEM_MASTER_ADDRESS2 or addr == SYSTEM_MASTER_ADDRESS3 :
-        key = (parsedData['ip_address'], int(parsedData['port']))
-        if (zigbeeAddressAuthorityDict.has_key(key)):
-            zigbeeAddressAuthorityDict[key].append(parsedData['device_address_long'])
-        else:
-            zigbeeAddressAuthorityDict[key] = [parsedData['device_address_long']]
-
-
-def processUdpPolicyClear(parsedData, addr):
-    ''' Method handle a policy set message
-
-        parsedData -- Pre-parsed Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-    print "=================================================================="
-    print "Clear policy: ", parsedData
-    
-    # do nothing if wrong source
-    if addr == SYSTEM_MASTER_ADDRESS : #or addr == SYSTEM_MASTER_ADDRESS2 or addr == SYSTEM_MASTER_ADDRESS3:
-        zigbeeAddressAuthorityDict.clear()
-
-
-# -------------
-# Zigbee 
-# -------------
-
-def processZigbeeATCommandMessage(parsedData):
-    ''' Method to process an AT zigbee message
-
-        parsedData -- Pre-parsed (into a dict) data from message.
-    '''
-    global ZIGBEE_DEVICE_ADDRESS
-    global didGetLocalRadioHighAddress
-    global didGetLocalRadioLowAddress
-
-    # command response for the high bytes of the local device long address
-    if(parsedData['command'] == 'SH'):
-        # convert the parameter to a string value (human readable)
-        value = ""
-        for e in parsedData['parameter']:
-            value += "{0:02x}".format(ord(e))
-
-        # set the correct portion of the address
-        ZIGBEE_DEVICE_ADDRESS = value + ZIGBEE_DEVICE_ADDRESS[8:]
-        
-        #signal that we got this part of the address
-        didGetLocalRadioHighAddress = True
-
-    # command response for the low bytes of the local device long address
-    elif(parsedData['command'] == 'SL'):
-        # convert the parameter to a string value (human readable)
-        value = ""
-        for e in parsedData['parameter']:
-            value += "{0:02x}".format(ord(e))
-
-        # set the correct portion of the address
-        ZIGBEE_DEVICE_ADDRESS = ZIGBEE_DEVICE_ADDRESS[0:8] + value
-
-        #signal that we got this part of the address
-        didGetLocalRadioLowAddress = True
-
-def processZigbeeRxExplicitCommandMessage(parsedData):
-    ''' Method to process a rx-explicit zigbee message
-
-        parsedData -- Pre-parsed (into a dict) data from message.
-    '''
-    global zigeeBindRequestMutex
-    global zigeeBindRequest
-    global zigbeeConnectionMutex
-    global zigbeeConnection
-    global ManagementPermitJoiningReqSuccess
-
-    # get the long and short addresses from the message payload since we can 
-    # use these to update the short addresses since this short address is fresh
-    longAddr = zigbeeHexStringToHexString(parsedData['source_addr_long'])
-    shortAddr = zigbeeHexStringToHexString(parsedData['source_addr'])
-
-    # check if this short address is for a device that has yet to be 
-    # registered
-    zigbeeUnregisteredAddressesMutex.acquire()
-    if(longAddr in zigbeeUnregisteredAddresses):
-        zigbeeUnregisteredAddresses.remove(longAddr)
-    zigbeeUnregisteredAddressesMutex.release()
-
-    # update/ or insert the short address
-    zigbeeLongShortAddrMutex.acquire()
-    zigbeeLongShortAddr[longAddr] = shortAddr
-    zigbeeLongShortAddrMutex.release()
-
-    global matchDescriptorReqSingleton
-    global deviceAnnouncementSingleton
-    global seqNumberForNotification
-
-    # if this is a ZDO message/response
-    if(parsedData['profile'] == '\x00\x00'):
-
-       # mabe by changwoo
-        # if this is a Match Descriptor Request so we need to answer.
-        if(parsedData['cluster'] == '\x00\x06' and matchDescriptorReqSingleton):
-            zigbeeConnectionMutex.acquire()
-            zigbeeConnection.send('tx_explicit',
-                            frame_id='\x08',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=parsedData['source_addr_long'],
-                            dest_addr=parsedData['source_addr'],
-                            src_endpoint='\x00',
-                            dest_endpoint='\x00',
-                            cluster='\x00\x06',
-                            profile='\x00\x00',
-                            data=parsedData['rf_data']
-                            )
-            time.sleep(1)
-            zigbeeConnection.send('tx_explicit',
-                            frame_id='\x40',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=parsedData['source_addr_long'],
-                            dest_addr=parsedData['source_addr'],
-                            src_endpoint='\x00',
-                            dest_endpoint='\x00',
-                            cluster='\x80\x06',
-                            profile='\x00\x00',
-                            data=parsedData['rf_data'][0]+ '\x00\x00\x00' + '\x01\x01'
-                            )
-            time.sleep(1)
-            print ''
-            print '[ 0x0006 ] Match Descriptor Request - answered'
-            print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-            zigbeeConnectionMutex.release()
-
-
-        # if this is a device announcement so we can get some useful data from it
-        elif(parsedData['cluster'] == '\x00\x13' and deviceAnnouncementSingleton):
-            
-            # pick out the correct parts of the payload
-            longAddr = zigbeeHexStringToHexString(parsedData['rf_data'][3:11])
-            shortAddr = zigbeeHexStringToHexString(parsedData['rf_data'][1:3])
-
-            # change the endian of the address
-            longAddr = changeEndian(longAddr)
-            shortAddr = changeEndian(shortAddr)
-
-            # update the table with the new information
-            zigbeeLongShortAddrMutex.acquire()
-            zigbeeLongShortAddr[longAddr] = shortAddr
-            zigbeeLongShortAddrMutex.release()
-
-            # check if this short address is for a device that has yet to be 
-            # registered
-            zigbeeUnregisteredAddressesMutex.acquire()
-            if(longAddr in zigbeeUnregisteredAddresses):
-                zigbeeUnregisteredAddresses.remove(longAddr)
-            zigbeeUnregisteredAddressesMutex.release()
-
-
-           # made by changwoo
-            zigbeeConnectionMutex.acquire()
-            zigbeeConnection.send('tx_explicit',
-                            frame_id='\x08',
-                            # frame_id=chr(seqNumber),
-                            dest_addr_long=parsedData['source_addr_long'],
-                            dest_addr=parsedData['source_addr'],
-                            src_endpoint='\x00',
-                            dest_endpoint='\x00',
-                            cluster='\x00\x13',
-                            profile='\x00\x00',
-                            data=parsedData['rf_data']
-                            )
-           print ''
-           print '[ 0x0013 ] device announcement - answered'
-           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-           deviceAnnouncementSingleton = False
-            zigbeeConnectionMutex.release()
-
-
-        # if this is a response to a zdo bind_req message
-        elif(parsedData['cluster'] == '\x80\x21'):
-
-            # get the status and sequence number from the message
-            seqNumber = parsedData['rf_data'][0]
-            statusCode = parsedData['rf_data'][1]
-
-            # get the bind tuple information
-            # for this specific bind request
-            tup = None
-            zigeeBindRequestMutex.acquire() 
-            if(zigeeBindRequest.has_key(ord(seqNumber))):
-                tup = zigeeBindRequest[ord(seqNumber)]
-            zigeeBindRequestMutex.release()
-
-            if(tup == None):
-                # cant really do anything in this case...
-                # don't have any information on who the data is for
-                return
-
-            # successful binding
-            if(ord(statusCode) == 0):
-
-                # add a callback for this specific device and cluster 
-                # to the HA callback dict 
-                zibeeHACallbackMutex.acquire();
-                if(zibeeHACallback.has_key((tup[0], tup[1]))):
-                    if(tup[3] not in zibeeHACallback[(tup[0], tup[1])]):
-                        zibeeHACallback[(tup[0], tup[1])].append(tup[3])
-                else:
-                    zibeeHACallback[(tup[0], tup[1])] = [tup[3]]
-                zibeeHACallbackMutex.release()
-
-                # send success message
-                sendUdpSuccessFail(tup[3], 'zdo_bind_request', tup[2], True)
-
-            # Not Supported
-            elif (ord(statusCode) == 170):
-                sendUdpSuccessFail(tup[3], 'zdo_bind_request', tup[2], False, 'not_supported')
-
-            # Table Full
-            elif (ord(statusCode) == 174):
-                sendUdpSuccessFail(tup[3], 'zdo_bind_request', tup[2], False, 'table_full')
-
-            # Other issue, dont have code for
-            else:
-                sendUdpSuccessFail(tup[3], 'zdo_bind_request', tup[2], False, 'other')
-
-        # if this is a response to a short address query
-        elif(parsedData['cluster'] == '\x80\x00'):
-            
-            # get a status code
-            statusCode = parsedData['rf_data'][0]
-
-            # does not matter if this is not a success, we can try again later
-            if(statusCode != '\x00'):
-                # status code was not success so do not do anything
-                return
-
-            # get the short and long address information
-            longAddr = changeEndian(zigbeeHexStringToHexString(parsedData['rf_data'][2:10]))
-            shortAddr = changeEndian(zigbeeHexStringToHexString( parsedData['rf_data'][10:12]))
-
-            # remove device from list of unregistered devices if it is in it
-            zigbeeUnregisteredAddressesMutex.acquire()
-            if(longAddr in zigbeeUnregisteredAddresses):
-                zigbeeUnregisteredAddresses.remove(longAddr)
-            zigbeeUnregisteredAddressesMutex.release()
-
-            # update/insert the short address
-            zigbeeLongShortAddrMutex.acquire()
-            zigbeeLongShortAddr[longAddr] = shortAddr
-            zigbeeLongShortAddrMutex.release()
-
-       #made by changwoo
-        elif(parsedData['cluster'] == '\x80\x06'):
-           print ''
-           print '[ 0x8006 ] get Match Descriptor Response'
-           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-
-       #made by changwoo
-        elif(parsedData['cluster'] == '\x80\x36'):
-           print ''
-           print '[ 0x8036 ] get Management Permit Joining Response'
-           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-
-           ManagementPermitJoiningReqSuccess = True
-
-       #made by changwoo
-        else :
-           print ''
-           print '[ '+zigbeeHexStringToHexString(parsedData['cluster'])+' ] ...'
-           print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-
-
-    # if this is a home automation zcl message/response
-    elif (parsedData['profile'] == '\x01\x04'):
-
-        # get the zcl message header
-        zclFrameControl = parsedData['rf_data'][0]
-        zclSeqNumber = parsedData['rf_data'][1]
-        zclCommand = parsedData['rf_data'][2]
-       zclStatus = parsedData['rf_data'][3]
-
-       #made by changwoo
-        if(zclCommand == '\x00'):
-           print ''
-           print '> ('+zigbeeHexStringToHexString(zclStatus)+') notification! : '+ zigbeeHexStringToHexString( parsedData['rf_data'] )
-           
-           # find who to send response 
-           tup = None
-            zigbeeSeqNumberToClientMutex.acquire()
-
-           if(longAddr in seqNumberForNotification):
-               key = longAddr
-                if(zigbeeSeqNumberToClient.has_key(seqNumberForNotification[key])):
-                    tup = zigbeeSeqNumberToClient[seqNumberForNotification[key]]
-                    #del zigbeeSeqNumberToClient[seqNumberForNotification] # don't delete.
-            zigbeeSeqNumberToClientMutex.release()
-
-            # no one to send the response to so just move on
-            if(tup == None):
-                # cant really do anything here
-                return
-            # create the response message
-            packetId = tup[2]
-            message = "type : zcl_zone_status_change_notification\n"
-            message += "packet_id: " + packetId + "\n"
-            message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
-            message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
-            message += "status: " + zigbeeHexStringToHexString(zclStatus) + "\n"
-            message += "attributes: success"
-            message += "\n"
-            # send the socket
-            sendSoceket.sendto(message,tup[0])
-           print(">port : ", tup[0][1])
-
-
-
-        # this is a zcl read attribute response
-        elif(zclCommand == '\x01'):
-
-            # get the zcl payload
-            zclPayload = parsedData['rf_data'][3:]
-            attibuteResponseList = []
-
-            # get the data for each data
-            while(len(zclPayload) > 0):
-                attributeId = zclPayload[0:2]
-                attributeStatus = zclPayload[2]
-                zclPayload = zclPayload[3:]
-                
-                if(ord(attributeStatus) != 0):
-                    # if attribute is not supported then it has no data
-                    # package the data and add it to the list
-                    attibuteResponseList.append((attributeId,"not_supported"))
-                else:
-
-                    # get the data type and data length of the attributre
-                    attributeType = zclPayload[0]
-                    dataLength = zclDataTypeToBytes(zclPayload)
-
-                    # consume zcl payload data
-                    if ((ord(attributeType) == 0x41) or (ord(attributeType) == 0x42)):
-                        zclPayload = zclPayload[2:]
-                    elif ((ord(attributeType) == 0x43) or (ord(attributeType) == 0x44)):
-                        zclPayload = zclPayload[3:]
-                    else:
-                        zclPayload = zclPayload[1:]
-
-                    # package the data and add it to the list
-                    newData = (attributeId,"success", attributeType ,zclPayload[0:dataLength])
-                    attibuteResponseList.append(newData)
-
-                    # consume the data size of the payload
-                    zclPayload = zclPayload[dataLength:]
-
-            # find who to send response to 
-            tup = None
-            zigbeeSeqNumberToClientMutex.acquire()
-            if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))):
-                tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-                del zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-            zigbeeSeqNumberToClientMutex.release()
-
-            # no one to send the response to so just move on
-            if(tup == None):
-                # cant really do anything here
-                return
-            
-            # create the response message
-            packetId = tup[2]
-            message = "type : zcl_read_attributes_response \n"
-            message += "packet_id: " + packetId + "\n"
-            message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
-            message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
-            message += "attributes: " 
-
-            # create the message for each attribute
-            for t in attibuteResponseList:
-                attrId = ord(t[0][0]) + (256 * ord(t[0][1]))
-                if(t[1] == "success"):
-                    attrIdStr = "%0.4x" % attrId
-                    attrIdStr = changeEndian(attrIdStr)
-
-                    message += attrIdStr
-                    message += ", "
-                    message +=  "success"
-                    message += ", "
-                    message += "%0.2x" % ord(t[2])
-                    message += ", "
-
-                    dat = ""
-                    for c in (t[3]):
-                        dat += "%0.2x" % ord(c)
-                    dat = changeEndian(dat)
-                    message += dat
-                    message += ";"
-                else:
-                    attrIdStr = "%0.4x" % attrId
-                    attrIdStr = changeEndian(attrIdStr)
-
-                    message += attrIdStr
-                    message += ", "
-                    message +=  "not_supported"
-                    message += ";"
-
-            message = message[0:len(message) - 1]
-            message += "\n"
-            # send the socket
-            sendSoceket.sendto(message,tup[0])
-
-
-
-
-       # made by changwoo
-        # this is a zcl write attribute response
-       elif(zclCommand == '\x04'):
-
-            # get the zcl payload
-            zclPayload = parsedData['rf_data'][3]
-           # the response is '70' which means already resister the mac address or 'success', then let JAVA knows it
-           if(zclStatus == '\x70' or zclPayload == '\x00'):
-
-                # find who to send response to 
-                tup = None
-                zigbeeSeqNumberToClientMutex.acquire()
-                if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))):
-                    tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-                   seqNumberForNotification[longAddr] = ord(zclSeqNumber)
-                    #del zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-                zigbeeSeqNumberToClientMutex.release()
-                # no one to send the response to so just move on
-                if(tup == None):
-                    # cant really do anything here
-                    return
-            
-                # create the response message
-                packetId = tup[2]
-                message = "type : zcl_write_attributes_response\n"
-                message += "packet_id: " + packetId + "\n"
-                message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
-                message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
-                message += "attributes: success"
-                message += "\n"
-                # send the socket
-                sendSoceket.sendto(message,tup[0])
-               print ''
-               print '[ 0x0500 ] get Write Attribute Response success'
-               print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-
-           else:
-               print ''
-               print '[ 0x0500 ] get Write Attribute Response'
-               print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
-
-
-
-        # this is a zcl configure attribute response
-        elif(zclCommand == '\x07'):
-
-            # find who to send response to 
-            tup = None
-            zigbeeSeqNumberToClientMutex.acquire()
-            if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))):
-                tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-                del zigbeeSeqNumberToClient[ord(zclSeqNumber)]
-            zigbeeSeqNumberToClientMutex.release()
-
-            # no one to send the response to so just move on
-            if(tup == None):
-                # cant really do anything here
-                return
-
-            # get zcl payload
-            zclPayload = parsedData['rf_data'][3:]
-            
-            # construct the message
-            packetId = tup[2]
-            message = "type : zcl_configure_reporting_response \n"
-            message += "packet_id: " + packetId + "\n"
-            message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
-            message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
-            message += "attributes: " 
-
-            if(len(zclPayload) == 1):
-                # if all the configurations are a success then only send back a success
-                # based on zigbee specs
-                message +=  "all_success \n";
-                sendSoceket.sendto(message,tup[0])
-            
-            else:
-                attibuteResponseList = []
-                
-                # get each attributes data
-                while(len(zclPayload) > 0):
-                    attributeStatus = zclPayload[0]
-                    attributeDirection = zclPayload[1]
-                    attributeId = zclPayload[2:4]
-                    zclPayload = zclPayload[4:]
-
-                    newData = (attributeStatus,attributeDirection, attributeId)
-                    attibuteResponseList.append(newData)
-
-                # package each attribute 
-                for t in attibuteResponseList:
-                    attrId = ord(t[2][0]) + (256 * ord(t[2][1]))
-                    attrIdStr = "%0.4x" % attrId
-                    attrIdStr = changeEndian(attrIdStr)
-
-                    message += attrIdStr
-                    message += ", "
-                    if(ord(t[0]) == 0):
-                        message +=  "success"
-                    else:
-                        message +=  "error"
-
-                    message += ", "
-
-                    if(ord(t[1]) == 0):
-                        message +=  "reported"
-                    else:
-                        message +=  "received"
-                    message += ";"
-
-                message = message[0:len(message) - 1]
-                message += "\n"
-                sendSoceket.sendto(message,tup[0])
-
-        # this is a zcl report attribute message
-        elif(zclCommand == '\x0a'):
-           print "get Report attribute "
-            # get teh zcl payload
-            zclPayload = parsedData['rf_data'][3:]
-            attibuteResponseList = []
-            # extract the attribute data
-            while(len(zclPayload) > 0):
-                attributeId = zclPayload[0:2]
-                zclPayload = zclPayload[2:]
-                attributeType = zclPayload[0]
-                dataLength = zclDataTypeToBytes(zclPayload)
-
-                if ((ord(attributeType) == 0x41) or (ord(attributeType) == 0x42)):
-                    zclPayload = zclPayload[2:]
-                elif ((ord(attributeType) == 0x43) or (ord(attributeType) == 0x44)):
-                    zclPayload = zclPayload[3:]
-                else:
-                    zclPayload = zclPayload[1:]
-
-                newData = (attributeId, attributeType ,zclPayload[0:dataLength])
-                attibuteResponseList.append(newData)
-                zclPayload = zclPayload[dataLength:]
-
-
-            # get callback clients to respond to
-            callbackIndex = (zigbeeHexStringToHexString(parsedData['source_addr_long']), zigbeeHexStringToHexString(parsedData['cluster']))
-            retAddr = None
-            zibeeHACallbackMutex.acquire()
-            if(zibeeHACallback.has_key(callbackIndex)):
-                retAddr = zibeeHACallback[callbackIndex]
-            zibeeHACallbackMutex.release()
-
-            # no one to respond to so do nothing here
-            if(retAddr == None):
-                return
-
-            # construct the message
-            message = "type : zcl_report_attributes \n"
-            message += "packet_id: " + ("%0.2x" % ord(zclSeqNumber)) + "\n"
-            message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n"
-            message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n"
-            message += "attributes: " 
-
-            # package the attributes
-            for t in attibuteResponseList:
-                attrId = ord(t[0][0]) + (256 * ord(t[0][1]))
-                attrIdStr = "%0.4x" % attrId
-                attrIdStr = changeEndian(attrIdStr)
-
-                message += attrIdStr
-                message += ", "
-                message += "%0.2x" % ord(t[1])
-                message += ", "
-
-                dat = ""
-                for c in (t[2]):
-                    dat += "%0.2x" % ord(c)
-                dat = changeEndian(dat)
-                message += dat
-                message += ";"
-
-            message = message[0:len(message) - 1]
-            message += "\n"
-           print "Sending", message
-           
-            # send to all client that want this callback
-            for ra in retAddr:
-                sendSoceket.sendto(message,ra)
-
-# -----------------------------------------------------------------------------
-# Communication Callback/Parse Methods
-# -----------------------------------------------------------------------------
-def handleNewZigbeeMessage(parsedData):
-    ''' Method to process a zigbee message from the local radio.
-
-        parsedData -- Pre-parsed (into a dict) data from message.
-    '''
-    #print "=================================================================="
-    #print ''
-    #print "New Zigbee Message"
-    #printMessageData(parsedData)
-
-    # dispatch to the correct zigbee handler
-    if (parsedData['id'] == 'at_response'):
-        processZigbeeATCommandMessage(parsedData)
-
-    elif (parsedData['id'] == 'rx_explicit'):
-        processZigbeeRxExplicitCommandMessage(parsedData)
-
-    else:
-        print "Unknown API format"
-
-    #print "=================================================================="
-
-
-
-def handleNewUdpPacket(data, addr):
-    ''' Method to parse and handle an incoming UDP packet.
-
-        data -- Data that was in the UDP packet.
-        addr -- Address (IP and Port) of the UDP packet origin.
-    '''
-    global ManagementPermitJoiningReqSuccess
-
-    #print "=================================================================="
-    #print ''
-    #print "Got New UDP packet..."
-    #print data
-
-
-    # data comes in as 'key: value\n key: value...' string and so needs to be
-    # parsed into a dict
-    parsedData = dict()
-
-    # 1 key, value pair per line
-    for line in data.split('\n'):
-
-        # key and values are split based on a ':'
-        fields = line.split(':')
-
-        # make sure properly formated otherwise just ignore it
-        if len(fields) == 2:
-
-            # do strips to remove any white spacing that may have resulted
-            # from improper packing on the sender side
-            parsedData[fields[0].strip()] = fields[1].strip()
-
-
-    # wrap in try statement just in case there is an improperly formated packet we
-    # can deal with it
-    try:
-        # dispatch to the correct process method
-        if(parsedData["type"] == "zdo_bind_request"):
-            processUdpZdoBindReqMessage(parsedData, addr)
-        elif(parsedData["type"] == "zdo_unbind_request"):
-            processUdpZdoUnBindReqMessage(parsedData, addr)
-        elif(parsedData["type"] == "send_address"):
-            processUdpSendAddressMessage(parsedData, addr)
-        elif(parsedData["type"] == "zcl_read_attributes"):
-            processUdpZclReadAttributesMessage(parsedData, addr)
-        elif(parsedData["type"] == "zcl_configure_reporting"):
-            processUdpZclConfigureReportingMessage(parsedData, addr)
-        elif(parsedData["type"] == "policy_set"):
-            processUdpPolicySet(parsedData, addr)
-        elif(parsedData["type"] == "policy_clear"):
-            processUdpPolicyClear(parsedData, addr)
-       elif(parsedData["type"] == "management_permit_joining_request"): #made by changwoo
-           processUdpManagementPermitJoiningReqMessage(parsedData, addr)
-       elif(parsedData["type"] == "zcl_write_attributes" and ManagementPermitJoiningReqSuccess): #made by changwoo
-            processUdpZclWriteAttributesMessage(parsedData, addr)
-       elif(parsedData["type"] == "zcl_enrollment_response"): #made by changwoo
-           processUdpEnrollmentResponse(parsedData, addr)
-       elif(parsedData["type"] == "zdo_broadcast_route_record_request"): #made by changwoo
-           processUdpBroadcastingRouteRecordReqMessage(parsedData, addr)
-       elif(parsedData["type"] == "zcl_change_switch_request"): #made by changwoo
-           processUdpZclChangeSwitchReqMessage(parsedData, addr)
-        else:
-            #print "unknown Packet: " + parsedData["type"]
-            pass
-    except:
-        # if we ever get here then something went wrong and so just ignore this
-        # packet and try again later
-        print "I didn't expect this error:", sys.exc_info()[0]
-        traceback.print_exc()
-
-    #print "=================================================================="
-
-
-# -----------------------------------------------------------------------------
-# Main Running Methods
-# -----------------------------------------------------------------------------
-
-def main():
-    '''Main function used for starting the application as the main driver'''
-
-    global ZIGBEE_SERIAL_PORT
-    global ZIGBEE_SERIAL_BAUD
-    global UDP_RECEIVE_PORT
-    global zigbeeConnection
-    global zigbeeMutex
-    global doEndFlag
-
-    parseCommandLineArgs(sys.argv[1:])
-
-    # create serial object used for communication to the zigbee radio
-    sc = serial.Serial(ZIGBEE_SERIAL_PORT, ZIGBEE_SERIAL_BAUD)
-
-    # create a zigbee object that handles all zigbee communication
-    # we use this to do all communication to and from the radio
-    # when data comes from the radio it will get a bit of unpacking
-    # and then a call to the callback specified will be done with the
-    # unpacked data
-    zigbeeConnection = ZigBee(sc, callback=handleNewZigbeeMessage)
-
-    # get the long address of our local radio before we start doing anything
-    getConnectedRadioLongAddress();
-
-    # setup incoming UDP socket and bind it to self and specified UDP port
-    # sending socket does not need to be bound to anything
-    receiveSoceket.bind(('127.0.0.1', UDP_RECEIVE_PORT))
-
-    # create the thread that does short address lookups
-    addressUpdateWorkerThread = threading.Thread(target=addressUpdateWorkerMethod)
-    addressUpdateWorkerThread.start()
-
-    try:
-        # Main running loop
-        while(True):
-            #print "=================================================================="
-            #print ''
-           #print "Waiting..."
-            #print "=================================================================="
-
-            # wait for an incoming UDP packet
-            # this is a blocking call
-            data, addr = receiveSoceket.recvfrom(4096)
-
-            # handle the UDP packet appropriately
-            handleNewUdpPacket(data, addr)
-
-    except KeyboardInterrupt:
-        # use the keyboard interupt to catch a ctrl-c and kill the application
-        pass
-
-    except:
-        # something went really wrong and so exit with error message
-        traceback.print_exc()
-
-    # signal all threads to exit
-    doEndFlag = True
-
-    # wait for threads to finish before closing of the resources
-    addressUpdateWorkerThread.join()
-
-
-    # make sure to close all the connections
-    zigbeeConnection.halt()
-    receiveSoceket.close()
-    sendSoceket.close()
-
-if __name__ == "__main__":
-    # call main function since this is being run as the start
-    main()