+# -----------------------------------------------------------------------------
+# ZigBee Gateway Driver for Vigilia v.1.0
+# Created by Ali Younis
+# Modified by Rahmadi Trimananda, Lee Changwoo, Jiawei
+# (c) 2016-2018 University of California, Irvine
+# -----------------------------------------------------------------------------
+
from xbee import ZigBee
import serial
import time
# -----------------------------------------------------------------------------
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.1.198", 12345) # ip address and portof the system master node
+LOCAL_ADDRESS = "192.168.1.192" # local IP address
# 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
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()
zigbeeSeqNumberToClient = dict()
zigbeeSeqNumberToClientMutex = Lock()
-zigeeBindRequest = dict()
-zigeeBindRequestMutex = Lock()
+zigbeeBindRequest = dict()
+zigbeeBindRequestMutex = Lock()
# Keeps record of where to send callbacks to when an HA message is received
zibeeHACallback = dict()
-zibeeHACallbackMutex = Lock()
+zigbeeHACallbackMutex = Lock()
# Keeps a record of device addresses whose short addresses have not been
# 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)
+sendSocket = socket(AF_INET, SOCK_DGRAM)
+receiveSocket = socket(AF_INET, SOCK_DGRAM)
# zigbee address authority list
zigbeeAddressAuthorityDict = dict()
+# Added 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
# create and send binding command
zigbeeConnectionMutex.acquire()
+
zigbeeConnection.send('tx_explicit',
frame_id='\x01',
dest_addr_long=hexStringToZigbeeHexString(ad),
)
zigbeeConnectionMutex.release()
- time.sleep(1)
+ time.sleep(1)
+
+
+# -------------
+# 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 sendSocket
+
+ # 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
+ sendSocket.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):
+ print "> Short address exists", shortAddr
+
+ # 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
+ zigbeeBindRequestMutex.acquire()
+ zigbeeBindRequest[seqNumber] = (parsedData['device_address_long'],
+ parsedData['cluster_id'],
+ parsedData['packet_id'],
+ addr)
+ zigbeeBindRequestMutex.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):
+ zigbeeHACallbackMutex.acquire();
+ if(zibeeHACallback.has_key(parsedData['device_address_long'], parsedData['cluster_id'])):
+ zibeeHACallback(parsedData['device_address_long'], parsedData['cluster_id']).remove(addr)
+ zigbeeHACallbackMutex.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 sendSocket
+
+ 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
+ sendSocket.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()
+
+
+
+# Added by Changwoo
+def processUdpEnrollmentResponse(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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
+
+
+
+
+# Added by Changwoo
+def processUdpZclWriteAttributesMessage(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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 += 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
+
+# Added by Changwoo
+def processUdpZclChangeSwitchReqMessage(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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
+
+
+# Added by Jiawei
+def processUdpZclLockOrUnlockDoorReqMessage(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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, 'lock_or_unlock_door_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',
+ 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 value == '\x01':
+ print '> The door lock is unlocked'
+ elif value == '\x00':
+ print '> The door lock is locked'
+ else:
+ print '> Unknown door lock value: ' + str(value)
+
+ zigbeeConnectionMutex.release()
+
+
+ else:
+ # send a fail response
+ sendUdpSuccessFail(addr, 'lock_or_unlock_door_request', parsedData['packet_id'], False, 'short_address_unknown')
+
+
+# Added by Jiawei
+def processUdpZclReadDoorStatusReqMessage(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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, 'read_door_status_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'])
+
+ # create and send binding command
+ zigbeeConnectionMutex.acquire()
+
+ zigbeeConnection.send('tx_explicit',
+ frame_id='\x40',
+ dest_addr_long=destLongAddr,
+ dest_addr=destShortAddr,
+ src_endpoint='\x01',
+ dest_endpoint=dstEndpoint,
+ cluster=clusterId,
+ profile=profileId,
+ data='\x10' + chr(seqNumber) + '\x00' + '\x00\x00'
+ )
+ time.sleep(1)
+
+ zigbeeConnectionMutex.release()
+ print "send read door status"
+
+ else:
+ # send a fail response
+ sendUdpSuccessFail(addr, 'read_door_status_request', parsedData['packet_id'], False, 'short_address_unknown')
+
+
+# Added by Changwoo
+def processUdpBroadcastingRouteRecordReqMessage(parsedData, addr):
+
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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'])
-# -------------
-# UDP
-# -------------
+ # send back failure
+ if(seqNumber == -1):
-def sendUdpSuccessFail(addr, packetTypeStr, packetIdStr, sucOrFail, reason=None):
- ''' Method to send a success or fail back to a client.
+ # 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
- 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)
+ # 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'
- global sendSoceket
+ zigbeeConnectionMutex.release()
- # 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 a fail response
+ sendUdpSuccessFail(addr, 'zcl_read_attributes', parsedData['packet_id'], False, 'short_address_unknown')
+ pass
- # send message in a UDP packet
- sendSoceket.sendto(message,addr)
-def processUdpZdoBindReqMessage(parsedData, addr):
+# Added by Changwoo
+def processUdpManagementPermitJoiningReqMessage(parsedData, addr):
+ global zigbeeLongShortAddr
+ global zigbeeLongShortAddrMutex
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ global zigbeeConnectionMutex
+ global zigbeeConnection
+ global matchDescriptorReqSingleton
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(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')
+ sendUdpSuccessFail(addr, 'management_permit_joining_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
+ # 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 += 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 += '\x5a'
payloadData += '\x00'
# create and send binding command
dest_addr=destShortAddr,
src_endpoint='\x00',
dest_endpoint='\x00',
- cluster='\x00\x21',
+ cluster=clusterId,
profile='\x00\x00',
data=payloadData
)
+ print '> ManagementPermitJoiningReq is sent'
+
+ #stop answering 0x6
+ matchDescriptorReqSingleton= False
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')
+ # send a fail response
+ sendUdpSuccessFail(addr, 'management_permit_joining_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
-
- if(zigbeeAddressAuthorityDict.has_key(addr)):
- l = zigbeeAddressAuthorityDict[addr]
- if(parsedData['device_address_long'] not in l):
- return
- else:
- return
-
-
- # 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)
-
- # 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()
def processUdpZclReadAttributesMessage(parsedData, addr):
''' Method handle a ZCL read attribute command
global zigbeeLongShortAddr
global zigbeeLongShortAddrMutex
- global zigeeBindRequestMutex
- global zigeeBindRequest
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
global zigbeeConnectionMutex
global zigbeeConnection
+
if(zigbeeAddressAuthorityDict.has_key(addr)):
l = zigbeeAddressAuthorityDict[addr]
if(parsedData['device_address_long'] not in l):
global zigbeeLongShortAddr
global zigbeeLongShortAddrMutex
- global zigeeBindRequestMutex
- global zigeeBindRequest
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
global zigbeeConnectionMutex
global zigbeeConnection
-
if(zigbeeAddressAuthorityDict.has_key(addr)):
l = zigbeeAddressAuthorityDict[addr]
if(parsedData['device_address_long'] not in l):
else:
return
+
shortAddr = None
# get the short address for this device long address if possible
'''
print "=================================================================="
print "Policy set: ", parsedData
-
+ print 'addr : ', addr
+
+
# do nothing if wrong source
- if addr == SYSTEM_MASTER_ADDRESS:
+ if addr == SYSTEM_MASTER_ADDRESS :
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
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
# -------------
parsedData -- Pre-parsed (into a dict) data from message.
'''
- global zigeeBindRequestMutex
- global zigeeBindRequest
+ global zigbeeBindRequestMutex
+ global zigbeeBindRequest
+ 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
zigbeeLongShortAddr[longAddr] = shortAddr
zigbeeLongShortAddrMutex.release()
+ global matchDescriptorReqSingleton
+ global deviceAnnouncementSingleton
+ global seqNumberForNotification
+
+ # Added by Jiawei
+ #doorlock response
+ if (parsedData['cluster'] == '\x01\x01' and parsedData['profile'] == '\x01\x04'):
+ zclSeqNumber = parsedData['rf_data'][1]
+ tup = None
+ zigbeeSeqNumberToClientMutex.acquire()
+ if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))):
+ tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)]
+ del zigbeeSeqNumberToClient[ord(zclSeqNumber)]
+ zigbeeSeqNumberToClientMutex.release()
+
+ rfdata = parsedData['rf_data']
+ framecontrol = rfdata[0]
+ command = rfdata[2]
+
+ if tup != None:
+ packetId = tup[2]
+
+ if framecontrol == '\x19':
+ if(command == '\x00'):
+ print ''
+ print "( 0x0101 ) Door Lock: Lock Door Response"
+ print time.strftime("%H:%M:%S", time.localtime())
+ value = rfdata[3]
+ if(value == '\x00'):
+ print "Door locked successfully"
+ else:
+ print "An error occurred in door locking"
+ elif(command == '\x01'):
+ print ''
+ print "( 0x0101 ) Door Lock: Unlock Door Response"
+ print time.strftime("%H:%M:%S", time.localtime())
+ value = rfdata[3]
+ if(value == '\x00'):
+ print "Door unlocked successfully"
+ else:
+ print "An error occurred in door unlocking"
+ return
+ elif framecontrol == '\x18':
+ if(command == '\x01'):
+ attributeId = (ord(rfdata[3]) * 256) + ord(rfdata[4])
+ if attributeId == 0x0000:
+ value = rfdata[7]
+ print "Door status: "
+ if value == '\x00':
+ print "Not fully locked"
+ elif value == '\x01':
+ print "Locked"
+ elif value == '\x02':
+ print "Unlocked"
+ else:
+ print "Unknown value: " + zigbeeHexStringToHexString(value)
+
+ 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: "
+
+ attrIdStr = "%0.4x" % attributeId
+ attrIdStr = changeEndian(attrIdStr)
+ message += attrIdStr
+ message += ", "
+
+ zclPayload = parsedData['rf_data'][3:]
+ zclPayload = zclPayload[3:]
+ attributeType = zclPayload[0]
+ message += "%0.2x" % ord(attributeType)
+ message += ", "
+
+ message += "success"
+ message += ", "
+
+ message += "%0.2x" % ord(value)
+ message += ";"
+
+ message += ";"
+
+ message = message[0:len(message) - 1]
+ message += "\n"
+
+ # no one to send the response to so just move on
+ if(tup == None):
+ # cant really do anything here
+ return
+ sendSocket.sendto(message,tup[0])
+ elif command == '\x07':
+ status = rfdata[3]
+ print ''
+ print "( 0x0101 ) Door Lock: Configure reporting response"
+ print 'rfdata : ' + zigbeeHexStringToHexString(rfdata)
+ if status == '\x00':
+ print "Configure report successfully"
+ 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: "
+ message += "all_success \n";
+
+ # no one to send the response to so just move on
+ if(tup == None):
+ # cant really do anything here
+ return
+ sendSocket.sendto(message,tup[0])
+ else:
+ print "Configure report unsuccessfully, status =", zigbeeHexStringToHexString(status)
+ elif(command == '\x0A'):
+ print "New update"
+ attributeId = (ord(rfdata[3]) * 256) + ord(rfdata[4])
+ if attributeId == 0x0000:
+ value = rfdata[6]
+ if value == '\x00':
+ print "Not fully locked"
+ elif value == '\x01':
+ print "Locked"
+ elif value == '\x02':
+ print "Unlocked"
+ else:
+ print "Unknown value: " + zigbeeHexStringToHexString(value)
+
+ message = "type : zcl_read_attributes_response \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: "
+
+ attrIdStr = "%0.4x" % attributeId
+ attrIdStr = changeEndian(attrIdStr)
+ message += attrIdStr
+ message += ", "
+
+ zclPayload = parsedData['rf_data'][3:]
+ zclPayload = zclPayload[3:]
+ attributeType = zclPayload[0]
+ message += "%0.2x" % ord(attributeType)
+ message += ", "
+
+ message += "success"
+ message += ", "
+
+ message += "%0.2x" % ord(value)
+ message += ";"
+
+ message += ";"
+
+ message = message[0:len(message) - 1]
+ message += "\n"
+
+ # get callback clients to respond to
+ callbackIndex = (zigbeeHexStringToHexString(parsedData['source_addr_long']), zigbeeHexStringToHexString(parsedData['cluster']))
+ retAddr = None
+ zigbeeHACallbackMutex.acquire()
+ if(zibeeHACallback.has_key(callbackIndex)):
+ retAddr = zibeeHACallback[callbackIndex]
+ zigbeeHACallbackMutex.release()
+
+ # no one to respond to so do nothing here
+ if(retAddr == None):
+ return
+ for ra in retAddr:
+ sendSocket.sendto(message,ra)
+ return
# if this is a ZDO message/response
if(parsedData['profile'] == '\x00\x00'):
+ # Added 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):
# pick out the correct parts of the payload
longAddr = zigbeeHexStringToHexString(parsedData['rf_data'][3:11])
shortAddr = zigbeeHexStringToHexString(parsedData['rf_data'][1:3])
zigbeeUnregisteredAddresses.remove(longAddr)
zigbeeUnregisteredAddressesMutex.release()
+ # Added 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
tup = None
- zigeeBindRequestMutex.acquire()
- if(zigeeBindRequest.has_key(ord(seqNumber))):
- tup = zigeeBindRequest[ord(seqNumber)]
- zigeeBindRequestMutex.release()
+ zigbeeBindRequestMutex.acquire()
+ if(zigbeeBindRequest.has_key(ord(seqNumber))):
+ tup = zigbeeBindRequest[ord(seqNumber)]
+ zigbeeBindRequestMutex.release()
if(tup == None):
# cant really do anything in this case...
# add a callback for this specific device and cluster
# to the HA callback dict
- zibeeHACallbackMutex.acquire();
+ zigbeeHACallbackMutex.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()
-
+ zigbeeHACallbackMutex.release()
+
# send success message
sendUdpSuccessFail(tup[3], 'zdo_bind_request', tup[2], True)
+
+ print "> Success message sent!"
# Not Supported
elif (ord(statusCode) == 170):
# 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]
zigbeeLongShortAddr[longAddr] = shortAddr
zigbeeLongShortAddrMutex.release()
+ # Added by Changwoo
+ elif(parsedData['cluster'] == '\x80\x06'):
+ print ''
+ print '[ 0x8006 ] get Match Descriptor Response'
+ print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+ # Added by Changwoo
+ elif(parsedData['cluster'] == '\x80\x36'):
+ print ''
+ print '[ 0x8036 ] get Management Permit Joining Response'
+ print '> rfdata : '+zigbeeHexStringToHexString(parsedData['rf_data'])
+
+ ManagementPermitJoiningReqSuccess = True
+
+ # Added 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'):
zclFrameControl = parsedData['rf_data'][0]
zclSeqNumber = parsedData['rf_data'][1]
zclCommand = parsedData['rf_data'][2]
+ zclStatus = parsedData['rf_data'][3]
+
+ # Added 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
+ sendSocket.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:]
message = message[0:len(message) - 1]
message += "\n"
-
# send the socket
- sendSoceket.sendto(message,tup[0])
+ sendSocket.sendto(message,tup[0])
+
+ # Added 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
+ sendSocket.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'):
# 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])
+ sendSocket.sendto(message,tup[0])
else:
attibuteResponseList = []
message = message[0:len(message) - 1]
message += "\n"
- sendSoceket.sendto(message,tup[0])
+ sendSocket.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 = []
# get callback clients to respond to
callbackIndex = (zigbeeHexStringToHexString(parsedData['source_addr_long']), zigbeeHexStringToHexString(parsedData['cluster']))
retAddr = None
- zibeeHACallbackMutex.acquire()
+ zigbeeHACallbackMutex.acquire()
if(zibeeHACallback.has_key(callbackIndex)):
retAddr = zibeeHACallback[callbackIndex]
- zibeeHACallbackMutex.release()
+ zigbeeHACallbackMutex.release()
# no one to respond to so do nothing here
if(retAddr == None):
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)
+ sendSocket.sendto(message,ra)
# -----------------------------------------------------------------------------
# Communication Callback/Parse Methods
parsedData -- Pre-parsed (into a dict) data from message.
'''
- print "=================================================================="
- print "New Zigbee Message"
- # printMessageData(parsedData)
+ #print "=================================================================="
+ #print ''
+ #print "New Zigbee Message"
+ #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"
+ #else:
+ #print "Unknown API format"
+
+ #print "=================================================================="
+
- 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 "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
# 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 "> processUdpZclConfigureReportingMessage 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"): # Added by Changwoo
+ processUdpManagementPermitJoiningReqMessage(parsedData, addr)
+ elif(parsedData["type"] == "zcl_write_attributes" and ManagementPermitJoiningReqSuccess): # Added by Changwoo
+ processUdpZclWriteAttributesMessage(parsedData, addr)
+ elif(parsedData["type"] == "zcl_enrollment_response"): # Added by Changwoo
+ processUdpEnrollmentResponse(parsedData, addr)
+ elif(parsedData["type"] == "zdo_broadcast_route_record_request"): # Added by Changwoo
+ processUdpBroadcastingRouteRecordReqMessage(parsedData, addr)
+ elif(parsedData["type"] == "zcl_change_switch_request"): # Added by Changwoo
+ processUdpZclChangeSwitchReqMessage(parsedData, addr)
+ elif(parsedData["type"] == "zcl_lock_or_unlock_door_request"): # Added by Jiawei
+ processUdpZclLockOrUnlockDoorReqMessage(parsedData, addr)
+ elif(parsedData["type"] == "zcl_read_door_status_request"): # Added by Jiawei
+ processUdpZclReadDoorStatusReqMessage(parsedData, addr)
else:
#print "unknown Packet: " + parsedData["type"]
pass
print "I didn't expect this error:", sys.exc_info()[0]
traceback.print_exc()
- print "=================================================================="
+ #print "=================================================================="
# -----------------------------------------------------------------------------
# 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))
+ receiveSocket.bind((LOCAL_ADDRESS, UDP_RECEIVE_PORT))
# create the thread that does short address lookups
addressUpdateWorkerThread = threading.Thread(target=addressUpdateWorkerMethod)
# 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)
+ data, addr = receiveSocket.recvfrom(4096)
# handle the UDP packet appropriately
handleNewUdpPacket(data, addr)
# make sure to close all the connections
zigbeeConnection.halt()
- receiveSoceket.close()
- sendSoceket.close()
+ receiveSocket.close()
+ sendSocket.close()
if __name__ == "__main__":
# call main function since this is being run as the start