android_server_BluetoothService.cpp revision 6d56b530e189d7213ec77d43d3d8af97fee04179
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
496d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh#define PROPERTIES_NREFS 10
502b5be0748d160c6df1a9197272a776dc35879081Nick Pelly
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// We initialize these variables when we load class
53bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly// android.server.BluetoothService
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_mNativeData;
5528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jfieldID field_mEventLoop;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct {
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusConnection *conn;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *adapter;  // dbus object name of the local adapter
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} native_data_t;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltextern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
6428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                                           jobject);
65d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshextern DBusHandlerResult agent_event_filter(DBusConnection *conn,
66d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            DBusMessage *msg,
67d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            void *data);
68d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
69d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Perform quick sanity check, if there are any problems return NULL
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (native_data_t *)(env->GetIntField(object, field_mNativeData));
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL || nat->conn == NULL) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Uninitialized native data\n");
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return nat;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void classInitNative(JNIEnv* env, jclass clazz) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
8928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    field_mEventLoop = get_field(env, clazz, "mEventLoop",
9028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            "Landroid/server/BluetoothEventLoop;");
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Returns true on success (even if adapter is present but disabled).
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return false if dbus is down, or another serious error (out of memory)
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool initializeNativeDataNative(JNIEnv* env, jobject object) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == nat) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s: out of memory!", __FUNCTION__);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->env = env;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, field_mNativeData, (jint)nat);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_threads_init_default();
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Could not get onto the system bus: %s", err.message);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_free(&err);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179e0a19515b9047a00a6e98ce7f20690dff511f43Nick Pelly    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif  /*HAVE_BLUETOOTH*/
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
122d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic const char *get_adapter_path(JNIEnv* env, jobject object) {
12382aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
124d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
125d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
127d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (event_nat == NULL)
128d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return NULL;
129d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return event_nat->adapter;
13082aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#else
13182aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh    return NULL;
13282aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#endif
133d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
134d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
135d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh// This function is called when the adapter is enabled.
136d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (native_data_t *)env->GetIntField(object, field_mNativeData);
141d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
142d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
143d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
144d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    // Register agent for remote devices.
145d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *device_agent_path = "/android/bluetooth/remote_device_agent";
146d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    static const DBusObjectPathVTable agent_vtable = {
147d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                 NULL, agent_event_filter, NULL, NULL, NULL, NULL };
148d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
149d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
150d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                              &agent_vtable, event_nat)) {
151d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't register object path %s for remote device agent!",
152d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               __FUNCTION__, device_agent_path);
153d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_FALSE;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
155d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
156d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
159d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
162d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
163d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh               (native_data_t *)env->GetIntField(object, field_mNativeData);
164d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat != NULL) {
165d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *device_agent_path =
166d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "/android/bluetooth/remote_device_agent";
167d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_unregister_object_path (nat->conn, device_agent_path);
168d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
169d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
170d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
171d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
172d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
173d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void cleanupNativeDataNative(JNIEnv* env, jobject object) {
174d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
175d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
176d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
177d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        (native_data_t *)env->GetIntField(object, field_mNativeData);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
179d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        free(nat);
180d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        nat = NULL;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring getAdapterPathNative(JNIEnv *env, jobject object) {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
190d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return (env->NewStringUTF(get_adapter_path(env, object)));
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean ret = JNI_FALSE;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
214d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
215d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
216d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
219d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
220d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
221d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
228d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
229d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         ret = JNI_FALSE;
230d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         goto done;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ret = JNI_TRUE;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
243d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void stopDiscoveryNative(JNIEnv *env, jobject object) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jstring ret;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat = get_native_data(env, object);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
261d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
262d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
263d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StopDiscovery");
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
265d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err))
266d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
273d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
274d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                   strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // hcid sends this if there is no active discovery to cancel
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("%s: There was no active discovery to cancel", __FUNCTION__);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_error_free(&err);
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
290d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         jstring address, jint timeout_ms) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
29428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
29528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    struct event_loop_native_data_t *eventLoopNat =
29628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            get_EventLoop_native_data(env, eventLoop);
29728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
29828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat && eventLoopNat) {
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("... address = %s", c_address);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
302d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *capabilities = "DisplayYesNo";
303d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *agent_path = "/android/bluetooth/remote_device_agent";
304d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
307d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        onCreatePairedDeviceResult, // callback
30828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        context_address,
30928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        eventLoopNat,
310d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        get_adapter_path(env, object),
311d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_ADAPTER_IFACE,
312d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        "CreatePairedDevice",
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_STRING, &c_address,
314d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
315d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_STRING, &capabilities,
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_INVALID);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret ? JNI_TRUE : JNI_FALSE;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
325d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
326d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring path,
327d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring pattern, jint attr_id) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
329d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
331d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
332d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    struct event_loop_native_data_t *eventLoopNat =
333d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            get_EventLoop_native_data(env, eventLoop);
334d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat && eventLoopNat) {
335d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
336d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
337d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... pattern = %s", c_pattern);
338d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... attr_id = %#X", attr_id);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
340d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args(env, nat->conn, c_path,
341d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
342d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_STRING, &c_pattern,
343d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_UINT16, &attr_id,
344d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_INVALID);
345d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(pattern, c_pattern);
346d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
347d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return reply ? dbus_returns_int32(env, reply) : -1;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
350d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return -1;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
353d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
354d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           jstring address) {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean result = JNI_FALSE;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
363d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... address = %s", c_address);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
365d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args_timeout(env, nat->conn, -1,
366d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   get_adapter_path(env, object),
367d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
368d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_STRING, &c_address,
369d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
371d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
372d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
373d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
374d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
375d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
376d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
378d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_TRUE;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
380d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
386d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
387d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
388d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jboolean result = JNI_FALSE;
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
392d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
396d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args_error(env, nat->conn, &err,
397d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 get_adapter_path(env, object),
398d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_ADAPTER_IFACE, "RemoveDevice",
399d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 DBUS_TYPE_INVALID);
401d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
402d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
403d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
404d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
405d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
406d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_FALSE;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
408d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_TRUE;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
410d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(object_path, c_object_path);
411d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (reply) dbus_message_unref(reply);
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4142b5be0748d160c6df1a9197272a776dc35879081Nick Pelly    return result;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint enableNative(JNIEnv *env, jobject object) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_enable();
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint disableNative(JNIEnv *env, jobject object) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_disable();
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint isEnabledNative(JNIEnv *env, jobject object) {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_is_enabled();
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
441b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
442b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             jstring address, bool confirm,
443b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             int nativeData) {
444b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
445b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
446b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
447b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
448b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
449b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply;
450b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (confirm) {
451b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_method_return(msg);
452b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        } else {
453b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_error(msg,
454b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Rejected", "User rejected confirmation");
455b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
456b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
457b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
458b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to RequestConfirmation to "
459b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                 "D-Bus\n", __FUNCTION__);
460b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
461b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
462b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
463b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
464b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
465b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
466b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
467b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
468b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
469b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
470b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
471b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
472b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
473b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
474b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                         int passkey, int nativeData) {
475b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
476b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
477b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
478b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
479b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
480b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply = dbus_message_new_method_return(msg);
481b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
482b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return Passkey code to "
483b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                 "D-Bus\n", __FUNCTION__);
484b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
485b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
486b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
487b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
488b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
489b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                 DBUS_TYPE_INVALID);
490b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
491b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
492b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
493b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
494b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
495b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
496b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
497b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
498b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
499b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         jstring pin, int nativeData) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Cannot create message reply to return PIN code to "
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-Bus\n", __FUNCTION__);
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_pin = env->GetStringUTFChars(pin, NULL);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 DBUS_TYPE_INVALID);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(pin, c_pin);
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
530b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
531b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                            jstring address, int nativeData) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_error(msg,
538b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Canceled", "Pairing User Input was canceled");
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
540b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return cancelUserInput to"
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-BUS\n", __FUNCTION__);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
555d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
556d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                    jstring path)
557d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh{
558d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
559d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
560d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
561d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
562d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
563d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
564d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
565d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
566d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
567d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
568d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, c_path,
569d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_DEVICE_IFACE, "GetProperties",
570d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
571d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
572d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
573d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
574d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
575d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
576d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
577d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
578d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
579d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
5806d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PushLocalFrame(PROPERTIES_NREFS);
5816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
582d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
583d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
584d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
585d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           str_array =  parse_remote_device_properties(env, &iter);
586d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
5876d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
5886d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PopLocalFrame(NULL);
5896d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
590d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
591d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
592d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
593d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
594d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
595d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
596d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
597d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
598d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
599d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
600d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
601d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
602d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
603d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
604d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
605d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
606d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, get_adapter_path(env, object),
607d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "GetProperties",
608d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
609d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
610d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
611d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
612d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
613d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
614d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
615d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
6166d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PushLocalFrame(PROPERTIES_NREFS);
6176d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
618d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
619d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
620d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
621d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            str_array = parse_adapter_properties(env, &iter);
622d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
6236d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
6246d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PopLocalFrame(NULL);
625d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
626d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
627d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
628d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
629d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
630d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
631d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
632d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         void *value, jint type) {
633d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
634d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
635d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
636d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
637d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *reply, *msg;
638d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
639d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
640d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_key = env->GetStringUTFChars(key, NULL);
641d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
642d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
643d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
644d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           get_adapter_path(env, object),
645d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           DBUS_ADAPTER_IFACE, "SetProperty");
646d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!msg) {
647d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOGE("%s: Can't allocate new method call for GetProperties!",
648d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                  __FUNCTION__);
649d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
650d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
651d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
652d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
653d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_iter_init_append(msg, &iter);
654d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        append_variant(&iter, type, value);
655d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
656d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
657d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(msg);
658d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
659d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(key, c_key);
660d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
661d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
662d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
663d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
664d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
665d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
666d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
667d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
668d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_TRUE;
669d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
670d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
671d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_FALSE;
672d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
673d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
674d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
675d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jstring value) {
676d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
677d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *c_value = env->GetStringUTFChars(value, NULL);
678d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jboolean ret =  setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
679d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    env->ReleaseStringUTFChars(value, (char *)c_value);
680d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return ret;
681d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
682d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
683d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
684d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
685d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
686d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
687d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
688d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
689d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
690d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
691d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
692d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
693d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
694d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
695d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
696d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
697d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
698d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
699d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
700d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
701d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
702d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
703d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
704d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"classInitNative", "()V", (void*)classInitNative},
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
709d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
710d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isEnabledNative", "()I", (void *)isEnabledNative},
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"enableNative", "()I", (void *)enableNative},
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"disableNative", "()I", (void *)disableNative},
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
718d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
719d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
720d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDevicePropertiesNative},
721d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
722d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyStringNative},
723d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
724d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyBooleanNative},
725d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
726d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyIntegerNative},
727d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
728d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
729d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
730d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
731d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
732d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
733d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
734d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
735d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDeviceServiceChannelNative},
736d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
737b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
738b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)setPairingConfirmationNative},
739b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
741b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
742b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)cancelPairingUserInputNative},
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
745bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyint register_android_server_BluetoothService(JNIEnv *env) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env,
747bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                "android/server/BluetoothService", sMethods, NELEM(sMethods));
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
751