blob: 5c6958a4fd08fc981dcbd44475d7595baf70136a [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2** Copyright 2006, The Android Open Source Project
3**
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08004** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007**
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08008** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009**
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -080010** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014** limitations under the License.
15*/
16
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -070017#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
18#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070019#define DBUS_INPUT_IFACE BLUEZ_DBUS_BASE_IFC ".Input"
Danica Chang6fdd0c62010-08-11 14:54:43 -070020#define DBUS_NETWORK_IFACE BLUEZ_DBUS_BASE_IFC ".Network"
21#define DBUS_NETWORKSERVER_IFACE BLUEZ_DBUS_BASE_IFC ".NetworkServer"
22
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070023
Nick Pellybd022f42009-08-14 18:33:38 -070024#define LOG_TAG "BluetoothService.cpp"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26#include "android_bluetooth_common.h"
27#include "android_runtime/AndroidRuntime.h"
28#include "JNIHelp.h"
29#include "jni.h"
30#include "utils/Log.h"
31#include "utils/misc.h"
32
33#include <ctype.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <errno.h>
38#include <unistd.h>
39
40#include <sys/socket.h>
41#include <sys/ioctl.h>
42#include <fcntl.h>
43
44#ifdef HAVE_BLUETOOTH
45#include <dbus/dbus.h>
46#include <bluedroid/bluetooth.h>
47#endif
48
49#include <cutils/properties.h>
50
51namespace android {
52
Nick Pelly2b5be072009-03-31 14:42:33 -070053#define BLUETOOTH_CLASS_ERROR 0xFF000000
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -070054#define PROPERTIES_NREFS 10
Nick Pelly2b5be072009-03-31 14:42:33 -070055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056#ifdef HAVE_BLUETOOTH
57// We initialize these variables when we load class
Nick Pellybd022f42009-08-14 18:33:38 -070058// android.server.BluetoothService
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059static jfieldID field_mNativeData;
Robert Greenwalt28d139f2009-04-02 22:41:08 -070060static jfieldID field_mEventLoop;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
62typedef struct {
63 JNIEnv *env;
64 DBusConnection *conn;
65 const char *adapter; // dbus object name of the local adapter
66} native_data_t;
67
Robert Greenwalt28d139f2009-04-02 22:41:08 -070068extern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
69 jobject);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -070070extern DBusHandlerResult agent_event_filter(DBusConnection *conn,
71 DBusMessage *msg,
72 void *data);
73void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -070074void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
75void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
Jaikumar Ganeshde075032010-07-19 16:28:27 -070076void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
Danica Chang6fdd0c62010-08-11 14:54:43 -070077void onConnectPanResult(DBusMessage *msg, void *user, void *n);
78void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -070079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
81/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
82 * Perform quick sanity check, if there are any problems return NULL
83 */
84static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
85 native_data_t *nat =
86 (native_data_t *)(env->GetIntField(object, field_mNativeData));
87 if (nat == NULL || nat->conn == NULL) {
88 LOGE("Uninitialized native data\n");
89 return NULL;
90 }
91 return nat;
92}
93#endif
94
95static void classInitNative(JNIEnv* env, jclass clazz) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -080096 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097#ifdef HAVE_BLUETOOTH
98 field_mNativeData = get_field(env, clazz, "mNativeData", "I");
Robert Greenwalt28d139f2009-04-02 22:41:08 -070099 field_mEventLoop = get_field(env, clazz, "mEventLoop",
100 "Landroid/server/BluetoothEventLoop;");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101#endif
102}
103
104/* Returns true on success (even if adapter is present but disabled).
105 * Return false if dbus is down, or another serious error (out of memory)
106*/
107static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800108 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109#ifdef HAVE_BLUETOOTH
110 native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
111 if (NULL == nat) {
112 LOGE("%s: out of memory!", __FUNCTION__);
113 return false;
114 }
115 nat->env = env;
116
117 env->SetIntField(object, field_mNativeData, (jint)nat);
118 DBusError err;
119 dbus_error_init(&err);
120 dbus_threads_init_default();
121 nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
122 if (dbus_error_is_set(&err)) {
123 LOGE("Could not get onto the system bus: %s", err.message);
124 dbus_error_free(&err);
125 return false;
126 }
Nick Pelly9e0a1952009-06-17 15:27:59 -0700127 dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128#endif /*HAVE_BLUETOOTH*/
129 return true;
130}
131
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700132static const char *get_adapter_path(JNIEnv* env, jobject object) {
Jaikumar Ganesh82aea4a2009-06-09 23:23:20 -0700133#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700134 event_loop_native_data_t *event_nat =
135 get_EventLoop_native_data(env, env->GetObjectField(object,
136 field_mEventLoop));
137 if (event_nat == NULL)
138 return NULL;
139 return event_nat->adapter;
Jaikumar Ganesh82aea4a2009-06-09 23:23:20 -0700140#else
141 return NULL;
142#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700143}
144
145// This function is called when the adapter is enabled.
146static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800147 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700148#ifdef HAVE_BLUETOOTH
149 native_data_t *nat =
150 (native_data_t *)env->GetIntField(object, field_mNativeData);
151 event_loop_native_data_t *event_nat =
152 get_EventLoop_native_data(env, env->GetObjectField(object,
153 field_mEventLoop));
154 // Register agent for remote devices.
155 const char *device_agent_path = "/android/bluetooth/remote_device_agent";
156 static const DBusObjectPathVTable agent_vtable = {
157 NULL, agent_event_filter, NULL, NULL, NULL, NULL };
158
159 if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
160 &agent_vtable, event_nat)) {
161 LOGE("%s: Can't register object path %s for remote device agent!",
162 __FUNCTION__, device_agent_path);
163 return JNI_FALSE;
164 }
165#endif /*HAVE_BLUETOOTH*/
166 return JNI_TRUE;
167}
168
169static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800170 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700171#ifdef HAVE_BLUETOOTH
172 native_data_t *nat =
173 (native_data_t *)env->GetIntField(object, field_mNativeData);
174 if (nat != NULL) {
175 const char *device_agent_path =
176 "/android/bluetooth/remote_device_agent";
177 dbus_connection_unregister_object_path (nat->conn, device_agent_path);
178 }
179#endif /*HAVE_BLUETOOTH*/
180 return JNI_TRUE;
181}
182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800184 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185#ifdef HAVE_BLUETOOTH
186 native_data_t *nat =
187 (native_data_t *)env->GetIntField(object, field_mNativeData);
188 if (nat) {
189 free(nat);
190 nat = NULL;
191 }
192#endif
193}
194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800196 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197#ifdef HAVE_BLUETOOTH
198 native_data_t *nat = get_native_data(env, object);
199 if (nat) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700200 return (env->NewStringUTF(get_adapter_path(env, object)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202#endif
203 return NULL;
204}
205
206
207static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800208 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209#ifdef HAVE_BLUETOOTH
210 DBusMessage *msg = NULL;
211 DBusMessage *reply = NULL;
212 DBusError err;
213 const char *name;
214 jboolean ret = JNI_FALSE;
215
216 native_data_t *nat = get_native_data(env, object);
217 if (nat == NULL) {
218 goto done;
219 }
220
221 dbus_error_init(&err);
222
223 /* Compose the command */
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700224 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
225 get_adapter_path(env, object),
226 DBUS_ADAPTER_IFACE, "StartDiscovery");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
228 if (msg == NULL) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700229 if (dbus_error_is_set(&err)) {
230 LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 goto done;
233 }
234
235 /* Send the command. */
236 reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
237 if (dbus_error_is_set(&err)) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700238 LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
239 ret = JNI_FALSE;
240 goto done;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 }
242
243 ret = JNI_TRUE;
244done:
245 if (reply) dbus_message_unref(reply);
246 if (msg) dbus_message_unref(msg);
247 return ret;
248#else
249 return JNI_FALSE;
250#endif
251}
252
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700253static void stopDiscoveryNative(JNIEnv *env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800254 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255#ifdef HAVE_BLUETOOTH
256 DBusMessage *msg = NULL;
257 DBusMessage *reply = NULL;
258 DBusError err;
259 const char *name;
260 jstring ret;
261 native_data_t *nat;
262
263 dbus_error_init(&err);
264
265 nat = get_native_data(env, object);
266 if (nat == NULL) {
267 goto done;
268 }
269
270 /* Compose the command */
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700271 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
272 get_adapter_path(env, object),
273 DBUS_ADAPTER_IFACE, "StopDiscovery");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 if (msg == NULL) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700275 if (dbus_error_is_set(&err))
276 LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 goto done;
278 }
279
280 /* Send the command. */
281 reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
282 if (dbus_error_is_set(&err)) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700283 if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
284 strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 // hcid sends this if there is no active discovery to cancel
286 LOGV("%s: There was no active discovery to cancel", __FUNCTION__);
287 dbus_error_free(&err);
288 } else {
289 LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
290 }
291 }
292
293done:
294 if (msg) dbus_message_unref(msg);
295 if (reply) dbus_message_unref(reply);
296#endif
297}
298
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700299static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800300 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700301#ifdef HAVE_BLUETOOTH
302 native_data_t *nat = get_native_data(env, object);
303 DBusError err;
304 jbyte *hash, *randomizer;
305 jbyteArray byteArray = NULL;
306 int hash_len, r_len;
307 if (nat) {
308 DBusMessage *reply = dbus_func_args(env, nat->conn,
309 get_adapter_path(env, object),
310 DBUS_ADAPTER_IFACE, "ReadLocalOutOfBandData",
311 DBUS_TYPE_INVALID);
312 if (!reply) return NULL;
313
314 dbus_error_init(&err);
315 if (dbus_message_get_args(reply, &err,
316 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hash_len,
317 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &r_len,
318 DBUS_TYPE_INVALID)) {
319 if (hash_len == 16 && r_len == 16) {
320 byteArray = env->NewByteArray(32);
321 if (byteArray) {
322 env->SetByteArrayRegion(byteArray, 0, 16, hash);
323 env->SetByteArrayRegion(byteArray, 16, 16, randomizer);
324 }
325 } else {
326 LOGE("readAdapterOutOfBandDataNative: Hash len = %d, R len = %d",
327 hash_len, r_len);
328 }
329 } else {
330 LOG_AND_FREE_DBUS_ERROR(&err);
331 }
332 dbus_message_unref(reply);
333 return byteArray;
334 }
335#endif
336 return NULL;
337}
338
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700339static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
340 jstring address, jint timeout_ms) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800341 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342#ifdef HAVE_BLUETOOTH
343 native_data_t *nat = get_native_data(env, object);
Robert Greenwalt28d139f2009-04-02 22:41:08 -0700344 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
345 struct event_loop_native_data_t *eventLoopNat =
346 get_EventLoop_native_data(env, eventLoop);
347
348 if (nat && eventLoopNat) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 const char *c_address = env->GetStringUTFChars(address, NULL);
350 LOGV("... address = %s", c_address);
351 char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700352 const char *capabilities = "DisplayYesNo";
353 const char *agent_path = "/android/bluetooth/remote_device_agent";
354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
356 bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700357 onCreatePairedDeviceResult, // callback
Robert Greenwalt28d139f2009-04-02 22:41:08 -0700358 context_address,
359 eventLoopNat,
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700360 get_adapter_path(env, object),
361 DBUS_ADAPTER_IFACE,
362 "CreatePairedDevice",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 DBUS_TYPE_STRING, &c_address,
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700364 DBUS_TYPE_OBJECT_PATH, &agent_path,
365 DBUS_TYPE_STRING, &capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 DBUS_TYPE_INVALID);
367 env->ReleaseStringUTFChars(address, c_address);
368 return ret ? JNI_TRUE : JNI_FALSE;
369
370 }
371#endif
372 return JNI_FALSE;
373}
374
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700375static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
376 jstring address, jint timeout_ms) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800377 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700378#ifdef HAVE_BLUETOOTH
379 native_data_t *nat = get_native_data(env, object);
380 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
381 struct event_loop_native_data_t *eventLoopNat =
382 get_EventLoop_native_data(env, eventLoop);
383
384 if (nat && eventLoopNat) {
385 const char *c_address = env->GetStringUTFChars(address, NULL);
386 LOGV("... address = %s", c_address);
387 char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
388 const char *capabilities = "DisplayYesNo";
389 const char *agent_path = "/android/bluetooth/remote_device_agent";
390
391 strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
392 bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
393 onCreatePairedDeviceResult, // callback
394 context_address,
395 eventLoopNat,
396 get_adapter_path(env, object),
397 DBUS_ADAPTER_IFACE,
398 "CreatePairedDeviceOutOfBand",
399 DBUS_TYPE_STRING, &c_address,
400 DBUS_TYPE_OBJECT_PATH, &agent_path,
401 DBUS_TYPE_STRING, &capabilities,
402 DBUS_TYPE_INVALID);
403 env->ReleaseStringUTFChars(address, c_address);
404 return ret ? JNI_TRUE : JNI_FALSE;
405 }
406#endif
407 return JNI_FALSE;
408}
409
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700410static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
411 jstring path,
412 jstring pattern, jint attr_id) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800414 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 native_data_t *nat = get_native_data(env, object);
Robert Greenwalt28d139f2009-04-02 22:41:08 -0700416 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
417 struct event_loop_native_data_t *eventLoopNat =
418 get_EventLoop_native_data(env, eventLoop);
419 if (nat && eventLoopNat) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700420 const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
421 const char *c_path = env->GetStringUTFChars(path, NULL);
422 LOGV("... pattern = %s", c_pattern);
423 LOGV("... attr_id = %#X", attr_id);
424 DBusMessage *reply =
425 dbus_func_args(env, nat->conn, c_path,
426 DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
427 DBUS_TYPE_STRING, &c_pattern,
428 DBUS_TYPE_UINT16, &attr_id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 DBUS_TYPE_INVALID);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700430 env->ReleaseStringUTFChars(pattern, c_pattern);
431 env->ReleaseStringUTFChars(path, c_path);
432 return reply ? dbus_returns_int32(env, reply) : -1;
433 }
434#endif
435 return -1;
436}
437
438static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
439 jstring address) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800440 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700441 jboolean result = JNI_FALSE;
442#ifdef HAVE_BLUETOOTH
443 native_data_t *nat = get_native_data(env, object);
444 if (nat) {
445 const char *c_address = env->GetStringUTFChars(address, NULL);
446 DBusError err;
447 dbus_error_init(&err);
448 LOGV("... address = %s", c_address);
449 DBusMessage *reply =
450 dbus_func_args_timeout(env, nat->conn, -1,
451 get_adapter_path(env, object),
452 DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
453 DBUS_TYPE_STRING, &c_address,
454 DBUS_TYPE_INVALID);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 env->ReleaseStringUTFChars(address, c_address);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700456 if (!reply) {
457 if (dbus_error_is_set(&err)) {
458 LOG_AND_FREE_DBUS_ERROR(&err);
459 } else
460 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
461 return JNI_FALSE;
462 } else {
463 result = JNI_TRUE;
464 }
465 dbus_message_unref(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 }
467#endif
468 return JNI_FALSE;
469}
470
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700471static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800472 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700473#ifdef HAVE_BLUETOOTH
474 native_data_t *nat = get_native_data(env, object);
475 if (nat) {
476 const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
Jaikumar Ganesh995ae822009-09-20 11:25:09 -0700477 bool ret = dbus_func_args_async(env, nat->conn, -1,
478 NULL,
479 NULL,
480 NULL,
481 get_adapter_path(env, object),
482 DBUS_ADAPTER_IFACE,
483 "RemoveDevice",
484 DBUS_TYPE_OBJECT_PATH, &c_object_path,
485 DBUS_TYPE_INVALID);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700486 env->ReleaseStringUTFChars(object_path, c_object_path);
Jaikumar Ganesh995ae822009-09-20 11:25:09 -0700487 return ret ? JNI_TRUE : JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700488 }
489#endif
Jaikumar Ganesh995ae822009-09-20 11:25:09 -0700490 return JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700491}
492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493static jint enableNative(JNIEnv *env, jobject object) {
494#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800495 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 return bt_enable();
497#endif
498 return -1;
499}
500
501static jint disableNative(JNIEnv *env, jobject object) {
502#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800503 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 return bt_disable();
505#endif
506 return -1;
507}
508
509static jint isEnabledNative(JNIEnv *env, jobject object) {
510#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800511 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 return bt_is_enabled();
513#endif
514 return -1;
515}
516
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700517static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
518 jstring address, bool confirm,
519 int nativeData) {
520#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800521 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700522 native_data_t *nat = get_native_data(env, object);
523 if (nat) {
524 DBusMessage *msg = (DBusMessage *)nativeData;
525 DBusMessage *reply;
526 if (confirm) {
527 reply = dbus_message_new_method_return(msg);
528 } else {
529 reply = dbus_message_new_error(msg,
530 "org.bluez.Error.Rejected", "User rejected confirmation");
531 }
532
533 if (!reply) {
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700534 LOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
535 "RequestPairingConsent to D-Bus\n", __FUNCTION__);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700536 dbus_message_unref(msg);
537 return JNI_FALSE;
538 }
539
540 dbus_connection_send(nat->conn, reply, NULL);
541 dbus_message_unref(msg);
542 dbus_message_unref(reply);
543 return JNI_TRUE;
544 }
545#endif
546 return JNI_FALSE;
547}
548
549static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
550 int passkey, int nativeData) {
551#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800552 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700553 native_data_t *nat = get_native_data(env, object);
554 if (nat) {
555 DBusMessage *msg = (DBusMessage *)nativeData;
556 DBusMessage *reply = dbus_message_new_method_return(msg);
557 if (!reply) {
558 LOGE("%s: Cannot create message reply to return Passkey code to "
559 "D-Bus\n", __FUNCTION__);
560 dbus_message_unref(msg);
561 return JNI_FALSE;
562 }
563
564 dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
565 DBUS_TYPE_INVALID);
566
567 dbus_connection_send(nat->conn, reply, NULL);
568 dbus_message_unref(msg);
569 dbus_message_unref(reply);
570 return JNI_TRUE;
571 }
572#endif
573 return JNI_FALSE;
574}
575
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700576static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
577 jbyteArray hash, jbyteArray randomizer, int nativeData) {
578#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800579 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700580 native_data_t *nat = get_native_data(env, object);
581 if (nat) {
582 DBusMessage *msg = (DBusMessage *)nativeData;
583 DBusMessage *reply = dbus_message_new_method_return(msg);
584 jbyte *h_ptr = env->GetByteArrayElements(hash, NULL);
585 jbyte *r_ptr = env->GetByteArrayElements(randomizer, NULL);
586 if (!reply) {
587 LOGE("%s: Cannot create message reply to return remote OOB data to "
588 "D-Bus\n", __FUNCTION__);
589 dbus_message_unref(msg);
590 return JNI_FALSE;
591 }
592
593 dbus_message_append_args(reply,
594 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &h_ptr, 16,
595 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &r_ptr, 16,
596 DBUS_TYPE_INVALID);
597
598 env->ReleaseByteArrayElements(hash, h_ptr, 0);
599 env->ReleaseByteArrayElements(randomizer, r_ptr, 0);
600
601 dbus_connection_send(nat->conn, reply, NULL);
602 dbus_message_unref(msg);
603 dbus_message_unref(reply);
604 return JNI_TRUE;
605 }
606#endif
607 return JNI_FALSE;
608}
609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
611 jstring pin, int nativeData) {
612#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800613 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 native_data_t *nat = get_native_data(env, object);
615 if (nat) {
616 DBusMessage *msg = (DBusMessage *)nativeData;
617 DBusMessage *reply = dbus_message_new_method_return(msg);
618 if (!reply) {
619 LOGE("%s: Cannot create message reply to return PIN code to "
620 "D-Bus\n", __FUNCTION__);
621 dbus_message_unref(msg);
622 return JNI_FALSE;
623 }
624
625 const char *c_pin = env->GetStringUTFChars(pin, NULL);
626
627 dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
628 DBUS_TYPE_INVALID);
629
630 dbus_connection_send(nat->conn, reply, NULL);
631 dbus_message_unref(msg);
632 dbus_message_unref(reply);
633 env->ReleaseStringUTFChars(pin, c_pin);
634 return JNI_TRUE;
635 }
636#endif
637 return JNI_FALSE;
638}
639
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700640static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
641 jstring address, int nativeData) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800643 LOGV("%s", __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 native_data_t *nat = get_native_data(env, object);
645 if (nat) {
646 DBusMessage *msg = (DBusMessage *)nativeData;
647 DBusMessage *reply = dbus_message_new_error(msg,
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700648 "org.bluez.Error.Canceled", "Pairing User Input was canceled");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 if (!reply) {
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700650 LOGE("%s: Cannot create message reply to return cancelUserInput to"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 "D-BUS\n", __FUNCTION__);
652 dbus_message_unref(msg);
653 return JNI_FALSE;
654 }
655
656 dbus_connection_send(nat->conn, reply, NULL);
657 dbus_message_unref(msg);
658 dbus_message_unref(reply);
659 return JNI_TRUE;
660 }
661#endif
662 return JNI_FALSE;
663}
664
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700665static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
666 jstring path)
667{
668#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800669 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700670 native_data_t *nat = get_native_data(env, object);
671 if (nat) {
672 DBusMessage *msg, *reply;
673 DBusError err;
674 dbus_error_init(&err);
675
676 const char *c_path = env->GetStringUTFChars(path, NULL);
677 reply = dbus_func_args_timeout(env,
678 nat->conn, -1, c_path,
679 DBUS_DEVICE_IFACE, "GetProperties",
680 DBUS_TYPE_INVALID);
681 env->ReleaseStringUTFChars(path, c_path);
682
683 if (!reply) {
684 if (dbus_error_is_set(&err)) {
685 LOG_AND_FREE_DBUS_ERROR(&err);
686 } else
687 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
688 return NULL;
689 }
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700690 env->PushLocalFrame(PROPERTIES_NREFS);
691
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700692 DBusMessageIter iter;
693 jobjectArray str_array = NULL;
694 if (dbus_message_iter_init(reply, &iter))
695 str_array = parse_remote_device_properties(env, &iter);
696 dbus_message_unref(reply);
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700697
Brian Carlstromb32b1dd2011-04-05 15:20:52 -0700698 return (jobjectArray) env->PopLocalFrame(str_array);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700699 }
700#endif
701 return NULL;
702}
703
704static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
705#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800706 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700707 native_data_t *nat = get_native_data(env, object);
708 if (nat) {
709 DBusMessage *msg, *reply;
710 DBusError err;
711 dbus_error_init(&err);
712
713 reply = dbus_func_args_timeout(env,
714 nat->conn, -1, get_adapter_path(env, object),
715 DBUS_ADAPTER_IFACE, "GetProperties",
716 DBUS_TYPE_INVALID);
717 if (!reply) {
718 if (dbus_error_is_set(&err)) {
719 LOG_AND_FREE_DBUS_ERROR(&err);
720 } else
721 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
722 return NULL;
723 }
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700724 env->PushLocalFrame(PROPERTIES_NREFS);
725
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700726 DBusMessageIter iter;
727 jobjectArray str_array = NULL;
728 if (dbus_message_iter_init(reply, &iter))
729 str_array = parse_adapter_properties(env, &iter);
730 dbus_message_unref(reply);
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700731
Brian Carlstromb32b1dd2011-04-05 15:20:52 -0700732 return (jobjectArray) env->PopLocalFrame(str_array);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700733 }
734#endif
735 return NULL;
736}
737
738static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
739 void *value, jint type) {
740#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800741 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700742 native_data_t *nat = get_native_data(env, object);
743 if (nat) {
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700744 DBusMessage *msg;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700745 DBusMessageIter iter;
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700746 dbus_bool_t reply = JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700747 const char *c_key = env->GetStringUTFChars(key, NULL);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700748
749 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
750 get_adapter_path(env, object),
751 DBUS_ADAPTER_IFACE, "SetProperty");
752 if (!msg) {
753 LOGE("%s: Can't allocate new method call for GetProperties!",
754 __FUNCTION__);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800755 env->ReleaseStringUTFChars(key, c_key);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700756 return JNI_FALSE;
757 }
758
759 dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
760 dbus_message_iter_init_append(msg, &iter);
761 append_variant(&iter, type, value);
762
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700763 // Asynchronous call - the callbacks come via propertyChange
764 reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700765 dbus_message_unref(msg);
766
767 env->ReleaseStringUTFChars(key, c_key);
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700768 return reply ? JNI_TRUE : JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700769
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700770 }
771#endif
772 return JNI_FALSE;
773}
774
775static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
776 jstring value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700777#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700778 const char *c_value = env->GetStringUTFChars(value, NULL);
779 jboolean ret = setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
780 env->ReleaseStringUTFChars(value, (char *)c_value);
781 return ret;
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700782#else
783 return JNI_FALSE;
784#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700785}
786
787static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
788 jint value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700789#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700790 return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700791#else
792 return JNI_FALSE;
793#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700794}
795
796static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
797 jint value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700798#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700799 return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700800#else
801 return JNI_FALSE;
802#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700803}
804
Lixin Yueefa1dd72009-08-31 15:55:13 +0800805static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
806 jstring key, void *value, jint type) {
807#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800808 LOGV("%s", __FUNCTION__);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800809 native_data_t *nat = get_native_data(env, object);
810 if (nat) {
811 DBusMessage *reply, *msg;
812 DBusMessageIter iter;
813 DBusError err;
814
815 const char *c_key = env->GetStringUTFChars(key, NULL);
816 const char *c_path = env->GetStringUTFChars(path, NULL);
817
818 dbus_error_init(&err);
819 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
820 c_path, DBUS_DEVICE_IFACE, "SetProperty");
821 if (!msg) {
822 LOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
823 env->ReleaseStringUTFChars(key, c_key);
824 env->ReleaseStringUTFChars(path, c_path);
825 return JNI_FALSE;
826 }
827
828 dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
829 dbus_message_iter_init_append(msg, &iter);
830 append_variant(&iter, type, value);
831
832 reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
833 dbus_message_unref(msg);
834
835 env->ReleaseStringUTFChars(key, c_key);
836 env->ReleaseStringUTFChars(path, c_path);
837 if (!reply) {
838 if (dbus_error_is_set(&err)) {
839 LOG_AND_FREE_DBUS_ERROR(&err);
840 } else
841 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
842 return JNI_FALSE;
843 }
844 return JNI_TRUE;
845 }
846#endif
847 return JNI_FALSE;
848}
849
850static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
851 jstring path, jstring key, jint value) {
852#ifdef HAVE_BLUETOOTH
853 return setDevicePropertyNative(env, object, path, key,
854 (void *)&value, DBUS_TYPE_BOOLEAN);
855#else
856 return JNI_FALSE;
857#endif
858}
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700859
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700860
861static jboolean createDeviceNative(JNIEnv *env, jobject object,
862 jstring address) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800863 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700864#ifdef HAVE_BLUETOOTH
865 native_data_t *nat = get_native_data(env, object);
866 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
867 struct event_loop_native_data_t *eventLoopNat =
868 get_EventLoop_native_data(env, eventLoop);
869
870 if (nat && eventLoopNat) {
871 const char *c_address = env->GetStringUTFChars(address, NULL);
872 LOGV("... address = %s", c_address);
873 char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
874 strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
875
876 bool ret = dbus_func_args_async(env, nat->conn, -1,
877 onCreateDeviceResult,
878 context_address,
879 eventLoopNat,
880 get_adapter_path(env, object),
881 DBUS_ADAPTER_IFACE,
882 "CreateDevice",
883 DBUS_TYPE_STRING, &c_address,
884 DBUS_TYPE_INVALID);
885 env->ReleaseStringUTFChars(address, c_address);
886 return ret ? JNI_TRUE : JNI_FALSE;
887 }
888#endif
889 return JNI_FALSE;
890}
891
892static jboolean discoverServicesNative(JNIEnv *env, jobject object,
893 jstring path, jstring pattern) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800894 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700895#ifdef HAVE_BLUETOOTH
896 native_data_t *nat = get_native_data(env, object);
897 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
898 struct event_loop_native_data_t *eventLoopNat =
899 get_EventLoop_native_data(env, eventLoop);
900
901 if (nat && eventLoopNat) {
902 const char *c_path = env->GetStringUTFChars(path, NULL);
903 const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
904 int len = env->GetStringLength(path) + 1;
905 char *context_path = (char *)calloc(len, sizeof(char));
906 strlcpy(context_path, c_path, len); // for callback
907
908 LOGV("... Object Path = %s", c_path);
909 LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
910
911 bool ret = dbus_func_args_async(env, nat->conn, -1,
912 onDiscoverServicesResult,
913 context_path,
914 eventLoopNat,
915 c_path,
916 DBUS_DEVICE_IFACE,
917 "DiscoverServices",
918 DBUS_TYPE_STRING, &c_pattern,
919 DBUS_TYPE_INVALID);
920 env->ReleaseStringUTFChars(path, c_path);
921 env->ReleaseStringUTFChars(pattern, c_pattern);
922 return ret ? JNI_TRUE : JNI_FALSE;
923 }
924#endif
925 return JNI_FALSE;
926}
927
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800928#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshaecb2c52010-12-13 14:04:45 -0800929static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800930 jint *handles;
931 jintArray handleArray = NULL;
932 int len;
933
934 DBusError err;
935 dbus_error_init(&err);
936
937 if (dbus_message_get_args(reply, &err,
938 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
939 DBUS_TYPE_INVALID)) {
940 handleArray = env->NewIntArray(len);
941 if (handleArray) {
942 env->SetIntArrayRegion(handleArray, 0, len, handles);
943 } else {
944 LOGE("Null array in extract_handles");
945 }
946 } else {
947 LOG_AND_FREE_DBUS_ERROR(&err);
948 }
949 return handleArray;
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800950}
Jaikumar Ganeshaecb2c52010-12-13 14:04:45 -0800951#endif
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800952
953static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
954 jintArray uuids) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800955 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800956#ifdef HAVE_BLUETOOTH
957 DBusMessage *reply = NULL;
958
959 native_data_t *nat = get_native_data(env, object);
960
961 jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
962 if (!svc_classes) return NULL;
963
964 int len = env->GetArrayLength(uuids);
965 reply = dbus_func_args(env, nat->conn,
966 get_adapter_path(env, object),
967 DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
968 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
969 &svc_classes, len, DBUS_TYPE_INVALID);
970 env->ReleaseIntArrayElements(uuids, svc_classes, 0);
971 return reply ? extract_handles(env, reply) : NULL;
972
973#endif
974 return NULL;
975}
976
977static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
978 jintArray handles) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800979 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800980#ifdef HAVE_BLUETOOTH
981 native_data_t *nat = get_native_data(env, object);
982 jint *values = env->GetIntArrayElements(handles, NULL);
983 DBusMessage *msg = NULL;
984 DBusMessage *reply = NULL;
985 if (values == NULL) return JNI_FALSE;
986
987 jsize len = env->GetArrayLength(handles);
988
989 reply = dbus_func_args(env, nat->conn,
990 get_adapter_path(env, object),
991 DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
992 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
993 &values, len, DBUS_TYPE_INVALID);
994 env->ReleaseIntArrayElements(handles, values, NULL);
995 return reply ? JNI_TRUE : JNI_FALSE;
996#endif
997 return JNI_FALSE;
998}
999
Nick Pelly24bb9b82009-10-02 20:34:18 -07001000static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
1001 jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001002 LOGV("%s", __FUNCTION__);
Nick Pelly24bb9b82009-10-02 20:34:18 -07001003#ifdef HAVE_BLUETOOTH
1004 native_data_t *nat = get_native_data(env, object);
1005 if (nat) {
1006 const char *c_name = env->GetStringUTFChars(name, NULL);
1007 LOGV("... name = %s", c_name);
1008 LOGV("... uuid1 = %llX", uuidMsb);
1009 LOGV("... uuid2 = %llX", uuidLsb);
1010 LOGV("... channel = %d", channel);
1011 DBusMessage *reply = dbus_func_args(env, nat->conn,
1012 get_adapter_path(env, object),
1013 DBUS_ADAPTER_IFACE, "AddRfcommServiceRecord",
1014 DBUS_TYPE_STRING, &c_name,
1015 DBUS_TYPE_UINT64, &uuidMsb,
1016 DBUS_TYPE_UINT64, &uuidLsb,
1017 DBUS_TYPE_UINT16, &channel,
1018 DBUS_TYPE_INVALID);
1019 env->ReleaseStringUTFChars(name, c_name);
1020 return reply ? dbus_returns_uint32(env, reply) : -1;
1021 }
1022#endif
1023 return -1;
1024}
1025
1026static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001027 LOGV("%s", __FUNCTION__);
Nick Pelly24bb9b82009-10-02 20:34:18 -07001028#ifdef HAVE_BLUETOOTH
1029 native_data_t *nat = get_native_data(env, object);
1030 if (nat) {
1031 LOGV("... handle = %X", handle);
1032 DBusMessage *reply = dbus_func_args(env, nat->conn,
1033 get_adapter_path(env, object),
1034 DBUS_ADAPTER_IFACE, "RemoveServiceRecord",
1035 DBUS_TYPE_UINT32, &handle,
1036 DBUS_TYPE_INVALID);
1037 return reply ? JNI_TRUE : JNI_FALSE;
1038 }
1039#endif
1040 return JNI_FALSE;
1041}
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001042
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001043static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
1044 jint num_slots) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001045 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001046#ifdef HAVE_BLUETOOTH
1047 native_data_t *nat = get_native_data(env, object);
1048 if (nat) {
1049 const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
1050 DBusMessage *reply = dbus_func_args(env, nat->conn,
1051 get_adapter_path(env, object),
1052 DBUS_ADAPTER_IFACE, "SetLinkTimeout",
1053 DBUS_TYPE_OBJECT_PATH, &c_object_path,
1054 DBUS_TYPE_UINT32, &num_slots,
1055 DBUS_TYPE_INVALID);
1056 env->ReleaseStringUTFChars(object_path, c_object_path);
1057 return reply ? JNI_TRUE : JNI_FALSE;
1058 }
1059#endif
1060 return JNI_FALSE;
1061}
1062
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001063static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001064 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001065#ifdef HAVE_BLUETOOTH
1066 native_data_t *nat = get_native_data(env, object);
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001067 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1068 struct event_loop_native_data_t *eventLoopNat =
1069 get_EventLoop_native_data(env, eventLoop);
1070
1071 if (nat && eventLoopNat) {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001072 const char *c_path = env->GetStringUTFChars(path, NULL);
1073
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001074 int len = env->GetStringLength(path) + 1;
1075 char *context_path = (char *)calloc(len, sizeof(char));
1076 strlcpy(context_path, c_path, len); // for callback
1077
1078 bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
1079 context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
1080 "Connect",
1081 DBUS_TYPE_INVALID);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001082
1083 env->ReleaseStringUTFChars(path, c_path);
1084 return ret ? JNI_TRUE : JNI_FALSE;
1085 }
1086#endif
1087 return JNI_FALSE;
1088}
1089
1090static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
1091 jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001092 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001093#ifdef HAVE_BLUETOOTH
1094 native_data_t *nat = get_native_data(env, object);
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001095 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1096 struct event_loop_native_data_t *eventLoopNat =
1097 get_EventLoop_native_data(env, eventLoop);
1098
1099 if (nat && eventLoopNat) {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001100 const char *c_path = env->GetStringUTFChars(path, NULL);
1101
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001102 int len = env->GetStringLength(path) + 1;
1103 char *context_path = (char *)calloc(len, sizeof(char));
1104 strlcpy(context_path, c_path, len); // for callback
1105
1106 bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
1107 context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
1108 "Disconnect",
1109 DBUS_TYPE_INVALID);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001110
1111 env->ReleaseStringUTFChars(path, c_path);
1112 return ret ? JNI_TRUE : JNI_FALSE;
1113 }
1114#endif
1115 return JNI_FALSE;
1116}
1117
Danica Chang6fdd0c62010-08-11 14:54:43 -07001118static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
1119 jstring src_role, jstring bridge) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001120 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001121#ifdef HAVE_BLUETOOTH
1122 native_data_t *nat = get_native_data(env, object);
1123 if (nat) {
1124 DBusMessage *reply;
1125 const char *c_role = env->GetStringUTFChars(src_role, NULL);
1126 const char *c_bridge = env->GetStringUTFChars(bridge, NULL);
1127 if (value) {
1128 LOGE("setBluetoothTetheringNative true");
1129 reply = dbus_func_args(env, nat->conn,
1130 get_adapter_path(env, object),
1131 DBUS_NETWORKSERVER_IFACE,
1132 "Register",
1133 DBUS_TYPE_STRING, &c_role,
1134 DBUS_TYPE_STRING, &c_bridge,
1135 DBUS_TYPE_INVALID);
1136 } else {
1137 LOGE("setBluetoothTetheringNative false");
1138 reply = dbus_func_args(env, nat->conn,
1139 get_adapter_path(env, object),
1140 DBUS_NETWORKSERVER_IFACE,
1141 "Unregister",
1142 DBUS_TYPE_STRING, &c_role,
1143 DBUS_TYPE_INVALID);
1144 }
1145 env->ReleaseStringUTFChars(src_role, c_role);
1146 env->ReleaseStringUTFChars(bridge, c_bridge);
1147 return reply ? JNI_TRUE : JNI_FALSE;
1148 }
1149#endif
1150 return JNI_FALSE;
1151}
1152
1153static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
Jaikumar Ganeshb7ec3e12010-12-16 18:02:29 -08001154 jstring dstRole) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001155 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001156#ifdef HAVE_BLUETOOTH
1157 LOGE("connectPanDeviceNative");
1158 native_data_t *nat = get_native_data(env, object);
1159 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1160 struct event_loop_native_data_t *eventLoopNat =
1161 get_EventLoop_native_data(env, eventLoop);
1162
1163 if (nat && eventLoopNat) {
1164 const char *c_path = env->GetStringUTFChars(path, NULL);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001165 const char *dst = env->GetStringUTFChars(dstRole, NULL);
1166
1167 int len = env->GetStringLength(path) + 1;
1168 char *context_path = (char *)calloc(len, sizeof(char));
1169 strlcpy(context_path, c_path, len); // for callback
1170
1171 bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
1172 context_path, eventLoopNat, c_path,
1173 DBUS_NETWORK_IFACE, "Connect",
Danica Chang6fdd0c62010-08-11 14:54:43 -07001174 DBUS_TYPE_STRING, &dst,
1175 DBUS_TYPE_INVALID);
1176
1177 env->ReleaseStringUTFChars(path, c_path);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001178 env->ReleaseStringUTFChars(dstRole, dst);
1179 return ret ? JNI_TRUE : JNI_FALSE;
1180 }
1181#endif
1182 return JNI_FALSE;
1183}
1184
1185static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
1186 jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001187 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001188#ifdef HAVE_BLUETOOTH
1189 LOGE("disconnectPanDeviceNative");
1190 native_data_t *nat = get_native_data(env, object);
1191 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1192 struct event_loop_native_data_t *eventLoopNat =
1193 get_EventLoop_native_data(env, eventLoop);
1194
1195 if (nat && eventLoopNat) {
1196 const char *c_path = env->GetStringUTFChars(path, NULL);
1197
1198 int len = env->GetStringLength(path) + 1;
1199 char *context_path = (char *)calloc(len, sizeof(char));
1200 strlcpy(context_path, c_path, len); // for callback
1201
1202 bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
1203 context_path, eventLoopNat, c_path,
1204 DBUS_NETWORK_IFACE, "Disconnect",
1205 DBUS_TYPE_INVALID);
1206
1207 env->ReleaseStringUTFChars(path, c_path);
1208 return ret ? JNI_TRUE : JNI_FALSE;
1209 }
1210#endif
1211 return JNI_FALSE;
1212}
1213
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001214static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
1215 jstring path, jstring address,
1216 jstring iface) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001217 LOGV("%s", __FUNCTION__);
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001218#ifdef HAVE_BLUETOOTH
1219 LOGE("disconnectPanServerDeviceNative");
1220 native_data_t *nat = get_native_data(env, object);
1221 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1222 struct event_loop_native_data_t *eventLoopNat =
1223 get_EventLoop_native_data(env, eventLoop);
1224
1225 if (nat && eventLoopNat) {
1226 const char *c_address = env->GetStringUTFChars(address, NULL);
1227 const char *c_path = env->GetStringUTFChars(path, NULL);
1228 const char *c_iface = env->GetStringUTFChars(iface, NULL);
1229
1230 int len = env->GetStringLength(path) + 1;
1231 char *context_path = (char *)calloc(len, sizeof(char));
1232 strlcpy(context_path, c_path, len); // for callback
1233
1234 bool ret = dbus_func_args_async(env, nat->conn, -1,
1235 onPanDeviceConnectionResult,
1236 context_path, eventLoopNat,
1237 get_adapter_path(env, object),
1238 DBUS_NETWORKSERVER_IFACE,
1239 "DisconnectDevice",
1240 DBUS_TYPE_STRING, &c_address,
1241 DBUS_TYPE_STRING, &c_iface,
1242 DBUS_TYPE_INVALID);
1243
1244 env->ReleaseStringUTFChars(address, c_address);
1245 env->ReleaseStringUTFChars(iface, c_iface);
1246 env->ReleaseStringUTFChars(path, c_path);
1247 return ret ? JNI_TRUE : JNI_FALSE;
1248 }
1249#endif
1250 return JNI_FALSE;
1251}
1252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253static JNINativeMethod sMethods[] = {
1254 /* name, signature, funcPtr */
1255 {"classInitNative", "()V", (void*)classInitNative},
1256 {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001257 {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
1258 {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
1260 {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
1261
1262 {"isEnabledNative", "()I", (void *)isEnabledNative},
1263 {"enableNative", "()I", (void *)enableNative},
1264 {"disableNative", "()I", (void *)disableNative},
1265
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001266 {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
1267 {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
1268 (void *)getDevicePropertiesNative},
1269 {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
1270 (void *)setAdapterPropertyStringNative},
1271 {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
1272 (void *)setAdapterPropertyBooleanNative},
1273 {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
1274 (void *)setAdapterPropertyIntegerNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001276 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
1277 {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001279 {"readAdapterOutOfBandDataNative", "()[B", (void *)readAdapterOutOfBandDataNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001280 {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001281 {"createPairedDeviceOutOfBandNative", "(Ljava/lang/String;I)Z",
1282 (void *)createPairedDeviceOutOfBandNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001283 {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
1284 {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
1285 {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
1286 (void *)getDeviceServiceChannelNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001288 {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
1289 (void *)setPairingConfirmationNative},
1290 {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001291 {"setRemoteOutOfBandDataNative", "(Ljava/lang/String;[B[BI)Z", (void *)setRemoteOutOfBandDataNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001293 {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
1294 (void *)cancelPairingUserInputNative},
Lixin Yueefa1dd72009-08-31 15:55:13 +08001295 {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
1296 (void *)setDevicePropertyBooleanNative},
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001297 {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
1298 {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
Nick Pelly24bb9b82009-10-02 20:34:18 -07001299 {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
1300 {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
Jaikumar Ganesh84690c82010-12-10 12:48:58 -08001301 {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
1302 {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001303 {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001304 // HID functions
1305 {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
1306 {"disconnectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectInputDeviceNative},
Danica Chang6fdd0c62010-08-11 14:54:43 -07001307
1308 {"setBluetoothTetheringNative", "(ZLjava/lang/String;Ljava/lang/String;)Z",
1309 (void *)setBluetoothTetheringNative},
Jaikumar Ganeshb7ec3e12010-12-16 18:02:29 -08001310 {"connectPanDeviceNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
Danica Chang6fdd0c62010-08-11 14:54:43 -07001311 (void *)connectPanDeviceNative},
1312 {"disconnectPanDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectPanDeviceNative},
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001313 {"disconnectPanServerDeviceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
1314 (void *)disconnectPanServerDeviceNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315};
1316
Danica Chang6fdd0c62010-08-11 14:54:43 -07001317
Nick Pellybd022f42009-08-14 18:33:38 -07001318int register_android_server_BluetoothService(JNIEnv *env) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 return AndroidRuntime::registerNativeMethods(env,
Nick Pellybd022f42009-08-14 18:33:38 -07001320 "android/server/BluetoothService", sMethods, NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321}
1322
1323} /* namespace android */