/*
 *  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.
 */

#include "precomp.h"
#include "otApi.tmh"

//#define DEBUG_ASYNC_IO

using namespace std;

// The maximum time we will wait for an overlapped result. Essentially, the maximum
// amount of time each synchronous IOCTL should take.
const DWORD c_MaxOverlappedWaitTimeMS = 5 * 1000;

// Version string returned by the API
const char c_Version[] = "Windows"; // TODO - What should we really put here?

template<class CallbackT>
class otCallback
{
public:
    RTL_REFERENCE_COUNT CallbackRefCount;
    HANDLE              CallbackCompleteEvent;
    GUID                InterfaceGuid;
    CallbackT           Callback;
    PVOID               CallbackContext;

    otCallback(
        CallbackT _Callback,
        PVOID _CallbackContext
        ) : 
        CallbackRefCount(1),
        CallbackCompleteEvent(CreateEvent(nullptr, FALSE, FALSE, nullptr)),
        Callback(_Callback),
        CallbackContext(_CallbackContext)
    {
    }

    otCallback(
        const GUID& _InterfaceGuid,
        CallbackT _Callback,
        PVOID _CallbackContext
        ) : 
        CallbackRefCount(1),
        CallbackCompleteEvent(CreateEvent(nullptr, FALSE, FALSE, nullptr)),
        InterfaceGuid(_InterfaceGuid),
        Callback(_Callback),
        CallbackContext(_CallbackContext)
    {
    }

    ~otCallback()
    {
        if (CallbackCompleteEvent) CloseHandle(CallbackCompleteEvent);
    }

    void AddRef()
    {
        RtlIncrementReferenceCount(&CallbackRefCount);
    }

    void Release(bool waitForShutdown = false)
    {
        if (RtlDecrementReferenceCount(&CallbackRefCount))
        {
            // Set completion event if there are no more refs
            SetEvent(CallbackCompleteEvent);
        }

        if (waitForShutdown)
        {
            WaitForSingleObject(CallbackCompleteEvent, INFINITE);
        }
    }
};

typedef otCallback<otDeviceAvailabilityChangedCallback> otApiDeviceAvailabilityCallback;
typedef otCallback<otHandleActiveScanResult> otApiActiveScanCallback;
typedef otCallback<otHandleEnergyScanResult> otApiEnergyScanCallback;
typedef otCallback<otStateChangedCallback> otApiStateChangeCallback;
typedef otCallback<otCommissionerEnergyReportCallback> otApiCommissionerEnergyReportCallback;
typedef otCallback<otCommissionerPanIdConflictCallback> otApiCommissionerPanIdConflictCallback;
typedef otCallback<otJoinerCallback> otApiJoinerCallback;

typedef struct otApiInstance
{
    // Handle to the driver
    HANDLE                      DeviceHandle;

    // Async IO variables
    OVERLAPPED                  Overlapped;
    PTP_WAIT                    ThreadpoolWait;

    // Notification variables
    CRITICAL_SECTION            CallbackLock;
    OTLWF_NOTIFICATION          NotificationBuffer;

    // Callbacks
    otApiDeviceAvailabilityCallback*    DeviceAvailabilityCallbacks;
    vector<otApiActiveScanCallback*>    ActiveScanCallbacks;
    vector<otApiEnergyScanCallback*>    EnergyScanCallbacks;
    vector<otApiActiveScanCallback*>    DiscoverCallbacks;
    vector<otApiStateChangeCallback*>   StateChangedCallbacks;
    vector<otApiCommissionerEnergyReportCallback*>  CommissionerEnergyReportCallbacks;
    vector<otApiCommissionerPanIdConflictCallback*> CommissionerPanIdConflictCallbacks;
    vector<otApiJoinerCallback*>        JoinerCallbacks;

    // Constructor
    otApiInstance() : 
        DeviceHandle(INVALID_HANDLE_VALUE),
        Overlapped({0}),
        ThreadpoolWait(nullptr),
        DeviceAvailabilityCallbacks(nullptr)
    { 
        InitializeCriticalSection(&CallbackLock);
    }

    ~otApiInstance()
    {
        DeleteCriticalSection(&CallbackLock);
    }

    // Helper function to set a callback
    template<class CallbackT>
    bool 
    SetCallback(
        vector<otCallback<CallbackT>*> &Callbacks, 
        const GUID& InterfaceGuid,
        CallbackT Callback,
        PVOID CallbackContext
        )
    {
        bool alreadyExists = false;
        otCallback<CallbackT>* CallbackToRelease = nullptr;

        EnterCriticalSection(&CallbackLock);

        if (Callback == nullptr)
        {
            for (size_t i = 0; i < Callbacks.size(); i++)
            {
                if (Callbacks[i]->InterfaceGuid == InterfaceGuid)
                {
                    CallbackToRelease = Callbacks[i];
                    Callbacks.erase(Callbacks.begin() + i);
                    break;
                }
            }
        }
        else
        {
            for (size_t i = 0; i < Callbacks.size(); i++)
            {
                if (Callbacks[i]->InterfaceGuid == InterfaceGuid)
                {
                    alreadyExists = true;
                    break;
                }
            }

            if (!alreadyExists)
            {
                Callbacks.push_back(new otCallback<CallbackT>(InterfaceGuid, Callback, CallbackContext));
            }
        }

        LeaveCriticalSection(&CallbackLock);

        if (CallbackToRelease)
        {
            CallbackToRelease->Release(true);
            delete CallbackToRelease;
        }

        return !alreadyExists;
    }

} otApiInstance;

typedef struct otInstance
{
    otApiInstance   *ApiHandle;      // Pointer to the Api handle
    NET_IFINDEX      InterfaceIndex; // Interface Index
    NET_LUID         InterfaceLuid;  // Interface Luid
    GUID             InterfaceGuid;  // Interface guid
    ULONG            CompartmentID;  // Interface Compartment ID

} otInstance;

// otpool wait callback for async IO completion
VOID CALLBACK 
otIoComplete(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context,
    _Inout_     PTP_WAIT              Wait,
    _In_        TP_WAIT_RESULT        WaitResult
    );

OTAPI 
otApiInstance *
OTCALL
otApiInit(
    )
{
    DWORD dwError = ERROR_SUCCESS;
    otApiInstance *aApitInstance = nullptr;
    
    LogFuncEntry(API_DEFAULT);

    aApitInstance = new(std::nothrow)otApiInstance();
    if (aApitInstance == nullptr)
    {
        dwError = GetLastError();
        LogWarning(API_DEFAULT, "Failed to allocate otApiInstance");
        goto error;
    }

    // Open the pipe to the OpenThread driver
    aApitInstance->DeviceHandle = 
        CreateFile(
            OTLWF_IOCLT_PATH,
            GENERIC_READ | GENERIC_WRITE,
            0,
            nullptr,                // no SECURITY_ATTRIBUTES structure
            OPEN_EXISTING,          // No special create flags
            FILE_FLAG_OVERLAPPED,   // Allow asynchronous requests
            nullptr
            );
    if (aApitInstance->DeviceHandle == INVALID_HANDLE_VALUE)
    {
        dwError = GetLastError();
        LogError(API_DEFAULT, "CreateFile failed, %!WINERROR!", dwError);
        goto error;
    }

    // Create event for completion of async IO
    aApitInstance->Overlapped.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    if (aApitInstance->Overlapped.hEvent == nullptr)
    {
        dwError = GetLastError();
        LogError(API_DEFAULT, "CreateEvent (Overlapped.hEvent) failed, %!WINERROR!", dwError);
        goto error;
    }

    // Create the otpool wait
    aApitInstance->ThreadpoolWait = 
        CreateThreadpoolWait(
            otIoComplete,
            aApitInstance,
            nullptr
            );
    if (aApitInstance->ThreadpoolWait == nullptr)
    {
        dwError = GetLastError();
        LogError(API_DEFAULT, "CreateThreadpoolWait failed, %!WINERROR!", dwError);
        goto error;
    }

    // Start the otpool waiting on the overlapped event
    SetThreadpoolWait(aApitInstance->ThreadpoolWait, aApitInstance->Overlapped.hEvent, nullptr);

#ifdef DEBUG_ASYNC_IO
    LogVerbose(API_DEFAULT, "Querying for 1st notification");
#endif

    // Request first notification asynchronously
    if (!DeviceIoControl(
            aApitInstance->DeviceHandle,
            IOCTL_OTLWF_QUERY_NOTIFICATION,
            nullptr, 0,
            &aApitInstance->NotificationBuffer, sizeof(OTLWF_NOTIFICATION),
            nullptr, 
            &aApitInstance->Overlapped))
    {
        dwError = GetLastError();
        if (dwError != ERROR_IO_PENDING)
        {
            LogError(API_DEFAULT, "DeviceIoControl for first notification failed, %!WINERROR!", dwError);
            goto error;
        }
        dwError = ERROR_SUCCESS;
    }

error:

    if (dwError != ERROR_SUCCESS)
    {
        otApiFinalize(aApitInstance);
        aApitInstance = nullptr;
    }
    
    LogFuncExit(API_DEFAULT);

    return aApitInstance;
}

OTAPI 
void 
OTCALL
otApiFinalize(
    _In_ otApiInstance *aApitInstance
)
{
    if (aApitInstance == nullptr) return;
    
    LogFuncEntry(API_DEFAULT);

    // If we never got the handle, nothing left to clean up
    if (aApitInstance->DeviceHandle != INVALID_HANDLE_VALUE)
    {
        //
        // Make sure we unregister callbacks
        //

        EnterCriticalSection(&aApitInstance->CallbackLock);

        otApiDeviceAvailabilityCallback* DeviceAvailabilityCallbacks = aApitInstance->DeviceAvailabilityCallbacks;
        aApitInstance->DeviceAvailabilityCallbacks = nullptr;

        vector<otApiActiveScanCallback*> ActiveScanCallbacks(aApitInstance->ActiveScanCallbacks);
        aApitInstance->ActiveScanCallbacks.clear();

        vector<otApiEnergyScanCallback*> EnergyScanCallbacks(aApitInstance->EnergyScanCallbacks);
        aApitInstance->EnergyScanCallbacks.clear();

        vector<otApiActiveScanCallback*> DiscoverCallbacks(aApitInstance->DiscoverCallbacks);
        aApitInstance->DiscoverCallbacks.clear();

        vector<otApiStateChangeCallback*> StateChangedCallbacks(aApitInstance->StateChangedCallbacks);
        aApitInstance->StateChangedCallbacks.clear();

        vector<otApiCommissionerEnergyReportCallback*> CommissionerEnergyReportCallbacks(aApitInstance->CommissionerEnergyReportCallbacks);
        aApitInstance->CommissionerEnergyReportCallbacks.clear();

        vector<otApiCommissionerPanIdConflictCallback*> CommissionerPanIdConflictCallbacks(aApitInstance->CommissionerPanIdConflictCallbacks);
        aApitInstance->CommissionerPanIdConflictCallbacks.clear();

        vector<otApiJoinerCallback*> JoinerCallbacks(aApitInstance->JoinerCallbacks);
        aApitInstance->JoinerCallbacks.clear();

        #ifdef DEBUG_ASYNC_IO
        LogVerbose(API_DEFAULT, "Clearing Threadpool Wait");
        #endif

        // Clear the threadpool wait to prevent further waits from being scheduled
        PTP_WAIT tpWait = aApitInstance->ThreadpoolWait;
        aApitInstance->ThreadpoolWait = nullptr;

        LeaveCriticalSection(&aApitInstance->CallbackLock);

        // Clear all callbacks
        if (DeviceAvailabilityCallbacks)
        {
            DeviceAvailabilityCallbacks->Release(true);
            delete DeviceAvailabilityCallbacks;
        }
        for (size_t i = 0; i < ActiveScanCallbacks.size(); i++)
        {
            ActiveScanCallbacks[i]->Release(true);
            delete ActiveScanCallbacks[i];
        }
        for (size_t i = 0; i < EnergyScanCallbacks.size(); i++)
        {
            EnergyScanCallbacks[i]->Release(true);
            delete EnergyScanCallbacks[i];
        }
        for (size_t i = 0; i < DiscoverCallbacks.size(); i++)
        {
            DiscoverCallbacks[i]->Release(true);
            delete DiscoverCallbacks[i];
        }
        for (size_t i = 0; i < StateChangedCallbacks.size(); i++)
        {
            StateChangedCallbacks[i]->Release(true);
            delete StateChangedCallbacks[i];
        }
        for (size_t i = 0; i < CommissionerEnergyReportCallbacks.size(); i++)
        {
            CommissionerEnergyReportCallbacks[i]->Release(true);
            delete CommissionerEnergyReportCallbacks[i];
        }
        for (size_t i = 0; i < CommissionerPanIdConflictCallbacks.size(); i++)
        {
            CommissionerPanIdConflictCallbacks[i]->Release(true);
            delete CommissionerPanIdConflictCallbacks[i];
        }
        for (size_t i = 0; i < JoinerCallbacks.size(); i++)
        {
            JoinerCallbacks[i]->Release(true);
            delete JoinerCallbacks[i];
        }
        
        // Clean up threadpool wait
        if (tpWait)
        {
            #ifdef DEBUG_ASYNC_IO
            LogVerbose(API_DEFAULT, "Waiting for outstanding threadpool callbacks to compelte");
            #endif

            // Cancel any queued waits and wait for any outstanding calls to compelte
            WaitForThreadpoolWaitCallbacks(tpWait, TRUE);
        
            #ifdef DEBUG_ASYNC_IO
            LogVerbose(API_DEFAULT, "Cancelling any pending IO");
            #endif

            // Cancel any async IO
            CancelIoEx(aApitInstance->DeviceHandle, &aApitInstance->Overlapped);

            // Free the threadpool wait
            CloseThreadpoolWait(tpWait);
        }

        // Clean up overlapped event
        if (aApitInstance->Overlapped.hEvent)
        {
            CloseHandle(aApitInstance->Overlapped.hEvent);
        }
    
        // Close the device handle
        CloseHandle(aApitInstance->DeviceHandle);
    }

    delete aApitInstance;
    
    LogFuncExit(API_DEFAULT);
}

