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");
126 ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
127 if (BT_ERROR_NONE != ret)
129 OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
133 ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
134 if (BT_ERROR_NONE != ret)
136 OIC_LOG(DEBUG, TAG, "bt_adapter_set_state_changed_cb failed");
140 ret = bt_gatt_set_connection_state_changed_cb(CALENWConnectionStateChangedCb, NULL);
141 if (BT_ERROR_NONE != ret)
143 OIC_LOG_V(ERROR, TAG,
144 "bt_gatt_set_connection_state_changed_cb has failed");
148 g_mainloop = g_main_loop_new(g_main_context_default(), FALSE);
150 ca_mutex_lock(g_btinitializeMutex);
151 g_isBTStackInitialised = true;
152 ca_mutex_unlock(g_btinitializeMutex);
153 ca_cond_signal(g_initializeCond);
155 // Run gmainloop to handle the events from bt stack
156 g_main_loop_run(g_mainloop);
157 OIC_LOG(DEBUG, TAG, "OUT");
160 CAResult_t CAInitializeLENetworkMonitor()
162 OIC_LOG(DEBUG, TAG, "IN");
164 if (NULL == g_bleDeviceStateChangedCbMutex)
166 g_bleDeviceStateChangedCbMutex = ca_mutex_new();
167 if (NULL == g_bleDeviceStateChangedCbMutex)
169 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
170 return CA_STATUS_FAILED;
174 if (NULL == g_bleConnectionStateChangedCbMutex)
176 g_bleConnectionStateChangedCbMutex = ca_mutex_new();
177 if (NULL == g_bleConnectionStateChangedCbMutex)
179 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
180 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
181 return CA_STATUS_FAILED;
185 if (NULL == g_btinitializeMutex)
187 g_btinitializeMutex = ca_mutex_new();
188 if (NULL == g_btinitializeMutex)
190 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
191 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
192 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
193 return CA_STATUS_FAILED;
197 if (NULL == g_initializeCond)
199 g_initializeCond = ca_cond_new();
200 if (NULL == g_initializeCond)
202 OIC_LOG(ERROR, TAG, "ca_cond_new failed");
203 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
204 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
205 ca_mutex_free(g_btinitializeMutex);
206 return CA_STATUS_FAILED;
209 OIC_LOG(DEBUG, TAG, "OUT");
214 void CATerminateLENetworkMonitor()
216 OIC_LOG(DEBUG, TAG, "IN");
218 ca_mutex_free(g_bleDeviceStateChangedCbMutex);
219 g_bleDeviceStateChangedCbMutex = NULL;
221 ca_mutex_free(g_bleConnectionStateChangedCbMutex);
222 g_bleConnectionStateChangedCbMutex = NULL;
224 ca_mutex_free(g_btinitializeMutex);
225 g_btinitializeMutex = NULL;
227 ca_cond_free(g_initializeCond);
228 g_initializeCond = NULL;
229 OIC_LOG(DEBUG, TAG, "OUT");
232 CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
234 OIC_LOG(DEBUG, TAG, "IN");
235 g_threadPoolHandle = threadPool;
236 OIC_LOG(DEBUG, TAG, "OUT");
240 CAResult_t CAStartLEAdapter()
242 OIC_LOG(DEBUG, TAG, "IN");
244 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEMainLoopThread, (void *) NULL))
246 OIC_LOG(ERROR, TAG, "Failed to create thread!");
247 return CA_STATUS_FAILED;
250 OIC_LOG(DEBUG, TAG, "OUT");
254 CAResult_t CAStopLEAdapter()
257 int ret = bt_adapter_unset_state_changed_cb();
258 if (BT_ERROR_NONE != ret)
260 OIC_LOG(DEBUG, TAG, "bt_adapter_unset_state_changed_cb failed");
261 return CA_STATUS_FAILED;
264 ret = bt_deinitialize();
265 if (BT_ERROR_NONE != ret)
267 OIC_LOG(ERROR, TAG, "bt_deinitialize failed");
268 return CA_STATUS_FAILED;
273 g_main_loop_quit(g_mainloop);
278 CAResult_t CAGetLEAdapterState()
280 OIC_LOG(DEBUG, TAG, "IN");
282 ca_mutex_lock(g_btinitializeMutex);
283 if (!g_isBTStackInitialised)
285 OIC_LOG(INFO, TAG, "Wait for BT initialization");
286 CAWaitResult_t ret = ca_cond_wait_for(g_initializeCond, g_btinitializeMutex,
288 if (CA_WAIT_TIMEDOUT == ret)
290 OIC_LOG(ERROR, TAG, "Timeout before BT initialize");
291 ca_mutex_unlock(g_btinitializeMutex);
292 return CA_STATUS_FAILED;
295 ca_mutex_unlock(g_btinitializeMutex);
297 bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
299 //Get Bluetooth adapter state
300 int ret = bt_adapter_get_state(&adapterState);
301 if (BT_ERROR_NONE != ret)
303 OIC_LOG_V(ERROR, TAG, "Bluetooth get state failed!, error num [%x]",
305 return CA_STATUS_FAILED;
308 if (BT_ADAPTER_ENABLED != adapterState)
310 OIC_LOG(DEBUG, TAG, "BT Adapter is not enabled");
311 return CA_ADAPTER_NOT_ENABLED;
314 OIC_LOG(DEBUG, TAG, "OUT");
318 CAResult_t CAGetLEAddress(char **local_address)
320 OIC_LOG(DEBUG, TAG, "IN");
322 VERIFY_NON_NULL(local_address, TAG, "local_address is null")
324 char *address = NULL;
326 int ret = bt_adapter_get_address(&address);
327 if (BT_ERROR_NONE != ret || !address)
329 OIC_LOG_V(ERROR, TAG, "bt_adapter_get_address failed!, error num [%x]",
331 return CA_STATUS_FAILED;
334 OIC_LOG_V(DEBUG, TAG, "bd address[%s]", address);
336 *local_address = address;
338 OIC_LOG(DEBUG, TAG, "OUT");
343 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
345 OIC_LOG(DEBUG, TAG, "IN");
346 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
347 g_bleDeviceStateChangedCallback = callback;
348 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
349 OIC_LOG(DEBUG, TAG, "OUT");
353 CAResult_t CAUnSetLEAdapterStateChangedCb()
355 OIC_LOG(DEBUG, TAG, "IN");
356 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
357 g_bleDeviceStateChangedCallback = NULL;
358 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
359 OIC_LOG(DEBUG, TAG, "OUT");
363 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
365 OIC_LOG(DEBUG, TAG, "IN");
366 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
367 g_bleConnectionStateChangedCallback = callback;
368 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
369 OIC_LOG(DEBUG, TAG, "OUT");
373 CAResult_t CAUnsetLENWConnectionStateChangedCb()
375 OIC_LOG(DEBUG, TAG, "IN");
376 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
377 g_bleConnectionStateChangedCallback = NULL;
378 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
379 OIC_LOG(DEBUG, TAG, "OUT");
383 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
386 OIC_LOG(DEBUG, TAG, "IN");
388 ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
390 if (NULL == g_bleDeviceStateChangedCallback)
392 OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
393 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
397 if (BT_ADAPTER_DISABLED == adapter_state)
399 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
400 g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
401 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
405 OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
406 g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
407 ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
409 OIC_LOG(DEBUG, TAG, "OUT");
412 void CALENWConnectionStateChangedCb(int result, bool connected,
413 const char *remoteAddress, void *userData)
415 OIC_LOG(DEBUG, TAG, "IN");
417 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
419 ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
420 char *addr = OICStrdup(remoteAddress);
423 OIC_LOG(ERROR, TAG, "addr is NULL");
424 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
427 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
429 ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
431 OIC_LOG(DEBUG, TAG, "OUT");