# Copyright (c) 2010 - 2017, Nordic Semiconductor ASA
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of Nordic Semiconductor ASA nor the names of its
#    contributors may be used to endorse or promote products derived from this
#    software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# This file was autogenerated by serial_doc_gen_pyaci.py at 2017-07-06 08:12:08.
from aci.aci_utils import EventPacket, barray_pop


class CmdRsp(EventPacket):
    """Command response."""
    def __init__(self, raw_data):
        __data = {}
        __data["opcode"] = barray_pop(raw_data, 1)
        __data["status"] = barray_pop(raw_data, 1)
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(CmdRsp, self).__init__("CmdRsp", 0x84, __data)


class DeviceStarted(EventPacket):
    """The device has started, and is ready for commands."""
    def __init__(self, raw_data):
        __data = {}
        __data["operating_mode"] = barray_pop(raw_data, 1)
        __data["hw_error"] = barray_pop(raw_data, 1)
        __data["data_credit_available"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(DeviceStarted, self).__init__("DeviceStarted", 0x81, __data)


class DeviceEchoRsp(EventPacket):
    """Response to the Echo command."""
    def __init__(self, raw_data):
        __data = {}
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(DeviceEchoRsp, self).__init__("DeviceEchoRsp", 0x82, __data)


class DeviceInternalEvent(EventPacket):
    """Internal stack event occurred."""
    def __init__(self, raw_data):
        __data = {}
        __data["event_type"] = barray_pop(raw_data, 1)
        __data["state"] = barray_pop(raw_data, 1)
        __data["packet_size"] = barray_pop(raw_data, 1)
        __data["packet"] = raw_data[:31]
        raw_data = raw_data[31:]
        assert(len(raw_data) == 0)
        super(DeviceInternalEvent, self).__init__("DeviceInternalEvent", 0x83, __data)


class Application(EventPacket):
    """Application event, only sent by the device application."""
    def __init__(self, raw_data):
        __data = {}
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(Application, self).__init__("Application", 0x8A, __data)


class SarStart(EventPacket):
    """Start of a Segmentation and Reassembly message from the device."""
    def __init__(self, raw_data):
        __data = {}
        super(SarStart, self).__init__("SarStart", 0x8B, __data)


class SarContinue(EventPacket):
    """Continuation of a Segmentation and Reassembly message from the
device."""
    def __init__(self, raw_data):
        __data = {}
        super(SarContinue, self).__init__("SarContinue", 0x8C, __data)


class DfuReqRelay(EventPacket):
    """Received a request from another device to act as a relay in a DFU
transaction."""
    def __init__(self, raw_data):
        __data = {}
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        __data["authority"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(DfuReqRelay, self).__init__("DfuReqRelay", 0xA0, __data)


class DfuReqSource(EventPacket):
    """Recevied a request from another device to act as a source in a
DFU transaction."""
    def __init__(self, raw_data):
        __data = {}
        __data["dfu_type"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(DfuReqSource, self).__init__("DfuReqSource", 0xA1, __data)


class DfuStart(EventPacket):
    """The current DFU operation started its data transfer stage."""
    def __init__(self, raw_data):
        __data = {}
        __data["role"] = barray_pop(raw_data, 1)
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        assert(len(raw_data) == 0)
        super(DfuStart, self).__init__("DfuStart", 0xA2, __data)


class DfuEnd(EventPacket):
    """The current DFU operation ended its data transfer stage."""
    def __init__(self, raw_data):
        __data = {}
        __data["role"] = barray_pop(raw_data, 1)
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        __data["end_reason"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(DfuEnd, self).__init__("DfuEnd", 0xA3, __data)


class DfuBankAvailable(EventPacket):
    """A DFU firmware bank is available for flashing."""
    def __init__(self, raw_data):
        __data = {}
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        __data["start_addr"] = barray_pop(raw_data, 4)
        __data["length"] = barray_pop(raw_data, 4)
        __data["is_signed"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(DfuBankAvailable, self).__init__("DfuBankAvailable", 0xA4, __data)


class DfuFirmwareOutdated(EventPacket):
    """The mesh has received a secure notification indicating that the
framework is out of date. Call _DFU Request_ to initiate a
request to receive the firmware upgrade."""
    def __init__(self, raw_data):
        __data = {}
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["available_fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        __data["current_fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        assert(len(raw_data) == 0)
        super(DfuFirmwareOutdated, self).__init__("DfuFirmwareOutdated", 0xA5, __data)


class DfuFirmwareOutdatedNoAuth(EventPacket):
    """The mesh has received an insecure notification indicating that
the framework is out of date. Call _Direct Firmware Upgrade
Request_ to initiate a request to receive the firmware upgrade."""
    def __init__(self, raw_data):
        __data = {}
        __data["dfu_type"] = barray_pop(raw_data, 1)
        __data["available_fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        __data["current_fwid"] = raw_data[:10]
        raw_data = raw_data[10:]
        assert(len(raw_data) == 0)
        super(DfuFirmwareOutdatedNoAuth, self).__init__("DfuFirmwareOutdatedNoAuth", 0xA6, __data)


class OpenmeshNew(EventPacket):
    """Not implemented."""
    def __init__(self, raw_data):
        __data = {}
        super(OpenmeshNew, self).__init__("OpenmeshNew", 0xB3, __data)


class OpenmeshUpdate(EventPacket):
    """Not implemented."""
    def __init__(self, raw_data):
        __data = {}
        super(OpenmeshUpdate, self).__init__("OpenmeshUpdate", 0xB4, __data)


class OpenmeshConflicting(EventPacket):
    """Not implemented."""
    def __init__(self, raw_data):
        __data = {}
        super(OpenmeshConflicting, self).__init__("OpenmeshConflicting", 0xB5, __data)


class OpenmeshTx(EventPacket):
    """Not implemented."""
    def __init__(self, raw_data):
        __data = {}
        super(OpenmeshTx, self).__init__("OpenmeshTx", 0xB6, __data)


class ProvUnprovisionedReceived(EventPacket):
    """The node received an unprovisioned beacon."""
    def __init__(self, raw_data):
        __data = {}
        __data["uuid"] = raw_data[:16]
        raw_data = raw_data[16:]
        __data["rssi"] = barray_pop(raw_data, 1)
        __data["gatt_supported"] = barray_pop(raw_data, 1)
        __data["adv_addr_type"] = barray_pop(raw_data, 1)
        __data["adv_addr"] = raw_data[:6]
        raw_data = raw_data[6:]
        assert(len(raw_data) == 0)
        super(ProvUnprovisionedReceived, self).__init__("ProvUnprovisionedReceived", 0xC0, __data)


class ProvLinkEstablished(EventPacket):
    """The given provisioning link has been established."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(ProvLinkEstablished, self).__init__("ProvLinkEstablished", 0xC1, __data)


class ProvLinkClosed(EventPacket):
    """The given provisioning link has been closed."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["close_reason"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(ProvLinkClosed, self).__init__("ProvLinkClosed", 0xC2, __data)


class ProvCapsReceived(EventPacket):
    """The device received provisioning capabilities on the provisioning
link with the given context ID."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["num_elements"] = barray_pop(raw_data, 1)
        __data["public_key_type"] = barray_pop(raw_data, 1)
        __data["static_oob_types"] = barray_pop(raw_data, 1)
        __data["output_oob_size"] = barray_pop(raw_data, 1)
        __data["output_oob_actions"] = barray_pop(raw_data, 2)
        __data["input_oob_size"] = barray_pop(raw_data, 1)
        __data["input_oob_actions"] = barray_pop(raw_data, 2)
        assert(len(raw_data) == 0)
        super(ProvCapsReceived, self).__init__("ProvCapsReceived", 0xC3, __data)


class ProvComplete(EventPacket):
    """The provisioning process was successfully completed."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["iv_index"] = barray_pop(raw_data, 4)
        __data["net_key_index"] = barray_pop(raw_data, 2)
        __data["address"] = barray_pop(raw_data, 2)
        __data["device_key"] = raw_data[:16]
        raw_data = raw_data[16:]
        __data["net_key"] = raw_data[:16]
        raw_data = raw_data[16:]
        assert(len(raw_data) == 0)
        super(ProvComplete, self).__init__("ProvComplete", 0xC5, __data)


class ProvAuthRequest(EventPacket):
    """Static authentication data is required to continue."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["method"] = barray_pop(raw_data, 1)
        __data["action"] = barray_pop(raw_data, 1)
        __data["size"] = barray_pop(raw_data, 1)
        assert(len(raw_data) == 0)
        super(ProvAuthRequest, self).__init__("ProvAuthRequest", 0xC6, __data)


class ProvEcdhRequest(EventPacket):
    """An ECDH shared secret must be calculated."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["peer_public"] = raw_data[:64]
        raw_data = raw_data[64:]
        __data["node_private"] = raw_data[:32]
        raw_data = raw_data[32:]
        assert(len(raw_data) == 0)
        super(ProvEcdhRequest, self).__init__("ProvEcdhRequest", 0xC7, __data)


class ProvOutputRequest(EventPacket):
    """The device is required to do an action the user can recognize and
use for authentication."""
    def __init__(self, raw_data):
        __data = {}
        __data["context_id"] = barray_pop(raw_data, 1)
        __data["output_action"] = barray_pop(raw_data, 1)
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(ProvOutputRequest, self).__init__("ProvOutputRequest", 0xC8, __data)


class MeshMessageReceivedUnicast(EventPacket):
    """The mesh framework received a message matching a registered local
unicast address, with the given parameters and data."""
    def __init__(self, raw_data):
        __data = {}
        __data["src"] = barray_pop(raw_data, 2)
        __data["dst"] = barray_pop(raw_data, 2)
        __data["appkey_handle"] = barray_pop(raw_data, 2)
        __data["subnet_handle"] = barray_pop(raw_data, 2)
        __data["ttl"] = barray_pop(raw_data, 1)
        __data["adv_addr_type"] = barray_pop(raw_data, 1)
        __data["adv_addr"] = raw_data[:6]
        raw_data = raw_data[6:]
        __data["rssi"] = barray_pop(raw_data, 1)
        __data["actual_length"] = barray_pop(raw_data, 2)
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(MeshMessageReceivedUnicast, self).__init__("MeshMessageReceivedUnicast", 0xD0, __data)


class MeshMessageReceivedSubscription(EventPacket):
    """The mesh framework received a message matching one of the
registered subscription addresses, with the given parameters and
data."""
    def __init__(self, raw_data):
        __data = {}
        __data["src"] = barray_pop(raw_data, 2)
        __data["dst"] = barray_pop(raw_data, 2)
        __data["appkey_handle"] = barray_pop(raw_data, 2)
        __data["subnet_handle"] = barray_pop(raw_data, 2)
        __data["ttl"] = barray_pop(raw_data, 1)
        __data["adv_addr_type"] = barray_pop(raw_data, 1)
        __data["adv_addr"] = raw_data[:6]
        raw_data = raw_data[6:]
        __data["rssi"] = barray_pop(raw_data, 1)
        __data["actual_length"] = barray_pop(raw_data, 2)
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(MeshMessageReceivedSubscription, self).__init__("MeshMessageReceivedSubscription", 0xD1, __data)


class MeshTxComplete(EventPacket):
    """A radio packet TX has completed."""
    def __init__(self, raw_data):
        __data = {}
        super(MeshTxComplete, self).__init__("MeshTxComplete", 0xD2, __data)


class MeshIvUpdateNotification(EventPacket):
    """The IV update procedure has been triggered for the network with
the given index."""
    def __init__(self, raw_data):
        __data = {}
        __data["iv_index"] = barray_pop(raw_data, 4)
        assert(len(raw_data) == 0)
        super(MeshIvUpdateNotification, self).__init__("MeshIvUpdateNotification", 0xD3, __data)


class MeshKeyRefreshStart(EventPacket):
    """The key refresh procedure has been started for the network with
the given index."""
    def __init__(self, raw_data):
        __data = {}
        super(MeshKeyRefreshStart, self).__init__("MeshKeyRefreshStart", 0xD5, __data)


class MeshKeyRefreshEnd(EventPacket):
    """The key refresh procedure has ended for the network with the
given index."""
    def __init__(self, raw_data):
        __data = {}
        super(MeshKeyRefreshEnd, self).__init__("MeshKeyRefreshEnd", 0xD6, __data)


class MeshSarFailed(EventPacket):
    """A Mesh transmission of a SAR packet failed."""
    def __init__(self, raw_data):
        __data = {}
        super(MeshSarFailed, self).__init__("MeshSarFailed", 0xD7, __data)


class ModelSpecific(EventPacket):
    """An event generated by one of the initialized models."""
    def __init__(self, raw_data):
        __data = {}
        __data["model_evt_info"] = raw_data[:5]
        raw_data = raw_data[5:]
        __data["data"] = raw_data[:len(raw_data)]
        raw_data = raw_data[len(raw_data):]
        assert(len(raw_data) == 0)
        super(ModelSpecific, self).__init__("ModelSpecific", 0xF0, __data)


class Event(object):
    APPLICATION = 0x8A
    CMD_RSP = 0x84
    DEVICE_ECHO_RSP = 0x82
    DEVICE_INTERNAL_EVENT = 0x83
    DEVICE_STARTED = 0x81
    DFU_BANK_AVAILABLE = 0xA4
    DFU_END = 0xA3
    DFU_FIRMWARE_OUTDATED = 0xA5
    DFU_FIRMWARE_OUTDATED_NO_AUTH = 0xA6
    DFU_REQ_RELAY = 0xA0
    DFU_REQ_SOURCE = 0xA1
    DFU_START = 0xA2
    MESH_IV_UPDATE_NOTIFICATION = 0xD3
    MESH_KEY_REFRESH_END = 0xD6
    MESH_KEY_REFRESH_START = 0xD5
    MESH_MESSAGE_RECEIVED_SUBSCRIPTION = 0xD1
    MESH_MESSAGE_RECEIVED_UNICAST = 0xD0
    MESH_SAR_FAILED = 0xD7
    MESH_TX_COMPLETE = 0xD2
    MODEL_SPECIFIC = 0xF0
    OPENMESH_CONFLICTING = 0xB5
    OPENMESH_NEW = 0xB3
    OPENMESH_TX = 0xB6
    OPENMESH_UPDATE = 0xB4
    PROV_AUTH_REQUEST = 0xC6
    PROV_CAPS_RECEIVED = 0xC3
    PROV_COMPLETE = 0xC5
    PROV_ECDH_REQUEST = 0xC7
    PROV_LINK_CLOSED = 0xC2
    PROV_LINK_ESTABLISHED = 0xC1
    PROV_OUTPUT_REQUEST = 0xC8
    PROV_UNPROVISIONED_RECEIVED = 0xC0
    SAR_CONTINUE = 0x8C
    SAR_START = 0x8B


EVENT_LUT = {
    Event.APPLICATION: Application,
    Event.CMD_RSP: CmdRsp,
    Event.DEVICE_ECHO_RSP: DeviceEchoRsp,
    Event.DEVICE_INTERNAL_EVENT: DeviceInternalEvent,
    Event.DEVICE_STARTED: DeviceStarted,
    Event.DFU_BANK_AVAILABLE: DfuBankAvailable,
    Event.DFU_END: DfuEnd,
    Event.DFU_FIRMWARE_OUTDATED: DfuFirmwareOutdated,
    Event.DFU_FIRMWARE_OUTDATED_NO_AUTH: DfuFirmwareOutdatedNoAuth,
    Event.DFU_REQ_RELAY: DfuReqRelay,
    Event.DFU_REQ_SOURCE: DfuReqSource,
    Event.DFU_START: DfuStart,
    Event.MESH_IV_UPDATE_NOTIFICATION: MeshIvUpdateNotification,
    Event.MESH_KEY_REFRESH_END: MeshKeyRefreshEnd,
    Event.MESH_KEY_REFRESH_START: MeshKeyRefreshStart,
    Event.MESH_MESSAGE_RECEIVED_SUBSCRIPTION: MeshMessageReceivedSubscription,
    Event.MESH_MESSAGE_RECEIVED_UNICAST: MeshMessageReceivedUnicast,
    Event.MESH_SAR_FAILED: MeshSarFailed,
    Event.MESH_TX_COMPLETE: MeshTxComplete,
    Event.MODEL_SPECIFIC: ModelSpecific,
    Event.OPENMESH_CONFLICTING: OpenmeshConflicting,
    Event.OPENMESH_NEW: OpenmeshNew,
    Event.OPENMESH_TX: OpenmeshTx,
    Event.OPENMESH_UPDATE: OpenmeshUpdate,
    Event.PROV_AUTH_REQUEST: ProvAuthRequest,
    Event.PROV_CAPS_RECEIVED: ProvCapsReceived,
    Event.PROV_COMPLETE: ProvComplete,
    Event.PROV_ECDH_REQUEST: ProvEcdhRequest,
    Event.PROV_LINK_CLOSED: ProvLinkClosed,
    Event.PROV_LINK_ESTABLISHED: ProvLinkEstablished,
    Event.PROV_OUTPUT_REQUEST: ProvOutputRequest,
    Event.PROV_UNPROVISIONED_RECEIVED: ProvUnprovisionedReceived,
    Event.SAR_CONTINUE: SarContinue,
    Event.SAR_START: SarStart
}


def event_deserialize(data):
    if not isinstance(data, bytearray):
        raise TypeError("Expected bytearray")

    if data[1] in EVENT_LUT:
        return EVENT_LUT[data[1]](data[2:])
    else:
        return None
