#include "caipinterface.h"
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
#include <wifi.h>
#include "caadapterutils.h"
-#include "camutex.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
-#define IP_MONITOR_TAG "IP_MONITOR"
+#define TAG "IP_MONITOR"
+#define MAX_INTERFACE_INFO_LENGTH (1024)
-/**
- * @var g_networkMonitorContextMutex
- * @brief Mutex for synchronizing access to cached interface and IP address information.
- */
-static ca_mutex g_networkMonitorContextMutex = NULL;
+static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
+ uint32_t addr, int flags);
-/**
- * @struct CAIPNwMonitorContext
- * @brief Used for storing network monitor context information.
- */
-typedef struct
-{
- u_arraylist_t *netInterfaceList;
- ca_thread_pool_t threadPool;
- CANetworkStatus_t nwConnectivityStatus;
- CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
-
-/**
- * @var g_networkMonitorContext
- * @brief network monitor context.
- */
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
-
-static void CARemoveInterfaceInfo()
-{
- ca_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->netInterfaceList)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG,
- "netInterfaceList is empty");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return;
- }
-
- uint32_t list_index = 0;
- uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
- for (list_index = 0; list_index < list_length; list_index++)
- {
- CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
- g_networkMonitorContext->netInterfaceList, list_index);
- if (!netInfo)
- {
- continue;
- }
-
- if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
- {
- if (g_networkMonitorContext->networkChangeCb)
- {
- g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
- CA_INTERFACE_DOWN);
- }
- }
- else
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
- }
+static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
+ char *name, int family, uint32_t addr, int flags);
- OICFree(netInfo);
- }
+static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
+ void *userData);
- u_arraylist_free(&g_networkMonitorContext->netInterfaceList);
+static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
- ca_mutex_unlock(g_networkMonitorContextMutex);
-}
-static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
+int CAGetPollingInterval(int interval)
{
- VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
-
- ca_mutex_lock(g_networkMonitorContextMutex);
- uint32_t list_index = 0;
- uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
- for (list_index = 0; list_index < list_length; list_index++)
- {
- CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
- g_networkMonitorContext->netInterfaceList, list_index);
- if (!netInfo)
- {
- continue;
- }
-
- if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
- {
- if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
- {
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return false;
- }
- else
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
- if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
- {
- if (g_networkMonitorContext->networkChangeCb)
- {
- g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
- CA_INTERFACE_DOWN);
- }
- OICFree(netInfo);
- }
- else
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
- }
- break;
- }
- }
- }
-
- CANetInfo_t *newNetInfo = (CANetInfo_t *)OICMalloc(sizeof(CANetInfo_t));
- if (!newNetInfo)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return false;
- }
- memcpy(newNetInfo, info, sizeof(*newNetInfo));
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
-
- CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
- (void *)newNetInfo);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
- OICFree(newNetInfo);
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return false;
- }
- ca_mutex_unlock(g_networkMonitorContextMutex);
-
- /*Callback will be unset only at the time of termination. By that time, all the threads will be
- stopped gracefully. This callback is properly protected*/
- if (g_networkMonitorContext->networkChangeCb)
- {
- g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
- }
-
- return true;
+ return interval;
}
-void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
+CAInterface_t *CAFindInterfaceChange()
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- int ret = WIFI_ERROR_NONE;
+ char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+ struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
- if (!interfaceName || !ipAddress || !subnetMask)
+ int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
+ if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
- return;
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
+ return NULL;
}
- // Get wifi interface name
- if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
- {
- OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
- return;
- }
-
- // Get wifi connected IP address
- wifi_ap_h accessPoint = NULL;
- if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
- {
- OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get access point! error num [%d]",
- ret);
-
- OICFree(*interfaceName);
- *interfaceName = NULL;
- return;
- }
+ CAInterface_t *foundNewInterface = NULL;
- if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
- ipAddress)))
- {
- OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
- ret);
- OICFree(*interfaceName);
- *interfaceName = NULL;
- return;
- }
+ struct ifreq* ifr = ifc.ifc_req;
+ size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]);
+ size_t ifreqsize = ifc.ifc_len;
- if (WIFI_ERROR_NONE != (ret = wifi_ap_get_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
- subnetMask)))
+ CAIfItem_t *previous = (CAIfItem_t *)OICMalloc(ifreqsize);
+ if (!previous)
{
- OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
- ret);
- OICFree(*ipAddress);
- OICFree(*interfaceName);
- *ipAddress = NULL;
- *interfaceName = NULL;
- return;
+ OIC_LOG(ERROR, TAG, "OICMalloc failed");
+ return NULL;
}
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
+ memcpy(previous, caglobals.ip.nm.ifItems, ifreqsize);
+ size_t numprevious = caglobals.ip.nm.numIfItems;
-static void CAIPGetInterfaceInformation(u_arraylist_t **netInterfaceList)
-{
- VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
- // Get wifi network information
- char *interfaceName = NULL;
- char *ipAddress = NULL;
- char *subnetMask = NULL;
- ///TODO: currently we are filling single interface. Once found the proper tizen apis for
- // getting multiple interfaces, then this function will be updated.
- CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
-
- if (!interfaceName || !ipAddress || !subnetMask)
+ if (ifreqsize > caglobals.ip.nm.sizeIfItems)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "interface/ipaddress/subnetmask is NULL!");
- return;
- }
- CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
- if (!netInfo)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
- OICFree(interfaceName);
- OICFree(ipAddress);
- OICFree(subnetMask);
- return;
+ CAIfItem_t *items = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifItems, ifreqsize);
+ if (!items)
+ {
+ OIC_LOG(ERROR, TAG, "OICRealloc failed");
+ OICFree(previous);
+ return NULL;
+ }
+ caglobals.ip.nm.ifItems = items;
+ caglobals.ip.nm.sizeIfItems = ifreqsize;
}
- // set interface name
- strncpy(netInfo->interfaceName, interfaceName, strlen(interfaceName));
-
- // set local ip address
- strncpy(netInfo->ipAddress, ipAddress, strlen(ipAddress));
-
- // set subnet mask
- strncpy(netInfo->subnetMask, subnetMask, strlen(subnetMask));
-
- CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)netInfo);
- if (CA_STATUS_OK != result)
+ caglobals.ip.nm.numIfItems = 0;
+ for (size_t i = 0; i < interfaces; i++)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
- }
- OICFree(interfaceName);
- OICFree(ipAddress);
- OICFree(subnetMask);
-}
-
+ struct ifreq* item = &ifr[i];
+ char *name = item->ifr_name;
+ struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr;
+ uint32_t ipv4addr = sa4->sin_addr.s_addr;
-void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
- void *userData)
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- if (WIFI_CONNECTION_STATE_ASSOCIATION == state
- || WIFI_CONNECTION_STATE_CONFIGURATION == state)
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Connection is in Association State");
- return;
- }
-
- // If Wifi is connected, then get the latest IP from the WIFI Interface
- if (WIFI_CONNECTION_STATE_CONNECTED == state)
- {
- // Get network information
- char *interfaceName = NULL;
- char *ipAddress = NULL;
- char *subnetMask = NULL;
- CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
-
- CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
- if (!netInfo)
+ if (ioctl(s, SIOCGIFFLAGS, item) < 0)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
- OICFree(interfaceName);
- OICFree(ipAddress);
- OICFree(subnetMask);
- return;
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno));
+ continue;
}
-
- // set interface name
- strncpy(netInfo->interfaceName, interfaceName, strlen(interfaceName));
-
- // set local ip address
- strncpy(netInfo->ipAddress, ipAddress, strlen(ipAddress));
-
- // set subnet mask
- strncpy(netInfo->subnetMask, subnetMask, strlen(subnetMask));
-
- bool ret = CACheckIsInterfaceInfoChanged(netInfo);
- if (ret)
+ int16_t flags = item->ifr_flags;
+ if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
+ continue;
}
-
- OICFree(interfaceName);
- OICFree(ipAddress);
- OICFree(subnetMask);
- }
- else
- {
- CARemoveInterfaceInfo();
- }
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- if (WIFI_DEVICE_STATE_ACTIVATED == state)
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Activated State");
- }
- else
- {
- CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Deactivated State");
- }
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-static CAResult_t CAInitializeNetworkMonitorMutexes()
-{
- if (!g_networkMonitorContextMutex)
- {
- g_networkMonitorContextMutex = ca_mutex_new();
- if (!g_networkMonitorContextMutex)
+ if (ioctl(s, SIOCGIFINDEX, item) < 0)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc failed");
- return CA_MEMORY_ALLOC_FAILED;
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno));
+ continue;
}
- }
-
- return CA_STATUS_OK;
-}
-static void CADestroyNetworkMonitorMutexes()
-{
- ca_mutex_free(g_networkMonitorContextMutex);
- g_networkMonitorContextMutex = NULL;
-}
-
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
+ int ifIndex = item->ifr_ifindex;
+ caglobals.ip.nm.ifItems[i].ifIndex = ifIndex; // refill interface list
+ caglobals.ip.nm.numIfItems++;
- VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
- CAResult_t ret = CAInitializeNetworkMonitorMutexes();
-
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
- return CA_STATUS_FAILED;
- }
- ca_mutex_lock(g_networkMonitorContextMutex);
-
- // Initialize Wifi service
- wifi_error_e retValue = wifi_initialize();
- if (WIFI_ERROR_NONE != retValue)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_initialize failed");
- return CA_STATUS_FAILED;
- }
+ if (foundNewInterface)
+ {
+ continue; // continue updating interface list
+ }
- g_networkMonitorContext = (CAIPNetworkMonitorContext *)OICCalloc(1,
- sizeof(*g_networkMonitorContext));
- if (!g_networkMonitorContext)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc failed");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- CADestroyNetworkMonitorMutexes();
- return CA_MEMORY_ALLOC_FAILED;
- }
+ // see if this interface didn't previously exist
+ bool found = false;
+ for (size_t j = 0; j < numprevious; j++)
+ {
+ if (ifIndex == previous[j].ifIndex)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ {
+ OIC_LOG_V(INFO, TAG, "Interface found: %s", name);
+ continue;
+ }
- g_networkMonitorContext->netInterfaceList = u_arraylist_create();
- if (!g_networkMonitorContext->netInterfaceList)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
- OICFree(g_networkMonitorContext);
- ca_mutex_unlock(g_networkMonitorContextMutex);
- CADestroyNetworkMonitorMutexes();
- return CA_MEMORY_ALLOC_FAILED;
+ foundNewInterface = CANewInterfaceItem(ifIndex, name, AF_INET, ipv4addr, flags);
}
- CAIPGetInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
- ca_mutex_unlock(g_networkMonitorContextMutex);
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
- return CA_STATUS_OK;
+ OICFree(previous);
+ return foundNewInterface;
}
-void CAIPTerminateNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor()
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
+ OIC_LOG(DEBUG, TAG, "IN");
- ca_mutex_lock(g_networkMonitorContextMutex);
-
- // Deinitialize Wifi service
- wifi_error_e ret = wifi_deinitialize();
+ // Initialize Wifi service
+ wifi_error_e ret = wifi_initialize();
if (WIFI_ERROR_NONE != ret)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_deinitialize failed");
+ OIC_LOG(ERROR, TAG, "wifi_initialize failed");
+ return CA_STATUS_FAILED;
}
- CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
-
- g_networkMonitorContext->netInterfaceList = NULL;
- g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
- g_networkMonitorContext->networkChangeCb = NULL;
-
- OICFree(g_networkMonitorContext);
- g_networkMonitorContext = NULL;
-
- ca_mutex_unlock(g_networkMonitorContextMutex);
-
- CADestroyNetworkMonitorMutexes();
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- // Set callback for receiving state changes
- wifi_error_e ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
+ // Set callback for receiving state changes
+ ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
if (WIFI_ERROR_NONE != ret)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
+ OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
return CA_STATUS_FAILED;
}
ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
if (WIFI_ERROR_NONE != ret)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
+ OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
return CA_STATUS_FAILED;
}
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+ OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
CAResult_t CAIPStopNetworkMonitor()
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
+ OIC_LOG(DEBUG, TAG, "IN");
// Reset callback for receiving state changes
wifi_error_e ret = wifi_unset_device_state_changed_cb();
if (WIFI_ERROR_NONE != ret)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
+ OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
}
// Reset callback for receiving connection state changes
ret = wifi_unset_connection_state_changed_cb();
if (WIFI_ERROR_NONE != ret)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
+ OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
+ }
+
+ // Deinitialize Wifi service
+ ret = wifi_deinitialize();
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
}
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+ OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
- VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
- "g_networkMonitorContext is null");
- VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
- "g_networkMonitorContextMutex is null");
-
- // Get the interface and ipaddress information from cache
- ca_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->netInterfaceList
- || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
+ u_arraylist_t *iflist = u_arraylist_create();
+ if (!iflist)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+ return NULL;
+ }
+
+ char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+ struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
+
+ int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
+ if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
+ {
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
+ u_arraylist_destroy(iflist);
+ return NULL;
+ }
+
+ struct ifreq* ifr = ifc.ifc_req;
+ size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]);
+ size_t ifreqsize = ifc.ifc_len;
+
+ if (ifreqsize > caglobals.ip.nm.sizeIfItems)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return CA_ADAPTER_NOT_ENABLED;
+ CAIfItem_t *items = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifItems, ifreqsize);
+ if (!items)
+ {
+ OIC_LOG(ERROR, TAG, "OICRealloc failed");
+ goto exit;
+ }
+ caglobals.ip.nm.ifItems = items;
+ caglobals.ip.nm.sizeIfItems = ifreqsize;
}
- uint32_t list_index = 0;
- uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
- list_length);
- for (list_index = 0; list_index < list_length; list_index++)
+ caglobals.ip.nm.numIfItems = 0;
+ for (size_t i = 0; i < interfaces; i++)
{
- CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
- g_networkMonitorContext->netInterfaceList, list_index);
- if (!info)
+ struct ifreq* item = &ifr[i];
+ char *name = item->ifr_name;
+ struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr;
+ uint32_t ipv4addr = sa4->sin_addr.s_addr;
+
+ if (ioctl(s, SIOCGIFFLAGS, item) < 0)
{
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno));
continue;
}
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
- info->ipAddress);
- CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
- if (!newNetinfo)
+ int16_t flags = item->ifr_flags;
+ if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return CA_MEMORY_ALLOC_FAILED;
+ continue;
+ }
+ if (ioctl(s, SIOCGIFINDEX, item) < 0)
+ {
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno));
+ continue;
}
- memcpy(newNetinfo, info, sizeof(*info));
+ int ifindex = item->ifr_ifindex;
+ caglobals.ip.nm.ifItems[i].ifIndex = ifindex;
+ caglobals.ip.nm.numIfItems++;
- CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)newNetinfo);
+ if (desiredIndex && (ifindex != desiredIndex))
+ {
+ continue;
+ }
+
+ // Add IPv4 interface
+ CAResult_t result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET, ipv4addr, flags);
if (CA_STATUS_OK != result)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return CA_STATUS_FAILED;
+ goto exit;
}
- }
- ca_mutex_unlock(g_networkMonitorContextMutex);
+ // Add IPv6 interface
+ result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET6, ipv4addr, flags);
+ if (CA_STATUS_OK != result)
+ {
+ goto exit;
+ }
+ }
+ return iflist;
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
- return CA_STATUS_OK;
+exit:
+ u_arraylist_destroy(iflist);
+ return NULL;
}
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
+static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
+ char *name, int family, uint32_t addr, int flags)
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
- VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
- VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
- "g_networkMonitorContext is null");
- VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
- "g_networkMonitorContextMutex is null");
-
- // Get the interface and ipaddress information from cache
- ca_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->netInterfaceList
- || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
+ CAInterface_t *ifitem = CANewInterfaceItem(index, name, family, addr, flags);
+ if (!ifitem)
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
- ca_mutex_unlock(g_networkMonitorContextMutex);
- return CA_ADAPTER_NOT_ENABLED;
+ return CA_STATUS_FAILED;
}
-
- uint32_t list_index = 0;
- uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
- for (list_index = 0; list_index < list_length; list_index++)
+ bool result = u_arraylist_add(iflist, ifitem);
+ if (!result)
{
- CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
- g_networkMonitorContext->netInterfaceList, list_index);
- if (!info)
- {
- continue;
- }
-
- if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
- {
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
- "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
- *subnetMask = OICStrdup(info->subnetMask);
- break;
- }
+ OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+ OICFree(ifitem);
+ return CA_STATUS_FAILED;
}
- ca_mutex_unlock(g_networkMonitorContextMutex);
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
return CA_STATUS_OK;
}
-bool CAIPIsConnected()
+static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
+ uint32_t addr, int flags)
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- wifi_connection_state_e connection_state;
- wifi_error_e ret = wifi_get_connection_state(&connection_state);
- if (WIFI_ERROR_NONE != ret)
+ CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof (CAInterface_t));
+ if (!ifitem)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get the Connection State");
- return false;
+ OIC_LOG(ERROR, TAG, "Malloc failed");
+ return NULL;
}
- if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "WIFI is not Connected");
- return false;
- }
+ OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
+ ifitem->index = index;
+ ifitem->family = family;
+ ifitem->ipv4addr = addr;
+ ifitem->flags = flags;
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
- return true;
+ return ifitem;
}
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
+void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
+ void *userData)
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
- if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ if (WIFI_CONNECTION_STATE_ASSOCIATION == state
+ || WIFI_CONNECTION_STATE_CONFIGURATION == state)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
+ OIC_LOG(DEBUG, TAG, "Connection is in Association State");
return;
}
- ca_mutex_lock(g_networkMonitorContextMutex);
- g_networkMonitorContext->networkChangeCb = callback;
+ if (WIFI_CONNECTION_STATE_CONNECTED == state)
+ {
+ CAWakeUpForChange();
+ }
+ else
+ {
+ u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+ if (!iflist)
+ {
+ OIC_LOG_V(ERROR, TAG, "get interface info failed");
+ return;
+ }
+ u_arraylist_destroy(iflist);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
- ca_mutex_unlock(g_networkMonitorContextMutex);
+ if (WIFI_DEVICE_STATE_ACTIVATED == state)
+ {
+ OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
+ }
+ else
+ {
+ CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
+ OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State");
+ }
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+ OIC_LOG(DEBUG, TAG, "OUT");
}