/*
** Copyright 2006, The Android Open Source Project
**
** 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.
*/

#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
#define DBUS_INPUT_IFACE BLUEZ_DBUS_BASE_IFC ".Input"
#define DBUS_NETWORK_IFACE BLUEZ_DBUS_BASE_IFC ".Network"
#define DBUS_NETWORKSERVER_IFACE BLUEZ_DBUS_BASE_IFC ".NetworkServer"
#define DBUS_HEALTH_MANAGER_PATH "/org/bluez"
#define DBUS_HEALTH_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".HealthManager"
#define DBUS_HEALTH_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".HealthDevice"
#define DBUS_HEALTH_CHANNEL_IFACE BLUEZ_DBUS_BASE_IFC ".HealthChannel"

#define LOG_TAG "BluetoothService.cpp"

#include "android_bluetooth_common.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_util_Binder.h"
#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#ifdef HAVE_BLUETOOTH
#include <dbus/dbus.h>
#include <bluedroid/bluetooth.h>
#endif

#include <cutils/properties.h>

namespace android {

#define BLUETOOTH_CLASS_ERROR 0xFF000000
#define PROPERTIES_NREFS 10

#ifdef HAVE_BLUETOOTH
// We initialize these variables when we load class
// android.server.BluetoothService
static jfieldID field_mNativeData;
static jfieldID field_mEventLoop;

typedef struct {
    JNIEnv *env;
    DBusConnection *conn;
    const char *adapter;  // dbus object name of the local adapter
} native_data_t;

extern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
                                                           jobject);
extern DBusHandlerResult agent_event_filter(DBusConnection *conn,
                                            DBusMessage *msg,
                                            void *data);
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);


/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
 *  Perform quick sanity check, if there are any problems return NULL
 */
static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
    native_data_t *nat =
            (native_data_t *)(env->GetIntField(object, field_mNativeData));
    if (nat == NULL || nat->conn == NULL) {
        ALOGE("Uninitialized native data\n");
        return NULL;
    }
    return nat;
}
#endif

static void classInitNative(JNIEnv* env, jclass clazz) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
    field_mEventLoop = get_field(env, clazz, "mEventLoop",
            "Landroid/server/BluetoothEventLoop;");
#endif
}

/* Returns true on success (even if adapter is present but disabled).
 * Return false if dbus is down, or another serious error (out of memory)
*/
static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
    if (NULL == nat) {
        ALOGE("%s: out of memory!", __FUNCTION__);
        return false;
    }
    nat->env = env;

    env->SetIntField(object, field_mNativeData, (jint)nat);
    DBusError err;
    dbus_error_init(&err);
    dbus_threads_init_default();
    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
    if (dbus_error_is_set(&err)) {
        ALOGE("Could not get onto the system bus: %s", err.message);
        dbus_error_free(&err);
        return false;
    }
    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
#endif  /*HAVE_BLUETOOTH*/
    return true;
}

static const char *get_adapter_path(JNIEnv* env, jobject object) {
#ifdef HAVE_BLUETOOTH
    event_loop_native_data_t *event_nat =
        get_EventLoop_native_data(env, env->GetObjectField(object,
                                                           field_mEventLoop));
    if (event_nat == NULL)
        return NULL;
    return event_nat->adapter;
#else
    return NULL;
#endif
}

// This function is called when the adapter is enabled.
static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat =
        (native_data_t *)env->GetIntField(object, field_mNativeData);
    event_loop_native_data_t *event_nat =
        get_EventLoop_native_data(env, env->GetObjectField(object,
                                                           field_mEventLoop));
    // Register agent for remote devices.
    const char *device_agent_path = "/android/bluetooth/remote_device_agent";
    static const DBusObjectPathVTable agent_vtable = {
                 NULL, agent_event_filter, NULL, NULL, NULL, NULL };

    if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
                                              &agent_vtable, event_nat)) {
        ALOGE("%s: Can't register object path %s for remote device agent!",
                               __FUNCTION__, device_agent_path);
        return JNI_FALSE;
    }
#endif /*HAVE_BLUETOOTH*/
    return JNI_TRUE;
}

static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat =
               (native_data_t *)env->GetIntField(object, field_mNativeData);
    if (nat != NULL) {
        const char *device_agent_path =
            "/android/bluetooth/remote_device_agent";
        dbus_connection_unregister_object_path (nat->conn, device_agent_path);
    }
#endif /*HAVE_BLUETOOTH*/
    return JNI_TRUE;
}

static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat =
        (native_data_t *)env->GetIntField(object, field_mNativeData);
    if (nat) {
        free(nat);
        nat = NULL;
    }
#endif
}

static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        return (env->NewStringUTF(get_adapter_path(env, object)));
    }
#endif
    return NULL;
}


static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    DBusError err;
    const char *name;
    jboolean ret = JNI_FALSE;

    native_data_t *nat = get_native_data(env, object);
    if (nat == NULL) {
        goto done;
    }

    dbus_error_init(&err);

    /* Compose the command */
    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                       get_adapter_path(env, object),
                                       DBUS_ADAPTER_IFACE, "StartDiscovery");

    if (msg == NULL) {
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        }
        goto done;
    }

    /* Send the command. */
    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
    if (dbus_error_is_set(&err)) {
         LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         ret = JNI_FALSE;
         goto done;
    }

    ret = JNI_TRUE;
done:
    if (reply) dbus_message_unref(reply);
    if (msg) dbus_message_unref(msg);
    return ret;
#else
    return JNI_FALSE;
#endif
}

static jboolean stopDiscoveryNative(JNIEnv *env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    DBusError err;
    const char *name;
    native_data_t *nat;
    jboolean ret = JNI_FALSE;

    dbus_error_init(&err);

    nat = get_native_data(env, object);
    if (nat == NULL) {
        goto done;
    }

    /* Compose the command */
    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                       get_adapter_path(env, object),
                                       DBUS_ADAPTER_IFACE, "StopDiscovery");
    if (msg == NULL) {
        if (dbus_error_is_set(&err))
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto done;
    }

    /* Send the command. */
    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
    if (dbus_error_is_set(&err)) {
        if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
                   strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
            // hcid sends this if there is no active discovery to cancel
            ALOGV("%s: There was no active discovery to cancel", __FUNCTION__);
            dbus_error_free(&err);
        } else {
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        }
        goto done;
    }

    ret = JNI_TRUE;
done:
    if (msg) dbus_message_unref(msg);
    if (reply) dbus_message_unref(reply);
    return ret;
#else
    return JNI_FALSE;
#endif
}

static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    DBusError err;
    jbyte *hash, *randomizer;
    jbyteArray byteArray = NULL;
    int hash_len, r_len;
    if (nat) {
       DBusMessage *reply = dbus_func_args(env, nat->conn,
                           get_adapter_path(env, object),
                           DBUS_ADAPTER_IFACE, "ReadLocalOutOfBandData",
                           DBUS_TYPE_INVALID);
       if (!reply) return NULL;

       dbus_error_init(&err);
       if (dbus_message_get_args(reply, &err,
                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hash_len,
                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &r_len,
                                DBUS_TYPE_INVALID)) {
          if (hash_len == 16 && r_len == 16) {
               byteArray = env->NewByteArray(32);
               if (byteArray) {
                   env->SetByteArrayRegion(byteArray, 0, 16, hash);
                   env->SetByteArrayRegion(byteArray, 16, 16, randomizer);
               }
           } else {
               ALOGE("readAdapterOutOfBandDataNative: Hash len = %d, R len = %d",
                                                                  hash_len, r_len);
           }
       } else {
          LOG_AND_FREE_DBUS_ERROR(&err);
       }
       dbus_message_unref(reply);
       return byteArray;
    }
#endif
    return NULL;
}

static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
                                         jstring address, jint timeout_ms) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_address = env->GetStringUTFChars(address, NULL);
        ALOGV("... address = %s", c_address);
        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
        const char *capabilities = "DisplayYesNo";
        const char *agent_path = "/android/bluetooth/remote_device_agent";

        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
                                        onCreatePairedDeviceResult, // callback
                                        context_address,
                                        eventLoopNat,
                                        get_adapter_path(env, object),
                                        DBUS_ADAPTER_IFACE,
                                        "CreatePairedDevice",
                                        DBUS_TYPE_STRING, &c_address,
                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
                                        DBUS_TYPE_STRING, &capabilities,
                                        DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(address, c_address);
        return ret ? JNI_TRUE : JNI_FALSE;

    }
#endif
    return JNI_FALSE;
}

static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
                                                jstring address, jint timeout_ms) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_address = env->GetStringUTFChars(address, NULL);
        ALOGV("... address = %s", c_address);
        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
        const char *capabilities = "DisplayYesNo";
        const char *agent_path = "/android/bluetooth/remote_device_agent";

        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
                                        onCreatePairedDeviceResult, // callback
                                        context_address,
                                        eventLoopNat,
                                        get_adapter_path(env, object),
                                        DBUS_ADAPTER_IFACE,
                                        "CreatePairedDeviceOutOfBand",
                                        DBUS_TYPE_STRING, &c_address,
                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
                                        DBUS_TYPE_STRING, &capabilities,
                                        DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(address, c_address);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
                                          jstring path,
                                          jstring pattern, jint attr_id) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);
    if (nat && eventLoopNat) {
        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
        const char *c_path = env->GetStringUTFChars(path, NULL);
        ALOGV("... pattern = %s", c_pattern);
        ALOGV("... attr_id = %#X", attr_id);
        DBusMessage *reply =
            dbus_func_args(env, nat->conn, c_path,
                           DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
                           DBUS_TYPE_STRING, &c_pattern,
                           DBUS_TYPE_UINT16, &attr_id,
                           DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(pattern, c_pattern);
        env->ReleaseStringUTFChars(path, c_path);
        return reply ? dbus_returns_int32(env, reply) : -1;
    }
#endif
    return -1;
}

