82bc169bdfe4c36ed5a10aaa5faf8775030364d4
[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     OIC_LOG(DEBUG, TAG, "IN");
112     if (NULL == g_bleDeviceStateChangedCbMutex)
113     {
114         g_bleDeviceStateChangedCbMutex = oc_mutex_new();
115         if (NULL == g_bleDeviceStateChangedCbMutex)
116         {
117             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
118             return CA_STATUS_FAILED;
119         }
120     }
121
122     if (NULL == g_bleConnectionStateChangedCbMutex)
123     {
124         g_bleConnectionStateChangedCbMutex = oc_mutex_new();
125         if (NULL == g_bleConnectionStateChangedCbMutex)
126         {
127             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
128             oc_mutex_free(g_bleDeviceStateChangedCbMutex);
129             return CA_STATUS_FAILED;
130         }
131     }
132
133     OIC_LOG(DEBUG, TAG, "OUT");
134     return CA_STATUS_OK;
135 }
136
137 void CATerminateLENwkMonitorMutexVaraibles()
138 {
139     OIC_LOG(DEBUG, TAG, "IN");
140
141     oc_mutex_free(g_bleDeviceStateChangedCbMutex);
142     g_bleDeviceStateChangedCbMutex = NULL;
143
144     oc_mutex_free(g_bleConnectionStateChangedCbMutex);
145     g_bleConnectionStateChangedCbMutex = NULL;
146
147     OIC_LOG(DEBUG, TAG, "OUT");
148 }
149
150 CAResult_t CAGetLEAdapterState()
151 {
152     OIC_LOG(DEBUG, TAG, "IN");
153
154     if (!g_jvm)
155     {
156         OIC_LOG(ERROR, TAG, "g_jvm is null");
157         return CA_STATUS_FAILED;
158     }
159
160     bool isAttached = false;
161     JNIEnv* env = NULL;
162     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
163     if (JNI_OK != res)
164     {
165         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
166         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
167
168         if (JNI_OK != res)
169         {
170             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
171             return CA_STATUS_FAILED;
172         }
173         isAttached = true;
174     }
175
176     if (!CALEIsEnableBTAdapter(env))
177     {
178         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
179         if (isAttached)
180         {
181             (*g_jvm)->DetachCurrentThread(g_jvm);
182         }
183         return CA_ADAPTER_NOT_ENABLED;
184     }
185
186     if (isAttached)
187     {
188         (*g_jvm)->DetachCurrentThread(g_jvm);
189     }
190
191     OIC_LOG(DEBUG, TAG, "OUT");
192     return CA_STATUS_OK;
193 }
194
195 CAResult_t CAInitializeLENetworkMonitor()
196 {
197     OIC_LOG(DEBUG, TAG, "IN");
198
199     CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
200     if (CA_STATUS_OK != res)
201     {
202         OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
203         return CA_STATUS_FAILED;
204     }
205
206     CALENetworkMonitorJNISetContext();
207     CALENetworkMonitorJniInit();
208
209     OIC_LOG(DEBUG, TAG, "OUT");
210
211     return CA_STATUS_OK;
212
213 }
214
215 void CATerminateLENetworkMonitor()
216 {
217     OIC_LOG(DEBUG, TAG, "IN");
218
219     CATerminateLENwkMonitorMutexVaraibles();
220
221     OIC_LOG(DEBUG, TAG, "OUT");
222 }
223
224 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
225 {
226     OIC_LOG(DEBUG, TAG, "IN");
227
228     OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
229
230     oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
231     CALESetAdapterStateCallback(callback);
232     oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
233
234     OIC_LOG(DEBUG, TAG, "OUT");
235     return CA_STATUS_OK;
236 }
237
238 CAResult_t CAUnSetLEAdapterStateChangedCb()
239 {
240     OIC_LOG(DEBUG, TAG, "it is not required in this platform");
241     return CA_STATUS_OK;
242 }
243
244 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
245 {
246     OIC_LOG(DEBUG, TAG, "IN");
247     oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
248     g_bleConnectionStateChangedCallback = callback;
249     oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
250     OIC_LOG(DEBUG, TAG, "OUT");
251     return CA_STATUS_OK;
252 }
253
254 CAResult_t CAUnsetLENWConnectionStateChangedCb()
255 {
256     OIC_LOG(DEBUG, TAG, "IN");
257     oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
258     g_bleConnectionStateChangedCallback = NULL;
259     oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
260     OIC_LOG(DEBUG, TAG, "OUT");
261     return CA_STATUS_OK;
262 }
263
264 static CAResult_t CALEStateConnectedCallback(JNIEnv *env, jstring jni_address,
265                                              jboolean isDescriptorFound)
266 {
267     VERIFY_NON_NULL(env, TAG, "env");
268     VERIFY_NON_NULL(jni_address, TAG, "jni_address");
269
270     if (CALEClientGetFlagFromState(env, jni_address, CA_LE_DESCRIPTOR_FOUND) == isDescriptorFound)
271     {
272         if (g_bleConnectionStateChangedCallback)
273         {
274             const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
275             if (!address)
276             {
277                 OIC_LOG(ERROR, TAG, "address is null");
278                 CACheckJNIException(env);
279                 return CA_STATUS_FAILED;
280             }
281
282             g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
283             OIC_LOG(DEBUG, TAG, "BLE is connected");
284
285             (*env)->ReleaseStringUTFChars(env, jni_address, address);
286         }
287     }
288
289     return CA_STATUS_OK;
290 }
291
292 JNIEXPORT void JNICALL
293 Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
294                                                                    jint status)
295 {
296     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
297     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
298
299     OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
300
301     if (!g_bleDeviceStateChangedCallback)
302     {
303         OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null");
304         return;
305     }
306
307     jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
308     jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
309     jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
310
311     if (state_on == status) // STATE_ON:12
312     {
313         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
314         CALEClientCreateDeviceList();
315
316         if (!(caglobals.bleFlags & CA_LE_SERVER_DISABLE))
317         {
318             CALEServerCreateCachedDeviceList();
319         }
320
321         g_bleDeviceStateChangedCallback(newStatus);
322     }
323     else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
324     {
325         // gatt Device list will be removed.
326         // so it is need to create list again when adapter is enabled.
327         CAStopLEGattClient();
328     }
329     else if (state_off == status) // STATE_OFF:10
330     {
331         // remove obj for client
332         CAResult_t res = CALEClientRemoveAllGattObjs(env);
333         if (CA_STATUS_OK != res)
334         {
335             OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
336         }
337
338         res = CALEClientResetDeviceStateForAll();
339         if (CA_STATUS_OK != res)
340         {
341             OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
342         }
343
344         // remove obj for server
345         res = CALEServerRemoveAllDevices(env);
346         if (CA_STATUS_OK != res)
347         {
348             OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
349         }
350
351         CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
352         g_bleDeviceStateChangedCallback(newStatus);
353     }
354 }
355
356 JNIEXPORT void JNICALL
357 Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
358                                                                       jstring jaddr)
359 {
360     OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
361     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
362     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
363     VERIFY_NON_NULL_VOID(jaddr, TAG, "jaddr is null");
364
365     // geneally 'addr' parameter will be not ble address, if you didn't bond for BLE.
366     // below logics will be needed when ble pairing is set.
367
368     CAResult_t res = CALEClientDisconnectforAddress(env, jaddr);
369     if (CA_STATUS_OK != res)
370     {
371         OIC_LOG(ERROR, TAG, "CALEClientDisconnectforAddress has failed");
372     }
373
374     // remove obj for client
375     res = CALEClientRemoveGattObjForAddr(env, jaddr);
376     if (CA_STATUS_OK != res)
377     {
378         OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
379     }
380
381     res = CALEClientRemoveDeviceInScanDeviceList(env, jaddr);
382     if (CA_STATUS_OK != res)
383     {
384         OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceInScanDeviceList has failed");
385     }
386
387     // remove obej for server
388     res = CALEServerRemoveDevice(env, jaddr);
389     if (CA_STATUS_OK != res)
390     {
391         OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
392     }
393 }
394
395 JNIEXPORT void JNICALL
396 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback(JNIEnv *env,
397                                                                                  jobject obj,
398                                                                                  jobject gatt,
399                                                                                  jint status,
400                                                                                  jint newState)
401 {
402     OIC_LOG_V(DEBUG, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
403               status, newState);
404     VERIFY_NON_NULL_VOID(env, TAG, "env");
405     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
406     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
407
408     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
409                                                     "STATE_DISCONNECTED");
410     if (state_disconnected == newState)
411     {
412         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
413         if (!jni_address)
414         {
415             OIC_LOG(ERROR, TAG, "jni_address is null");
416             return;
417         }
418
419         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
420         if (!address)
421         {
422             OIC_LOG(ERROR, TAG, "address is null");
423             CACheckJNIException(env);
424             return;
425         }
426
427         if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
428         {
429             if (g_bleConnectionStateChangedCallback)
430             {
431                 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
432                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
433             }
434         }
435
436         (*env)->ReleaseStringUTFChars(env, jni_address, address);
437     }
438 }
439
440 JNIEXPORT void JNICALL
441 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCallback(
442         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
443 {
444     OIC_LOG_V(DEBUG, TAG, "caLeGattServerNWConnectionStateChangeCallback - status %d, newstate %d",
445               status, newState);
446     VERIFY_NON_NULL_VOID(env, TAG, "env");
447     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
448     VERIFY_NON_NULL_VOID(device, TAG, "device");
449
450     if (CONNECTION_FAILED_TO_BE_EASTABLISHED != status)
451     {
452         if (g_bleConnectionStateChangedCallback)
453         {
454             jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
455             if (!jni_remoteAddress)
456             {
457                 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
458                 return;
459             }
460
461             const char* address = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
462             if (!address)
463             {
464                 OIC_LOG(ERROR, TAG, "address is null");
465                 CACheckJNIException(env);
466                 return;
467             }
468
469             // STATE_DISCONNECTED
470             jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
471                                                             "STATE_DISCONNECTED");
472
473             // STATE_CONNECTED
474             jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
475                                                          "STATE_CONNECTED");
476
477             if (state_disconnected == newState)
478             {
479                 OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
480                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
481             }
482             else if (state_connected == newState)
483             {
484                 OIC_LOG_V(DEBUG, TAG, "LE Connected state is %d, %s", newState, address);
485                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, true);
486             }
487             else
488             {
489                 OIC_LOG_V(DEBUG, TAG, "Unknown state : %d, %s", newState, address);
490             }
491
492             (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, address);
493         }
494     }
495 }
496
497 JNIEXPORT void JNICALL
498 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWServicesDiscoveredCallback(JNIEnv *env,
499                                                                               jobject obj,
500                                                                               jobject gatt,
501                                                                               jint status)
502 {
503     OIC_LOG_V(DEBUG, TAG, "caLeGattNWServicesDiscoveredCallback - status %d", status);
504     VERIFY_NON_NULL_VOID(env, TAG, "env");
505     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
506     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
507
508     if (GATT_SUCCESS == status)
509     {
510         jstring jni_address = CALEGetAddressFromGatt(env, gatt);
511         if (!jni_address)
512         {
513             OIC_LOG(ERROR, TAG, "jni_address is null");
514             return;
515         }
516
517         if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_FALSE))
518         {
519             OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
520         }
521
522         (*env)->DeleteLocalRef(env, jni_address);
523     }
524 }
525
526 JNIEXPORT void JNICALL
527 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWDescriptorWriteCallback(JNIEnv *env,
528                                                                            jobject obj,
529                                                                            jobject gatt,
530                                                                            jint status)
531 {
532     OIC_LOG_V(DEBUG, TAG, "caLeGattNWDescriptorWriteCallback - status %d", status);
533     VERIFY_NON_NULL_VOID(env, TAG, "env");
534     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
535     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
536
537     if (GATT_SUCCESS == status)
538     {
539         jstring jni_address = CALEGetAddressFromGatt(env, gatt);
540         if (!jni_address)
541         {
542             OIC_LOG(ERROR, TAG, "jni_address is null");
543             return;
544         }
545
546         if (CA_STATUS_OK != CALEStateConnectedCallback(env, jni_address, JNI_TRUE))
547         {
548             OIC_LOG(ERROR, TAG, "CALEStateConnectedCallback has failed");
549         }
550
551         (*env)->DeleteLocalRef(env, jni_address);
552     }
553 }