android_server_BluetoothService.cpp revision bd022f423a33f0794bb53e5b0720da2d67e4631c
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
18d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
19bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly#define LOG_TAG "BluetoothService.cpp"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_bluetooth_common.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dbus/dbus.h>
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <bluedroid/bluetooth.h>
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h>
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
482b5be0748d160c6df1a9197272a776dc35879081Nick Pelly#define BLUETOOTH_CLASS_ERROR 0xFF000000
492b5be0748d160c6df1a9197272a776dc35879081Nick Pelly
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// We initialize these variables when we load class
52bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly// android.server.BluetoothService
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_mNativeData;
5428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jfieldID field_mEventLoop;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusConnection *conn;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *adapter;  // dbus object name of the local adapter
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} native_data_t;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltextern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
6328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                                           jobject);
64d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshextern DBusHandlerResult agent_event_filter(DBusConnection *conn,
65d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            DBusMessage *msg,
66d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            void *data);
67d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
68d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Perform quick sanity check, if there are any problems return NULL
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (native_data_t *)(env->GetIntField(object, field_mNativeData));
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL || nat->conn == NULL) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Uninitialized native data\n");
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return nat;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void classInitNative(JNIEnv* env, jclass clazz) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
8828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    field_mEventLoop = get_field(env, clazz, "mEventLoop",
8928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            "Landroid/server/BluetoothEventLoop;");
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Returns true on success (even if adapter is present but disabled).
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return false if dbus is down, or another serious error (out of memory)
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool initializeNativeDataNative(JNIEnv* env, jobject object) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == nat) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s: out of memory!", __FUNCTION__);
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->env = env;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, field_mNativeData, (jint)nat);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_threads_init_default();
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Could not get onto the system bus: %s", err.message);
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_free(&err);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169e0a19515b9047a00a6e98ce7f20690dff511f43Nick Pelly    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif  /*HAVE_BLUETOOTH*/
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
121d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic const char *get_adapter_path(JNIEnv* env, jobject object) {
12282aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
123d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
124d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
125d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (event_nat == NULL)
127d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return NULL;
128d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return event_nat->adapter;
12982aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#else
13082aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh    return NULL;
13182aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#endif
132d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
133d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
134d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh// This function is called when the adapter is enabled.
135d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (native_data_t *)env->GetIntField(object, field_mNativeData);
140d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
141d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
142d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
143d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    // Register agent for remote devices.
144d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *device_agent_path = "/android/bluetooth/remote_device_agent";
145d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    static const DBusObjectPathVTable agent_vtable = {
146d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                 NULL, agent_event_filter, NULL, NULL, NULL, NULL };
147d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
148d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
149d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                              &agent_vtable, event_nat)) {
150d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't register object path %s for remote device agent!",
151d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               __FUNCTION__, device_agent_path);
152d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_FALSE;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
154d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
155d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
158d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
161d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
162d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh               (native_data_t *)env->GetIntField(object, field_mNativeData);
163d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat != NULL) {
164d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *device_agent_path =
165d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "/android/bluetooth/remote_device_agent";
166d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_unregister_object_path (nat->conn, device_agent_path);
167d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
168d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
169d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
170d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
171d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
172d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void cleanupNativeDataNative(JNIEnv* env, jobject object) {
173d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
174d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
175d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
176d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        (native_data_t *)env->GetIntField(object, field_mNativeData);
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
178d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        free(nat);
179d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        nat = NULL;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring getAdapterPathNative(JNIEnv *env, jobject object) {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
189d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return (env->NewStringUTF(get_adapter_path(env, object)));
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean ret = JNI_FALSE;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
213d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
214d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
215d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
218d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
219d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
220d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
227d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
228d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         ret = JNI_FALSE;
229d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         goto done;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ret = JNI_TRUE;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
242d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void stopDiscoveryNative(JNIEnv *env, jobject object) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jstring ret;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat = get_native_data(env, object);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
260d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
261d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
262d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StopDiscovery");
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
264d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err))
265d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
272d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
273d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                   strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // hcid sends this if there is no active discovery to cancel
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("%s: There was no active discovery to cancel", __FUNCTION__);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_error_free(&err);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
288d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
289d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         jstring address, jint timeout_ms) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
29328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
29428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    struct event_loop_native_data_t *eventLoopNat =
29528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            get_EventLoop_native_data(env, eventLoop);
29628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
29728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat && eventLoopNat) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("... address = %s", c_address);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
301d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *capabilities = "DisplayYesNo";
302d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *agent_path = "/android/bluetooth/remote_device_agent";
303d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
306d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        onCreatePairedDeviceResult, // callback
30728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        context_address,
30828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        eventLoopNat,
309d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        get_adapter_path(env, object),
310d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_ADAPTER_IFACE,
311d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        "CreatePairedDevice",
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_STRING, &c_address,
313d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
314d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_STRING, &capabilities,
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_INVALID);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret ? JNI_TRUE : JNI_FALSE;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
324d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
325d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring path,
326d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring pattern, jint attr_id) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
328d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
330d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
331d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    struct event_loop_native_data_t *eventLoopNat =
332d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            get_EventLoop_native_data(env, eventLoop);
333d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat && eventLoopNat) {
334d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
335d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
336d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... pattern = %s", c_pattern);
337d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... attr_id = %#X", attr_id);
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
339d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args(env, nat->conn, c_path,
340d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
341d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_STRING, &c_pattern,
342d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_UINT16, &attr_id,
343d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_INVALID);
344d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(pattern, c_pattern);
345d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
346d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return reply ? dbus_returns_int32(env, reply) : -1;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
349d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return -1;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
352d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
353d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           jstring address) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean result = JNI_FALSE;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
362d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... address = %s", c_address);
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
364d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args_timeout(env, nat->conn, -1,
365d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   get_adapter_path(env, object),
366d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
367d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_STRING, &c_address,
368d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
370d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
371d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
372d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
373d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
374d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
375d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
377d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_TRUE;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
379d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
385d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
386d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
387d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jboolean result = JNI_FALSE;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
391d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
395d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args_error(env, nat->conn, &err,
396d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 get_adapter_path(env, object),
397d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_ADAPTER_IFACE, "RemoveDevice",
398d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 DBUS_TYPE_INVALID);
400d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
401d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
402d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
403d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
404d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
405d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_FALSE;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
407d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_TRUE;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
409d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(object_path, c_object_path);
410d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (reply) dbus_message_unref(reply);
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4132b5be0748d160c6df1a9197272a776dc35879081Nick Pelly    return result;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint enableNative(JNIEnv *env, jobject object) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_enable();
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint disableNative(JNIEnv *env, jobject object) {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_disable();
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint isEnabledNative(JNIEnv *env, jobject object) {
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_is_enabled();
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
440b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
441b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             jstring address, bool confirm,
442b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             int nativeData) {
443b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
444b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
445b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
446b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
447b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
448b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply;
449b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (confirm) {
450b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_method_return(msg);
451b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        } else {
452b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_error(msg,
453b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Rejected", "User rejected confirmation");
454b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
455b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
456b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
457b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to RequestConfirmation to "
458b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                 "D-Bus\n", __FUNCTION__);
459b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
460b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
461b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
462b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
463b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
464b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
465b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
466b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
467b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
468b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
469b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
470b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
471b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
472b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
473b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                         int passkey, int nativeData) {
474b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
475b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
476b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
477b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
478b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
479b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply = dbus_message_new_method_return(msg);
480b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
481b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return Passkey code to "
482b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                 "D-Bus\n", __FUNCTION__);
483b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
484b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
485b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
486b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
487b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
488b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                 DBUS_TYPE_INVALID);
489b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
490b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
491b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
492b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
493b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
494b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
495b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
496b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
497b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
498b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         jstring pin, int nativeData) {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Cannot create message reply to return PIN code to "
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-Bus\n", __FUNCTION__);
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_pin = env->GetStringUTFChars(pin, NULL);
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 DBUS_TYPE_INVALID);
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(pin, c_pin);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
530b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                            jstring address, int nativeData) {
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_error(msg,
537b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Canceled", "Pairing User Input was canceled");
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
539b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return cancelUserInput to"
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-BUS\n", __FUNCTION__);
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
554d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
555d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                    jstring path)
556d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh{
557d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
558d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
559d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
560d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
561d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
562d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
563d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
564d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
565d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
566d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
567d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, c_path,
568d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_DEVICE_IFACE, "GetProperties",
569d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
570d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
571d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
572d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
573d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
574d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
575d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
576d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
577d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
578d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
579d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
580d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
581d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
582d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           str_array =  parse_remote_device_properties(env, &iter);
583d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
584d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
585d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
586d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
587d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
588d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
589d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
590d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
591d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
592d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
593d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
594d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
595d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
596d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
597d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
598d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
599d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
600d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, get_adapter_path(env, object),
601d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "GetProperties",
602d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
603d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
604d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
605d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
606d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
607d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
608d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
609d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
610d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
611d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
612d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
613d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            str_array = parse_adapter_properties(env, &iter);
614d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
615d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
616d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
617d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
618d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
619d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
620d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
621d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
622d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         void *value, jint type) {
623d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
624d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
625d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
626d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
627d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *reply, *msg;
628d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
629d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
630d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_key = env->GetStringUTFChars(key, NULL);
631d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
632d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
633d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
634d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           get_adapter_path(env, object),
635d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           DBUS_ADAPTER_IFACE, "SetProperty");
636d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!msg) {
637d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOGE("%s: Can't allocate new method call for GetProperties!",
638d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                  __FUNCTION__);
639d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
640d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
641d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
642d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
643d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_iter_init_append(msg, &iter);
644d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        append_variant(&iter, type, value);
645d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
646d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
647d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(msg);
648d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
649d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(key, c_key);
650d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
651d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
652d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
653d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
654d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
655d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
656d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
657d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
658d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_TRUE;
659d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
660d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
661d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_FALSE;
662d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
663d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
664d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
665d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jstring value) {
666d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
667d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *c_value = env->GetStringUTFChars(value, NULL);
668d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jboolean ret =  setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
669d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    env->ReleaseStringUTFChars(value, (char *)c_value);
670d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return ret;
671d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
672d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
673d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
674d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
675d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
676d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
677d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
678d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
679d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
680d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
681d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
682d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
683d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
684d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
685d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
686d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
687d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
688d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
689d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
690d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
691d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
692d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
693d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
694d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"classInitNative", "()V", (void*)classInitNative},
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
699d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
700d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isEnabledNative", "()I", (void *)isEnabledNative},
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"enableNative", "()I", (void *)enableNative},
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"disableNative", "()I", (void *)disableNative},
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
708d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
709d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
710d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDevicePropertiesNative},
711d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
712d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyStringNative},
713d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
714d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyBooleanNative},
715d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
716d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyIntegerNative},
717d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
718d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
719d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
720d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
721d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
722d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
723d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
724d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
725d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDeviceServiceChannelNative},
726d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
727b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
728b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)setPairingConfirmationNative},
729b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
731b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
732b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)cancelPairingUserInputNative},
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
735bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyint register_android_server_BluetoothService(JNIEnv *env) {
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env,
737bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                "android/server/BluetoothService", sMethods, NELEM(sMethods));
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
741