/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements NLWeaveDeviceManager interface
 *
 */

#import <Foundation/Foundation.h>
#import "NLWeaveStack.h"
#import "NLLogging.h"

#include <Weave/Core/WeaveError.h>

#include <Weave/Support/CodeUtils.h>

#include <WeaveDeviceManager.h>

#include <net/if.h>

#import "NLWeaveBleDelegate.h"
#import "NLWeaveDeviceManager_Protected.h"
#import "NLWeaveDeviceDescriptor_Protected.h"
#import "NLWeaveHushResponse_Protected.h"
#import "NLNetworkInfo_Protected.h"
#import "NLProfileStatusError.h"
#import "NLWeaveError_Protected.h"
#include <Weave/Profiles/device-description/DeviceDescription.h>
#import "NLIdentifyDeviceCriteria_Protected.h"
#import "Base64Encoding.h"

static void onIdentifyDeviceComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *appReqState, const nl::Weave::DeviceManager::DeviceDescription::WeaveDeviceDescriptor *devdesc);

@interface NLWeaveDeviceManager ()
{
    nl::Weave::DeviceManager::WeaveDeviceManager * _mWeaveCppDM;
    dispatch_queue_t _mWeaveWorkQueue;
    dispatch_queue_t _mAppCallbackQueue;

    // Note that these context variables are independent from context variables in the C++ Weave Device Manager,
    // for the C++ Weave Device Manager only takes one pointer as the app context, which is not enough to hold all
    // context information we need.
    WDMCompletionBlock _mCompletionHandler;
    WDMFailureBlock _mFailureHandler;
    NSString * _mRequestName;

    CBPeripheral * _blePeripheral;
}

-(NSString*)GetCurrentRequest;

@end

@implementation NLWeaveDeviceManager

@synthesize blePeripheral = _blePeripheral;
@synthesize resultCallbackQueue = _mAppCallbackQueue;

/**
 @note
 This function can only be called by the ARC runtime
 */
- (void)dealloc
{
    // This method can only be called by ARC
    // Let's not rely on this unpredictable mechanism for de-initialization
    // application shall call ShutdownStack if it want to cleanly destroy everything before application termination
    WDM_LOG_METHOD_SIG();

    [self MarkTransactionCompleted];

    _mRequestName = @"dealloc-Shutdown";

    // we need to force the queue to be Weave work queue, as dealloc could be
    // called at random queues (most probably from UI, when the app de-reference this device manager)
    dispatch_sync(_mWeaveWorkQueue, ^()
    {
        [self Shutdown_Internal];
    });
}

- (instancetype)init:(NSString*)name
      weaveWorkQueue:(dispatch_queue_t)weaveWorkQueue
    appCallbackQueue:(dispatch_queue_t)appCallbackQueue
         exchangeMgr:(nl::Weave::WeaveExchangeManager*)exchangeMgr
         securityMgr:(nl::Weave::WeaveSecurityManager *)securityMgr
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    WDM_LOG_METHOD_SIG();

    self = [super init];
    VerifyOrExit(nil != self, err = WEAVE_ERROR_NO_MEMORY);

    _mWeaveWorkQueue = weaveWorkQueue;
    _mAppCallbackQueue = appCallbackQueue;

    _name = name;

    _mWeaveCppDM = new nl::Weave::DeviceManager::WeaveDeviceManager();
    VerifyOrExit(NULL != _mWeaveCppDM, err = WEAVE_ERROR_NO_MEMORY);

    err = _mWeaveCppDM->Init(exchangeMgr, securityMgr);
    SuccessOrExit(err);

    _mWeaveCppDM->SetConnectTimeout(60000);

    // simple bridge shall not increase our reference count
    _mWeaveCppDM->AppState = (__bridge void *)self;

    [self MarkTransactionCompleted];

exit:
    id result = nil;
    if (WEAVE_NO_ERROR == err)
    {
        result = self;
    }
    else
    {
        WDM_LOG_ERROR(@"Error in init : (%d) %@\n", err, [NSString stringWithUTF8String:nl::ErrorStr(err)]);

        [self Shutdown_Internal];
    }
    return result;
}

-(void)MarkTransactionCompleted
{
    _mRequestName = nil;
    _mCompletionHandler = nil;
    _mFailureHandler = nil;
}

-(NSString*)GetCurrentRequest
{
    return _mRequestName;
}

-(void)DispatchAsyncFailureBlock:(WEAVE_ERROR)code taskName:(NSString*)taskName handler:(WDMFailureBlock)handler
{
    NSError *error = [NSError errorWithDomain:@"com.nest.error"
                                         code:code
                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:nl::ErrorStr(code)], @"error", nil]];
    [self DispatchAsyncFailureBlockWithError:error taskName:taskName handler:handler];
}

-(void)DispatchAsyncFailureBlockWithError:(NSError *)error taskName:(NSString*)taskName handler:(WDMFailureBlock)handler
{
    if (NULL != handler)
    {
        // we use async because we don't need to wait for completion of this final completion report
        dispatch_async(_mAppCallbackQueue, ^()
        {
            WDM_LOG_DEBUG(@"%@: Calling failure handler for %@", _name, taskName);
            handler(_owner, error);
        });
    }
    else
    {
        WDM_LOG_DEBUG(@"%@: Skipping failure handler for %@", _name, taskName);
    }
}

-(void)DispatchAsyncDefaultFailureBlockWithCode:(WEAVE_ERROR)code
{
    NSError *error = [NSError errorWithDomain:@"com.nest.error"
                                         code:code
                                     userInfo:nil];
    [self DispatchAsyncDefaultFailureBlock:error];
}