OTAPI 
void 
OTCALL
otFreeMemory(
    _In_ const void *mem
    )
{
    free((void*)mem);
}

// Handles cleanly invoking the register callback
VOID
ProcessNotification(
    _In_ otApiInstance         *aApitInstance,
    _In_ POTLWF_NOTIFICATION    Notif
    )
{
    if (Notif->NotifType == OTLWF_NOTIF_DEVICE_AVAILABILITY)
    {
        otCallback<otDeviceAvailabilityChangedCallback>* Callback = nullptr;
        
        EnterCriticalSection(&aApitInstance->CallbackLock);

        if (aApitInstance->DeviceAvailabilityCallbacks != nullptr)
        {
            aApitInstance->DeviceAvailabilityCallbacks->AddRef();
            Callback = aApitInstance->DeviceAvailabilityCallbacks;
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);

        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->DeviceAvailabilityPayload.Available != FALSE, 
                &Notif->InterfaceGuid, 
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_STATE_CHANGE)
    {
        otCallback<otStateChangedCallback>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->StateChangedCallbacks.size(); i++)
        {
            if (aApitInstance->StateChangedCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->StateChangedCallbacks[i]->AddRef();
                Callback = aApitInstance->StateChangedCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->StateChangePayload.Flags, 
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_DISCOVER)
    {
        otCallback<otHandleActiveScanResult>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->DiscoverCallbacks.size(); i++)
        {
            if (aApitInstance->DiscoverCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->DiscoverCallbacks[i]->AddRef();
                Callback = aApitInstance->DiscoverCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->DiscoverPayload.Valid ? &Notif->DiscoverPayload.Results : nullptr, 
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_ACTIVE_SCAN)
    {
        otCallback<otHandleActiveScanResult>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->ActiveScanCallbacks.size(); i++)
        {
            if (aApitInstance->ActiveScanCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->ActiveScanCallbacks[i]->AddRef();
                Callback = aApitInstance->ActiveScanCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->ActiveScanPayload.Valid ? &Notif->ActiveScanPayload.Results : nullptr, 
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_ENERGY_SCAN)
    {
        otCallback<otHandleEnergyScanResult>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->EnergyScanCallbacks.size(); i++)
        {
            if (aApitInstance->EnergyScanCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->EnergyScanCallbacks[i]->AddRef();
                Callback = aApitInstance->EnergyScanCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->EnergyScanPayload.Valid ? &Notif->EnergyScanPayload.Results : nullptr, 
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_COMMISSIONER_ENERGY_REPORT)
    {
        otCallback<otCommissionerEnergyReportCallback>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->CommissionerEnergyReportCallbacks.size(); i++)
        {
            if (aApitInstance->CommissionerEnergyReportCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->CommissionerEnergyReportCallbacks[i]->AddRef();
                Callback = aApitInstance->CommissionerEnergyReportCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->CommissionerEnergyReportPayload.ChannelMask,
                Notif->CommissionerEnergyReportPayload.EnergyList,
                Notif->CommissionerEnergyReportPayload.EnergyListLength,
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_COMMISSIONER_PANID_QUERY)
    {
        otCallback<otCommissionerPanIdConflictCallback>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->CommissionerPanIdConflictCallbacks.size(); i++)
        {
            if (aApitInstance->CommissionerPanIdConflictCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->CommissionerPanIdConflictCallbacks[i]->AddRef();
                Callback = aApitInstance->CommissionerPanIdConflictCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            Callback->Callback(
                Notif->CommissionerPanIdQueryPayload.PanId,
                Notif->CommissionerPanIdQueryPayload.ChannelMask,
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else if (Notif->NotifType == OTLWF_NOTIF_JOINER_COMPLETE)
    {
        otCallback<otJoinerCallback>* Callback = nullptr;

        EnterCriticalSection(&aApitInstance->CallbackLock);

        for (size_t i = 0; i < aApitInstance->JoinerCallbacks.size(); i++)
        {
            if (aApitInstance->JoinerCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
            {
                aApitInstance->JoinerCallbacks[i]->AddRef();
                Callback = aApitInstance->JoinerCallbacks[i];
                break;
            }
        }

        LeaveCriticalSection(&aApitInstance->CallbackLock);
        
        // Invoke the callback outside the lock and release ref when done
        if (Callback)
        {
            aApitInstance->SetCallback(
                aApitInstance->JoinerCallbacks,
                Notif->InterfaceGuid, (otJoinerCallback)nullptr, (PVOID)nullptr
                );

            Callback->Callback(
                Notif->JoinerCompletePayload.Error,
                Callback->CallbackContext);

            Callback->Release();
        }
    }
    else
    {
        // Unexpected notif type
    }
}

// Threadpool wait callback for async IO completion
VOID CALLBACK 
otIoComplete(
    _Inout_     PTP_CALLBACK_INSTANCE /* Instance */,
    _Inout_opt_ PVOID                 Context,
    _Inout_     PTP_WAIT              /* Wait */,
    _In_        TP_WAIT_RESULT        /* WaitResult */
    )
{
#ifdef DEBUG_ASYNC_IO
    LogFuncEntry(API_DEFAULT);
#endif

    otApiInstance *aApitInstance = (otApiInstance*)Context;
    if (aApitInstance == nullptr) return;

    // Get the result of the IO operation
    DWORD dwBytesTransferred = 0;
    if (!GetOverlappedResult(
            aApitInstance->DeviceHandle,
            &aApitInstance->Overlapped,
            &dwBytesTransferred,
            FALSE))
    {
        DWORD dwError = GetLastError();
        LogError(API_DEFAULT, "GetOverlappedResult for notification failed, %!WINERROR!", dwError);
    }
    else
    {
        LogVerbose(API_DEFAULT, "Received successful callback for notification, type=%d", 
                     aApitInstance->NotificationBuffer.NotifType);

        // Invoke the callback if set
        ProcessNotification(aApitInstance, &aApitInstance->NotificationBuffer);
            
        // Try to get the threadpool wait to see if we are allowed to continue processing notifications
        EnterCriticalSection(&aApitInstance->CallbackLock);
        PTP_WAIT tpWait = aApitInstance->ThreadpoolWait;
        LeaveCriticalSection(&aApitInstance->CallbackLock);

        if (tpWait)
        {
            // Start waiting for next notification
            SetThreadpoolWait(tpWait, aApitInstance->Overlapped.hEvent, nullptr);
            
#ifdef DEBUG_ASYNC_IO
            LogVerbose(API_DEFAULT, "Querying for next notification");
#endif

            // Request next notification
            if (!DeviceIoControl(
                    aApitInstance->DeviceHandle,
                    IOCTL_OTLWF_QUERY_NOTIFICATION,
                    nullptr, 0,
                    &aApitInstance->NotificationBuffer, sizeof(OTLWF_NOTIFICATION),
                    nullptr, 
                    &aApitInstance->Overlapped))
            {
                DWORD dwError = GetLastError();
                if (dwError != ERROR_IO_PENDING)
                {
                    LogError(API_DEFAULT, "DeviceIoControl for new notification failed, %!WINERROR!", dwError);
                }
            }
        }
    }
    
#ifdef DEBUG_ASYNC_IO
    LogFuncExit(API_DEFAULT);
#endif
}

DWORD
SendIOCTL(
    _In_ otApiInstance *aApitInstance,
    _In_ DWORD dwIoControlCode,
    _In_reads_bytes_opt_(nInBufferSize) LPVOID lpInBuffer,
    _In_ DWORD nInBufferSize,
    _Out_writes_bytes_opt_(nOutBufferSize) LPVOID lpOutBuffer,
    _In_ DWORD nOutBufferSize
    )
{
    DWORD dwError = ERROR_SUCCESS;
    OVERLAPPED Overlapped = { 0 };
    DWORD dwBytesReturned = 0;
    
    Overlapped.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    if (Overlapped.hEvent == nullptr)
    {
        dwError = GetLastError();
        LogError(API_DEFAULT, "CreateEvent (Overlapped.hEvent) failed, %!WINERROR!", dwError);
        goto error;
    }
    
    // Send the IOCTL the OpenThread driver
    if (!DeviceIoControl(
            aApitInstance->DeviceHandle,
            dwIoControlCode,
            lpInBuffer, nInBufferSize,
            lpOutBuffer, nOutBufferSize,
            nullptr, 
            &Overlapped))
    {
        dwError = GetLastError();
        if (dwError != ERROR_IO_PENDING)
        {
            LogError(API_DEFAULT, "DeviceIoControl(0x%x) failed, %!WINERROR!", dwIoControlCode, dwError);
            goto error;
        }
        dwError = ERROR_SUCCESS;
    }

    // Get the result of the IO operation
    if (!GetOverlappedResultEx(
            aApitInstance->DeviceHandle,
            &Overlapped,
            &dwBytesReturned,
            c_MaxOverlappedWaitTimeMS,
            FALSE
            ))
    {
        dwError = GetLastError();
        if (dwError == WAIT_TIMEOUT)
        {
            dwError = ERROR_TIMEOUT;
            CancelIoEx(aApitInstance->DeviceHandle, &Overlapped);
        }
        LogError(API_DEFAULT, "GetOverlappedResult failed, %!WINERROR!", dwError);
        goto error;
    }

    if (dwBytesReturned != nOutBufferSize)
    {
        dwError = ERROR_INVALID_DATA;
        LogError(API_DEFAULT, "GetOverlappedResult returned invalid output size, expected=%u actual=%u", 
                     nOutBufferSize, dwBytesReturned);
        goto error;
    }

error:

    if (Overlapped.hEvent)
    {
        CloseHandle(Overlapped.hEvent);
    }

    return dwError;
}

__pragma(pack(push,1))
template <class T1, class T2>
struct PackedBuffer2
{
    T1 data1; T2 data2;
    PackedBuffer2(const T1 &d1, const T2 &d2) : data1(d1), data2(d2) { }
};
template <class T1, class T2, class T3>
struct PackedBuffer3
{
    T1 data1; T2 data2; T3 data3;
    PackedBuffer3(const T1 &d1, const T2 &d2, const T3 &d3) : data1(d1), data2(d2), data3(d3) { }
};
template <class T1, class T2, class T3, class T4>
struct PackedBuffer4
{
    T1 data1; T2 data2; T3 data3; T4 data4;
    PackedBuffer4(const T1 &d1, const T2 &d2, const T3 &d3, const T4 &d4) : data1(d1), data2(d2), data3(d3), data4(d4) { }
};
template <class T1, class T2, class T3, class T4, class T5>
struct PackedBuffer5
{
    T1 data1; T2 data2; T3 data3; T4 data4; T5 data5;
    PackedBuffer5(const T1 &d1, const T2 &d2, const T3 &d3, const T4 &d4, const T5 &d5) : data1(d1), data2(d2), data3(d3), data4(d4), data5(d5) { }
};
template <class T1, class T2, class T3, class T4, class T5, class T6>
struct PackedBuffer6
{
    T1 data1; T2 data2; T3 data3; T4 data4; T5 data5; T6 data6;
    PackedBuffer6(const T1 &d1, const T2 &d2, const T3 &d3, const T4 &d4, const T5 &d5, const T6 &d6) : data1(d1), data2(d2), data3(d3), data4(d4), data5(d5), data6(d6) { }
};
 __pragma(pack(pop))

template <class in, class out>
DWORD
QueryIOCTL(
    _In_ otInstance *aInstance,
    _In_ DWORD dwIoControlCode,
    _In_ const in *input,
    _Out_ out* output
    )
{
    PackedBuffer2<GUID,in> Buffer(aInstance->InterfaceGuid, *input);
    return SendIOCTL(aInstance->ApiHandle, dwIoControlCode, &Buffer, sizeof(Buffer), output, sizeof(out));
}

template <class out>
DWORD
QueryIOCTL(
    _In_ otInstance *aInstance,
    _In_ DWORD dwIoControlCode,
    _Out_ out* output
    )
{
    return SendIOCTL(aInstance->ApiHandle, dwIoControlCode, &aInstance->InterfaceGuid, sizeof(GUID), output, sizeof(out));
}

template <class in>
DWORD
SetIOCTL(
    _In_ otInstance *aInstance,
    _In_ DWORD dwIoControlCode,
    _In_ const in* input
    )
{
    PackedBuffer2<GUID,in> Buffer(aInstance->InterfaceGuid, *input);
    return SendIOCTL(aInstance->ApiHandle, dwIoControlCode, &Buffer, sizeof(Buffer), nullptr, 0);
}

template <class in>
DWORD
SetIOCTL(
    _In_ otInstance *aInstance,
    _In_ DWORD dwIoControlCode,
    _In_ const in input
    )
{
    PackedBuffer2<GUID,in> Buffer(aInstance->InterfaceGuid, input);
    return SendIOCTL(aInstance->ApiHandle, dwIoControlCode, &Buffer, sizeof(Buffer), nullptr, 0);
}

DWORD
SetIOCTL(
    _In_ otInstance *aInstance,
    _In_ DWORD dwIoControlCode
    )
{
    return SendIOCTL(aInstance->ApiHandle, dwIoControlCode, &aInstance->InterfaceGuid, sizeof(GUID), nullptr, 0);
}

otError
DwordToThreadError(
    DWORD dwError
    )
{
    if (((int)dwError) > 0)
    {
        return OT_ERROR_GENERIC;
    }
    else
    {
        return (otError)(-(int)dwError);
    }
}

OTAPI 
void 
OTCALL
otSetDeviceAvailabilityChangedCallback(
    _In_ otApiInstance *aApitInstance,
    _In_ otDeviceAvailabilityChangedCallback aCallback,
    _In_ void *aCallbackContext
    )
{
    otApiDeviceAvailabilityCallback* CallbackToRelease = nullptr;

    EnterCriticalSection(&aApitInstance->CallbackLock);

    if (aApitInstance->DeviceAvailabilityCallbacks != nullptr)
    {
        CallbackToRelease = aApitInstance->DeviceAvailabilityCallbacks;
        aApitInstance->DeviceAvailabilityCallbacks = nullptr;
    }

    if (aCallback != nullptr)
    {
        aApitInstance->DeviceAvailabilityCallbacks = 
            new otApiDeviceAvailabilityCallback(aCallback, aCallbackContext);
    }
    
    LeaveCriticalSection(&aApitInstance->CallbackLock);

    if (CallbackToRelease)
    {
        CallbackToRelease->Release(true);
        delete CallbackToRelease;
    }
}

OTAPI 
otDeviceList* 
OTCALL
otEnumerateDevices(
    _In_ otApiInstance *aApitInstance
    )
{
    DWORD dwError = ERROR_SUCCESS;
    OVERLAPPED Overlapped = { 0 };
    DWORD dwBytesReturned = 0;
    otDeviceList* pDeviceList = nullptr;
    DWORD cbDeviceList = sizeof(otDeviceList);
    
    LogFuncEntry(API_DEFAULT);

    Overlapped.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    if (Overlapped.hEvent == nullptr)
    {
        dwError = GetLastError();
        LogError(API_DEFAULT, "CreateEvent (Overlapped.hEvent) failed, %!WINERROR!", dwError);
        goto error;
    }
    
    pDeviceList = (otDeviceList*)malloc(cbDeviceList);
    if (pDeviceList == nullptr)
    {
        LogWarning(API_DEFAULT, "Failed to allocate otDeviceList of %u bytes.", cbDeviceList);
        dwError = ERROR_NOT_ENOUGH_MEMORY;
        goto error;
    }
    RtlZeroMemory(pDeviceList, cbDeviceList);
    
    // Query in a loop to account for it changing between calls
    while (true)
    {
        // Send the IOCTL to query the interfaces
        if (!DeviceIoControl(
                aApitInstance->DeviceHandle,
                IOCTL_OTLWF_ENUMERATE_DEVICES,
                nullptr, 0,
                pDeviceList, cbDeviceList,
                nullptr, 
                &Overlapped))
        {
            dwError = GetLastError();
            if (dwError != ERROR_IO_PENDING)
            {
                LogError(API_DEFAULT, "DeviceIoControl(IOCTL_OTLWF_ENUMERATE_DEVICES) failed, %!WINERROR!", dwError);
                goto error;
            }
            dwError = ERROR_SUCCESS;
        }

        // Get the result of the IO operation
        if (!GetOverlappedResultEx(
                aApitInstance->DeviceHandle,
                &Overlapped,
                &dwBytesReturned,
                c_MaxOverlappedWaitTimeMS,
                TRUE))
        {
            dwError = GetLastError();
            if (dwError == WAIT_TIMEOUT)
            {
                dwError = ERROR_TIMEOUT;
                CancelIoEx(aApitInstance->DeviceHandle, &Overlapped);
            }
            LogError(API_DEFAULT, "GetOverlappedResult for notification failed, %!WINERROR!", dwError);
            goto error;
        }
        
        // Calculate the expected size of the full buffer
        cbDeviceList = 
            FIELD_OFFSET(otDeviceList, aDevices) +
            pDeviceList->aDevicesLength * sizeof(otDeviceList::aDevices);
        
        // Make sure they returned a complete buffer
        if (dwBytesReturned != sizeof(otDeviceList::aDevicesLength)) break;
        
        // If we get here that means we didn't have a big enough buffer
        // Reallocate a new buffer
        free(pDeviceList);
        pDeviceList = (otDeviceList*)malloc(cbDeviceList);
        if (pDeviceList == nullptr)
        {
            LogError(API_DEFAULT, "Failed to allocate otDeviceList of %u bytes.", cbDeviceList);
            dwError = ERROR_NOT_ENOUGH_MEMORY;
            goto error;
        }
        RtlZeroMemory(pDeviceList, cbDeviceList);
    }

error:

    if (dwError != ERROR_SUCCESS)
    {
        free(pDeviceList);
        pDeviceList = nullptr;
    }

    if (Overlapped.hEvent)
    {
        CloseHandle(Overlapped.hEvent);
    }
    
    LogFuncExitMsg(API_DEFAULT, "%d devices", pDeviceList == nullptr ? -1 : (int)pDeviceList->aDevicesLength);

    return pDeviceList;
}
    
OTAPI 
otInstance *
OTCALL
otInstanceInit(
    _In_ otApiInstance *aApitInstance, 
    _In_ const GUID *aDeviceGuid
    )
{
    otInstance *aInstance = nullptr;

    OTLWF_DEVICE Result = {0};
    if (aApitInstance &&
        SendIOCTL(
            aApitInstance, 
            IOCTL_OTLWF_QUERY_DEVICE, 
            (LPVOID)aDeviceGuid, 
            sizeof(GUID), 
            &Result, 
            sizeof(Result)
            ) == ERROR_SUCCESS)
    {
        aInstance = (otInstance*)malloc(sizeof(otInstance));
        if (aInstance)
        {
            aInstance->ApiHandle = aApitInstance;
            aInstance->InterfaceGuid = *aDeviceGuid;
            aInstance->CompartmentID = Result.CompartmentID;

            if (ConvertInterfaceGuidToLuid(aDeviceGuid, &aInstance->InterfaceLuid) != ERROR_SUCCESS ||
                ConvertInterfaceLuidToIndex(&aInstance->InterfaceLuid, &aInstance->InterfaceIndex) != ERROR_SUCCESS)
            {
                LogError(API_DEFAULT, "Failed to convert interface guid to index!");
                free(aInstance);
                aInstance = nullptr;
            }
        }
    }

    return aInstance;
}

OTAPI 
GUID 
OTCALL
otGetDeviceGuid(
    otInstance *aInstance
    )
{
    if (aInstance == nullptr) return {};
    return aInstance->InterfaceGuid;
}

OTAPI 
uint32_t 
OTCALL
otGetDeviceIfIndex(
    otInstance *aInstance
    )
{
    if (aInstance == nullptr) return (uint32_t)-1;
    return aInstance->InterfaceIndex;
}

OTAPI 
uint32_t 
OTCALL
otGetCompartmentId(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return (uint32_t)-1;
    return aInstance->CompartmentID;
}

OTAPI 
const char *
OTCALL
otGetVersionString()
{
    char* szVersion = (char*)malloc(sizeof(c_Version));
    if (szVersion)
    {
        memcpy_s(szVersion, sizeof(c_Version), c_Version, sizeof(c_Version));
    }
    return szVersion;
}

OTAPI 
otError 
OTCALL
otIp6SetEnabled(
    _In_ otInstance *aInstance,
    bool aEnabled
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_INTERFACE, (BOOLEAN)aEnabled));
}

OTAPI 
bool 
OTCALL
otIp6IsEnabled(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_INTERFACE, &Result);
    return Result != FALSE;
}

OTAPI 
otError 
OTCALL
otThreadSetEnabled(
    _In_ otInstance *aInstance,
    bool aEnabled
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD, (BOOLEAN)aEnabled));
}

OTAPI
otError
OTCALL
otThreadSetAutoStart(
    _In_ otInstance *aInstance,
    bool aStartAutomatically
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD_AUTO_START, (BOOLEAN)(aStartAutomatically ? TRUE : FALSE)));
}

OTAPI
bool
OTCALL
otThreadGetAutoStart(
    otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_THREAD_AUTO_START, &Result);
    return Result != FALSE;
}

OTAPI 
bool 
OTCALL
otThreadIsSingleton(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_SINGLETON, &Result);
    return Result != FALSE;
}

