c72abd8542f0df651e078135250fa103338546b9
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleutils.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 #include <jni.h>
22 #include <stdio.h>
23 #include <android/log.h>
24
25 #include "caleutils.h"
26 #include "logger.h"
27 #include "cathreadpool.h"
28 #include "uarraylist.h"
29 #include "caadapterutils.h"
30
31 #define TAG PCF("OIC_CA_LE_UTILS")
32
33 jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
34 {
35     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
36     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
37
38     jclass jni_cid_UUID = (*env)->FindClass(env, "java/util/UUID");
39     if (!jni_cid_UUID)
40     {
41         OIC_LOG(ERROR, TAG, "jni_cid_UUID is not available");
42         goto error_exit;
43     }
44
45     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
46                                                              "(Ljava/lang/String;)"
47                                                              "Ljava/util/UUID;");
48     if (!jni_mid_fromString)
49     {
50         OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
51         goto error_exit;
52     }
53
54     jstring str_uuid = (*env)->NewStringUTF(env, uuid);
55     if (!str_uuid)
56     {
57         OIC_LOG(ERROR, TAG, "str_uuid is not available");
58         goto error_exit;
59     }
60
61     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_UUID, jni_mid_fromString,
62                                                           str_uuid);
63     if (!jni_obj_uuid)
64     {
65         OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
66         goto error_exit;
67     }
68
69     return jni_obj_uuid;
70
71 error_exit:
72     CACheckJNIException(env);
73     return NULL;
74 }
75
76 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
77 {
78     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
79     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
80
81     jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
82     if (!jni_cid_ParcelUuid)
83     {
84         OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
85         goto error_exit;
86     }
87
88     jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
89                                                        "(Ljava/util/UUID;)V");
90     if (!jni_mid_ParcelUuid)
91     {
92         OIC_LOG(ERROR, TAG, "jni_mid_ParcelUuid is not available");
93         goto error_exit;
94     }
95
96     jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
97     if (!jni_ParcelUuid)
98     {
99         OIC_LOG(ERROR, TAG, "Fail to get jni ParcelUuid");
100         goto error_exit;
101     }
102
103     return jni_ParcelUuid;
104 error_exit:
105     CACheckJNIException(env);
106     return NULL;
107 }
108
109 bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
110 {
111     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
112     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", false);
113
114     jmethodID jni_mid_getBondState = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
115                                                       "getBondState",
116                                                       "()I");
117     if (!jni_mid_getBondState)
118     {
119         OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
120         return false;
121     }
122
123     jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
124     CACheckJNIException(env);
125     OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
126
127     if (BOND_BONDED == jni_bondState)
128     {
129         OIC_LOG(DEBUG, TAG, "remote device is bonded");
130         return true;
131     }
132     else
133     {
134         OIC_LOG(DEBUG, TAG, "remote device is not bonded");
135         return false;
136     }
137 }
138
139 jobjectArray CALEGetBondedDevices(JNIEnv *env)
140 {
141     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
142
143     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
144     if (!jni_cid_BTAdapter)
145     {
146         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
147         goto error_exit;
148     }
149
150     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
151                                                                     "getDefaultAdapter",
152                                                                     METHODID_OBJECTNONPARAM);
153     CACheckJNIException(env);
154     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
155                                                                jni_mid_getDefaultAdapter);
156     if (!jni_obj_BTAdapter)
157     {
158         OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
159         goto error_exit;
160     }
161
162     // Get a list of currently paired devices
163     jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
164                                                              "getBondedDevices",
165                                                              "()Ljava/util/Set;");
166     if (!jni_mid_getBondedDevices)
167     {
168         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
169         goto error_exit;
170     }
171
172     jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
173                                                                 jni_mid_getBondedDevices);
174     if (!jni_obj_setPairedDevices)
175     {
176         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
177         goto error_exit;
178     }
179
180     jmethodID jni_mid_toArray = CAGetJNIMethodID(env, "java/util/Set", "toArray",
181                                                  "()[Ljava/lang/Object;");
182     if (!jni_mid_toArray)
183     {
184         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_toArray is null");
185         return NULL;
186     }
187
188     jobjectArray jni_arrayPairedDevices = (jobjectArray)(
189             (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
190     if (!jni_arrayPairedDevices)
191     {
192         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
193         goto error_exit;
194     }
195
196     return jni_arrayPairedDevices;
197
198 error_exit:
199     CACheckJNIException(env);
200     return NULL;
201 }
202
203 jint CALEGetBTStateOnInfo(JNIEnv *env)
204 {
205     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
206
207     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
208     if (!jni_cid_BTAdapter)
209     {
210         OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
211         CACheckJNIException(env);
212         return -1;
213     }
214
215     jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
216     if (!jni_fid_stateon)
217     {
218         OIC_LOG(ERROR, TAG, "get_field_state is not available");
219         CACheckJNIException(env);
220         return -1;
221     }
222
223     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
224     CACheckJNIException(env);
225     OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
226
227     return jni_int_val;
228 }
229
230 CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level)
231 {
232     jint jni_int_sdk = CALEGetBuildVersion(env);
233     if (jni_int_sdk < level)
234     {
235         OIC_LOG(ERROR, TAG, "it is not supported");
236         return CA_NOT_SUPPORTED;
237     }
238
239     return CA_STATUS_OK;
240 }
241
242 jint CALEGetBuildVersion(JNIEnv *env)
243 {
244     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
245
246     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
247     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION");
248     if (!jni_cls_version)
249     {
250         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
251         CACheckJNIException(env);
252         return -1;
253     }
254
255     jfieldID jni_fid_sdk = (*env)->GetStaticFieldID(env, jni_cls_version, "SDK_INT", "I");
256     if (!jni_fid_sdk)
257     {
258         OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
259         CACheckJNIException(env);
260         return -1;
261     }
262
263     jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
264     CACheckJNIException(env);
265     OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
266
267     return jni_int_sdk;
268 }
269
270 jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
271 {
272     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
273     VERIFY_NON_NULL_RET(versionName, TAG, "versionName is null", -1);
274
275     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
276     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION_CODES");
277     if (!jni_cls_version)
278     {
279         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
280         CACheckJNIException(env);
281         return -1;
282     }
283
284     jfieldID jni_fid_version = (*env)->GetStaticFieldID(env, jni_cls_version, versionName, "I");
285     if (!jni_fid_version)
286     {
287         OIC_LOG(ERROR, TAG, "jni_fid_version is null");
288         CACheckJNIException(env);
289         return -1;
290     }
291
292     jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
293     CACheckJNIException(env);
294     OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
295
296     return jni_int_version;
297 }
298
299 jboolean CALEIsEnableBTAdapter(JNIEnv *env)
300 {
301     VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
302
303     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
304     if (!jni_cid_BTAdapter)
305     {
306         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
307         CACheckJNIException(env);
308         return JNI_FALSE;
309     }
310
311     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
312                                                                     "getDefaultAdapter",
313                                                                     METHODID_OBJECTNONPARAM);
314     if (!jni_mid_getDefaultAdapter)
315     {
316         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
317         CACheckJNIException(env);
318         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
319         return JNI_FALSE;
320     }
321
322     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
323                                                                jni_mid_getDefaultAdapter);
324     if (!jni_obj_BTAdapter)
325     {
326         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
327         CACheckJNIException(env);
328         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
329         return JNI_FALSE;
330     }
331
332     // isEnable()
333     jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z");
334     if (!jni_mid_isEnable)
335     {
336         OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
337         CACheckJNIException(env);
338         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
339         (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
340         return JNI_FALSE;
341     }
342
343     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
344     CACheckJNIException(env);
345     OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
346
347     (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
348     (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
349     return jni_isEnable;
350 }
351
352 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
353 {
354     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
355     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
356
357     jmethodID jni_mid_getAddress = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
358                                                     "getAddress",
359                                                     "()Ljava/lang/String;");
360     if (!jni_mid_getAddress)
361     {
362         OIC_LOG(ERROR, TAG, "jni_mid_getAddress is null");
363         return NULL;
364     }
365
366     jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice,
367                                                             jni_mid_getAddress);
368     if (!jni_address)
369     {
370         OIC_LOG(ERROR, TAG, "jni_address is null");
371         CACheckJNIException(env);
372         return NULL;
373     }
374
375     return jni_address;
376 }
377
378 jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
379 {
380     VERIFY_NON_NULL_RET(env, TAG, "env", -1);
381     VERIFY_NON_NULL_RET(classType, TAG, "classType", -1);
382     VERIFY_NON_NULL_RET(name, TAG, "name", -1);
383
384     jclass jni_cid = (*env)->FindClass(env, classType);
385     if (!jni_cid)
386     {
387         OIC_LOG(ERROR, TAG, "jni_cid is null");
388         CACheckJNIException(env);
389         return -1;
390     }
391
392     jfieldID jni_fieldID = (*env)->GetStaticFieldID(env, jni_cid,
393                                                     name, "I");
394     if (!jni_fieldID)
395     {
396         OIC_LOG(ERROR, TAG, "jni_fieldID is null");
397         CACheckJNIException(env);
398         return -1;
399     }
400
401     jint jni_id = (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
402     CACheckJNIException(env);
403     return jni_id;
404 }
405
406 jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
407 {
408     OIC_LOG(DEBUG, TAG, "IN - CALEGetRemoteDevice");
409
410     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
411     VERIFY_NON_NULL_RET(address, TAG, "address is null", NULL);
412
413     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
414     if (!jni_cid_BTAdapter)
415     {
416         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
417         goto error_exit;
418     }
419
420     // get remote bt adapter method
421     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
422                                                                     "getDefaultAdapter",
423                                                                     METHODID_OBJECTNONPARAM);
424     if (!jni_mid_getDefaultAdapter)
425     {
426         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
427         goto error_exit;
428     }
429
430     // gat bt adapter object
431     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
432                                                                jni_mid_getDefaultAdapter);
433     if (!jni_obj_BTAdapter)
434     {
435         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
436         goto error_exit;
437     }
438
439     jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
440                                                             "getRemoteDevice",
441                                                             METHODID_BT_REMOTE_DEVICE);
442     if (!jni_mid_getRemoteDevice)
443     {
444         OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null");
445         goto error_exit;
446     }
447
448     jobject jni_obj_device = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
449                                                       jni_mid_getRemoteDevice,
450                                                       address);
451     if (!jni_obj_device)
452     {
453         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
454         goto error_exit;
455     }
456
457     OIC_LOG(DEBUG, TAG, "OUT - CALEGetRemoteDevice");
458     return jni_obj_device;
459
460 error_exit:
461     CACheckJNIException(env);
462     return NULL;
463 }
464
465 jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
466 {
467     OIC_LOG(DEBUG, TAG, "IN - CALEGetAddressFromGatt");
468
469     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
470     VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
471
472     jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
473                                                    METHODID_BT_DEVICE);
474     if (!jni_mid_getDevice)
475     {
476         OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
477         return NULL;
478     }
479
480     jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
481     if (!jni_obj_device)
482     {
483         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
484         CACheckJNIException(env);
485         return NULL;
486     }
487
488     jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
489     if (!jni_address)
490     {
491         OIC_LOG(ERROR, TAG, "jni_address is null");
492         return NULL;
493     }
494
495     OIC_LOG(DEBUG, TAG, "OUT - CALEGetAddressFromGatt");
496     return jni_address;
497 }