-(void)DispatchAsyncDefaultFailureBlock:(NSError *)error
{
    NSString * taskName = _mRequestName;
    WDMFailureBlock failureHandler = _mFailureHandler;

    [self MarkTransactionCompleted];
    [self DispatchAsyncFailureBlockWithError:error taskName:taskName handler:failureHandler];
}

-(void)DispatchAsyncCompletionBlock:(id)data
{
    WDMCompletionBlock completionHandler = _mCompletionHandler;

    [self MarkTransactionCompleted];

    if (nil != completionHandler)
    {
        dispatch_async(_mAppCallbackQueue, ^()
        {
            completionHandler(_owner, data);
        });
    }
}

-(void)DispatchAsyncResponseBlock:(id)data
{
    WDMCompletionBlock completionHandler = _mCompletionHandler;

    if (nil != completionHandler)
    {
        dispatch_async(_mAppCallbackQueue, ^()
        {
            completionHandler(_owner, data);
        });
    }
}

-(NSString *)toErrorString:(WEAVE_ERROR)err
{
    WDM_LOG_METHOD_SIG();

    __block NSString * msg = nil;

    dispatch_sync(_mWeaveWorkQueue, ^()
    {
        msg = [NSString stringWithUTF8String:nl::ErrorStr(err)];
    });

    return msg;
}

-(NSString *)statusReportToString:(NSUInteger)profileId statusCode:(NSInteger)statusCode
{
    WDM_LOG_METHOD_SIG();

    NSString * report = nil;

    const char *result = nl::StatusReportStr((uint32_t)profileId, statusCode);

    if (result)
    {
        report = [NSString stringWithUTF8String:result];
    }

    return report;
}

-(void)Shutdown_Internal
{
    WDM_LOG_METHOD_SIG();

    // there is no need to release Objective C objects, as we have ARC for them
    if (_mWeaveCppDM)
    {
        WDM_LOG_ERROR(@"Shutdown C++ Weave Device Manager");

        if (_blePeripheral)
        {
            // this is a hack to avoid further callback from BleLayer after closign
            [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];
        }

        _mWeaveCppDM->Shutdown();

        delete _mWeaveCppDM;
        _mWeaveCppDM = NULL;
    }

    [self DispatchAsyncCompletionBlock:nil];
}

- (void)Shutdown:(WDMCompletionBlock)completionHandler
{
    WDM_LOG_METHOD_SIG();

    dispatch_async(_mWeaveWorkQueue, ^()
    {
        // Note that conceptually we probably should not call shutdown while we're still closing the device manager and vice versa,
        // but both Shutdown and Close are implemented in a synchronous way so there is really no chance for them to be intertwined.
        if (nil != _mRequestName)
        {
            WDM_LOG_ERROR(@"%@: Forcefully shutdown while we're still executing %@, continue shutdown", _name, _mRequestName);
        }

        [self MarkTransactionCompleted];

        _mCompletionHandler = completionHandler;
        _mRequestName = @"Shutdown";
        [self Shutdown_Internal];
    });
}

