Imported Upstream version 1.1.0
[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         // remove obj for client
299         CAResult_t res = CALEClientRemoveAllGattObjs(env);
300         if (CA_STATUS_OK != res)
301         {
302             OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
303         }
304
305         res = CALEClientResetDeviceStateForAll();
306         if (CA_STATUS_OK != res)
307         {
308             OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
309         }
310
311         // remove obj for server
312         res = CALEServerRemoveAllDevices(env);
313         if (CA_STATUS_OK != res)
314         {
315             OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
316         }
317
318         CALEClientSetScanFlag(false);
319
320         CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
321         g_bleDeviceStateChangedCallback(newStatus);
322     }
323 }
324
325 JNIEXPORT void JNICALL
326 Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
327                                                                       jstring jaddr)
328 {
329     OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
330     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
331     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
332     VERIFY_NON_NULL_VOID(jaddr, TAG, "jaddr is null");
333
334     // geneally 'addr' parameter will be not ble address, if you didn't bond for BLE.
335     // below logics will be needed when ble pairing is set.
336
337     CAResult_t res = CALEClientDisconnectforAddress(env, jaddr);
338     if (CA_STATUS_OK != res)
339     {
340         OIC_LOG(ERROR, TAG, "CALEClientDisconnectforAddress has failed");
341     }
342
343     // remove obj for client
344     res = CALEClientRemoveGattObjForAddr(env, jaddr);
345     if (CA_STATUS_OK != res)
346     {
347         OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
348     }
349
350     res = CALEClientRemoveDeviceInScanDeviceList(env, jaddr);
351     if (CA_STATUS_OK != res)
352     {
353         OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceInScanDeviceList has failed");
354     }
355
356     // remove obej for server
357     res = CALEServerRemoveDevice(env, jaddr);
358     if (CA_STATUS_OK != res)
359     {
360         OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
361     }
362 }
363
364 JNIEXPORT void JNICALL
365 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback(JNIEnv *env,
366                                                                                  jobject obj,
367                                                                                  jobject gatt,
368                                                                                  jint status,
369                                                                                  jint newstate)
370 {
371     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
372     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
373     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
374
375     OIC_LOG_V(DEBUG, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
376               status, newstate);
377
378     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
379                                                     "STATE_DISCONNECTED");
380     if (state_disconnected == newstate)
381     {
382         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
383         if (!jni_address)
384         {
385             OIC_LOG(ERROR, TAG, "jni_address is null");
386             return;
387         }
388
389         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
390         if (!address)
391         {
392             OIC_LOG(ERROR, TAG, "address is null");
393             return;
394         }
395
396         if (g_bleConnectionStateChangedCallback)
397         {
398             g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
399         }
400
401         (*env)->ReleaseStringUTFChars(env, jni_address, address);
402     }
403 }
404
405 JNIEXPORT void JNICALL
406 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCallback(
407         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
408 {
409     OIC_LOG(DEBUG, TAG, " Gatt Server NWConnectionStateChange Callback");
410
411     VERIFY_NON_NULL_VOID(env, TAG, "env");
412     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
413     VERIFY_NON_NULL_VOID(device, TAG, "device");
414     (void)status;
415
416     // STATE_DISCONNECTED
417     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE,
418                                                     "STATE_DISCONNECTED");
419     if (state_disconnected == newState)
420     {
421         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
422         if (!jni_remoteAddress)
423         {
424             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
425             return;
426         }
427
428         const char* address = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
429         if (!address)
430         {
431             OIC_LOG(ERROR, TAG, "address is null");
432             return;
433         }
434
435         if (g_bleConnectionStateChangedCallback)
436         {
437             g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
438         }
439
440         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, address);
441     }
442 }