コード例 #1
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devscope(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Return an RDM packet for device scope
    RDM_GET = yes
    RDM_SET = yes
    """
    #TODO: Currently this only returns scope 1
    if recpdu.cc == defines.CC_Get_command:
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = 0x21
        sendpdu.pid = 0x0800 
        sendpdu.pdl = 34
        sendpdu.pd = bytearray(b'\x00\x01')
        if len(self.device_descriptor.scope) > 63:
            sendpdu.pd.extend(bytes(self.device_descriptor.scope[:63], 'utf-8'))
        else:
            sendpdu.pd.extend(bytes(self.device_descriptor.scope, 'utf-8'))
            for i in range(63-len(self.device_descriptor.scope)):
                sendpdu.pd.extend(b'\x00')
        #Static config Type,
        sendpdu.pd.extend(b'\x01')
        #IPv4 Address
        sendpdu.pd.extend(b'\x7f\x00\x00\x01')
        #IPv6 Address
        sendpdu.pd.extend(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
        #Port
        sendpdu.pd.extend(b'\x00\x00')
        sendpdu.pdl = len(sendpdu.pd)
        sendpdu.length = 24+sendpdu.pdl
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        self.device_descriptor.scope = recpdu.pd.decode('utf-8')
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #2
0
ファイル: llrp.py プロジェクト: gagarcr/dummyRDM
def handlerdm(self, pdu):
    # Check cid is ours
    if pdu[46:62] != self.device_descriptor.cid:
        print("Incorrect CID - ignoring")
        return None
    # Check UID is ours
    if pdu[72:78] != self.device_descriptor.uid:
        print("Incorrect UID - ignoring")
        return None
    # Process the packet
    #Now we know it's ours, make an RDM packet for the source
    srcpacket = rdmpacket.RDMpacket()
    srcpacket.fromart(pdu[70:])
    if not srcpacket.checkchecksum():
        return None
    func = self.device_descriptor.llrpswitcher.get(srcpacket.pid, "NACK")
    if func is not "NACK":
        returnpacket = func(self, srcpacket)
        pdu = pdus.llrp_rpt_pdu(self, returnpacket.artserialise(), pdu)
        self.transport.sendto(pdu, (llrp_multicast_v4_response, 5569))
    else:
        print("Device {} does not support PID:0x{:04x} on LLRP target".format(
            self.uid.hex(), srcpacket.pid))
        returnpacket = gethandlers.nackreturn(self, srcpacket,
                                              nackcodes.nack_unknown)
        pdu = pdus.llrp_rpt_pdu(self, returnpacket.artserialise(), pdu)
        self.transport.sendto(pdu, (llrp_multicast_v4_response, 5569))
    return
コード例 #3
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def sensorval(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns a sensor value rdmpacket for the given device
    RDM_GET = yes
    RDM_SET = no
    """

    if recpdu.cc is not defines.CC_Get_command:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
    else:
        sensno = recpdu.pd[0]
        if sensno < len(self.device_descriptor.sensors):
            #Ack and return definition
            sendpdu = rdmpacket.RDMpacket()
            self.device_descriptor.sensors[sensno].updateval()
            sendpdu.destuid = recpdu.srcuid
            sendpdu.srcuid = self.device_descriptor.uid
            sendpdu.tn = recpdu.tn
            sendpdu.port_resp = 0x00
            sendpdu.mess_cnt = 0x00
            sendpdu.sub_id = 0x0000
            sendpdu.cc = 0x21
            sendpdu.pid = 0x0201
            sendpdu.pd = bytearray(sensno.to_bytes(1, 'big'))
            sendpdu.pd.extend(pack('!h', self.device_descriptor.sensors[sensno].value))
            sendpdu.pdl = len(sendpdu.pd)
            sendpdu.length = 0x18 + sendpdu.pdl
            sendpdu.calcchecksum()
            return sendpdu
        else:
            #NACK
            return nackreturn(self, recpdu, nackcodes.nack_data_range)
コード例 #4
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devreset(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Performs a simulated hot/cold reset on the device
    RDM_GET = no
    RDM_SET = yes
    """

    if recpdu.cc == defines.CC_Set_command:
        if recpdu.pd[0] == 0x01:
            #Warm Reset
            print("Device {}: Warm reset requested".format(self.device_descriptor.uid.hex()))
        elif recpdu.pd[0] == 0xFF:
            #Cold Reset
            print("Device {}: Cold reset requested".format(self.device_descriptor.uid.hex()))
        else:
            #Out of range NACK
            return nackreturn(self, recpdu, nackcodes.nack_data_range)
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
        return sendpdu
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #5
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devmodel(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns a Device Model Description rdmpacket for the given device
    RDM_GET = yes
    RDM_SET = no
    """

    if recpdu.cc is not defines.CC_Get_command:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
    sendpdu = rdmpacket.RDMpacket()
    sendpdu.destuid = recpdu.srcuid
    sendpdu.srcuid = self.device_descriptor.uid
    sendpdu.tn = recpdu.tn
    sendpdu.port_resp = 0x00
    sendpdu.mess_cnt = 0x00
    sendpdu.sub_id = 0x0000
    sendpdu.cc = 0x21
    sendpdu.pid = 0x0080
    if len(self.device_descriptor.model) > 32:
        sendpdu.pd = bytes(self.device_descriptor.model[:32], 'utf-8')
    else:
        sendpdu.pd = bytes(self.device_descriptor.model, 'utf-8') #Limit 32 Characters
    sendpdu.pdl = len(sendpdu.pd)
    sendpdu.length = 24+sendpdu.pdl
    sendpdu.calcchecksum()
    return sendpdu
コード例 #6
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def supportedpids(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns an rdmpacket containing a list of supported pids
    for the given device
    RDM_GET = yes
    RDM_SET = no
    """

    if recpdu.cc is not defines.CC_Get_command:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
    sendpdu = rdmpacket.RDMpacket()
    sendpdu.destuid = recpdu.srcuid
    sendpdu.srcuid = self.device_descriptor.uid
    sendpdu.tn = recpdu.tn
    sendpdu.port_resp = 0x00
    sendpdu.mess_cnt = 0x00
    sendpdu.sub_id = 0x0000
    sendpdu.cc = 0x21
    sendpdu.pid = 0x0050  
    rdmlist = list(self.device_descriptor.getswitcher.keys())
    llrplist = list(self.device_descriptor.llrpswitcher.keys())
    sendpdu.pdl = (len(rdmlist)+len(llrplist))*2
    keybytes = bytearray()
    for key in rdmlist:
        keybytes.extend(key.to_bytes(2, byteorder='big'))
    for key in llrplist:
        keybytes.extend(key.to_bytes(2, byteorder='big'))
    sendpdu.pd = keybytes
    sendpdu.length = 24+sendpdu.pdl
    sendpdu.calcchecksum()
    return sendpdu
コード例 #7
0
ファイル: packets.py プロジェクト: gagarcr/dummyRDM
 def __init__(self):
     self.opcode = 0x8300
     self.ver = 0x0101
     self.rdmver =0x01
     self.net = 0x00
     self.command = 0x00
     self.address = 0x00
     self.rdmpd = rdmpacket.RDMpacket()
コード例 #8
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devidentify(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Either sets the device identify status or returns the device identify
    status to the requesting controller
    RDM_GET = yes
    RDM_SET = no
    """

    if recpdu.cc == defines.CC_Get_command:
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 25
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Get_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 1
        sendpdu.pd = self.device_descriptor.identifystatus.to_bytes(1, 'big')
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        if recpdu.pd[0] <= 1:
            print("Device {}: Identify set to {:02x}".format(self.device_descriptor.uid.hex(), recpdu.pd[0]))
            self.device_descriptor.identifystatus = recpdu.pd[0]
            sendpdu = rdmpacket.RDMpacket()
            sendpdu.length = 24
            sendpdu.destuid = recpdu.srcuid
            sendpdu.srcuid = self.device_descriptor.uid
            sendpdu.tn = recpdu.tn
            sendpdu.port_resp = 0x00
            sendpdu.mess_cnt = 0x00
            sendpdu.sub_id = 0x0000
            sendpdu.cc = defines.CC_Set_command_resp
            sendpdu.pid = recpdu.pid
            sendpdu.pdl = 0
            sendpdu.calcchecksum()
            return sendpdu
        else:
            #Out of range NACK
            return nackreturn(self, recpdu, nackcodes.nack_data_range)
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #9
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devsearch(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Return an RDM packet for device scope
    RDM_GET = yes
    RDM_SET = yes
    """

    if recpdu.cc == defines.CC_Get_command:
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = 0x21
        sendpdu.pid = 0x0801
        if len(self.device_descriptor.searchdomain) > 32:
            sendpdu.pd = bytes(self.device_descriptor.searchdomain[:32], 'utf-8')
        else:
            sendpdu.pd = bytes(self.device_descriptor.searchdomain, 'utf-8') #Limit 32 Characters
        sendpdu.pdl = len(sendpdu.pd)
        sendpdu.length = 24+sendpdu.pdl
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        self.device_descriptor.searchdomain = recpdu.pd.decode('utf-8')
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #10
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def lamppowerstate(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns an rdmpacket containing the lamp sate on power on
    as a unsigned char for the given device
    RDM_GET = yes
    RDM_SET = yes
    """

    if recpdu.cc == defines.CC_Get_command:
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 0x1c
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = 0x21
        sendpdu.pid = 0x0405
        sendpdu.pdl = 0x04
        sendpdu.pd = self.device_descriptor.lamppowerstate.to_bytes(1, 'big')
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        self.device_descriptor.lamppowerstate = unpack('!B', recpdu.pd[0])[0]
        print("Device {}: Lamp Power State set to: {}".format(self.device_descriptor.uid.hex(),
                                                              self.device_descriptor.lamppowerstatus))
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #11
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devfactory(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Either sets the device to factory defaults or gets if the device is
    currently set to factory defaults
    RDM_GET = yes
    RDM_SET = yes
    """
    #BUG: Currently Returning with incorrect checksum - needs verification
    if recpdu.cc == defines.CC_Get_command:
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 25
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Get_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 1
        sendpdu.pd = self.device_descriptor.factorystatus.to_bytes(1, 'big')
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        print("Device {}: Factory Reset".format(self.device_descriptor.uid.hex()))
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
        return sendpdu
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #12
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def powercycles(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns a power cycles rdmpacket for the given device
    RDM_GET = yes
    RDM_SET = yes
    """

    if recpdu.cc == defines.CC_Get_command:
        self.device_descriptor.powercycles += 1
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 0x1c
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = 0x21
        sendpdu.pid = 0x0405
        sendpdu.pdl = 0x04
        sendpdu.pd = self.device_descriptor.powercycles.to_bytes(4, 'big')
        sendpdu.calcchecksum()
        return sendpdu
    elif recpdu.cc == defines.CC_Set_command:
        self.device_descriptor.powercycles = unpack('!L', recpdu.pd[0:4])[0]
        sendpdu = rdmpacket.RDMpacket()
        sendpdu.length = 24
        sendpdu.destuid = recpdu.srcuid
        sendpdu.srcuid = self.device_descriptor.uid
        sendpdu.tn = recpdu.tn
        sendpdu.port_resp = 0x00
        sendpdu.mess_cnt = 0x00
        sendpdu.sub_id = 0x0000
        sendpdu.cc = defines.CC_Set_command_resp
        sendpdu.pid = recpdu.pid
        sendpdu.pdl = 0
        sendpdu.calcchecksum()
    else:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
コード例 #13
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def nackreturn(self, recpdu: rdmpacket.RDMpacket, reasoncode) -> rdmpacket.RDMpacket:
    """Returns a NACK for a given rdmpacket with a reason"""

    print("Nacking PID {:04x}".format(recpdu.pid))
    sendpdu = rdmpacket.RDMpacket()
    sendpdu.length = 0x1a
    sendpdu.destuid = recpdu.srcuid
    sendpdu.srcuid = self.device_descriptor.uid
    sendpdu.tn = recpdu.tn
    sendpdu.port_resp = 0x02
    sendpdu.cc = 0x21
    sendpdu.pid = recpdu.pid
    sendpdu.pdl = 0x02
    sendpdu.pd = reasoncode
    sendpdu.calcchecksum()
    return sendpdu
コード例 #14
0
ファイル: rpthandlers.py プロジェクト: gagarcr/dummyRDM
async def rptrequest(self, data: bytearray) -> None:
    """Processes an RPT Request PDU.

    RPT Request PDUs can only contain ONE RDM payload.
    """
    #TODO: Handle invalid data
    print("RPT Request")
    sourceuid = data[7:13]
    sourceendpoint = data[13:15]
    destuid = data[15:21]
    destendpoint = data[21:23]
    sequence = data[23:27]
    payload = rdmpacket.RDMpacket()
    payload.fromart(data[39:])
    retpacket = None
    func = self.device_descriptor.llrpswitcher.get(payload.pid, "NACK")
    if func is "NACK":
        func = self.device_descriptor.getswitcher.get(payload.pid, "NACK")
    if func is not "NACK":
        retpacket = func(self, payload)
    else:
        retpacket = gethandlers.nackreturn(self, payload,
                                           nackcodes.nack_unknown)

    # Now we have a RDMPacket - add that to a notification PDU and return to sender
    packet = pdus.ACNTCPPreamble()
    rlppacket = pdus.RLPPDU(vectors.vector_root_rpt,
                            self.device_descriptor.cid)
    rptpacket = pdus.RptPdu(vectors.vector_rpt_notification, sourceuid,
                            sourceendpoint, destuid, destendpoint, sequence)
    notifpacket = pdus.RPTNotificationPDU()
    cmdpacket = pdus.RDMCommandPDU()

    print("PID {:04x}".format(payload.pid))
    cmdpacket.message = retpacket
    notifpacket.message = cmdpacket
    rptpacket.message = notifpacket
    rlppacket.message = rptpacket
    packet.message = rlppacket
    retval = packet.serialise()
    print("Total Length: {}".format(len(retval)))
    if payload.pid == 0x00f0:
        hexdump.hexdump(retval)
    self.writer.write(retval)
    await self.writer.drain()
コード例 #15
0
ファイル: gethandlers.py プロジェクト: gagarcr/dummyRDM
def devinfo(self, recpdu: rdmpacket.RDMpacket) -> rdmpacket.RDMpacket:
    """Returns an device info rdmpacket for the given device
    RDM_GET = yes
    RDM_SET = no
    """

    if recpdu.cc is not defines.CC_Get_command:
        return nackreturn(self, recpdu, nackcodes.nack_unsupported_cc)
    sendpdu = rdmpacket.RDMpacket()
    sendpdu.length = 0x2b
    sendpdu.destuid = recpdu.srcuid
    sendpdu.srcuid = self.device_descriptor.uid
    sendpdu.tn = recpdu.tn
    sendpdu.port_resp = 0x00
    sendpdu.mess_cnt = 0x00
    sendpdu.sub_id = 0x0000
    sendpdu.cc = 0x21
    sendpdu.pid = 0x0060
    sendpdu.pdl = 0x13
    # 16-bit Protocol Version
    sendpdu.pd.extend(b'\x01\x00')
    # Model ID
    sendpdu.pd.extend(b'\x01\x02')
    # Category
    sendpdu.pd.extend(b'\x71\x01')
    # Software Version
    sendpdu.pd.extend(b'\x01\x02\x03\x04')
    # DMX Footprint
    sendpdu.pd.extend(self.device_descriptor.dmxfootprint.to_bytes(2, 'big'))
    # DMX Personality
    sendpdu.pd.extend(self.device_descriptor.currentpers.to_bytes(1, 'big'))
    perslen = len(self.device_descriptor.perslist)+1
    sendpdu.pd.extend(perslen.to_bytes(1, 'big'))
    # DMX Start Address
    sendpdu.pd.extend(self.device_descriptor.dmxaddress.to_bytes(2, 'big'))
    # Sub Device Count
    sendpdu.pd.extend(b'\x00\x00')
    # Sensor Count
    sendpdu.pd.extend(len(self.device_descriptor.sensors).to_bytes(1, 'big'))
    sendpdu.calcchecksum()
    return sendpdu