static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
                                           jstring address) {
    ALOGV("%s", __FUNCTION__);
    jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_address = env->GetStringUTFChars(address, NULL);
        DBusError err;
        dbus_error_init(&err);
        ALOGV("... address = %s", c_address);
        DBusMessage *reply =
            dbus_func_args_timeout(env, nat->conn, -1,
                                   get_adapter_path(env, object),
                                   DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
                                   DBUS_TYPE_STRING, &c_address,
                                   DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(address, c_address);
        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            } else
                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
            return JNI_FALSE;
        } else {
            result = JNI_TRUE;
        }
        dbus_message_unref(reply);
    }
#endif
    return JNI_FALSE;
}

static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
        bool ret = dbus_func_args_async(env, nat->conn, -1,
                                        NULL,
                                        NULL,
                                        NULL,
                                        get_adapter_path(env, object),
                                        DBUS_ADAPTER_IFACE,
                                        "RemoveDevice",
                                        DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                        DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(object_path, c_object_path);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    return bt_enable();
#endif
    return -1;
}

static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    return bt_disable();
#endif
    return -1;
}

static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    return bt_is_enabled();
#endif
    return -1;
}

static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
                                             jstring address, bool confirm,
                                             int nativeData) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply;
        if (confirm) {
            reply = dbus_message_new_method_return(msg);
        } else {
            reply = dbus_message_new_error(msg,
                "org.bluez.Error.Rejected", "User rejected confirmation");
        }

        if (!reply) {
            ALOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
                  "RequestPairingConsent to D-Bus\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
                         int passkey, int nativeData) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply = dbus_message_new_method_return(msg);
        if (!reply) {
            ALOGE("%s: Cannot create message reply to return Passkey code to "
                 "D-Bus\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
                                 DBUS_TYPE_INVALID);

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
                         jbyteArray hash, jbyteArray randomizer, int nativeData) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply = dbus_message_new_method_return(msg);
        jbyte *h_ptr = env->GetByteArrayElements(hash, NULL);
        jbyte *r_ptr = env->GetByteArrayElements(randomizer, NULL);
        if (!reply) {
            ALOGE("%s: Cannot create message reply to return remote OOB data to "
                 "D-Bus\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        dbus_message_append_args(reply,
                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &h_ptr, 16,
                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &r_ptr, 16,
                                DBUS_TYPE_INVALID);

        env->ReleaseByteArrayElements(hash, h_ptr, 0);
        env->ReleaseByteArrayElements(randomizer, r_ptr, 0);

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setAuthorizationNative(JNIEnv *env, jobject object, jstring address,
                         jboolean val, int nativeData) {
#ifdef HAVE_BLUETOOTH
  ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply;
        if (val) {
            reply = dbus_message_new_method_return(msg);
        } else {
            reply = dbus_message_new_error(msg,
                    "org.bluez.Error.Rejected", "Authorization rejected");
        }
        if (!reply) {
            ALOGE("%s: Cannot create message reply D-Bus\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
                         jstring pin, int nativeData) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply = dbus_message_new_method_return(msg);
        if (!reply) {
            ALOGE("%s: Cannot create message reply to return PIN code to "
                 "D-Bus\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        const char *c_pin = env->GetStringUTFChars(pin, NULL);

        dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
                                 DBUS_TYPE_INVALID);

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        env->ReleaseStringUTFChars(pin, c_pin);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
                                            jstring address, int nativeData) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg = (DBusMessage *)nativeData;
        DBusMessage *reply = dbus_message_new_error(msg,
                "org.bluez.Error.Canceled", "Pairing User Input was canceled");
        if (!reply) {
            ALOGE("%s: Cannot create message reply to return cancelUserInput to"
                 "D-BUS\n", __FUNCTION__);
            dbus_message_unref(msg);
            return JNI_FALSE;
        }

        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(msg);
        dbus_message_unref(reply);
        return JNI_TRUE;
    }
#endif
    return JNI_FALSE;
}

static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
                                                    jstring path)
{
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg, *reply;
        DBusError err;
        dbus_error_init(&err);

        const char *c_path = env->GetStringUTFChars(path, NULL);
        reply = dbus_func_args_timeout(env,
                                   nat->conn, -1, c_path,
                                   DBUS_DEVICE_IFACE, "GetProperties",
                                   DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(path, c_path);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            } else
                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
            return NULL;
        }
        env->PushLocalFrame(PROPERTIES_NREFS);

        DBusMessageIter iter;
        jobjectArray str_array = NULL;
        if (dbus_message_iter_init(reply, &iter))
           str_array =  parse_remote_device_properties(env, &iter);
        dbus_message_unref(reply);

        return (jobjectArray) env->PopLocalFrame(str_array);
    }
