replace : iotivity -> iotivity-sec
[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 jobject CALEGetParcelUuidFromString(JNIEnv *env, const char* uuid)
110 {
111     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
112     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
113
114     jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
115     if (!jni_cid_ParcelUuid)
116     {
117         OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
118         goto error_exit;
119     }
120
121     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_ParcelUuid,
122                                                              "fromString",
123                                                              "(Ljava/lang/String;)"
124                                                              "Landroid/os/ParcelUuid;");
125     if (!jni_mid_fromString)
126     {
127         OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
128         goto error_exit;
129     }
130
131     jstring str_uuid = (*env)->NewStringUTF(env, uuid);
132     if (!str_uuid)
133     {
134         OIC_LOG(ERROR, TAG, "str_uuid is not available");
135         goto error_exit;
136     }
137
138     jobject jni_obj_parcelUuid = (*env)->CallStaticObjectMethod(env, jni_cid_ParcelUuid,
139                                                                 jni_mid_fromString,
140                                                                 str_uuid);
141     if (!jni_obj_parcelUuid)
142     {
143         OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
144         goto error_exit;
145     }
146
147     return jni_obj_parcelUuid;
148 error_exit:
149     CACheckJNIException(env);
150     return NULL;
151 }
152
153 bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
154 {
155     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
156     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", false);
157
158     jmethodID jni_mid_getBondState = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
159                                                       "getBondState",
160                                                       "()I");
161     if (!jni_mid_getBondState)
162     {
163         OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
164         return false;
165     }
166
167     jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
168     CACheckJNIException(env);
169     OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
170
171     if (BOND_BONDED == jni_bondState)
172     {
173         OIC_LOG(DEBUG, TAG, "remote device is bonded");
174         return true;
175     }
176     else
177     {
178         OIC_LOG(DEBUG, TAG, "remote device is not bonded");
179         return false;
180     }
181
182     return false;
183 }
184
185 jobjectArray CALEGetBondedDevices(JNIEnv *env)
186 {
187     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
188
189     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
190     if (!jni_cid_BTAdapter)
191     {
192         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
193         goto error_exit;
194     }
195
196     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
197                                                                     "getDefaultAdapter",
198                                                                     METHODID_OBJECTNONPARAM);
199     CACheckJNIException(env);
200     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
201                                                                jni_mid_getDefaultAdapter);
202     if (!jni_obj_BTAdapter)
203     {
204         OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
205         goto error_exit;
206     }
207
208     // Get a list of currently paired devices
209     jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
210                                                              "getBondedDevices",
211                                                              "()Ljava/util/Set;");
212     if (!jni_mid_getBondedDevices)
213     {
214         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
215         goto error_exit;
216     }
217
218     jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
219                                                                 jni_mid_getBondedDevices);
220     if (!jni_obj_setPairedDevices)
221     {
222         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
223         goto error_exit;
224     }
225
226     jmethodID jni_mid_toArray = CAGetJNIMethodID(env, "java/util/Set", "toArray",
227                                                  "()[Ljava/lang/Object;");
228     if (!jni_mid_toArray)
229     {
230         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_toArray is null");
231         return NULL;
232     }
233
234     jobjectArray jni_arrayPairedDevices = (jobjectArray)(
235             (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
236     if (!jni_arrayPairedDevices)
237     {
238         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
239         goto error_exit;
240     }
241
242     return jni_arrayPairedDevices;
243
244 error_exit:
245     CACheckJNIException(env);
246     return NULL;
247 }
248
249 jint CALEGetBTStateOnInfo(JNIEnv *env)
250 {
251     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
252
253     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
254     if (!jni_cid_BTAdapter)
255     {
256         OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
257         CACheckJNIException(env);
258         return -1;
259     }
260
261     jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
262     if (!jni_fid_stateon)
263     {
264         OIC_LOG(ERROR, TAG, "get_field_state is not available");
265         CACheckJNIException(env);
266         return -1;
267     }
268
269     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
270     CACheckJNIException(env);
271     OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
272
273     return jni_int_val;
274 }
275
276 CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level)
277 {
278     jint jni_int_sdk = CALEGetBuildVersion(env);
279     if (jni_int_sdk < level)
280     {
281         OIC_LOG(ERROR, TAG, "it is not supported");
282         return CA_NOT_SUPPORTED;
283     }
284
285     return CA_STATUS_OK;
286 }
287
288 jint CALEGetBuildVersion(JNIEnv *env)
289 {
290     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
291
292     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
293     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION");
294     if (!jni_cls_version)
295     {
296         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
297         CACheckJNIException(env);
298         return -1;
299     }
300
301     jfieldID jni_fid_sdk = (*env)->GetStaticFieldID(env, jni_cls_version, "SDK_INT", "I");
302     if (!jni_fid_sdk)
303     {
304         OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
305         CACheckJNIException(env);
306         return -1;
307     }
308
309     jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
310     CACheckJNIException(env);
311     OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
312
313     return jni_int_sdk;
314 }
315
316 jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
317 {
318     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
319     VERIFY_NON_NULL_RET(versionName, TAG, "versionName is null", -1);
320
321     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
322     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION_CODES");
323     if (!jni_cls_version)
324     {
325         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
326         CACheckJNIException(env);
327         return -1;
328     }
329
330     jfieldID jni_fid_version = (*env)->GetStaticFieldID(env, jni_cls_version, versionName, "I");
331     if (!jni_fid_version)
332     {
333         OIC_LOG(ERROR, TAG, "jni_fid_version is null");
334         CACheckJNIException(env);
335         return -1;
336     }
337
338     jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
339     CACheckJNIException(env);
340     OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
341
342     return jni_int_version;
343 }
344
345 jboolean CALEIsEnableBTAdapter(JNIEnv *env)
346 {
347     VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
348
349     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
350     if (!jni_cid_BTAdapter)
351     {
352         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
353         CACheckJNIException(env);
354         return JNI_FALSE;
355     }
356
357     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
358                                                                     "getDefaultAdapter",
359                                                                     METHODID_OBJECTNONPARAM);
360     if (!jni_mid_getDefaultAdapter)
361     {
362         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
363         CACheckJNIException(env);
364         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
365         return JNI_FALSE;
366     }
367
368     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
369                                                                jni_mid_getDefaultAdapter);
370     if (!jni_obj_BTAdapter)
371     {
372         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
373         CACheckJNIException(env);
374         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
375         return JNI_FALSE;
376     }
377
378     // isEnable()
379     jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z");
380     if (!jni_mid_isEnable)
381     {
382         OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
383         CACheckJNIException(env);
384         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
385         (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
386         return JNI_FALSE;
387     }
388
389     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
390     CACheckJNIException(env);
391     OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
392
393     (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
394     (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
395     return jni_isEnable;
396 }
397
398 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
399 {
400     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
401     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
402
403     jmethodID jni_mid_getAddress = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
404                                                     "getAddress",
405                                                     "()Ljava/lang/String;");
406     if (!jni_mid_getAddress)
407     {
408         OIC_LOG(ERROR, TAG, "jni_mid_getAddress is null");
409         return NULL;
410     }
411
412     jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice,
413                                                             jni_mid_getAddress);
414     if (!jni_address)
415     {
416         OIC_LOG(ERROR, TAG, "jni_address is null");
417         CACheckJNIException(env);
418         return NULL;
419     }
420
421     return jni_address;
422 }
423
424 jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
425 {
426     VERIFY_NON_NULL_RET(env, TAG, "env", -1);
427     VERIFY_NON_NULL_RET(classType, TAG, "classType", -1);
428     VERIFY_NON_NULL_RET(name, TAG, "name", -1);
429
430     jclass jni_cid = (*env)->FindClass(env, classType);
431     if (!jni_cid)
432     {
433         OIC_LOG(ERROR, TAG, "jni_cid is null");
434         CACheckJNIException(env);
435         return -1;
436     }
437
438     jfieldID jni_fieldID = (*env)->GetStaticFieldID(env, jni_cid,
439                                                     name, "I");
440     if (!jni_fieldID)
441     {
442         OIC_LOG(ERROR, TAG, "jni_fieldID is null");
443         CACheckJNIException(env);
444         return -1;
445     }
446
447     jint jni_id = (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
448     CACheckJNIException(env);
449     return jni_id;
450 }
451
452 jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
453 {
454     OIC_LOG(DEBUG, TAG, "CALEGetRemoteDevice");
455
456     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
457     VERIFY_NON_NULL_RET(address, TAG, "address is null", NULL);
458
459     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
460     if (!jni_cid_BTAdapter)
461     {
462         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
463         goto error_exit;
464     }
465
466     // get remote bt adapter method
467     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
468                                                                     "getDefaultAdapter",
469                                                                     METHODID_OBJECTNONPARAM);
470     if (!jni_mid_getDefaultAdapter)
471     {
472         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
473         goto error_exit;
474     }
475
476     // gat bt adapter object
477     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
478                                                                jni_mid_getDefaultAdapter);
479     if (!jni_obj_BTAdapter)
480     {
481         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
482         goto error_exit;
483     }
484
485     jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
486                                                             "getRemoteDevice",
487                                                             METHODID_BT_REMOTE_DEVICE);
488     if (!jni_mid_getRemoteDevice)
489     {
490         OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null");
491         goto error_exit;
492     }
493
494     jobject jni_obj_device = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
495                                                       jni_mid_getRemoteDevice,
496                                                       address);
497     if (!jni_obj_device)
498     {
499         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
500         goto error_exit;
501     }
502     return jni_obj_device;
503
504 error_exit:
505     CACheckJNIException(env);
506     return NULL;
507 }
508
509 jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
510 {
511     OIC_LOG(DEBUG, TAG, "CALEGetAddressFromGatt");
512
513     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
514     VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
515
516     jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
517                                                    METHODID_BT_DEVICE);
518     if (!jni_mid_getDevice)
519     {
520         OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
521         return NULL;
522     }
523
524     jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
525     if (!jni_obj_device)
526     {
527         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
528         CACheckJNIException(env);
529         return NULL;
530     }
531
532     jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
533     if (!jni_address)
534     {
535         OIC_LOG(ERROR, TAG, "jni_address is null");
536         return NULL;
537     }
538
539     return jni_address;
540 }