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