-(void)Close:(WDMCompletionBlock)completionHandler failure:(WDMFailureBlock)failureHandler;
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"Close";

    dispatch_async(_mWeaveWorkQueue, ^()
    {
        bool IsOKay = true;
        if (nil != _mRequestName)
        {
            // Note that conceptually we probably should not call shutdown while we're still closing the device manager and vice versa,
            // but both Shutdown and Close are implemented in a synchronous way so there is really no chance for them to be intertwined.
            if ([_mRequestName isEqualToString:@"Shutdown"])
            {
                IsOKay = false;
            }
        }

        if (IsOKay)
        {
            if (_blePeripheral)
            {
                // this is a hack to avoid further callback from BleLayer after closign
                [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];

                // release reference to the CBPeripheral
                // since device manager is the only one who holds a strong reference to this peripheral,
                // releasing it here cause immediate destruction and hence disconnection
                _blePeripheral = nil;
            }

            // Note that we're already in Weave work queue, which means all callbacks for the previous or current request
            // has either happened/completed or would be canceled by this call to Close. Therefore, it should be safe
            // to wipe out request context variables like _mRequestName and _mCompletionHandler.
            _mWeaveCppDM->Close();

            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            [self DispatchAsyncCompletionBlock:nil];
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

-(BOOL)isConnected
{
    __block bool result = false;

    WDM_LOG_METHOD_SIG();

    // we use sync so the result is immediately available to the caller upon return
    dispatch_sync(_mWeaveWorkQueue, ^()
    {
        result = _mWeaveCppDM->IsConnected();
    });

    return result ? YES : NO;
}

-(BOOL)isValidPairingCode:(NSString *)pairingCode;
{
    __block bool result = false;

    WDM_LOG_METHOD_SIG();

    if ([pairingCode length] != 0)
    {
        // note we're not executing in any specific queue, as this subroutine is supposed to be 'static'
        result = nl::Weave::DeviceManager::WeaveDeviceManager::IsValidPairingCode([pairingCode UTF8String]);
    }

    return result ? YES : NO;
}

-(WEAVE_ERROR)GetDeviceId:(uint64_t*)deviceId
{
    __block WEAVE_ERROR err = WEAVE_NO_ERROR;
    __block uint64_t result = 0;

    WDM_LOG_METHOD_SIG();

    VerifyOrExit(NULL != _mWeaveCppDM, err = WEAVE_ERROR_INCORRECT_STATE);
    VerifyOrExit(NULL != deviceId, err = WEAVE_ERROR_INVALID_ARGUMENT);

    // need this bracket to use Verify macros
    {
        // we use sync so the result is immediately available to the caller upon return
        dispatch_sync(_mWeaveWorkQueue, ^()
        {
            err = _mWeaveCppDM->GetDeviceId(result);

            if (err == WEAVE_ERROR_INCORRECT_STATE)
            {
                WDM_LOG_DEBUG(@"Got incorrect state error from GetDeviceId, ignore");

                err = WEAVE_NO_ERROR; // No exception, just return 0.
                result = 0;
            }
        });
    }

exit:
    if ((WEAVE_NO_ERROR == err) && (NULL != deviceId))
    {
        *deviceId = result;
    }
    return err;
}

-(WEAVE_ERROR)GetDeviceAddress:(NSMutableString *)strAddr;
{
    __block WEAVE_ERROR err = WEAVE_NO_ERROR;
    __block NSString * strResult = nil;

    WDM_LOG_METHOD_SIG();

    VerifyOrExit(NULL != strAddr, err = WEAVE_ERROR_INVALID_ARGUMENT);

    // need this bracket to use Verify macros
    {
        // we use sync so the result is immediately available to the caller upon return
        dispatch_sync(_mWeaveWorkQueue, ^()
        {
            nl::Inet::IPAddress devAddr;
            err = _mWeaveCppDM->GetDeviceAddress(devAddr);
            if (WEAVE_NO_ERROR == err)
            {
                char devAddrStrBuf[32];
                strResult = [NSString stringWithUTF8String:devAddr.ToString(devAddrStrBuf, sizeof(devAddrStrBuf))];
            }
            else
            {
                strResult = @"";
            }
        });
    }

    [strAddr setString:strResult];

    if (err == WEAVE_ERROR_INCORRECT_STATE)
    {
        err = WEAVE_NO_ERROR; // No exception, just return null.
    }

exit:

    return err;
}

static void HandleSimpleOperationComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState)
{
    WDM_LOG_DEBUG(@"HandleSimpleOperationComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;
    [dm DispatchAsyncCompletionBlock:nil];
}

static void onIdentifyDeviceComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *appReqState, const nl::Weave::DeviceManager::DeviceDescription::WeaveDeviceDescriptor *devdesc)
{
    WDM_LOG_DEBUG(@"onIdentifyDeviceComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)appReqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;
    [dm DispatchAsyncCompletionBlock:[NLWeaveDeviceDescriptor createUsing:*devdesc]];
}

static void onWeaveError(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *appReqState, WEAVE_ERROR code, nl::Weave::DeviceManager::DeviceStatus *devStatus)
{
    WDM_LOG_DEBUG(@"onWeaveError");

    NSError *error = nil;
    NSDictionary *userInfo = nil;

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)appReqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    WDM_LOG_DEBUG(@"%@: Received error response to request %@, deviceMgrErr = %d, devStatus = %p\n", dm.name, [dm GetCurrentRequest], code, devStatus);

    NLWeaveRequestError requestError;
    if (devStatus != NULL && code == WEAVE_ERROR_STATUS_REPORT_RECEIVED)
    {
        NLProfileStatusError *statusError =
        [[NLProfileStatusError alloc] initWithProfileId:devStatus->StatusProfileId
                                             statusCode:devStatus->StatusCode
                                              errorCode:devStatus->SystemErrorCode
                                           statusReport:[dm statusReportToString:devStatus->StatusProfileId statusCode:devStatus->StatusCode]];
        requestError = NLWeaveRequestError_ProfileStatusError;
        userInfo = @{ @"WeaveRequestErrorType": @(requestError),
                      @"errorInfo": statusError };

        WDM_LOG_DEBUG(@"%@: status error: %@", dm.name, userInfo);
    }
    else
    {
        NLWeaveError *weaveError = [[NLWeaveError alloc] initWithWeaveError:code report:[NSString stringWithUTF8String:nl::ErrorStr(code)]];
        requestError = NLWeaveRequestError_WeaveError;
        userInfo = @{ @"WeaveRequestErrorType": @(requestError),
                      @"errorInfo": weaveError };
    }

    error = [NSError errorWithDomain:@"com.nest.error"
                                code:code
                            userInfo:userInfo];

    [dm DispatchAsyncDefaultFailureBlock:error];
}

-(void)identifyDevice:(WDMCompletionBlock)completionHandler failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"IdentifyDevice";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;

            WEAVE_ERROR err = _mWeaveCppDM->IdentifyDevice((__bridge void *)self, onIdentifyDeviceComplete, onWeaveError);

            if (WEAVE_NO_ERROR != err)
            {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
            }
         }
         else
         {
             WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

             // do not change _mRequestName, as we're rejecting this request
             [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
         }
     });
}


-(void)rendezvousWithDevicePairingCode:(NSString *)pairingCode
                            completion:(WDMCompletionBlock)completionHandler
                               failure:(WDMFailureBlock)failureHandler
{
    // Note that NLIdentifyDeviceCriteria::create an empty criteria, which shall meet all devices
    // The prior implementation for this function, however, puts a limitation on the device mode
    NLIdentifyDeviceCriteria * criteria = [NLIdentifyDeviceCriteria create];
    criteria.TargetModes = NLTargetDeviceModeUserSelectedMode;

    [self rendezvousWithDevicePairingCode:pairingCode identifyDeviceCriteria:criteria completion:completionHandler failure:failureHandler];
}

