19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, 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
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "BluetoothEventLoop.cpp"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_bluetooth_common.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h"
2128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#include "cutils/sockets.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dbus/dbus.h>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3916fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_ALREADY_EXISTS 1
4016fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_SUCCESS 0
4116fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_FAILED -1
4216fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_mNativeData;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onPropertyChanged;
47d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDevicePropertyChanged;
48d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceFound;
49d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceDisappeared;
50d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceCreated;
51d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceRemoved;
525e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganeshstatic jmethodID method_onDeviceDisconnectRequested;
53c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganeshstatic jmethodID method_onNetworkDeviceDisconnected;
54c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganeshstatic jmethodID method_onNetworkDeviceConnected;
55d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
56d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onCreatePairedDeviceResult;
571caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jmethodID method_onCreateDeviceResult;
581caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jmethodID method_onDiscoverServicesResult;
59d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onGetDeviceServiceChannelResult;
60d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
61d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onRequestPinCode;
62b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jmethodID method_onRequestPasskey;
6332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onRequestPasskeyConfirmation;
6432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onRequestPairingConsent;
6532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onDisplayPasskey;
66cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganeshstatic jmethodID method_onRequestOobData;
67cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganeshstatic jmethodID method_onAgentOutOfBandDataAvailable;
68d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onAgentAuthorize;
69d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onAgentCancel;
70c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project
71545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshstatic jmethodID method_onInputDevicePropertyChanged;
72de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganeshstatic jmethodID method_onInputDeviceConnectionResult;
736fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changstatic jmethodID method_onPanDevicePropertyChanged;
746fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changstatic jmethodID method_onPanDeviceConnectionResult;
752ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganeshstatic jmethodID method_onHealthDevicePropertyChanged;
762ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganeshstatic jmethodID method_onHealthDeviceChannelChanged;
77b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganeshstatic jmethodID method_onHealthDeviceConnectionResult;
78545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef event_loop_native_data_t native_data_t;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh#define EVENT_LOOP_REFS 10
826d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (native_data_t *)(env->GetIntField(object,
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 field_mNativeData));
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltnative_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) {
8928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return get_native_data(env, object);
9028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
9128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void classInitNative(JNIEnv* env, jclass clazz) {
942653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
97d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
98d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                "([Ljava/lang/String;)V");
99d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDevicePropertyChanged = env->GetMethodID(clazz,
100d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                      "onDevicePropertyChanged",
101d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                      "(Ljava/lang/String;[Ljava/lang/String;)V");
102d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound",
103d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            "(Ljava/lang/String;[Ljava/lang/String;)V");
104d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared",
105d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                  "(Ljava/lang/String;)V");
106d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
107d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
1085e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh    method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
1095e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                                        "(Ljava/lang/String;)V");
110c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected",
111707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                                                     "(Ljava/lang/String;Ljava/lang/String;I)V");
112c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected",
113c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                                              "(Ljava/lang/String;)V");
114d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
115d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
116d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                         "(Ljava/lang/String;I)V");
1171caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
11816fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly                                                         "(Ljava/lang/String;I)V");
1191caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
1201caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                                         "(Ljava/lang/String;Z)V");
121d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
122d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
123a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                                               "(Ljava/lang/String;Ljava/lang/String;I)V");
124cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable",
125cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                               "(Ljava/lang/String;)Z");
126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V");
127d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode",
128d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
129b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
130b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                               "(Ljava/lang/String;I)V");
13132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
13232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                               "(Ljava/lang/String;II)V");
13332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
13432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                               "(Ljava/lang/String;I)V");
13532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
136b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                               "(Ljava/lang/String;II)V");
137545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
1386fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
139de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
140fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
1416fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
1426fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
1436fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
144fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
145b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
146b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                                                             "onHealthDeviceConnectionResult",
147b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                                                             "(II)V");
1482ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
1492ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
1502ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
1512ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                               "(Ljava/lang/String;Ljava/lang/String;Z)V");
152cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
153cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
154c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void initializeNativeDataNative(JNIEnv* env, jobject object) {
1602653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == nat) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s: out of memory!", __FUNCTION__);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    memset(nat, 0, sizeof(native_data_t));
16828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
16928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_init(&(nat->thread_mutex), NULL);
17028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, field_mNativeData, (jint)nat);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_threads_init_default();
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Could not get onto the system bus!", __FUNCTION__);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_error_free(&err);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829e0a19515b9047a00a6e98ce7f20690dff511f43Nick Pelly        dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
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 void cleanupNativeDataNative(JNIEnv* env, jobject object) {
1882653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (native_data_t *)env->GetIntField(object, field_mNativeData);
19228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
19328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_destroy(&(nat->thread_mutex));
19428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(nat);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      void *data);
204d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar GaneshDBusHandlerResult agent_event_filter(DBusConnection *conn,
205d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     DBusMessage *msg,
206d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     void *data);
207d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic int register_agent(native_data_t *nat,
208d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                          const char *agent_path, const char *capabilities);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const DBusObjectPathVTable agent_vtable = {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NULL, agent_event_filter, NULL, NULL, NULL, NULL
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2144a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pellystatic unsigned int unix_events_to_dbus_flags(short events) {
2154a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    return (events & DBUS_WATCH_READABLE ? POLLIN : 0) |
2164a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) |
2174a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_ERROR ? POLLERR : 0) |
2184a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_HANGUP ? POLLHUP : 0);
2194a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly}
2204a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly
2214a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pellystatic short dbus_flags_to_unix_events(unsigned int flags) {
2224a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) |
2234a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) |
2244a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLERR ? DBUS_WATCH_ERROR : 0) |
2254a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0);
2264a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly}
22728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
22828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean setUpEventLoop(native_data_t *nat) {
2292653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat != NULL && nat->conn != NULL) {
232d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_threads_init_default();
233d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
234d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
235d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
2365ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        const char *agent_path = "/android/bluetooth/agent";
2375ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        const char *capabilities = "DisplayYesNo";
2385ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        if (register_agent(nat, agent_path, capabilities) < 0) {
2395ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo            dbus_connection_unregister_object_path (nat->conn, agent_path);
2405ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo            return JNI_FALSE;
2415ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        }
2425ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Add a filter for all incoming messages
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set which messages will be processed by this dbus connection
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
250c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                "type='signal',interface='org.freedesktop.DBus'",
251c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                &err);
252c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (dbus_error_is_set(&err)) {
253c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
254c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            return JNI_FALSE;
255c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        }
256c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        dbus_bus_add_match(nat->conn,
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
264d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
27156d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
27256d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                &err);
27356d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
27456d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
27556d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            return JNI_FALSE;
27656d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        }
27756d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        dbus_bus_add_match(nat->conn,
27856d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
27956d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                &err);
28056d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
28156d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
28256d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            return JNI_FALSE;
28356d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        }
28456d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        dbus_bus_add_match(nat->conn,
285c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
286c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
287c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
288c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
289c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            return JNI_FALSE;
290c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
2912ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
2922ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        dbus_bus_add_match(nat->conn,
2932ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
2942ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                &err);
2952ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (dbus_error_is_set(&err)) {
2962ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
2972ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            return JNI_FALSE;
2982ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        }
2992ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
300c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_add_match(nat->conn,
301d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                "type='signal',interface='org.bluez.AudioSink'",
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
308d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_TRUE;
309d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
310d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_FALSE;
311d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
313d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
314d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshconst char * get_adapter_path(DBusConnection *conn) {
31532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    DBusMessage *msg = NULL, *reply = NULL;
316d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusError err;
317d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *device_path = NULL;
318176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    int attempt = 0;
319176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
320176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
321176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        msg = dbus_message_new_method_call("org.bluez", "/",
322176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh              "org.bluez.Manager", "DefaultAdapter");
323176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        if (!msg) {
324176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            LOGE("%s: Can't allocate new method call for get_adapter_path!",
325176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                  __FUNCTION__);
326176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            return NULL;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
328176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        dbus_message_append_args(msg, DBUS_TYPE_INVALID);
329176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        dbus_error_init(&err);
330176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
331176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
332176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        if (!reply) {
333176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
334176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                if (dbus_error_has_name(&err,
335176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    "org.freedesktop.DBus.Error.ServiceUnknown")) {
336176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    // bluetoothd is still down, retry
337176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
338176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    usleep(10000);  // 10 ms
339176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    continue;
340176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                } else {
341176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    // Some other error we weren't expecting
342176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
343176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                }
344176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            }
345176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            goto failed;
346176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        }
347176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    }
348176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    if (attempt == 1000) {
349176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        LOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
350176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        goto failed;
351d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
352176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
353d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
354d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               &device_path, DBUS_TYPE_INVALID)
355d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               || !device_path){
356d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
357d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
359176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        goto failed;
360d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
361176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    dbus_message_unref(msg);
362d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return device_path;
363176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
364176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganeshfailed:
365176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    dbus_message_unref(msg);
366176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    return NULL;
367d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic int register_agent(native_data_t *nat,
370d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                          const char * agent_path, const char * capabilities)
371d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh{
372d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusMessage *msg, *reply;
373d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusError err;
37475d14c33d795621988a1df173d3d69abe0b6c8f4Nicu Pavel    dbus_bool_t oob = TRUE;
375d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
376d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_connection_register_object_path(nat->conn, agent_path,
377d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            &agent_vtable, nat)) {
378d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't register object path %s for agent!",
379d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh              __FUNCTION__, agent_path);
380d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
381d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
382d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
383d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    nat->adapter = get_adapter_path(nat->conn);
384176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    if (nat->adapter == NULL) {
385176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        return -1;
386176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    }
387d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call("org.bluez", nat->adapter,
388d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh          "org.bluez.Adapter", "RegisterAgent");
389d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!msg) {
390d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't allocate new method call for agent!",
391d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh              __FUNCTION__);
392d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
393d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
394d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
395d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                             DBUS_TYPE_STRING, &capabilities,
396d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                             DBUS_TYPE_INVALID);
397d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
398d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_error_init(&err);
399d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
400d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_unref(msg);
401d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
402d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!reply) {
403d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGE("%s: Can't register agent!", __FUNCTION__);
404d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
407d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
410d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_unref(reply);
411d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_connection_flush(nat->conn);
412d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
413d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return 0;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void tearDownEventLoop(native_data_t *nat) {
4172653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat != NULL && nat->conn != NULL) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
420d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
423d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char * agent_path = "/android/bluetooth/agent";
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
425d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        msg = dbus_message_new_method_call("org.bluez",
426d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           nat->adapter,
427d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           "org.bluez.Adapter",
428d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           "UnregisterAgent");
4299b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh        if (msg != NULL) {
4309b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
4319b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                                     DBUS_TYPE_INVALID);
4329b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            reply = dbus_connection_send_with_reply_and_block(nat->conn,
4339b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                                                              msg, -1, &err);
4349b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh
4359b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            if (!reply) {
4369b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                if (dbus_error_is_set(&err)) {
4379b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
4389b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                    dbus_error_free(&err);
4399b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                }
4409b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            } else {
4419b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                dbus_message_unref(reply);
4429b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            }
4439b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            dbus_message_unref(msg);
4449b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh        } else {
4459b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh             LOGE("%s: Can't create new method call!", __FUNCTION__);
446d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
448d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_flush(nat->conn);
449d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_unregister_object_path(nat->conn, agent_path);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
452c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".AudioSink'",
453c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
454c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
455c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
456c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
457c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
458c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
464c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
465c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
466c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
467c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
468c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
469c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
470c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
471c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
472c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
473c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
474c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
475c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
476c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
4822ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
4832ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                &err);
4842ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (dbus_error_is_set(&err)) {
4852ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
4862ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        }
4872ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='org.bluez.audio.Manager'",
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
499c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        dbus_bus_remove_match(nat->conn,
500c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                "type='signal',interface='org.freedesktop.DBus'",
501c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                &err);
502c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (dbus_error_is_set(&err)) {
503c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
504c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        }
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_remove_filter(nat->conn, event_filter, nat);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
50928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_EXIT 1
51228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_ADD  2
51328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_REMOVE 3
514f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir#define EVENT_LOOP_WAKEUP 4
51528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltdbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
51728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
51828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (dbus_watch_get_enabled(watch)) {
52028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // note that we can't just send the watch and inspect it later
52128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // because we may get a removeWatch call before this data is reacted
52228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // to by our eventloop and remove this watch..  reading the add first
52328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // and then inspecting the recently deceased watch would be bad.
52428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        char control = EVENT_LOOP_ADD;
52528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &control, sizeof(char));
52628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
52728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        int fd = dbus_watch_get_fd(watch);
52828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &fd, sizeof(int));
52928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
53028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        unsigned int flags = dbus_watch_get_flags(watch);
53128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &flags, sizeof(unsigned int));
53228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
53328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &watch, sizeof(DBusWatch*));
53428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
53528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return true;
53628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
53728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
53828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltvoid dbusRemoveWatch(DBusWatch *watch, void *data) {
53928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
54028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    char control = EVENT_LOOP_REMOVE;
54228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &control, sizeof(char));
54328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int fd = dbus_watch_get_fd(watch);
54528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &fd, sizeof(int));
54628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags = dbus_watch_get_flags(watch);
54828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &flags, sizeof(unsigned int));
54928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
55028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
55128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltvoid dbusToggleWatch(DBusWatch *watch, void *data) {
55228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (dbus_watch_get_enabled(watch)) {
55328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        dbusAddWatch(watch, data);
55428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    } else {
55528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        dbusRemoveWatch(watch, data);
55628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
55728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
55828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
559f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojirvoid dbusWakeup(void *data) {
560f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    native_data_t *nat = (native_data_t *)data;
561f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir
562f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    char control = EVENT_LOOP_WAKEUP;
563f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    write(nat->controlFdW, &control, sizeof(char));
564f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir}
565f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir
56628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void handleWatchAdd(native_data_t *nat) {
56728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    DBusWatch *watch;
56828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int newFD;
56928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags;
57028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
57128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &newFD, sizeof(int));
57228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &flags, sizeof(unsigned int));
57328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &watch, sizeof(DBusWatch *));
5744a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    short events = dbus_flags_to_unix_events(flags);
57528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
57628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    for (int y = 0; y<nat->pollMemberCount; y++) {
57728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if ((nat->pollData[y].fd == newFD) &&
57828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollData[y].events == events)) {
57928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            LOGV("DBusWatch duplicate add");
58028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
58128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
58228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
58328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollMemberCount == nat->pollDataSize) {
58428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGV("Bluetooth EventLoop poll struct growing");
58528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        struct pollfd *temp = (struct pollfd *)malloc(
58628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                sizeof(struct pollfd) * (nat->pollMemberCount+1));
58728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (!temp) {
58828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
58928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
59028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        memcpy(temp, nat->pollData, sizeof(struct pollfd) *
59128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                nat->pollMemberCount);
59228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->pollData);
59328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = temp;
59428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) *
59528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollMemberCount+1));
59628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (!temp2) {
59728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
59828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
59928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        memcpy(temp2, nat->watchData, sizeof(DBusWatch *) *
60028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                nat->pollMemberCount);
60128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->watchData);
60228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = temp2;
60328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize++;
60428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
60528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].fd = newFD;
60628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].revents = 0;
60728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].events = events;
60828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->watchData[nat->pollMemberCount] = watch;
60928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollMemberCount++;
61028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
61128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
61228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void handleWatchRemove(native_data_t *nat) {
61328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int removeFD;
61428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags;
61528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
61628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &removeFD, sizeof(int));
61728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &flags, sizeof(unsigned int));
6184a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    short events = dbus_flags_to_unix_events(flags);
61928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
62028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    for (int y = 0; y < nat->pollMemberCount; y++) {
62128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if ((nat->pollData[y].fd == removeFD) &&
62228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollData[y].events == events)) {
62328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            int newCount = --nat->pollMemberCount;
62428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            // copy the last live member over this one
62528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].fd = nat->pollData[newCount].fd;
62628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].events = nat->pollData[newCount].events;
62728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].revents = nat->pollData[newCount].revents;
62828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->watchData[y] = nat->watchData[newCount];
62928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
63028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
63128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
63228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    LOGW("WatchRemove given with unknown watch");
63328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
63428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
63528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void *eventLoopMain(void *ptr) {
63628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)ptr;
63728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
63828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
63928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JavaVMAttachArgs args;
64028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    char name[] = "BT EventLoop";
64128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.version = nat->envVer;
64228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.name = name;
64328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.group = NULL;
64428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
64528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->AttachCurrentThread(&env, &args);
64628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
64728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
64828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
649f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
65028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
651b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = true;
652b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh
65328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    while (1) {
65428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        for (int i = 0; i < nat->pollMemberCount; i++) {
65528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            if (!nat->pollData[i].revents) {
65628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                continue;
65728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            }
65828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            if (nat->pollData[i].fd == nat->controlFdR) {
65928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                char data;
66028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT)
66128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        != -1) {
66228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    switch (data) {
66328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_EXIT:
66428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
66528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        dbus_connection_set_watch_functions(nat->conn,
66628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                NULL, NULL, NULL, NULL, NULL);
66728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        tearDownEventLoop(nat);
66828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        nat->vm->DetachCurrentThread();
669ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson
670ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        int fd = nat->controlFdR;
671ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        nat->controlFdR = 0;
672ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        close(fd);
67328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        return NULL;
67428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
67528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_ADD:
67628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
67728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        handleWatchAdd(nat);
67828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        break;
67928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
68028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_REMOVE:
68128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
68228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        handleWatchRemove(nat);
68328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        break;
68428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
685f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                    case EVENT_LOOP_WAKEUP:
686f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                    {
687f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                        // noop
688f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                        break;
68928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
69028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
69128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                }
69228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            } else {
6934a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                short events = nat->pollData[i].revents;
6944a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                unsigned int flags = unix_events_to_dbus_flags(events);
6954a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                dbus_watch_handle(nat->watchData[i], flags);
6964a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                nat->pollData[i].revents = 0;
6974a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                // can only do one - it may have caused a 'remove'
6984a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                break;
69928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            }
70028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
701b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh        while (dbus_connection_dispatch(nat->conn) ==
70228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                DBUS_DISPATCH_DATA_REMAINS) {
70328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
70428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
70528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        poll(nat->pollData, nat->pollMemberCount, -1);
70628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
70728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
70828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
70928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
71028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean startEventLoopNative(JNIEnv *env, jobject object) {
71128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jboolean result = JNI_FALSE;
71228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
71328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    event_loop_native_data_t *nat = get_native_data(env, object);
71428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
71528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
71628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
717b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = false;
718b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh
71928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollData) {
72028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGW("trying to start EventLoop a second time!");
72128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        pthread_mutex_unlock( &(nat->thread_mutex) );
72228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        return JNI_FALSE;
72328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
72428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
72528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData = (struct pollfd *)malloc(sizeof(struct pollfd) *
72628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            DEFAULT_INITIAL_POLLFD_COUNT);
72728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (!nat->pollData) {
72828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGE("out of memory error starting EventLoop!");
72928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
73028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
73128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
73228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->watchData = (DBusWatch **)malloc(sizeof(DBusWatch *) *
73328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            DEFAULT_INITIAL_POLLFD_COUNT);
73428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (!nat->watchData) {
73528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGE("out of memory error starting EventLoop!");
73628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
73728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
73828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
73928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    memset(nat->pollData, 0, sizeof(struct pollfd) *
74028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            DEFAULT_INITIAL_POLLFD_COUNT);
74128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    memset(nat->watchData, 0, sizeof(DBusWatch *) *
74228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            DEFAULT_INITIAL_POLLFD_COUNT);
74328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
74428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollMemberCount = 1;
74528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
74628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) {
74728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGE("Error getting BT control socket");
74828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
74928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
75028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[0].fd = nat->controlFdR;
75128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[0].events = POLLIN;
75228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->GetJavaVM( &(nat->vm) );
75428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->envVer = env->GetVersion();
75528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->me = env->NewGlobalRef(object);
75728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (setUpEventLoop(nat) != JNI_TRUE) {
75928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        LOGE("failure setting up Event Loop!");
76028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
76128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
76228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
76328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_create(&(nat->thread), NULL, eventLoopMain, nat);
76428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    result = JNI_TRUE;
76528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
76628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltdone:
76728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (JNI_FALSE == result) {
768ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        if (nat->controlFdW) {
769ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson            close(nat->controlFdW);
77028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->controlFdW = 0;
771ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        }
772ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        if (nat->controlFdR) {
773ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson            close(nat->controlFdR);
77428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->controlFdR = 0;
77528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
77628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->me) env->DeleteGlobalRef(nat->me);
77728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->me = NULL;
77828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->pollData) free(nat->pollData);
77928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = NULL;
78028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->watchData) free(nat->watchData);
78128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = NULL;
78228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize = 0;
78328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollMemberCount = 0;
78428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
78528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
78628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
78728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
78828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return result;
78928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
79028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
79128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void stopEventLoopNative(JNIEnv *env, jobject object) {
79228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
79328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = get_native_data(env, object);
79428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
79528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
79628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollData) {
79728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        char data = EVENT_LOOP_EXIT;
79828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        ssize_t t = write(nat->controlFdW, &data, sizeof(char));
79928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        void *ret;
80028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        pthread_join(nat->thread, &ret);
80128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
80228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        env->DeleteGlobalRef(nat->me);
80328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->me = NULL;
80428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->pollData);
80528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = NULL;
80628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->watchData);
80728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = NULL;
80828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize = 0;
80928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollMemberCount = 0;
810ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson
811ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        int fd = nat->controlFdW;
81228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->controlFdW = 0;
813ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        close(fd);
81428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
815b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = false;
81628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
81728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
81828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
81928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
82028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) {
82128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jboolean result = JNI_FALSE;
82228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
82328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = get_native_data(env, object);
82428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
82528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
826b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    if (nat->running) {
82728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        result = JNI_TRUE;
82828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
82928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
83028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
83128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
83228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return result;
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env);
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Called by dbus during WaitForAndDispatchEventNative()
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      void *data) {
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
8446d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    DBusHandlerResult ret;
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat = (native_data_t *)data;
84928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("%s: not interested (not a signal).", __FUNCTION__);
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
855b1ef24473297410872654a6c4ad51c8341b2c40bJaikumar Ganesh    LOGV("%s: Received signal %s:%s from %s", __FUNCTION__,
856d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_get_interface(msg), dbus_message_get_member(msg),
857d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_get_path(msg));
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8596d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PushLocalFrame(EVENT_LOOP_REFS);
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_is_signal(msg,
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               "org.bluez.Adapter",
862d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               "DeviceFound")) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *c_address;
864d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
865d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
866d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(msg, &iter)) {
867d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_message_iter_get_basic(&iter, &c_address);
868d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_message_iter_next(&iter))
869d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                str_array =
870d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    parse_remote_device_properties(env, &iter);
871d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
872d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
874d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                method_onDeviceFound,
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                env->NewStringUTF(c_address),
876d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                str_array);
877d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        } else
878d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
8796d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
881d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
882d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceDisappeared")) {
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *c_address;
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_STRING, &c_address,
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_INVALID)) {
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... address = %s", c_address);
888d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                env->NewStringUTF(c_address));
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
8916d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
893d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
894d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceCreated")) {
895d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *c_object_path;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
897d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_object_path,
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_INVALID)) {
899d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOGV("... address = %s", c_object_path);
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
901d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                method_onDeviceCreated,
902d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                env->NewStringUTF(c_object_path));
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9046d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
906d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
907d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceRemoved")) {
908d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *c_object_path;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
910d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
911d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_INVALID)) {
912d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           LOGV("... Object Path = %s", c_object_path);
913d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           env->CallVoidMethod(nat->me,
914d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               method_onDeviceRemoved,
915d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               env->NewStringUTF(c_object_path));
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9176d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      "org.bluez.Adapter",
920d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "PropertyChanged")) {
921d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = parse_adapter_property_change(env, msg);
922d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
923d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            /* Check if bluetoothd has (re)started, if so update the path. */
924d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            jstring property =(jstring) env->GetObjectArrayElement(str_array, 0);
925d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            const char *c_property = env->GetStringUTFChars(property, NULL);
926d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (!strncmp(c_property, "Powered", strlen("Powered"))) {
927d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                jstring value =
928d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    (jstring) env->GetObjectArrayElement(str_array, 1);
929d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                const char *c_value = env->GetStringUTFChars(value, NULL);
930d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                if (!strncmp(c_value, "true", strlen("true")))
931d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    nat->adapter = get_adapter_path(nat->conn);
932d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                env->ReleaseStringUTFChars(value, c_value);
933d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            }
934d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            env->ReleaseStringUTFChars(property, c_property);
935d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
937d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                              method_onPropertyChanged,
938d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                              str_array);
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9406d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
942d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "org.bluez.Device",
943d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "PropertyChanged")) {
944d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = parse_remote_device_property_change(env, msg);
945d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
946d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            const char *remote_device_path = dbus_message_get_path(msg);
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
948d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            method_onDevicePropertyChanged,
949d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            env->NewStringUTF(remote_device_path),
950d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            str_array);
951c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9526d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9535e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh    } else if (dbus_message_is_signal(msg,
9545e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                      "org.bluez.Device",
9555e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                      "DisconnectRequested")) {
9565e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        const char *remote_device_path = dbus_message_get_path(msg);
9575e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        env->CallVoidMethod(nat->me,
9585e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                            method_onDeviceDisconnectRequested,
9595e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                            env->NewStringUTF(remote_device_path));
9605e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        goto success;
961545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    } else if (dbus_message_is_signal(msg,
962545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                      "org.bluez.Input",
963545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                      "PropertyChanged")) {
964545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
965545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        jobjectArray str_array =
966545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                    parse_input_property_change(env, msg);
967545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        if (str_array != NULL) {
968545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            const char *c_path = dbus_message_get_path(msg);
969545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            env->CallVoidMethod(nat->me,
970545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                method_onInputDevicePropertyChanged,
971545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                env->NewStringUTF(c_path),
972545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                str_array);
973545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        } else {
974545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
975545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
976545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        goto success;
9776fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    } else if (dbus_message_is_signal(msg,
9786fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                     "org.bluez.Network",
9796fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                     "PropertyChanged")) {
9806fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
9816fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       jobjectArray str_array =
9826fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                   parse_pan_property_change(env, msg);
9836fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       if (str_array != NULL) {
9846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           const char *c_path = dbus_message_get_path(msg);
9856fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           env->CallVoidMethod(nat->me,
9866fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               method_onPanDevicePropertyChanged,
9876fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               env->NewStringUTF(c_path),
9886fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               str_array);
9896fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       } else {
9906fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9916fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       }
9926fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       goto success;
993c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
994c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "org.bluez.NetworkServer",
995c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "DeviceDisconnected")) {
996c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       char *c_address;
997c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
998c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_address,
999c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
1000c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           env->CallVoidMethod(nat->me,
1001c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               method_onNetworkDeviceDisconnected,
1002c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               env->NewStringUTF(c_address));
1003c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       } else {
1004c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
1005c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       }
1006c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       goto success;
1007c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
1008c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "org.bluez.NetworkServer",
1009c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "DeviceConnected")) {
1010c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       char *c_address;
1011707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh       char *c_iface;
1012c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       uint16_t uuid;
1013c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh
1014c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
1015c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_address,
1016707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_iface,
1017c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_UINT16, &uuid,
1018c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
1019c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           env->CallVoidMethod(nat->me,
1020c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               method_onNetworkDeviceConnected,
1021c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               env->NewStringUTF(c_address),
1022707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                               env->NewStringUTF(c_iface),
1023c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               uuid);
1024c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       } else {
1025c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
1026c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       }
1027c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       goto success;
10282ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
10292ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "org.bluez.HealthDevice",
10302ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "ChannelConnected")) {
10312ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_path = dbus_message_get_path(msg);
10322ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_channel_path;
10332ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       jboolean exists = JNI_TRUE;
10342ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
10352ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
10362ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
10372ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           env->CallVoidMethod(nat->me,
10382ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               method_onHealthDeviceChannelChanged,
10392ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_path),
10402ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_channel_path),
10412ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               exists);
10422ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10432ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10442ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10452ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
10462ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
1047ae37d06dd0f844fe397b76210e6d145abf4210b6Jaikumar Ganesh                                     "org.bluez.HealthDevice",
10482ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "ChannelDeleted")) {
10492ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
10502ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_path = dbus_message_get_path(msg);
10512ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_channel_path;
10522ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       jboolean exists = JNI_FALSE;
10532ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
10542ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
10552ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
10562ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           env->CallVoidMethod(nat->me,
10572ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               method_onHealthDeviceChannelChanged,
10582ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_path),
10592ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_channel_path),
10602ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               exists);
10612ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10622ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10632ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10642ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
10652ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
10662ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "org.bluez.HealthDevice",
10672ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "PropertyChanged")) {
10682ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        jobjectArray str_array =
10692ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                    parse_health_device_property_change(env, msg);
10702ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (str_array != NULL) {
10712ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            const char *c_path = dbus_message_get_path(msg);
10722ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            env->CallVoidMethod(nat->me,
10732ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                method_onHealthDevicePropertyChanged,
10742ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                env->NewStringUTF(c_path),
10752ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                str_array);
10762ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10772ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10782ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10792ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
1080c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    }
10816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
10826d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    ret = a2dp_event_filter(msg, env);
10836d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
10846d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return ret;
10856d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
10866d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshsuccess:
10876d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
10886d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return DBUS_HANDLER_RESULT_HANDLED;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Called by dbus during WaitForAndDispatchEventNative()
1092d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar GaneshDBusHandlerResult agent_event_filter(DBusConnection *conn,
1093d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     DBusMessage *msg, void *data) {
109428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("%s: not interested (not a method call).", __FUNCTION__);
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1100d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    LOGI("%s: Received method %s:%s", __FUNCTION__,
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         dbus_message_get_interface(msg), dbus_message_get_member(msg));
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1103d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1105d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
11066d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PushLocalFrame(EVENT_LOOP_REFS);
11076d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
1108d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (dbus_message_is_method_call(msg,
1109d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "Cancel")) {
1110d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onAgentCancel);
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // reply
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Cannot create message reply\n", __FUNCTION__);
11156d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
11196d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1122d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "Authorize")) {
1123d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *object_path;
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *uuid;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_message_get_args(msg, NULL,
1126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_STRING, &uuid,
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_INVALID)) {
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
11306d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1133d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("... object_path = %s", object_path);
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("... uuid = %s", uuid);
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1136a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        dbus_message_ref(msg);  // increment refcount because we pass to java
113714fcf900ce65e5c8c952c95ee12041f8de16fbb7Jeff Brown        env->CallVoidMethod(nat->me, method_onAgentAuthorize,
1138a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                env->NewStringUTF(object_path), env->NewStringUTF(uuid),
1139a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                int(msg));
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11416d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1143cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            "org.bluez.Agent", "OutOfBandAvailable")) {
1144cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        char *object_path;
1145cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1146cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1147cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
1148cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            LOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__);
1149cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            goto failure;
1150cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1151cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1152cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        LOGV("... object_path = %s", object_path);
1153cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1154cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        bool available =
1155cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable,
1156cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                env->NewStringUTF(object_path));
1157cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1158cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1159cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        // reply
1160cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (available) {
1161cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            DBusMessage *reply = dbus_message_new_method_return(msg);
1162cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            if (!reply) {
1163cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                LOGE("%s: Cannot create message reply\n", __FUNCTION__);
1164cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                goto failure;
1165cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            }
1166cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_connection_send(nat->conn, reply, NULL);
1167cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_message_unref(reply);
1168cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        } else {
1169cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            DBusMessage *reply = dbus_message_new_error(msg,
1170cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                    "org.bluez.Error.DoesNotExist", "OutofBand data not available");
1171cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            if (!reply) {
1172cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                LOGE("%s: Cannot create message reply\n", __FUNCTION__);
1173cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                goto failure;
1174cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            }
1175cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_connection_send(nat->conn, reply, NULL);
1176cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_message_unref(reply);
1177cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1178cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        goto success;
1179cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1180d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "RequestPinCode")) {
1181d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *object_path;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_message_get_args(msg, NULL,
1183d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_INVALID)) {
1185d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
11866d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1190d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPinCode,
1191d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       env->NewStringUTF(object_path),
1192d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       int(msg));
11936d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1195b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            "org.bluez.Agent", "RequestPasskey")) {
1196b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        char *object_path;
1197b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1198b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1199b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
1200b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
12016d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
1202b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
1203b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
1204b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1205b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPasskey,
1206b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       env->NewStringUTF(object_path),
1207b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       int(msg));
12086d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
1209b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1210cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            "org.bluez.Agent", "RequestOobData")) {
1211cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        char *object_path;
1212cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1213cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1214cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
1215cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            LOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__);
1216cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            goto failure;
1217cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1218cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1219cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1220cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestOobData,
1221cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                       env->NewStringUTF(object_path),
1222cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                       int(msg));
1223cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        goto success;
1224cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
122532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            "org.bluez.Agent", "DisplayPasskey")) {
122632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        char *object_path;
122732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        uint32_t passkey;
122832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
122932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
123032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_UINT32, &passkey,
123132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
123232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
123332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            goto failure;
123432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        }
123532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh
123632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
123732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onDisplayPasskey,
123832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       env->NewStringUTF(object_path),
123932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       passkey,
124032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       int(msg));
124132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        goto success;
124232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1243b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            "org.bluez.Agent", "RequestConfirmation")) {
1244b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        char *object_path;
1245b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        uint32_t passkey;
1246b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1247b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1248b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_UINT32, &passkey,
1249b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
1250b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            LOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
12516d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
1252b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
1253b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
1254b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
125532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
1256b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       env->NewStringUTF(object_path),
1257b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       passkey,
1258b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       int(msg));
12596d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
1260b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
126132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            "org.bluez.Agent", "RequestPairingConsent")) {
126232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        char *object_path;
126332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
126432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
126532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
126632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            LOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
126732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            goto failure;
126832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        }
126932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh
127032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
127132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
127232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       env->NewStringUTF(object_path),
127332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       int(msg));
127432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        goto success;
127532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1276d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                  "org.bluez.Agent", "Release")) {
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // reply
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: Cannot create message reply\n", __FUNCTION__);
12816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
12856d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1287d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        LOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12906d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshfailure:
12916d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
12936d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
12946d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshsuccess:
12956d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
12966d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return DBUS_HANDLER_RESULT_HANDLED;
12976d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
130328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1304d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
13052653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
130728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)n;
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *address = (const char *)user;
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
131128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
1312a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr;
1313a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh
131428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("... address = %s", address);
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint result = BOND_RESULT_SUCCESS;
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_set_error_from_message(&err, msg)) {
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) {
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pins did not match, or remote device did not respond to pin
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // request in time
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_FAILED;
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) {
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We rejected pairing, or the remote side rejected pairing. This
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // happens if either side presses 'cancel' at the pairing dialog.
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_REJECTED;
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) {
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Not sure if this happens
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_CANCELED;
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) {
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Other device is not responding at all
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_REMOTE_DEVICE_DOWN;
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) {
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // already bonded
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_SUCCESS;
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   !strcmp(err.message, "Bonding in progress")) {
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto done;
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   !strcmp(err.message, "Discover in progress")) {
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("... error = %s (%s)\n", err.name, err.message);
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
135032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
135132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            LOGV("... error = %s (%s)\n", err.name, err.message);
135232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            result = BOND_RESULT_REPEATED_ATTEMPTS;
135332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
135432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            LOGV("... error = %s (%s)\n", err.name, err.message);
135532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            result = BOND_RESULT_AUTH_TIMEOUT;
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_ERROR;
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1362a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    addr = env->NewStringUTF(address);
136328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->CallVoidMethod(nat->me,
1364d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                        method_onCreatePairedDeviceResult,
1365a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        result);
1367a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_free(&err);
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(user);
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13731caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
13742653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
13751caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
13761caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
13771caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    const char *address= (const char *)user;
13781caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    DBusError err;
13791caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    dbus_error_init(&err);
13801caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    JNIEnv *env;
13811caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
13821caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
13831caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    LOGV("... Address = %s", address);
13841caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
138516fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly    jint result = CREATE_DEVICE_SUCCESS;
13861caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
138716fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly        if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
138816fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly            result = CREATE_DEVICE_ALREADY_EXISTS;
1389cf5f6527401bcbd9f558e41a5b067d4d02920dc7Jaikumar Ganesh        } else {
1390cf5f6527401bcbd9f558e41a5b067d4d02920dc7Jaikumar Ganesh            result = CREATE_DEVICE_FAILED;
139116fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly        }
13921caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
13931caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
1394a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr = env->NewStringUTF(address);
13951caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    env->CallVoidMethod(nat->me,
13961caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        method_onCreateDeviceResult,
1397a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
13981caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        result);
1399a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
14001caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    free(user);
14011caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
14021caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14031caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
14042653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
14051caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14061caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
14071caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    const char *path = (const char *)user;
14081caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    DBusError err;
14091caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    dbus_error_init(&err);
14101caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    JNIEnv *env;
14111caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
14121caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14131caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    LOGV("... Device Path = %s", path);
14141caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14151caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    bool result = JNI_TRUE;
14161caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
14171caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
14181caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        result = JNI_FALSE;
14191caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
1420a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring jPath = env->NewStringUTF(path);
14211caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    env->CallVoidMethod(nat->me,
14221caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        method_onDiscoverServicesResult,
1423a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        jPath,
14241caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        result);
1425a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(jPath);
14261caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    free(user);
14271caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
14281caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
1429d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
14302653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *address = (const char *) user;
143328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *) n;
143428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
143728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
143828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
143928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint channel = -2;
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("... address = %s", address);
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_set_error_from_message(&err, msg) ||
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        !dbus_message_get_args(msg, &err,
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               DBUS_TYPE_INT32, &channel,
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               DBUS_TYPE_INVALID)) {
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_free(&err);
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
1453a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr = env->NewStringUTF(address);
145428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->CallVoidMethod(nat->me,
1455d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                        method_onGetDeviceServiceChannelResult,
1456a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        channel);
1458a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(user);
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1461de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1462de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganeshvoid onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
14632653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
1464de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1465de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
1466de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    const char *path = (const char *)user;
1467de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    DBusError err;
1468de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    dbus_error_init(&err);
1469de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    JNIEnv *env;
1470de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
1471de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1472fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    jint result = INPUT_OPERATION_SUCCESS;
1473de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
1474fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
1475fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
1476fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
1477fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
1478fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
1479fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            // TODO():This is flaky, need to change Bluez to add new error codes
1480fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            if (!strcmp(err.message, "Transport endpoint is not connected")) {
1481fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh              result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
1482fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else {
1483fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh              result = INPUT_OPERATION_GENERIC_FAILURE;
1484fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            }
1485fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else {
1486fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_OPERATION_GENERIC_FAILURE;
1487fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        }
1488de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
1489de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    }
1490fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
1491de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    LOGV("... Device Path = %s, result = %d", path, result);
1492de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    jstring jPath = env->NewStringUTF(path);
1493de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    env->CallVoidMethod(nat->me,
1494de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        method_onInputDeviceConnectionResult,
1495de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        jPath,
1496de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        result);
1497de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    env->DeleteLocalRef(jPath);
1498de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    free(user);
1499de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh}
1500de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
15016fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changvoid onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
15022653a1e7ca55b03f5230dffa85dfe2705757e2b7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
15036fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
15046fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    native_data_t *nat = (native_data_t *)n;
15056fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    const char *path = (const char *)user;
15066fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    DBusError err;
15076fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    dbus_error_init(&err);
15086fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    JNIEnv *env;
15096fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    nat->vm->GetEnv((void**)&env, nat->envVer);
15106fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
1511fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    jint result = PAN_OPERATION_SUCCESS;
15126fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    if (dbus_set_error_from_message(&err, msg)) {
1513fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
1514fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
1515fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
1516fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            // TODO():This is flaky, need to change Bluez to add new error codes
1517fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            if (!strcmp(err.message, "Device already connected")) {
1518fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
1519fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else if (!strcmp(err.message, "Device not connected")) {
1520fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
1521fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else {
1522fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_OPERATION_GENERIC_FAILURE;
1523fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            }
1524fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else {
1525fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = PAN_OPERATION_GENERIC_FAILURE;
1526fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        }
15276fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        LOG_AND_FREE_DBUS_ERROR(&err);
15286fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    }
1529fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
15306fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    LOGV("... Pan Device Path = %s, result = %d", path, result);
15316fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    jstring jPath = env->NewStringUTF(path);
15326fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    env->CallVoidMethod(nat->me,
15336fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        method_onPanDeviceConnectionResult,
15346fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        jPath,
15356fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        result);
15366fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    env->DeleteLocalRef(jPath);
15376fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    free(user);
15386fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang}
15396fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
1540b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganeshvoid onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
1541b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    LOGV("%s", __FUNCTION__);
1542b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1543b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
1544b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    DBusError err;
1545b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    dbus_error_init(&err);
1546b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    JNIEnv *env;
1547b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
1548b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1549b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    jint result = HEALTH_OPERATION_SUCCESS;
1550b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
1551b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
1552b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_INVALID_ARGS;
1553b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
1554b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_ERROR;
1555b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
1556b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_NOT_FOUND;
1557b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
1558b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_NOT_ALLOWED;
1559b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else {
1560b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_GENERIC_FAILURE;
1561b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        }
1562b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
1563b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    }
1564b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1565b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    jint code = *(int *) user;
156662f7c9737f0270b8ca1baeb3739ef3c8ef89d186Matthew Xie    LOGV("... Health Device Code = %d, result = %d", code, result);
1567b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    env->CallVoidMethod(nat->me,
1568b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        method_onHealthDeviceConnectionResult,
1569b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        code,
1570b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        result);
1571b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    free(user);
1572b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh}
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"classInitNative", "()V", (void *)classInitNative},
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
158028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"startEventLoopNative", "()V", (void *)startEventLoopNative},
158128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"stopEventLoopNative", "()V", (void *)stopEventLoopNative},
158228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative}
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_BluetoothEventLoop(JNIEnv *env) {
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env,
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods));
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
1591