To support autoconnect flag of connectGatt(..) for multi-connection.
[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 JavaVM *g_jvm;
40
41 /**
42  * @var g_bleDeviceStateChangedCallback
43  * @brief Maintains the callback to be notified on device state changed.
44  */
45 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
46
47 /**
48  * @var g_bleConnectionStateChangedCallback
49  * @brief Maintains the callback to be notified on device state changed.
50  */
51 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
52
53 /**
54  * @var g_bleDeviceStateChangedCbMutex
55  * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
56  *           of the LE adapter gets change.
57  */
58 static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
59
60 /**
61  * @var g_bleConnectionStateChangedCbMutex
62  * @brief Mutex to synchronize access to the LE ConnectionStateChanged Callback when the state
63  *           of the LE adapter gets change.
64  */
65 static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
66
67 //getting context
68 void CALENetworkMonitorJNISetContext()
69 {
70     OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext - it is not supported");
71 }
72
73 //getting jvm
74 void CALENetworkMonitorJniInit()
75 {
76     OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJniInit");
77     g_jvm = CANativeJNIGetJavaVM();
78 }
79
80 void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback)
81 {
82     OIC_LOG(DEBUG, TAG, "CALESetAdapterStateCallback");
83     g_bleDeviceStateChangedCallback = callback;
84 }
85
86 CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
87 {
88     OIC_LOG(DEBUG, TAG, "IN");
89     (void)threadPool;
90     OIC_LOG(DEBUG, TAG, "OUT");
91     return CA_STATUS_OK;
92 }
93
94 CAResult_t CAStartLEAdapter()
95 {
96     // Nothing to do.
97
98     return CA_STATUS_OK;
99 }
100
101 CAResult_t CAStopLEAdapter()
102 {
103     // Nothing to do.
104
105     return CA_STATUS_OK;
106 }
107
108 CAResult_t CAInitLENwkMonitorMutexVaraibles()
109 {
110     OIC_LOG(DEBUG, TAG, "IN");
111     if (NULL == g_bleDeviceStateChangedCbMutex)
112     {
113         g_bleDeviceStateChangedCbMutex = ca_mutex_new();
114         if (NULL == g_bleDeviceStateChangedCbMutex)
115         {
116             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
117             return CA_STATUS_FAILED;
118         }
119     }
120
121     if (NULL == g_bleConnectionStateChangedCbMutex)
122     {
123         g_bleConnectionStateChangedCbMutex = ca_mutex_new();
124         if (NULL == g_bleConnectionStateChangedCbMutex)
125         {
126             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
127             ca_mutex_free(g_bleDeviceStateChangedCbMutex);
128             return CA_STATUS_FAILED;
129         }
130     }
131
132     OIC_LOG(DEBUG, TAG, "OUT");
133     return CA_STATUS_OK;
134 }
135
136 void CATerminateLENwkMonitorMutexVaraibles()
137 {
138     OIC_LOG(DEBUG, TAG, "IN");
139
140     ca_mutex_free(g_bleDeviceStateChangedCbMutex);
141     g_bleDeviceStateChangedCbMutex = NULL;
142
143     ca_mutex_free(g_bleConnectionStateChangedCbMutex);
144     g_bleConnectionStateChangedCbMutex = NULL;
145
146     OIC_LOG(DEBUG, TAG, "OUT");
147 }
148
149 CAResult_t CAGetLEAdapterState()
150 {
151     OIC_LOG(DEBUG, TAG, "IN");
152
153     if (!g_jvm)
154     {
155         OIC_LOG(ERROR, TAG, "g_jvm is null");
156         return CA_STATUS_FAILED;
157     }
158
159     bool isAttached = false;
160     JNIEnv* env;
161     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
162     if (JNI_OK != res)
163     {
164         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
165         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166
167         if (JNI_OK != res)
168         {
169             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
170             return CA_STATUS_FAILED;
171         }
172         isAttached = true;
173     }
174
175     if (!CALEIsEnableBTAdapter(env))
176     {
177         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
178         if (isAttached)
179         {
180             (*g_jvm)->DetachCurrentThread(g_jvm);
181         }
182         return CA_ADAPTER_NOT_ENABLED;
183     }
184
185     if (isAttached)
186     {
187         (*g_jvm)->DetachCurrentThread(g_jvm);
188     }
189
190     OIC_LOG(DEBUG, TAG, "OUT");
191     return CA_STATUS_OK;
192 }
193
194 CAResult_t CAInitializeLENetworkMonitor()
195 {
196     OIC_LOG(DEBUG, TAG, "IN");
197
198     CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
199     if (CA_STATUS_OK != res)
200     {
201         OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
202         return CA_STATUS_FAILED;
203     }
204
205     CALENetworkMonitorJNISetContext();
206     CALENetworkMonitorJniInit();
207
208     OIC_LOG(DEBUG, TAG, "OUT");
209
210     return CA_STATUS_OK;
211
212 }
213
214 void CATerminateLENetworkMonitor()
215 {
216     OIC_LOG(DEBUG, TAG, "IN");
217
218     CATerminateLENwkMonitorMutexVaraibles();
219
220     OIC_LOG(DEBUG, TAG, "OUT");
221 }
222
223 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
224 {
225     OIC_LOG(DEBUG, TAG, "IN");
226
227     OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
228
229     ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
230     CALESetAdapterStateCallback(callback);
231     ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
232
233     OIC_LOG(DEBUG, TAG, "OUT");
234     return CA_STATUS_OK;
235 }
236
237 CAResult_t CAUnSetLEAdapterStateChangedCb()
238 {
239     OIC_LOG(DEBUG, TAG, "it is not required in this platform");
240     return CA_STATUS_OK;
241 }
242
243 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
244 {
245     OIC_LOG(DEBUG, TAG, "IN");
246     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
247     g_bleConnectionStateChangedCallback = callback;
248     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
249     OIC_LOG(DEBUG, TAG, "OUT");
250     return CA_STATUS_OK;
251 }
252
253 CAResult_t CAUnsetLENWConnectionStateChangedCb()
254 {
255     OIC_LOG(DEBUG, TAG, "IN");
256     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
257     g_bleConnectionStateChangedCallback = NULL;
258     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
259     OIC_LOG(DEBUG, TAG, "OUT");
260     return CA_STATUS_OK;
261 }
262
263 JNIEXPORT void JNICALL
264 Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
265                                                                    jint status)
266 {
267     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
268     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
269
270     OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
271
272     if (!g_bleDeviceStateChangedCallback)
273     {
274         OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null");
275         return;
276     }
277
278     jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
279     jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
280     jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
281
282     if (state_on == status) // STATE_ON:12
283     {
284         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
285         CALEClientCreateDeviceList();
286         CALEServerCreateCachedDeviceList();
287
288         g_bleDeviceStateChangedCallback(newStatus);
289     }
290     else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
291     {
292         // gatt Device list will be removed.
293         // so it is need to create list again when adapter is enabled.
294         CAStopLEGattClient();
295     }
296     else if (state_off == status) // STATE_OFF:10
297     {
298         CALEClientStopMulticastServer();
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 }