Remove unused pkg dependancy
[platform/upstream/iotivity.git] / resource / csdk / connectivity / util / src / camanager / bt_le_manager / android / caleconnectionmanager.c
1 /* ****************************************************************
2  *
3  * Copyright 2016 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 "logger.h"
23 #include "cautilinterface.h"
24 #include "camanagerleinterface.h"
25 #include "camanagerleutil.h"
26 #include "caleautoconnector.h"
27 #include "cacommon.h"
28 #include "cacommonutil.h"
29 #include "camanagerdevice.h"
30 #include "caleclient.h"
31 #include "caleutils.h"
32
33 #define TAG "OIC_CA_MANAGER_LE"
34
35 static const jint SUPPORT_ADNROID_API_LEVEL = 18;
36 static const jint AUTH_FAIL = 5;
37 static const jint LINK_LOSS = 8;
38 static const jint ACCEPT_TIMEOUT_EXCEPTION = 16;
39 static const jint REMOTE_DISCONNECT = 19;
40 static const jint LOCAL_DISCONNECT = 22;
41 static const jint USER_REMOVED_BOND = 68;
42 static JavaVM *g_jvm = NULL;
43 static jobject g_context = NULL;
44 static jobject g_connectedDeviceSet = NULL;
45
46
47 CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char* address)
48 {
49     OIC_LOG(DEBUG, TAG, "CASetClientAutoConnectionDeviceInfo");
50     VERIFY_NON_NULL(address, TAG, "address");
51
52     bool isAttached = false;
53     JNIEnv* env = NULL;
54     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
55     if (JNI_OK != res)
56     {
57         OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
58         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
59
60         if (JNI_OK != res)
61         {
62             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
63             return CA_STATUS_FAILED;
64         }
65         isAttached = true;
66     }
67     OIC_LOG_V(DEBUG, TAG, "set [%s] for Auto Connection", address);
68
69     jstring jni_leAddress = (*env)->NewStringUTF(env, address);
70     if (!jni_leAddress)
71     {
72         OIC_LOG(ERROR, TAG, "jni_leAddress is null");
73         goto error_exit;
74     }
75
76     if (!CAManagerCheckBTAddress(env, jni_leAddress))
77     {
78         OIC_LOG(ERROR, TAG, "this address is not BT address string format");
79         goto error_exit;
80     }
81
82     // if there is target address in SharedPreference, it will be reset.
83     if (CAManagerIsConnectedDeviceAddress(env, g_context, jni_leAddress, g_connectedDeviceSet))
84     {
85         if (!CAManagerRemoveConnectedDeviceAddress(env, g_context, jni_leAddress,
86                                                    g_connectedDeviceSet))
87         {
88             OIC_LOG(ERROR, TAG, "Preference - remove has failed");
89         }
90         else
91         {
92             OIC_LOG(INFO, TAG, "Preference - remove success");
93         }
94     }
95
96     // it will be added new target address.
97     if (!CAManagerAddConnectedDeviceAddress(env, g_context, jni_leAddress, g_connectedDeviceSet))
98     {
99         OIC_LOG(ERROR, TAG, "Preference - putting has failed");
100     }
101     else
102     {
103         OIC_LOG(INFO, TAG, "Preference - putting success");
104     }
105
106     if (isAttached)
107     {
108         (*g_jvm)->DetachCurrentThread(g_jvm);
109     }
110
111     return CA_STATUS_OK;
112
113 error_exit:
114
115     if (isAttached)
116     {
117         (*g_jvm)->DetachCurrentThread(g_jvm);
118     }
119
120     return CA_STATUS_FAILED;
121 }
122
123 CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char* address)
124 {
125     OIC_LOG(DEBUG, TAG, "CAUnsetClientAutoConnectionDeviceInfo");
126     VERIFY_NON_NULL(address, TAG, "address");
127
128     bool isAttached = false;
129     JNIEnv* env = NULL;
130     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
131     if (JNI_OK != res)
132     {
133         OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
134         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
135
136         if (JNI_OK != res)
137         {
138             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
139             return CA_STATUS_FAILED;
140         }
141         isAttached = true;
142     }
143     OIC_LOG_V(DEBUG, TAG, "unset [%s] for Auto Connection", address);
144
145     jstring jni_leAddress = (*env)->NewStringUTF(env, address);
146     if (!jni_leAddress)
147     {
148         OIC_LOG(ERROR, TAG, "jni_leAddress is null");
149         goto error_exit;
150     }
151
152     if (!CAManagerCheckBTAddress(env, jni_leAddress))
153     {
154         OIC_LOG(ERROR, TAG, "this address is not BT address string format");
155         goto error_exit;
156     }
157
158     // if there is target address in SharedPreference, it will be removed
159     if (CAManagerIsConnectedDeviceAddress(env, g_context, jni_leAddress, g_connectedDeviceSet))
160     {
161         if (!CAManagerRemoveConnectedDeviceAddress(env, g_context, jni_leAddress,
162                                                    g_connectedDeviceSet))
163         {
164             OIC_LOG(ERROR, TAG, "Preference - remove has failed");
165         }
166         else
167         {
168             OIC_LOG(INFO, TAG, "Preference - remove success");
169         }
170     }
171
172     // remove target device for auto connection
173     CAResult_t ret = CAManagerRemoveACData(env, jni_leAddress);
174     if (CA_STATUS_OK != ret)
175     {
176         OIC_LOG(ERROR, TAG, "CAManagerRemoveACData has failed");
177     }
178
179     if (isAttached)
180     {
181         (*g_jvm)->DetachCurrentThread(g_jvm);
182     }
183
184     return ret;
185
186 error_exit:
187
188     if (isAttached)
189     {
190         (*g_jvm)->DetachCurrentThread(g_jvm);
191     }
192
193     return CA_STATUS_FAILED;
194 }
195
196 CAResult_t CAManagerLEClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
197 {
198     OIC_LOG(DEBUG, TAG, "CAManagerClientInitialize");
199     VERIFY_NON_NULL(env, TAG, "env");
200     VERIFY_NON_NULL(jvm, TAG, "jvm");
201     VERIFY_NON_NULL(context, TAG, "context");
202
203     jint jni_int_sdk = CALEGetBuildVersion(env);
204     if (jni_int_sdk < SUPPORT_ADNROID_API_LEVEL)
205     {
206         OIC_LOG_V(ERROR, TAG, "it is not supported (%d)", jni_int_sdk);
207         return CA_STATUS_FAILED;
208     }
209
210     g_jvm = jvm;
211     g_context = (*env)->NewGlobalRef(env, context);;
212
213     CAManagerInitMutexVaraibles();
214     CAManagerInitLEAutoConnection();
215     CAManagerCreateACDataList();
216
217     // get last connected device list
218     jobject set = NULL;
219     set = CAManagerGetConnectedDeviceAddress(env, g_context);
220     if (!set)
221     {
222         // create new set<String> object
223         set = CAManagerCreateSetString(env);
224         if (!set)
225         {
226             OIC_LOG(ERROR, TAG, "CAManagerCreateSetString has failed");
227             return CA_STATUS_FAILED;
228         }
229         OIC_LOG(DEBUG, TAG, "created new SetString");
230     }
231     else
232     {
233         OIC_LOG(DEBUG, TAG, "get previous Set<String> object");
234     }
235
236     g_connectedDeviceSet = (jobject)(*env)->NewGlobalRef(env, set);
237     if (!g_connectedDeviceSet)
238     {
239         OIC_LOG(ERROR, TAG, "g_connectedDeviceSet is null");
240         return CA_STATUS_FAILED;
241     }
242
243     return CA_STATUS_OK;
244 }
245
246 CAResult_t CAManagerLEClientTerminate(JNIEnv *env)
247 {
248     OIC_LOG(DEBUG, TAG, "CAManagerClientTerminate");
249     VERIFY_NON_NULL(env, TAG, "env");
250
251     // stop gatt connection
252     CAResult_t res = CALEClientDisconnectAll(env);
253     if (CA_STATUS_OK != res)
254     {
255         OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
256     }
257
258     res = CAManagerRemoveAllACData(env);
259     if (CA_STATUS_OK != res)
260     {
261         OIC_LOG(ERROR, TAG, "CAManagerRemoveAllACData has failed");
262     }
263
264     CAManagerDestroyACDataList();
265     CAManagerTerminateLEAutoConnection();
266     CAManagerTerminateMutexVariables();
267
268     if (g_context)
269     {
270         (*env)->DeleteGlobalRef(env, g_context);
271         g_context = NULL;
272     }
273
274     if (g_connectedDeviceSet)
275     {
276         (*env)->DeleteGlobalRef(env, g_connectedDeviceSet);
277         g_connectedDeviceSet = NULL;
278     }
279
280     return res;
281 }
282
283 void CAManagerLESetScanInterval(jint interval, jint count)
284 {
285     OIC_LOG(DEBUG, TAG, "CAManagerLESetScanInterval");
286     CALERestartScanWithInterval(interval, count, BLE_SCAN_ENABLE);
287 }
288
289 void CAManagerLEStopScan()
290 {
291     OIC_LOG(DEBUG, TAG, "CAManagerLEStopScan");
292     CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
293 }
294
295 void CAManagerSetConfigure(CAUtilConfig_t config)
296 {
297     OIC_LOG_V(INFO, TAG, "set configure for bleFlags : %d", config.bleFlags);
298     caglobals.bleFlags = config.bleFlags;
299 }
300
301 CAResult_t CAManagerLEStartAdvertising()
302 {
303     CAResult_t ret = CALEServerStartAdvertise();
304     if (CA_STATUS_OK != ret)
305     {
306         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
307     }
308     return ret;
309 }
310
311 CAResult_t CAManagerLEStopAdvertising()
312 {
313     CAResult_t ret = CALEServerStopAdvertise();
314     if (CA_STATUS_OK != ret)
315     {
316         OIC_LOG(ERROR, TAG, "CAManagerLEStopAdvertising has failed");
317     }
318     return ret;
319 }
320
321 JNIEXPORT void JNICALL
322 Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback(
323         JNIEnv *env, jobject obj, jint state)
324 {
325     OIC_LOG_V(INFO, TAG, "caManagerAdapterStateChangedCallback - state %d", state);
326     VERIFY_NON_NULL_VOID(env, TAG, "env");
327     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
328
329     jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
330     jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
331     jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
332
333     if (state_on == state)
334     {
335         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_on");
336
337         // when BT state is on. recovery flag has to be reset.
338         CAManagerSetBTRecovery(false);
339
340         // find target device for autoconnect
341         size_t length = CAManagerGetACDataLength();
342         OIC_LOG_V(DEBUG, TAG, "length of ACDataList : %d", length);
343         for (size_t idx = 0; idx < length; idx++)
344         {
345             jstring leAddress = CAManagerGetLEAddressFromACData(env, idx);
346             if (leAddress)
347             {
348                 CAResult_t res = CAManagerStartAutoConnection(env, leAddress);
349                 if (CA_STATUS_OK != res)
350                 {
351                     OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
352                     return;
353                 }
354             }
355         }
356     }
357     else if (state_off == state)
358     {
359         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_off");
360
361         // reset isAutoConnecting flag for all target devices
362         size_t length = CAManagerGetACDataLength();
363         OIC_LOG_V(DEBUG, TAG, "length of ACDataList : %d", length);
364         for (size_t idx = 0; idx < length; idx++)
365         {
366             jstring address = CAManagerGetLEAddressFromACData(env, idx);
367             if (address)
368             {
369                 CAManagerSetAutoConnectingFlag(env, address, false);
370             }
371         }
372
373         // check whether BT recovery is needed or not
374         if (CAManagerIsRecoveryFlagSet())
375         {
376             CAManagerProcessRecovery(env, STATE_OFF);
377         }
378     }
379     else if (state_turning_off == state)
380     {
381         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_turning_off");
382     }
383     else
384     {
385         OIC_LOG(INFO, TAG, "AdapterStateChangedCallback state is not available");
386     }
387 }
388
389 JNIEXPORT void JNICALL
390 Java_org_iotivity_ca_CaLeClientInterface_caManagerBondStateChangedCallback(
391         JNIEnv *env, jobject obj, jobject device)
392 {
393     OIC_LOG(INFO, TAG, "caManagerBondStateChangedCallback");
394     // this callback is called by CaLeClientInterface
395     // only when bond state is changed from BOND_BONDED to BOND_NONE
396     OIC_LOG(DEBUG, TAG, "bond state is changed from BOND_BONDED to BOND_NONE");
397     VERIFY_NON_NULL_VOID(env, TAG, "env");
398     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
399     VERIFY_NON_NULL_VOID(device, TAG, "device");
400
401     // get ble address from Bluetooth Device object
402     jstring jni_leAddress = CALEClientGetLEAddressFromBTDevice(env, device);
403     if (!jni_leAddress)
404     {
405         OIC_LOG(INFO, TAG, "unbonded : it isn't same device type");
406         return;
407     }
408
409     char* leAddress = (char*)(*env)->GetStringUTFChars(env, jni_leAddress, NULL);
410     if (!leAddress)
411     {
412         OIC_LOG(ERROR, TAG, "leAddress is null");
413         return;
414     }
415
416     // if there is no data, CAData will be created.
417     OIC_LOG_V(DEBUG, TAG, "bond none device : %s", leAddress);
418
419     CAResult_t res = CAManagerRemoveACData(env, jni_leAddress);
420     if (CA_STATUS_OK != res)
421     {
422         OIC_LOG(ERROR, TAG, "CAManagerRemoveACData has failed");
423     }
424
425     (*env)->ReleaseStringUTFChars(env, jni_leAddress, leAddress);
426
427     if (!CAManagerRemoveConnectedDeviceAddress(env, g_context, jni_leAddress,
428                                                g_connectedDeviceSet))
429     {
430         OIC_LOG(ERROR, TAG, "CAManagerRemoveConnectedDeviceAddress has failed");
431     }
432 }
433
434 JNIEXPORT void JNICALL
435 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
436         JNIEnv *env, jobject obj, jobject gatt, jint status, jint newState)
437 {
438     VERIFY_NON_NULL_VOID(env, TAG, "env");
439     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
440     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
441
442     jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
443     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
444
445     jstring jni_address = CALEGetAddressFromGatt(env, gatt);
446     if (!jni_address)
447     {
448         OIC_LOG(ERROR, TAG, "CALEGetAddressFromGatt is null");
449         return;
450     }
451
452     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
453     if (!address)
454     {
455         OIC_LOG(ERROR, TAG, "address is null");
456         (*env)->DeleteLocalRef(env, jni_address);
457         return;
458     }
459
460     if (GATT_SUCCESS == status && state_connected == newState) // le connected
461     {
462         CAResult_t res = CAManagerReadRemoteRssi(env, gatt);
463         if (CA_STATUS_OK != res)
464         {
465             OIC_LOG(ERROR, TAG, "CAManagerReadRemoteRssi has failed");
466             goto exit;
467         }
468     }
469     else if (state_disconnected == newState)// le disconnected
470     {
471         if (LINK_LOSS == status || REMOTE_DISCONNECT == status)
472         {
473             if (!CAManagerIsInACDataList(env, jni_address))
474             {
475                 OIC_LOG_V(DEBUG, TAG, "this[%s] is not target address for Auto Connection",
476                           address);
477                 goto exit;
478             }
479
480             CAManagerSetAutoConnectingFlag(env, jni_address, false);
481
482             CAResult_t res = CAManagerStartAutoConnection(env, jni_address);
483             if (CA_STATUS_OK != res)
484             {
485                 OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
486                 goto exit;
487             }
488         }
489         else if (ACCEPT_TIMEOUT_EXCEPTION == status)
490         {
491             CAManagerProcessRecovery(env, START_RECOVERY);
492         }
493     }
494
495 exit:
496     (*env)->ReleaseStringUTFChars(env, jni_address, address);
497     (*env)->DeleteLocalRef(env, jni_address);
498 }
499
500 /*
501  * Class:     org_iotivity_ca_jar_caleinterface
502  * Method:    caManagerLeServicesDiscoveredCallback
503  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
504  */
505 JNIEXPORT void JNICALL
506 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(JNIEnv *env,
507                                                                                jobject obj,
508                                                                                jobject gatt,
509                                                                                jint status)
510 {
511     VERIFY_NON_NULL_VOID(env, TAG, "env");
512     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
513     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
514
515     if (GATT_SUCCESS == status)
516     {
517         if (!g_connectedDeviceSet)
518         {
519             OIC_LOG(INFO, TAG, "g_connectedDeviceSet is needed for CM. "
520                     "please call CAManagerLEClientInitialize");
521             return;
522         }
523
524         jstring jni_address = CALEGetAddressFromGatt(env, gatt);
525         if (!jni_address)
526         {
527             OIC_LOG(ERROR, TAG, "CALEGetAddressFromGatt is null");
528             return;
529         }
530
531         char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
532         if (!address)
533         {
534             OIC_LOG(ERROR, TAG, "address is null");
535             (*env)->DeleteLocalRef(env, jni_address);
536             return;
537         }
538
539         if (CAManagerIsConnectedDeviceAddress(env, g_context, jni_address, g_connectedDeviceSet))
540         {
541             OIC_LOG(INFO, TAG, "AC list - the address will be added to ACData list");
542             CAManagerAddACData(env, jni_address);
543             CAManagerSetAutoConnectingFlag(env, jni_address, false);
544
545             // next connection will be requested with JNI_TRUE on autoConnect flag
546             // after first connection
547             CALEClientSetFlagToState(env, jni_address, CA_LE_AUTO_CONNECT_FLAG, JNI_TRUE);
548         }
549         else
550         {
551             OIC_LOG(DEBUG, TAG, "AC list - the address is not set to AutoConnect");
552         }
553
554         (*env)->ReleaseStringUTFChars(env, jni_address, address);
555         (*env)->DeleteLocalRef(env, jni_address);
556     }
557     else
558     {
559         OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
560     }
561 }
562
563 /*
564  * Class:     org_iotivity_ca_jar_caleinterface
565  * Method:    caManagerLeRemoteRssiCallback
566  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
567  */
568 JNIEXPORT void JNICALL
569 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback(JNIEnv *env,
570                                                                        jobject obj,
571                                                                        jobject gatt,
572                                                                        jint rssi,
573                                                                        jint status)
574 {
575 #ifndef TB_LOG
576     (void)rssi;
577     (void)status;
578 #endif
579     OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - rssi : %d: ", rssi);
580     OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - status : %d: ", status);
581     VERIFY_NON_NULL_VOID(env, TAG, "env");
582     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
583     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
584 }