-(void)rendezvousWithDevicePairingCode:(NSString *)pairingCode
                identifyDeviceCriteria:(NLIdentifyDeviceCriteria *)identifyDeviceCriteria
                            completion:(WDMCompletionBlock)completionHandler
                               failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"RendezvousDevice";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;

            nl::Weave::Profiles::DeviceDescription::IdentifyDeviceCriteria deviceCriteria = [identifyDeviceCriteria toIdentifyDeviceCriteria];

            // note that RendezvousDevice interanlly makes a copy of the pairing code before return
            WEAVE_ERROR err = _mWeaveCppDM->RendezvousDevice(
                                [pairingCode UTF8String], deviceCriteria, (__bridge void *)self,
                                HandleSimpleOperationComplete, onWeaveError);

            if (WEAVE_NO_ERROR != err)
            {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
            }
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

- (void)rendezvousWithDeviceAccessToken:(NSString *)accessToken
                 identifyDeviceCriteria:(NLIdentifyDeviceCriteria *)identifyDeviceCriteria
                             completion:(WDMCompletionBlock)completionHandler
                                failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"RendezvousDevice";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           nl::Weave::Profiles::DeviceDescription::IdentifyDeviceCriteria criteria = [identifyDeviceCriteria toIdentifyDeviceCriteria];

                           Base64Encoding *base64coder = [Base64Encoding createBase64StringEncoding];
                           NSData *accessTokenData = [base64coder decode:accessToken];

                           // Note: accessTokenData is not supposed to be longer than uint32_t_max bytes
                           // Weave, in general, uses unsigned 32-bit to represent data length
                           uint32_t accessTokenLen = (uint32_t)[accessTokenData length];
                           uint8_t *pAccessToken = (uint8_t *)[accessTokenData bytes];

                           // note that RendezvousDevice interanlly makes a copy of the access token before return
                           WEAVE_ERROR err = _mWeaveCppDM->RendezvousDevice(
                                                                            pAccessToken, accessTokenLen, criteria, (__bridge void *)self,
                                                                            HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

- (void)passiveRendezvousWithCompletion:(WDMCompletionBlock)completionHandler
                                failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"PassiveRendezvous";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           WEAVE_ERROR err = _mWeaveCppDM->PassiveRendezvousDevice(
                                                                            (__bridge void *)self,
                                                                            HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

- (void)passiveRendezvousWithDevicePairingCode:(NSString *)pairingCode
                                    completion:(WDMCompletionBlock)completionHandler
                                       failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"PassiveRendezvous";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           // note that PassiveRendezvousDevice interanlly makes a copy of the pairing code before return
                           WEAVE_ERROR err = _mWeaveCppDM->PassiveRendezvousDevice([pairingCode UTF8String],
                                                                                   (__bridge void *)self,
                                                                                   HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

- (void)passiveRendezvousWithDeviceAccessToken:(NSString *)accessToken
                                    completion:(WDMCompletionBlock)completionHandler
                                       failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"PassiveRendezvous";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           Base64Encoding *base64coder = [Base64Encoding createBase64StringEncoding];
                           NSData *accessTokenData = [base64coder decode:accessToken];

                           // Note: accessTokenData is not supposed to be longer than uint32_t_max bytes
                           // Weave, in general, uses unsigned 32-bit to represent data length
                           uint32_t accessTokenLen = (uint32_t)[accessTokenData length];
                           uint8_t *pAccessToken = (uint8_t *)[accessTokenData bytes];

                           // note that PassiveRendezvousDevice interanlly makes a copy of the access token before return
                           WEAVE_ERROR err = _mWeaveCppDM->PassiveRendezvousDevice(pAccessToken, accessTokenLen,
                                                                                   (__bridge void *)self,
                                                                                   HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

- (void)remotePassiveRendezvousWithDevicePairingCode:(NSString *)pairingCode
                                   IPAddress:(NSString *)IPAddress
                                   rendezvousTimeout:(uint16_t)rendezvousTimeoutSec
                                   inactivityTimeout:(uint16_t)inactivityTimeoutSec
                                          completion:(WDMCompletionBlock)completionHandler
                                             failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"RemotePassiveRendezvous";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           nl::Inet::IPAddress rendezvousAddr;
                           const char *rendezvousAddrStr = [IPAddress UTF8String];
                           if (!nl::Inet::IPAddress::IPAddress::FromString(rendezvousAddrStr, rendezvousAddr))
                           {
                               rendezvousAddr = nl::Inet::IPAddress::Any;
                           }

                           // note that RemotePassiveRendezvous interanlly makes a copy of the pairing code before return
                           WEAVE_ERROR err = _mWeaveCppDM->RemotePassiveRendezvous(rendezvousAddr,
                                                                                   [pairingCode UTF8String],
                                                                                   rendezvousTimeoutSec,
                                                                                   inactivityTimeoutSec,
                                                                                   (__bridge void *)self,
                                                                                   HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

- (NSInteger)setRendezvousAddress:(NSString *)aRendezvousAddress
{
    WDM_LOG_METHOD_SIG();

    __block WEAVE_ERROR err = WEAVE_NO_ERROR;
    const char *rendezvousAddrStr = [aRendezvousAddress UTF8String];
    nl::Inet::IPAddress rendezvousAddr;

    if (!nl::Inet::IPAddress::FromString(rendezvousAddrStr, rendezvousAddr))
    {
        ExitNow(err = WEAVE_ERROR_INVALID_ADDRESS);
    }

    // need this bracket to use Verify macros
    {
        // we use sync so the result is immediately available to the caller upon return
        dispatch_sync(_mWeaveWorkQueue, ^()
                      {
                          err = _mWeaveCppDM->SetWiFiRendezvousAddress(rendezvousAddr);
                      });
    }

exit:
    return err;
}

static void onDeviceEnumerationResponse(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr,
                                        void *appReqState,
                                        const nl::Weave::DeviceManager::DeviceDescription::WeaveDeviceDescriptor *devdesc,
                                        nl::Inet::IPAddress deviceAddr,
                                        nl::Inet::InterfaceId deviceIntf
                                       )
{
    WDM_LOG_DEBUG(@"onDeviceEnumerationResponse");

    WEAVE_ERROR err = WEAVE_NO_ERROR;
    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)appReqState;
    NSString * deviceAddrStr;
    NSDictionary * deviceEnumerationResponsePlist;
    char devAddrCStr[INET6_ADDRSTRLEN + IF_NAMESIZE + 2]; // Include space for "<addr>%<interface name>" and NULL terminator

    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    VerifyOrExit(deviceAddr.ToString(devAddrCStr, sizeof(devAddrCStr)) > 0, err = WEAVE_ERROR_NO_MEMORY);

    // Add "%" separator character, with NULL terminator, per IETF RFCs 4001 and 4007
    VerifyOrExit(snprintf(&(devAddrCStr[strlen(devAddrCStr)]), 2, "%%") > 0, err = nl::Weave::System::MapErrorPOSIX(errno));

    // Concatenate zone index (aka interface name) to IP address, with NULL terminator, per IETF RFCs 4001 and 4007
    err = nl::Inet::GetInterfaceName(deviceIntf, &(devAddrCStr[strlen(devAddrCStr)]), IF_NAMESIZE + 1);
    SuccessOrExit(err);

    // create NSString from IPAddress, including IPv6 zone identifier
    deviceAddrStr = [NSString stringWithUTF8String:devAddrCStr];

    deviceEnumerationResponsePlist = @{
        @"deviceAddress" : deviceAddrStr,
        @"deviceDescriptor" : [NLWeaveDeviceDescriptor createUsing:*devdesc]
    };

    [dm DispatchAsyncResponseBlock:deviceEnumerationResponsePlist];

exit:
    WDM_LOG_ERROR(@"Error in onDeviceEnumerationResponse: (%d) %@\n", err, [NSString stringWithUTF8String:nl::ErrorStr(err)]);
}

-(void)startDeviceEnumerationWithIdentifyDeviceCriteria:(NLIdentifyDeviceCriteria *)identifyDeviceCriteria
                                             completion:(WDMCompletionBlock)completionBlock
                                                failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"DeviceEnumeration";

    // we use async for the results that are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionBlock;
            _mFailureHandler = failureBlock;

            nl::Weave::Profiles::DeviceDescription::IdentifyDeviceCriteria deviceCriteria = [identifyDeviceCriteria toIdentifyDeviceCriteria];

            WEAVE_ERROR err = _mWeaveCppDM->StartDeviceEnumeration(
                                (__bridge void *)self, deviceCriteria,
                                onDeviceEnumerationResponse, onWeaveError);

            if (WEAVE_NO_ERROR != err)
            {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
            }
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
        }
    });
}

