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"
27 #include "caadapterutils.h"
30 #include "oic_malloc.h"
32 #define WIFI_MONITOR_TAG "WIFI_MONITOR"
35 * @var nwConnectivityStatus
36 * @brief Maintains network status.
38 static CANetworkStatus_t nwConnectivityStatus;
41 * @var gWifiNetInfoMutex
42 * @brief Mutex for synchronizing access to cached interface and IP address information.
44 static u_mutex gWifiNetInfoMutex = NULL;
47 * @var gWifiInterfaceName
48 * @brief Maintains interface name.
50 static char *gWifiInterfaceName = NULL;
54 * @brief Maintains interface IP address.
56 static char *gWifiIPAddress = NULL;
60 * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
62 static u_thread_pool_t gThreadPool = NULL;
65 * @var gStopNetworkMonitor
66 * @brief Flag to control the Network Monitor Thread
68 static bool gStopNetworkMonitor = false;
71 * @var gNetworkChangeCb
72 * @brief Maintains network connection state change callback.
74 static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
77 * @fn CAWiFiGetInterfaceInformation
78 * @brief This methods gets local interface name and IP address information.
80 static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
82 static void CANetworkMonitorThread(void* threadData);
84 CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
86 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
88 gThreadPool = threadPool;
90 if (!gWifiNetInfoMutex)
92 gWifiNetInfoMutex = u_mutex_new();
95 u_mutex_lock(gWifiNetInfoMutex);
96 CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
97 u_mutex_unlock(gWifiNetInfoMutex);
99 nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
101 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
105 void CAWiFiTerminateNetworkMonitor(void)
107 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
111 if (gWifiInterfaceName)
113 OICFree(gWifiInterfaceName);
114 gWifiInterfaceName = NULL;
119 OICFree(gWifiIPAddress);
120 gWifiIPAddress = NULL;
123 if (gWifiNetInfoMutex)
125 u_mutex_free(gWifiNetInfoMutex);
126 gWifiNetInfoMutex = NULL;
129 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
132 CAResult_t CAWiFiStartNetworkMonitor(void)
134 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
136 u_mutex_lock(gWifiNetInfoMutex);
137 gStopNetworkMonitor = false;
138 u_mutex_unlock(gWifiNetInfoMutex);
140 if (gStopNetworkMonitor)
142 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Network Monitor Thread is already running!");
143 return CA_SERVER_STARTED_ALREADY;
146 if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CANetworkMonitorThread,
149 OIC_LOG(ERROR, WIFI_MONITOR_TAG, "[ThreadPool] thread_pool_add_task failed!");
150 return CA_STATUS_FAILED;
153 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
157 CAResult_t CAWiFiStopNetworkMonitor(void)
159 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
161 if (gStopNetworkMonitor)
163 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "CAWiFiStopNetworkMonitor, already stopped");
168 u_mutex_lock(gWifiNetInfoMutex);
169 gStopNetworkMonitor = true;
170 u_mutex_unlock(gWifiNetInfoMutex);
172 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
176 CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
178 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
180 VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name holder is NULL");
181 VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "IP address holder is NULL");
183 u_mutex_lock(gWifiNetInfoMutex);
185 if (gWifiInterfaceName && strlen(gWifiInterfaceName))
187 *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName, strlen(gWifiInterfaceName)) :
191 if (gWifiIPAddress && strlen(gWifiIPAddress))
193 *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress, strlen(gWifiIPAddress)) :
197 u_mutex_unlock(gWifiNetInfoMutex);
199 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
203 bool CAWiFiIsConnected(void)
205 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
207 if (nwConnectivityStatus == CA_INTERFACE_DOWN)
213 void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
215 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
217 gNetworkChangeCb = callback;
220 void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
222 struct ifaddrs *ifa = NULL;
223 struct ifaddrs *ifp = NULL;
225 if (getifaddrs(&ifp) < 0)
227 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get network interface list error");
230 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
232 char localIPAddress[CA_IPADDR_SIZE];
235 if (ifa->ifa_addr == NULL)
238 if (ifa->ifa_addr->sa_family == AF_INET)
239 len = sizeof(struct sockaddr_in);
240 else if (ifa->ifa_addr->sa_family == AF_INET6)
245 if (getnameinfo(ifa->ifa_addr, len, localIPAddress,
246 sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST) < 0)
248 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get IPAddress fail");
251 // except loopback address
252 if (strcmp(localIPAddress, "127.0.0.1") == 0)
255 // set interface name
256 *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
258 // set local ip address
259 *ipAddress = strndup(localIPAddress, strlen(localIPAddress));
265 void CANetworkMonitorThread(void* threadData)
267 while (!gStopNetworkMonitor)
269 if (gStopNetworkMonitor)
271 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Stop Network Monitor Thread is called");
275 // Get network information
276 CANetworkStatus_t currNetworkStatus;
277 char *interfaceName = NULL;
278 char *ipAddress = NULL;
279 CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
281 // check current network status
282 currNetworkStatus = (ipAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
284 // if network status is changed
285 if (currNetworkStatus != nwConnectivityStatus)
287 // set current network information
288 u_mutex_lock(gWifiNetInfoMutex);
290 nwConnectivityStatus = currNetworkStatus;
292 OICFree(gWifiInterfaceName);
293 OICFree(gWifiIPAddress);
294 gWifiInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
295 gWifiIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
297 u_mutex_unlock(gWifiNetInfoMutex);
299 if (gNetworkChangeCb)
301 gNetworkChangeCb(gWifiIPAddress, nwConnectivityStatus);
304 OICFree(interfaceName);