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 "caipinterface.h"
23 #include <sys/types.h>
26 #include <sys/socket.h>
31 #include <sys/ioctl.h>
34 #include "caadapterutils.h"
36 #include "oic_malloc.h"
37 #include "oic_string.h"
39 #define TAG "IP_MONITOR"
40 #define MAX_INTERFACE_INFO_LENGTH (1024)
42 static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
43 uint32_t addr, int flags);
45 static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
46 char *name, int family, uint32_t addr, int flags);
48 static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
51 static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
53 int CAGetPollingInterval(int interval)
58 CAInterface_t *CAFindInterfaceChange()
63 CAResult_t CAIPInitializeNetworkMonitor()
65 OIC_LOG(DEBUG, TAG, "IN");
67 // Initialize Wifi service
68 wifi_error_e ret = wifi_initialize();
69 if (WIFI_ERROR_NONE != ret)
71 OIC_LOG(ERROR, TAG, "wifi_initialize failed");
72 return CA_STATUS_FAILED;
75 // Set callback for receiving state changes
76 ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
77 if (WIFI_ERROR_NONE != ret)
79 OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
80 return CA_STATUS_FAILED;
83 // Set callback for receiving connection state changes
84 ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
85 if (WIFI_ERROR_NONE != ret)
87 OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
88 return CA_STATUS_FAILED;
91 OIC_LOG(DEBUG, TAG, "OUT");
95 CAResult_t CAIPTerminateNetworkMonitor()
97 OIC_LOG(DEBUG, TAG, "IN");
99 // Reset callback for receiving state changes
100 wifi_error_e ret = wifi_unset_device_state_changed_cb();
101 if (WIFI_ERROR_NONE != ret)
103 OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
106 // Reset callback for receiving connection state changes
107 ret = wifi_unset_connection_state_changed_cb();
108 if (WIFI_ERROR_NONE != ret)
110 OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
113 // Deinitialize Wifi service
114 ret = wifi_deinitialize();
115 if (WIFI_ERROR_NONE != ret)
117 OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
120 OIC_LOG(DEBUG, TAG, "OUT");
124 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
126 u_arraylist_t *iflist = u_arraylist_create();
129 OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
133 char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
135 ifc.ifc_len = MAX_INTERFACE_INFO_LENGTH;
138 int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
139 if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
141 OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
142 u_arraylist_destroy(iflist);
146 struct ifreq* ifr = ifc.ifc_req;
147 int32_t interfaces = ifc.ifc_len / sizeof (struct ifreq);
149 if (interfaces > caglobals.ip.nm.numifitems)
151 int ifreqsiz = interfaces * sizeof (struct ifreq);
152 caglobals.ip.nm.numifitems = interfaces;
153 caglobals.ip.nm.ifitems = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifitems, ifreqsiz);
156 for (int i = 0; i < interfaces; i++)
158 CAResult_t result = CA_STATUS_OK;
159 struct ifreq* item = &ifr[i];
160 char *name = item->ifr_name;
161 struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr;
162 uint32_t ipv4addr = sa4->sin_addr.s_addr;
164 if (ioctl(s, SIOCGIFFLAGS, item) < 0)
166 OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno));
169 int16_t flags = item->ifr_flags;
170 if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
174 if (ioctl(s, SIOCGIFINDEX, item) < 0)
176 OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno));
179 int ifindex = item->ifr_ifindex;
180 if (desiredIndex && (ifindex != desiredIndex))
184 caglobals.ip.nm.ifitems[i].ifindex = ifindex;
186 // Add IPv4 interface
187 result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET, ipv4addr, flags);
188 if (CA_STATUS_OK != result)
193 // Add IPv6 interface
194 result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET6, ipv4addr, flags);
195 if (CA_STATUS_OK != result)
203 u_arraylist_destroy(iflist);
207 static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
208 char *name, int family, uint32_t addr, int flags)
210 CAInterface_t *ifitem = CANewInterfaceItem(index, name, family, addr, flags);
213 return CA_STATUS_FAILED;
215 CAResult_t result = u_arraylist_add(iflist, ifitem);
216 if (CA_STATUS_OK != result)
218 OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
220 return CA_STATUS_FAILED;
226 static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
227 uint32_t addr, int flags)
229 CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof (CAInterface_t));
232 OIC_LOG(ERROR, TAG, "Malloc failed");
236 OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
237 ifitem->index = index;
238 ifitem->family = family;
239 ifitem->ipv4addr = addr;
240 ifitem->flags = flags;
245 void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
248 OIC_LOG(DEBUG, TAG, "IN");
250 if (WIFI_CONNECTION_STATE_ASSOCIATION == state
251 || WIFI_CONNECTION_STATE_CONFIGURATION == state)
253 OIC_LOG(DEBUG, TAG, "Connection is in Association State");
257 // If Wifi is connected, then get the latest IP from the WIFI Interface
258 if (WIFI_CONNECTION_STATE_CONNECTED == state)
264 // TODO : Remove Ip intercase case
267 OIC_LOG(DEBUG, TAG, "OUT");
270 void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
272 OIC_LOG(DEBUG, TAG, "IN");
274 if (WIFI_DEVICE_STATE_ACTIVATED == state)
276 OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
280 CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
281 OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State");
284 OIC_LOG(DEBUG, TAG, "OUT");