Exemple #1
0
    def onUnsolicitedMessage(self, pkt, address):
        """
        Called when an unsolicited message is received.
        We do not know the node id the message is from. Only the ip address.
        """
        zipPkt = Message.decode(pkt)
        sourceIp = ipaddress.IPv6Address(address[0])
        sourceEP = zipPkt.sourceEP

        if isinstance(zipPkt.command, NetworkManagementProxy.NodeListReport):
            return asyncio.ensure_future(self.__handleNodeListReport__(zipPkt.command))

        # Find the node this was from
        for nodeId, node in self._nodes.items():
            if node.get("ip") != sourceIp:
                continue
            if zipPkt.ackRequest:
                # This message needs an ack response.
                ackReponse = zipPkt.response(success=True)
                self._unsolicitedConnection.sendTo(ackReponse.compose(), address)

            self.speak(
                "messageReceived",
                nodeId,
                sourceEP,
                zipPkt.command,
                zipPkt.headerExtension,
            )
            return True
        _LOGGER.warning(
            "Got message from unknown sender %s: %s", sourceIp, zipPkt.command
        )
        return False
def test_ListIterationReport():
    # pylint: disable=line-too-long
    pkt = b"x\x04\x02\x01\x10~Mp\x22\xf1\xd9\xb4\xa9\xa8\x13\xd6\nlr\xa4\xe0m\x01\x01i\x01\x00n\x02\x00\x00"
    msg = Message.decode(pkt)
    assert msg.seqNo == 2
    assert msg.remainingCount == 1
    assert msg.dsk == "32333-28706-61913-46249-43027-54794-27762-42208"
def test_groupinforeport():
    report = Message.decode(b"Y\x04\x81\x01\x00q\x07\x00\x00\x00")
    assert report.groupCount == 1
    assert report.groups[0].groupingIdentifier == 1
    assert report.groups[0].mode == 0
    assert report.groups[0].profile == 0x7107
    assert report.groups[0].eventCode == 0
def test_node_add_dsk_report():
    pkt = b"4\x13\x08\x00T\xcb\xc0}/_\x14\x1ee\x9e\x82\x82\xe67\xc5\x0e"
    msg: NetworkManagementInclusion.NodeAddDSKReport = Message.decode(pkt)
    assert isinstance(msg, NetworkManagementInclusion.NodeAddDSKReport)
    assert msg.seqNo == 8
    assert msg.inputDSKLength == 0
    assert msg.dsk == "21707-49277-12127-05150-26014-33410-58935-50446"
def test_Report():
    pkt = b"\x70\x06\x01\x01\x09"
    msg = Message.decode(pkt)
    assert isinstance(msg, Configuration.Report)
    assert msg.parameterNumber == 1
    assert msg.size == 1
    assert msg.value == 9
Exemple #6
0
async def test_ipOfNode(gateway: ZIPGateway):
    # pylint: disable=line-too-long
    pkt = b"X\x01\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\xa8\x00\xee\xea\xec\xfa\xf9"
    zipNodeAdvertisement = Message.decode(pkt)
    [reply, _] = await asyncio.gather(
        gateway.ipOfNode(6),
        runDelayed(gateway.commandReceived, zipNodeAdvertisement))
    assert reply == ipaddress.IPv6Address("::ffff:c0a8:ee")
Exemple #7
0
 def assert_message_sent(self, cmd: Message):
     for msg in self._sent:
         if inspect.isclass(cmd):
             # Not any specific parameters, just make sure any message with this type is sent
             if msg.hid() == cmd.hid():
                 return True
         elif msg == cmd:
             return True
     raise Exception("Excpected message {} was not sent".format(cmd))
Exemple #8
0
def test_zipnd_zipnodeadvertisement():
    # pylint: disable=line-too-long
    pkt = b"X\x01\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\xa8\x00\xee\xea\xec\xfa\xf9"
    msg = Message.decode(pkt)
    assert isinstance(msg, ZipND.ZipNodeAdvertisement)
    assert msg.local == False
    assert msg.nodeId == 6
    assert msg.ipv6 == ipaddress.IPv6Address("::ffff:c0a8:ee")
    assert msg.homeId == 0xEAECFAF9
    assert msg.compose() == pkt
