Imported Upstream version 0.9.1
[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 "oic_malloc.h"
28 #include "cathreadpool.h"
29 #include "uarraylist.h"
30 #include "caadapterutils.h"
31
32 #define TAG PCF("CA_LE_UTILS")
33
34 #define METHODID_OBJECTNONPARAM   "()Landroid/bluetooth/BluetoothAdapter;"
35 #define METHODID_STRINGNONPARAM   "()Ljava/lang/String;"
36 #define CLASSPATH_BT_ADPATER "android/bluetooth/BluetoothAdapter"
37
38 jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
39 {
40     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
41     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
42
43     OIC_LOG(DEBUG, TAG, "CALEGetUuidFromString");
44
45     jclass jni_cid_UUID = (*env)->FindClass(env, "java/util/UUID");
46     if (!jni_cid_UUID)
47     {
48         OIC_LOG(ERROR, TAG, "jni_cid_UUID is not available");
49         return NULL;
50     }
51
52     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
53                                                              "(Ljava/lang/String;)"
54                                                              "Ljava/util/UUID;");
55     if (!jni_mid_fromString)
56     {
57         OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
58         return NULL;
59     }
60
61     jstring str_uuid = (*env)->NewStringUTF(env, uuid);
62     if (!str_uuid)
63     {
64         OIC_LOG(ERROR, TAG, "str_uuid is not available");
65         return NULL;
66     }
67
68     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_UUID, jni_mid_fromString,
69                                                           str_uuid);
70     if (!jni_obj_uuid)
71     {
72         OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
73         return NULL;
74     }
75
76     return jni_obj_uuid;
77 }
78
79 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
80 {
81     OIC_LOG(DEBUG, TAG, "CALEGetParcelUuid");
82     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
83     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
84
85     jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
86     if (!jni_cid_ParcelUuid)
87     {
88         OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
89         return NULL;
90     }
91
92     jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
93                                                        "(Ljava/util/UUID;)V");
94     if (!jni_mid_ParcelUuid)
95     {
96         OIC_LOG(ERROR, TAG, "jni_mid_ParcelUuid is not available");
97         return NULL;
98     }
99
100     jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
101     if (!jni_ParcelUuid)
102     {
103         OIC_LOG(ERROR, TAG, "Fail to get jni ParcelUuid");
104         return NULL;
105     }
106
107     return jni_ParcelUuid;
108 }
109
110 bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
111 {
112     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
113     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", false);
114
115     jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
116     if (!jni_cid_device_list)
117     {
118         OIC_LOG(ERROR, TAG, "jni_cid_device_list is null");
119         return false;
120     }
121
122     jmethodID jni_mid_getBondState = (*env)->GetMethodID(env, jni_cid_device_list, "getBondState",
123                                                          "()I");
124     if (!jni_mid_getBondState)
125     {
126         OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
127         return false;
128     }
129
130     jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
131
132     OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
133
134     if (BOND_BONDED == jni_bondState)
135     {
136         OIC_LOG(DEBUG, TAG, "remote device is bonded");
137         return true;
138     }
139     else
140     {
141         OIC_LOG(DEBUG, TAG, "remote device is not bonded");
142         return false;
143     }
144
145     return false;
146 }
147
148 jobjectArray CALEGetBondedDevices(JNIEnv *env)
149 {
150     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
151
152     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
153     if (!jni_cid_BTAdapter)
154     {
155         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
156         return NULL;
157     }
158
159     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
160                                                                     "getDefaultAdapter",
161                                                                     METHODID_OBJECTNONPARAM);
162
163     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
164                                                                jni_mid_getDefaultAdapter);
165     if (!jni_obj_BTAdapter)
166     {
167         OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
168         return NULL;
169     }
170
171     // Get a list of currently paired devices
172     jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
173                                                              "getBondedDevices",
174                                                              "()Ljava/util/Set;");
175     if (!jni_mid_getBondedDevices)
176     {
177         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
178         return NULL;
179     }
180
181     jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
182                                                                 jni_mid_getBondedDevices);
183     if (!jni_obj_setPairedDevices)
184     {
185         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
186         return NULL;
187     }
188
189     jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
190     if (!jni_cid_Set)
191     {
192         OIC_LOG(ERROR, TAG, "getBondedDevices : jni_cid_Set is null");
193         return NULL;
194     }
195
196     jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray",
197                                                     "()[Ljava/lang/Object;");
198     if (!jni_mid_toArray)
199     {
200         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_toArray is null");
201         return NULL;
202     }
203
204     jobjectArray jni_arrayPairedDevices = (jobjectArray)(
205             (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
206     if (!jni_arrayPairedDevices)
207     {
208         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
209         return NULL;
210     }
211
212     return jni_arrayPairedDevices;
213 }
214
215 jint CALEGetBTStateOnInfo(JNIEnv *env)
216 {
217     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
218
219     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
220     if (!jni_cid_BTAdapter)
221     {
222         OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
223         return -1;
224     }
225
226     jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
227     if (!jni_fid_stateon)
228     {
229         OIC_LOG(ERROR, TAG, "get_field_state is not available");
230         return -1;
231     }
232
233     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
234     OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
235
236     return jni_int_val;
237 }
238
239 CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level)
240 {
241     jint jni_int_sdk = CALEGetBuildVersion(env);
242     if (jni_int_sdk < level)
243     {
244         OIC_LOG(ERROR, TAG, "it is not supported");
245         return CA_NOT_SUPPORTED;
246     }
247
248     return CA_STATUS_OK;
249 }
250
251 jint CALEGetBuildVersion(JNIEnv *env)
252 {
253     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
254
255     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
256     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION");
257     if (!jni_cls_version)
258     {
259         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
260         return -1;
261     }
262
263     jfieldID jni_fid_sdk = (*env)->GetStaticFieldID(env, jni_cls_version, "SDK_INT", "I");
264     if (!jni_fid_sdk)
265     {
266         OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
267         return -1;
268     }
269
270     jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
271     OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
272
273     return jni_int_sdk;
274 }
275
276 jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
277 {
278     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
279     VERIFY_NON_NULL_RET(versionName, TAG, "versionName is null", -1);
280
281     // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
282     jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION_CODES");
283     if (!jni_cls_version)
284     {
285         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
286         return -1;
287     }
288
289     jfieldID jni_fid_version = (*env)->GetStaticFieldID(env, jni_cls_version, versionName, "I");
290     if (!jni_fid_version)
291     {
292         OIC_LOG(ERROR, TAG, "jni_fid_version is null");
293         return -1;
294     }
295
296     jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
297     OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
298
299     return jni_int_version;
300 }
301
302 jboolean CALEIsEnableBTAdapter(JNIEnv *env)
303 {
304     VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
305
306     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
307     if (!jni_cid_BTAdapter)
308     {
309         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
310         return JNI_FALSE;
311     }
312
313     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
314                                                                     "getDefaultAdapter",
315                                                                     METHODID_OBJECTNONPARAM);
316     if (!jni_mid_getDefaultAdapter)
317     {
318         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
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         return JNI_FALSE;
328     }
329
330     // isEnable()
331     jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z");
332     if (!jni_mid_isEnable)
333     {
334         OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
335         return JNI_FALSE;
336     }
337
338     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
339     OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
340
341     return jni_isEnable;
342 }
343
344 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
345 {
346     OIC_LOG(DEBUG, TAG, "IN - CALEGetAddressFromBTDevice");
347     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
348     VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
349
350     jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
351     if (!jni_cid_device_list)
352     {
353         OIC_LOG(ERROR, TAG, "jni_cid_device_list is null");
354         return NULL;
355     }
356
357     jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_device_list, "getAddress",
358                                                        "()Ljava/lang/String;");
359     if (!jni_mid_getAddress)
360     {
361         OIC_LOG(ERROR, TAG, "jni_mid_getAddress is null");
362         return NULL;
363     }
364
365     jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice,
366                                                             jni_mid_getAddress);
367     if (!jni_address)
368     {
369         OIC_LOG(ERROR, TAG, "jni_address is null");
370         return NULL;
371     }
372
373     OIC_LOG(DEBUG, TAG, "OUT - CALEGetAddressFromBTDevice");
374     return jni_address;
375 }