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