Exemple #9
0
 async def sendAck():
     await asyncio.sleep(0)
     # pylint: disable=line-too-long
     pkt = b"#\x020\x90\x01\x00\x00\x16\x01\x03\x00\x06=\x03\x0e\x00\x01\x00\x01\x02\x00\x1a\x02\x05\x00\x00\x00\x00\x02"
     msg = Message.decode(pkt)
     adapter.ackReceived(msg)
     await asyncio.sleep(0)
     await asyncio.sleep(0)
     await asyncio.sleep(0)
     adapter.ackReceived(Zip.ZipPacket(ackResponse=True, seqNo=1))
Exemple #10
0
async def test_getNodeInfo(gateway: ZIPGateway):
    # pylint: disable=line-too-long
    cachedNodeInfoReport = Message.decode(
        b"R\x04\x03\x1b\x9c\x9c\x00\x04\x10\x01^%'\x85\\pru\x86ZYszh#")

    gateway.send = sendNop
    [nodeInfo, _] = await asyncio.gather(
        gateway.getNodeInfo(1),
        runDelayed(gateway.commandReceived, cachedNodeInfoReport),
    )
    assert isinstance(nodeInfo, NetworkManagementProxy.NodeInfoCachedReport)
    assert nodeInfo == cachedNodeInfoReport
Exemple #11
0
 async def sendAndReceive(
     self, cmd: Message, waitFor: Message, timeout: int = 3, **kwargs
 ) -> Message:
     self._sent.append(cmd)
     for msg in self._queue:
         if msg.hid() == waitFor.hid():
             return msg
     raise Exception(
         "Error in test setup. Node is not setup to answer on message {}".format(
             waitFor
         )
     )