OTAPI 
otError 
OTCALL
otLinkActiveScan(
    _In_ otInstance *aInstance, 
    uint32_t aScanChannels, 
    uint16_t aScanDuration,
    otHandleActiveScanResult aCallback,
    _In_ void *aCallbackContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->ActiveScanCallbacks,
        aInstance->InterfaceGuid, aCallback, aCallbackContext
        );
    
    PackedBuffer3<GUID,uint32_t,uint16_t> Buffer(aInstance->InterfaceGuid, aScanChannels, aScanDuration);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_ACTIVE_SCAN, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
bool 
OTCALL
otLinkIsActiveScanInProgress(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ACTIVE_SCAN, &Result);
    return Result != FALSE;
}

OTAPI 
otError 
OTCALL 
otLinkEnergyScan(
    _In_ otInstance *aInstance, 
    uint32_t aScanChannels, 
    uint16_t aScanDuration,
    _In_ otHandleEnergyScanResult aCallback, 
    _In_ void *aCallbackContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->EnergyScanCallbacks,
        aInstance->InterfaceGuid, aCallback, aCallbackContext
        );
    
    PackedBuffer3<GUID,uint32_t,uint16_t> Buffer(aInstance->InterfaceGuid, aScanChannels, aScanDuration);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_ENERGY_SCAN, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
