dd4e3f3ef3d0bbbcbeca15c172259763dec66ad5
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / 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 "caleinterface.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <glib.h>
27 #include <arpa/inet.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31
32 #include <bluetooth.h>
33 #include <bluetooth_internal.h>
34 #include <bluetooth_type.h>
35
36 #include "camutex.h"
37 #include "caleadapter.h"
38 #include "caadapterutils.h"
39 #include "oic_string.h"
40 #include "oic_malloc.h"
41
42 /**
43  * Logging tag for module name
44  */
45 #define TAG "OIC_CA_LE_MONITOR"
46
47 #define MICROSECS_PER_SEC 1000000
48
49 static uint64_t const INITIALIZE_TIMEOUT = 1 * MICROSECS_PER_SEC;
50
51 static GMainLoop *g_mainloop = NULL;
52 static ca_thread_pool_t g_threadPoolHandle = NULL;
53
54 /**
55  * Maintains the callback to be notified on device state changed.
56  */
57 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
58
59 /**
60  * Maintains the callback to be notified on device state changed.
61  */
62 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
63
64 /**
65  * Mutex to synchronize access to the deviceStateChanged Callback when the state
66  *           of the LE adapter gets change.
67  */
68 static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
69
70 /**
71  * Mutex to synchronize access to the ConnectionStateChanged Callback when the state
72  * of the LE adapter gets change.
73  */
74 static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
75
76 /**
77  * Mutex to synchronize access to
78  */
79 static ca_mutex g_btinitializeMutex = NULL;
80
81 /**
82  * Condition for gmainloop to run.
83  */
84 static ca_cond g_initializeCond = NULL;
85
86 /**
87  * Flag to check if BT stack is initialised.
88  */
89 static bool g_isBTStackInitialised = false;
90
91 /**
92 * This is the callback which will be called when the adapter state gets changed.
93 *
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.
97 *
98 * @return  None.
99 */
100 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
101                                void *user_data);
102
103 /**
104 * This is the callback which will be called when the connection state gets changed.
105 *
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.
110 *
111 * @return  None.
112 */
113 void CALENWConnectionStateChangedCb(int result, bool connected,
114                                     const char *remoteAddress, void *userData);
115
116 void CALEMainLoopThread(void *param)
117 {
118     OIC_LOG(DEBUG, TAG, "IN");
119
120     int ret = bt_initialize();
121     if (BT_ERROR_NONE != ret)
122     {
123         OIC_LOG(ERROR, TAG, "bt_initialize failed");
124         return;
125     }
126     ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
127     if (BT_ERROR_NONE != ret)
128     {
129         OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
130         return;
131     }
132
133     ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
134     if (BT_ERROR_NONE != ret)
135     {
136         OIC_LOG(DEBUG, TAG, "bt_adapter_set_state_changed_cb failed");
137         return;
138     }
139
140     ret = bt_gatt_set_connection_state_changed_cb(CALENWConnectionStateChangedCb, NULL);
141     if (BT_ERROR_NONE != ret)
142     {
143         OIC_LOG_V(ERROR, TAG,
144                   "bt_gatt_set_connection_state_changed_cb has failed");
145         return;
146     }
147
148     g_mainloop = g_main_loop_new(g_main_context_default(), FALSE);
149
150     ca_mutex_lock(g_btinitializeMutex);
151     g_isBTStackInitialised = true;
152     ca_mutex_unlock(g_btinitializeMutex);
153     ca_cond_signal(g_initializeCond);
154
155     // Run gmainloop to handle the events from bt stack
156     g_main_loop_run(g_mainloop);
157     OIC_LOG(DEBUG, TAG, "OUT");
158 }
159
160 CAResult_t CAInitializeLENetworkMonitor()
161 {
162     OIC_LOG(DEBUG, TAG, "IN");
163
164     if (NULL == g_bleDeviceStateChangedCbMutex)
165     {
166         g_bleDeviceStateChangedCbMutex = ca_mutex_new();
167         if (NULL == g_bleDeviceStateChangedCbMutex)
168         {
169             OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
170             return CA_STATUS_FAILED;
171         }
172     }
173
174     if (NULL == g_bleConnectionStateChangedCbMutex)
175     {
176         g_bleConnectionStateChangedCbMutex = ca_mutex_new();
177         if (NULL == g_bleConnectionStateChangedCbMutex)
178         {
179             OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
180             ca_mutex_free(g_bleDeviceStateChangedCbMutex);
181             return CA_STATUS_FAILED;
182         }
183     }
184
185     if (NULL == g_btinitializeMutex)
186     {
187         g_btinitializeMutex = ca_mutex_new();
188         if (NULL == g_btinitializeMutex)
189         {
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;
194         }
195     }
196
197     if (NULL == g_initializeCond)
198     {
199         g_initializeCond = ca_cond_new();
200         if (NULL == g_initializeCond)
201         {
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;
207         }
208     }
209     OIC_LOG(DEBUG, TAG, "OUT");
210
211     return CA_STATUS_OK;
212 }
213
214 void CATerminateLENetworkMonitor()
215 {
216     OIC_LOG(DEBUG, TAG, "IN");
217
218     ca_mutex_free(g_bleDeviceStateChangedCbMutex);
219     g_bleDeviceStateChangedCbMutex = NULL;
220
221     ca_mutex_free(g_bleConnectionStateChangedCbMutex);
222     g_bleConnectionStateChangedCbMutex = NULL;
223
224     ca_mutex_free(g_btinitializeMutex);
225     g_btinitializeMutex = NULL;
226
227     ca_cond_free(g_initializeCond);
228     g_initializeCond = NULL;
229     OIC_LOG(DEBUG, TAG, "OUT");
230 }
231
232 CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
233 {
234     OIC_LOG(DEBUG, TAG, "IN");
235     g_threadPoolHandle = threadPool;
236     OIC_LOG(DEBUG, TAG, "OUT");
237     return CA_STATUS_OK;
238 }
239
240 CAResult_t CAStartLEAdapter()
241 {
242     OIC_LOG(DEBUG, TAG, "IN");
243
244     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEMainLoopThread, (void *) NULL))
245     {
246         OIC_LOG(ERROR, TAG, "Failed to create thread!");
247         return CA_STATUS_FAILED;
248     }
249
250     OIC_LOG(DEBUG, TAG, "OUT");
251     return CA_STATUS_OK;
252 }
253
254 CAResult_t CAStopLEAdapter()
255 {
256
257     int ret = bt_adapter_unset_state_changed_cb();
258     if (BT_ERROR_NONE != ret)
259     {
260         OIC_LOG(DEBUG, TAG, "bt_adapter_unset_state_changed_cb failed");
261         return CA_STATUS_FAILED;
262     }
263
264     ret = bt_deinitialize();
265     if (BT_ERROR_NONE != ret)
266     {
267         OIC_LOG(ERROR, TAG, "bt_deinitialize failed");
268         return CA_STATUS_FAILED;
269     }
270
271     if (g_mainloop)
272     {
273         g_main_loop_quit(g_mainloop);
274     }
275     return CA_STATUS_OK;
276 }
277
278 CAResult_t CAGetLEAdapterState()
279 {
280     OIC_LOG(DEBUG, TAG, "IN");
281
282     ca_mutex_lock(g_btinitializeMutex);
283     if (!g_isBTStackInitialised)
284     {
285         OIC_LOG(INFO, TAG, "Wait for BT initialization");
286         CAWaitResult_t ret = ca_cond_wait_for(g_initializeCond, g_btinitializeMutex,
287                                               INITIALIZE_TIMEOUT);
288         if (CA_WAIT_TIMEDOUT == ret)
289         {
290             OIC_LOG(ERROR, TAG, "Timeout before BT initialize");
291             ca_mutex_unlock(g_btinitializeMutex);
292             return CA_STATUS_FAILED;
293         }
294     }
295     ca_mutex_unlock(g_btinitializeMutex);
296
297     bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
298
299     //Get Bluetooth adapter state
300     int ret = bt_adapter_get_state(&adapterState);
301     if (BT_ERROR_NONE != ret)
302     {
303         OIC_LOG_V(ERROR, TAG, "Bluetooth get state failed!, error num [%x]",
304                   ret);
305         return CA_STATUS_FAILED;
306     }
307
308     if (BT_ADAPTER_ENABLED != adapterState)
309     {
310         OIC_LOG(DEBUG, TAG, "BT Adapter is not enabled");
311         return CA_ADAPTER_NOT_ENABLED;
312     }
313
314     OIC_LOG(DEBUG, TAG, "OUT");
315     return CA_STATUS_OK;
316 }
317
318 CAResult_t CAGetLEAddress(char **local_address)
319 {
320     OIC_LOG(DEBUG, TAG, "IN");
321
322     VERIFY_NON_NULL(local_address, TAG, "local_address is null")
323
324     char *address = NULL;
325
326     int ret = bt_adapter_get_address(&address);
327     if (BT_ERROR_NONE != ret || !address)
328     {
329         OIC_LOG_V(ERROR, TAG, "bt_adapter_get_address failed!, error num [%x]",
330                   ret);
331         return CA_STATUS_FAILED;
332     }
333
334     OIC_LOG_V(DEBUG, TAG, "bd address[%s]", address);
335
336     *local_address = address;
337
338     OIC_LOG(DEBUG, TAG, "OUT");
339
340     return CA_STATUS_OK;
341 }
342
343 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
344 {
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");
350     return CA_STATUS_OK;
351 }
352
353 CAResult_t CAUnSetLEAdapterStateChangedCb()
354 {
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");
360     return CA_STATUS_OK;
361 }
362
363 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
364 {
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");
370     return CA_STATUS_OK;
371 }
372
373 CAResult_t CAUnsetLENWConnectionStateChangedCb()
374 {
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");
380     return CA_STATUS_OK;
381 }
382
383 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
384                                           void *user_data)
385 {
386     OIC_LOG(DEBUG, TAG, "IN");
387
388     ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
389
390     if (NULL == g_bleDeviceStateChangedCallback)
391     {
392         OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
393         ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
394         return;
395     }
396
397     if (BT_ADAPTER_DISABLED == adapter_state)
398     {
399         OIC_LOG(DEBUG, TAG, "Adapter is disabled");
400         g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
401         ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
402         return;
403     }
404
405     OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
406     g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
407     ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
408
409     OIC_LOG(DEBUG, TAG, "OUT");
410 }
411
412 void CALENWConnectionStateChangedCb(int result, bool connected,
413                                     const char *remoteAddress, void *userData)
414 {
415     OIC_LOG(DEBUG, TAG, "IN");
416
417     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
418
419     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
420     char *addr = OICStrdup(remoteAddress);
421     if (NULL == addr)
422     {
423         OIC_LOG(ERROR, TAG, "addr is NULL");
424         ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
425         return;
426     }
427     g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
428     OICFree(addr);
429     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
430
431     OIC_LOG(DEBUG, TAG, "OUT");
432 }