/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  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 the copyright holder 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 THE COPYRIGHT HOLDER 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.
 */

/**
 * @file
 * @brief
 *  This file implements the Tunnel mode (Thread Miniport) functions required for the OpenThread library.
 */

#include "precomp.h"
#include "tunnel.tmh"

KSTART_ROUTINE otLwfTunWorkerThread;

SPINEL_CMD_HANDLER otLwfIrpCommandHandler;

typedef struct _SPINEL_IRP_CMD_CONTEXT
{
    PMS_FILTER              pFilter;
    PIRP                    Irp;
    SPINEL_IRP_CMD_HANDLER *Handler;
    spinel_tid_t            tid;
} SPINEL_IRP_CMD_CONTEXT;

_IRQL_requires_max_(PASSIVE_LEVEL)
NDIS_STATUS 
otLwfTunInitialize(
    _In_ PMS_FILTER pFilter
    )
{
    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    HANDLE threadHandle = NULL;

    LogFuncEntry(DRIVER_DEFAULT);

    NT_ASSERT(pFilter->DeviceCapabilities & OTLWF_DEVICE_CAP_THREAD_1_0);
    
    KeInitializeEvent(
        &pFilter->TunWorkerThreadStopEvent,
        SynchronizationEvent, // auto-clearing event
        FALSE                 // event initially non-signalled
        );
    KeInitializeEvent(
        &pFilter->TunWorkerThreadAddressChangedEvent,
        SynchronizationEvent, // auto-clearing event
        FALSE                 // event initially non-signalled
        );

    // Start the worker thread
    Status = PsCreateSystemThread(
                &threadHandle,                  // ThreadHandle
                THREAD_ALL_ACCESS,              // DesiredAccess
                NULL,                           // ObjectAttributes
                NULL,                           // ProcessHandle
                NULL,                           // ClientId
                otLwfTunWorkerThread,           // StartRoutine
                pFilter                         // StartContext
                );
    if (!NT_SUCCESS(Status))
    {
        LogError(DRIVER_DEFAULT, "PsCreateSystemThread failed, %!STATUS!", Status);
        goto error;
    }

    // Grab the object reference to the worker thread
    Status = ObReferenceObjectByHandle(
                threadHandle,
                THREAD_ALL_ACCESS,
                *PsThreadType,
                KernelMode,
                &pFilter->TunWorkerThread,
                NULL
                );
    if (!NT_VERIFYMSG("ObReferenceObjectByHandle can't fail with a valid kernel handle", NT_SUCCESS(Status)))
    {
        LogError(DRIVER_DEFAULT, "ObReferenceObjectByHandle failed, %!STATUS!", Status);
        KeSetEvent(&pFilter->TunWorkerThreadStopEvent, IO_NO_INCREMENT, FALSE);
    }

    // Make sure to enable RLOC passthrough
    Status =
        otLwfCmdSetProp(
            pFilter,
            SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU,
            SPINEL_DATATYPE_BOOL_S,
            TRUE
        );
    if (!NT_SUCCESS(Status))
    {
        LogError(DRIVER_DEFAULT, "Enabling RLOC pass through failed, %!STATUS!", Status);
        goto error;
    }

    // TODO - Query other values and capabilities

error:

    if (!NT_SUCCESS(Status))
    {
        otLwfTunUninitialize(pFilter);
    }

    LogFuncExitNDIS(DRIVER_DEFAULT, Status);

    return Status;
}

