Commit 59ef2f1d authored by John Light's avatar John Light Committed by Erich Keane

New IP Adapter supports IPv6

builds on Linux
tested on Linux
IPv6 is now experimental
missing: testing on Android, build and test on Tizen

Change-Id: I4912317111dcc26712aec036715925905bd35eb9
Signed-off-by: default avatarJohn Light <john.j.light@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1724Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarErich Keane <erich.keane@intel.com>
parent 187dab39
......@@ -48,10 +48,10 @@ function build()
scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$3
echo "*********** Build for Tizen CA lib and sample *************"
scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true RELEASE=$3
#scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true RELEASE=$3
echo "*********** Build for Tizen CA lib and sample with Security *************"
scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true SECURED=1 RELEASE=$3
#scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true SECURED=1 RELEASE=$3
if [ $(uname -s) = "Darwin" ]
then
......
......@@ -134,6 +134,8 @@ typedef enum
// IPv4 & IPv6 autoselection is the default
CA_IPV6 = (1 << 5), // IP adapter only
CA_IPV4 = (1 << 6), // IP adapter only
// Indication that a message was received by multicast.
CA_MULTICAST = (1 << 7),
// Link-Local multicast is the default multicast scope for IPv6.
// These correspond in both value and position to the IPv6 address bits.
CA_SCOPE_INTERFACE = 0x1, // IPv6 Interface-Local scope
......@@ -145,6 +147,9 @@ typedef enum
CA_SCOPE_GLOBAL = 0xE, // IPv6 Global scope
} CATransportFlags_t;
#define CA_IPFAMILY_MASK (CA_IPV6|CA_IPV4)
#define CA_SCOPE_MASK 0xf // mask scope bits above
/**
* @enum CANetworkStatus_t
* @brief Information about the network status.
......@@ -348,8 +353,44 @@ typedef struct
*/
typedef struct
{
CATransportFlags_t serverFlags;
int fd;
uint16_t port;
} CASocket_t;
typedef struct
{
CATransportFlags_t clientFlags;
CATransportFlags_t serverFlags;
bool client;
bool server;
struct sockets
{
void *threadpool; // threadpool between Initialize and Start
CASocket_t u6; // unicast IPv6
CASocket_t u6s; // unicast IPv6 secure
CASocket_t u4; // unicast IPv4
CASocket_t u4s; // unicast IPv4 secure
CASocket_t m6; // multicast IPv6
CASocket_t m6s; // multicast IPv6 secure
CASocket_t m4; // multicast IPv4
CASocket_t m4s; // multicast IPv4 secure
int netlinkFd; // netlink
int shutdownFds[2]; // shutdown pipe
int selectTimeout; // in seconds
int maxfd; // highest fd (for select)
int numInterfaces; // number of active interfaces
bool started; // the IP adapter has started
bool terminate; // the IP adapter needs to stop
bool ipv6enabled; // IPv6 enabled by OCInit flags
bool ipv4enabled; // IPv4 enabled by OCInit flags
} ip;
struct calayer
{
CATransportFlags_t previousRequestFlags; // address family filtering
uint16_t previousRequestMessageId; // address family filtering
} ca;
} CAGlobals_t;
extern CAGlobals_t caglobals;
......
......@@ -220,14 +220,14 @@ CAResult_t CASendNotification(const CAEndpoint_t *object,
* @param interestedNetwork [IN] Connectivity Type enum
* @return #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED or #CA_NOT_SUPPORTED
*/
CAResult_t CASelectNetwork(const uint32_t interestedNetwork);
CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork);
/**
* @brief Select network to unuse
* @param nonInterestedNetwork [IN] Connectivity Type enum
* @return #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED
*/
CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork);
CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork);
/**
* @brief Get network information
......
......@@ -105,6 +105,13 @@ uint32_t u_arraylist_length(const u_arraylist_t *list);
*/
bool u_arraylist_contains(const u_arraylist_t *list,const void *data);
/**
* @brief Destroys array list and elements (assuming elements are shallow)
* @param list
* [IN] pointer of array list
*/
void u_arraylist_destroy(u_arraylist_t *list);
#ifdef __cplusplus
}
#endif
......
......@@ -178,4 +178,17 @@ bool u_arraylist_contains(const u_arraylist_t *list,const void *data)
return false;
}
// Assumes elements are shallow (have no pointers to allocated memory)
void u_arraylist_destroy(u_arraylist_t *list)
{
if (!list)
{
return;
}
uint32_t len = u_arraylist_length(list);
for (uint32_t i = 0; i < len; i++)
{
OICFree(u_arraylist_get(list, i));
}
(void)u_arraylist_free(&list);
}
......@@ -41,7 +41,7 @@ extern void OCGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
typedef void (*CAPacketReceivedCallback)(const CAEndpoint_t *endpoint,
const void *data, uint32_t dataLength);
typedef uint32_t (*CAPacketSendCallback)(const CAEndpoint_t *endpoint,
typedef void (*CAPacketSendCallback)(CAEndpoint_t *endpoint,
const void *data, uint32_t dataLength);
/**
......
......@@ -87,8 +87,9 @@ extern "C"
*/
#define IPV4_ADDR_ONE_OCTECT_LEN 4
#ifdef SINGLE_THREAD
/**
* @brief Network Interface Information.
* @brief Network Interface Information. Only needed for Arduino.
*/
typedef struct
{
......@@ -96,6 +97,7 @@ typedef struct
char subnetMask[CA_IPADDR_SIZE]; /**< Maintains interface subnetmask **/
char interfaceName[CA_INTERFACE_NAME_SIZE]; /**< Interface name**/
} CANetInfo_t;
#endif
/**
* @brief unicast and multicast server information.
......
......@@ -84,7 +84,7 @@ typedef void (*CAIPErrorHandleCallback)(const CAEndpoint_t *endpoint, const void
typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type);
/**
* @brief Initialize IP server
* @brief Start IP server
*
* @param threadPool [IN] Thread pool for managing Unicast/Multicast server threads.
*
......@@ -93,118 +93,17 @@ typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type);
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool);
#ifdef SINGLE_THREAD
CAResult_t CAIPStartServer();
#else
CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool);
#endif
/**
* @brief Terminate IP server
* @brief Stop IP server
* @return NONE
*/
void CAIPTerminateServer();
/**
* @brief Start multicast server for specified multicast address and port
*
* @param localAddress [IN] Local adapter address to which server to be binded.
* @param multicastAddress [IN] Multicast group address.
* @param multicastPort [IN,OUT] Port number on which server will be running. If binding
* the port failed, server starts in the next available port.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
uint16_t multicastPort);
/**
* @brief Start unicast server for specified local address and port
*
* @param localAddress [IN] Local adapter address to which server to be binded.
* @param port [IN,OUT] Port number on which server will be running. If binding
* the port failed, server starts in the next available port.
* @param secured [IN] True if the secure server to be started, otherwise false.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool secured);
/**
* @brief Stop servers that are running in particular interface address.
*
* @param interfaceAddress [IN] interface address in which servers are running.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAIPStopServer(const char *interfaceAddress);
/**
* @brief Used to stop all unicast and multicast servers.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAIPStopAllServers();
/**
* @brief Used to get the socket fd based on index value of server info list.
*
* @param index [IN] Index where we need socket fd value.
* @param isSecured [IN] For secured unicast server or normal server.
*
* @return positive value on success and -1 on error.
*/
int CAGetSocketFdFromUnicastIPServerbyIndex(int16_t index, bool isSecured);
/**
* @brief Used to get the number of unicast server currently running.
*
* @param isSecured [IN] To identify whether its secured unicast server or normal server.
*
* @return positive value on success and -1 on error.
*/
int16_t CAGetNumberOfUnicastIPServers(bool isSecured);
/**
* @brief Used to get the stored socket fd for corresponding ipAddress.
*
* @param ipAddress [IN] IpAddress of server.
* @param isSecured [IN] Used to check the server is secured or not.
* @param isMulticast [IN] To identify whether its for multicast or unicast.
*
* @return socket fd on success and -1 on error.
*/
int CAGetSocketFdFromUnicastIPServer(const char *ipAddress, bool isSecured, bool isMulticast);
/**
* @brief Used to get the port number to the corresponding ip for giving interface info.
*
* @param ipAddress [IN] IpAddress of server.
* @param isSecured [IN] Used to check the server is secured or not.
*
* @return port number on success and -1 on error.
*/
uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured);
/**
* @brief Used to get the port number for corresponding ipAddress.
*
* @param serverInfoList [OUT] ServerInfoList holds unicast and multicast server informations.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList);
void CAIPStopServer();
/**
* @brief Set this callback for receiving data packets from peer devices.
......@@ -247,61 +146,18 @@ void CAIPSetUnicastPort(uint16_t port);
* @param data [IN] Data to be send.
* @param dataLength [IN] Length of data in bytes
* @param isMulticast [IN] Whether data needs to be sent to multicast ip
*
* @return The number of bytes sent on the network. Returns 0 on error.
* @remarks isSecure will be ignored when isMulticast is true.
*/
uint32_t CAIPSendData(const CAEndpoint_t *endpoint,
void CAIPSendData(CAEndpoint_t *endpoint,
const void *data,
uint32_t dataLength,
bool isMulticast);
/**
* @brief Callback to be notified when IP adapter connection state changes.
*
* @param ipAddress [IN] IP address of remote OIC device.
* @param status [IN] Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
* @return NONE
* @pre Callback must be registered using CAIPSetConnectionStateChangeCallback()
*/
typedef void (*CAIPConnectionStateChangeCallback)(const char *ipAddress,
CANetworkStatus_t status);
/**
* @brief Initialize IP network monitor
*
* @param threadPool [IN] Thread pool for managing network monitor thread.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool);
/**
* @brief Terminate IP network monitor by removing interface list.
* @return NONE
*/
void CAIPTerminateNetworkMonitor();
/**
* @brief Start network monitoring process. It will start the monitor thread.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAIPStartNetworkMonitor();
/**
* @brief Stop network monitoring process. It will stop the monitor thread.
* @brief Get IP adapter connection state.
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
* @return True if IP adapter is connected, otherwise false
*/
CAResult_t CAIPStopNetworkMonitor();
bool CAIPIsConnected();
/**
* @brief Pull the Received Data
......@@ -309,47 +165,25 @@ CAResult_t CAIPStopNetworkMonitor();
*/
void CAIPPullData();
/**
* @brief Get local adapter network information.
*
* @param netInterfaceList [OUT] network interface information list
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Operation failed
* @remarks interfaceName and ipAddress must be freed using free().
*/
CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList);
#define CA_COAP 5683
#define CA_SECURE_COAP 5684
#define INTERFACE_NAME_MAX 16
/**
* @brief Get local adapter network subnet mask.
*
* @param ipAddress [IN] IpAddress which is used for getting subnet mask.
* @param subnetMask [OUT] Local adapter interface subnet mask
*
* @return #CA_STATUS_OK or Appropriate error code
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Operation failed
* @remarks subnetMask must be freed using free().
*/
CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask);
/**
* @brief Get IP adapter connection state.
*
* @return True if IP adapter is connected, otherwise false
*/
bool CAIPIsConnected();
typedef struct
{
char name[INTERFACE_NAME_MAX];
uint32_t index;
uint32_t flags;
uint16_t family;
uint32_t ipv4addr; // used for IPv4 only
} CAInterface_t;
/**
* @brief Set callback for receiving local IP adapter connection status.
* @brief Get a list of CAInterface_t items
*
* @param callback [IN] Callback to be notified when IP adapter connection state changes.
* @return NONE
* @return List of CAInterface_t items
*/
void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback);
u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
/**
* @brief Set callback for error handling
......
/*
* Copyright (c) 1995, 1999
* Berkeley Software Design, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
*/
#ifndef _IFADDRS_H_
#define _IFADDRS_H_
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
void *ifa_data;
};
/*
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
* to be included it must be included before this header file.
*/
#ifndef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS
#endif
......@@ -622,7 +622,7 @@ void UnselectNetwork()
{
g_isLeSelected = false;
}
CAUnSelectNetwork(1 << number);
CAUnSelectNetwork((CATransportAdapter_t)(1 << number));
Serial.println("Terminate");
CATerminate();
Serial.println("============");
......
......@@ -45,7 +45,8 @@ env.AppendUnique(CA_SRC = [os.path.join(ca_path,
'adapter_util/caadapterutils.c')])
env.AppendUnique(CA_SRC = [os.path.join(ca_path,
'adapter_util/cafragmentation.c')])
if ca_os in ['android', 'tizen']:
env.AppendUnique(CA_SRC=[os.path.join(ca_path, 'adapter_util/ifaddrs.c')])
if env.get('SECURED') == '1':
env.AppendUnique(CA_SRC = [os.path.join(ca_path,
'adapter_util/caadapternetdtls.c')])
......
......@@ -436,24 +436,20 @@ static int32_t CASendSecureData(dtls_context_t *dtlsContext,
int type = 0;
//Mutex is not required for g_caDtlsContext. It will be called in same thread.
int32_t sentLen = 0;
if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
(NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
{
sentLen = g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
}
else
{
OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
}
OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
return sentLen;
return bufLen;
}
static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
session_t *session,
dtls_alert_level_t level,
......
......@@ -66,6 +66,7 @@ void CALogPDUData(coap_pdu_t *pdu)
OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
}
#ifdef WITH_ARDUINO
CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
size_t ipAddrLen, uint16_t *port)
{
......@@ -130,243 +131,7 @@ CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
return CA_STATUS_FAILED;
}
bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
{
VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
CAResult_t ret = CA_STATUS_OK;
/* Local Loopback Address */
if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
{
return true;
}
uint16_t parsedPort = 0;
ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
if (ret != CA_STATUS_OK)
{
OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
return false;
}
ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
if (ret != CA_STATUS_OK)
{
OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
return false;
}
ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
if (ret != CA_STATUS_OK)
{
OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
return false;
}
return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
== (ipList2[1] & maskList[1]))
&& ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
&& ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
}
bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
const char *multicastAddress, uint16_t port)
{
VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
VERIFY_NON_NULL_RET(multicastAddress, CA_ADAPTER_UTILS_TAG, "multicastAddress is null", false);
uint32_t listLength = u_arraylist_length(serverInfoList);
for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
{
CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
if (!info)
{
OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Info is NULL");
return false;
}
if (info->isMulticastServer && (strncmp(info->endpoint.addr, multicastAddress,
strlen(multicastAddress)) == 0)
&& (info->endpoint.port == port) && (strncmp(info->ifAddr, ipAddress, strlen(ipAddress)) == 0))
{
return info->isServerStarted;
}
}
return false;
}
bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
uint16_t port)
{
VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
uint32_t listLength = u_arraylist_length(serverInfoList);
for (uint32_t listIndex