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 "cawifiinterface.h"
25 #include "caadapterutils.h"
27 #include "oic_malloc.h"
29 #define WIFI_MONITOR_TAG "WIFI_MONITOR"
33 * @var gWifiNetInfoMutex
34 * @brief Mutex for synchronizing access to cached interface and IP address information.
36 static u_mutex gWifiNetInfoMutex = NULL;
39 * @var gWifiInterfaceName
40 * @brief Maintains interface name.
42 static char *gWifiInterfaceName = NULL;
46 * @brief Maintains interface IP address.
48 static char *gWifiIPAddress = NULL;
51 * @var gWifiSubnetMask
52 * @brief Maintains interface subnetmask.
54 static char *gWifiSubnetMask = NULL;
57 * @var gNetworkChangeCb
58 * @brief Maintains network connection state change callback.
60 static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
63 * @fn CAWIFIConnectionStateChangedCb
64 * @brief This callback is registered to receive wifi network connection state changes.
66 static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
70 * @fn CAWIFIDeviceStateChangedCb
71 * @brief This callback is registered to receive wifi device state changes.
73 static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
76 * @fn CAWiFiGetInterfaceInformation
77 * @brief This methods gets local interface name and IP address information.
79 static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress,
82 CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
84 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
86 // Initialize Wifi service
87 wifi_error_e ret = wifi_initialize();
88 if (WIFI_ERROR_NONE != ret)
90 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_initialize failed");
91 return CA_STATUS_FAILED;
94 if (!gWifiNetInfoMutex)
96 gWifiNetInfoMutex = u_mutex_new();
99 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
103 void CAWiFiTerminateNetworkMonitor(void)
105 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
107 // Deinitialize Wifi service
108 wifi_error_e ret = wifi_deinitialize();
109 if (WIFI_ERROR_NONE != ret)
111 OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_deinitialize failed");
114 if (gWifiInterfaceName)
116 OICFree(gWifiInterfaceName);
117 gWifiInterfaceName = NULL;
122 OICFree(gWifiIPAddress);
123 gWifiIPAddress = NULL;
128 OICFree(gWifiSubnetMask);
129 gWifiSubnetMask = NULL;
132 if (gWifiNetInfoMutex)
134 u_mutex_free(gWifiNetInfoMutex);
135 gWifiNetInfoMutex = NULL;
138 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
141 CAResult_t CAWiFiStartNetworkMonitor(void)
143 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
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)
149 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
150 return CA_STATUS_FAILED;
153 // Set callback for receiving connection state changes
154 ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
155 if (WIFI_ERROR_NONE != ret)
157 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
158 return CA_STATUS_FAILED;
161 CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress, &gWifiSubnetMask);
163 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
167 CAResult_t CAWiFiStopNetworkMonitor(void)
169 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
171 // Reset callback for receiving state changes
172 wifi_error_e ret = wifi_unset_device_state_changed_cb();
173 if (WIFI_ERROR_NONE != ret)
175 OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
178 // Reset callback for receiving connection state changes
179 ret = wifi_unset_connection_state_changed_cb();
180 if (WIFI_ERROR_NONE != ret)
182 OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
185 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
189 CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
191 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
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");
196 u_mutex_lock(gWifiNetInfoMutex);
198 if (NULL == gWifiInterfaceName || NULL == gWifiIPAddress)
200 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Network not enabled");
201 u_mutex_unlock(gWifiNetInfoMutex);
202 return CA_ADAPTER_NOT_ENABLED;
205 if (gWifiInterfaceName && strlen(gWifiInterfaceName))
207 *interfaceName = strndup(gWifiInterfaceName, strlen(gWifiInterfaceName));
210 if (gWifiIPAddress && strlen(gWifiIPAddress))
212 *ipAddress = strndup(gWifiIPAddress, strlen(gWifiIPAddress));
215 u_mutex_unlock(gWifiNetInfoMutex);
217 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
221 CAResult_t CAWiFiGetInterfaceSubnetMask(char **subnetMask)
223 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
225 VERIFY_NON_NULL(subnetMask, WIFI_MONITOR_TAG, "subnet mask");
227 u_mutex_lock(gWifiNetInfoMutex);
228 if (NULL == gWifiSubnetMask)
230 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "There is no subnet mask information!");
231 return CA_STATUS_FAILED;
234 *subnetMask = (gWifiSubnetMask) ? strndup(gWifiSubnetMask, strlen(gWifiSubnetMask))
236 u_mutex_unlock(gWifiNetInfoMutex);
238 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
242 bool CAWiFiIsConnected(void)
244 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
246 wifi_connection_state_e connection_state;
247 wifi_error_e ret = wifi_get_connection_state(&connection_state);
248 if (WIFI_ERROR_NONE != ret)
250 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get the Connection State");
254 if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
256 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "WIFI is not Connected");
260 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
264 void CAWiFiSetConnectionStateChangeCallback(
265 CAWiFiConnectionStateChangeCallback callback)
267 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
269 gNetworkChangeCb = callback;
272 void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
275 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
277 if (WIFI_CONNECTION_STATE_ASSOCIATION == state
278 || WIFI_CONNECTION_STATE_CONFIGURATION == state)
280 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Connection is in Association State");
284 CANetworkStatus_t nwStatus = CA_INTERFACE_DOWN;
286 // If Wifi is connected, then get the latest IP from the WIFI Interface
287 if (WIFI_CONNECTION_STATE_CONNECTED == state)
289 nwStatus = CA_INTERFACE_UP;
291 // Get network information
292 char *interfaceName = NULL;
293 char *ipAddress = NULL;
294 char *subnetMask = NULL;
295 CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
297 // Update the cached network information
298 u_mutex_lock(gWifiNetInfoMutex);
300 OICFree(gWifiInterfaceName);
301 OICFree(gWifiIPAddress);
302 OICFree(gWifiSubnetMask);
303 gWifiInterfaceName = interfaceName;
304 gWifiIPAddress = ipAddress;
305 gWifiSubnetMask = subnetMask;
307 u_mutex_unlock(gWifiNetInfoMutex);
311 nwStatus = CA_INTERFACE_DOWN;
314 if (gNetworkChangeCb)
316 gNetworkChangeCb(gWifiIPAddress, nwStatus);
319 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
323 void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
325 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
327 if (WIFI_DEVICE_STATE_ACTIVATED == state)
329 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Activated State");
333 CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
334 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Deactivated State");
337 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
341 void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
343 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
345 int ret = WIFI_ERROR_NONE;
347 if (!interfaceName || !ipAddress || !subnetMask)
349 OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
353 u_mutex_lock(gWifiNetInfoMutex);
354 // Get wifi interface name
355 if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
357 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
359 u_mutex_unlock(gWifiNetInfoMutex);
363 // Get wifi connected IP address
364 wifi_ap_h accessPoint = NULL;
365 if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
367 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get access point! error num [%d]",
370 OICFree(*interfaceName);
371 *interfaceName = NULL;
372 u_mutex_unlock(gWifiNetInfoMutex);
376 if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
379 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
381 OICFree(*interfaceName);
382 *interfaceName = NULL;
383 u_mutex_unlock(gWifiNetInfoMutex);
387 if (WIFI_ERROR_NONE != (ret = wifi_ap_get_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
390 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
393 OICFree(*interfaceName);
395 *interfaceName = NULL;
396 u_mutex_unlock(gWifiNetInfoMutex);
400 u_mutex_unlock(gWifiNetInfoMutex);
402 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");