replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / calenwmonitor.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 #include "logger.h"
25 #include "calenwmonitor.h"
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
31
32 #include "octhread.h"
33
34 #include "org_iotivity_ca_CaLeClientInterface.h"
35 #include "org_iotivity_ca_CaLeServerInterface.h"
36
37 #define TAG PCF("OIC_CA_LE_MONITOR")
38
39 static const jint CONNECTION_FAILED_TO_BE_EASTABLISHED = 62;
40
41 static JavaVM *g_jvm;
42
43 /**
44  * @var g_bleDeviceStateChangedCallback
45  * @brief Maintains the callback to be notified on device state changed.
46  */
47 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
48
49 /**
50  * @var g_bleConnectionStateChangedCallback
51  * @brief Maintains the callback to be notified on device state changed.
52  */
53 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
54
55 /**
56  * @var g_bleDeviceStateChangedCbMutex
57  * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
58  *           of the LE adapter gets change.
59  */
60 static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
61
62 /**
63  * @var g_bleConnectionStateChangedCbMutex
64  * @brief Mutex to synchronize access to the LE ConnectionStateChanged Callback when the state
65  *           of the LE adapter gets change.
66  */
67 static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
68
69 //getting context
70 void CALENetworkMonitorJNISetContext()
71 {
72     OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext - it is not supported");
73 }
74
75 //getting jvm
76 void CALENetworkMonitorJniInit()
77 {
78     OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJniInit");
79     g_jvm = CANativeJNIGetJavaVM();
80 }
81
82 void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback)
83 {
84     OIC_LOG(DEBUG, TAG, "CALESetAdapterStateCallback");
85     g_bleDeviceStateChangedCallback = callback;
86 }
87
88 CAResult_t CAInitializeLEAdapter()
89 {
90     // Nothing to do.
91
92     return CA_STATUS_OK;
93 }
94
95 CAResult_t CAStartLEAdapter()
96 {
97     // Nothing to do.
98
99     return CA_STATUS_OK;
100 }
101
102 CAResult_t CAStopLEAdapter()
103 {
104     // Nothing to do.
105
106     return CA_STATUS_OK;
107 }
108
109 CAResult_t CAInitLENwkMonitorMutexVaraibles()
110 {
111     if (NULL == g_bleDeviceStateChangedCbMutex)
112     {
113         g_bleDeviceStateChangedCbMutex = oc_mutex_new();
114         if (NULL == g_bleDeviceStateChangedCbMutex)
115         {
116             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
117             return CA_STATUS_FAILED;
118         }
119     }
120
121     if (NULL == g_bleConnectionStateChangedCbMutex)
122     {
123         g_bleConnectionStateChangedCbMutex = oc_mutex_new();
124         if (NULL == g_bleConnectionStateChangedCbMutex)
125         {
126             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
127             oc_mutex_free(g_bleDeviceStateChangedCbMutex);
128             return CA_STATUS_FAILED;
129         }
130     }
131
132     return CA_STATUS_OK;
133 }
134
135 void CATerminateLENwkMonitorMutexVaraibles()
136 {
137     oc_mutex_free(g_bleDeviceStateChangedCbMutex);
138     g_bleDeviceStateChangedCbMutex = NULL;
139
140     oc_mutex_free(g_bleConnectionStateChangedCbMutex);
141     g_bleConnectionStateChangedCbMutex = NULL;
142 }
143
144 CAResult_t CAGetLEAdapterState()
145 {
146     if (!g_jvm)
147     {
148         OIC_LOG(ERROR, TAG, "g_jvm is null");
149         return CA_STATUS_FAILED;
150     }
151
152     bool isAttached = false;
153     JNIEnv* env = NULL;
154     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
155     if (JNI_OK != res)
156     {
157         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
158         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
159
160         if (JNI_OK != res)
161         {
162             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
163             return CA_STATUS_FAILED;
164         }
165         isAttached = true;
166     }
167
168     if (!CALEIsEnableBTAdapter(env))
169     {
170         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
171         if (isAttached)
172         {
173             (*g_jvm)->DetachCurrentThread(g_jvm);
174         }
175         return CA_ADAPTER_NOT_ENABLED;
176     }
177
178     if (isAttached)
179     {
180         (*g_jvm)->DetachCurrentThread(g_jvm);
181     }
182
183     return CA_STATUS_OK;
184 }
185
186 CAResult_t CAInitializeLENetworkMonitor()
187 {
188     CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
189     if (CA_STATUS_OK != res)
190     {
191         OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
192         return CA_STATUS_FAILED;
193     }
194
195     CALENetworkMonitorJNISetContext();
196     CALENetworkMonitorJniInit();
197
198     return CA_STATUS_OK;
199 }
200
201 void CATerminateLENetworkMonitor()
202 {
203     OIC_LOG(DEBUG, TAG, "CATerminateLENetworkMonitor");
204
205     CATerminateLENwkMonitorMutexVaraibles();
206 }
207
208 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
209 {
210     OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
211
212     oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
213     CALESetAdapterStateCallback(callback);
214     oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
215
216     return CA_STATUS_OK;
217 }
218
219 CAResult_t CAUnSetLEAdapterStateChangedCb()
220 {
221     OIC_LOG(DEBUG, TAG, "it is not required in this platform");
222     return CA_STATUS_OK;
223 }
224
225 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
226 {
227     OIC_LOG(DEBUG, TAG, "CASetLENWConnectionStateChangedCb");
228     oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
229     g_bleConnectionStateChangedCallback = callback;
230     oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
231     return CA_STATUS_OK;
232 }
233
234 CAResult_t CAUnSetLENWConnectionStateChangedCb()
235 {
236     OIC_LOG(DEBUG, TAG, "CAUnSetLENWConnectionStateChangedCb");
237     oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
238     g_bleConnectionStateChangedCallback = NULL;
239     oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
240     return CA_STATUS_OK;
241 }
242
243 static CAResult_t CALEStateConnectedCallback(JNIEnv *env, jstring jni_address,
244                                              jboolean isDescriptorFound)
245 {
246     VERIFY_NON_NULL(env, TAG, "env");
247     VERIFY_NON_NULL(jni_address, TAG, "jni_address");
248
249     if (CALEClientGetFlagFromState(env, jni_address, CA_LE_DESCRIPTOR_FOUND) == isDescriptorFound)
250     {
251         if (g_bleConnectionStateChangedCallback)
252         {
253             const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
254             if (!address)
255             {
256                 OIC_LOG(ERROR, TAG, "address is null");
257                 CACheckJNIException(env);
258                 return CA_STATUS_FAILED;
259             }
260
261             g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
262             OIC_LOG(DEBUG, TAG, "BLE is connected");
263
264             (*env)->ReleaseStringUTFChars(env, jni_address, address);
265         }
266     }
267
268     return CA_STATUS_OK;
269 }
270
271 JNIEXPORT void JNICALL
272 Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
273                                                                    jint status)
274 {
275     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
276     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
277
278     OIC_LOG_V(INFO, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
279
280     if (!g_bleDeviceStateChangedCallback)
281     {
282         OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null");
283         return;
284     }
285
286     jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
287     jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
288     jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
289
290     if (state_on == status) // STATE_ON:12
291     {
292         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
293         CALEClientCreateDeviceList();
294
295         if (!(caglobals.bleFlags & CA_LE_SERVER_DISABLE))
296         {
297             CALEServerCreateCachedDeviceList();
298         }
299
300         g_bleDeviceStateChangedCallback(newStatus);
301     }
302     else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
303     {
304         // gatt Device list will be removed.
305         // so it is need to create list again when adapter is enabled.
306         CAStopLEGattClient();
307     }
308     else if (state_off == status) // STATE_OFF:10
309     {
310         // remove obj for client
311         CAResult_t res = CALEClientRemoveAllGattObjs(env);
312         if (CA_STATUS_OK != res)
313         {
314             OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
315         }
316
317         res = CALEClientResetDeviceStateForAll();
318         if (CA_STATUS_OK != res)
319         {
320             OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
321         }
322
323         // remove obj for server
324         res = CALEServerRemoveAllDevices(env);
325         if (CA_STATUS_OK != res)
326         {
327             OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
328         }
329
330         CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
331         g_bleDeviceStateChangedCallback(newStatus);
332     }
333 }
334
335 JNIEXPORT void JNICALL
336 Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
337                                                                       jstring jaddr)
338 {
339     OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
340     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
341     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
342     VERIFY_NON_NULL_VOID(jaddr, TAG, "jaddr is null");
343
344     // geneally 'addr' parameter will be not ble address, if you didn't bond for BLE.
345     // below logics will be needed when ble pairing is set.
346
347     CAResult_t res = CALEClientDisconnectforAddress(env, jaddr);
348     if (CA_STATUS_OK != res)
349     {
350         OIC_LOG(ERROR, TAG, "CALEClientDisconnectforAddress has failed");
351     }
352
353     // remove obj for client
354     res = CALEClientRemoveGattObjForAddr(env, jaddr);
355     if (CA_STATUS_OK != res)
356     {
357         OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
358     }
359
360     res = CALEClientRemoveDeviceInScanDeviceList(env, jaddr);
361     if (CA_STATUS_OK != res)
362     {
363         OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceInScanDeviceList has failed");
364     }
365
366     // remove obej for server
367     res = CALEServerRemoveDevice(env, jaddr);
368     if (CA_STATUS_OK != res)
369     {
370         OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
371     }
372 }
373
374 JNIEXPORT void JNICALL
375 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback(JNIEnv *env,
376                                                                                  jobject obj,
377                                                                                  jobject gatt,
378                                                                                  jint status,
379                                                                                  jint newState)
380 {
381     OIC_LOG_V(INFO, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
382               status, newState);
383     VERIFY_NON_NULL_VOID(env, TAG, "env");
384     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
385     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
386
387     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
388                                                     "STATE_DISCONNECTED");
389     if (state_disconnected == newState)
390     {
391         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
392         if (!jni_address)
393         {
394             OIC_LOG(ERROR, TAG, "jni_address is null");
395             return;
396         }
397
398         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
399         if (!address)
400         {
401             OIC_LOG(ERROR, TAG, "address is null");
402             CACheckJNIException(env);
403             return;
404         }
405
406         if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
407         {
408             if (g_bleConnectionStateChangedCallback)
409             {
410                 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %s", address);
411                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
412             }
413         }
414
415         (*env)->ReleaseStringUTFChars(env, jni_address, address);
416     }
417 }
418
419 JNIEXPORT void JNICALL
420 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCallback(
421         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
422 {
423     OIC_LOG_V(DEBUG, TAG, "caLeGattServerNWConnectionStateChangeCallback - status %d, newstate %d",
424               status, newState);
425     VERIFY_NON_NULL_VOID(env, TAG, "env");
426     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
427     VERIFY_NON_NULL_VOID(device, TAG, "device");
428
429     if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
430     {
431         if (g_bleConnectionStateChangedCallback)
432         {
433             jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
434             if (!jni_remoteAddress)
435             {
436                 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
437                 return;
438             }
439
440             const char* address = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
441             if (!address)
442             {
443                 OIC_LOG(ERROR, TAG, "address is null");
444                 CACheckJNIException(env);
445                 return;
446             }
447
448             // STATE_DISCONNECTED
449             jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
450                                                             "STATE_DISCONNECTED");
451
452             // STATE_CONNECTED
453             jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
454                                                          "STATE_CONNECTED");
455
456             if (state_disconnected == newState)
457             {
458                 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
459                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
460             }
461             else if (state_connected == newState)
462             {
463                 OIC_LOG_V(DEBUG, TAG, "LE Connected state is %d, %s", newState, address);
464                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
465             }
466             else
467             {
468                 OIC_LOG_V(DEBUG, TAG, "Unknown state : %d, %s", newState, address);
469             }
470
471             (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, address);
472         }
473     }
474 }
475
476 JNIEXPORT void JNICALL
477 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWServicesDiscoveredCallback(JNIEnv *env,
478                                                                               jobject obj,
479                                                                               jobject gatt,
480                                                                               jint status)
481 {
482     OIC_LOG_V(INFO, TAG, "caLeGattNWServicesDiscoveredCallback - status %d", status);
483     VERIFY_NON_NULL_VOID(env, TAG, "env");
484     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
485     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
486
487     if (GATT_SUCCESS == status)
488     {
489         jstring jni_address = CALEGetAddressFromGatt(env, gatt);
490         if (!jni_address)
491         {
492             OIC_LOG(ERROR, TAG, "jni_address is null");
493             return;
494         }
495
496         if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_FALSE))
497         {
498             OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
499         }
500
501         (*env)->DeleteLocalRef(env, jni_address);
502     }
503 }
504
505 JNIEXPORT void JNICALL
506 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWDescriptorWriteCallback(JNIEnv *env,
507                                                                            jobject obj,
508                                                                            jobject gatt,
509                                                                            jint status)
510 {
511     OIC_LOG_V(INFO, TAG, "caLeGattNWDescriptorWriteCallback - status %d", status);
512     VERIFY_NON_NULL_VOID(env, TAG, "env");
513     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
514     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
515
516     if (GATT_SUCCESS == status)
517     {
518         jstring jni_address = CALEGetAddressFromGatt(env, gatt);
519         if (!jni_address)
520         {
521             OIC_LOG(ERROR, TAG, "jni_address is null");
522             return;
523         }
524
525         if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_TRUE))
526         {
527             OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
528         }
529
530         (*env)->DeleteLocalRef(env, jni_address);
531     }
532 }