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