Replace glib threadpool usage with a 'dumb' thread implementation.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / wifi_adapter / tizen / cawifinwmonitor.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 "cawifiinterface.h"
22
23 #include <wifi.h>
24 #include "logger.h"
25 #include "caadapterutils.h"
26 #include "camutex.h"
27 #include "oic_malloc.h"
28 #include "oic_string.h"
29
30 #define WIFI_MONITOR_TAG "WIFI_MONITOR"
31
32
33 /**
34  * @var g_wifiNetInfoMutex
35  * @brief  Mutex for synchronizing access to cached interface and IP address information.
36  */
37 static ca_mutex g_wifiNetInfoMutex = NULL;
38
39 /**
40  * @var g_wifiInterfaceName
41  * @brief  Maintains interface name.
42  */
43 static char *g_wifiInterfaceName = NULL;
44
45 /**
46  * @var g_wifiIPAddress
47  * @brief  Maintains interface IP address.
48  */
49 static char *g_wifiIPAddress = NULL;
50
51 /**
52  * @var g_wifiSubnetMask
53  * @brief  Maintains interface subnetmask.
54  */
55 static char *g_wifiSubnetMask = NULL;
56
57 /**
58  * @var g_networkChangeCb
59  * @brief  Maintains network connection state change callback.
60  */
61 static CAWiFiConnectionStateChangeCallback g_networkChangeCb = NULL;
62
63 /**
64  * @fn CAWIFIConnectionStateChangedCb
65  * @brief  This callback is registered to receive wifi network connection state changes.
66  */
67 static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
68         void *userData);
69
70 /**
71  * @fn CAWIFIDeviceStateChangedCb
72  * @brief This callback is registered to receive wifi device state changes.
73  */
74 static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
75
76 /**
77  * @fn CAWiFiGetInterfaceInformation
78  * @brief This methods gets local interface name and IP address information.
79  */
80 static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress,
81         char **subnetMask);
82
83 CAResult_t CAWiFiInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
84 {
85     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
86
87     // Initialize Wifi service
88     wifi_error_e ret = wifi_initialize();
89     if (WIFI_ERROR_NONE != ret)
90     {
91         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_initialize failed");
92         return CA_STATUS_FAILED;
93     }
94
95     if (!g_wifiNetInfoMutex)
96     {
97         g_wifiNetInfoMutex = ca_mutex_new();
98     }
99
100     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
101     return CA_STATUS_OK;
102 }
103
104 void CAWiFiTerminateNetworkMonitor(void)
105 {
106     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
107
108     // Deinitialize Wifi service
109     wifi_error_e ret = wifi_deinitialize();
110     if (WIFI_ERROR_NONE != ret)
111     {
112         OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_deinitialize failed");
113     }
114
115     if (g_wifiInterfaceName)
116     {
117         OICFree(g_wifiInterfaceName);
118         g_wifiInterfaceName = NULL;
119     }
120
121     if (g_wifiIPAddress)
122     {
123         OICFree(g_wifiIPAddress);
124         g_wifiIPAddress = NULL;
125     }
126
127     if (g_wifiSubnetMask)
128     {
129         OICFree(g_wifiSubnetMask);
130         g_wifiSubnetMask = NULL;
131     }
132
133     if (g_wifiNetInfoMutex)
134     {
135         ca_mutex_free(g_wifiNetInfoMutex);
136         g_wifiNetInfoMutex = NULL;
137     }
138
139     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
140 }
141
142 CAResult_t CAWiFiStartNetworkMonitor(void)
143 {
144     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
145
146     // Set callback for receiving state changes
147     wifi_error_e ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
148     if (WIFI_ERROR_NONE != ret)
149     {
150         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
151         return CA_STATUS_FAILED;
152     }
153
154     // Set callback for receiving connection state changes
155     ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
156     if (WIFI_ERROR_NONE != ret)
157     {
158         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
159         return CA_STATUS_FAILED;
160     }
161
162     CAWiFiGetInterfaceInformation(&g_wifiInterfaceName, &g_wifiIPAddress, &g_wifiSubnetMask);
163
164     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
165     return CA_STATUS_OK;
166 }
167
168 CAResult_t CAWiFiStopNetworkMonitor(void)
169 {
170     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
171
172     // Reset callback for receiving state changes
173     wifi_error_e ret = wifi_unset_device_state_changed_cb();
174     if (WIFI_ERROR_NONE != ret)
175     {
176         OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
177     }
178
179     // Reset callback for receiving connection state changes
180     ret = wifi_unset_connection_state_changed_cb();
181     if (WIFI_ERROR_NONE != ret)
182     {
183         OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
184     }
185
186     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
187     return CA_STATUS_OK;
188 }
189
190 CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
191 {
192     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
193
194     VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name holder is NULL");
195     VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "IP address holder is NULL");
196
197     ca_mutex_lock(g_wifiNetInfoMutex);
198
199     if (NULL == g_wifiInterfaceName || NULL == g_wifiIPAddress)
200     {
201         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Network not enabled");
202         ca_mutex_unlock(g_wifiNetInfoMutex);
203         return CA_ADAPTER_NOT_ENABLED;
204     }
205
206     if (g_wifiInterfaceName && strlen(g_wifiInterfaceName))
207     {
208         *interfaceName = OICStrdup((const char *)g_wifiInterfaceName);
209     }
210
211     if (g_wifiIPAddress && strlen(g_wifiIPAddress))
212     {
213         *ipAddress = OICStrdup((const char *)g_wifiIPAddress);
214     }
215
216     ca_mutex_unlock(g_wifiNetInfoMutex);
217
218     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
219     return CA_STATUS_OK;
220 }
221
222 CAResult_t CAWiFiGetInterfaceSubnetMask(char **subnetMask)
223 {
224     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
225
226     VERIFY_NON_NULL(subnetMask, WIFI_MONITOR_TAG, "subnet mask");
227
228     ca_mutex_lock(g_wifiNetInfoMutex);
229     if (NULL == g_wifiSubnetMask)
230     {
231         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "There is no subnet mask information!");
232         ca_mutex_unlock(g_wifiNetInfoMutex);
233         return CA_STATUS_FAILED;
234     }
235
236     *subnetMask = (g_wifiSubnetMask) ? OICStrdup((const char *)g_wifiSubnetMask): NULL;
237     ca_mutex_unlock(g_wifiNetInfoMutex);
238
239     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
240     return CA_STATUS_OK;
241 }
242
243 bool CAWiFiIsConnected(void)
244 {
245     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
246
247     wifi_connection_state_e connection_state;
248     wifi_error_e ret = wifi_get_connection_state(&connection_state);
249     if (WIFI_ERROR_NONE != ret)
250     {
251         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Failed to get the Connection State");
252         return false;
253     }
254
255     if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
256     {
257         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "WIFI is not Connected");
258         return false;
259     }
260
261     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
262     return true;
263 }
264
265 void CAWiFiSetConnectionStateChangeCallback(
266     CAWiFiConnectionStateChangeCallback callback)
267 {
268     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
269
270     g_networkChangeCb = callback;
271 }
272
273 void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
274                                     void *userData)
275 {
276     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
277
278     if (WIFI_CONNECTION_STATE_ASSOCIATION == state
279         || WIFI_CONNECTION_STATE_CONFIGURATION == state)
280     {
281         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Connection is in Association State");
282         return;
283     }
284
285     CANetworkStatus_t nwStatus = CA_INTERFACE_DOWN;
286
287     // If Wifi is connected, then get the latest IP from the WIFI Interface
288     if (WIFI_CONNECTION_STATE_CONNECTED == state)
289     {
290         nwStatus = CA_INTERFACE_UP;
291
292         // Get network information
293         char *interfaceName = NULL;
294         char *ipAddress = NULL;
295         char *subnetMask = NULL;
296         CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
297
298         // Update the cached network information
299         ca_mutex_lock(g_wifiNetInfoMutex);
300
301         OICFree(g_wifiInterfaceName);
302         OICFree(g_wifiIPAddress);
303         OICFree(g_wifiSubnetMask);
304         g_wifiInterfaceName = interfaceName;
305         g_wifiIPAddress = ipAddress;
306         g_wifiSubnetMask = subnetMask;
307
308         ca_mutex_unlock(g_wifiNetInfoMutex);
309     }
310     else
311     {
312         nwStatus = CA_INTERFACE_DOWN;
313     }
314
315     if (g_networkChangeCb)
316     {
317         g_networkChangeCb(g_wifiIPAddress, nwStatus);
318     }
319
320     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
321     return;
322 }
323
324 void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
325 {
326     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
327
328     if (WIFI_DEVICE_STATE_ACTIVATED == state)
329     {
330         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Activated State");
331     }
332     else
333     {
334         CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
335         OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Deactivated State");
336     }
337
338     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
339     return;
340 }
341
342 void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
343 {
344     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
345
346     int ret = WIFI_ERROR_NONE;
347
348     if (!interfaceName || !ipAddress || !subnetMask)
349     {
350         OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
351         return;
352     }
353
354     ca_mutex_lock(g_wifiNetInfoMutex);
355     // Get wifi interface name
356     if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
357     {
358         OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
359
360         ca_mutex_unlock(g_wifiNetInfoMutex);
361         return;
362     }
363
364     // Get wifi connected IP address
365     wifi_ap_h accessPoint = NULL;
366     if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
367     {
368         OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get access point! error num [%d]",
369                   ret);
370
371         OICFree(*interfaceName);
372         *interfaceName = NULL;
373         ca_mutex_unlock(g_wifiNetInfoMutex);
374         return;
375     }
376
377     if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
378                                   ipAddress)))
379     {
380         OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
381                   ret);
382         OICFree(*interfaceName);
383         *interfaceName = NULL;
384         ca_mutex_unlock(g_wifiNetInfoMutex);
385         return;
386     }
387
388     if (WIFI_ERROR_NONE != (ret = wifi_ap_get_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
389                                   subnetMask)))
390     {
391         OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
392                   ret);
393         OICFree(*ipAddress);
394         OICFree(*interfaceName);
395         *ipAddress = NULL;
396         *interfaceName = NULL;
397         ca_mutex_unlock(g_wifiNetInfoMutex);
398         return;
399     }
400
401     ca_mutex_unlock(g_wifiNetInfoMutex);
402
403     OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
404 }
405