_IRQL_requires_max_(PASSIVE_LEVEL)
void 
otLwfTunUninitialize(
    _In_ PMS_FILTER pFilter
    )
{
    LogFuncEntry(DRIVER_DEFAULT);

    // Clean up worker thread
    if (pFilter->TunWorkerThread)
    {
        LogInfo(DRIVER_DEFAULT, "Stopping tunnel worker thread and waiting for it to complete.");

        // Send event to shutdown worker thread
        KeSetEvent(&pFilter->TunWorkerThreadStopEvent, 0, FALSE);

        // Wait for worker thread to finish
        KeWaitForSingleObject(
            pFilter->TunWorkerThread,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        // Free worker thread
        ObDereferenceObject(pFilter->TunWorkerThread);
        pFilter->TunWorkerThread = NULL;

        LogInfo(DRIVER_DEFAULT, "Tunnel worker thread cleaned up.");
    }

    LogFuncExit(DRIVER_DEFAULT);
}

// Worker thread for processing all tunnel events
_Use_decl_annotations_
VOID
otLwfTunWorkerThread(
    PVOID   Context
    )
{
    PMS_FILTER pFilter = (PMS_FILTER)Context;
    NT_ASSERT(pFilter);

    LogFuncEntry(DRIVER_DEFAULT);

    PKEVENT WaitEvents[] = 
    { 
        &pFilter->TunWorkerThreadStopEvent,
        &pFilter->TunWorkerThreadAddressChangedEvent
    };

    LogFuncExit(DRIVER_DEFAULT);
    
    while (true)
    {
        // Wait for event to stop or process event to fire
        NTSTATUS status = 
            KeWaitForMultipleObjects(
                ARRAYSIZE(WaitEvents), 
                (PVOID*)WaitEvents, 
                WaitAny, 
                Executive, 
                KernelMode, 
                FALSE, 
                NULL, 
                NULL);

        // If it is the first event, then we are shutting down. Exit loop and terminate thread
        if (status == STATUS_WAIT_0)
        {
            LogInfo(DRIVER_DEFAULT, "Received tunnel worker thread shutdown event.");
            break;
        }
        else if (status == STATUS_WAIT_0 + 1) // TunWorkerThreadAddressChangedEvent fired
        {
            PVOID DataBuffer = NULL;
            const uint8_t* value_data_ptr = NULL;
            spinel_size_t value_data_len = 0;
            
            // Query the current addresses
            status = 
                otLwfCmdGetProp(
                    pFilter,
                    &DataBuffer,
                    SPINEL_PROP_IPV6_ADDRESS_TABLE,
                    SPINEL_DATATYPE_DATA_S,
                    &value_data_ptr,
                    &value_data_len);
            if (NT_SUCCESS(status))
            {
                uint32_t aNotifFlags = 0;
                otLwfTunAddressesUpdated(pFilter, value_data_ptr, value_data_len, &aNotifFlags);

                // Send notification
                if (aNotifFlags != 0)
                {
                    PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
                    if (NotifEntry)
                    {
                        RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
                        NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
                        NotifEntry->Notif.NotifType = OTLWF_NOTIF_STATE_CHANGE;
                        NotifEntry->Notif.StateChangePayload.Flags = aNotifFlags;

                        otLwfIndicateNotification(NotifEntry);
                    }
                }
            }
            else
            {
                LogWarning(DRIVER_DEFAULT, "Failed to query addresses, %!STATUS!", status);
            }

            if (DataBuffer) FILTER_FREE_MEM(DataBuffer);
        }
        else
        {
            LogWarning(DRIVER_DEFAULT, "Unexpected wait result, %!STATUS!", status);
        }
    }

    PsTerminateSystemThread(STATUS_SUCCESS);
}

_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
otLwfIrpCommandHandler(
    _In_ PMS_FILTER pFilter,
    _In_ PVOID Context,
    _In_ UINT Command,
    _In_ spinel_prop_key_t Key,
    _In_reads_bytes_(DataLength) const uint8_t* Data,
    _In_ spinel_size_t DataLength
    )
{
    SPINEL_IRP_CMD_CONTEXT* CmdContext = (SPINEL_IRP_CMD_CONTEXT*)Context;
    PIO_STACK_LOCATION  IrpSp = IoGetCurrentIrpStackLocation(CmdContext->Irp);
    
    ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
    PVOID OutBuffer = CmdContext->Irp->AssociatedIrp.SystemBuffer;
    ULONG OutBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
    ULONG OrigOutBufferLength = OutBufferLength;

    NTSTATUS status;

    UNREFERENCED_PARAMETER(pFilter);

    // Clear the cancel routine
    IoSetCancelRoutine(CmdContext->Irp, NULL);
    
    if (Data == NULL)
    {
        status = STATUS_CANCELLED;
        OutBufferLength = 0;
    }
    else if (Command == SPINEL_CMD_PROP_VALUE_IS && Key == SPINEL_PROP_LAST_STATUS)
    {
        spinel_status_t spinel_status = SPINEL_STATUS_OK;
        spinel_ssize_t packed_len = spinel_datatype_unpack(Data, DataLength, "i", &spinel_status);
        if (packed_len < 0 || (ULONG)packed_len > DataLength)
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else
        {
            status = ThreadErrorToNtstatus(SpinelStatusToThreadError(spinel_status));
        }
    }
    else if (CmdContext->Handler)
    {
        status = CmdContext->Handler(Key, Data, DataLength, OutBuffer, &OutBufferLength);
    }
    else // No handler, so no output
    {
        status = STATUS_SUCCESS;
        OutBufferLength = 0;
    }

    // Clear any leftover output buffer
    if (OutBufferLength < OrigOutBufferLength)
    {
        RtlZeroMemory((PUCHAR)OutBuffer + OutBufferLength, OrigOutBufferLength - OutBufferLength);
    }

    LogVerbose(DRIVER_IOCTL, "Completing Irp=%p, with %!STATUS! for %s (Out:%u)", 
                CmdContext->Irp, status, IoCtlString(IoControlCode), OutBufferLength);

    // Complete the IRP
    CmdContext->Irp->IoStatus.Information = OutBufferLength;
    CmdContext->Irp->IoStatus.Status = status;
    IoCompleteRequest(CmdContext->Irp, IO_NO_INCREMENT);

    FILTER_FREE_MEM(Context);
}

_Function_class_(DRIVER_CANCEL)
_Requires_lock_held_(_Global_cancel_spin_lock_)
_Releases_lock_(_Global_cancel_spin_lock_)
_IRQL_requires_min_(DISPATCH_LEVEL)
_IRQL_requires_(DISPATCH_LEVEL)
VOID
otLwfTunCancelIrp(
    _Inout_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ _IRQL_uses_cancel_ struct _IRP *Irp
    )
{
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    SPINEL_IRP_CMD_CONTEXT* CmdContext = (SPINEL_IRP_CMD_CONTEXT*)IrpStack->Context;

    UNREFERENCED_PARAMETER(DeviceObject);

    LogFuncEntryMsg(DRIVER_IOCTL, "Irp=%p", Irp);

    IoReleaseCancelSpinLock(Irp->CancelIrql);

    // Try to cancel pending command
    otLwfCmdCancel(
        CmdContext->pFilter, 
        (Irp->CancelIrql == DISPATCH_LEVEL) ? TRUE : FALSE, 
        CmdContext->tid);

    LogFuncExit(DRIVER_IOCTL);
}

_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfTunSendCommandForIrp(
    _In_ PMS_FILTER pFilter,
    _In_ PIRP Irp,
    _In_opt_ SPINEL_IRP_CMD_HANDLER *Handler,
    _In_ UINT Command,
    _In_ spinel_prop_key_t Key,
    _In_ ULONG MaxDataLength,
    _In_opt_ const char *pack_format, 
    ...
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    SPINEL_IRP_CMD_CONTEXT *pContext = NULL;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

    // Create the context structure
    pContext = FILTER_ALLOC_MEM(pFilter->FilterHandle, sizeof(SPINEL_IRP_CMD_CONTEXT));
    if (pContext == NULL)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        LogWarning(DRIVER_DEFAULT, "Failed to allocate irp cmd context");
        goto exit;
    }

    pContext->pFilter = pFilter;
    pContext->Irp = Irp;
    pContext->Handler = Handler;

    NT_ASSERT(IrpStack->Context == NULL);
    IrpStack->Context = pContext;

    // Set the cancel routine
    IoSetCancelRoutine(Irp, otLwfTunCancelIrp);
    
    va_list args;
    va_start(args, pack_format);
    status = 
        otLwfCmdSendAsyncV(
            pFilter, 
            otLwfIrpCommandHandler, 
            pContext, 
            &pContext->tid,
            Command, 
            Key, 
            MaxDataLength, 
            pack_format, 
            args);
    va_end(args);

    // Remove the handler entry from the list
    if (!NT_SUCCESS(status))
    {
        // Clear the cancel routine
        IoSetCancelRoutine(Irp, NULL);

        FILTER_FREE_MEM(pContext);
    }

exit:

    return status;
}