bool 
OTCALL 
otLinkIsEnergyScanInProgress(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ENERGY_SCAN, &Result);
    return Result != FALSE;
}

OTAPI 
otError 
OTCALL
otThreadDiscover(
    _In_ otInstance *aInstance, 
    uint32_t aScanChannels, 
    uint16_t aPanid,
    bool aJoiner,
    bool aEnableEui64Filtering,
    otHandleActiveScanResult aCallback,
    void *aCallbackContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->DiscoverCallbacks,
        aInstance->InterfaceGuid, aCallback, aCallbackContext
        );

    PackedBuffer5<GUID,uint32_t,uint16_t, uint8_t, uint8_t> Buffer(aInstance->InterfaceGuid, aScanChannels, aPanid, aJoiner, aEnableEui64Filtering);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_DISCOVER, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
bool 
OTCALL
otIsDiscoverInProgress(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = FALSE;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_DISCOVER, &Result);
    return Result != FALSE;
}

OTAPI 
otError
OTCALL
otLinkSendDataRequest(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    UNREFERENCED_PARAMETER(aInstance);
    return OT_ERROR_NOT_IMPLEMENTED; // TODO
}

OTAPI 
uint8_t 
OTCALL
otLinkGetChannel(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_CHANNEL, &Result);
    return Result;
}

OTAPI 
otError 
OTCALL
otLinkSetChannel(
    _In_ otInstance *aInstance, 
    uint8_t aChannel
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_CHANNEL, aChannel));
}

OTAPI
otError
OTCALL
otDatasetSetDelayTimerMinimal(
    _In_ otInstance *aInstance,
    uint32_t aDelayTimerMinimal
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    // TODO
    UNREFERENCED_PARAMETER(aDelayTimerMinimal);
    return OT_ERROR_NOT_IMPLEMENTED;
}

OTAPI
uint32_t
OTCALL
otDatasetGetDelayTimerMinimal(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return 0;
    // TODO
    return 0;
}

OTAPI 
uint8_t 
OTCALL
otThreadGetMaxAllowedChildren(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAX_CHILDREN, &Result);
    return Result;
}

OTAPI 
otError 
OTCALL
otThreadSetMaxAllowedChildren(
    _In_ otInstance *aInstance, 
    uint8_t aMaxChildren
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_MAX_CHILDREN, aMaxChildren));
}

OTAPI 
uint32_t 
OTCALL
otThreadGetChildTimeout(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_CHILD_TIMEOUT, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otThreadSetChildTimeout(
    _In_ otInstance *aInstance, 
    uint32_t aTimeout
    )
{
    if (aInstance == nullptr) return;
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_CHILD_TIMEOUT, aTimeout);
}

OTAPI 
const 
uint8_t *
OTCALL
otLinkGetExtendedAddress(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otExtAddress *Result = (otExtAddress*)malloc(sizeof(otExtAddress));
    if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_ADDRESS, Result) != ERROR_SUCCESS)
    {
        free(Result);
        Result = nullptr;
    }
    return (uint8_t*)Result;
}

OTAPI 
otError 
OTCALL
otLinkSetExtendedAddress(
    _In_ otInstance *aInstance, 
    const otExtAddress *aExtendedAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_ADDRESS, aExtendedAddress));
}

OTAPI 
const uint8_t *
OTCALL
otThreadGetExtendedPanId(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otExtendedPanId *Result = (otExtendedPanId*)malloc(sizeof(otExtendedPanId));
    if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_PANID, Result) != ERROR_SUCCESS)
    {
        free(Result);
        Result = nullptr;
    }
    return (uint8_t*)Result;
}

OTAPI 
otError 
OTCALL
otThreadSetExtendedPanId(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtendedPanId
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_EXTENDED_PANID, (const otExtendedPanId*)aExtendedPanId));
}

OTAPI 
void 
OTCALL
otLinkGetFactoryAssignedIeeeEui64(
    _In_ otInstance *aInstance, 
    _Out_ otExtAddress *aEui64
)
{
    if (aInstance == nullptr) return;
    (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_FACTORY_EUI64, aEui64);
}

OTAPI 
void 
OTCALL
otLinkGetJoinerId(
    _In_ otInstance *aInstance, 
    _Out_ otExtAddress *aHashMacAddress
    )
{
    if (aInstance == nullptr) return;
    (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_HASH_MAC_ADDRESS, aHashMacAddress);
}

OTAPI 
otError 
OTCALL
otThreadGetLeaderRloc(
    _In_ otInstance *aInstance, 
    _Out_ otIp6Address *aLeaderRloc
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LEADER_RLOC, aLeaderRloc));
}

OTAPI 
otLinkModeConfig 
OTCALL
otThreadGetLinkMode(
    _In_ otInstance *aInstance
    )
{
    otLinkModeConfig Result = {0};
    static_assert(sizeof(otLinkModeConfig) == 4, "The size of otLinkModeConfig should be 4 bytes");
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LINK_MODE, &Result);
    return Result;
}

OTAPI 
otError 
OTCALL
otThreadSetLinkMode(
    _In_ otInstance *aInstance, 
    otLinkModeConfig aConfig
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    static_assert(sizeof(otLinkModeConfig) == 4, "The size of otLinkModeConfig should be 4 bytes");
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_LINK_MODE, aConfig));
}

OTAPI 
const otMasterKey *
OTCALL
otThreadGetMasterKey(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otMasterKey *Result = (otMasterKey*)malloc(sizeof(otMasterKey));
    if (Result == nullptr) return nullptr;
    if (QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MASTER_KEY, Result) != ERROR_SUCCESS)
    {
        free(Result);
        return nullptr;
    }
    return Result;
}

OTAPI
otError
OTCALL
otThreadSetMasterKey(
    _In_ otInstance *aInstance, 
    const otMasterKey *aKey
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_MASTER_KEY, aKey));
}

OTAPI 
const uint8_t *
OTCALL
otThreadGetPSKc(
    _In_ otInstance *aInstance 
    )
{
    if (aInstance == nullptr) return nullptr;

    uint8_t *Result = (uint8_t*)malloc(sizeof(otPSKc));
    if (Result == nullptr) return nullptr;
    if (QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PSKC, Result) != ERROR_SUCCESS)
    {
        free(Result);
        return nullptr;
    }
    return Result;
}

OTAPI
otError
OTCALL
otThreadSetPSKc(
    _In_ otInstance *aInstance, 
    const uint8_t *aPSKc 
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    
    BYTE Buffer[sizeof(GUID) + sizeof(otPSKc)];
    memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), aPSKc, sizeof(otPSKc));
    
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_PSKC, Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
int8_t 
OTCALL
otLinkGetMaxTransmitPower(
    _In_ otInstance *aInstance
    )
{
    int8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAX_TRANSMIT_POWER, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otLinkSetMaxTransmitPower(
    _In_ otInstance *aInstance, 
    int8_t aPower
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_MAX_TRANSMIT_POWER, aPower);
}

OTAPI
const otIp6Address *
OTCALL
otThreadGetMeshLocalEid(
    _In_ otInstance *aInstance
    )
{
    otIp6Address *Result = (otIp6Address*)malloc(sizeof(otIp6Address));
    if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MESH_LOCAL_EID, Result) != ERROR_SUCCESS)
    {
        free(Result);
        Result = nullptr;
    }
    return Result;
}

OTAPI
const uint8_t *
OTCALL
otThreadGetMeshLocalPrefix(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otMeshLocalPrefix *Result = (otMeshLocalPrefix*)malloc(sizeof(otMeshLocalPrefix));
    if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MESH_LOCAL_PREFIX, Result) != ERROR_SUCCESS)
    {
        free(Result);
        Result = nullptr;
    }
    return (uint8_t*)Result;
}

OTAPI
otError
OTCALL
otThreadSetMeshLocalPrefix(
    _In_ otInstance *aInstance, 
    const uint8_t *aMeshLocalPrefix
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_MESH_LOCAL_PREFIX, (const otMeshLocalPrefix*)aMeshLocalPrefix));
}

OTAPI
otError
OTCALL
otThreadGetNetworkDataLeader(
    _In_ otInstance *aInstance, 
    bool aStable, 
    _Out_ uint8_t *aData, 
    _Out_ uint8_t *aDataLength
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    UNREFERENCED_PARAMETER(aInstance);
    UNREFERENCED_PARAMETER(aStable);
    UNREFERENCED_PARAMETER(aData);
    UNREFERENCED_PARAMETER(aDataLength);
    return OT_ERROR_NOT_IMPLEMENTED; // TODO
}

OTAPI
otError
OTCALL
otThreadGetNetworkDataLocal(
    _In_ otInstance *aInstance, 
    bool aStable, 
    _Out_ uint8_t *aData, 
    _Out_ uint8_t *aDataLength
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    UNREFERENCED_PARAMETER(aInstance);
    UNREFERENCED_PARAMETER(aStable);
    UNREFERENCED_PARAMETER(aData);
    UNREFERENCED_PARAMETER(aDataLength);
    return OT_ERROR_NOT_IMPLEMENTED; // TODO
}

OTAPI
const char *
OTCALL
otThreadGetNetworkName(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otNetworkName *Result = (otNetworkName*)malloc(sizeof(otNetworkName));
    if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_NETWORK_NAME, Result) != ERROR_SUCCESS)
    {
        free(Result);
        Result = nullptr;
    }
    return (char*)Result;
}

OTAPI
otError
OTCALL
otThreadSetNetworkName(
    _In_ otInstance *aInstance, 
    _In_ const char *aNetworkName
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    otNetworkName Buffer = {0};
    strcpy_s(Buffer.m8, sizeof(Buffer), aNetworkName);
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_NETWORK_NAME, (const otNetworkName*)&Buffer));
}

OTAPI 
otError 
OTCALL
otNetDataGetNextOnMeshPrefix(
    _In_ otInstance *aInstance, 
    _Inout_ otNetworkDataIterator *aIterator,
    _Out_ otBorderRouterConfig *aConfig
    )
{
    if (aInstance == nullptr || aConfig == nullptr) return OT_ERROR_INVALID_ARGS;
    
    BOOLEAN aLocal = FALSE;
    PackedBuffer3<GUID,BOOLEAN,otNetworkDataIterator> InBuffer(aInstance->InterfaceGuid, aLocal, *aIterator);
    BYTE OutBuffer[sizeof(uint8_t) + sizeof(otBorderRouterConfig)];

    otError aError =
        DwordToThreadError(
            SendIOCTL(
                aInstance->ApiHandle,
                IOCTL_OTLWF_OT_NEXT_ON_MESH_PREFIX,
                &InBuffer, sizeof(InBuffer),
                OutBuffer, sizeof(OutBuffer)));

    if (aError == OT_ERROR_NONE)
    {
        memcpy(aIterator, OutBuffer, sizeof(uint8_t));
        memcpy(aConfig, OutBuffer + sizeof(uint8_t), sizeof(otBorderRouterConfig));
    }
    else
    {
        ZeroMemory(aConfig, sizeof(otBorderRouterConfig));
    }

    return aError;
}

