CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured) { OIC_LOG(DEBUG, IP_SERVER_TAG, "IN"); // Input validation VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress"); VERIFY_NON_NULL(port, IP_SERVER_TAG, "port"); ca_mutex_lock(g_mutexServerInfoList); bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port); if (!isUnicastServerStarted) { int unicastServerFd = -1; if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, isSecured, &unicastServerFd)) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!"); ca_mutex_unlock(g_mutexServerInfoList); return CA_STATUS_FAILED; } CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t)); if (!info) { OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed"); close(unicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return CA_MEMORY_ALLOC_FAILED; } char *netMask = NULL; if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask)) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet"); } if (netMask) { OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask); OICFree(netMask); } OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress); info->endpoint.port = *port; info->endpoint.flags = isSecured ? CA_SECURE : 0; info->endpoint.adapter = CA_ADAPTER_IP; info->socketFd = unicastServerFd; info->isServerStarted = true; info->isMulticastServer = false; OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress); CAResult_t res = CAAddServerInfo(g_serverInfoList, info); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!"); close(unicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return res; } ca_mutex_unlock(g_mutexServerInfoList); res = CAIPStartPacketReceiverHandler(); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!"); close(unicastServerFd); return res; } } else { OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]", localAddress, *port); ca_mutex_unlock(g_mutexServerInfoList); } OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT"); return CA_STATUS_OK; }
CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress, uint16_t multicastPort) { OIC_LOG(DEBUG, IP_SERVER_TAG, "IN"); // Input validation VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress"); VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port"); uint16_t port = multicastPort; if (0 >= port) { OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!"); return CA_STATUS_INVALID_PARAM; } ca_mutex_lock(g_mutexServerInfoList); bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress, multicastAddress, port); if (!isMulticastServerStarted) { int mulicastServerFd = -1; CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, false); if (ret != CA_STATUS_OK) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket"); ca_mutex_unlock(g_mutexServerInfoList); return ret; } struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)}; inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr); if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &multicastMemberReq, sizeof(struct ip_mreq))) { OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n", strerror(errno)); close(mulicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return CA_STATUS_FAILED; } CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t)); if (!info) { OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed"); close(mulicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return CA_MEMORY_ALLOC_FAILED; } char *netMask = NULL; if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask)) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet"); } if (netMask) { OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask); OICFree(netMask); } OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress); info->endpoint.port = multicastPort; info->endpoint.flags = 0; info->socketFd = mulicastServerFd; info->isServerStarted = true; info->isMulticastServer = true; OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress); ret = CAAddServerInfo(g_serverInfoList, info); if (CA_STATUS_OK != ret) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!"); close(mulicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return ret; } ca_mutex_unlock(g_mutexServerInfoList); ret = CAIPStartPacketReceiverHandler(); if (CA_STATUS_OK != ret) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!"); close(mulicastServerFd); return ret; } }
CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool forceBindStart, bool isSecured) { OIC_LOG(DEBUG, IP_SERVER_TAG, "IN"); // Input validation VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress"); VERIFY_NON_NULL(port, IP_SERVER_TAG, "port"); if (0 >= *port) { OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!"); return CA_STATUS_INVALID_PARAM; } ca_mutex_lock(g_mutexServerInfoList); bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port); if (!isUnicastServerStarted) { int unicastServerFd = -1; if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceBindStart, isSecured, &unicastServerFd)) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!"); ca_mutex_unlock(g_mutexServerInfoList); return CA_STATUS_FAILED; } CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t)); if (!info) { OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed"); close(unicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return CA_MEMORY_ALLOC_FAILED; } char *netMask = NULL; if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask)) { OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet"); } if (netMask) { strncpy(info->subNetMask, netMask, sizeof(info->subNetMask) - 1); info->subNetMask[sizeof(info->subNetMask)-1] = '\0'; OICFree(netMask); } strncpy(info->ipAddress, localAddress, sizeof(info->ipAddress) - 1); info->ipAddress[sizeof(info->ipAddress) - 1] = '\0'; info->port = *port; info->socketFd = unicastServerFd; info->isSecured = isSecured; info->isServerStarted = true; info->isMulticastServer = false; strncpy(info->ifAddr, localAddress, sizeof(info->ifAddr) - 1); info->ifAddr[sizeof(info->ifAddr) - 1] = '\0'; CAResult_t res = CAAddServerInfo(g_serverInfoList, info); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!"); close(unicastServerFd); ca_mutex_unlock(g_mutexServerInfoList); return res; } ca_mutex_unlock(g_mutexServerInfoList); res = CAIPStartPacketReceiverHandler(); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!"); close(unicastServerFd); return res; } } else { OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]", localAddress, *port); ca_mutex_unlock(g_mutexServerInfoList); } OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT"); return CA_STATUS_OK; }