u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
/**
- * Find a new network interface.
+ * Find network interface changes.
*
- * @return Description of interface (or NULL if no change)
+ * @return List of CAInterface_t items.
*/
-CAInterface_t *CAFindInterfaceChange();
+u_arraylist_t *CAFindInterfaceChange();
/**
* Start network monitor.
return CA_STATUS_OK;
}
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
{
// release netlink event
char *bufPtr = (char *)OICCalloc(NETLINK_MESSAGE_LENGTH, sizeof (char));
return NULL;
}
+ u_arraylist_t *iflist = NULL;
CAInterface_t *foundNewInterface = NULL;
struct ifreq* ifr = ifc.ifc_req;
}
OICFree(previous);
- return foundNewInterface;
+ // below code is temporary impl for consistency with caipserver.
+ // TODO: whole code which using ioctl will be removed and changed with internal getifaddrs impl.
+ if (foundNewInterface)
+ {
+ iflist = u_arraylist_create();
+
+ if (!iflist)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+ goto exit;
+ }
+
+ CAResult_t result = CAAddInterfaceItem(iflist,
+ foundNewInterface->index,
+ foundNewInterface->name,
+ foundNewInterface->family,
+ foundNewInterface->addr,
+ foundNewInterface->flags);
+ if (CA_STATUS_OK != result)
+ {
+ goto exit;
+ }
+
+ // release foundNewInterface
+ OICFree(foundNewInterface);
+ foundNewInterface = NULL;
+ }
+ return iflist;
+exit:
+ OICFree(foundNewInterface);
+ foundNewInterface = NULL;
+ u_arraylist_destroy(iflist);
+ return NULL;
}
u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
{
- CAInterface_t *ifchanged = CAFindInterfaceChange();
- if (ifchanged)
+ u_arraylist_t *iflist = CAFindInterfaceChange();
+ if (iflist)
{
- CAProcessNewInterface(ifchanged);
- OICFree(ifchanged);
+ uint32_t listLength = u_arraylist_length(iflist);
+ for (uint32_t i = 0; i < listLength; i++)
+ {
+ CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+ if (ifitem)
+ {
+ CAProcessNewInterface(ifitem);
+ }
+ }
+ u_arraylist_destroy(iflist);
}
break;
}
if ((caglobals.ip.addressChangeEvent != WSA_INVALID_EVENT) &&
(caglobals.ip.addressChangeEvent == eventArray[eventIndex]))
{
- CAInterface_t *newAddress;
- while ((newAddress = CAFindInterfaceChange()) != NULL)
+ u_arraylist_t *iflist = CAFindInterfaceChange();
+ if (iflist)
{
- CAProcessNewInterface(newAddress);
- OICFree(newAddress);
+ uint32_t listLength = u_arraylist_length(iflist);
+ for (uint32_t i = 0; i < listLength; i++)
+ {
+ CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+ if (ifitem)
+ {
+ CAProcessNewInterface(ifitem);
+ }
+ }
+ u_arraylist_destroy(iflist);
}
break;
}
return ifitem;
}
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
{
- CAInterface_t *foundNewInterface = NULL;
+ u_arraylist_t *iflist = NULL;
#ifdef __linux__
char buf[4096] = { 0 };
struct nlmsghdr *nh = NULL;
continue;
}
- u_arraylist_t *iflist = CAIPGetInterfaceInformation(ifiIndex);
+ iflist = CAIPGetInterfaceInformation(ifiIndex);
+
if (!iflist)
{
OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
return NULL;
}
-
- uint32_t listLength = u_arraylist_length(iflist);
- for (uint32_t i = 0; i < listLength; i++)
- {
- CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
- if (!ifitem)
- {
- continue;
- }
-
- if ((int)ifitem->index != ifiIndex)
- {
- continue;
- }
-
- foundNewInterface = CANewInterfaceItem(ifitem->index, ifitem->name, ifitem->family,
- ifitem->addr, ifitem->flags);
- break; // we found the one we were looking for
- }
- u_arraylist_destroy(iflist);
}
#endif
- return foundNewInterface;
+ return iflist;
}
u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
return CA_STATUS_OK;
}
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
{
- CAInterface_t *foundNewInterface = NULL;
+ u_arraylist_t *iflist = NULL;
char buf[NETLINK_MESSAGE_LENGTH] = { 0 };
struct sockaddr_nl sa = { 0 };
struct iovec iov = { .iov_base = buf,
struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
- int ifiIndex = ifi->ifi_index;
- u_arraylist_t *iflist = CAIPGetInterfaceInformation(ifiIndex);
-
if ((!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING)))
{
continue;
}
+ int ifiIndex = ifi->ifi_index;
+ iflist = CAIPGetInterfaceInformation(ifiIndex);
+
if (!iflist)
{
OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
return NULL;
}
-
- uint32_t listLength = u_arraylist_length(iflist);
- for (uint32_t i = 0; i < listLength; i++)
- {
- CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
- if (!ifitem)
- {
- continue;
- }
-
- if ((int)ifitem->index != ifiIndex)
- {
- continue;
- }
-
- foundNewInterface = CANewInterfaceItem(ifitem->index, ifitem->name, ifitem->family,
- ifitem->addr, ifitem->flags);
- break; // we found the one we were looking for
- }
- u_arraylist_destroy(iflist);
}
- return foundNewInterface;
+ return iflist;
}
CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
}
/**
- * Find a new IP address. Note that this can only return one, so the caller must
- * call multiple times to get the list, which is pretty inefficient. The caller is
- * responsible for freeing the pointer returned via OICFree().
- * @todo Change the API to allow returning a list or, even better, allow calling
- * CAIPPassNetworkChangesToTransportAdapter() at any time from IpAddressChangeCallback.
+ * Find a new IP address.
+ * The caller is responsible for freeing the pointer returned via u_arraylist_destroy().
*
- * @return Dynamically allocated IP address entry, or NULL if no change.
+ * @return Dynamically allocated IP address list, or NULL if no change.
*/
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
{
+ u_arraylist_t *iflist = u_arraylist_create();
+ if (!iflist)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+ return NULL;
+ }
+
oc_mutex_lock(g_CAIPNetworkMonitorMutex);
bool someAddressWentAway = g_CAIPNetworkMonitorSomeAddressWentAway;
g_CAIPNetworkMonitorSomeAddressWentAway = false;
- CAInterface_t *newAddress = NULL;
- if (g_CAIPNetworkMonitorNewAddressQueue)
+ bool newAddress = false;
+
+ // Pop whole new address in list.
+ while (g_CAIPNetworkMonitorNewAddressQueue)
{
- // Pop the first new address to return.
CANewAddress_t *change = g_CAIPNetworkMonitorNewAddressQueue;
- DL_DELETE(g_CAIPNetworkMonitorNewAddressQueue, change);
- newAddress = change->ipAddressInfo;
- OICFree(change);
+
+ bool result = u_arraylist_add(iflist, change->ipAddressInfo);
+ if (!result)
+ {
+ OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+ break;
+ }
+ else
+ {
+ DL_DELETE(g_CAIPNetworkMonitorNewAddressQueue, change);
+ OICFree(change);
+ newAddress = true;
+ }
}
oc_mutex_unlock(g_CAIPNetworkMonitorMutex);
CAIPPassNetworkChangesToTransportAdapter(CA_INTERFACE_UP);
}
- return newAddress;
+ return iflist;
}
static bool IsValidNetworkAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex)