#include <string.h>
#include <ctype.h>
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include <errno.h>
+
+#ifndef WITH_ARDUINO
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#endif
#ifdef __ANDROID__
#include <jni.h>
#endif
-#include "oic_malloc.h"
-#include "oic_string.h"
-
#define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
#ifdef __ANDROID__
OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
}
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address)
-{
- CALocalConnectivity_t *info = (CALocalConnectivity_t *)
- OICCalloc(1, sizeof(CALocalConnectivity_t));
- if (NULL == info)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
- return NULL;
- }
-
- info->type = type;
- if (address && strlen(address))
- {
- if (CA_EDR == type)
- {
- strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
- info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_LE == type)
- {
- strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
- info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_IPV4 == type)
- {
- strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
- info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
- }
- else if (CA_IPV6 == type)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
- OICFree(info);
- return NULL;
- }
- else
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
- OICFree(info);
- return NULL;
- }
- }
-
- return info;
-}
-
-CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity)
-{
- VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL);
-
- CALocalConnectivity_t *info = (CALocalConnectivity_t *)
- OICCalloc(1, sizeof(CALocalConnectivity_t));
- if (NULL == info)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
- return NULL;
- }
-
- info->type = connectivity->type;
- if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress))
- {
- strncpy(info->addressInfo.BT.btMacAddress, connectivity->addressInfo.BT.btMacAddress,
- CA_MACADDR_SIZE - 1);
- info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress))
- {
- strncpy(info->addressInfo.LE.leMacAddress, connectivity->addressInfo.LE.leMacAddress,
- CA_MACADDR_SIZE - 1);
- info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if ((CA_IPV4 == info->type)
-
- && strlen(connectivity->addressInfo.IP.ipAddress))
- {
- strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress,
- CA_IPADDR_SIZE - 1);
- info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
- info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
- }
- else if (CA_IPV6 == info->type)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
- OICFree(info);
- return NULL;
- }
- else
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
- OICFree(info);
- return NULL;
- }
-
- info->isSecured = connectivity->isSecured;
- return info;
-}
-
-void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint)
-{
- OICFree(localEndpoint);
-}
-
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address,
- const char *resourceUri)
-{
- CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
- OICCalloc(1, sizeof(CARemoteEndpoint_t));
- if (NULL == info)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
- return NULL;
- }
-
- info->transportType = type;
- if (address && strlen(address))
- {
- if (CA_EDR == type)
- {
- strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
- info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_LE == type)
- {
- strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
- info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_IPV4 == type)
- {
- strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
- info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
- }
- else if (CA_IPV6 == type)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
- OICFree(info);
- return NULL;
- }
- else
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
- OICFree(info);
- return NULL;
- }
- }
-
- if (resourceUri && strlen(resourceUri))
- {
- info->resourceUri = OICStrdup(resourceUri);
- }
-
- return info;
-}
-
-CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint)
-{
- VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL);
-
- CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
- OICCalloc(1, sizeof(CARemoteEndpoint_t));
- if (NULL == info)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
- return NULL;
- }
-
- info->transportType = remoteEndpoint->transportType;
- if (CA_EDR == info->transportType && ('\0' != remoteEndpoint->addressInfo.BT.btMacAddress[0]))
- {
- strncpy(info->addressInfo.BT.btMacAddress, remoteEndpoint->addressInfo.BT.btMacAddress,
- CA_MACADDR_SIZE - 1);
- info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if (CA_LE == info->transportType
- && ('\0' != remoteEndpoint->addressInfo.LE.leMacAddress[0]))
- {
- strncpy(info->addressInfo.LE.leMacAddress, remoteEndpoint->addressInfo.LE.leMacAddress,
- CA_MACADDR_SIZE - 1);
- info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
- }
- else if ((CA_IPV4 == info->transportType)
- && ('\0' != remoteEndpoint->addressInfo.IP.ipAddress[0]))
- {
- strncpy(info->addressInfo.IP.ipAddress, remoteEndpoint->addressInfo.IP.ipAddress,
- CA_IPADDR_SIZE - 1);
- info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
- info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port;
- }
- else if (CA_IPV6 == info->transportType)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
- }
- else
- {
- OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "Its not matching. May be multicast.");
- }
-
- //For Multicast, remote address will be null while resourceUri will have the service UUID
-
- if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri))
- {
- info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
- }
-
- info->isSecured = remoteEndpoint->isSecured;
- return info;
-}
-
-void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
-{
- if (remoteEndpoint)
- {
- OICFree(remoteEndpoint->resourceUri);
- OICFree(remoteEndpoint);
- }
-}
-
+#ifdef WITH_ARDUINO
CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
size_t ipAddrLen, uint16_t *port)
{
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->ipAddress, multicastAddress,
- strlen(multicastAddress) == 0))
- && (info->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 = 0; listIndex < listLength; listIndex++)
- {
- CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
- if (!info)
- {
- continue;
- }
-
- if (!info->isMulticastServer && (strncmp(info->ipAddress, ipAddress,
- strlen(ipAddress)) == 0)
- && (info->port == port))
- {
- return info->isServerStarted;
- }
- }
- return false;
-}
-
-uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, bool isSecured)
+#else // not with_arduino
+/*
+ * These two conversion functions return void because errors can't happen
+ * (because of NI_NUMERIC), and there's nothing to do if they do happen.
+ */
+void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, char *host, uint16_t *port)
{
- VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", 0);
- VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", 0);
+ VERIFY_NON_NULL_VOID(sockAddr, CA_ADAPTER_UTILS_TAG, "sockAddr is null");
+ VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
+ VERIFY_NON_NULL_VOID(port, CA_ADAPTER_UTILS_TAG, "port is null");
- uint32_t listLength = u_arraylist_length(serverInfoList);
- for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+ int r = getnameinfo((struct sockaddr *)sockAddr,
+ sizeof (struct sockaddr_storage),
+ host, MAX_ADDR_STR_SIZE_CA,
+ NULL, 0,
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ if (r)
{
- CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
- if (!info)
- {
- continue;
- }
- if ((strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0) &&
- (info->isSecured == isSecured))
+ if (EAI_SYSTEM == r)
{
- return info->port;
+ OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+ "getaddrinfo failed: errno %s", strerror(errno));
}
- }
-
- return 0;
-}
-
-int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress,
- bool isSecured, bool isMulticast, CATransportType_t type)
-{
- VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", -1);
- VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", -1);
-
- 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)
- {
- continue;
- }
-
- if (!CAAdapterIsSameSubnet(info->ipAddress, ipAddress, info->subNetMask))
- {
- continue;
- }
-
- if (!info->isMulticastServer && (info->isSecured == isSecured))
+ else
{
- OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG,
- "CAGetSocketFdForServer found socket [%d]", info->socketFd);
- return info->socketFd;
+ OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+ "getaddrinfo failed: %s", gai_strerror(r));
}
-
+ return;
}
-
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG,
- "CAGetSocketFdForServer socket fd is not found");
- return -1;
+ *port = ntohs(((struct sockaddr_in *)sockAddr)->sin_port); // IPv4 and IPv6
}
-CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info)
+void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr)
{
- VERIFY_NON_NULL(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
- VERIFY_NON_NULL(info, CA_ADAPTER_UTILS_TAG, "info is null");
-
- CAResult_t result = u_arraylist_add(serverInfoList, (void *) info);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_add failed!");
- }
- return result;
-}
+ VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
+ VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
-void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd)
-{
- VERIFY_NON_NULL_VOID(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
+ struct addrinfo *addrs;
+ struct addrinfo hints = { 0 };
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_NUMERICHOST;
- uint32_t listLength = u_arraylist_length(serverInfoList);
- for (uint32_t listIndex = 0; listIndex < listLength;)
+ int r = getaddrinfo(host, NULL, &hints, &addrs);
+ if (r)
{
- CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
- if (!info)
- {
- listIndex++;
- continue;
- }
-
- if (info->socketFd == sockFd)
+ if (EAI_SYSTEM == r)
{
- if (u_arraylist_remove(serverInfoList, listIndex))
- {
- OICFree(info);
- listLength--;
- }
- else
- {
- OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_remove failed!");
- break;
- }
+ OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+ "getaddrinfo failed: errno %s", strerror(errno));
}
else
{
- listIndex++;
+ OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+ "getaddrinfo failed: %s", gai_strerror(r));
}
+ return;
}
-}
-
-void CAClearNetInterfaceInfoList(u_arraylist_t *infoList)
-{
- uint32_t listLength = u_arraylist_length(infoList);
- for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+ // assumption: in this case, getaddrinfo will only return one addrinfo
+ // or first is the one we want.
+ if (addrs[0].ai_family == AF_INET6)
{
- CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(infoList, listIndex);
- if (!netInfo)
- {
- continue;
- }
- OICFree(netInfo);
+ memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6));
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port);
}
- u_arraylist_free(&infoList);
-}
-
-void CAClearServerInfoList(u_arraylist_t *serverInfoList)
-{
- uint32_t listLength = u_arraylist_length(serverInfoList);
- for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+ else
{
- CAServerInfo_t *serverInfo = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
- if (!serverInfo)
- {
- continue;
- }
- OICFree(serverInfo);
+ memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in));
+ ((struct sockaddr_in *)sockaddr)->sin_port = htons(port);
}
- u_arraylist_free(&serverInfoList);
+ freeaddrinfo(addrs);
}
+#endif // WITH_ARDUINO
#ifdef __ANDROID__
void CANativeJNISetContext(JNIEnv *env, jobject context)
return g_jvm;
}
#endif
-