android_server_BluetoothService.cpp revision 995ae82f38d93050a5f1b80433e8ae844a05953d
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);
691caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
701caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
71d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Perform quick sanity check, if there are any problems return NULL
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (native_data_t *)(env->GetIntField(object, field_mNativeData));
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL || nat->conn == NULL) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Uninitialized native data\n");
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return nat;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void classInitNative(JNIEnv* env, jclass clazz) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
9128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    field_mEventLoop = get_field(env, clazz, "mEventLoop",
9228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            "Landroid/server/BluetoothEventLoop;");
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Returns true on success (even if adapter is present but disabled).
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return false if dbus is down, or another serious error (out of memory)
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool initializeNativeDataNative(JNIEnv* env, jobject object) {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == nat) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s: out of memory!", __FUNCTION__);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->env = env;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, field_mNativeData, (jint)nat);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_threads_init_default();
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Could not get onto the system bus: %s", err.message);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_free(&err);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199e0a19515b9047a00a6e98ce7f20690dff511f43Nick Pelly    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif  /*HAVE_BLUETOOTH*/
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
124d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic const char *get_adapter_path(JNIEnv* env, jobject object) {
12582aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
127d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
128d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
129d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (event_nat == NULL)
130d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return NULL;
131d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return event_nat->adapter;
13282aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#else
13382aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh    return NULL;
13482aea4abef3a1753425e4486af13710c27383588Jaikumar Ganesh#endif
135d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
136d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
137d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh// This function is called when the adapter is enabled.
138d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (native_data_t *)env->GetIntField(object, field_mNativeData);
143d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    event_loop_native_data_t *event_nat =
144d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        get_EventLoop_native_data(env, env->GetObjectField(object,
145d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                           field_mEventLoop));
146d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    // Register agent for remote devices.
147d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *device_agent_path = "/android/bluetooth/remote_device_agent";
148d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    static const DBusObjectPathVTable agent_vtable = {
149d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                 NULL, agent_event_filter, NULL, NULL, NULL, NULL };
150d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
151d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
152d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                              &agent_vtable, event_nat)) {
153d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't register object path %s for remote device agent!",
154d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               __FUNCTION__, device_agent_path);
155d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_FALSE;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
157d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
158d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
161d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
164d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
165d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh               (native_data_t *)env->GetIntField(object, field_mNativeData);
166d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat != NULL) {
167d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *device_agent_path =
168d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "/android/bluetooth/remote_device_agent";
169d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_unregister_object_path (nat->conn, device_agent_path);
170d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
171d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif /*HAVE_BLUETOOTH*/
172d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_TRUE;
173d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
174d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
175d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void cleanupNativeDataNative(JNIEnv* env, jobject object) {
176d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
177d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
178d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat =
179d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        (native_data_t *)env->GetIntField(object, field_mNativeData);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
181d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        free(nat);
182d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        nat = NULL;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring getAdapterPathNative(JNIEnv *env, jobject object) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
192d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return (env->NewStringUTF(get_adapter_path(env, object)));
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean ret = JNI_FALSE;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
216d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
217d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
218d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
221d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
222d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
223d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
230d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
231d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         ret = JNI_FALSE;
232d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         goto done;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ret = JNI_TRUE;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
245d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic void stopDiscoveryNative(JNIEnv *env, jobject object) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *msg = NULL;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusMessage *reply = NULL;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *name;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jstring ret;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat = get_native_data(env, object);
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat == NULL) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Compose the command */
263d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
264d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       get_adapter_path(env, object),
265d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       DBUS_ADAPTER_IFACE, "StopDiscovery");
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg == NULL) {
267d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err))
268d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Send the command. */
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_error_is_set(&err)) {
275d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
276d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                   strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // hcid sends this if there is no active discovery to cancel
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("%s: There was no active discovery to cancel", __FUNCTION__);
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_error_free(&err);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (msg) dbus_message_unref(msg);
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply) dbus_message_unref(reply);
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
291d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
292d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         jstring address, jint timeout_ms) {
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
29628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
29728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    struct event_loop_native_data_t *eventLoopNat =
29828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            get_EventLoop_native_data(env, eventLoop);
29928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
30028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat && eventLoopNat) {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("... address = %s", c_address);
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
304d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *capabilities = "DisplayYesNo";
305d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *agent_path = "/android/bluetooth/remote_device_agent";
306d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
309d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        onCreatePairedDeviceResult, // callback
31028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        context_address,
31128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                        eventLoopNat,
312d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        get_adapter_path(env, object),
313d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_ADAPTER_IFACE,
314d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        "CreatePairedDevice",
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_STRING, &c_address,
316d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
317d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                        DBUS_TYPE_STRING, &capabilities,
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        DBUS_TYPE_INVALID);
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret ? JNI_TRUE : JNI_FALSE;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
327d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
328d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring path,
329d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                          jstring pattern, jint attr_id) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
331d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
333d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
334d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    struct event_loop_native_data_t *eventLoopNat =
335d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            get_EventLoop_native_data(env, eventLoop);
336d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat && eventLoopNat) {
337d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
338d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
339d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... pattern = %s", c_pattern);
340d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... attr_id = %#X", attr_id);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
342d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args(env, nat->conn, c_path,
343d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
344d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_STRING, &c_pattern,
345d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_UINT16, &attr_id,
346d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                           DBUS_TYPE_INVALID);
347d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(pattern, c_pattern);
348d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
349d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return reply ? dbus_returns_int32(env, reply) : -1;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
352d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return -1;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
355d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
356d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           jstring address) {
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean result = JNI_FALSE;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_address = env->GetStringUTFChars(address, NULL);
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
365d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... address = %s", c_address);
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply =
367d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_func_args_timeout(env, nat->conn, -1,
368d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   get_adapter_path(env, object),
369d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
370d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_STRING, &c_address,
371d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(address, c_address);
373d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
374d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
375d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
376d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
377d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
378d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
380d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            result = JNI_TRUE;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
382d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
388d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
389d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
393d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
394995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh        bool ret = dbus_func_args_async(env, nat->conn, -1,
395995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        NULL,
396995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        NULL,
397995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        NULL,
398995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        get_adapter_path(env, object),
399995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        DBUS_ADAPTER_IFACE,
400995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        "RemoveDevice",
401995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        DBUS_TYPE_OBJECT_PATH, &c_object_path,
402995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh                                        DBUS_TYPE_INVALID);
403d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(object_path, c_object_path);
404995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh        return ret ? JNI_TRUE : JNI_FALSE;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
407995ae82f38d93050a5f1b80433e8ae844a05953dJaikumar Ganesh    return JNI_FALSE;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint enableNative(JNIEnv *env, jobject object) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_enable();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint disableNative(JNIEnv *env, jobject object) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_disable();
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint isEnabledNative(JNIEnv *env, jobject object) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return bt_is_enabled();
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
434b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
435b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             jstring address, bool confirm,
436b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                             int nativeData) {
437b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
438b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
439b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
440b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
441b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
442b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply;
443b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (confirm) {
444b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_method_return(msg);
445b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        } else {
446b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            reply = dbus_message_new_error(msg,
447b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Rejected", "User rejected confirmation");
448b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
449b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
450b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
45132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            LOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
45232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                  "RequestPairingConsent to D-Bus\n", __FUNCTION__);
453b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
454b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
455b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
456b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
457b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
458b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
459b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
460b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
461b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
462b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
463b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
464b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
465b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
466b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
467b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                         int passkey, int nativeData) {
468b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#ifdef HAVE_BLUETOOTH
469b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    LOGV(__FUNCTION__);
470b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
471b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    if (nat) {
472b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *msg = (DBusMessage *)nativeData;
473b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        DBusMessage *reply = dbus_message_new_method_return(msg);
474b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!reply) {
475b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return Passkey code to "
476b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                 "D-Bus\n", __FUNCTION__);
477b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            dbus_message_unref(msg);
478b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            return JNI_FALSE;
479b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
480b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
481b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
482b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                 DBUS_TYPE_INVALID);
483b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
484b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_connection_send(nat->conn, reply, NULL);
485b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(msg);
486b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_unref(reply);
487b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return JNI_TRUE;
488b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
489b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh#endif
490b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    return JNI_FALSE;
491b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh}
492b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         jstring pin, int nativeData) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Cannot create message reply to return PIN code to "
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-Bus\n", __FUNCTION__);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *c_pin = env->GetStringUTFChars(pin, NULL);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 DBUS_TYPE_INVALID);
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleaseStringUTFChars(pin, c_pin);
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
523b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
524b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                            jstring address, int nativeData) {
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV(__FUNCTION__);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = get_native_data(env, object);
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *msg = (DBusMessage *)nativeData;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_error(msg,
531b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                "org.bluez.Error.Canceled", "Pairing User Input was canceled");
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
533b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Cannot create message reply to return cancelUserInput to"
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 "D-BUS\n", __FUNCTION__);
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_message_unref(msg);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(msg);
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
548d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
549d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                    jstring path)
550d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh{
551d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
552d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
553d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
554d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
555d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
556d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
557d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
558d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
559d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
560d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
561d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, c_path,
562d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_DEVICE_IFACE, "GetProperties",
563d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
564d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
565d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
566d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
567d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
568d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
569d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
570d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
571d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
572d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
5736d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PushLocalFrame(PROPERTIES_NREFS);
5746d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
575d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
576d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
577d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
578d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           str_array =  parse_remote_device_properties(env, &iter);
579d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
5806d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
5816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PopLocalFrame(NULL);
5826d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
583d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
584d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
585d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
586d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
587d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
588d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
589d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
590d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
591d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
592d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
593d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
594d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
595d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
596d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
597d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
598d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_func_args_timeout(env,
599d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   nat->conn, -1, get_adapter_path(env, object),
600d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_ADAPTER_IFACE, "GetProperties",
601d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_INVALID);
602d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
603d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
604d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
605d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
606d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
607d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return NULL;
608d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
6096d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PushLocalFrame(PROPERTIES_NREFS);
6106d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
611d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
612d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
613d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(reply, &iter))
614d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            str_array = parse_adapter_properties(env, &iter);
615d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(reply);
6166d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
6176d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        env->PopLocalFrame(NULL);
618d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return str_array;
619d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
620d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
621d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return NULL;
622d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
623d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
624d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
625d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                         void *value, jint type) {
626d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
627d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGV(__FUNCTION__);
628d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
629d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat) {
630d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *reply, *msg;
631d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
632d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
633d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char *c_key = env->GetStringUTFChars(key, NULL);
634d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
635d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
636d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
637d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           get_adapter_path(env, object),
638d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           DBUS_ADAPTER_IFACE, "SetProperty");
639d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!msg) {
640d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOGE("%s: Can't allocate new method call for GetProperties!",
641d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                  __FUNCTION__);
642efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            env->ReleaseStringUTFChars(key, c_key);
643d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
644d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
645d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
646d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
647d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_iter_init_append(msg, &iter);
648d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        append_variant(&iter, type, value);
649d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
650d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
651d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_unref(msg);
652d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
653d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->ReleaseStringUTFChars(key, c_key);
654d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
655d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (!reply) {
656d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
657d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOG_AND_FREE_DBUS_ERROR(&err);
658d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            } else
659d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
660d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            return JNI_FALSE;
661d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
662d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_TRUE;
663d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
664d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh#endif
665d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_FALSE;
666d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
667d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
668d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
669d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jstring value) {
670d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
671d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *c_value = env->GetStringUTFChars(value, NULL);
672d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    jboolean ret =  setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
673d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    env->ReleaseStringUTFChars(value, (char *)c_value);
674d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return ret;
675d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
676d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
677d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
678d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
679d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
680d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
681d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
682d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
683d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
684d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
685d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
686d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
687d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
688d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
689d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
690d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               jint value) {
691d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#ifdef HAVE_BLUETOOTH
692d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
693d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#else
694d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh    return JNI_FALSE;
695d46134946dd6c227d60cc27915b6fd477e36a598Jaikumar Ganesh#endif
696d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
697d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
698efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yuestatic jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
699efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue                                               jstring key, void *value, jint type) {
700efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue#ifdef HAVE_BLUETOOTH
701efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    LOGV(__FUNCTION__);
702efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    native_data_t *nat = get_native_data(env, object);
703efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    if (nat) {
704efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        DBusMessage *reply, *msg;
705efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        DBusMessageIter iter;
706efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        DBusError err;
707efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
708efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        const char *c_key = env->GetStringUTFChars(key, NULL);
709efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        const char *c_path = env->GetStringUTFChars(path, NULL);
710efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
711efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        dbus_error_init(&err);
712efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
713efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue                                          c_path, DBUS_DEVICE_IFACE, "SetProperty");
714efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        if (!msg) {
715efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            LOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
716efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            env->ReleaseStringUTFChars(key, c_key);
717efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            env->ReleaseStringUTFChars(path, c_path);
718efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            return JNI_FALSE;
719efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        }
720efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
721efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
722efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        dbus_message_iter_init_append(msg, &iter);
723efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        append_variant(&iter, type, value);
724efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
725efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
726efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        dbus_message_unref(msg);
727efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
728efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        env->ReleaseStringUTFChars(key, c_key);
729efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        env->ReleaseStringUTFChars(path, c_path);
730efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        if (!reply) {
731efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            if (dbus_error_is_set(&err)) {
732efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue                LOG_AND_FREE_DBUS_ERROR(&err);
733efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            } else
734efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            LOGE("DBus reply is NULL in function %s", __FUNCTION__);
735efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            return JNI_FALSE;
736efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        }
737efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        return JNI_TRUE;
738efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    }
739efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue#endif
740efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    return JNI_FALSE;
741efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue}
742efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
743efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yuestatic jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
744efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue                                                     jstring path, jstring key, jint value) {
745efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue#ifdef HAVE_BLUETOOTH
746efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    return setDevicePropertyNative(env, object, path, key,
747efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue                                        (void *)&value, DBUS_TYPE_BOOLEAN);
748efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue#else
749efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    return JNI_FALSE;
750efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue#endif
751efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue}
752d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
7531caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
7541caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jboolean createDeviceNative(JNIEnv *env, jobject object,
7551caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                                jstring address) {
7561caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    LOGV(__FUNCTION__);
7571caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh#ifdef HAVE_BLUETOOTH
7581caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
7591caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
7601caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    struct event_loop_native_data_t *eventLoopNat =
7611caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh            get_EventLoop_native_data(env, eventLoop);
7621caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
7631caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (nat && eventLoopNat) {
7641caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        const char *c_address = env->GetStringUTFChars(address, NULL);
7651caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOGV("... address = %s", c_address);
7661caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
7671caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
7681caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
7691caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        bool ret = dbus_func_args_async(env, nat->conn, -1,
7701caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        onCreateDeviceResult,
7711caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        context_address,
7721caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        eventLoopNat,
7731caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        get_adapter_path(env, object),
7741caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_ADAPTER_IFACE,
7751caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        "CreateDevice",
7761caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_TYPE_STRING, &c_address,
7771caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_TYPE_INVALID);
7781caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        env->ReleaseStringUTFChars(address, c_address);
7791caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        return ret ? JNI_TRUE : JNI_FALSE;
7801caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
7811caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh#endif
7821caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    return JNI_FALSE;
7831caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
7841caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
7851caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jboolean discoverServicesNative(JNIEnv *env, jobject object,
7861caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                               jstring path, jstring pattern) {
7871caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    LOGV(__FUNCTION__);
7881caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh#ifdef HAVE_BLUETOOTH
7891caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = get_native_data(env, object);
7901caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
7911caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    struct event_loop_native_data_t *eventLoopNat =
7921caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh            get_EventLoop_native_data(env, eventLoop);
7931caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
7941caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (nat && eventLoopNat) {
7951caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        const char *c_path = env->GetStringUTFChars(path, NULL);
7961caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
7971caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        int len = env->GetStringLength(path) + 1;
7981caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        char *context_path = (char *)calloc(len, sizeof(char));
7991caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        strlcpy(context_path, c_path, len);  // for callback
8001caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
8011caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOGV("... Object Path = %s", c_path);
8021caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
8031caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
8041caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        bool ret = dbus_func_args_async(env, nat->conn, -1,
8051caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        onDiscoverServicesResult,
8061caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        context_path,
8071caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        eventLoopNat,
8081caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        c_path,
8091caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_DEVICE_IFACE,
8101caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        "DiscoverServices",
8111caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_TYPE_STRING, &c_pattern,
8121caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                        DBUS_TYPE_INVALID);
8131caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        env->ReleaseStringUTFChars(path, c_path);
8141caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        env->ReleaseStringUTFChars(pattern, c_pattern);
8151caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        return ret ? JNI_TRUE : JNI_FALSE;
8161caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
8171caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh#endif
8181caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    return JNI_FALSE;
8191caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
8201caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
8211caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"classInitNative", "()V", (void*)classInitNative},
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
826d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
827d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isEnabledNative", "()I", (void *)isEnabledNative},
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"enableNative", "()I", (void *)enableNative},
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"disableNative", "()I", (void *)disableNative},
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
835d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
836d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
837d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDevicePropertiesNative},
838d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
839d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyStringNative},
840d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
841d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyBooleanNative},
842d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
843d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)setAdapterPropertyIntegerNative},
844d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
845d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
846d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
847d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
848d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
849d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
850d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
851d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
852d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh      (void *)getDeviceServiceChannelNative},
853d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
854b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
855b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)setPairingConfirmationNative},
856b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
858b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
859b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            (void *)cancelPairingUserInputNative},
860efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
861efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            (void *)setDevicePropertyBooleanNative},
8621caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
8631caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
866bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyint register_android_server_BluetoothService(JNIEnv *env) {
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env,
868bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                "android/server/BluetoothService", sMethods, NELEM(sMethods));
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
872