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