_IRQL_requires_max_(DISPATCH_LEVEL)
void
otLwfTunValueIs(
    _In_ PMS_FILTER pFilter,
    _In_ BOOLEAN DispatchLevel,
    _In_ spinel_prop_key_t key,
    _In_reads_bytes_(value_data_len) const uint8_t* value_data_ptr,
    _In_ spinel_size_t value_data_len
    )
{
    uint32_t aNotifFlags = 0;

    LogFuncEntryMsg(DRIVER_DEFAULT, "[%p] received Value for %s", pFilter, spinel_prop_key_to_cstr(key));

    if (key == SPINEL_PROP_NET_ROLE)
    {
        uint8_t value;
        spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT8_S, &value);

        LogInfo(DRIVER_DEFAULT, "Interface %!GUID! new spinel role: %u", &pFilter->InterfaceGuid, value);

        // Make sure we are in the correct media connect state
        otLwfIndicateLinkState(
            pFilter,
            value > SPINEL_NET_ROLE_DETACHED ?
            MediaConnectStateConnected :
            MediaConnectStateDisconnected);

        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_ROLE;
    }
    else if (key == SPINEL_PROP_IPV6_LL_ADDR)
    {
        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_LL_ADDR;
    }
    else if (key == SPINEL_PROP_IPV6_ML_ADDR)
    {
        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_ML_ADDR;
    }
    else if (key == SPINEL_PROP_NET_PARTITION_ID)
    {
        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_PARTITION_ID;
    }
    else if (key == SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER)
    {
        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER;
    }
    else if (key == SPINEL_PROP_IPV6_ADDRESS_TABLE)
    {
        KeSetEvent(&pFilter->TunWorkerThreadAddressChangedEvent, IO_NO_INCREMENT, FALSE);
    }
    else if (key == SPINEL_PROP_THREAD_CHILD_TABLE)
    {
        // TODO - Update cached children
        // TODO - Send notification
    }
    else if (key == SPINEL_PROP_THREAD_ON_MESH_NETS)
    {
        // TODO - Slaac

        // Set flag to indicate we should send a notification
        aNotifFlags = OT_CHANGED_THREAD_NETDATA;
    }
    else if ((key == SPINEL_PROP_STREAM_NET) || (key == SPINEL_PROP_STREAM_NET_INSECURE))
    {
        const uint8_t* frame_ptr = NULL;
        UINT frame_len = 0;
        spinel_ssize_t ret;

        ret = spinel_datatype_unpack(
            value_data_ptr,
            value_data_len,
            SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_S,
            &frame_ptr,
            &frame_len,
            NULL,
            NULL);

        NT_ASSERT(ret > 0);
        if (ret > 0)
        {
            otLwfTunReceiveIp6Packet(
                pFilter,
                DispatchLevel,
                (SPINEL_PROP_STREAM_NET_INSECURE == key) ? FALSE : TRUE,
                frame_ptr,
                frame_len);
        }
    }
    else if (key == SPINEL_PROP_MAC_SCAN_STATE)
    {
        // TODO - If pending scan, send notification of completion
    }
    else if (key == SPINEL_PROP_STREAM_RAW)
    {
        // May be used in the future
    }
    else if (key == SPINEL_PROP_STREAM_DEBUG)
    {
        const uint8_t* output = NULL;
        UINT output_len = 0;
        spinel_ssize_t ret;

        ret = spinel_datatype_unpack(
            value_data_ptr,
            value_data_len,
            SPINEL_DATATYPE_DATA_S,
            &output,
            &output_len);

        NT_ASSERT(ret > 0);
        if (ret > 0 && output && output_len <= (UINT)ret)
        {
            if (strnlen((char*)output, output_len) != output_len)
            {
                LogInfo(DRIVER_DEFAULT, "DEVICE: %s", (char*)output);
            }
            else if (output_len < 128)
            {
                char strOutput[128] = { 0 };
                memcpy(strOutput, output, output_len);
                LogInfo(DRIVER_DEFAULT, "DEVICE: %s", strOutput);
            }
        }
    }

    // Send notification
    if (aNotifFlags != 0)
    {
        PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
        if (NotifEntry)
        {
            RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
            NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
            NotifEntry->Notif.NotifType = OTLWF_NOTIF_STATE_CHANGE;
            NotifEntry->Notif.StateChangePayload.Flags = aNotifFlags;

            otLwfIndicateNotification(NotifEntry);
        }
    }

    LogFuncExit(DRIVER_DEFAULT);
}