#endif
    return NULL;
}

static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg, *reply;
        DBusError err;
        dbus_error_init(&err);

        reply = dbus_func_args_timeout(env,
                                   nat->conn, -1, get_adapter_path(env, object),
                                   DBUS_ADAPTER_IFACE, "GetProperties",
                                   DBUS_TYPE_INVALID);
        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            } else
                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
            return NULL;
        }
        env->PushLocalFrame(PROPERTIES_NREFS);

        DBusMessageIter iter;
        jobjectArray str_array = NULL;
        if (dbus_message_iter_init(reply, &iter))
            str_array = parse_adapter_properties(env, &iter);
        dbus_message_unref(reply);

        return (jobjectArray) env->PopLocalFrame(str_array);
    }
#endif
    return NULL;
}

static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
                                         void *value, jint type) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg;
        DBusMessageIter iter;
        dbus_bool_t reply = JNI_FALSE;
        const char *c_key = env->GetStringUTFChars(key, NULL);

        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                           get_adapter_path(env, object),
                                           DBUS_ADAPTER_IFACE, "SetProperty");
        if (!msg) {
            ALOGE("%s: Can't allocate new method call for GetProperties!",
                  __FUNCTION__);
            env->ReleaseStringUTFChars(key, c_key);
            return JNI_FALSE;
        }

        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
        dbus_message_iter_init_append(msg, &iter);
        append_variant(&iter, type, value);

        // Asynchronous call - the callbacks come via propertyChange
        reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
        dbus_message_unref(msg);

        env->ReleaseStringUTFChars(key, c_key);
        return reply ? JNI_TRUE : JNI_FALSE;

    }
#endif
    return JNI_FALSE;
}

static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
                                               jstring value) {
#ifdef HAVE_BLUETOOTH
    const char *c_value = env->GetStringUTFChars(value, NULL);
    jboolean ret =  setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
    env->ReleaseStringUTFChars(value, (char *)c_value);
    return ret;
#else
    return JNI_FALSE;
#endif
}

static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
                                               jint value) {
#ifdef HAVE_BLUETOOTH
    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
#else
    return JNI_FALSE;
#endif
}

static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
                                               jint value) {
#ifdef HAVE_BLUETOOTH
    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
#else
    return JNI_FALSE;
#endif
}

static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
                                               jstring key, void *value, jint type) {
#ifdef HAVE_BLUETOOTH
    ALOGV("%s", __FUNCTION__);
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *msg;
        DBusMessageIter iter;
        dbus_bool_t reply = JNI_FALSE;

        const char *c_key = env->GetStringUTFChars(key, NULL);
        const char *c_path = env->GetStringUTFChars(path, NULL);

        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                          c_path, DBUS_DEVICE_IFACE, "SetProperty");
        if (!msg) {
            ALOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
            env->ReleaseStringUTFChars(key, c_key);
            env->ReleaseStringUTFChars(path, c_path);
            return JNI_FALSE;
        }

        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
        dbus_message_iter_init_append(msg, &iter);
        append_variant(&iter, type, value);

        // Asynchronous call - the callbacks come via Device propertyChange
        reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
        dbus_message_unref(msg);

        env->ReleaseStringUTFChars(path, c_path);
        env->ReleaseStringUTFChars(key, c_key);

        return reply ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
                                                     jstring path, jstring key, jint value) {
#ifdef HAVE_BLUETOOTH
    return setDevicePropertyNative(env, object, path, key,
                                        (void *)&value, DBUS_TYPE_BOOLEAN);
#else
    return JNI_FALSE;
#endif
}

static jboolean setDevicePropertyStringNative(JNIEnv *env, jobject object,
                                              jstring path, jstring key, jstring value) {
#ifdef HAVE_BLUETOOTH
    const char *c_value = env->GetStringUTFChars(value, NULL);
    jboolean ret = setDevicePropertyNative(env, object, path, key,
                                           (void *)&c_value, DBUS_TYPE_STRING);
    env->ReleaseStringUTFChars(value, (char *)c_value);
    return ret;
#else
    return JNI_FALSE;
#endif
}

