Fix to notify connected state to Tizen LE client from network monitor
[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
37 #include "camutex.h"
38 #include "caleadapter.h"
39 #include "caadapterutils.h"
40
41 /**
42  * Logging tag for module name
43  */
44 #define TAG "OIC_CA_LE_MONITOR"
45
46 static GMainLoop *g_mainloop = NULL;
47 static ca_thread_pool_t g_threadPoolHandle = NULL;
48
49 /**
50  * Maintains the callback to be notified on device state changed.
51  */
52 static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
53
54 /**
55  * Maintains the callback to be notified on device state changed.
56  */
57 static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
58
59 /**
60  * Mutex to synchronize access to the deviceStateChanged Callback when the state
61  *           of the LE adapter gets change.
62  */
63 static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
64
65 /**
66  * Mutex to synchronize access to the ConnectionStateChanged Callback when the state
67  * of the LE adapter gets change.
68  */
69 static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
70
71 /**
72 * This is the callback which will be called when the adapter state gets changed.
73 *
74 * @param result         [IN] Result of the query done to the platform.
75 * @param adapter_state  [IN] State of the LE adapter.
76 * @param user_data      [IN] Any user_data passed by the caller when querying for the state changed cb.
77 *
78 * @return  None.
79 */
80 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
81                                void *user_data);
82
83 /**
84 * This is the callback which will be called when the connection state gets changed.
85 *
86 * @param result         [IN] Result of the query done to the platform.
87 * @param connected      [IN] State of connection.
88 * @param remoteAddress  [IN] LE address of the device to be notified.
89 * @param user_data      [IN] Any user_data passed by the caller when querying for the state changed cb.
90 *
91 * @return  None.
92 */
93 void CALENWConnectionStateChangedCb(int result, bool connected,
94                                     const char *remoteAddress, void *userData);
95
96 void CALEMainLoopThread(void *param)
97 {
98     g_main_loop_run(g_mainloop);
99 }
100
101 CAResult_t CAInitializeLENetworkMonitor()
102 {
103     OIC_LOG(DEBUG, TAG, "IN");
104
105     if (NULL == g_bleDeviceStateChangedCbMutex)
106     {
107         g_bleDeviceStateChangedCbMutex = ca_mutex_new();
108         if (NULL == g_bleDeviceStateChangedCbMutex)
109         {
110             OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
111             return CA_STATUS_FAILED;
112         }
113     }
114
115     if (NULL == g_bleConnectionStateChangedCbMutex)
116     {
117         g_bleConnectionStateChangedCbMutex = ca_mutex_new();
118         if (NULL == g_bleConnectionStateChangedCbMutex)
119         {
120             OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
121             ca_mutex_free(g_bleDeviceStateChangedCbMutex);
122             return CA_STATUS_FAILED;
123         }
124     }
125     OIC_LOG(DEBUG, TAG, "OUT");
126
127     return CA_STATUS_OK;
128 }
129
130 void CATerminateLENetworkMonitor()
131 {
132     OIC_LOG(DEBUG, TAG, "IN");
133
134     ca_mutex_free(g_bleDeviceStateChangedCbMutex);
135     g_bleDeviceStateChangedCbMutex = NULL;
136
137     ca_mutex_free(g_bleConnectionStateChangedCbMutex);
138     g_bleConnectionStateChangedCbMutex = NULL;
139     OIC_LOG(DEBUG, TAG, "OUT");
140 }
141
142 CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
143 {
144     OIC_LOG(DEBUG, TAG, "IN");
145     g_threadPoolHandle = threadPool;
146     OIC_LOG(DEBUG, TAG, "OUT");
147     return CA_STATUS_OK;
148 }
149
150 CAResult_t CAStartLEAdapter()
151 {
152     OIC_LOG(DEBUG, TAG, "IN");
153     g_mainloop = g_main_loop_new(NULL, 0);
154     if(!g_mainloop)
155     {
156         OIC_LOG(ERROR, TAG, "g_main_loop_new failed\n");
157         return CA_STATUS_FAILED;
158     }
159
160     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEMainLoopThread, (void *) NULL))
161     {
162         OIC_LOG(ERROR, TAG, "Failed to create thread!");
163         return CA_STATUS_FAILED;
164     }
165
166     int ret = bt_initialize();
167     if (0 != ret)
168     {
169         OIC_LOG(ERROR, TAG, "bt_initialize failed");
170         return CA_STATUS_FAILED;
171     }
172
173     ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
174     if (0 != ret)
175     {
176         OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
177         return CA_STATUS_FAILED;
178     }
179
180     ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
181     if (BT_ERROR_NONE != ret)
182     {
183         OIC_LOG(DEBUG, TAG, "bt_adapter_set_state_changed_cb failed");
184         return CA_STATUS_FAILED;
185     }
186
187     ret = bt_gatt_set_connection_state_changed_cb(CALENWConnectionStateChangedCb, NULL);
188     if (BT_ERROR_NONE != ret)
189     {
190         OIC_LOG_V(ERROR, TAG,
191                   "bt_gatt_set_connection_state_changed_cb has failed");
192         return CA_STATUS_FAILED;
193     }
194
195     OIC_LOG(DEBUG, TAG, "OUT");
196     return CA_STATUS_OK;
197 }
198
199 CAResult_t CAStopLEAdapter()
200 {
201
202     int ret = bt_adapter_unset_state_changed_cb();
203     if (BT_ERROR_NONE != ret)
204     {
205         OIC_LOG(DEBUG, TAG, "bt_adapter_unset_state_changed_cb failed");
206         return CA_STATUS_FAILED;
207     }
208
209     ret = bt_deinitialize();
210     if (0 != ret)
211     {
212         OIC_LOG(ERROR, TAG, "bt_deinitialize failed");
213         return CA_STATUS_FAILED;
214     }
215
216     if (g_mainloop)
217     {
218         g_main_loop_quit(g_mainloop);
219     }
220     return CA_STATUS_OK;
221 }
222
223 CAResult_t CAGetLEAdapterState()
224 {
225     OIC_LOG(DEBUG, TAG, "IN");
226
227     bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
228
229     //Get Bluetooth adapter state
230     int ret = bt_adapter_get_state(&adapterState);
231     if (BT_ERROR_NONE != ret)
232     {
233         OIC_LOG_V(ERROR, TAG, "Bluetooth get state failed!, error num [%x]",
234                   ret);
235         return CA_STATUS_FAILED;
236     }
237
238     if (BT_ADAPTER_ENABLED != adapterState)
239     {
240         OIC_LOG(DEBUG, TAG, "BT Adapter is not enabled");
241         return CA_ADAPTER_NOT_ENABLED;
242     }
243
244     OIC_LOG(DEBUG, TAG, "OUT");
245     return CA_STATUS_OK;
246 }
247
248 CAResult_t CAGetLEAddress(char **local_address)
249 {
250     OIC_LOG(DEBUG, TAG, "IN");
251
252     VERIFY_NON_NULL(local_address, TAG, "local_address is null")
253
254     char *address = NULL;
255
256     int ret = bt_adapter_get_address(&address);
257     if (BT_ERROR_NONE != ret || !address)
258     {
259         OIC_LOG_V(ERROR, TAG, "bt_adapter_get_address failed!, error num [%x]",
260                   ret);
261         return CA_STATUS_FAILED;
262     }
263
264     OIC_LOG_V(DEBUG, TAG, "bd address[%s]", address);
265
266     *local_address = address;
267
268     OIC_LOG(DEBUG, TAG, "OUT");
269
270     return CA_STATUS_OK;
271 }
272
273 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
274 {
275     OIC_LOG(DEBUG, TAG, "IN");
276     ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
277     g_bleDeviceStateChangedCallback = callback;
278     ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
279     OIC_LOG(DEBUG, TAG, "OUT");
280     return CA_STATUS_OK;
281 }
282
283 CAResult_t CAUnSetLEAdapterStateChangedCb()
284 {
285     OIC_LOG(DEBUG, TAG, "IN");
286     ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
287     g_bleDeviceStateChangedCallback = NULL;
288     ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
289     OIC_LOG(DEBUG, TAG, "OUT");
290     return CA_STATUS_OK;
291 }
292
293 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
294 {
295     OIC_LOG(DEBUG, TAG, "IN");
296     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
297     g_bleConnectionStateChangedCallback = callback;
298     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
299     OIC_LOG(DEBUG, TAG, "OUT");
300     return CA_STATUS_OK;
301 }
302
303 CAResult_t CAUnsetLENWConnectionStateChangedCb()
304 {
305     OIC_LOG(DEBUG, TAG, "IN");
306     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
307     g_bleConnectionStateChangedCallback = NULL;
308     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
309     OIC_LOG(DEBUG, TAG, "OUT");
310     return CA_STATUS_OK;
311 }
312
313 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
314                                           void *user_data)
315 {
316     OIC_LOG(DEBUG, TAG, "IN");
317
318     ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
319
320     if (NULL == g_bleDeviceStateChangedCallback)
321     {
322         OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
323         ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
324         return;
325     }
326
327     if (BT_ADAPTER_DISABLED == adapter_state)
328     {
329         OIC_LOG(DEBUG, TAG, "Adapter is disabled");
330         g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
331         ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
332         return;
333     }
334
335     OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
336     g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
337     ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
338
339     OIC_LOG(DEBUG, TAG, "OUT");
340 }
341
342 void CALENWConnectionStateChangedCb(int result, bool connected,
343                                     const char *remoteAddress, void *userData)
344 {
345     OIC_LOG(DEBUG, TAG, "IN");
346
347     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
348
349     ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
350     const char *addr = OICStrdup(remoteAddress);
351     if (NULL == addr)
352     {
353         OIC_LOG(ERROR, TAG, "addr is NULL");
354         ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
355         return;
356     }
357     g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
358     OICFree(addr);
359     ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
360
361     OIC_LOG(DEBUG, TAG, "OUT");
362 }