/*
 *
 *    Copyright (c) 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 provides Weave over Bluez Peripheral implementation, which uses Bluez DBUS APIs.
 *
 */

#include "BluezHelperCode.h"
#include "WoBluez.h"

#if CONFIG_BLE_PLATFORM_BLUEZ

namespace nl {
namespace Ble {
namespace Platform {
namespace BlueZ {

static void WeaveRegisterSetup(DBusMessageIter * iter, void * bluezData);
static void WeaveRegisterReply(DBusMessage * message, void * bluezData);
static void WeaveUnregisterSetup(DBusMessageIter *iter, void *bluezData);
static void WeaveUnregisterReply(DBusMessage *message, void *bluezData);
static gboolean WeaveAdvertisingGetType(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean GetWeaveUUIDs(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean WeaveServiceDataCheck(const GDBusPropertyTable * property, void * bluezData);
static gboolean AppendArrayVariant(DBusMessageIter * iter, int type, void * val, int nElements);
static gboolean DictAppendBasicArray(DBusMessageIter * dict, int keyType, const void * key, int type, void * val, int nElements);
static gboolean GetWeaveServiceData(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean WeaveNameCheck(const GDBusPropertyTable * property, void * bluezData);
static gboolean WeaveGetName(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static DBusMessage * WeaveDestroyAdvertising(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static DBusMessage * WeaveDestroyProfile(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static void RegisterWeaveAppSetup(DBusMessageIter * iter, void * bluezData);
static void RegisterWeaveAppReply(DBusMessage * message, void * bluezData);
static void WeaveCharacteristicDestroy(void * bluezData);
static gboolean WeaveServiceGetUUID(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean WeaveServiceGetPrimary(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static void ServiceDestroy(void * bluezData);
static gboolean CharacteristicGetUUID(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean CharacteristicGetService(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean CharacteristicGetValue(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean CharacteristicGetNotifying(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static gboolean CharacteristicGetFlags(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
static DBusMessage * CharacteristicRead(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);

#if BLE_CONFIG_BLUEZ_MTU_FEATURE
static bool WritePipeIORead(struct io * io, void * bluezData);
static bool PipeIODestroy(struct io * io, void * bluezData);
static DBusMessage * CharacteristicCreatePipe(Characteristic * characteristic, DBusMessage * dbusMsg);
static DBusMessage * CharacteristicAcquireWrite(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static DBusMessage * CharacteristicAcquireNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static gboolean CharacteristicPipeAcquired(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData);
#endif

static DBusMessage * CharacteristicWrite(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static DBusMessage * CharacteristicStartNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static DBusMessage * CharacteristicStopNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static DBusMessage * CharacteristicIndicationConf(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData);
static void WeaveClientConnectHandler(DBusConnection * connection, void * bluezData);
static void WeaveClientDisconnectHandler(DBusConnection * connection, void * bluezData);
static gboolean CheckDeviceIsChild(GDBusProxy * childProxy, GDBusProxy * parentProxy);
static void WeaveAdapterAdded(GDBusProxy * proxy);
static void WeaveProfileAdded(GDBusProxy * proxy);
static void WeaveAdvertisingAdded(GDBusProxy * proxy);
static void WeaveDeviceAdded(GDBusProxy *proxy);
static void WeaveProxyAdded(GDBusProxy * proxy, void * bluezData);
static void WeaveProxyDeleted(GDBusProxy * proxy, void * bluezData);
static void WeaveDisconnReply(DBusMessage * dbusMsg, void * bluezData);
static void WeaveDeviceDisconnect(GDBusProxy * proxy);
static void WeavePropertyChange(GDBusProxy *proxy, const char *name, DBusMessageIter *iter, void *bluezData);
static void PowerCb(const DBusError * error, void * bluezData);
static void WeaveClientReady(GDBusClient * weaveClient, void * bluezData);

BluezServerEndpoint * gBluezServerEndpoint = NULL;
BluezBlePlatformDelegate * gBluezBlePlatformDelegate = NULL;
BluezBleApplicationDelegate * gBluezBleApplicationDelegate = NULL;
static GMainLoop * gBluezMainLoop;
static DBusConnection * gBluezDbusConn;
static Adapter * gDefaultAdapter;

static const GDBusMethodTable weaveAdvertisingMethods[] = {
    { "Release", WeaveDestroyAdvertising, (GDBusMethodFlags) 0, 0, NULL, NULL }, { }
};

static const GDBusPropertyTable weaveAdvertisingProperties[] = { { "Type", "s", WeaveAdvertisingGetType },
                                                                 { "ServiceUUIDs", "as", GetWeaveUUIDs, NULL, NULL },
                                                                 { "LocalName", "s", WeaveGetName, NULL, WeaveNameCheck },
                                                                 { "ServiceData", "a{sv}", GetWeaveServiceData, NULL,
                                                                   WeaveServiceDataCheck },
                                                                 { } };

static const GDBusMethodTable weaveAppMethods[] = { { "Release", WeaveDestroyProfile, GDBusMethodFlags(0), 0, NULL, NULL }, { } };

static const GDBusPropertyTable weaveAppProperties[] = { { "UUIDs", "as", GetWeaveUUIDs }, { } };

static const GDBusPropertyTable serviceProperties[] = { { "UUID", "s", WeaveServiceGetUUID },
                                                        { "Primary", "b", WeaveServiceGetPrimary },
                                                        { } };

static const GDBusPropertyTable WeaveCharacteristicProperties[] = {
    { "UUID", "s", CharacteristicGetUUID, NULL, NULL },
    { "Service", "o", CharacteristicGetService, NULL, NULL },
    { "Value", "ay", CharacteristicGetValue, NULL, NULL },
    { "Notifying", "b", CharacteristicGetNotifying, NULL, NULL },
    { "Flags", "as", CharacteristicGetFlags, NULL, NULL },
#if BLE_CONFIG_BLUEZ_MTU_FEATURE
    { "WriteAcquired", "b", CharacteristicPipeAcquired, NULL, NULL },
    { "NotifyAcquired", "b", CharacteristicPipeAcquired, NULL, NULL },
#endif // BLE_CONFIG_BLUEZ_MTU_FEATURE
    { }
};

static const GDBusMethodTable weaveCharacteristicMethods[] = {
    { "ReadValue", CharacteristicRead, G_DBUS_METHOD_FLAG_ASYNC, 0, GDBUS_ARGS( { "options", "a{sv}" }),
      GDBUS_ARGS( { "value", "ay" }) },
#if BLE_CONFIG_BLUEZ_MTU_FEATURE
    { "AcquireWrite", CharacteristicAcquireWrite, G_DBUS_METHOD_FLAG_ASYNC, 0, GDBUS_ARGS( { "options", "a{sv}" }), NULL },
    { "AcquireNotify", CharacteristicAcquireNotify, G_DBUS_METHOD_FLAG_ASYNC, 0, GDBUS_ARGS( { "options", "a{sv}" }), NULL },
#endif // BLE_CONFIG_BLUEZ_MTU_FEATURE
    { "WriteValue", CharacteristicWrite, G_DBUS_METHOD_FLAG_ASYNC, 0, GDBUS_ARGS( { "value", "ay" }, { "options", "a{sv}" }), NULL },
    { "StartNotify", CharacteristicStartNotify, G_DBUS_METHOD_FLAG_ASYNC, 0, NULL, NULL },
    { "StopNotify", CharacteristicStopNotify, G_DBUS_METHOD_FLAG_ASYNC, 0, NULL, NULL },
    { "Confirm", CharacteristicIndicationConf, G_DBUS_METHOD_FLAG_ASYNC, 0, NULL, NULL },
    { }
};

static void WeaveRegisterSetup(DBusMessageIter * iter, void * bluezData)
{
    DBusMessageIter dict;
    const char * path = ADVERTISING_PATH;
    gboolean success  = FALSE;
    const char * msg  = NULL;

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in WeaveRegisterSetup");

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
                                               DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
                                                   DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
                                               &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in WeaveRegisterSetup");

    success = dbus_message_iter_close_container(iter, &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in WeaveRegisterSetup");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }
}

static void WeaveRegisterReply(DBusMessage * message, void * bluezData)
{
    DBusConnection * dbusConn = static_cast<DBusConnection *>(bluezData);
    DBusError error;
    dbus_error_init(&error);

    if (TRUE == dbus_set_error_from_message(&error, message))
    {
        WeaveLogError(Ble, "Fail to register weave advertisement in WeaveRegisterReply: %s", error.name);
        dbus_error_free(&error);

        if (FALSE == g_dbus_unregister_interface(dbusConn, ADVERTISING_PATH, ADVERTISING_INTERFACE))
        {
            WeaveLogError(Ble, "Fail to unregister weave advertisement in WeaveRegisterReply");
        }
    }
    else
    {
        WeaveLogProgress(Ble, "Weave advertisement object registered");
    }
}

static void WeaveUnregisterSetup(DBusMessageIter *iter, void *bluezData)
{
    const char *path = ADVERTISING_PATH;
    gboolean success = FALSE;
    const char *msg = NULL;

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in WeaveUnregisterSetup");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }
}

static void WeaveUnregisterReply(DBusMessage *message, void *bluezData)
{
    DBusError error;

    dbus_error_init(&error);

    if (FALSE == dbus_set_error_from_message(&error, message))
    {
        WeaveLogProgress(Ble, "Weave advertisement unregistered");
        if (gBluezDbusConn)
        {
            if (FALSE == g_dbus_unregister_interface(gBluezDbusConn, ADVERTISING_PATH, ADVERTISING_INTERFACE))
            {
                WeaveLogError(Ble, "Fail to unregister weave advertisement object in WeaveUnregisterReply");
            }
        }
    }
    else
    {
        WeaveLogError(Ble, "Fail to unregister weave advertisement in WeaveUnregisterReply: %s", error.name);
        dbus_error_free(&error);
    }
}

static gboolean WeaveAdvertisingGetType(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    gboolean success = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &(gBluezServerEndpoint->advertisingType));
    if (FALSE == success)
    {
        WeaveLogError(Ble, "Fail to get advertising type in WeaveAdvertisingGetType");
    }

    return success;
}

static gboolean GetWeaveUUIDs(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    const char * msg = NULL;
    gboolean success = FALSE;
    DBusMessageIter dbusArray;

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "as", &dbusArray);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in GetWeaveUUIDs");

    success = dbus_message_iter_append_basic(&dbusArray, DBUS_TYPE_STRING, &(gBluezServerEndpoint->advertisingUUID));
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in GetWeaveUUIDs");

    success = dbus_message_iter_close_container(iter, &dbusArray);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in GetWeaveUUIDs");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean WeaveServiceDataCheck(const GDBusPropertyTable * property, void * bluezData)
{
    gboolean success = FALSE;

    if (NULL != gBluezServerEndpoint->weaveServiceData)
    {
        success = TRUE;
    }

    return success;
}

static gboolean AppendArrayVariant(DBusMessageIter * iter, int type, void * val, int nElements)
{
    const char * msg = NULL;
    gboolean success = FALSE;
    DBusMessageIter variant, array;
    const char *** strArray = (const char ***) val;
    int i;
    char typeSig[2]  = { (char) type, '\0' };
    char arraySig[3] = { DBUS_TYPE_ARRAY, (char) type, '\0' };

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, arraySig, &variant);
    VerifyOrExit(success == TRUE, msg = "Fail to open DBUS_TYPE_VARIANT container in AppendArrayVariant");

    success = dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, typeSig, &array);
    VerifyOrExit(success == TRUE, msg = "Fail to open DBUS_TYPE_ARRAY container in AppendArrayVariant");

    if (dbus_type_is_fixed(type) == TRUE)
    {
        success = dbus_message_iter_append_fixed_array(&array, type, val, nElements);
        VerifyOrExit(success == TRUE, msg = "Fail to append fixed array in AppendArrayVariant");
    }
    else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH)
    {
        for (i = 0; i < nElements; i++)
        {
            success = dbus_message_iter_append_basic(&array, type, &((*strArray)[i]));
            VerifyOrExit(success == TRUE, msg = "Fail to append basic in AppendArrayVariant");
        }
    }

    success = dbus_message_iter_close_container(&variant, &array);
    VerifyOrExit(success == TRUE, msg = "Fail to close DBUS_TYPE_ARRAY container in AppendArrayVariant");

    success = dbus_message_iter_close_container(iter, &variant);
    VerifyOrExit(success == TRUE, msg = "Fail to close DBUS_TYPE_VARIANT container in AppendArrayVariant");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean DictAppendBasicArray(DBusMessageIter * dict, int keyType, const void * key, int type, void * val, int nElements)
{
    const char * msg = NULL;
    gboolean success = FALSE;
    DBusMessageIter entry;

    success = dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
    VerifyOrExit(success == TRUE, msg = "Fail to open DBUS_TYPE_DICT_ENTRY container in DictAppendBasicArray");

    success = dbus_message_iter_append_basic(&entry, keyType, key);
    VerifyOrExit(success == TRUE, msg = "Fail to append key in DictAppendBasicArray");

    success = AppendArrayVariant(&entry, type, val, nElements);
    VerifyOrExit(success == TRUE, msg = "Fail to append array variant in DictAppendBasicArray");

    success = dbus_message_iter_close_container(dict, &entry);
    VerifyOrExit(success == TRUE, msg = "Fail to close DBUS_TYPE_DICT_ENTRY container in DictAppendBasicArray");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean GetWeaveServiceData(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    const char * msg = NULL;
    gboolean success = FALSE;
    DBusMessageIter dict;

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to open DBUS_TYPE_ARRAY container in GetWeaveServiceData");

    success = DictAppendBasicArray(&dict, DBUS_TYPE_STRING, &gBluezServerEndpoint->advertisingUUID, DBUS_TYPE_BYTE,
                                   &gBluezServerEndpoint->weaveServiceData, sizeof(WeaveServiceData));
    VerifyOrExit(success == TRUE, msg = "Fail to append dictionary in GetWeaveServiceData");

    success = dbus_message_iter_close_container(iter, &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to close DBUS_TYPE_ARRAY container in GetWeaveServiceData");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean WeaveNameCheck(const GDBusPropertyTable * property, void * bluezData)
{
    gboolean success = FALSE;

    if (NULL != gBluezServerEndpoint->adapterName)
    {
        success = TRUE;
    }

    return success;
}

static gboolean WeaveGetName(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    gboolean success = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &(gBluezServerEndpoint->adapterName));

    if (FALSE == success)
    {
        WeaveLogError(Ble, "Fail to get Weave Local name in WeaveGetName");
    }

    return success;
}

static DBusMessage * WeaveDestroyAdvertising(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    if (FALSE == g_dbus_unregister_interface(dbusConn, ADVERTISING_PATH, ADVERTISING_INTERFACE))
    {
        WeaveLogError(Ble, "Fail to destroy advertising object in WeaveDestroyAdvertising");
    }

    return dbus_message_new_method_return(dbusMsg);
}

gboolean SetAlias(void)
{
    gboolean success = g_dbus_proxy_set_property_basic(gDefaultAdapter->adapterProxy, "Alias", DBUS_TYPE_STRING, &(gBluezServerEndpoint->adapterName), NULL, NULL, NULL);
    if (FALSE == success)
    {
        WeaveLogError(Ble, "Fail to set controller alias for adapter %p(%s)", gDefaultAdapter->adapterProxy, gBluezServerEndpoint->adapterName);
    }

    return success;
}

gboolean EnableDiscoverable(void)
{
    gboolean success = FALSE;
    dbus_bool_t discoverable = TRUE;
    success = g_dbus_proxy_set_property_basic(gDefaultAdapter->adapterProxy, "Discoverable", DBUS_TYPE_BOOLEAN, &discoverable, NULL, NULL, NULL);
    if (FALSE == success)
    {
        WeaveLogError(Ble, "Fail to set Discoverable property for adapter %p", gDefaultAdapter->adapterProxy);
    }

    return success;
}

gboolean AdvertisingRegister(DBusConnection * dbusConn, GDBusProxy * proxy)
{
    gboolean success = FALSE;
    const char * msg = NULL;

    success = g_dbus_register_interface(dbusConn, ADVERTISING_PATH, ADVERTISING_INTERFACE, weaveAdvertisingMethods, NULL,
                                        weaveAdvertisingProperties, NULL, NULL);
    VerifyOrExit(success == TRUE, msg = "Failed to register advertising object in AdvertisingRegister");

    success = g_dbus_proxy_method_call(proxy, "RegisterAdvertisement", WeaveRegisterSetup, WeaveRegisterReply, dbusConn, NULL);
    VerifyOrExit(success == TRUE, msg = "Failed to call RegisterAdvertisement in AdvertisingRegister");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static DBusMessage * WeaveDestroyProfile(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    if (FALSE == g_dbus_unregister_interface(dbusConn, WEAVE_PATH, PROFILE_INTERFACE))
    {
        WeaveLogError(Ble, "Failed to destroy advertising object in WeaveDestroyProfile");
    }

    return dbus_message_new_method_return(dbusMsg);
}

static void RegisterWeaveAppSetup(DBusMessageIter * iter, void * bluezData)
{
    DBusMessageIter dict;
    const char * path = "/";
    gboolean success  = FALSE;
    const char * msg  = NULL;

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in RegisterWeaveAppSetup");

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
                                               DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
                                                   DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
                                               &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in RegisterWeaveAppSetup");

    success = dbus_message_iter_close_container(iter, &dict);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in RegisterWeaveAppSetup");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }
}

static void RegisterWeaveAppReply(DBusMessage * message, void * bluezData)
{
    DBusError error;
    dbus_error_init(&error);

    if (TRUE == dbus_set_error_from_message(&error, message))
    {
        WeaveLogError(Ble, "Failed to setup weave application in RegisterWeaveAppReply: %s", error.name);
        dbus_error_free(&error);
    }
}

gboolean SetupWeaveApp(DBusConnection * dbusConn, GDBusProxy * proxy)
{
    gboolean success = FALSE;
    const char * msg = NULL;
    success =
        g_dbus_register_interface(dbusConn, WEAVE_PATH, PROFILE_INTERFACE, weaveAppMethods, NULL, weaveAppProperties, NULL, NULL);
    VerifyOrExit(success == TRUE, msg = "Fail in register interface in SetupWeaveApp");

    success = g_dbus_proxy_method_call(proxy, "RegisterApplication", RegisterWeaveAppSetup, RegisterWeaveAppReply, NULL, NULL);
    if (FALSE == success)
    {
        msg = "Fail to call RegisterApplication in SetupWeaveApp";
        g_dbus_unregister_interface(dbusConn, WEAVE_PATH, PROFILE_INTERFACE);
        ExitNow();
    }

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static void WeaveCharacteristicDestroy(void * bluezData)
{
    Characteristic * WeaveCharacteristic = static_cast<Characteristic *>(bluezData);
    if (NULL != WeaveCharacteristic)
    {
        g_free(WeaveCharacteristic->path);
        g_free(WeaveCharacteristic->servicePath);
        g_free(WeaveCharacteristic->uuid);
        g_strfreev(WeaveCharacteristic->flags);
        g_free(WeaveCharacteristic->value);
        g_free(WeaveCharacteristic);
    }
}

static gboolean WeaveServiceGetUUID(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Service * weaveService = static_cast<Service *>(bluezData);
    gboolean success       = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &weaveService->uuid);
    if (FALSE == success)
    {
        WeaveLogError(Ble, "Failed to get weave service uuid property in WeaveServiceGetUUID");
    }

    return success;
}

static gboolean WeaveServiceGetPrimary(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Service * weaveService = static_cast<Service *>(bluezData);
    dbus_bool_t servicePrimary;
    gboolean success = FALSE;
    const char * msg = NULL;

    VerifyOrExit(weaveService != NULL, msg = "weaveService is NULL in WeaveServiceGetPrimary");

    servicePrimary = weaveService->isPrimary ? TRUE : FALSE;

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &servicePrimary);
    VerifyOrExit(success == TRUE, msg = "Failed to get weave service primary property in WeaveServiceGetPrimary");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static void ServiceDestroy(void * bluezData)
{
    Service * weaveService = static_cast<Service *>(bluezData);
    if (NULL != weaveService)
    {
        g_free(weaveService->path);
        g_free(weaveService->uuid);
        g_free(weaveService);
    }
}

gboolean RegisterWeaveService(DBusConnection * dbusConn)
{
    gboolean success = FALSE;
    const char * msg = NULL;
    Service * weaveService;
    weaveService = g_new0(Service, 1);

    VerifyOrExit(weaveService != NULL, msg = "weaveService is NULL in RegisterWeaveService");

    weaveService->dbusConn  = dbusConn;
    weaveService->path      = g_strdup_printf("%s/WeaveService%p", WEAVE_PATH, weaveService);
    weaveService->isPrimary = true;
    weaveService->uuid      = g_strdup(UUID_WEAVE);

    success = g_dbus_register_interface(dbusConn, weaveService->path, SERVICE_INTERFACE, NULL, NULL, serviceProperties,
                                        weaveService, ServiceDestroy);
    if (FALSE == success)
    {
        msg = "Failed to register weave service";
        ServiceDestroy(weaveService);
        weaveService = NULL;
    }

    gBluezServerEndpoint->weaveService = weaveService;

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean CharacteristicGetUUID(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    const char * msg                = NULL;
    gboolean success                = FALSE;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicGetUUID");

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &characteristic->uuid);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in CharacteristicGetUUID");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean CharacteristicGetService(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    const char * msg                = NULL;
    gboolean success                = FALSE;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicGetService");

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &characteristic->servicePath);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in CharacteristicGetService");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean CharacteristicGetValue(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    DBusMessageIter array;
    const char * msg = NULL;
    gboolean success = FALSE;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicGetValue");

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in CharacteristicGetValue");

    success = dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE, &characteristic->value, characteristic->valueLen);
    VerifyOrExit(success == TRUE, msg = "Fail to append array in CharacteristicGetValue");

    success = dbus_message_iter_close_container(iter, &array);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in CharacteristicGetValue");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean CharacteristicGetNotifying(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    dbus_bool_t characteristicNotify;
    const char * msg = NULL;
    gboolean success = FALSE;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicGetNotifying");

    characteristicNotify = characteristic->isNotifying ? TRUE : FALSE;

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &characteristicNotify);
    VerifyOrExit(success == TRUE, msg = "Fail to append basic in CharacteristicGetNotifying");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static gboolean CharacteristicGetFlags(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    int flagIndex                   = 0;
    DBusMessageIter array;
    const char * msg = NULL;
    gboolean success = FALSE;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicGetFlags");

    success = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &array);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in CharacteristicGetFlags");

    while (characteristic->flags[flagIndex])
    {
        success = dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &characteristic->flags[flagIndex]);
        VerifyOrExit(success == TRUE, msg = "Fail to append array in CharacteristicGetFlags");
        flagIndex++;
    }

    success = dbus_message_iter_close_container(iter, &array);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in CharacteristicGetFlags");

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static DBusMessage * CharacteristicRead(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    DBusMessage * readReply         = NULL;
    DBusMessageIter iter, array;
    const char * msg = NULL;
    gboolean success = FALSE;
    readReply        = g_dbus_create_reply(dbusMsg, DBUS_TYPE_INVALID);
    dbus_message_iter_init_append(readReply, &iter);

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicRead");

    success = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "y", &array);
    VerifyOrExit(success == TRUE, msg = "Fail to open container in CharacteristicRead");

    success = dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE, &(characteristic->value), characteristic->valueLen);
    VerifyOrExit(success == TRUE, msg = "Fail to append fixed array in CharacteristicRead");

    success = dbus_message_iter_close_container(&iter, &array);
    VerifyOrExit(success == TRUE, msg = "Fail to close container in CharacteristicRead");

exit:

    if ((success != TRUE) && (NULL != msg))
    {
        WeaveLogError(Ble, msg);
    }

    return readReply;
}

#if BLE_CONFIG_BLUEZ_MTU_FEATURE
static bool WritePipeIORead(struct io * io, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    int fd;
    const char * msg = NULL;
    uint8_t writerData[BUFF_SIZE];
    ssize_t writerDataLength;
    bool success = false;

    VerifyOrExit(bluezData != NULL, msg = "characteristic is NULL in WritePipeIORead");

    if (io == characteristic->writePipeIO)
    {
        fd = io_get_fd(io);
        VerifyOrExit(fd >= 0, msg = "expect file descriptor with non-negatvie value in WritePipeIORead");
    }
    else
    {
        msg = "expect writePipeIO in WritePipeIORead";
        ExitNow();
    }

    writerDataLength = read(fd, writerData, sizeof(writerData));
    VerifyOrExit(writerDataLength >= 0, msg = "writerDataLength should be larger than or equal to 0");

    g_free(characteristic->value);
    characteristic->value    = static_cast<uint8_t *>(g_memdup(writerData, writerDataLength));
    characteristic->valueLen = writerDataLength;

    if (strcmp(characteristic->uuid, UUID_WEAVE_C1) == 0)
    {
        WoBLEz_WriteReceived(gBluezServerEndpoint, characteristic->value, characteristic->valueLen);
        success = true;
    }
    else
    {
        msg = "current uuid is not UUID_WEAVE_C1";
    }

exit:

    if (NULL != msg)
    {
        WeaveLogDetail(Ble, msg);
    }

    return success;
}

static bool PipeIODestroy(struct io * io, void * bluezData)
{
    const char * msg                = NULL;
    bool success                    = false;
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in PipeIODestroy");

    if (io != NULL)
    {
        if (io == characteristic->indicatePipeIO)
        {
            io_destroy(characteristic->indicatePipeIO);
            characteristic->indicatePipeIO = NULL;
        }
        else if (io == characteristic->writePipeIO)
        {
            io_destroy(characteristic->writePipeIO);
            characteristic->writePipeIO = NULL;
        }
        else
        {
            msg = "unknow io in PipeIODestroy";
            ExitNow();
        }
    }

    success = true;

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return success;
}

static DBusMessage * CharacteristicCreatePipe(Characteristic * characteristic, DBusMessage * dbusMsg)
{
    int characteristicPipefd[2];
    int fdToClose, fdToUse, ioSelection;
    struct io * io;
    const char * msg                            = NULL;
    DBusMessage * CharacteristicCreatePipeReply = NULL;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicAcquireWrite");

    if (pipe2(characteristicPipefd, O_DIRECT | O_NONBLOCK | O_CLOEXEC) < 0)
    {
        msg                           = strerror(errno);
        CharacteristicCreatePipeReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.Failed", "%s", strerror(errno));
        ExitNow();
    }

    if (TRUE == dbus_message_has_member(dbusMsg, "AcquireWrite"))
    {
        fdToClose   = characteristicPipefd[1];
        fdToUse     = characteristicPipefd[0];
        ioSelection = 1;
    }
    else if (TRUE == dbus_message_has_member(dbusMsg, "AcquireNotify"))
    {
        fdToClose   = characteristicPipefd[0];
        fdToUse     = characteristicPipefd[1];
        ioSelection = 0;
    }
    else
    {
        msg = "dbus message expects member, AcquireWrite or AcquireNotify";
        ExitNow();
    }

    io = io_new(fdToUse);
    if (io == NULL)
    {
        close(fdToClose);
        close(fdToUse);
        msg                           = strerror(errno);
        CharacteristicCreatePipeReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.Failed", "%s", strerror(errno));
        ExitNow();
    }

    io_set_close_on_destroy(io, true);
    io_set_read_handler(io, WritePipeIORead, characteristic, NULL);
    io_set_disconnect_handler(io, PipeIODestroy, characteristic, NULL);

    CharacteristicCreatePipeReply = g_dbus_create_reply(dbusMsg, DBUS_TYPE_UNIX_FD, &fdToClose, DBUS_TYPE_UINT16,
                                                        &gBluezServerEndpoint->mtu, DBUS_TYPE_INVALID);

    close(fdToClose);

    if (ioSelection == 1)
        characteristic->writePipeIO = io;
    else
        characteristic->indicatePipeIO = io;

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return CharacteristicCreatePipeReply;
}

static DBusMessage * CharacteristicAcquireWrite(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    const char * msg                = NULL;
    const char * key;
    DBusMessageIter iter, dict, value, entry;
    DBusMessage * acquireWriteReply = NULL;
    bool acquireMTU                 = false;
    dbus_bool_t iterCheck;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicAcquireWrite");

    if (characteristic->writePipeIO != NULL)
    {
        msg               = "there exists writePipeIO, error";
        acquireWriteReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.NotPermitted", NULL);
        ExitNow();
    }

    dbus_message_iter_init(dbusMsg, &iter);
    VerifyOrExit(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY,
                 msg = "dbus iterator is not array in CharacteristicAcquireWrite");

    dbus_message_iter_recurse(&iter, &dict);

    while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY)
    {
        dbus_message_iter_recurse(&dict, &entry);
        dbus_message_iter_get_basic(&entry, &key);
        iterCheck = dbus_message_iter_next(&entry);
        VerifyOrExit(iterCheck == TRUE, msg = "Reach the end of iterator");

        dbus_message_iter_recurse(&entry, &value);

        if (strcasecmp(key, "MTU") == 0)
        {
            dbus_message_iter_get_basic(&value, &gBluezServerEndpoint->mtu);
            acquireMTU = true;
            break;
        }

        dbus_message_iter_next(&dict);
    }

    if (!acquireMTU)
    {
        msg               = "AcquireWite cannot get MTU from bluez";
        acquireWriteReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.InvalidArguments", NULL);
        ExitNow();
    }

    acquireWriteReply = CharacteristicCreatePipe(characteristic, dbusMsg);

    if (characteristic->writePipeIO != NULL)
    {
        if (strcmp(characteristic->uuid, UUID_WEAVE_C1) == 0)
        {
            g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "WriteAcquired");
        }
        else
        {
            msg = "uuid expects UUID_WEAVE_C1";
            ExitNow();
        }
    }

exit:

    if (NULL != msg)
    {
        WeaveLogDetail(Ble, msg);
    }

    return acquireWriteReply;
}

static DBusMessage * CharacteristicAcquireNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic  = static_cast<Characteristic *>(bluezData);
    const char * msg                 = NULL;
    DBusMessage * acquireNotifyReply = NULL;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicAcquireNotify");

    if (characteristic->isNotifying)
    {
        msg                = "Notifying has been enabled in CharacteristicAcquireNotify";
        acquireNotifyReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.NotPermitted", NULL);
        ExitNow();
    }

    if (characteristic->indicatePipeIO != NULL)
    {
        msg                = "there exists indicatePipeIO, error";
        acquireNotifyReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.NotPermitted", NULL);
        ExitNow();
    }

    acquireNotifyReply = CharacteristicCreatePipe(characteristic, dbusMsg);

    if (characteristic->indicatePipeIO != NULL)
    {
        characteristic->isNotifying = true;

        WeaveLogProgress(Ble, "Characteristic path %s notification enabled", characteristic->path);

        if (strcmp(characteristic->uuid, UUID_WEAVE_C2) == 0)
        {
            WoBLEz_SubscriptionChange(gBluezServerEndpoint);
        }
        else
        {
            msg = "uuid expects UUID_WEAVE_C2";
            ExitNow();
        }

        g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "Notifying");
        g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "NotifyAcquired");
    }

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return acquireNotifyReply;
}
#endif // BLE_CONFIG_BLUEZ_MTU_FEATURE

static DBusMessage * CharacteristicWrite(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    DBusMessageIter iter;
    dbus_message_iter_init(dbusMsg, &iter);
    const char * msg = NULL;
    DBusMessageIter array;
    DBusMessage * writeReply = NULL;
    uint8_t * writerData     = NULL;
    int writerDataLength;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicWrite");

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
    {
        msg        = "Fail to get arg type in CharacteristicWrite";
        writeReply = g_dbus_create_error(dbusMsg, "org.bluez.Error.InvalidArguments", NULL);
        ExitNow();
    }

    dbus_message_iter_recurse(&iter, &array);
    dbus_message_iter_get_fixed_array(&array, &(writerData), &(writerDataLength));
    characteristic->value    = static_cast<uint8_t *>(g_memdup(writerData, writerDataLength));
    characteristic->valueLen = writerDataLength;

    g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "Value");

    if (strcmp(characteristic->uuid, UUID_WEAVE_C1) == 0)
    {
        WoBLEz_WriteReceived(gBluezServerEndpoint, characteristic->value, characteristic->valueLen);
    }

    writeReply = g_dbus_create_reply(dbusMsg, DBUS_TYPE_INVALID);

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return writeReply;
}

static DBusMessage * CharacteristicStartNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    const char * msg                = NULL;
    DBusMessage * notifyReply       = NULL;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicStartNotify");

    VerifyOrExit(!characteristic->isNotifying, msg = "Notifying has been enabled in CharacteristicStartNotify");

    characteristic->isNotifying = true;
    g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "Notifying");
    WeaveLogDetail(Ble, "Characteristic path %s notification enabled", characteristic->path);

    if (strcmp(characteristic->uuid, UUID_WEAVE_C2) == 0)
    {
        WoBLEz_SubscriptionChange(gBluezServerEndpoint);
    }

    notifyReply = g_dbus_create_reply(dbusMsg, DBUS_TYPE_INVALID);

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return notifyReply;
}

static DBusMessage * CharacteristicStopNotify(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    const char * msg                = NULL;
    DBusMessage * notifyReply       = NULL;

    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicStopNotify");

    VerifyOrExit(characteristic->isNotifying, msg = "Notifying has been disabled in CharacteristicStopNotify");

    characteristic->isNotifying = false;
    g_dbus_emit_property_changed(dbusConn, characteristic->path, CHARACTERISTIC_INTERFACE, "Notifying");
    WeaveLogProgress(Ble, "Characteristic path %s notification disabled", characteristic->path);

    if (strcmp(characteristic->uuid, UUID_WEAVE_C2) == 0)
    {
        WoBLEz_SubscriptionChange(gBluezServerEndpoint);
    }

    notifyReply = g_dbus_create_reply(dbusMsg, DBUS_TYPE_INVALID);

exit:

    if (NULL != msg)
    {
        WeaveLogError(Ble, msg);
    }

    return notifyReply;
}

static DBusMessage * CharacteristicIndicationConf(DBusConnection * dbusConn, DBusMessage * dbusMsg, void * bluezData)
{
    const char * msg                = NULL;
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicIndicationConf");

    WeaveLogDetail(Ble, "Indication confirmation received at %s", characteristic->path);
    WoBLEz_IndicationConfirmation(gBluezServerEndpoint);

exit:

    if (NULL != msg)
    {
        WeaveLogDetail(Ble, msg);
    }

    return g_dbus_create_reply(dbusMsg, DBUS_TYPE_INVALID);
}

#if BLE_CONFIG_BLUEZ_MTU_FEATURE
static gboolean CharacteristicPipeAcquired(const GDBusPropertyTable * property, DBusMessageIter * iter, void * bluezData)
{
    gboolean success                = FALSE;
    dbus_bool_t value               = FALSE;
    const char * msg                = NULL;
    Characteristic * characteristic = static_cast<Characteristic *>(bluezData);
    VerifyOrExit(characteristic != NULL, msg = "characteristic is NULL in CharacteristicPipeAcquired");

    if (strcmp(characteristic->uuid, UUID_WEAVE_C1) == 0)
    {
        value = (characteristic->writePipeIO != NULL) ? TRUE : FALSE;
    }
    else if (strcmp(characteristic->uuid, UUID_WEAVE_C2) == 0)
    {
        value = (characteristic->indicatePipeIO != NULL) ? TRUE : FALSE;
    }
    else
    {
        VerifyOrExit(value == TRUE, msg = "writePipeIO or indicatePipeIO is not set in C1 and C2");
    }

    success = dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);

exit:

    if (NULL != msg)
    {
        WeaveLogDetail(Ble, msg);
    }

    return success;
}
#endif // BLE_CONFIG_BLUEZ_MTU_FEATURE

Characteristic * RegisterWeaveCharacteristic(DBusConnection * dbusConn, const char * uuid, const char * flags)
{
    Characteristic * weaveCharacteristic = NULL;
    gboolean success                     = FALSE;
    const char * msg                     = NULL;

    weaveCharacteristic = g_new0(Characteristic, 1);

    VerifyOrExit(weaveCharacteristic != NULL, msg = "no memory allocated for characteristic in RegisterWeaveCharacteristic");

    weaveCharacteristic->dbusConn = dbusConn;
    weaveCharacteristic->uuid     = g_strdup(uuid);
    weaveCharacteristic->value    = NULL;
    weaveCharacteristic->path =
        g_strdup_printf("%s/weaveCharacteristic%p", gBluezServerEndpoint->weaveService->path, weaveCharacteristic);
    weaveCharacteristic->servicePath = g_strdup_printf("%s", gBluezServerEndpoint->weaveService->path);
    weaveCharacteristic->flags       = g_strsplit(flags, ",", -1);
#if BLE_CONFIG_BLUEZ_MTU_FEATURE
    weaveCharacteristic->writePipeIO    = NULL;
    weaveCharacteristic->indicatePipeIO = NULL;
#endif // BLE_CONFIG_BLUEZ_MTU_FEATURE
    success = g_dbus_register_interface(dbusConn, weaveCharacteristic->path, CHARACTERISTIC_INTERFACE, weaveCharacteristicMethods,
                                        NULL, WeaveCharacteristicProperties, weaveCharacteristic, WeaveCharacteristicDestroy);

    if (FALSE == success)
    {
        msg = "Failed to register weaveCharacteristic object in RegisterWeaveCharacteristic";
        WeaveCharacteristicDestroy(weaveCharacteristic);
        weaveCharacteristic = NULL;
    }

exit:

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    return weaveCharacteristic;
}

static void WeaveClientConnectHandler(DBusConnection * connection, void * bluezData)
{
    WeaveLogProgress(Ble, "Weave client connected to bluez daemon via dbus");
}

static void WeaveClientDisconnectHandler(DBusConnection * connection, void * bluezData)
{
    WeaveLogError(Ble, "Weave client disconnected from bluez daemon(Daemon crash?)");
    // Recovery from bluez daemon crash not implemented. So, exiting from mainloop.
    ExitBluezIOThread();
}

static gboolean CheckDeviceIsChild(GDBusProxy * childProxy, GDBusProxy * parentProxy)
{
    DBusMessageIter iter;
    const char * adapterPath1 = NULL;
    const char * adapterPath2 = NULL;
    const char * msg = NULL;
    bool success = false;

    VerifyOrExit(NULL != parentProxy, msg = "parentProxy is NULL");
    VerifyOrExit(NULL != childProxy, msg = "childProxy is NULL");

    if (g_dbus_proxy_get_property(childProxy, "Adapter", &iter))
    {
        dbus_message_iter_get_basic(&iter, &adapterPath1);
        adapterPath2 = g_dbus_proxy_get_path(parentProxy);

        if (strcmp(adapterPath1, adapterPath2) == 0)
        {
            success = true;
        }
    }

exit:

    if (msg != NULL)
    {
        WeaveLogDetail(Ble, msg);
    }

    return success;
}

static void WeaveAdapterAdded(GDBusProxy * proxy)
{
    DBusMessageIter iter;
    const char * addr = NULL;
    bool proxyAdded = false;
    dbus_bool_t powered = TRUE;

    if (g_dbus_proxy_get_property(proxy, "Address", &iter))
    {
        dbus_message_iter_get_basic(&iter, &addr);
        if (!strcasecmp(addr, gBluezServerEndpoint->adapterAddr))
        {
            if (gDefaultAdapter)
            {
                gDefaultAdapter->adapterProxy = proxy;
                gDefaultAdapter->advertisingProxy = NULL;
                gDefaultAdapter->profileProxy = NULL;
                gDefaultAdapter->deviceProxies.clear();
                proxyAdded = true;

                WeaveLogProgress(Ble, "%p(%s) added as default adapter proxy", proxy, addr);

                if (FALSE == g_dbus_proxy_set_property_basic(proxy, "Powered", DBUS_TYPE_BOOLEAN, &powered, PowerCb, NULL, NULL))
                {
                    WeaveLogError(Ble, "Fail to set Powered property for adapter %p(%s)", proxy, addr);
                }
            }
        }
    }

    if (!proxyAdded)
    {
        WeaveLogDetail(Ble, "Adaptor proxy %p(%s) ignored", proxy, addr);
    }
}

static void WeaveProfileAdded(GDBusProxy * proxy)
{
    if (gDefaultAdapter && gDefaultAdapter->adapterProxy)
    {
        if (strcmp(g_dbus_proxy_get_path(proxy), g_dbus_proxy_get_path(gDefaultAdapter->adapterProxy)) == 0)
        {
            WeaveLogProgress(Ble, "%p added as default profile(Gatt manager) proxy", proxy);
            gDefaultAdapter->profileProxy = proxy;
        }
    }
}

static void WeaveAdvertisingAdded(GDBusProxy * proxy)
{
    if (gDefaultAdapter && gDefaultAdapter->adapterProxy)
    {
        if (strcmp(g_dbus_proxy_get_path(proxy), g_dbus_proxy_get_path(gDefaultAdapter->adapterProxy)) == 0)
        {
            WeaveLogProgress(Ble, "%p added as default advertising manager proxy", proxy);
            gDefaultAdapter->advertisingProxy = proxy;
        }
    }
}

static void WeaveDeviceAdded(GDBusProxy *proxy)
{
    const char * devAddr = NULL;
    DBusMessageIter iter;

    if (gDefaultAdapter && CheckDeviceIsChild(proxy, gDefaultAdapter->adapterProxy))
    {
        if (g_dbus_proxy_get_property(proxy, "Address", &iter))
        {
            dbus_message_iter_get_basic(&iter, &devAddr);
            WeaveLogProgress(Ble, "%p(%s) added to device proxy list", proxy, devAddr);
        }

        gDefaultAdapter->deviceProxies.push_back(proxy);
    }
}

static void WeaveProxyAdded(GDBusProxy * proxy, void * bluezData)
{
    const char *interface = NULL;

    interface = g_dbus_proxy_get_interface(proxy);

    if (!strcmp(interface, ADAPTER_INTERFACE))
    {
        WeaveAdapterAdded(proxy);
    }
    else if (!strcmp(interface, PROFILE_INTERFACE))
    {
        WeaveProfileAdded(proxy);
    }
    else if (!strcmp(interface, ADVERTISING_MANAGER_INTERFACE))
    {
        WeaveAdvertisingAdded(proxy);
    }
    else if (!strcmp(interface, DEVICE_INTERFACE))
    {
        WeaveDeviceAdded(proxy);
    }
}

static void WeaveProxyDeleted(GDBusProxy * proxy, void * bluezData)
{
    const char *interface = NULL;
    interface = g_dbus_proxy_get_interface(proxy);

    if (!strcmp(interface, ADAPTER_INTERFACE))
    {
        WeaveLogProgress(Ble, "Got notification about %p adaptor proxy removal", proxy);
        if (gDefaultAdapter && gDefaultAdapter->adapterProxy == proxy)
        {
            gDefaultAdapter->adapterProxy = NULL;
        }
    }
    else if (!strcmp(interface, PROFILE_INTERFACE))
    {
        WeaveLogProgress(Ble, "Got notification about %p profile(gatt manager) proxy removal", proxy);
        if (gDefaultAdapter && gDefaultAdapter->profileProxy == proxy)
        {
            gDefaultAdapter->profileProxy = NULL;
        }
    }
    else if (!strcmp(interface, ADVERTISING_MANAGER_INTERFACE))
    {
        WeaveLogProgress(Ble, "Got notification about %p advertising manager proxy removal", proxy);
        if (gDefaultAdapter && gDefaultAdapter->advertisingProxy == proxy)
        {
            gDefaultAdapter->advertisingProxy = NULL;
        }
    }
    else if (!strcmp(interface, DEVICE_INTERFACE))
    {
        WeaveLogProgress(Ble, "Got notification about %p device proxy removal", proxy);
        if (gDefaultAdapter && !(gDefaultAdapter->deviceProxies.empty()))
        {
            gDefaultAdapter->deviceProxies.remove(proxy);
        }
    }
}

static void WeaveDisconnReply(DBusMessage * dbusMsg, void * bluezData)
{
    DBusError error;
    dbus_error_init(&error);
    if (TRUE == dbus_set_error_from_message(&error, dbusMsg))
    {
        WeaveLogError(Ble, "failed to disconnect with error: %s", error.name);
        dbus_error_free(&error);
    }
}

static void WeaveDeviceDisconnect(GDBusProxy * proxy)
{
    dbus_bool_t connected;
    const char * devAddr = NULL;
    DBusMessageIter iter;
    if (g_dbus_proxy_get_property(proxy, "Connected", &iter))
    {
        dbus_message_iter_get_basic(&iter, &connected);
        if (connected)
        {
            if (g_dbus_proxy_get_property(proxy, "Address", &iter))
            {
                dbus_message_iter_get_basic(&iter, &devAddr);
                WeaveLogRetain(Ble, "Issuing disconnect to device:%s", devAddr);
            }
            g_dbus_proxy_method_call(proxy, "Disconnect", NULL, WeaveDisconnReply, proxy, NULL);
        }
    }
}

static void WeavePropertyChange(GDBusProxy *proxy, const char *name, DBusMessageIter *iter, void *bluezData)
{
    const char *interface = NULL;
    dbus_bool_t connected;
    const char * devAddr = NULL;
    DBusMessageIter addrIter;

    interface = g_dbus_proxy_get_interface(proxy);
    if (!strcmp(interface, DEVICE_INTERFACE)) {
        if (CheckDeviceIsChild(proxy, gDefaultAdapter->adapterProxy)) {
            if (strcmp(name, "Connected") == 0)
            {
                dbus_message_iter_get_basic(iter, &connected);

                if (g_dbus_proxy_get_property(proxy, "Address", &addrIter))
                {
                    dbus_message_iter_get_basic(&addrIter, &devAddr);
                    WeaveLogRetain(Ble, "%s device %p(%s)", connected?"Connected to":"Disconnected with", proxy, devAddr);
                }

                if (connected)
                {
                    gBluezBleApplicationDelegate->NotifyBleActivity(kBleConnect);
                    WoBLEz_NewConnection(gBluezServerEndpoint);
                }
                else
                {
                    WoBLEz_ConnectionClosed(gBluezServerEndpoint);
                    CloseBleconnection();
                    gBluezBleApplicationDelegate->NotifyBleActivity(kBleDisconnect);
                }
            }
        }
    }
}

static void PowerCb(const DBusError * error, void * bluezData)
{
    WEAVE_ERROR err  = WEAVE_NO_ERROR;
    gboolean success = FALSE;

    VerifyOrExit(!dbus_error_is_set(error), err = WEAVE_ERROR_INCORRECT_STATE);

    success = RegisterWeaveService(gBluezDbusConn);
    VerifyOrExit(success == TRUE, err = WEAVE_ERROR_INCORRECT_STATE);

    gBluezServerEndpoint->weaveC1 = RegisterWeaveCharacteristic(gBluezDbusConn, UUID_WEAVE_C1, FLAGS_WEAVE_C1);
    VerifyOrExit(gBluezServerEndpoint->weaveC1 != NULL, err = WEAVE_ERROR_NO_MEMORY);

    WeaveLogDetail(Ble, "weave C1 uuid: %s, path: %s", gBluezServerEndpoint->weaveC1->uuid, gBluezServerEndpoint->weaveC1->path);

    gBluezServerEndpoint->weaveC2 = RegisterWeaveCharacteristic(gBluezDbusConn, UUID_WEAVE_C2, FLAGS_WEAVE_C2);
    VerifyOrExit(gBluezServerEndpoint->weaveC2 != NULL, err = WEAVE_ERROR_NO_MEMORY);

    WeaveLogDetail(Ble, "weave C2 uuid: %s, path: %s", gBluezServerEndpoint->weaveC2->uuid, gBluezServerEndpoint->weaveC2->path);

    success = SetupWeaveApp(gBluezDbusConn, gDefaultAdapter->profileProxy);
    VerifyOrExit(success == TRUE, err = WEAVE_ERROR_INCORRECT_STATE);

    success = EnableDiscoverable();
    VerifyOrExit(success == TRUE, err = WEAVE_ERROR_INCORRECT_STATE);

    success = SetAlias();
    VerifyOrExit(success == TRUE, err = WEAVE_ERROR_INCORRECT_STATE);

    success = AdvertisingRegister(gBluezDbusConn, gDefaultAdapter->advertisingProxy);
    VerifyOrExit(success == TRUE, err = WEAVE_ERROR_INCORRECT_STATE);

exit:

    if (err != WEAVE_NO_ERROR)
    {
        WeaveLogError(Ble, "PowerCb failed: %d", err);
    }
}

static void WeaveClientReady(GDBusClient * weaveClient, void * bluezData)
{
    WeaveLogProgress(Ble, "Weave client is ready");
    return;
}

uint16_t GetMTUWeaveCb(BLE_CONNECTION_OBJECT connObj)
{
    uint16_t mtu = gBluezServerEndpoint->mtu;
    WeaveLogDetail(Ble, "GetMTU: %d", mtu);
    return mtu;
}

void CloseBleconnection()
{
    if (gDefaultAdapter && !(gDefaultAdapter->deviceProxies.empty()))
    {
        // Check for connected device & close the connection
        for (auto iter = gDefaultAdapter->deviceProxies.begin();
                iter != gDefaultAdapter->deviceProxies.end(); iter++)
        {
            WeaveDeviceDisconnect(*iter);
        }
    }

    gBluezServerEndpoint->weaveC2->isNotifying = false;
    g_dbus_emit_property_changed(gBluezServerEndpoint->weaveC2->dbusConn, gBluezServerEndpoint->weaveC2->path,
                                 CHARACTERISTIC_INTERFACE, "Notifying");
#if BLE_CONFIG_BLUEZ_MTU_FEATURE
    PipeIODestroy(gBluezServerEndpoint->weaveC2->indicatePipeIO, gBluezServerEndpoint->weaveC2);
    PipeIODestroy(gBluezServerEndpoint->weaveC1->writePipeIO, gBluezServerEndpoint->weaveC1);
#endif //BLE_CONFIG_BLUEZ_MTU_FEATURE
}

void ExitBluezIOThread(void)
{
    g_main_loop_quit(gBluezMainLoop);
}

bool RunOnBluezIOThread(int (*aCallback)(void *), void * aClosure)
{
    GMainContext * context = NULL;
    const char * msg       = NULL;

    VerifyOrExit(gBluezMainLoop != NULL, msg = "RunOnBluezIOThread: BlueZ mainloop is NULL");
    VerifyOrExit(g_main_loop_is_running(gBluezMainLoop), msg = "RunOnBluezIOThread: mainloop is not running");

    context = g_main_loop_get_context(gBluezMainLoop);
    VerifyOrExit(context != NULL, msg = "RunOnBluezIOThread: main context is NULL");
    g_main_context_invoke(context, aCallback, aClosure);

exit:
    if (msg != NULL)
    {
        WeaveLogError(Ble, msg);
    }
    return msg == NULL;
}

bool RunBluezIOThread(BluezPeripheralArgs * arg)
{
    GDBusClient * weaveClient    = NULL;
    const char * msg             = NULL;
    gboolean success             = FALSE;
    WEAVE_ERROR err              = WEAVE_NO_ERROR;
    const char * advertisingType = "peripheral";

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

    VerifyOrExit(arg->bluezBleApplicationDelegate != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    gBluezBleApplicationDelegate = arg->bluezBleApplicationDelegate;

    VerifyOrExit(arg->bluezBlePlatformDelegate != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    gBluezBlePlatformDelegate = arg->bluezBlePlatformDelegate;

    gBluezBlePlatformDelegate->SetSendIndicationCallback(WoBLEz_ScheduleSendIndication);
    gBluezBlePlatformDelegate->SetGetMTUCallback(GetMTUWeaveCb);

    gDefaultAdapter = new Adapter();
    VerifyOrExit(gDefaultAdapter != NULL, err = WEAVE_ERROR_NO_MEMORY);

    gBluezServerEndpoint = (BluezServerEndpoint *) g_new0(BluezServerEndpoint, 1);
    VerifyOrExit(gBluezServerEndpoint != NULL, err = WEAVE_ERROR_NO_MEMORY);

    gBluezServerEndpoint->adapterName     = g_strdup(arg->bleName);
    gBluezServerEndpoint->adapterAddr     = g_strdup(arg->bleAddress);
    gBluezServerEndpoint->advertisingUUID = g_strdup(UUID_WEAVE_SHORT);
    gBluezServerEndpoint->advertisingType = g_strdup(advertisingType);

    gBluezServerEndpoint->weaveServiceData = g_new0(WeaveServiceData, 1);
    VerifyOrExit(gBluezServerEndpoint->weaveServiceData != NULL, err = WEAVE_ERROR_NO_MEMORY);
    /**
     * Data arranged in "Length Type Value" pairs inside Weave service data.
     * Length should include size of value + size of Type field, which is 1 byte
     */
    gBluezServerEndpoint->weaveServiceData->dataBlock0Len             = sizeof(WeaveIdInfo) + 1;
    gBluezServerEndpoint->weaveServiceData->dataBlock0Type            = WEAVE_SRV_DATA_BLOCK_TYPE_WEAVE_ID_INFO;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.major         = WEAVE_ID_INFO_MAJ_VER;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.minor         = WEAVE_ID_INFO_MIN_VER;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.vendorId      = arg->vendorId;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.productId     = arg->productId;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.deviceId      = arg->deviceId;
    gBluezServerEndpoint->weaveServiceData->weaveIdInfo.pairingStatus = arg->pairingStatus;

    gBluezServerEndpoint->mtu = HCI_MAX_MTU;
    gBluezMainLoop            = g_main_loop_new(NULL, FALSE);
    gBluezDbusConn            = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
    VerifyOrExit(gBluezDbusConn != NULL, err = WEAVE_ERROR_NO_MEMORY);

    success = g_dbus_attach_object_manager(gBluezDbusConn);
    VerifyOrExit(success == TRUE, msg = "Fail to attach object manager in RunBluezIOThread");

    weaveClient = g_dbus_client_new(gBluezDbusConn, BLUEZ_INTERFACE, BLUEZ_PATH);
    VerifyOrExit(weaveClient != NULL, err = WEAVE_ERROR_NO_MEMORY);

    success = g_dbus_client_set_proxy_handlers(weaveClient, WeaveProxyAdded, WeaveProxyDeleted, WeavePropertyChange, NULL);
    VerifyOrExit(success == TRUE, msg = "Fail to set weave proxy handler in RunBluezIOThread");

    success = g_dbus_client_set_ready_watch(weaveClient, WeaveClientReady, NULL);
    VerifyOrExit(success == TRUE, msg = "Fail to set ready watch for weave client in RunBluezIOThread");

    success = g_dbus_client_set_connect_watch(weaveClient, WeaveClientConnectHandler, NULL);
    VerifyOrExit(success == TRUE, msg = "Fail to set connect watch for weave client in RunBluezIOThread");

    success = g_dbus_client_set_disconnect_watch(weaveClient, WeaveClientDisconnectHandler, NULL);
    VerifyOrExit(success == TRUE, msg = "Fail to set disconnect watch for weave client in RunBluezIOThread");

    g_main_loop_run(gBluezMainLoop);
    WeaveLogProgress(Ble, "Exited from Bluez main loop");
exit:

    if (err != WEAVE_NO_ERROR)
    {
        success = FALSE;
        WeaveLogError(Ble, "RunBluezIOThread failed: %d", err);
    }

    if ((success != TRUE) && (msg != NULL))
    {
        WeaveLogError(Ble, msg);
    }

    if (gDefaultAdapter && gDefaultAdapter->advertisingProxy)
    {
        WeaveLogProgress(Ble, "Unregistering weave advertisement");

        if (FALSE == g_dbus_proxy_method_call(gDefaultAdapter->advertisingProxy,
                                              "UnregisterAdvertisement",
                                              WeaveUnregisterSetup, WeaveUnregisterReply,
                                              gBluezDbusConn, NULL))
        {
            WeaveLogError(Ble, "Fail to call UnregisterAdvertisement method");
        }

        if (FALSE == g_dbus_unregister_interface(gBluezDbusConn, ADVERTISING_PATH,
                                                 ADVERTISING_INTERFACE))
        {
            WeaveLogError(Ble, "Fail to unregister weave advertisement object");
        }
    }


    if (NULL != gBluezServerEndpoint)
    {
        if (NULL != gBluezServerEndpoint->weaveService)
        {
            ServiceDestroy(gBluezServerEndpoint->weaveService);
            gBluezServerEndpoint->weaveService = NULL;
        }

        if (NULL != gBluezServerEndpoint->weaveC1)
        {
            WeaveCharacteristicDestroy(gBluezServerEndpoint->weaveC1);
            gBluezServerEndpoint->weaveC1 = NULL;
        }

        if (NULL != gBluezServerEndpoint->weaveC2)
        {
            WeaveCharacteristicDestroy(gBluezServerEndpoint->weaveC2);
            gBluezServerEndpoint->weaveC2 = NULL;
        }

        g_free(gBluezServerEndpoint->adapterName);
        gBluezServerEndpoint->adapterName = NULL;
        g_free(gBluezServerEndpoint->adapterAddr);
        gBluezServerEndpoint->adapterAddr = NULL;
        g_free(gBluezServerEndpoint->advertisingUUID);
        gBluezServerEndpoint->advertisingUUID = NULL;
        g_free(gBluezServerEndpoint->advertisingType);
        gBluezServerEndpoint->advertisingType = NULL;
        g_free(gBluezServerEndpoint->weaveServiceData);
        gBluezServerEndpoint->weaveServiceData = NULL;
        g_free(gBluezServerEndpoint);
        gBluezServerEndpoint = NULL;
    }

    if (NULL != gDefaultAdapter)
    {
        delete gDefaultAdapter;
        gDefaultAdapter = NULL;
    }

    if (NULL != weaveClient)
    {
        g_dbus_client_unref(weaveClient);
    }

    if (NULL != gBluezDbusConn)
    {
        dbus_connection_unref(gBluezDbusConn);
        gBluezDbusConn = NULL;
    }

    if (NULL != gBluezMainLoop)
    {
        g_main_loop_unref(gBluezMainLoop);
        gBluezMainLoop = NULL;
    }

    gBluezBlePlatformDelegate = NULL;
    gBluezBleApplicationDelegate = NULL;
    return success;
}

} // namespace BlueZ
} /* namespace Platform */
} /* namespace Ble */
} /* namespace nl */

#endif /* CONFIG_BLE_PLATFORM_BLUEZ */