static jboolean createDeviceNative(JNIEnv *env, jobject object,
                                                jstring address) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_address = env->GetStringUTFChars(address, NULL);
        ALOGV("... address = %s", c_address);
        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1,
                                        onCreateDeviceResult,
                                        context_address,
                                        eventLoopNat,
                                        get_adapter_path(env, object),
                                        DBUS_ADAPTER_IFACE,
                                        "CreateDevice",
                                        DBUS_TYPE_STRING, &c_address,
                                        DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(address, c_address);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean discoverServicesNative(JNIEnv *env, jobject object,
                                               jstring path, jstring pattern) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);
        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        ALOGV("... Object Path = %s", c_path);
        ALOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));

        bool ret = dbus_func_args_async(env, nat->conn, -1,
                                        onDiscoverServicesResult,
                                        context_path,
                                        eventLoopNat,
                                        c_path,
                                        DBUS_DEVICE_IFACE,
                                        "DiscoverServices",
                                        DBUS_TYPE_STRING, &c_pattern,
                                        DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(path, c_path);
        env->ReleaseStringUTFChars(pattern, c_pattern);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

#ifdef HAVE_BLUETOOTH
static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
    jint *handles;
    jintArray handleArray = NULL;
    int len;

    DBusError err;
    dbus_error_init(&err);

    if (dbus_message_get_args(reply, &err,
                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
                              DBUS_TYPE_INVALID)) {
        handleArray = env->NewIntArray(len);
        if (handleArray) {
            env->SetIntArrayRegion(handleArray, 0, len, handles);
        } else {
            ALOGE("Null array in extract_handles");
        }
    } else {
        LOG_AND_FREE_DBUS_ERROR(&err);
    }
    return handleArray;
}
#endif

static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
                                                jintArray uuids) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    DBusMessage *reply = NULL;

    native_data_t *nat = get_native_data(env, object);

    jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
    if (!svc_classes) return NULL;

    int len = env->GetArrayLength(uuids);
    reply = dbus_func_args(env, nat->conn,
                            get_adapter_path(env, object),
                            DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
                            &svc_classes, len, DBUS_TYPE_INVALID);
    env->ReleaseIntArrayElements(uuids, svc_classes, 0);
    return reply ? extract_handles(env, reply) : NULL;

#endif
    return NULL;
}

static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
                                                   jintArray handles) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jint *values = env->GetIntArrayElements(handles, NULL);
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    if (values == NULL) return JNI_FALSE;

    jsize len = env->GetArrayLength(handles);

    reply = dbus_func_args(env, nat->conn,
                            get_adapter_path(env, object),
                            DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
                            &values, len, DBUS_TYPE_INVALID);
    env->ReleaseIntArrayElements(handles, values, 0);
    return reply ? JNI_TRUE : JNI_FALSE;
#endif
    return JNI_FALSE;
}

static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
        jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_name = env->GetStringUTFChars(name, NULL);
        ALOGV("... name = %s", c_name);
        ALOGV("... uuid1 = %llX", uuidMsb);
        ALOGV("... uuid2 = %llX", uuidLsb);
        ALOGV("... channel = %d", channel);
        DBusMessage *reply = dbus_func_args(env, nat->conn,
                           get_adapter_path(env, object),
                           DBUS_ADAPTER_IFACE, "AddRfcommServiceRecord",
                           DBUS_TYPE_STRING, &c_name,
                           DBUS_TYPE_UINT64, &uuidMsb,
                           DBUS_TYPE_UINT64, &uuidLsb,
                           DBUS_TYPE_UINT16, &channel,
                           DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(name, c_name);
        return reply ? dbus_returns_uint32(env, reply) : -1;
    }
#endif
    return -1;
}

