1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "caleinterface.h"
27 #include <arpa/inet.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
32 #include <bluetooth.h>
33 #include <bluetooth_internal.h>
34 #include <bluetooth_type.h>
37 #include "caleadapter.h"
38 #include "caadapterutils.h"
39 #include "oic_string.h"
40 #include "oic_malloc.h"
43 * Logging tag for module name
45 #define TAG "OIC_CA_LE_MONITOR"
47 #define MICROSECS_PER_SEC 1000000
49 static uint64_t const INITIALIZE_TIMEOUT = 1 * MICROSECS_PER_SEC;
51 static GMainLoop *g_mainloop = NULL;
52 static ca_thread_pool_t g_threadPoolHandle = NULL;
55 * Maintains the callback to be notified on device state changed.
57 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
60 * Maintains the callback to be notified on device state changed.
62 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
65 * Mutex to synchronize access to the deviceStateChanged Callback when the state
66 * of the LE adapter gets change.
68 static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
71 * Mutex to synchronize access to the ConnectionStateChanged Callback when the state
72 * of the LE adapter gets change.
74 static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
77 * Mutex to synchronize access to
79 static ca_mutex g_btinitializeMutex = NULL;
82 * Condition for gmainloop to run.
84 static ca_cond g_initializeCond = NULL;
87 * Flag to check if BT stack is initialised.
89 static bool g_isBTStackInitialised = false;
92 * This is the callback which will be called when the adapter state gets changed.
94 * @param result [IN] Result of the query done to the platform.
95 * @param adapter_state [IN] State of the LE adapter.
96 * @param user_data [IN] User data passed by the caller when querying for the state changed cb.
100 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
104 * This is the callback which will be called when the connection state gets changed.
106 * @param result [IN] Result of the query done to the platform.
107 * @param connected [IN] State of connection.
108 * @param remoteAddress [IN] LE address of the device to be notified.
109 * @param user_data [IN] User data passed by the caller when querying for the state changed cb.
113 void CALENWConnectionStateChangedCb(int result, bool connected,
114 const char *remoteAddress, void *userData);
116 void CALEMainLoopThread(void *param)
118 OIC_LOG(DEBUG, TAG, "IN");
120 int ret = bt_initialize();
121 if (BT_ERROR_NONE != ret)
123 OIC_LOG(ERROR, TAG, "bt_initialize failed");
127 bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
128 //Get Bluetooth adapter state
129 ret = bt_adapter_get_state(&adapterState);
131 if (BT_ERROR_NONE != ret && BT_ADAPTER_ENABLED == adapterState)
133 ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
134 if (BT_ERROR_NONE != ret)
136 OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
141 ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
142 if (BT_ERROR_NONE != ret)
144 OIC_LOG(DEBUG, TAG, "bt_adapter_set_state_changed_cb failed");
148 ret = bt_gatt_set_connection_state_changed_cb(CALENWConnectionStateChangedCb, NULL);
149 if (BT_ERROR_NONE != ret)
151 OIC_LOG_V(ERROR, TAG,
152 "bt_gatt_set_connection_state_changed_cb has failed");
156 g_mainloop = g_main_loop_new(g_main_context_default(), FALSE);
158 ca_mutex_lock(g_btinitializeMutex);
159 g_isBTStackInitialised = true;
160 ca_mutex_unlock(g_btinitializeMutex);
161 ca_cond_signal(g_initializeCond);
163 // Run gmainloop to handle the events from bt stack
164 g_main_loop_run(g_mainloop);
165 OIC_LOG(DEBUG, TAG, "OUT");
168 CAResult_t CAInitializeLENetworkMonitor()
170 OIC_LOG(DEBUG, TAG, "IN");
172 if (NULL == g_bleDeviceStateChangedCbMutex)
174 g_bleDeviceStateChangedCbMutex = ca_mutex_new();
175 if (NULL == g_bleDeviceStateChangedCbMutex)
177 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
178 return CA_STATUS_FAILED;
182 if (NULL == g_bleConnectionStateChangedCbMutex)
184 g_bleConnectionStateChangedCbMutex = ca_mutex_new();
185 if (NULL == g_bleConnectionStateChangedCbMutex)
187 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
188 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
189 return CA_STATUS_FAILED;
193 if (NULL == g_btinitializeMutex)
195 g_btinitializeMutex = ca_mutex_new();
196 if (NULL == g_btinitializeMutex)
198 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
199 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
200 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
201 return CA_STATUS_FAILED;
205 if (NULL == g_initializeCond)
207 g_initializeCond = ca_cond_new();
208 if (NULL == g_initializeCond)
210 OIC_LOG(ERROR, TAG, "ca_cond_new failed");
211 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
212 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
213 ca_mutex_free(g_btinitializeMutex);
214 return CA_STATUS_FAILED;
217 OIC_LOG(DEBUG, TAG, "OUT");
222 void CATerminateLENetworkMonitor()
224 OIC_LOG(DEBUG, TAG, "IN");
226 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
227 g_bleDeviceStateChangedCbMutex = NULL;
229 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
230 g_bleConnectionStateChangedCbMutex = NULL;
232 ca_mutex_free(g_btinitializeMutex);
233 g_btinitializeMutex = NULL;
235 ca_cond_free(g_initializeCond);
236 g_initializeCond = NULL;
237 OIC_LOG(DEBUG, TAG, "OUT");
240 CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
242 OIC_LOG(DEBUG, TAG, "IN");
243 g_threadPoolHandle = threadPool;
244 OIC_LOG(DEBUG, TAG, "OUT");
248 CAResult_t CAStartLEAdapter()
250 OIC_LOG(DEBUG, TAG, "IN");
252 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEMainLoopThread, (void *) NULL))
254 OIC_LOG(ERROR, TAG, "Failed to create thread!");
255 return CA_STATUS_FAILED;
258 OIC_LOG(DEBUG, TAG, "OUT");
262 CAResult_t CAStopLEAdapter()
265 int ret = bt_adapter_unset_state_changed_cb();
266 if (BT_ERROR_NONE != ret)
268 OIC_LOG(DEBUG, TAG, "bt_adapter_unset_state_changed_cb failed");
269 return CA_STATUS_FAILED;
272 ret = bt_deinitialize();
273 if (BT_ERROR_NONE != ret)
275 OIC_LOG(ERROR, TAG, "bt_deinitialize failed");
276 return CA_STATUS_FAILED;
281 g_main_loop_quit(g_mainloop);
286 CAResult_t CAGetLEAdapterState()
288 OIC_LOG(DEBUG, TAG, "IN");
290 ca_mutex_lock(g_btinitializeMutex);
291 if (!g_isBTStackInitialised)
293 OIC_LOG(INFO, TAG, "Wait for BT initialization");
294 CAWaitResult_t ret = ca_cond_wait_for(g_initializeCond, g_btinitializeMutex,
296 if (CA_WAIT_TIMEDOUT == ret)
298 OIC_LOG(ERROR, TAG, "Timeout before BT initialize");
299 ca_mutex_unlock(g_btinitializeMutex);
300 return CA_STATUS_FAILED;
303 ca_mutex_unlock(g_btinitializeMutex);
305 bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
307 //Get Bluetooth adapter state
308 int ret = bt_adapter_get_state(&adapterState);
309 if (BT_ERROR_NONE != ret)
311 OIC_LOG_V(ERROR, TAG, "Bluetooth get state failed!, error num [%x]",
313 return CA_STATUS_FAILED;
316 if (BT_ADAPTER_ENABLED != adapterState)
318 OIC_LOG(DEBUG, TAG, "BT Adapter is not enabled");
319 return CA_ADAPTER_NOT_ENABLED;
322 OIC_LOG(DEBUG, TAG, "OUT");
326 CAResult_t CAGetLEAddress(char **local_address)
328 OIC_LOG(DEBUG, TAG, "IN");
330 VERIFY_NON_NULL(local_address, TAG, "local_address is null")
332 char *address = NULL;
334 int ret = bt_adapter_get_address(&address);
335 if (BT_ERROR_NONE != ret || !address)
337 OIC_LOG_V(ERROR, TAG, "bt_adapter_get_address failed!, error num [%x]",
339 return CA_STATUS_FAILED;
342 OIC_LOG_V(DEBUG, TAG, "bd address[%s]", address);
344 *local_address = address;
346 OIC_LOG(DEBUG, TAG, "OUT");
351 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
353 OIC_LOG(DEBUG, TAG, "IN");
354 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
355 g_bleDeviceStateChangedCallback = callback;
356 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
357 OIC_LOG(DEBUG, TAG, "OUT");
361 CAResult_t CAUnSetLEAdapterStateChangedCb()
363 OIC_LOG(DEBUG, TAG, "IN");
364 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
365 g_bleDeviceStateChangedCallback = NULL;
366 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
367 OIC_LOG(DEBUG, TAG, "OUT");
371 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
373 OIC_LOG(DEBUG, TAG, "IN");
374 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
375 g_bleConnectionStateChangedCallback = callback;
376 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
377 OIC_LOG(DEBUG, TAG, "OUT");
381 CAResult_t CAUnsetLENWConnectionStateChangedCb()
383 OIC_LOG(DEBUG, TAG, "IN");
384 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
385 g_bleConnectionStateChangedCallback = NULL;
386 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
387 OIC_LOG(DEBUG, TAG, "OUT");
391 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
394 OIC_LOG(DEBUG, TAG, "IN");
396 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
398 if (NULL == g_bleDeviceStateChangedCallback)
400 OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
401 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
405 if (BT_ADAPTER_DISABLED == adapter_state)
407 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
408 g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
409 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
413 OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
415 int ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
416 if (BT_ERROR_NONE != ret)
418 OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
422 g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
423 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
425 OIC_LOG(DEBUG, TAG, "OUT");
428 void CALENWConnectionStateChangedCb(int result, bool connected,
429 const char *remoteAddress, void *userData)
431 OIC_LOG(DEBUG, TAG, "IN");
433 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
435 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
436 char *addr = OICStrdup(remoteAddress);
439 OIC_LOG(ERROR, TAG, "addr is NULL");
440 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
443 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
445 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
447 OIC_LOG(DEBUG, TAG, "OUT");