1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
23 #include <android/log.h>
25 #include "caleutils.h"
27 #include "cathreadpool.h"
28 #include "uarraylist.h"
29 #include "caadapterutils.h"
31 #define TAG PCF("OIC_CA_LE_UTILS")
33 jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
35 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
36 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
38 jclass jni_cid_UUID = (*env)->FindClass(env, "java/util/UUID");
41 OIC_LOG(ERROR, TAG, "jni_cid_UUID is not available");
45 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
46 "(Ljava/lang/String;)"
48 if (!jni_mid_fromString)
50 OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
54 jstring str_uuid = (*env)->NewStringUTF(env, uuid);
57 OIC_LOG(ERROR, TAG, "str_uuid is not available");
61 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_UUID, jni_mid_fromString,
65 OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
72 CACheckJNIException(env);
76 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
78 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
79 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
81 jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
82 if (!jni_cid_ParcelUuid)
84 OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
88 jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
89 "(Ljava/util/UUID;)V");
90 if (!jni_mid_ParcelUuid)
92 OIC_LOG(ERROR, TAG, "jni_mid_ParcelUuid is not available");
96 jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
99 OIC_LOG(ERROR, TAG, "Fail to get jni ParcelUuid");
103 return jni_ParcelUuid;
105 CACheckJNIException(env);
109 jobject CALEGetParcelUuidFromString(JNIEnv *env, const char* uuid)
111 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
112 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
114 jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
115 if (!jni_cid_ParcelUuid)
117 OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
121 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_ParcelUuid,
123 "(Ljava/lang/String;)"
124 "Landroid/os/ParcelUuid;");
125 if (!jni_mid_fromString)
127 OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
131 jstring str_uuid = (*env)->NewStringUTF(env, uuid);
134 OIC_LOG(ERROR, TAG, "str_uuid is not available");
138 jobject jni_obj_parcelUuid = (*env)->CallStaticObjectMethod(env, jni_cid_ParcelUuid,
141 if (!jni_obj_parcelUuid)
143 OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
147 return jni_obj_parcelUuid;
149 CACheckJNIException(env);
153 static int CALEGetIntFromHex(char c)
155 if(c >= '0' && c <= '9')
176 jbyteArray CALEGetManufacturerData(JNIEnv *env, const char* uuid)
178 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
179 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
181 jbyteArray jni_byte_Data = (*env)->NewByteArray(env, 2);
182 uint8_t data_array[2];
184 c1 = CALEGetIntFromHex(uuid[4]);
185 c2 = CALEGetIntFromHex(uuid[5]);
186 c3 = CALEGetIntFromHex(uuid[6]);
187 c4 = CALEGetIntFromHex(uuid[7]);
188 data_array[0] = c1 * 16 + c2;
189 data_array[1] = c3 * 16 + c4;
190 OIC_LOG_V(DEBUG, TAG, "data_array[0]: %d, data_array[1]: %d", data_array[0], data_array[1]);
191 (*env)->SetByteArrayRegion(env, jni_byte_Data, 0, 2, data_array);
192 return jni_byte_Data;
196 bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
198 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
199 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", false);
201 jmethodID jni_mid_getBondState = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
204 if (!jni_mid_getBondState)
206 OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
210 jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
211 CACheckJNIException(env);
212 OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
214 if (BOND_BONDED == jni_bondState)
216 OIC_LOG(DEBUG, TAG, "remote device is bonded");
221 OIC_LOG(DEBUG, TAG, "remote device is not bonded");
228 jobjectArray CALEGetBondedDevices(JNIEnv *env)
230 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
232 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
233 if (!jni_cid_BTAdapter)
235 OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
239 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
241 METHODID_OBJECTNONPARAM);
242 CACheckJNIException(env);
243 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
244 jni_mid_getDefaultAdapter);
245 if (!jni_obj_BTAdapter)
247 OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
251 // Get a list of currently paired devices
252 jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
254 "()Ljava/util/Set;");
255 if (!jni_mid_getBondedDevices)
257 OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
261 jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
262 jni_mid_getBondedDevices);
263 if (!jni_obj_setPairedDevices)
265 OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
269 jmethodID jni_mid_toArray = CAGetJNIMethodID(env, "java/util/Set", "toArray",
270 "()[Ljava/lang/Object;");
271 if (!jni_mid_toArray)
273 OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_toArray is null");
277 jobjectArray jni_arrayPairedDevices = (jobjectArray)(
278 (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
279 if (!jni_arrayPairedDevices)
281 OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
285 return jni_arrayPairedDevices;
288 CACheckJNIException(env);
292 jint CALEGetBTStateOnInfo(JNIEnv *env)
294 VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
296 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
297 if (!jni_cid_BTAdapter)
299 OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
300 CACheckJNIException(env);
304 jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
305 if (!jni_fid_stateon)
307 OIC_LOG(ERROR, TAG, "get_field_state is not available");
308 CACheckJNIException(env);
312 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
313 CACheckJNIException(env);
314 OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
319 CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level)
321 jint jni_int_sdk = CALEGetBuildVersion(env);
322 if (jni_int_sdk < level)
324 OIC_LOG(ERROR, TAG, "it is not supported");
325 return CA_NOT_SUPPORTED;
331 jint CALEGetBuildVersion(JNIEnv *env)
333 VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
335 // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
336 jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION");
337 if (!jni_cls_version)
339 OIC_LOG(ERROR, TAG, "jni_cls_version is null");
340 CACheckJNIException(env);
344 jfieldID jni_fid_sdk = (*env)->GetStaticFieldID(env, jni_cls_version, "SDK_INT", "I");
347 OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
348 CACheckJNIException(env);
352 jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
353 CACheckJNIException(env);
354 OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
359 jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
361 VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
362 VERIFY_NON_NULL_RET(versionName, TAG, "versionName is null", -1);
364 // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
365 jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION_CODES");
366 if (!jni_cls_version)
368 OIC_LOG(ERROR, TAG, "jni_cls_version is null");
369 CACheckJNIException(env);
373 jfieldID jni_fid_version = (*env)->GetStaticFieldID(env, jni_cls_version, versionName, "I");
374 if (!jni_fid_version)
376 OIC_LOG(ERROR, TAG, "jni_fid_version is null");
377 CACheckJNIException(env);
381 jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
382 CACheckJNIException(env);
383 OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
385 return jni_int_version;
388 jboolean CALEIsEnableBTAdapter(JNIEnv *env)
390 VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
392 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
393 if (!jni_cid_BTAdapter)
395 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
396 CACheckJNIException(env);
400 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
402 METHODID_OBJECTNONPARAM);
403 if (!jni_mid_getDefaultAdapter)
405 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
406 CACheckJNIException(env);
407 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
411 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
412 jni_mid_getDefaultAdapter);
413 if (!jni_obj_BTAdapter)
415 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
416 CACheckJNIException(env);
417 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
422 jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z");
423 if (!jni_mid_isEnable)
425 OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
426 CACheckJNIException(env);
427 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
428 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
432 jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
433 CACheckJNIException(env);
434 OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
436 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
437 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
441 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
443 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
444 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
446 jmethodID jni_mid_getAddress = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
448 "()Ljava/lang/String;");
449 if (!jni_mid_getAddress)
451 OIC_LOG(ERROR, TAG, "jni_mid_getAddress is null");
455 jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice,
459 OIC_LOG(ERROR, TAG, "jni_address is null");
460 CACheckJNIException(env);
467 jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
469 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
470 VERIFY_NON_NULL_RET(classType, TAG, "classType", -1);
471 VERIFY_NON_NULL_RET(name, TAG, "name", -1);
473 jclass jni_cid = (*env)->FindClass(env, classType);
476 OIC_LOG(ERROR, TAG, "jni_cid is null");
477 CACheckJNIException(env);
481 jfieldID jni_fieldID = (*env)->GetStaticFieldID(env, jni_cid,
485 OIC_LOG(ERROR, TAG, "jni_fieldID is null");
486 CACheckJNIException(env);
490 jint jni_id = (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
491 CACheckJNIException(env);
495 jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
497 OIC_LOG(DEBUG, TAG, "CALEGetRemoteDevice");
499 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
500 VERIFY_NON_NULL_RET(address, TAG, "address is null", NULL);
502 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
503 if (!jni_cid_BTAdapter)
505 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
509 // get remote bt adapter method
510 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
512 METHODID_OBJECTNONPARAM);
513 if (!jni_mid_getDefaultAdapter)
515 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
519 // gat bt adapter object
520 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
521 jni_mid_getDefaultAdapter);
522 if (!jni_obj_BTAdapter)
524 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
528 jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
530 METHODID_BT_REMOTE_DEVICE);
531 if (!jni_mid_getRemoteDevice)
533 OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null");
537 jobject jni_obj_device = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
538 jni_mid_getRemoteDevice,
542 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
545 return jni_obj_device;
548 CACheckJNIException(env);
552 jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
554 OIC_LOG(DEBUG, TAG, "CALEGetAddressFromGatt");
556 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
557 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
559 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
561 if (!jni_mid_getDevice)
563 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
567 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
570 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
571 CACheckJNIException(env);
575 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
578 OIC_LOG(ERROR, TAG, "jni_address is null");
585 bool CALEAttachCurrentThread(JNIEnv **env, JavaVM *g_jvm, bool *attach_status)
587 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) env, JNI_VERSION_1_6);
590 res = (*g_jvm)->AttachCurrentThread(g_jvm, env, NULL);
594 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
597 *attach_status = true;