static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        ALOGV("... handle = %X", handle);
        DBusMessage *reply = dbus_func_args(env, nat->conn,
                           get_adapter_path(env, object),
                           DBUS_ADAPTER_IFACE, "RemoveServiceRecord",
                           DBUS_TYPE_UINT32, &handle,
                           DBUS_TYPE_INVALID);
        return reply ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
                                     jint num_slots) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
        DBusMessage *reply = dbus_func_args(env, nat->conn,
                           get_adapter_path(env, object),
                           DBUS_ADAPTER_IFACE, "SetLinkTimeout",
                           DBUS_TYPE_OBJECT_PATH, &c_object_path,
                           DBUS_TYPE_UINT32, &num_slots,
                           DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(object_path, c_object_path);
        return reply ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);

        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
                                        context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
                                        "Connect",
                                        DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(path, c_path);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
                                     jstring path) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);

        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
                                        context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
                                        "Disconnect",
                                        DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(path, c_path);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
                                            jstring src_role, jstring bridge) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        DBusMessage *reply;
        const char *c_role = env->GetStringUTFChars(src_role, NULL);
        const char *c_bridge = env->GetStringUTFChars(bridge, NULL);
        if (value) {
            ALOGE("setBluetoothTetheringNative true");
            reply = dbus_func_args(env, nat->conn,
                                  get_adapter_path(env, object),
                                  DBUS_NETWORKSERVER_IFACE,
                                  "Register",
                                  DBUS_TYPE_STRING, &c_role,
                                  DBUS_TYPE_STRING, &c_bridge,
                                  DBUS_TYPE_INVALID);
        } else {
            ALOGE("setBluetoothTetheringNative false");
            reply = dbus_func_args(env, nat->conn,
                                  get_adapter_path(env, object),
                                  DBUS_NETWORKSERVER_IFACE,
                                  "Unregister",
                                  DBUS_TYPE_STRING, &c_role,
                                  DBUS_TYPE_INVALID);
        }
        env->ReleaseStringUTFChars(src_role, c_role);
        env->ReleaseStringUTFChars(bridge, c_bridge);
        return reply ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
                                       jstring dstRole) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    ALOGE("connectPanDeviceNative");
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);
        const char *dst = env->GetStringUTFChars(dstRole, NULL);

        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
                                    context_path, eventLoopNat, c_path,
                                    DBUS_NETWORK_IFACE, "Connect",
                                    DBUS_TYPE_STRING, &dst,
                                    DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(path, c_path);
        env->ReleaseStringUTFChars(dstRole, dst);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
                                     jstring path) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    ALOGE("disconnectPanDeviceNative");
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);

        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
                                        context_path, eventLoopNat, c_path,
                                        DBUS_NETWORK_IFACE, "Disconnect",
                                        DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(path, c_path);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
                                                jstring path, jstring address,
                                                jstring iface) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    ALOGE("disconnectPanServerDeviceNative");
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_address = env->GetStringUTFChars(address, NULL);
        const char *c_path = env->GetStringUTFChars(path, NULL);
        const char *c_iface = env->GetStringUTFChars(iface, NULL);

        int len = env->GetStringLength(path) + 1;
        char *context_path = (char *)calloc(len, sizeof(char));
        strlcpy(context_path, c_path, len);  // for callback

        bool ret = dbus_func_args_async(env, nat->conn, -1,
                                        onPanDeviceConnectionResult,
                                        context_path, eventLoopNat,
                                        get_adapter_path(env, object),
                                        DBUS_NETWORKSERVER_IFACE,
                                        "DisconnectDevice",
                                        DBUS_TYPE_STRING, &c_address,
                                        DBUS_TYPE_STRING, &c_iface,
                                        DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(address, c_address);
        env->ReleaseStringUTFChars(iface, c_iface);
        env->ReleaseStringUTFChars(path, c_path);
        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jstring registerHealthApplicationNative(JNIEnv *env, jobject object,
                                           jint dataType, jstring role,
                                           jstring name, jstring channelType) {
    ALOGV("%s", __FUNCTION__);
    jstring path = NULL;
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_role = env->GetStringUTFChars(role, NULL);
        const char *c_name = env->GetStringUTFChars(name, NULL);
        const char *c_channel_type = env->GetStringUTFChars(channelType, NULL);
        char *c_path;
        DBusMessage *msg, *reply;
        DBusError err;
        dbus_error_init(&err);

        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                            DBUS_HEALTH_MANAGER_PATH,
                                            DBUS_HEALTH_MANAGER_IFACE,
                                            "CreateApplication");

        if (msg == NULL) {
            ALOGE("Could not allocate D-Bus message object!");
            return NULL;
        }

        /* append arguments */
        append_dict_args(msg,
                         "DataType", DBUS_TYPE_UINT16, &dataType,
                         "Role", DBUS_TYPE_STRING, &c_role,
                         "Description", DBUS_TYPE_STRING, &c_name,
                         "ChannelType", DBUS_TYPE_STRING, &c_channel_type,
                         DBUS_TYPE_INVALID);


        /* Make the call. */
        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);

        env->ReleaseStringUTFChars(role, c_role);
        env->ReleaseStringUTFChars(name, c_name);
        env->ReleaseStringUTFChars(channelType, c_channel_type);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
        } else {
            if (!dbus_message_get_args(reply, &err,
                                      DBUS_TYPE_OBJECT_PATH, &c_path,
                                      DBUS_TYPE_INVALID)) {
                if (dbus_error_is_set(&err)) {
                    LOG_AND_FREE_DBUS_ERROR(&err);
                }
            } else {
               path = env->NewStringUTF(c_path);
            }
            dbus_message_unref(reply);
        }
    }
#endif
    return path;
}

static jstring registerSinkHealthApplicationNative(JNIEnv *env, jobject object,
                                           jint dataType, jstring role,
                                           jstring name) {
    ALOGV("%s", __FUNCTION__);
    jstring path = NULL;
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_role = env->GetStringUTFChars(role, NULL);
        const char *c_name = env->GetStringUTFChars(name, NULL);
        char *c_path;

        DBusMessage *msg, *reply;
        DBusError err;
        dbus_error_init(&err);

        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                            DBUS_HEALTH_MANAGER_PATH,
                                            DBUS_HEALTH_MANAGER_IFACE,
                                            "CreateApplication");

        if (msg == NULL) {
            ALOGE("Could not allocate D-Bus message object!");
            return NULL;
        }

        /* append arguments */
        append_dict_args(msg,
                         "DataType", DBUS_TYPE_UINT16, &dataType,
                         "Role", DBUS_TYPE_STRING, &c_role,
                         "Description", DBUS_TYPE_STRING, &c_name,
                         DBUS_TYPE_INVALID);


        /* Make the call. */
        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);

        env->ReleaseStringUTFChars(role, c_role);
        env->ReleaseStringUTFChars(name, c_name);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
        } else {
            if (!dbus_message_get_args(reply, &err,
                                      DBUS_TYPE_OBJECT_PATH, &c_path,
                                      DBUS_TYPE_INVALID)) {
                if (dbus_error_is_set(&err)) {
                    LOG_AND_FREE_DBUS_ERROR(&err);
                }
            } else {
                path = env->NewStringUTF(c_path);
            }
            dbus_message_unref(reply);
        }
    }