OTAPI
otError
OTCALL
otBorderRouterGetNextOnMeshPrefix(
    _In_ otInstance *aInstance,
    _Inout_ otNetworkDataIterator *aIterator,
    _Out_ otBorderRouterConfig *aConfig
    )
{
    if (aInstance == nullptr || aConfig == nullptr) return OT_ERROR_INVALID_ARGS;

    BOOLEAN aLocal = TRUE;
    PackedBuffer3<GUID,BOOLEAN,otNetworkDataIterator> InBuffer(aInstance->InterfaceGuid, aLocal, *aIterator);
    BYTE OutBuffer[sizeof(uint8_t) + sizeof(otBorderRouterConfig)];

    otError aError = 
        DwordToThreadError(
            SendIOCTL(
                aInstance->ApiHandle, 
                IOCTL_OTLWF_OT_NEXT_ON_MESH_PREFIX, 
                &InBuffer, sizeof(InBuffer), 
                OutBuffer, sizeof(OutBuffer)));

    if (aError == OT_ERROR_NONE)
    {
        memcpy(aIterator, OutBuffer, sizeof(uint8_t));
        memcpy(aConfig, OutBuffer + sizeof(uint8_t), sizeof(otBorderRouterConfig));
    }
    else
    {
        ZeroMemory(aConfig, sizeof(otBorderRouterConfig));
    }

    return aError;
}

OTAPI
otPanId 
OTCALL
otLinkGetPanId(
    _In_ otInstance *aInstance
    )
{
    otPanId Result = {0};
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PAN_ID, &Result);
    return Result;
}

OTAPI
otError
OTCALL
otLinkSetPanId(
    _In_ otInstance *aInstance, 
    otPanId aPanId
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PAN_ID, aPanId));
}

OTAPI
bool 
OTCALL
otThreadIsRouterRoleEnabled(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = {0};
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_ROLL_ENABLED, &Result);
    return Result != FALSE;
}

OTAPI
void 
OTCALL
otThreadSetRouterRoleEnabled(
    _In_ otInstance *aInstance, 
    bool aEnabled
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_ROLL_ENABLED, (BOOLEAN)aEnabled);
}

OTAPI
otError
OTCALL
otThreadSetPreferredRouterId(
    _In_ otInstance *aInstance,
    uint8_t aRouterId
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PAN_ID, aRouterId));
}

OTAPI
otShortAddress 
OTCALL
otLinkGetShortAddress(
    _In_ otInstance *aInstance
    )
{
    otShortAddress Result = {0};
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_SHORT_ADDRESS, &Result);
    return Result;
}

BOOL
GetAdapterAddresses(
    PIP_ADAPTER_ADDRESSES * ppIAA
)
{
    PIP_ADAPTER_ADDRESSES pIAA = NULL;
    DWORD len = 0;
    DWORD flags;

    flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
    if (GetAdaptersAddresses(AF_INET6, flags, NULL, NULL, &len) != ERROR_BUFFER_OVERFLOW)
        return FALSE;

    pIAA = (PIP_ADAPTER_ADDRESSES)malloc(len);
    if (pIAA) {
        GetAdaptersAddresses(AF_INET6, flags, NULL, pIAA, &len);
        *ppIAA = pIAA;
        return TRUE;
    }
    return FALSE;
}

OTAPI
const otNetifAddress *
OTCALL
otIp6GetUnicastAddresses(
    _In_ otInstance *aInstance
    )
{
    LogFuncEntry(API_DEFAULT);
    if (aInstance == nullptr)
    {
        LogFuncExit(API_DEFAULT);
        return nullptr;
    }

    // Put the current thead in the correct compartment
    bool RevertCompartmentOnExit = false;
    ULONG OriginalCompartmentID = GetCurrentThreadCompartmentId();
    if (OriginalCompartmentID != aInstance->CompartmentID)
    {
        DWORD dwError = ERROR_SUCCESS;
        if ((dwError = SetCurrentThreadCompartmentId(aInstance->CompartmentID)) != ERROR_SUCCESS)
        {
            LogError(API_DEFAULT, "SetCurrentThreadCompartmentId failed, %!WINERROR!", dwError);
            return nullptr;
        }
        RevertCompartmentOnExit = true;
    }

    otNetifAddress *addrs = nullptr;
    ULONG AddrCount = 0;

    // Query the current adapter addresses and format them in the proper output format
    PIP_ADAPTER_ADDRESSES pIAAList;
    if (GetAdapterAddresses(&pIAAList))
    {
        // Loop through all the interfaces
        for (auto pIAA = pIAAList; pIAA != nullptr; pIAA = pIAA->Next) 
        {
            // Look for the right interface
            if (pIAA->Ipv6IfIndex != aInstance->InterfaceIndex) continue;

            // Look through all unicast addresses
            for (auto pUnicastAddr = pIAA->FirstUnicastAddress; 
                 pUnicastAddr != nullptr; 
                 pUnicastAddr = pUnicastAddr->Next)
            {
                AddrCount++;
            }

            break;
        }

        // If we didn't find any addresses, just break out
        if (AddrCount == 0) goto error;

        // Allocate the addresses
        addrs = (otNetifAddress*)malloc(AddrCount * sizeof(otNetifAddress));
        if (addrs == nullptr)
        {
            LogWarning(API_DEFAULT, "Not enough memory to alloc otNetifAddress array");
            goto error;
        }
        ZeroMemory(addrs, AddrCount * sizeof(otNetifAddress));

        // Initialize the next pointers
        for (ULONG i = 0; i < AddrCount; i++)
        {
            addrs[i].mNext = (i + 1 == AddrCount) ? nullptr : &addrs[i + 1];
        }

        AddrCount = 0;

        // Loop through all the interfaces
        for (auto pIAA = pIAAList; pIAA != nullptr; pIAA = pIAA->Next) 
        {
            // Look for the right interface
            if (pIAA->Ipv6IfIndex != aInstance->InterfaceIndex) continue;

            // Look through all unicast addresses
            for (auto pUnicastAddr = pIAA->FirstUnicastAddress; 
                 pUnicastAddr != nullptr; 
                 pUnicastAddr = pUnicastAddr->Next)
            {
                LPSOCKADDR_IN6 pAddr = (LPSOCKADDR_IN6)pUnicastAddr->Address.lpSockaddr;

                // Copy the necessary parameters
                memcpy(&addrs[AddrCount].mAddress, &pAddr->sin6_addr, sizeof(pAddr->sin6_addr));
                addrs[AddrCount].mPreferred = pUnicastAddr->PreferredLifetime != 0;
                addrs[AddrCount].mValid = pUnicastAddr->ValidLifetime != 0;
                addrs[AddrCount].mPrefixLength = pUnicastAddr->OnLinkPrefixLength;

                AddrCount++;
            }

            break;
        }

    error:
        free(pIAAList);
    }
    else
    {
        LogError(API_DEFAULT, "GetAdapterAddresses failed!");
    }

    // Revert the comparment if necessary
    if (RevertCompartmentOnExit)
    {
        (VOID)SetCurrentThreadCompartmentId(OriginalCompartmentID);
    }
    
    LogFuncExitMsg(API_DEFAULT, "%d addrs", AddrCount);
    return addrs;
}

OTAPI
otError
OTCALL
otIp6AddUnicastAddress(
    _In_ otInstance *aInstance, 
    const otNetifAddress *aAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    // Put the current thead in the correct compartment
    bool RevertCompartmentOnExit = false;
    ULONG OriginalCompartmentID = GetCurrentThreadCompartmentId();
    if (OriginalCompartmentID != aInstance->CompartmentID)
    {
        DWORD dwError = ERROR_SUCCESS;
        if ((dwError = SetCurrentThreadCompartmentId(aInstance->CompartmentID)) != ERROR_SUCCESS)
        {
            LogError(API_DEFAULT, "SetCurrentThreadCompartmentId failed, %!WINERROR!", dwError);
            return OT_ERROR_FAILED;
        }
        RevertCompartmentOnExit = true;
    }

    MIB_UNICASTIPADDRESS_ROW newRow;
    InitializeUnicastIpAddressEntry(&newRow);

    newRow.InterfaceIndex = aInstance->InterfaceIndex;
    newRow.InterfaceLuid = aInstance->InterfaceLuid;
    newRow.Address.si_family = AF_INET6;
    newRow.Address.Ipv6.sin6_family = AF_INET6;
        
    static_assert(sizeof(IN6_ADDR) == sizeof(otIp6Address), "Windows and OpenThread IPv6 Addr Structs must be same size");

    memcpy(&newRow.Address.Ipv6.sin6_addr, &aAddress->mAddress, sizeof(IN6_ADDR));
    newRow.OnLinkPrefixLength = aAddress->mPrefixLength;
    newRow.PreferredLifetime = aAddress->mPreferred ? 0xffffffff : 0;
    newRow.ValidLifetime = aAddress->mValid ? 0xffffffff : 0;
    newRow.PrefixOrigin = IpPrefixOriginOther;  // Derived from network XPANID
    newRow.SkipAsSource = FALSE;                // Allow automatic binding to this address (default)

    if (IN6_IS_ADDR_LINKLOCAL(&newRow.Address.Ipv6.sin6_addr))
    {
        newRow.SuffixOrigin = IpSuffixOriginLinkLayerAddress;   // Derived from Extended MAC address
    }
    else
    {
        newRow.SuffixOrigin = IpSuffixOriginRandom;             // Was created randomly
    }

    DWORD dwError = CreateUnicastIpAddressEntry(&newRow);

    // Revert the comparment if necessary
    if (RevertCompartmentOnExit)
    {
        (VOID)SetCurrentThreadCompartmentId(OriginalCompartmentID);
    }

    if (dwError != ERROR_SUCCESS)
    {
        LogError(API_DEFAULT, "CreateUnicastIpAddressEntry failed %!WINERROR!", dwError);
        return OT_ERROR_FAILED;
    }

    return OT_ERROR_NONE;
}

OTAPI
otError
OTCALL
otIp6RemoveUnicastAddress(
    _In_ otInstance *aInstance, 
    const otIp6Address *aAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    // Put the current thead in the correct compartment
    bool RevertCompartmentOnExit = false;
    ULONG OriginalCompartmentID = GetCurrentThreadCompartmentId();
    if (OriginalCompartmentID != aInstance->CompartmentID)
    {
        DWORD dwError = ERROR_SUCCESS;
        if ((dwError = SetCurrentThreadCompartmentId(aInstance->CompartmentID)) != ERROR_SUCCESS)
        {
            LogError(API_DEFAULT, "SetCurrentThreadCompartmentId failed, %!WINERROR!", dwError);
            return OT_ERROR_FAILED;
        }
        RevertCompartmentOnExit = true;
    }

    MIB_UNICASTIPADDRESS_ROW deleteRow;
    InitializeUnicastIpAddressEntry(&deleteRow);

    deleteRow.InterfaceIndex = aInstance->InterfaceIndex;
    deleteRow.InterfaceLuid = aInstance->InterfaceLuid;
    deleteRow.Address.si_family = AF_INET6;

    memcpy(&deleteRow.Address.Ipv6.sin6_addr, aAddress, sizeof(IN6_ADDR));
    
    DWORD dwError = DeleteUnicastIpAddressEntry(&deleteRow);

    // Revert the comparment if necessary
    if (RevertCompartmentOnExit)
    {
        (VOID)SetCurrentThreadCompartmentId(OriginalCompartmentID);
    }

    if (dwError != ERROR_SUCCESS)
    {
        LogError(API_DEFAULT, "DeleteUnicastIpAddressEntry failed %!WINERROR!", dwError);
        return OT_ERROR_FAILED;
    }

    return OT_ERROR_NONE;
}

OTAPI
otError 
OTCALL
otSetStateChangedCallback(
    _In_ otInstance *aInstance, 
    _In_ otStateChangedCallback aCallback, 
    _In_ void *aContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    bool success = 
        aInstance->ApiHandle->SetCallback(
            aInstance->ApiHandle->StateChangedCallbacks,
            aInstance->InterfaceGuid, aCallback, aContext
            );
    return success ? OT_ERROR_NONE : OT_ERROR_ALREADY;
}

OTAPI
void
OTCALL
otRemoveStateChangeCallback(
    _In_ otInstance *aInstance,
    _In_ otStateChangedCallback /* aCallback */,
    _In_ void *aContext
    )
{
    if (aInstance == nullptr) return;
    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->StateChangedCallbacks,
        aInstance->InterfaceGuid, (otStateChangedCallback)nullptr, aContext
        );
}

OTAPI
otError
OTCALL
otDatasetGetActive(
    _In_ otInstance *aInstance, 
    _Out_ otOperationalDataset *aDataset
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ACTIVE_DATASET, aDataset));
}

OTAPI
otError
OTCALL
otDatasetSetActive(
    _In_ otInstance *aInstance, 
    const otOperationalDataset *aDataset
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_ACTIVE_DATASET, aDataset));
}

OTAPI
otError
OTCALL
otDatasetGetPending(
    _In_ otInstance *aInstance, 
    _Out_ otOperationalDataset *aDataset
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PENDING_DATASET, aDataset));
}

OTAPI
otError
OTCALL
otDatasetSetPending(
    _In_ otInstance *aInstance, 
    const otOperationalDataset *aDataset
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PENDING_DATASET, aDataset));
}

OTAPI 
otError 
OTCALL
otDatasetSendMgmtActiveGet(
    _In_ otInstance *aInstance, 
    const uint8_t *aTlvTypes, 
    uint8_t aLength,
    _In_opt_ const otIp6Address *aAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvTypes == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(uint8_t) + aLength;
    if (aAddress) BufferSize += sizeof(otIp6Address);
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(uint8_t), aTlvTypes, aLength);
    if (aAddress)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + aLength, BufferSize - sizeof(GUID) - sizeof(uint8_t) - aLength, aAddress, sizeof(otIp6Address));
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_ACTIVE_GET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL
otDatasetSendMgmtActiveSet(
    _In_ otInstance *aInstance, 
    const otOperationalDataset *aDataset, 
    const uint8_t *aTlvs,
    uint8_t aLength
    )
{
    if (aInstance == nullptr || aDataset == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvs == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(otOperationalDataset) + sizeof(uint8_t) + aLength;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), aDataset, sizeof(otOperationalDataset));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otOperationalDataset), BufferSize - sizeof(GUID) - sizeof(otOperationalDataset), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(otOperationalDataset) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(otOperationalDataset) - sizeof(uint8_t), aTlvs, aLength);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_ACTIVE_SET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL
otDatasetSendMgmtPendingGet(
    _In_ otInstance *aInstance, 
    const uint8_t *aTlvTypes, 
    uint8_t aLength,
    _In_opt_ const otIp6Address *aAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvTypes == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(uint8_t) + aLength;
    if (aAddress) BufferSize += sizeof(otIp6Address);
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(uint8_t), aTlvTypes, aLength);
    if (aAddress)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + aLength, BufferSize - sizeof(GUID) - sizeof(uint8_t) - aLength, aAddress, sizeof(otIp6Address));
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_PENDING_GET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL
otDatasetSendMgmtPendingSet(
    _In_ otInstance *aInstance, 
    const otOperationalDataset *aDataset, 
    const uint8_t *aTlvs,
    uint8_t aLength
    )
{
    if (aInstance == nullptr || aDataset == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvs == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(otOperationalDataset) + sizeof(uint8_t) + aLength;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), aDataset, sizeof(otOperationalDataset));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otOperationalDataset), BufferSize - sizeof(GUID) - sizeof(otOperationalDataset), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(otOperationalDataset) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(otOperationalDataset) - sizeof(uint8_t), aTlvs, aLength);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_PENDING_SET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
uint32_t 
OTCALL
otLinkGetPollPeriod(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_POLL_PERIOD, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otLinkSetPollPeriod(
    _In_ otInstance *aInstance, 
    uint32_t aPollPeriod
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_POLL_PERIOD, aPollPeriod);
}

OTAPI
uint8_t 
OTCALL
otThreadGetLocalLeaderWeight(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LOCAL_LEADER_WEIGHT, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetLocalLeaderWeight(
    _In_ otInstance *aInstance, 
    uint8_t aWeight
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_LOCAL_LEADER_WEIGHT, aWeight);
}

OTAPI 
uint32_t 
OTCALL
otThreadGetLocalLeaderPartitionId(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LOCAL_LEADER_PARTITION_ID, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otThreadSetLocalLeaderPartitionId(
    _In_ otInstance *aInstance, 
    uint32_t aPartitionId
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_LOCAL_LEADER_PARTITION_ID, aPartitionId);
}

OTAPI 
uint16_t 
OTCALL 
otThreadGetJoinerUdpPort(
    _In_ otInstance *aInstance
)
{
    uint16_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_UDP_PORT, &Result);
    return Result;
}

OTAPI 
otError 
OTCALL 
otThreadSetJoinerUdpPort(
    _In_ otInstance *aInstance, 
    uint16_t aJoinerUdpPort
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_UDP_PORT, aJoinerUdpPort));
}

OTAPI
otError
OTCALL
otBorderRouterAddOnMeshPrefix(
    _In_ otInstance *aInstance, 
    const otBorderRouterConfig *aConfig
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_ADD_BORDER_ROUTER, aConfig));
}

OTAPI
otError
OTCALL
otBorderRouterRemoveOnMeshPrefix(
    _In_ otInstance *aInstance, 
    const otIp6Prefix *aPrefix
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_REMOVE_BORDER_ROUTER, aPrefix));
}

OTAPI
otError
OTCALL
otBorderRouterAddRoute(
    _In_ otInstance *aInstance, 
    const otExternalRouteConfig *aConfig
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_ADD_EXTERNAL_ROUTE, aConfig));
}

OTAPI
otError
OTCALL
otBorderRouterRemoveRoute(
    _In_ otInstance *aInstance, 
    const otIp6Prefix *aPrefix
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_REMOVE_EXTERNAL_ROUTE, aPrefix));
}

OTAPI
otError
OTCALL
otBorderRouterRegister(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_SEND_SERVER_DATA));
}

OTAPI
uint32_t 
OTCALL
otThreadGetContextIdReuseDelay(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_CONTEXT_ID_REUSE_DELAY, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetContextIdReuseDelay(
    _In_ otInstance *aInstance, 
    uint32_t aDelay
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_CONTEXT_ID_REUSE_DELAY, aDelay);
}

OTAPI
uint32_t 
OTCALL
otThreadGetKeySequenceCounter(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_KEY_SEQUENCE_COUNTER, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetKeySequenceCounter(
    _In_ otInstance *aInstance, 
    uint32_t aKeySequenceCounter
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_KEY_SEQUENCE_COUNTER, aKeySequenceCounter);
}

OTAPI
uint32_t 
OTCALL
otThreadGetKeySwitchGuardTime(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_KEY_SWITCH_GUARDTIME, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetKeySwitchGuardTime(
    _In_ otInstance *aInstance, 
    uint32_t aKeySwitchGuardTime
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_KEY_SWITCH_GUARDTIME, aKeySwitchGuardTime);
}

OTAPI
uint8_t
OTCALL
otThreadGetNetworkIdTimeout(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_NETWORK_ID_TIMEOUT, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetNetworkIdTimeout(
    _In_ otInstance *aInstance, 
    uint8_t aTimeout
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_NETWORK_ID_TIMEOUT, aTimeout);
}

OTAPI
uint8_t 
OTCALL
otThreadGetRouterUpgradeThreshold(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_UPGRADE_THRESHOLD, &Result);
    return Result;
}

OTAPI
void 
OTCALL
otThreadSetRouterUpgradeThreshold(
    _In_ otInstance *aInstance, 
    uint8_t aThreshold
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_UPGRADE_THRESHOLD, aThreshold);
}

OTAPI 
uint8_t 
OTCALL
otThreadGetRouterDowngradeThreshold(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_DOWNGRADE_THRESHOLD, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otThreadSetRouterDowngradeThreshold(
    _In_ otInstance *aInstance, 
    uint8_t aThreshold
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_DOWNGRADE_THRESHOLD, aThreshold);
}

OTAPI 
uint8_t 
OTCALL
otThreadGetRouterSelectionJitter(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_SELECTION_JITTER, &Result);
    return Result;
}

OTAPI 
void 
OTCALL
otThreadSetRouterSelectionJitter(
    _In_ otInstance *aInstance, 
    uint8_t aRouterJitter
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_SELECTION_JITTER, aRouterJitter);
}

OTAPI
otError
OTCALL
otThreadReleaseRouterId(
    _In_ otInstance *aInstance, 
    uint8_t aRouterId
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_RELEASE_ROUTER_ID, aRouterId));
}

OTAPI
otError
OTCALL
otLinkAddWhitelist(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_ADD_MAC_WHITELIST, (const otExtAddress*)aExtAddr));
}

OTAPI
otError
OTCALL
otLinkAddWhitelistRssi(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr, 
    int8_t aRssi
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    
    PackedBuffer3<GUID,otExtAddress,int8_t> Buffer(aInstance->InterfaceGuid, *(otExtAddress*)aExtAddr, aRssi);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_ADD_MAC_WHITELIST, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI
void 
OTCALL
otLinkRemoveWhitelist(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_REMOVE_MAC_WHITELIST, (const otExtAddress*)aExtAddr);
}

OTAPI
otError
OTCALL
otLinkGetWhitelistEntry(
    _In_ otInstance *aInstance, 
    uint8_t aIndex, 
    _Out_ otMacWhitelistEntry *aEntry
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_WHITELIST_ENTRY, &aIndex, aEntry));
}

OTAPI
void 
OTCALL
otLinkClearWhitelist(
    _In_ otInstance *aInstance
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_CLEAR_MAC_WHITELIST);
}

OTAPI
void 
OTCALL
otLinkSetWhitelistEnabled(
    _In_ otInstance *aInstance,
    bool aEnabled
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_WHITELIST_ENABLED, (BOOLEAN)aEnabled);
}

OTAPI
bool 
OTCALL
otLinkIsWhitelistEnabled(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_WHITELIST_ENABLED, &Result);
    return Result != FALSE;
}

OTAPI
otError
OTCALL
otThreadBecomeDetached(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_DEVICE_ROLE, (uint8_t)OT_DEVICE_ROLE_DETACHED));
}

OTAPI
otError
OTCALL
otThreadBecomeChild(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_DEVICE_ROLE, (uint8_t)OT_DEVICE_ROLE_CHILD));
}

OTAPI
otError
OTCALL
otThreadBecomeRouter(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_DEVICE_ROLE, (uint8_t)OT_DEVICE_ROLE_ROUTER));
}

OTAPI
otError
OTCALL
otThreadBecomeLeader(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_DEVICE_ROLE, (uint8_t)OT_DEVICE_ROLE_LEADER));
}

OTAPI
otError
OTCALL
otLinkAddBlacklist(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_ADD_MAC_BLACKLIST, (const otExtAddress*)aExtAddr));
}

OTAPI
void 
OTCALL
otLinkRemoveBlacklist(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_REMOVE_MAC_BLACKLIST, (const otExtAddress*)aExtAddr);
}

OTAPI
otError
OTCALL
otLinkGetBlacklistEntry(
    _In_ otInstance *aInstance, 
    uint8_t aIndex, 
    _Out_ otMacBlacklistEntry *aEntry
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_BLACKLIST_ENTRY, &aIndex, aEntry));
}

OTAPI
void 
OTCALL
otLinkClearBlacklist(
    _In_ otInstance *aInstance
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_CLEAR_MAC_BLACKLIST);
}

OTAPI
void 
OTCALL
otLinkSetBlacklistEnabled(
    _In_ otInstance *aInstance,
    bool aEnabled
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_BLACKLIST_ENABLED, (BOOLEAN)aEnabled);
}

OTAPI
bool 
OTCALL
otLinkIsBlacklistEnabled(
    _In_ otInstance *aInstance
    )
{
    BOOLEAN Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_BLACKLIST_ENABLED, &Result);
    return Result != FALSE;
}

