Exemplo n.º 1
0
    def frame_received(self, data):
        """Handle a received EZSP frame

        The protocol has taken care of UART specific framing etc, so we should
        just have EZSP application stuff here, with all escaping/stuffing and
        data randomization removed.
        """
        sequence, frame_id, data = data[0], data[2], data[3:]
        if frame_id == 0xFF:
            frame_id = 0
            if len(data) > 1:
                frame_id = data[1]
                data = data[2:]

        frame_name = self.COMMANDS_BY_ID[frame_id][0]
        LOGGER.debug(
            "Application frame %s (%s) received",
            frame_id,
            frame_name,
        )

        if sequence in self._awaiting:
            expected_id, schema, future = self._awaiting.pop(sequence)
            assert expected_id == frame_id
            result, data = t.deserialize(data, schema)
            future.set_result(result)
        else:
            schema = self.COMMANDS_BY_ID[frame_id][2]
            frame_name = self.COMMANDS_BY_ID[frame_id][0]
            result, data = t.deserialize(data, schema)
            self.handle_callback(frame_name, result)

        if frame_id == 0x00:
            self.ezsp_version = result[0]
Exemplo n.º 2
0
    def frame_received(self, data):
        """Handle a received EZSP frame

        The protocol has taken care of UART specific framing etc, so we should
        just have EZSP application stuff here, with all escaping/stuffing and
        data randomization removed.
        """
        sequence, frame_id, data = data[0], data[2], data[3:]
        if frame_id == 0xFF:
            frame_id = 0
            if len(data) > 1:
                frame_id = data[1]
                data = data[2:]

        frame_name = self.COMMANDS_BY_ID[frame_id][0]
        LOGGER.debug(
            "Application frame %s (%s) received: %s",
            frame_id,
            frame_name,
            binascii.hexlify(data),
        )

        if sequence in self._awaiting:
            expected_id, schema, future = self._awaiting.pop(sequence)
            assert expected_id == frame_id
            result, data = t.deserialize(data, schema)
            try:
                future.set_result(result)
            except asyncio.InvalidStateError:
                LOGGER.debug(
                    "Error processing %s response. %s command timed out?",
                    sequence,
                    self.COMMANDS_BY_ID.get(expected_id, [expected_id])[0],
                )
        else:
            schema = self.COMMANDS_BY_ID[frame_id][2]
            frame_name = self.COMMANDS_BY_ID[frame_id][0]
            result, data = t.deserialize(data, schema)
            self.handle_callback(frame_name, result)
Exemplo n.º 3
0
def deserialize(aps_frame, data):
    frame_control, data = data[0], data[1:]
    frame_type = frame_control & 0b0011
    direction = (frame_control & 0b1000) >> 3
    if frame_control & 0b0100:
        # Manufacturer specific value present
        data = data[2:]
    tsn, command_id, data = data[0], data[1], data[2:]

    is_reply = bool(direction)

    if frame_type == 1:
        # Cluster command
        if aps_frame.clusterId not in Cluster._registry:
            LOGGER.debug("Ignoring unknown cluster ID 0x%04x",
                         aps_frame.clusterId)
            return tsn, command_id + 256, is_reply, data
        cluster = Cluster._registry[aps_frame.clusterId]
        # Cluster-specific command

        if direction:
            commands = cluster.client_commands
        else:
            commands = cluster.server_commands

        try:
            schema = commands[command_id][1]
            is_reply = commands[command_id][2]
        except KeyError:
            LOGGER.warning("Unknown cluster-specific command %s", command_id)
            return tsn, command_id + 256, is_reply, data

        # Bad hack to differentiate foundation vs cluster
        command_id = command_id + 256
    else:
        # General command
        try:
            schema = foundation.COMMANDS[command_id][1]
            is_reply = foundation.COMMANDS[command_id][2]
        except KeyError:
            LOGGER.warning("Unknown foundation command %s", command_id)
            return tsn, command_id, is_reply, data

    value, data = t.deserialize(data, schema)
    if data != b'':
        # TODO: Seems sane to check, but what should we do?
        LOGGER.warning("Data remains after deserializing ZCL frame")

    return tsn, command_id, is_reply, value
Exemplo n.º 4
0
def deserialize(cluster_id, data):
    tsn, data = data[0], data[1:]

    is_reply = bool(cluster_id & 0x8000)
    try:
        cluster_details = types.CLUSTERS[cluster_id]
    except KeyError:
        LOGGER.warning("Unknown ZDO cluster 0x%02x", cluster_id)
        return tsn, cluster_id, is_reply, data

    args, data = t.deserialize(data, cluster_details[2])
    if data != b'':
        # TODO: Seems sane to check, but what should we do?
        LOGGER.warning("Data remains after deserializing ZDO frame")

    return tsn, cluster_id, is_reply, args