#endif
    return path;
}

static jboolean unregisterHealthApplicationNative(JNIEnv *env, jobject object,
                                                    jstring path) {
    ALOGV("%s", __FUNCTION__);
    jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_path = env->GetStringUTFChars(path, NULL);
        DBusError err;
        dbus_error_init(&err);
        DBusMessage *reply =
            dbus_func_args_timeout(env, nat->conn, -1,
                                   DBUS_HEALTH_MANAGER_PATH,
                                   DBUS_HEALTH_MANAGER_IFACE, "DestroyApplication",
                                   DBUS_TYPE_OBJECT_PATH, &c_path,
                                   DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(path, c_path);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
        } else {
            result = JNI_TRUE;
        }
    }
#endif
    return result;
}

static jboolean createChannelNative(JNIEnv *env, jobject object,
                                       jstring devicePath, jstring appPath, jstring config,
                                       jint code) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
        const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
        const char *c_config = env->GetStringUTFChars(config, NULL);
        int *data = (int *) malloc(sizeof(int));
        if (data == NULL) return JNI_FALSE;

        *data = code;
        bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
                                        data, eventLoopNat, c_device_path,
                                        DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
                                        DBUS_TYPE_OBJECT_PATH, &c_app_path,
                                        DBUS_TYPE_STRING, &c_config,
                                        DBUS_TYPE_INVALID);


        env->ReleaseStringUTFChars(devicePath, c_device_path);
        env->ReleaseStringUTFChars(appPath, c_app_path);
        env->ReleaseStringUTFChars(config, c_config);

        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
                                     jstring channelPath, jint code) {
    ALOGE("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
    struct event_loop_native_data_t *eventLoopNat =
            get_EventLoop_native_data(env, eventLoop);

    if (nat && eventLoopNat) {
        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
        int *data = (int *) malloc(sizeof(int));
        if (data == NULL) return JNI_FALSE;

        *data = code;
        bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
                                        data, eventLoopNat, c_device_path,
                                        DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
                                        DBUS_TYPE_OBJECT_PATH, &c_channel_path,
                                        DBUS_TYPE_INVALID);

        env->ReleaseStringUTFChars(devicePath, c_device_path);
        env->ReleaseStringUTFChars(channelPath, c_channel_path);

        return ret ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
    ALOGE("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
        DBusError err;
        dbus_error_init(&err);

        DBusMessage *reply = dbus_func_args(env, nat->conn,
                           c_device_path,
                           DBUS_HEALTH_DEVICE_IFACE, "GetProperties",
                           DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(devicePath, c_device_path);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
        } else {
            DBusMessageIter iter;
            jobjectArray str_array = NULL;
            if (dbus_message_iter_init(reply, &iter))
                str_array = parse_health_device_properties(env, &iter);
            dbus_message_unref(reply);
            jstring path = (jstring) env->GetObjectArrayElement(str_array, 1);

            return path;
        }
    }
#endif
    return NULL;
}

static jstring getChannelApplicationNative(JNIEnv *env, jobject object, jstring channelPath) {
    ALOGE("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
        DBusError err;
        dbus_error_init(&err);

        DBusMessage *reply = dbus_func_args(env, nat->conn,
                                            c_channel_path,
                                            DBUS_HEALTH_CHANNEL_IFACE, "GetProperties",
                                            DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(channelPath, c_channel_path);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
        } else {
            DBusMessageIter iter;
            jobjectArray str_array = NULL;
            if (dbus_message_iter_init(reply, &iter))
                str_array = parse_health_channel_properties(env, &iter);
            dbus_message_unref(reply);

            jint len = env->GetArrayLength(str_array);

            jstring name, path;
            const char *c_name;

            for (int i = 0; i < len; i+=2) {
                name = (jstring) env->GetObjectArrayElement(str_array, i);
                c_name = env->GetStringUTFChars(name, NULL);

                if (!strcmp(c_name, "Application")) {
                    path = (jstring) env->GetObjectArrayElement(str_array, i+1);
                    env->ReleaseStringUTFChars(name, c_name);
                    return path;
                }
                env->ReleaseStringUTFChars(name, c_name);
            }
        }
    }
#endif
    return NULL;
}

static jboolean releaseChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
        DBusError err;
        dbus_error_init(&err);

        DBusMessage *reply = dbus_func_args(env, nat->conn,
                                            c_channel_path,
                                            DBUS_HEALTH_CHANNEL_IFACE, "Release",
                                            DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(channelPath, c_channel_path);

        return reply ? JNI_TRUE : JNI_FALSE;
    }
#endif
    return JNI_FALSE;
}

