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