-(void)stopDeviceEnumeration
{
    WDM_LOG_METHOD_SIG();

    dispatch_sync(_mWeaveWorkQueue, ^()
                      {
                          _mWeaveCppDM->StopDeviceEnumeration();
                      });

    [self MarkTransactionCompleted];
}

-(void)connectDevice:(uint64_t)deviceId
       deviceAddress:(NSString *)deviceAddress
          completion:(WDMCompletionBlock)completionHandler
             failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ConnectDevice";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;

            nl::Inet::IPAddress deviceAddr;
            nl::Inet::IPAddress::FromString([deviceAddress UTF8String], deviceAddr);

            WEAVE_ERROR err = _mWeaveCppDM->ConnectDevice(deviceId, deviceAddr,
                (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

            if (WEAVE_NO_ERROR != err)
            {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
            }
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

-(void)reconnectDevice:(WDMCompletionBlock)completionHandler
               failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ReconnectDevice";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;

                           WEAVE_ERROR err = _mWeaveCppDM->ReconnectDevice((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

-(void)connectBle:(CBPeripheral*)peripheral
       completion:(WDMCompletionBlock)completionHandler
          failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ConnectBle";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;
            _blePeripheral = peripheral;

            // this will be called when the preparation completes one Weave work queue
            _BleConnectionPreparationCompleteHandler = ^(NLWeaveDeviceManager *dm, WEAVE_ERROR err) {
                if (WEAVE_NO_ERROR == err)
                {
                    err = _mWeaveCppDM->ConnectBle((__bridge void *)_blePeripheral,
                                                           (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                }
                if (WEAVE_NO_ERROR != err)
                {
                    [dm DispatchAsyncDefaultFailureBlockWithCode:err];
                }
            };

            [[[NLWeaveStack sharedStack] BleDelegate] prepareNewBleConnection:self];
        }
        else
            {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

-(void)connectBleWithPairingCode:(CBPeripheral*)peripheral
                     pairingCode:(NSString *)pairingCode
                      completion:(WDMCompletionBlock)completionHandler
                         failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ConnectBle";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;
            _blePeripheral = peripheral;

            // this will be called when the preparation completes one Weave work queue
            _BleConnectionPreparationCompleteHandler = ^(NLWeaveDeviceManager *dm, WEAVE_ERROR err) {
                if (WEAVE_NO_ERROR == err)
                {
                    const char *pairingCodeStr = [pairingCode UTF8String];

                    err = _mWeaveCppDM->ConnectBle((__bridge void *)_blePeripheral, pairingCodeStr,
                                                           (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                }
                if (WEAVE_NO_ERROR != err)
                {
                    [dm DispatchAsyncDefaultFailureBlockWithCode:err];
                }
            };

            [[[NLWeaveStack sharedStack] BleDelegate] prepareNewBleConnection:self];
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

static void onGetCameraAuthDataComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, const char *macAddress, const char *signedPayload)
{
    WDM_LOG_DEBUG(@"onGetCameraAuthDataComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    NSString *macAddressStr = [NSString stringWithUTF8String:macAddress];
    NSString *signedPayloadStr = [NSString stringWithUTF8String:signedPayload];

    WDM_LOG_DEBUG(@"Camera MAC = %s, payload = %s\n", macAddress, signedPayload);

    NSDictionary * cameraAuthDataPlist = @{
		@"macAddress" : macAddressStr,
		@"signedPayload" : signedPayloadStr
    };

    [dm DispatchAsyncCompletionBlock:cameraAuthDataPlist];
}

- (void)getCameraAuthData:(NSString *)nonce
         completion:(WDMCompletionBlock)completionBlock
            failure:(WDMFailureBlock)failureBlock
{
	WDM_LOG_METHOD_SIG();

    NSString * taskName = @"GetCameraAuthData";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
	{
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionBlock;
            _mFailureHandler = failureBlock;
			const char *nonceStr = [nonce UTF8String];

		    WEAVE_ERROR err = _mWeaveCppDM->GetCameraAuthData(nonceStr, (__bridge void *)self, onGetCameraAuthDataComplete, onWeaveError);

		    if (WEAVE_NO_ERROR != err)
		    {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
		    }
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
        }
    });
}

-(void)connectBleWithDeviceAccessToken:(CBPeripheral*)peripheral
                           accessToken:(NSString *)accessToken
                            completion:(WDMCompletionBlock)completionHandler
                               failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ConnectBle";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionHandler;
                           _mFailureHandler = failureHandler;
                           _blePeripheral = peripheral;

                           // this will be called when the preparation completes one Weave work queue
                           _BleConnectionPreparationCompleteHandler = ^(NLWeaveDeviceManager *dm, WEAVE_ERROR err) {
                               if (WEAVE_NO_ERROR == err)
                               {
                                   Base64Encoding *base64coder = [Base64Encoding createBase64StringEncoding];
                                   NSData *accessTokenData = [base64coder decode:accessToken];

                                   // Note: accessTokenData is not supposed to be longer than uint32_t_max bytes
                                   // Weave, in general, uses unsigned 32-bit to represent data length
                                   uint32_t accessTokenLen = (uint32_t)[accessTokenData length];
                                   uint8_t *pAccessToken = (uint8_t *)[accessTokenData bytes];

                                   err = _mWeaveCppDM->ConnectBle((__bridge void *)_blePeripheral, pAccessToken, accessTokenLen,
                                                                  (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                               }

                               if (WEAVE_NO_ERROR != err)
                               {
                                   [dm DispatchAsyncDefaultFailureBlockWithCode:err];
                               }
                           };

                           [[[NLWeaveStack sharedStack] BleDelegate] prepareNewBleConnection:self];
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
                       }
                   });
}

static void onNetworkScanComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, uint16_t netCount, const NetworkInfo *netInfoList)
{
    WDM_LOG_DEBUG(@"onNetworkScanComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    NSMutableArray *networkInfoList = [NSMutableArray arrayWithCapacity:netCount];

    WDM_LOG_DEBUG(@"Count = %u\n", netCount);

    for (uint32_t i = 0; i < netCount; i++)
    {
        NetworkInfo *pNetworkInfoElement = (NetworkInfo *)&netInfoList[i];
        NLNetworkInfo *nlNetworkInfo = [NLNetworkInfo createUsing:pNetworkInfoElement];
        [networkInfoList addObject:nlNetworkInfo];
    }

    [dm DispatchAsyncCompletionBlock:networkInfoList];
}

- (void)scanNetworks:(NLNetworkType)networkType
          completion:(WDMCompletionBlock)completionBlock
             failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ScanNetworks";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           bool isValidType = false;
                           nl::Weave::Profiles::NetworkProvisioning::NetworkType type;

                           switch (networkType)
                           {
                                case kNLNetworkType_NotSpecified:
                                    type = nl::Weave::Profiles::NetworkProvisioning::kNetworkType_NotSpecified;
                                    isValidType = true;
                                    break;
                                case kNLNetworkType_WiFi:
                                    type = nl::Weave::Profiles::NetworkProvisioning::kNetworkType_WiFi;
                                    isValidType = true;
                                    break;
                                default:
                                   WDM_LOG_ERROR(@"%@: invalid network type, abort", _name);
                                   type = nl::Weave::Profiles::NetworkProvisioning::kNetworkType_NotSpecified;
                                   isValidType = false;
                           }

                           if (isValidType)
                           {
                               WEAVE_ERROR err = _mWeaveCppDM->ScanNetworks(type, (__bridge void *)self, onNetworkScanComplete, onWeaveError);
                               if (WEAVE_NO_ERROR != err)
                               {
                                   [self DispatchAsyncDefaultFailureBlockWithCode:err];
                               }
                           }
                           else
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:WEAVE_ERROR_INVALID_ARGUMENT];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

static void onAddNetworkComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, uint32_t networkId)
{
    WDM_LOG_DEBUG(@"onAddNetworkComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    WDM_LOG_DEBUG(@"networkId = %u\n", networkId);

    [dm DispatchAsyncCompletionBlock:@(networkId)];
}

- (void)addNetwork:(NLNetworkInfo *)nlNetworkInfo
        completion:(WDMCompletionBlock)completionBlock
           failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"AddNetwork";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           NetworkInfo networkInfo = [nlNetworkInfo toNetworkInfo];

                            WEAVE_ERROR err = _mWeaveCppDM->AddNetwork(&networkInfo, (__bridge void *)self, onAddNetworkComplete, onWeaveError);
                            if (WEAVE_NO_ERROR != err)
                            {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                            }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)updateNetwork:(NLNetworkInfo *)nlNetworkInfo
           completion:(WDMCompletionBlock)completionBlock
              failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"updateNetwork";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           NetworkInfo networkInfo = [nlNetworkInfo toNetworkInfo];

                           WEAVE_ERROR err = _mWeaveCppDM->UpdateNetwork(&networkInfo, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)removeNetwork:(NLNetworkID)networkId
           completion:(WDMCompletionBlock)completionBlock
              failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"removeNetwork";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->RemoveNetwork((uint32_t)networkId, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)getNetworks:(uint8_t)flags
         completion:(WDMCompletionBlock)completionBlock
            failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"getNetworks";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->GetNetworks(flags, (__bridge void *)self, onNetworkScanComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)enableNetwork:(NLNetworkID)networkId
           completion:(WDMCompletionBlock)completionBlock
              failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"enableNetwork";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->EnableNetwork((uint32_t)networkId, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)disableNetwork:(NLNetworkID)networkId
           completion:(WDMCompletionBlock)completionBlock
              failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"disableNetwork";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->DisableNetwork((uint32_t)networkId, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)testNetworkConnectivity:(NLNetworkID)networkId
            completion:(WDMCompletionBlock)completionBlock
               failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"testNetworkConnectivity";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->TestNetworkConnectivity((uint32_t)networkId, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

static void onGetRendezvousModeComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, uint16_t modeFlags)
{
    WDM_LOG_DEBUG(@"onAddNetworkComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    WDM_LOG_DEBUG(@"networkId = %u\n", modeFlags);

    [dm DispatchAsyncCompletionBlock:@(modeFlags)];
}

- (void)getRendezvousMode:(WDMCompletionBlock)completionBlock
                        failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"getRendezvousMode";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->GetRendezvousMode((__bridge void *)self, onGetRendezvousModeComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)setRendezvousMode:(uint16_t)rendezvousFlags
               completion:(WDMCompletionBlock)completionBlock
                  failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"SetRendezvousMode";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->SetRendezvousMode((uint16_t)rendezvousFlags, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (WEAVE_ERROR)setAutoReconnect:(BOOL)autoReconnect
{
    __block WEAVE_ERROR err = WEAVE_NO_ERROR;

    WDM_LOG_METHOD_SIG();

    VerifyOrExit(NULL != _mWeaveCppDM, err = WEAVE_ERROR_INCORRECT_STATE);

    // need this bracket to use Verify macros
    {
        // we use sync so the result is immediately available to the caller upon return
        dispatch_sync(_mWeaveWorkQueue, ^()
                      {
                          err = _mWeaveCppDM->SetAutoReconnect(autoReconnect ? true : false);
                      });
    }

exit:
    return err;
}

- (void)createFabric:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"CreateFabric";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->CreateFabric((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)leaveFabric:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"LeaveFabric";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->LeaveFabric((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

static void onGetFabricConfigComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, const uint8_t *fabricConfig, uint32_t fabricConfigLen)
{
    WDM_LOG_DEBUG(@"onGetFabricConfigComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    [dm DispatchAsyncCompletionBlock:[NSData dataWithBytes:fabricConfig length:fabricConfigLen]];
}

- (void)getFabricConfig:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"GetFabricConfig";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->GetFabricConfig((__bridge void *)self, onGetFabricConfigComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this reques
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)joinExistingFabric:(NSData *)fabricConfig
                completion:(WDMCompletionBlock)completionBlock
                   failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"JoinExistingFabric";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           uint16_t fabricConfigLen = fabricConfig ? (uint16_t)[fabricConfig length] : 0;
                           uint8_t *fabricConfigBuf = (uint8_t *)[fabricConfig bytes];

                           WEAVE_ERROR err = _mWeaveCppDM->JoinExistingFabric(fabricConfigBuf, fabricConfigLen, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)registerServicePairAccount:(NLServiceInfo *)nlServiceInfo
                        completion:(WDMCompletionBlock)completionBlock
                           failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"RegisterServicePairAccount";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           const char *pAccountIdStr = [nlServiceInfo.accountId UTF8String];

                           NSData *serviceConfigData = [nlServiceInfo decodeServiceConfig];
                           uint16_t serviceConfigLen = (uint16_t) [serviceConfigData length];
                           uint8_t *pServiceConfig = (uint8_t *)[serviceConfigData bytes];

                           NSData *data = [NSData dataWithBytes:[nlServiceInfo.pairingToken UTF8String] length:[nlServiceInfo.pairingToken lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
                           uint16_t pairingTokenLen = (uint16_t) [nlServiceInfo.pairingToken length];
                           uint8_t *pPairingToken = (uint8_t *)[data bytes];

                           data = [nlServiceInfo.pairingInitData dataUsingEncoding:NSUTF8StringEncoding];
                           uint16_t pairingInitDataLen = (uint16_t)data.length;
                           uint8_t *pPairingInitData = (uint8_t *)[data bytes];

                           WEAVE_ERROR err = _mWeaveCppDM->RegisterServicePairAccount(nlServiceInfo.serviceId, pAccountIdStr,
                                                                                      pServiceConfig, serviceConfigLen,
                                                                                      pPairingToken, pairingTokenLen,
                                                                                      pPairingInitData, pairingInitDataLen,
                                                                                      (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)updateService:(NLServiceInfo *)nlServiceInfo
           completion:(WDMCompletionBlock)completionBlock
              failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"UpdateService";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           NSData *serviceConfigData = [nlServiceInfo decodeServiceConfig];
                           uint16_t serviceConfigLen = [serviceConfigData length];
                           uint8_t *pServiceConfig = (uint8_t *)[serviceConfigData bytes];

                           WEAVE_ERROR err = _mWeaveCppDM->UpdateService(nlServiceInfo.serviceId, pServiceConfig, serviceConfigLen,
                                                                        (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)unregisterService:(uint64_t)serviceId
               completion:(WDMCompletionBlock)completionBlock
                  failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"UnregisterService";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->UnregisterService(serviceId,
                                                                             (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)getLastNetworkProvisioningResult:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"GetLastNetworkProvisioningResult";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->GetLastNetworkProvisioningResult((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)armFailSafe:(uint8_t)armMode
      failSafeToken:(uint32_t)failSafeToken
         completion:(WDMCompletionBlock)completionBlock
            failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ArmFailSafe";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->ArmFailSafe(armMode, failSafeToken, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)disarmFailSafe:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"DisarmFailSafe";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->DisarmFailSafe((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)resetConfig:(uint16_t)resetFlags
         completion:(WDMCompletionBlock)completionBlock
            failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"ResetConfig";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->ResetConfig(resetFlags, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)enableConnectionMonitor:(NSInteger)intervalMs
                        timeout:(NSInteger)timeoutMs
                     completion:(WDMCompletionBlock)completionBlock
                        failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"EnableConnectionMonitor";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->EnableConnectionMonitor(intervalMs, timeoutMs, (__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)disableConnectionMonitor:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"DisableConnectionMonitor";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->DisableConnectionMonitor((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

- (void)startSystemTest:(uint32_t)profileId
                 testId:(uint32_t)testId
             completion:(WDMCompletionBlock)completionBlock
                failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"StartSystemTest";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->StartSystemTest((__bridge void *)self, profileId, testId, HandleSimpleOperationComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

/**
 * static function to called from WeaveDeviceManager when WeaveAlarmHushResponse is received
 *
 * @param[in] deviceMgr  pointer to WeaveDeviceManager
 * @param[in] reqState   C string pointing to the name of current operation
 * @param[in] hushResult result code for the hush operation
 * @param[in] length     number of alarm conditions in the conditions array
 * @param[in] conditions byte array of alarm conditions. each byte represents one alarm condition
 */
static void onHushComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, uint8_t hushResult, uint8_t length, const uint8_t *conditions)
{
    WDM_LOG_DEBUG(@"onHushComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    NLWeaveHushResponse * weaveHushResponse = [NLWeaveHushResponse createUsing:(NLWeaveHushResult)hushResult length:length conditions:conditions];

    [dm DispatchAsyncCompletionBlock:weaveHushResponse];
}

- (void)hush:(uint32_t)proximityVerificationCode
   challenge:(uint32_t)challenge
       keyId:(uint16_t)keyId
         key:(NSData *)key
  completion:(WDMCompletionBlock)completionBlock
     failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"Hush";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           WEAVE_ERROR err = _mWeaveCppDM->SignedHush(proximityVerificationCode, challenge, keyId, (const uint8_t*)key.bytes, key.length,
                                                                      (__bridge void *)self, onHushComplete, onWeaveError);

                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

-(void)ping:(WDMCompletionBlock)completionHandler failure:(WDMFailureBlock)failureHandler
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"Ping";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
    {
        if (nil == _mRequestName)
        {
            _mRequestName = taskName;
            _mCompletionHandler = completionHandler;
            _mFailureHandler = failureHandler;

            WEAVE_ERROR err = _mWeaveCppDM->Ping((__bridge void *)self, HandleSimpleOperationComplete, onWeaveError);

            if (WEAVE_NO_ERROR != err)
            {
                [self DispatchAsyncDefaultFailureBlockWithCode:err];
            }
        }
        else
        {
            WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

            // do not change _mRequestName, as we're rejecting this request
            [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureHandler];
        }
    });
}

static void onPairTokenComplete(nl::Weave::DeviceManager::WeaveDeviceManager *deviceMgr, void *reqState, const uint8_t *pairingTokenBundle, uint32_t pairingTokenBundleLen)
{
    WDM_LOG_DEBUG(@"onPairTokenComplete");

    NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager*)reqState;
    // ignore the pointer to C++ device manager
    (void)deviceMgr;

    [dm DispatchAsyncCompletionBlock:[NSData dataWithBytes:pairingTokenBundle length:pairingTokenBundleLen]];
}

- (void)pairToken:(NSData *)pairingToken
         completion:(WDMCompletionBlock)completionBlock
            failure:(WDMFailureBlock)failureBlock
{
    WDM_LOG_METHOD_SIG();

    NSString * taskName = @"pairToken";

    // we use async for the results are sent back to caller via async means also
    dispatch_async(_mWeaveWorkQueue, ^()
                   {
                       if (nil == _mRequestName)
                       {
                           _mRequestName = taskName;
                           _mCompletionHandler = completionBlock;
                           _mFailureHandler = failureBlock;

                           uint16_t pairingTokenLen = pairingToken ? (uint16_t)[pairingToken length] : 0;
                           uint8_t *pairingTokenBuf = (uint8_t *)[pairingToken bytes];

                           WEAVE_ERROR err = _mWeaveCppDM->PairToken(pairingTokenBuf, pairingTokenLen,  (__bridge void *)self, onPairTokenComplete, onWeaveError);
                           if (WEAVE_NO_ERROR != err)
                           {
                               [self DispatchAsyncDefaultFailureBlockWithCode:err];
                           }
                       }
                       else
                       {
                           WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);

                           // do not change _mRequestName, as we're rejecting this request
                           [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
                       }
                   });
}

@end