static jobject getChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
    ALOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    if (nat) {
        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
        int32_t fd;
        DBusError err;
        dbus_error_init(&err);

        DBusMessage *reply = dbus_func_args(env, nat->conn,
                                            c_channel_path,
                                            DBUS_HEALTH_CHANNEL_IFACE, "Acquire",
                                            DBUS_TYPE_INVALID);
        env->ReleaseStringUTFChars(channelPath, c_channel_path);

        if (!reply) {
            if (dbus_error_is_set(&err)) {
                LOG_AND_FREE_DBUS_ERROR(&err);
            }
            return NULL;
        }

        fd = dbus_returns_unixfd(env, reply);
        if (fd == -1) return NULL;

        int flags = fcntl(fd, F_GETFL);
        if (flags < 0) {
           ALOGE("Can't get flags with fcntl(): %s (%d)",
                                strerror(errno), errno);
           releaseChannelFdNative(env, object, channelPath);
           close(fd);
           return NULL;
        }

        flags &= ~O_NONBLOCK;
        int status = fcntl(fd, F_SETFL, flags);
        if (status < 0) {
           ALOGE("Can't set flags with fcntl(): %s (%d)",
               strerror(errno), errno);
           releaseChannelFdNative(env, object, channelPath);
           close(fd);
           return NULL;
        }

        // Create FileDescriptor object
        jobject fileDesc = jniCreateFileDescriptor(env, fd);
        if (fileDesc == NULL) {
            // FileDescriptor constructor has thrown an exception
            releaseChannelFdNative(env, object, channelPath);
            close(fd);
            return NULL;
        }

        // Wrap it in a ParcelFileDescriptor
        jobject parcelFileDesc = newParcelFileDescriptor(env, fileDesc);
        if (parcelFileDesc == NULL) {
            // ParcelFileDescriptor constructor has thrown an exception
            releaseChannelFdNative(env, object, channelPath);
            close(fd);
            return NULL;
        }

        return parcelFileDesc;
    }
#endif
    return NULL;
}



static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
    {"classInitNative", "()V", (void*)classInitNative},
    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
    {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
    {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
    {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},

    {"isEnabledNative", "()I", (void *)isEnabledNative},
    {"enableNative", "()I", (void *)enableNative},
    {"disableNative", "()I", (void *)disableNative},

    {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
    {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
      (void *)getDevicePropertiesNative},
    {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
      (void *)setAdapterPropertyStringNative},
    {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
      (void *)setAdapterPropertyBooleanNative},
    {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
      (void *)setAdapterPropertyIntegerNative},

    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
    {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},

    {"readAdapterOutOfBandDataNative", "()[B", (void *)readAdapterOutOfBandDataNative},
    {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
    {"createPairedDeviceOutOfBandNative", "(Ljava/lang/String;I)Z",
                                    (void *)createPairedDeviceOutOfBandNative},
    {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
    {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
    {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
      (void *)getDeviceServiceChannelNative},

    {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
            (void *)setPairingConfirmationNative},
    {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
    {"setRemoteOutOfBandDataNative", "(Ljava/lang/String;[B[BI)Z", (void *)setRemoteOutOfBandDataNative},
    {"setAuthorizationNative", "(Ljava/lang/String;ZI)Z", (void *)setAuthorizationNative},
    {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
    {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
            (void *)cancelPairingUserInputNative},
    {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
            (void *)setDevicePropertyBooleanNative},
    {"setDevicePropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
            (void *)setDevicePropertyStringNative},
    {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
    {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
    {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
    {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
    {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
    {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
    // HID functions
    {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
    {"disconnectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectInputDeviceNative},

    {"setBluetoothTetheringNative", "(ZLjava/lang/String;Ljava/lang/String;)Z",
              (void *)setBluetoothTetheringNative},
    {"connectPanDeviceNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
              (void *)connectPanDeviceNative},
    {"disconnectPanDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectPanDeviceNative},
    {"disconnectPanServerDeviceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
              (void *)disconnectPanServerDeviceNative},
    // Health function
    {"registerHealthApplicationNative",
              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
              (void *)registerHealthApplicationNative},
    {"registerHealthApplicationNative",
            "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
            (void *)registerSinkHealthApplicationNative},

    {"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
              (void *)unregisterHealthApplicationNative},
    {"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
              (void *)createChannelNative},
    {"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
              (void *)destroyChannelNative},
    {"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
    {"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
              (void *)getChannelApplicationNative},
    {"getChannelFdNative", "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", (void *)getChannelFdNative},
    {"releaseChannelFdNative", "(Ljava/lang/String;)Z", (void *)releaseChannelFdNative},
};


int register_android_server_BluetoothService(JNIEnv *env) {
    return AndroidRuntime::registerNativeMethods(env,
                "android/server/BluetoothService", sMethods, NELEM(sMethods));
}

} /* namespace android */