_IRQL_requires_max_(DISPATCH_LEVEL)
void
otLwfTunValueInserted(
    _In_ PMS_FILTER pFilter,
    _In_ BOOLEAN DispatchLevel,
    _In_ spinel_prop_key_t key,
    _In_reads_bytes_(value_data_len) const uint8_t* value_data_ptr,
    _In_ spinel_size_t value_data_len
    )
{
    LogFuncEntryMsg(DRIVER_DEFAULT, "[%p] received Value Inserted for %s", pFilter, spinel_prop_key_to_cstr(key));

    UNREFERENCED_PARAMETER(pFilter);
    UNREFERENCED_PARAMETER(DispatchLevel);
    UNREFERENCED_PARAMETER(value_data_ptr);
    UNREFERENCED_PARAMETER(value_data_len);

    if (key == SPINEL_PROP_MAC_SCAN_BEACON)
    {
        PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
        if (NotifEntry)
        {
            RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
            NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
            NotifEntry->Notif.NotifType = OTLWF_NOTIF_ACTIVE_SCAN;
            NotifEntry->Notif.ActiveScanPayload.Valid = TRUE;

            const uint8_t *aExtAddr = NULL;
            const uint8_t *aExtPanId = NULL;
            const char *aNetworkName = NULL;
            unsigned int xpanid_len = 0;

            if (try_spinel_datatype_unpack(
                value_data_ptr,
                value_data_len,
                SPINEL_DATATYPE_MAC_SCAN_RESULT_S(
                    SPINEL_802_15_4_DATATYPE_MAC_SCAN_RESULT_V1_S,
                    SPINEL_NET_DATATYPE_MAC_SCAN_RESULT_V1_S
                ),
                &NotifEntry->Notif.ActiveScanPayload.Results.mChannel,
                &NotifEntry->Notif.ActiveScanPayload.Results.mRssi,
                &aExtAddr,
                NULL, // saddr (don't care)
                &NotifEntry->Notif.ActiveScanPayload.Results.mPanId,
                &NotifEntry->Notif.ActiveScanPayload.Results.mLqi,
                NULL, // proto (don't care)
                NULL, // flags (don't care)
                &aNetworkName,
                &aExtPanId,
                &xpanid_len
            ) &&
                aExtAddr != NULL && aExtPanId != NULL && aNetworkName != NULL &&
                xpanid_len == OT_EXT_PAN_ID_SIZE)
            {
                memcpy_s(NotifEntry->Notif.ActiveScanPayload.Results.mExtAddress.m8,
                    sizeof(NotifEntry->Notif.ActiveScanPayload.Results.mExtAddress.m8),
                    aExtAddr, sizeof(otExtAddress));
                memcpy_s(NotifEntry->Notif.ActiveScanPayload.Results.mExtendedPanId.m8,
                    sizeof(NotifEntry->Notif.ActiveScanPayload.Results.mExtendedPanId.m8),
                    aExtPanId, sizeof(otExtendedPanId));
                strcpy_s(NotifEntry->Notif.ActiveScanPayload.Results.mNetworkName.m8,
                    sizeof(NotifEntry->Notif.ActiveScanPayload.Results.mNetworkName.m8),
                    aNetworkName);
                otLwfIndicateNotification(NotifEntry);
            }
            else
            {
                FILTER_FREE_MEM(NotifEntry);
            }
        }
    }
    else if (key == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT)
    {
        PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
        if (NotifEntry)
        {
            RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
            NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
            NotifEntry->Notif.NotifType = OTLWF_NOTIF_ENERGY_SCAN;
            NotifEntry->Notif.EnergyScanPayload.Valid = TRUE;

            if (try_spinel_datatype_unpack(
                value_data_ptr,
                value_data_len,
                "Cc",
                &NotifEntry->Notif.EnergyScanPayload.Results.mChannel,
                &NotifEntry->Notif.EnergyScanPayload.Results.mMaxRssi
            ))
            {
                otLwfIndicateNotification(NotifEntry);
            }
            else
            {
                FILTER_FREE_MEM(NotifEntry);
            }
        }
    }

    LogFuncExit(DRIVER_DEFAULT);
}