OTAPI 
otError 
OTCALL
otLinkGetAssignLinkQuality(
    _In_ otInstance *aInstance, 
    const uint8_t *aExtAddr, 
    _Out_ uint8_t *aLinkQuality
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY, (otExtAddress*)aExtAddr, aLinkQuality));
}

OTAPI 
void 
OTCALL
otLinkSetAssignLinkQuality(
    _In_ otInstance *aInstance,
    const uint8_t *aExtAddr, 
    uint8_t aLinkQuality
    )
{
    if (aInstance == nullptr) return;
    PackedBuffer3<GUID,otExtAddress,uint8_t> Buffer(aInstance->InterfaceGuid, *(otExtAddress*)aExtAddr, aLinkQuality);
    (void)SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY, &Buffer, sizeof(Buffer), nullptr, 0);
}

OTAPI 
void 
OTCALL
otInstanceReset(
    _In_ otInstance *aInstance
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_PLATFORM_RESET);
}

OTAPI 
void 
OTCALL
otInstanceFactoryReset(
    _In_ otInstance *aInstance
    )
{
    if (aInstance) (void)SetIOCTL(aInstance, IOCTL_OTLWF_OT_FACTORY_RESET);
}

OTAPI
otError
OTCALL
otThreadGetChildInfoById(
    _In_ otInstance *aInstance, 
    uint16_t aChildId, 
    _Out_ otChildInfo *aChildInfo
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_CHILD_INFO_BY_ID, &aChildId, aChildInfo));
}

OTAPI
otError
OTCALL
otThreadGetChildInfoByIndex(
    _In_ otInstance *aInstance, 
    uint8_t aChildIndex, 
    _Out_ otChildInfo *aChildInfo
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_CHILD_INFO_BY_INDEX, &aChildIndex, aChildInfo));
}

OTAPI
otError
OTCALL
otThreadGetNextNeighborInfo(
    _In_ otInstance *aInstance,
    _Inout_ otNeighborInfoIterator *aIterator,
    _Out_ otNeighborInfo *aInfo
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    UNREFERENCED_PARAMETER(aIterator);
    UNREFERENCED_PARAMETER(aInfo);
    return OT_ERROR_NOT_IMPLEMENTED; // TODO
}

OTAPI
otDeviceRole 
OTCALL
otThreadGetDeviceRole(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = OT_DEVICE_ROLE_DISABLED;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_DEVICE_ROLE, &Result);
    return (otDeviceRole)Result;
}

OTAPI
otError
OTCALL
otThreadGetEidCacheEntry(
    _In_ otInstance *aInstance, 
    uint8_t aIndex, 
    _Out_ otEidCacheEntry *aEntry
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_EID_CACHE_ENTRY, &aIndex, aEntry));
}

OTAPI
otError
OTCALL
otThreadGetLeaderData(
    _In_ otInstance *aInstance, 
    _Out_ otLeaderData *aLeaderData
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LEADER_DATA, aLeaderData));
}

OTAPI
uint8_t 
OTCALL
otThreadGetLeaderRouterId(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LEADER_ROUTER_ID, &Result);
    return Result;
}

OTAPI
uint8_t 
OTCALL
otThreadGetLeaderWeight(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LEADER_WEIGHT, &Result);
    return Result;
}

OTAPI
uint8_t 
OTCALL
otNetDataGetVersion(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_NETWORK_DATA_VERSION, &Result);
    return Result;
}

OTAPI
uint32_t 
OTCALL
otThreadGetPartitionId(
    _In_ otInstance *aInstance
    )
{
    uint32_t Result = 0xFFFFFFFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PARTITION_ID, &Result);
    return Result;
}

OTAPI
uint16_t 
OTCALL
otThreadGetRloc16(
    _In_ otInstance *aInstance
    )
{
    uint16_t Result = 0xFFFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_RLOC16, &Result);
    return Result;
}

OTAPI
uint8_t 
OTCALL
otThreadGetRouterIdSequence(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_ID_SEQUENCE, &Result);
    return Result;
}

OTAPI
otError
OTCALL
otThreadGetRouterInfo(
    _In_ otInstance *aInstance, 
    uint16_t aRouterId, 
    _Out_ otRouterInfo *aRouterInfo
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_ROUTER_INFO, &aRouterId, aRouterInfo));
}

OTAPI 
otError 
OTCALL
otThreadGetParentInfo(
    _In_ otInstance *aInstance, 
    _Out_ otRouterInfo *aParentInfo
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    static_assert(sizeof(otRouterInfo) == 20, "The size of otRouterInfo should be 20 bytes");
    return DwordToThreadError(QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PARENT_INFO, aParentInfo));
}

OTAPI
uint8_t 
OTCALL
otNetDataGetStableVersion(
    _In_ otInstance *aInstance
    )
{
    uint8_t Result = 0xFF;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_STABLE_NETWORK_DATA_VERSION, &Result);
    return Result;
}

OTAPI
const otMacCounters*
OTCALL
otLinkGetCounters(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return nullptr;

    otMacCounters* aCounters = (otMacCounters*)malloc(sizeof(otMacCounters));
    if (aCounters)
    {
        if (ERROR_SUCCESS != QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MAC_COUNTERS, aCounters))
        {
            free(aCounters);
            aCounters = nullptr;
        }
    }
    return aCounters;
}

OTAPI
void
OTCALL
otMessageGetBufferInfo(
    _In_ otInstance *,
    _Out_ otBufferInfo *aBufferInfo
    )
{
    // Not supported on Windows
    ZeroMemory(aBufferInfo, sizeof(otBufferInfo));
}

OTAPI
bool 
OTCALL
otIsIp6AddressEqual(
    const otIp6Address *a, 
    const otIp6Address *b
    )
{
    return memcmp(a->mFields.m8, b->mFields.m8, sizeof(otIp6Address)) == 0;
}

OTAPI
otError 
OTCALL
otIp6AddressFromString(
    const char *str, 
    otIp6Address *address
    )
{
    otError error = OT_ERROR_NONE;
    uint8_t *dst = reinterpret_cast<uint8_t *>(address->mFields.m8);
    uint8_t *endp = reinterpret_cast<uint8_t *>(address->mFields.m8 + 15);
    uint8_t *colonp = NULL;
    uint16_t val = 0;
    uint8_t count = 0;
    bool first = true;
    char ch;
    uint8_t d;

    memset(address->mFields.m8, 0, 16);

    dst--;

    for (;;)
    {
        ch = *str++;
        d = ch & 0xf;

        if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F'))
        {
            d += 9;
        }
        else if (ch == ':' || ch == '\0' || ch == ' ')
        {
            if (count)
            {
                if (dst + 2 > endp)
                {
                    error = OT_ERROR_PARSE;
                    goto exit;
                }
                *(dst + 1) = static_cast<uint8_t>(val >> 8);
                *(dst + 2) = static_cast<uint8_t>(val);
                dst += 2;
                count = 0;
                val = 0;
            }
            else if (ch == ':')
            {
                if (!(colonp == nullptr || first))
                {
                    error = OT_ERROR_PARSE;
                    goto exit;
                }
                colonp = dst;
            }

            if (ch == '\0' || ch == ' ')
            {
                break;
            }

            continue;
        }
        else
        {
            if (!('0' <= ch && ch <= '9'))
            {
                error = OT_ERROR_PARSE;
                goto exit;
            }
        }

        first = false;
        val = static_cast<uint16_t>((val << 4) | d);
        if (!(++count <= 4))
        {
            error = OT_ERROR_PARSE;
            goto exit;
        }
    }

    while (colonp && dst > colonp)
    {
        *endp-- = *dst--;
    }

    while (endp > dst)
    {
        *endp-- = 0;
    }

exit:
    return error;
}

OTAPI 
uint8_t 
OTCALL
otIp6PrefixMatch(
    const otIp6Address *aFirst, 
    const otIp6Address *aSecond
    )
{
    uint8_t rval = 0;
    uint8_t diff;

    for (uint8_t i = 0; i < sizeof(otIp6Address); i++)
    {
        diff = aFirst->mFields.m8[i] ^ aSecond->mFields.m8[i];

        if (diff == 0)
        {
            rval += 8;
        }
        else
        {
            while ((diff & 0x80) == 0)
            {
                rval++;
                diff <<= 1;
            }

            break;
        }
    }

    return rval;
}

OTAPI
const char *
OTCALL
otThreadErrorToString(
    otError aError
    )
{
    const char *retval;

    switch (aError)
    {
    case OT_ERROR_NONE:
        retval = "None";
        break;

    case OT_ERROR_FAILED:
        retval = "Failed";
        break;

    case OT_ERROR_DROP:
        retval = "Drop";
        break;

    case OT_ERROR_NO_BUFS:
        retval = "NoBufs";
        break;

    case OT_ERROR_NO_ROUTE:
        retval = "NoRoute";
        break;

    case OT_ERROR_BUSY:
        retval = "Busy";
        break;

    case OT_ERROR_PARSE:
        retval = "Parse";
        break;

    case OT_ERROR_INVALID_ARGS:
        retval = "InvalidArgs";
        break;

    case OT_ERROR_SECURITY:
        retval = "Security";
        break;

    case OT_ERROR_ADDRESS_QUERY:
        retval = "AddressQuery";
        break;

    case OT_ERROR_NO_ADDRESS:
        retval = "NoAddress";
        break;

    case OT_ERROR_ABORT:
        retval = "Abort";
        break;

    case OT_ERROR_NOT_IMPLEMENTED:
        retval = "NotImplemented";
        break;

    case OT_ERROR_INVALID_STATE:
        retval = "InvalidState";
        break;

    case OT_ERROR_NO_ACK:
        retval = "NoAck";
        break;

    case OT_ERROR_CHANNEL_ACCESS_FAILURE:
        retval = "ChannelAccessFailure";
        break;

    case OT_ERROR_DETACHED:
        retval = "Detached";
        break;

    case OT_ERROR_FCS:
        retval = "FcsErr";
        break;

    case OT_ERROR_NO_FRAME_RECEIVED:
        retval = "NoFrameReceived";
        break;

    case OT_ERROR_UNKNOWN_NEIGHBOR:
        retval = "UnknownNeighbor";
        break;

    case OT_ERROR_INVALID_SOURCE_ADDRESS:
        retval = "InvalidSourceAddress";
        break;

    case OT_ERROR_WHITELIST_FILTERED:
        retval = "WhitelistFiltered";
        break;

    case OT_ERROR_DESTINATION_ADDRESS_FILTERED:
        retval = "DestinationAddressFiltered";
        break;

    case OT_ERROR_NOT_FOUND:
        retval = "NotFound";
        break;

    case OT_ERROR_ALREADY:
        retval = "Already";
        break;

    case OT_ERROR_BLACKLIST_FILTERED:
        retval = "BlacklistFiltered";
        break;

    case OT_ERROR_IP6_ADDRESS_CREATION_FAILURE:
        retval = "Ipv6AddressCreationFailure";
        break;

    case OT_ERROR_NOT_CAPABLE:
        retval = "NotCapable";
        break;

    case OT_ERROR_RESPONSE_TIMEOUT:
        retval = "ResponseTimeout";
        break;

    case OT_ERROR_DUPLICATED:
        retval = "Duplicated";
        break;

    case OT_ERROR_GENERIC:
        retval = "GenericError";
        break;

    default:
        retval = "UnknownErrorType";
        break;
    }

    return retval;
}

OTAPI 
otError 
OTCALL 
otThreadSendDiagnosticGet(
    _In_ otInstance *aInstance, 
    const otIp6Address *aDestination, 
    const uint8_t aTlvTypes[],
    uint8_t aCount
    )
{
    if (aInstance == nullptr || aDestination == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvTypes == nullptr && aCount != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(otIp6Address) + sizeof(uint8_t) + aCount;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), aDestination, sizeof(otIp6Address));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otIp6Address), BufferSize - sizeof(GUID) - sizeof(otIp6Address), &aCount, sizeof(aCount));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otIp6Address) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(otIp6Address) - sizeof(uint8_t), aTlvTypes, aCount);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_GET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL 
