blob: 158e47573c52af59d35defb15a205ee9044542ef [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
698 env->PopLocalFrame(NULL);
699
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700700 return str_array;
701 }
702#endif
703 return NULL;
704}
705
706static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
707#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800708 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700709 native_data_t *nat = get_native_data(env, object);
710 if (nat) {
711 DBusMessage *msg, *reply;
712 DBusError err;
713 dbus_error_init(&err);
714
715 reply = dbus_func_args_timeout(env,
716 nat->conn, -1, get_adapter_path(env, object),
717 DBUS_ADAPTER_IFACE, "GetProperties",
718 DBUS_TYPE_INVALID);
719 if (!reply) {
720 if (dbus_error_is_set(&err)) {
721 LOG_AND_FREE_DBUS_ERROR(&err);
722 } else
723 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
724 return NULL;
725 }
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700726 env->PushLocalFrame(PROPERTIES_NREFS);
727
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700728 DBusMessageIter iter;
729 jobjectArray str_array = NULL;
730 if (dbus_message_iter_init(reply, &iter))
731 str_array = parse_adapter_properties(env, &iter);
732 dbus_message_unref(reply);
Jaikumar Ganesh6d56b532009-08-24 17:11:11 -0700733
734 env->PopLocalFrame(NULL);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700735 return str_array;
736 }
737#endif
738 return NULL;
739}
740
741static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
742 void *value, jint type) {
743#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800744 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700745 native_data_t *nat = get_native_data(env, object);
746 if (nat) {
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700747 DBusMessage *msg;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700748 DBusMessageIter iter;
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700749 dbus_bool_t reply = JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700750 const char *c_key = env->GetStringUTFChars(key, NULL);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700751
752 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
753 get_adapter_path(env, object),
754 DBUS_ADAPTER_IFACE, "SetProperty");
755 if (!msg) {
756 LOGE("%s: Can't allocate new method call for GetProperties!",
757 __FUNCTION__);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800758 env->ReleaseStringUTFChars(key, c_key);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700759 return JNI_FALSE;
760 }
761
762 dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
763 dbus_message_iter_init_append(msg, &iter);
764 append_variant(&iter, type, value);
765
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700766 // Asynchronous call - the callbacks come via propertyChange
767 reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700768 dbus_message_unref(msg);
769
770 env->ReleaseStringUTFChars(key, c_key);
Jaikumar Ganeshff7db402010-10-25 16:25:52 -0700771 return reply ? JNI_TRUE : JNI_FALSE;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700772
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700773 }
774#endif
775 return JNI_FALSE;
776}
777
778static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
779 jstring value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700780#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700781 const char *c_value = env->GetStringUTFChars(value, NULL);
782 jboolean ret = setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
783 env->ReleaseStringUTFChars(value, (char *)c_value);
784 return ret;
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700785#else
786 return JNI_FALSE;
787#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700788}
789
790static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
791 jint value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700792#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700793 return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700794#else
795 return JNI_FALSE;
796#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700797}
798
799static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
800 jint value) {
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700801#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700802 return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
Jaikumar Ganeshd4613492009-06-09 23:32:42 -0700803#else
804 return JNI_FALSE;
805#endif
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700806}
807
Lixin Yueefa1dd72009-08-31 15:55:13 +0800808static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
809 jstring key, void *value, jint type) {
810#ifdef HAVE_BLUETOOTH
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800811 LOGV("%s", __FUNCTION__);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800812 native_data_t *nat = get_native_data(env, object);
813 if (nat) {
814 DBusMessage *reply, *msg;
815 DBusMessageIter iter;
816 DBusError err;
817
818 const char *c_key = env->GetStringUTFChars(key, NULL);
819 const char *c_path = env->GetStringUTFChars(path, NULL);
820
821 dbus_error_init(&err);
822 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
823 c_path, DBUS_DEVICE_IFACE, "SetProperty");
824 if (!msg) {
825 LOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
826 env->ReleaseStringUTFChars(key, c_key);
827 env->ReleaseStringUTFChars(path, c_path);
828 return JNI_FALSE;
829 }
830
831 dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
832 dbus_message_iter_init_append(msg, &iter);
833 append_variant(&iter, type, value);
834
835 reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
836 dbus_message_unref(msg);
837
838 env->ReleaseStringUTFChars(key, c_key);
839 env->ReleaseStringUTFChars(path, c_path);
840 if (!reply) {
841 if (dbus_error_is_set(&err)) {
842 LOG_AND_FREE_DBUS_ERROR(&err);
843 } else
844 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
845 return JNI_FALSE;
846 }
847 return JNI_TRUE;
848 }
849#endif
850 return JNI_FALSE;
851}
852
853static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
854 jstring path, jstring key, jint value) {
855#ifdef HAVE_BLUETOOTH
856 return setDevicePropertyNative(env, object, path, key,
857 (void *)&value, DBUS_TYPE_BOOLEAN);
858#else
859 return JNI_FALSE;
860#endif
861}
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700862
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700863
864static jboolean createDeviceNative(JNIEnv *env, jobject object,
865 jstring address) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800866 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700867#ifdef HAVE_BLUETOOTH
868 native_data_t *nat = get_native_data(env, object);
869 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
870 struct event_loop_native_data_t *eventLoopNat =
871 get_EventLoop_native_data(env, eventLoop);
872
873 if (nat && eventLoopNat) {
874 const char *c_address = env->GetStringUTFChars(address, NULL);
875 LOGV("... address = %s", c_address);
876 char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
877 strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
878
879 bool ret = dbus_func_args_async(env, nat->conn, -1,
880 onCreateDeviceResult,
881 context_address,
882 eventLoopNat,
883 get_adapter_path(env, object),
884 DBUS_ADAPTER_IFACE,
885 "CreateDevice",
886 DBUS_TYPE_STRING, &c_address,
887 DBUS_TYPE_INVALID);
888 env->ReleaseStringUTFChars(address, c_address);
889 return ret ? JNI_TRUE : JNI_FALSE;
890 }
891#endif
892 return JNI_FALSE;
893}
894
895static jboolean discoverServicesNative(JNIEnv *env, jobject object,
896 jstring path, jstring pattern) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800897 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700898#ifdef HAVE_BLUETOOTH
899 native_data_t *nat = get_native_data(env, object);
900 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
901 struct event_loop_native_data_t *eventLoopNat =
902 get_EventLoop_native_data(env, eventLoop);
903
904 if (nat && eventLoopNat) {
905 const char *c_path = env->GetStringUTFChars(path, NULL);
906 const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
907 int len = env->GetStringLength(path) + 1;
908 char *context_path = (char *)calloc(len, sizeof(char));
909 strlcpy(context_path, c_path, len); // for callback
910
911 LOGV("... Object Path = %s", c_path);
912 LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
913
914 bool ret = dbus_func_args_async(env, nat->conn, -1,
915 onDiscoverServicesResult,
916 context_path,
917 eventLoopNat,
918 c_path,
919 DBUS_DEVICE_IFACE,
920 "DiscoverServices",
921 DBUS_TYPE_STRING, &c_pattern,
922 DBUS_TYPE_INVALID);
923 env->ReleaseStringUTFChars(path, c_path);
924 env->ReleaseStringUTFChars(pattern, c_pattern);
925 return ret ? JNI_TRUE : JNI_FALSE;
926 }
927#endif
928 return JNI_FALSE;
929}
930
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800931#ifdef HAVE_BLUETOOTH
Jaikumar Ganeshaecb2c52010-12-13 14:04:45 -0800932static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800933 jint *handles;
934 jintArray handleArray = NULL;
935 int len;
936
937 DBusError err;
938 dbus_error_init(&err);
939
940 if (dbus_message_get_args(reply, &err,
941 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
942 DBUS_TYPE_INVALID)) {
943 handleArray = env->NewIntArray(len);
944 if (handleArray) {
945 env->SetIntArrayRegion(handleArray, 0, len, handles);
946 } else {
947 LOGE("Null array in extract_handles");
948 }
949 } else {
950 LOG_AND_FREE_DBUS_ERROR(&err);
951 }
952 return handleArray;
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800953}
Jaikumar Ganeshaecb2c52010-12-13 14:04:45 -0800954#endif
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800955
956static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
957 jintArray uuids) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800958 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800959#ifdef HAVE_BLUETOOTH
960 DBusMessage *reply = NULL;
961
962 native_data_t *nat = get_native_data(env, object);
963
964 jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
965 if (!svc_classes) return NULL;
966
967 int len = env->GetArrayLength(uuids);
968 reply = dbus_func_args(env, nat->conn,
969 get_adapter_path(env, object),
970 DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
971 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
972 &svc_classes, len, DBUS_TYPE_INVALID);
973 env->ReleaseIntArrayElements(uuids, svc_classes, 0);
974 return reply ? extract_handles(env, reply) : NULL;
975
976#endif
977 return NULL;
978}
979
980static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
981 jintArray handles) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -0800982 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh84690c82010-12-10 12:48:58 -0800983#ifdef HAVE_BLUETOOTH
984 native_data_t *nat = get_native_data(env, object);
985 jint *values = env->GetIntArrayElements(handles, NULL);
986 DBusMessage *msg = NULL;
987 DBusMessage *reply = NULL;
988 if (values == NULL) return JNI_FALSE;
989
990 jsize len = env->GetArrayLength(handles);
991
992 reply = dbus_func_args(env, nat->conn,
993 get_adapter_path(env, object),
994 DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
995 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
996 &values, len, DBUS_TYPE_INVALID);
997 env->ReleaseIntArrayElements(handles, values, NULL);
998 return reply ? JNI_TRUE : JNI_FALSE;
999#endif
1000 return JNI_FALSE;
1001}
1002
Nick Pelly24bb9b82009-10-02 20:34:18 -07001003static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
1004 jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001005 LOGV("%s", __FUNCTION__);
Nick Pelly24bb9b82009-10-02 20:34:18 -07001006#ifdef HAVE_BLUETOOTH
1007 native_data_t *nat = get_native_data(env, object);
1008 if (nat) {
1009 const char *c_name = env->GetStringUTFChars(name, NULL);
1010 LOGV("... name = %s", c_name);
1011 LOGV("... uuid1 = %llX", uuidMsb);
1012 LOGV("... uuid2 = %llX", uuidLsb);
1013 LOGV("... channel = %d", channel);
1014 DBusMessage *reply = dbus_func_args(env, nat->conn,
1015 get_adapter_path(env, object),
1016 DBUS_ADAPTER_IFACE, "AddRfcommServiceRecord",
1017 DBUS_TYPE_STRING, &c_name,
1018 DBUS_TYPE_UINT64, &uuidMsb,
1019 DBUS_TYPE_UINT64, &uuidLsb,
1020 DBUS_TYPE_UINT16, &channel,
1021 DBUS_TYPE_INVALID);
1022 env->ReleaseStringUTFChars(name, c_name);
1023 return reply ? dbus_returns_uint32(env, reply) : -1;
1024 }
1025#endif
1026 return -1;
1027}
1028
1029static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001030 LOGV("%s", __FUNCTION__);
Nick Pelly24bb9b82009-10-02 20:34:18 -07001031#ifdef HAVE_BLUETOOTH
1032 native_data_t *nat = get_native_data(env, object);
1033 if (nat) {
1034 LOGV("... handle = %X", handle);
1035 DBusMessage *reply = dbus_func_args(env, nat->conn,
1036 get_adapter_path(env, object),
1037 DBUS_ADAPTER_IFACE, "RemoveServiceRecord",
1038 DBUS_TYPE_UINT32, &handle,
1039 DBUS_TYPE_INVALID);
1040 return reply ? JNI_TRUE : JNI_FALSE;
1041 }
1042#endif
1043 return JNI_FALSE;
1044}
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001045
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001046static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
1047 jint num_slots) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001048 LOGV("%s", __FUNCTION__);
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001049#ifdef HAVE_BLUETOOTH
1050 native_data_t *nat = get_native_data(env, object);
1051 if (nat) {
1052 const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
1053 DBusMessage *reply = dbus_func_args(env, nat->conn,
1054 get_adapter_path(env, object),
1055 DBUS_ADAPTER_IFACE, "SetLinkTimeout",
1056 DBUS_TYPE_OBJECT_PATH, &c_object_path,
1057 DBUS_TYPE_UINT32, &num_slots,
1058 DBUS_TYPE_INVALID);
1059 env->ReleaseStringUTFChars(object_path, c_object_path);
1060 return reply ? JNI_TRUE : JNI_FALSE;
1061 }
1062#endif
1063 return JNI_FALSE;
1064}
1065
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001066static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001067 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001068#ifdef HAVE_BLUETOOTH
1069 native_data_t *nat = get_native_data(env, object);
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001070 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1071 struct event_loop_native_data_t *eventLoopNat =
1072 get_EventLoop_native_data(env, eventLoop);
1073
1074 if (nat && eventLoopNat) {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001075 const char *c_path = env->GetStringUTFChars(path, NULL);
1076
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001077 int len = env->GetStringLength(path) + 1;
1078 char *context_path = (char *)calloc(len, sizeof(char));
1079 strlcpy(context_path, c_path, len); // for callback
1080
1081 bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
1082 context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
1083 "Connect",
1084 DBUS_TYPE_INVALID);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001085
1086 env->ReleaseStringUTFChars(path, c_path);
1087 return ret ? JNI_TRUE : JNI_FALSE;
1088 }
1089#endif
1090 return JNI_FALSE;
1091}
1092
1093static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
1094 jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001095 LOGV("%s", __FUNCTION__);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001096#ifdef HAVE_BLUETOOTH
1097 native_data_t *nat = get_native_data(env, object);
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001098 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1099 struct event_loop_native_data_t *eventLoopNat =
1100 get_EventLoop_native_data(env, eventLoop);
1101
1102 if (nat && eventLoopNat) {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001103 const char *c_path = env->GetStringUTFChars(path, NULL);
1104
Jaikumar Ganeshde075032010-07-19 16:28:27 -07001105 int len = env->GetStringLength(path) + 1;
1106 char *context_path = (char *)calloc(len, sizeof(char));
1107 strlcpy(context_path, c_path, len); // for callback
1108
1109 bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
1110 context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
1111 "Disconnect",
1112 DBUS_TYPE_INVALID);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001113
1114 env->ReleaseStringUTFChars(path, c_path);
1115 return ret ? JNI_TRUE : JNI_FALSE;
1116 }
1117#endif
1118 return JNI_FALSE;
1119}
1120
Danica Chang6fdd0c62010-08-11 14:54:43 -07001121static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
1122 jstring src_role, jstring bridge) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001123 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001124#ifdef HAVE_BLUETOOTH
1125 native_data_t *nat = get_native_data(env, object);
1126 if (nat) {
1127 DBusMessage *reply;
1128 const char *c_role = env->GetStringUTFChars(src_role, NULL);
1129 const char *c_bridge = env->GetStringUTFChars(bridge, NULL);
1130 if (value) {
1131 LOGE("setBluetoothTetheringNative true");
1132 reply = dbus_func_args(env, nat->conn,
1133 get_adapter_path(env, object),
1134 DBUS_NETWORKSERVER_IFACE,
1135 "Register",
1136 DBUS_TYPE_STRING, &c_role,
1137 DBUS_TYPE_STRING, &c_bridge,
1138 DBUS_TYPE_INVALID);
1139 } else {
1140 LOGE("setBluetoothTetheringNative false");
1141 reply = dbus_func_args(env, nat->conn,
1142 get_adapter_path(env, object),
1143 DBUS_NETWORKSERVER_IFACE,
1144 "Unregister",
1145 DBUS_TYPE_STRING, &c_role,
1146 DBUS_TYPE_INVALID);
1147 }
1148 env->ReleaseStringUTFChars(src_role, c_role);
1149 env->ReleaseStringUTFChars(bridge, c_bridge);
1150 return reply ? JNI_TRUE : JNI_FALSE;
1151 }
1152#endif
1153 return JNI_FALSE;
1154}
1155
1156static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
Jaikumar Ganeshb7ec3e12010-12-16 18:02:29 -08001157 jstring dstRole) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001158 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001159#ifdef HAVE_BLUETOOTH
1160 LOGE("connectPanDeviceNative");
1161 native_data_t *nat = get_native_data(env, object);
1162 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1163 struct event_loop_native_data_t *eventLoopNat =
1164 get_EventLoop_native_data(env, eventLoop);
1165
1166 if (nat && eventLoopNat) {
1167 const char *c_path = env->GetStringUTFChars(path, NULL);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001168 const char *dst = env->GetStringUTFChars(dstRole, NULL);
1169
1170 int len = env->GetStringLength(path) + 1;
1171 char *context_path = (char *)calloc(len, sizeof(char));
1172 strlcpy(context_path, c_path, len); // for callback
1173
1174 bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
1175 context_path, eventLoopNat, c_path,
1176 DBUS_NETWORK_IFACE, "Connect",
Danica Chang6fdd0c62010-08-11 14:54:43 -07001177 DBUS_TYPE_STRING, &dst,
1178 DBUS_TYPE_INVALID);
1179
1180 env->ReleaseStringUTFChars(path, c_path);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001181 env->ReleaseStringUTFChars(dstRole, dst);
1182 return ret ? JNI_TRUE : JNI_FALSE;
1183 }
1184#endif
1185 return JNI_FALSE;
1186}
1187
1188static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
1189 jstring path) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001190 LOGV("%s", __FUNCTION__);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001191#ifdef HAVE_BLUETOOTH
1192 LOGE("disconnectPanDeviceNative");
1193 native_data_t *nat = get_native_data(env, object);
1194 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1195 struct event_loop_native_data_t *eventLoopNat =
1196 get_EventLoop_native_data(env, eventLoop);
1197
1198 if (nat && eventLoopNat) {
1199 const char *c_path = env->GetStringUTFChars(path, NULL);
1200
1201 int len = env->GetStringLength(path) + 1;
1202 char *context_path = (char *)calloc(len, sizeof(char));
1203 strlcpy(context_path, c_path, len); // for callback
1204
1205 bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
1206 context_path, eventLoopNat, c_path,
1207 DBUS_NETWORK_IFACE, "Disconnect",
1208 DBUS_TYPE_INVALID);
1209
1210 env->ReleaseStringUTFChars(path, c_path);
1211 return ret ? JNI_TRUE : JNI_FALSE;
1212 }
1213#endif
1214 return JNI_FALSE;
1215}
1216
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001217static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
1218 jstring path, jstring address,
1219 jstring iface) {
Jaikumar Ganesh2653a1e2011-02-22 10:53:29 -08001220 LOGV("%s", __FUNCTION__);
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001221#ifdef HAVE_BLUETOOTH
1222 LOGE("disconnectPanServerDeviceNative");
1223 native_data_t *nat = get_native_data(env, object);
1224 jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1225 struct event_loop_native_data_t *eventLoopNat =
1226 get_EventLoop_native_data(env, eventLoop);
1227
1228 if (nat && eventLoopNat) {
1229 const char *c_address = env->GetStringUTFChars(address, NULL);
1230 const char *c_path = env->GetStringUTFChars(path, NULL);
1231 const char *c_iface = env->GetStringUTFChars(iface, NULL);
1232
1233 int len = env->GetStringLength(path) + 1;
1234 char *context_path = (char *)calloc(len, sizeof(char));
1235 strlcpy(context_path, c_path, len); // for callback
1236
1237 bool ret = dbus_func_args_async(env, nat->conn, -1,
1238 onPanDeviceConnectionResult,
1239 context_path, eventLoopNat,
1240 get_adapter_path(env, object),
1241 DBUS_NETWORKSERVER_IFACE,
1242 "DisconnectDevice",
1243 DBUS_TYPE_STRING, &c_address,
1244 DBUS_TYPE_STRING, &c_iface,
1245 DBUS_TYPE_INVALID);
1246
1247 env->ReleaseStringUTFChars(address, c_address);
1248 env->ReleaseStringUTFChars(iface, c_iface);
1249 env->ReleaseStringUTFChars(path, c_path);
1250 return ret ? JNI_TRUE : JNI_FALSE;
1251 }
1252#endif
1253 return JNI_FALSE;
1254}
1255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256static JNINativeMethod sMethods[] = {
1257 /* name, signature, funcPtr */
1258 {"classInitNative", "()V", (void*)classInitNative},
1259 {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001260 {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
1261 {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
1263 {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
1264
1265 {"isEnabledNative", "()I", (void *)isEnabledNative},
1266 {"enableNative", "()I", (void *)enableNative},
1267 {"disableNative", "()I", (void *)disableNative},
1268
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001269 {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
1270 {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
1271 (void *)getDevicePropertiesNative},
1272 {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
1273 (void *)setAdapterPropertyStringNative},
1274 {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
1275 (void *)setAdapterPropertyBooleanNative},
1276 {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
1277 (void *)setAdapterPropertyIntegerNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001279 {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
1280 {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001282 {"readAdapterOutOfBandDataNative", "()[B", (void *)readAdapterOutOfBandDataNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001283 {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001284 {"createPairedDeviceOutOfBandNative", "(Ljava/lang/String;I)Z",
1285 (void *)createPairedDeviceOutOfBandNative},
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001286 {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
1287 {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
1288 {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
1289 (void *)getDeviceServiceChannelNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001291 {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
1292 (void *)setPairingConfirmationNative},
1293 {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001294 {"setRemoteOutOfBandDataNative", "(Ljava/lang/String;[B[BI)Z", (void *)setRemoteOutOfBandDataNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001296 {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
1297 (void *)cancelPairingUserInputNative},
Lixin Yueefa1dd72009-08-31 15:55:13 +08001298 {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
1299 (void *)setDevicePropertyBooleanNative},
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001300 {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
1301 {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
Nick Pelly24bb9b82009-10-02 20:34:18 -07001302 {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
1303 {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
Jaikumar Ganesh84690c82010-12-10 12:48:58 -08001304 {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
1305 {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
Jaikumar Ganeshb7e029d2010-03-09 15:31:24 -08001306 {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001307 // HID functions
1308 {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
1309 {"disconnectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectInputDeviceNative},
Danica Chang6fdd0c62010-08-11 14:54:43 -07001310
1311 {"setBluetoothTetheringNative", "(ZLjava/lang/String;Ljava/lang/String;)Z",
1312 (void *)setBluetoothTetheringNative},
Jaikumar Ganeshb7ec3e12010-12-16 18:02:29 -08001313 {"connectPanDeviceNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
Danica Chang6fdd0c62010-08-11 14:54:43 -07001314 (void *)connectPanDeviceNative},
1315 {"disconnectPanDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectPanDeviceNative},
Jaikumar Ganesha44a1e72011-02-11 12:40:44 -08001316 {"disconnectPanServerDeviceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
1317 (void *)disconnectPanServerDeviceNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318};
1319
Danica Chang6fdd0c62010-08-11 14:54:43 -07001320
Nick Pellybd022f42009-08-14 18:33:38 -07001321int register_android_server_BluetoothService(JNIEnv *env) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 return AndroidRuntime::registerNativeMethods(env,
Nick Pellybd022f42009-08-14 18:33:38 -07001323 "android/server/BluetoothService", sMethods, NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324}
1325
1326} /* namespace android */