Exemple #12
0
async def test_getFailedNodeList(gateway: ZIPGateway):
    # pylint: disable=line-too-long
    failedNodeListReport = Message.decode(
        b"R\x0C\x02!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    )

    gateway.send = sendNop
    [nodeList, _] = await asyncio.gather(
        gateway.getFailedNodeList(),
        runDelayed(gateway.commandReceived, failedNodeListReport),
    )
    assert nodeList == {1, 6}
Exemple #13
0
 async def handleMessage(self, message: Message,
                         flags: Zip.HeaderExtension) -> bool:
     """Handle and incomming message. Route it to the correct handler"""
     handled = False
     if self.messageReceived(message) is True:
         # Message has already been handled
         handled = True
     cmdClass: CommandClass = self.supported.get(message.cmdClass())
     if cmdClass:
         retval = await cmdClass.handleMessage(message, flags)
         if retval:
             return retval
     if handled:
         return True
     for retval in await self.ask("onMessage", message):
         if retval:
             return retval
     # Message was not handled
     _LOGGER.warning("Unhandled message %s from node %s", message,
                     self.nodeId)
     _LOGGER.debug(message.debugString())
     return False
def test_node_add_status_partial():
    pkt = b"\x34\x02\x0c\x06\x00N\x15\xd3\x9c\x04\x10\x01^%'\x85\\pru\x86"
    msg = Message.decode(pkt)
    assert isinstance(msg, NetworkManagementInclusion.NodeAddStatus)
    assert msg.seqNo == 12
    assert msg.newNodeID == 78
    assert msg.commandClass == [
        94,
        37,
        39,
        133,
        92,
        112,
        114,
        117,
        134,
    ]
Exemple #15
0
async def test_getNodeList(gateway: ZIPGateway):
    # pylint: disable=line-too-long
    nodeListReport = Message.decode(
        b"R\x02\x02\x00\x01!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    )

    async def dummySend(_msg):
        pass

    gateway.send = dummySend
    assert gateway.nodeId == 0
    [nodeList, _] = await asyncio.gather(
        gateway.getNodeList(),
        runDelayed(gateway.commandReceived, nodeListReport))
    assert nodeList == {1, 6}
    assert gateway._nodes == {1: {}, 6: {}}
    assert gateway.nodeId == 1
Exemple #16
0
def test_zip_packet_networkmanagementproxt_nodelistget():
    pkt = b"#\x02\x80P\x02\x00\x00R\x01\x02"
    msg = Message.decode(pkt)
    assert isinstance(msg, Zip.ZipPacket)
    assert msg.ackRequest == True
    assert msg.ackResponse == False
    assert msg.nackResponse == False
    assert msg.nackWaiting == False
    assert msg.nackQueueFull == False
    assert msg.nackOptionError == False
    assert msg.headerExtIncluded == False
    assert msg.zwCmdIncluded == True
    assert msg.moreInformation == False
    assert msg.secureOrigin == True
    assert msg.seqNo == 2
    assert msg.sourceEP == 0
    assert msg.destEP == 0
    assert type(msg.command) is NetworkManagementProxy.NodeListGet
    assert msg.compose() == pkt
Exemple #17
0
 def onPacket(self, pkt):
     """Called when a packed has recevied from the connection"""
     try:
         zipPkt = Message.decode(pkt)
     except Exception:
         _LOGGER.error("Could not decode message. Raw message:")
         _LOGGER.error("%s", pkt)
         return False
     if isinstance(zipPkt, Zip.ZipPacket):
         if zipPkt.ackResponse:
             self.ackReceived(zipPkt)
             return True
         if zipPkt.nackResponse:
             if zipPkt.nackWaiting:
                 # Waiting: the preceding Z/IP Packet encapsulated Z-Wave Command is not yet
                 # delivered to the destination and delivery will be attempted later on
                 # Threat these as normal acks
                 self.ackReceived(zipPkt)
                 return True
             _LOGGER.error("Nack response not implemented %s",
                           zipPkt.debugString())
             # self.nackReceived(zipPkt.seqNo)
             return False
         if zipPkt.ackRequest:
             _LOGGER.error(
                 "This message needs an ack response. Not implemented")
             return False
         if zipPkt.zwCmdIncluded:
             self.commandReceived(zipPkt)
     elif isinstance(zipPkt, Zip.ZipKeepAlive):
         if zipPkt.ackResponse:
             # Ignore a response
             return True
         _LOGGER.error(
             "This message needs an ack response. Not implemented")
         return False
     elif isinstance(zipPkt, ZipND.ZipNodeAdvertisement):
         self.commandReceived(zipPkt)
     else:
         _LOGGER.warning("Received unknown Z/IP packet from zipgateway: %s",
                         zipPkt)
         return False
     return True
Exemple #18
0
def test_zip_packet_networkmanagementproxt_nodelistreport():
    # pylint: disable=line-too-long
    pkt = b"#\x02\x00\xd0`\x00\x00\x05\x84\x02\x04\x00R\x02\x01\x00\x01!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    msg = Message.decode(pkt)
    assert isinstance(msg, Zip.ZipPacket)
    assert msg.ackRequest == False
    assert msg.ackResponse == False
    assert msg.nackResponse == False
    assert msg.nackWaiting == False
    assert msg.nackQueueFull == False
    assert msg.nackOptionError == False
    assert msg.headerExtIncluded == True
    assert msg.zwCmdIncluded == True
    assert msg.moreInformation == False
    assert msg.secureOrigin == True
    assert msg.seqNo == 96
    assert msg.sourceEP == 0
    assert msg.destEP == 0
    assert type(msg.command) is NetworkManagementProxy.NodeListReport
Exemple #19
0
def test_zip_packet_response():
    # pylint: disable=line-too-long
    pkt = b"#\x02\x00\xd0`\x00\x00\x05\x84\x02\x04\x00R\x02\x01\x00\x01!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    msg = Message.decode(pkt)
    assert isinstance(msg, Zip.ZipPacket)
    reply = msg.response(success=True)
    assert reply.ackRequest == False
    assert reply.ackResponse == True
    assert reply.nackResponse == False
    assert reply.nackWaiting == False
    assert reply.nackQueueFull == False
    assert reply.nackOptionError == False
    assert reply.seqNo == msg.seqNo
    reply = msg.response(success=False, nackQueueFull=True)
    assert reply.ackRequest == False
    assert reply.ackResponse == False
    assert reply.nackResponse == True
    assert reply.nackWaiting == False
    assert reply.nackQueueFull == True
    assert reply.nackOptionError == False
    assert reply.seqNo == msg.seqNo
Exemple #20
0
    async def handleMessage(self, message: Message, flags) -> bool:
        """Handle and incomming message specific to this command class"""
        # Find internal handlers
        if not message.NAME:
            # Not implemented, do not look for handlers
            return False

        hid = message.hid()
        if self.__messageHandlers__:
            handler = self.__messageHandlers__.get(hid)
            if handler and await handler(self, message, flags):
                # Message was handled, stop further processing
                return True

        components = message.NAME.lower().split("_")
        name = "".join(["on", *map(str.title, components)])
        for retval in await self.ask(name, message, flags):
            if retval:
                return True

        # No message handlers for this kind of message
        return False
Exemple #21
0
def test_parse_command():
    pkt = b"\x6C\x01\x03\x03\x20\x03\x02"
    msg = Message.decode(pkt)
    assert isinstance(msg, Supervision.Get)
    assert msg.sessionID == 3
    assert isinstance(msg.command, Basic.Report)
Exemple #22
0
def test_report():
    pkt = b"\x20\x03\x02"
    msg = Message.decode(pkt)
    assert isinstance(msg, Basic.Report)
    assert msg.value == 2
    assert msg.compose() == pkt
def test_groupcommandlistreport():
    report = Message.decode(b"Y\x06\t\x021\x05")
    assert report.commandClass == [[49, 5]]
Exemple #24
0
def test_NodeFailing(pkt, queueHandle):
    msg = Message.decode(pkt)
    assert msg.queueHandle == queueHandle
Exemple #25
0
 def parse_command(stream: BitStreamReader):  # pylint: disable=invalid-name
     """Parse the length prefixed command"""
     length = stream.byte()
     return Message.decode(stream.value(length))
Exemple #26
0
def test_onPacket_Zip(connection: ZIPConnection):
    connection.ackReceived = MagicMock()
    connection.commandReceived = MagicMock()

    ackResponse = Zip.ZipPacket(
        ackRequest=False,
        ackResponse=True,
        nackResponse=False,
        nackWaiting=False,
        nackQueueFull=False,
        nackOptionError=False,
        headerExtIncluded=False,
        zwCmdIncluded=False,
        moreInformation=False,
        secureOrigin=True,
        seqNo=0,
        sourceEP=0,
        destEP=0,
        command=None,
    )
    assert connection.onPacket(ackResponse.compose()) is True
    connection.ackReceived.assert_called_once()

    nackResponse = Zip.ZipPacket(
        ackRequest=False,
        ackResponse=False,
        nackResponse=True,
        nackWaiting=False,
        nackQueueFull=False,
        nackOptionError=False,
        headerExtIncluded=False,
        zwCmdIncluded=False,
        moreInformation=False,
        secureOrigin=True,
        seqNo=0,
        sourceEP=0,
        destEP=0,
        command=None,
    )
    msg = Message.decode(nackResponse.compose())
    assert msg.ackRequest == False
    assert msg.ackResponse == False
    assert msg.nackResponse == True
    assert connection.onPacket(nackResponse.compose()) is False

    nackResponse = Zip.ZipPacket(
        ackRequest=False,
        ackResponse=False,
        nackResponse=True,
        nackWaiting=True,
        nackQueueFull=False,
        nackOptionError=False,
        headerExtIncluded=False,
        zwCmdIncluded=False,
        moreInformation=False,
        secureOrigin=True,
        seqNo=0,
        sourceEP=0,
        destEP=0,
        command=None,
    )
    msg = Message.decode(nackResponse.compose())
    assert msg.ackRequest == False
    assert msg.ackResponse == False
    assert msg.nackResponse == True
    # This should be treated as success
    assert connection.onPacket(nackResponse.compose()) is True

    ackRequest = Zip.ZipPacket(
        ackRequest=True,
        ackResponse=False,
        nackResponse=False,
        nackWaiting=False,
        nackQueueFull=False,
        nackOptionError=False,
        headerExtIncluded=False,
        zwCmdIncluded=False,
        moreInformation=False,
        secureOrigin=True,
        seqNo=0,
        sourceEP=0,
        destEP=0,
        command=None,
    )
    assert connection.onPacket(ackRequest.compose()) is False

    pkt = Zip.ZipPacket(
        ackRequest=False,
        ackResponse=False,
        nackResponse=False,
        nackWaiting=False,
        nackQueueFull=False,
        nackOptionError=False,
        headerExtIncluded=False,
        zwCmdIncluded=True,
        moreInformation=False,
        secureOrigin=True,
        seqNo=0,
        sourceEP=0,
        destEP=0,
        command=Basic.Get(),
    )
    assert connection.onPacket(pkt.compose()) is True
    connection.commandReceived.assert_called_once()
Exemple #27
0
def test_decode(pkt, params):
    msg = Message.decode(bytes.fromhex(pkt))
    for key, value in params.items():
        msgValue = getattr(msg, key)
        assert msgValue == value
def test_SupportedSensorReport():
    msg = Message.decode(b"\x31\x02\x01")
    assert msg.bitMask == set([1])
    msg = Message.decode(b"\x31\x02\x05")
    assert msg.bitMask == set([1, 3])
Exemple #29
0
 async def send(self, cmd: Message, timeout: int = 3) -> bool:
     self._sent.append(cmd)
     for msg, reply in self._replies:
         if msg.hid() == cmd.hid():
             await self.handleMessage(reply, 0)
             break