otThreadSendDiagnosticReset(
    _In_ otInstance *aInstance, 
    const otIp6Address *aDestination, 
    const uint8_t aTlvTypes[],
    uint8_t aCount
    )
{
    if (aInstance == nullptr || aDestination == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvTypes == nullptr && aCount != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(otIp6Address) + sizeof(uint8_t) + aCount;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), aDestination, sizeof(otIp6Address));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otIp6Address), BufferSize - sizeof(GUID) - sizeof(otIp6Address), &aCount, sizeof(aCount));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otIp6Address) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(otIp6Address) - sizeof(uint8_t), aTlvTypes, aCount);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_DIAGNOSTIC_RESET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL
otCommissionerStart(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_COMMISIONER_START));
}

OTAPI 
otError 
OTCALL
otCommissionerAddJoiner(
    _In_ otInstance *aInstance, 
    const otExtAddress *aExtAddress, 
    const char *aPSKd,
    uint32_t aTimeout
    )
{
    if (aInstance == nullptr || aPSKd == nullptr) return OT_ERROR_INVALID_ARGS;

    size_t aPSKdLength = strnlen(aPSKd, OPENTHREAD_PSK_MAX_LENGTH + 1);
    if (aPSKdLength > OPENTHREAD_PSK_MAX_LENGTH)
    {
        return OT_ERROR_INVALID_ARGS;
    }

    uint8_t aExtAddressValid = aExtAddress ? 1 : 0;
    
    const ULONG BufferLength = sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + (ULONG)aPSKdLength + 1 + sizeof(aTimeout);
    BYTE Buffer[sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + OPENTHREAD_PSK_MAX_LENGTH + 1 + sizeof(aTimeout)] = {0};
    memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), &aExtAddressValid, sizeof(aExtAddressValid));
    if (aExtAddressValid)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t), aExtAddress, sizeof(otExtAddress));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress), sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t) - sizeof(otExtAddress), aPSKd, aPSKdLength);
    memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress) + aPSKdLength + 1, sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t) - sizeof(otExtAddress) - aPSKdLength - 1, &aTimeout, sizeof(aTimeout));
    
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISIONER_ADD_JOINER, Buffer, BufferLength, nullptr, 0));
}

OTAPI 
otError 
OTCALL
otCommissionerRemoveJoiner(
    _In_ otInstance *aInstance, 
    const otExtAddress *aExtAddress
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    uint8_t aExtAddressValid = aExtAddress ? 1 : 0;
    
    BYTE Buffer[sizeof(GUID) + sizeof(uint8_t) + sizeof(otExtAddress)] = {0};
    memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), &aExtAddressValid, sizeof(aExtAddressValid));
    if (aExtAddressValid)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), sizeof(Buffer) - sizeof(GUID) - sizeof(uint8_t), aExtAddress, sizeof(otExtAddress));

    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISIONER_REMOVE_JOINER, Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
otError 
OTCALL
otCommissionerSetProvisioningUrl(
    _In_ otInstance *aInstance,
    const char *aProvisioningUrl
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    size_t aProvisioningUrlLength = aProvisioningUrl ? strnlen(aProvisioningUrl, OPENTHREAD_PROV_URL_MAX_LENGTH + 1) : 0;
    if (aProvisioningUrlLength > OPENTHREAD_PROV_URL_MAX_LENGTH)
    {
        return OT_ERROR_INVALID_ARGS;
    }
    
    const ULONG BufferLength = sizeof(GUID) + (ULONG)aProvisioningUrlLength + 1;
    BYTE Buffer[sizeof(GUID) + OPENTHREAD_PROV_URL_MAX_LENGTH + 1] = {0};
    memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
    if (aProvisioningUrlLength > 0)
        memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), aProvisioningUrl, aProvisioningUrlLength);
    
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISIONER_PROVISIONING_URL, Buffer, BufferLength, nullptr, 0));
}

OTAPI
otError
OTCALL
otCommissionerAnnounceBegin(
    otInstance *aInstance,
    uint32_t aChannelMask,
    uint8_t aCount,
    uint16_t aPeriod,
    const otIp6Address *aAddress
    )
{
    if (aInstance == nullptr || aAddress == nullptr) return OT_ERROR_INVALID_ARGS;

    PackedBuffer5<GUID,uint32_t,uint8_t,uint16_t,otIp6Address> Buffer(aInstance->InterfaceGuid, aChannelMask, aCount, aPeriod, *aAddress);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISIONER_ANNOUNCE_BEGIN, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
otError 
OTCALL
otCommissionerStop(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_COMMISIONER_STOP));
}

OTAPI
otError 
OTCALL
otCommissionerEnergyScan(
    _In_ otInstance *aInstance, 
    uint32_t aChannelMask, 
    uint8_t aCount, 
    uint16_t aPeriod,
    uint16_t aScanDuration, 
    const otIp6Address *aAddress,
    _In_ otCommissionerEnergyReportCallback aCallback, 
    _In_ void *aContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->CommissionerEnergyReportCallbacks,
        aInstance->InterfaceGuid, aCallback, aContext
        );

    PackedBuffer6<GUID,uint32_t,uint8_t,uint16_t,uint16_t,otIp6Address> Buffer(aInstance->InterfaceGuid, aChannelMask, aCount, aPeriod, aScanDuration, *aAddress);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISSIONER_ENERGY_SCAN, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI
otError 
OTCALL
otCommissionerPanIdQuery(
    _In_ otInstance *aInstance, 
    uint16_t aPanId, 
    uint32_t aChannelMask,
    const otIp6Address *aAddress,
    _In_ otCommissionerPanIdConflictCallback aCallback, 
    _In_ void *aContext
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->CommissionerPanIdConflictCallbacks,
        aInstance->InterfaceGuid, aCallback, aContext
        );

    PackedBuffer4<GUID,uint16_t,uint32_t,otIp6Address> Buffer(aInstance->InterfaceGuid, aPanId, aChannelMask, *aAddress);
    return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_COMMISSIONER_PANID_QUERY, &Buffer, sizeof(Buffer), nullptr, 0));
}

OTAPI 
otError 
OTCALL 
otCommissionerSendMgmtGet(
    _In_ otInstance *aInstance, 
    const uint8_t *aTlvs, 
    uint8_t aLength
)
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvs == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(uint8_t) + aLength;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(uint8_t), aTlvs, aLength);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_GET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI 
otError 
OTCALL 
otCommissionerSendMgmtSet(
    _In_ otInstance *aInstance,
    const otCommissioningDataset *aDataset,
    const uint8_t *aTlvs,
    uint8_t aLength
    )
{
    if (aInstance == nullptr || aDataset == nullptr) return OT_ERROR_INVALID_ARGS;
    if (aTlvs == nullptr && aLength != 0) return OT_ERROR_INVALID_ARGS;
    
    DWORD BufferSize = sizeof(GUID) + sizeof(otCommissioningDataset) + sizeof(uint8_t) + aLength;
    PBYTE Buffer = (PBYTE)malloc(BufferSize);
    if (Buffer == nullptr) return OT_ERROR_NO_BUFS;

    memcpy_s(Buffer, BufferSize, &aInstance->InterfaceGuid, sizeof(GUID));
    memcpy_s(Buffer + sizeof(GUID), BufferSize - sizeof(GUID), aDataset, sizeof(otCommissioningDataset));
    memcpy_s(Buffer + sizeof(GUID) + sizeof(otCommissioningDataset), BufferSize - sizeof(GUID) - sizeof(otCommissioningDataset), &aLength, sizeof(aLength));
    if (aLength > 0)
        memcpy_s(Buffer + sizeof(GUID) + sizeof(otCommissioningDataset) + sizeof(uint8_t), BufferSize - sizeof(GUID) - sizeof(otCommissioningDataset) - sizeof(uint8_t), aTlvs, aLength);
    
    otError result = 
        DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_SEND_MGMT_COMMISSIONER_SET, Buffer, BufferSize, nullptr, 0));

    free(Buffer);
    return result;
}

OTAPI
uint16_t
OTCALL
otCommissionerGetSessionId(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return 0;
    // TODO
    return 0;
}

OTAPI 
otError 
OTCALL
otJoinerStart(
    _In_ otInstance *aInstance,
    _Null_terminated_ const char *aPSKd,
    _Null_terminated_ const char *aProvisioningUrl,
    _Null_terminated_ const char *aVendorName,
    _Null_terminated_ const char *aVendorModel,
    _Null_terminated_ const char *aVendorSwVersion,
    _Null_terminated_ const char *aVendorData,
    _In_ otJoinerCallback aCallback,
    _In_ void *aCallbackContext
    )
{
    if (aInstance == nullptr || aPSKd == nullptr) return OT_ERROR_INVALID_ARGS;

    otCommissionConfig config = {0};

    size_t aPSKdLength = strlen(aPSKd);
    size_t aProvisioningUrlLength = aProvisioningUrl == nullptr ? 0 : strlen(aProvisioningUrl);
    size_t aVendorNameLength = aVendorName == nullptr ? 0 : strlen(aVendorName);
    size_t aVendorModelLength = aVendorModel == nullptr ? 0 : strlen(aVendorModel);
    size_t aVendorSwVersionLength = aVendorSwVersion == nullptr ? 0 : strlen(aVendorSwVersion);
    size_t aVendorDataLength = aVendorData == nullptr ? 0 : strlen(aVendorData);

    if (aPSKdLength > OPENTHREAD_PSK_MAX_LENGTH ||
        aProvisioningUrlLength > OPENTHREAD_PROV_URL_MAX_LENGTH ||
        aVendorNameLength > OPENTHREAD_VENDOR_NAME_MAX_LENGTH ||
        aVendorModelLength > OPENTHREAD_VENDOR_MODEL_MAX_LENGTH ||
        aVendorSwVersionLength > OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH ||
        aVendorDataLength > OPENTHREAD_VENDOR_DATA_MAX_LENGTH)
    {
        return OT_ERROR_INVALID_ARGS;
    }

    memcpy_s(config.PSKd, sizeof(config.PSKd), aPSKd, aPSKdLength);
    memcpy_s(config.ProvisioningUrl, sizeof(config.ProvisioningUrl), aProvisioningUrl, aProvisioningUrlLength);
    memcpy_s(config.VendorName, sizeof(config.VendorName), aVendorName, aVendorNameLength);
    memcpy_s(config.VendorModel, sizeof(config.VendorModel), aVendorModel, aVendorModelLength);
    memcpy_s(config.VendorSwVersion, sizeof(config.VendorSwVersion), aVendorSwVersion, aVendorSwVersionLength);
    memcpy_s(config.VendorData, sizeof(config.VendorData), aVendorData, aVendorDataLength);

    aInstance->ApiHandle->SetCallback(
        aInstance->ApiHandle->JoinerCallbacks,
        aInstance->InterfaceGuid, aCallback, aCallbackContext
        );

    auto ret = DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_START, (const otCommissionConfig*)&config));

    if (ret != OT_ERROR_NONE)
    {
        aInstance->ApiHandle->SetCallback(
            aInstance->ApiHandle->JoinerCallbacks,
            aInstance->InterfaceGuid, (otJoinerCallback)nullptr, (PVOID)nullptr
            );
    }

    return ret;
}

OTAPI 
otError 
OTCALL
otJoinerStop(
    _In_ otInstance *aInstance
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_STOP));
}

OTAPI
int8_t
OTCALL
otThreadGetParentPriority(
    _In_ otInstance *aInstance
)
{
    int8_t Result = 0;
    if (aInstance) (void)QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PARENT_PRIORITY, &Result);
    return Result;
}

OTAPI
otError
OTCALL
otThreadSetParentPriority(
    _In_ otInstance *aInstance,
    int8_t aParentPriority
    )
{
    if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS;
    return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PARENT_PRIORITY, aParentPriority));
}
