Added CA Util API to assign the port number of IP(UDP/TCP)
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Mon, 23 May 2016 23:42:31 +0000 (08:42 +0900)
committerJon A. Cruz <jon@joncruz.org>
Fri, 3 Jun 2016 09:12:03 +0000 (09:12 +0000)
CA utility layer provides transport specific functions.
and the UDP/TCP port number related functions are added.
- get the port number currently openned.
- set the port number to use.

Change-Id: Ibb4ca1b1a08ee2d7e540f07c0b6267b05dd0bd6a
Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8113
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: John Light <john.j.light@intel.com>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Jon A. Cruz <jon@joncruz.org>
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cautilinterface.h
resource/csdk/connectivity/src/ip_adapter/caipadapter.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c
resource/csdk/connectivity/util/src/cautilinterface.c
resource/include/CAManager.h
resource/src/CAManager.cpp

index 19e1520..e725c44 100644 (file)
@@ -468,6 +468,28 @@ typedef struct
     int32_t ifIndex; /**< network interface index */
 } CAIfItem_t;
 
+/**
+ * Hold the port number assigned from application.
+ * It will be used when creating a socket.
+ */
+typedef struct
+{
+    struct udpports
+    {
+        uint16_t u6;    /**< unicast IPv6 socket port */
+        uint16_t u6s;   /**< unicast IPv6 socket secure port */
+        uint16_t u4;    /**< unicast IPv4 socket port */
+        uint16_t u4s;   /**< unicast IPv4 socket secure port */
+    } udp;
+#ifdef TCP_ADAPTER
+    struct tcpports
+    {
+        uint16_t u4;    /**< unicast IPv4 socket port */
+        uint16_t u6;    /**< unicast IPv6 socket port */
+    } tcp;
+#endif
+} CAPorts_t;
+
 typedef struct
 {
     CATransportFlags_t clientFlags; /**< flag for client */
@@ -475,6 +497,8 @@ typedef struct
     bool client; /**< client mode */
     bool server; /**< server mode */
 
+    CAPorts_t ports;
+
     struct sockets
     {
         void *threadpool;   /**< threadpool between Initialize and Start */
index cdd377b..d77bc30 100644 (file)
@@ -70,6 +70,26 @@ CAResult_t CASetAutoConnectionDeviceInfo(const char* address);
  */
 CAResult_t CAUnsetAutoConnectionDeviceInfo(const char* address);
 
+/**
+ * Set the port number to assign .
+ * @param[in]   adapter     Transport adapter information.
+ * @param[in]   flag        Transport flag information.
+ * @param[in]   port        The port number to use.
+ *
+ * @return  ::CA_STATUS_OK or ::CA_STATUS_FAILED.
+ */
+CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
+                                   CATransportFlags_t flag, uint16_t port);
+
+/**
+ * Get the assigned port number currently.
+ * @param[in]   adapter     Transport adapter information.
+ * @param[in]   flag        Transport flag information.
+ *
+ * @return  assigned port number information.
+ */
+uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag);
+
 #ifdef __ANDROID__
 /**
  * initialize util client for android
index 10613af..e77f46d 100644 (file)
@@ -272,6 +272,12 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
 
 CAResult_t CAStartIP()
 {
+    // Specific the port number received from application.
+    caglobals.ip.u6.port  = caglobals.ports.udp.u6;
+    caglobals.ip.u6s.port = caglobals.ports.udp.u6s;
+    caglobals.ip.u4.port  = caglobals.ports.udp.u4;
+    caglobals.ip.u4s.port = caglobals.ports.udp.u4s;
+
     CAIPStartNetworkMonitor();
 #ifdef SINGLE_THREAD
     uint16_t unicastPort = 55555;
index 7609199..4ff5c64 100644 (file)
@@ -361,7 +361,7 @@ void CAIPPullData()
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static int CACreateSocket(int family, uint16_t *port)
+static int CACreateSocket(int family, uint16_t *port, bool isMulticast)
 {
     int socktype = SOCK_DGRAM;
 #ifdef SOCK_CLOEXEC
@@ -396,7 +396,7 @@ static int CACreateSocket(int family, uint16_t *port)
             OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno));
         }
 
-        if (*port)      // only do this for multicast ports
+        if (isMulticast && *port)  // only do this for multicast ports
         {
             if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on)))
             {
@@ -409,7 +409,7 @@ static int CACreateSocket(int family, uint16_t *port)
     }
     else
     {
-        if (*port)      // only do this for multicast ports
+        if (isMulticast && *port)  // only do this for multicast ports
         {
             int on = 1;
             if (-1 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &on, sizeof (on)))
@@ -422,7 +422,7 @@ static int CACreateSocket(int family, uint16_t *port)
         socklen = sizeof (struct sockaddr_in);
     }
 
-    if (*port)  // use the given port
+    if (isMulticast && *port)  // use the given port
     {
         int on = 1;
         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)))
@@ -459,8 +459,13 @@ static int CACreateSocket(int family, uint16_t *port)
 #define CHECKFD(FD) \
     if (FD > caglobals.ip.maxfd) \
         caglobals.ip.maxfd = FD;
-#define NEWSOCKET(FAMILY, NAME) \
-    caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port); \
+#define NEWSOCKET(FAMILY, NAME, MULTICAST) \
+    caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+    if (caglobals.ip.NAME.fd == -1) \
+    {   \
+        caglobals.ip.NAME.port = 0; \
+        caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+    }   \
     CHECKFD(caglobals.ip.NAME.fd)
 
 static void CAInitializeNetlink()
@@ -557,18 +562,18 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
 
     if (caglobals.ip.ipv6enabled)
     {
-        NEWSOCKET(AF_INET6, u6)
-        NEWSOCKET(AF_INET6, u6s)
-        NEWSOCKET(AF_INET6, m6)
-        NEWSOCKET(AF_INET6, m6s)
+        NEWSOCKET(AF_INET6, u6, false)
+        NEWSOCKET(AF_INET6, u6s, false)
+        NEWSOCKET(AF_INET6, m6, true)
+        NEWSOCKET(AF_INET6, m6s, true)
         OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
     }
     if (caglobals.ip.ipv4enabled)
     {
-        NEWSOCKET(AF_INET, u4)
-        NEWSOCKET(AF_INET, u4s)
-        NEWSOCKET(AF_INET, m4)
-        NEWSOCKET(AF_INET, m4s)
+        NEWSOCKET(AF_INET, u4, false)
+        NEWSOCKET(AF_INET, u4s, false)
+        NEWSOCKET(AF_INET, m4, true)
+        NEWSOCKET(AF_INET, m4s, true)
         OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
     }
 
index d2fda2c..1b5e0f5 100644 (file)
@@ -202,9 +202,7 @@ void CATCPSetKeepAliveCallbacks(CAKeepAliveConnectionCallback ConnHandler)
 static void CAInitializeTCPGlobals()
 {
     caglobals.tcp.ipv4.fd = -1;
-    caglobals.tcp.ipv4.port = 0;
     caglobals.tcp.ipv6.fd = -1;
-    caglobals.tcp.ipv6.port = 0;
     caglobals.tcp.selectTimeout = CA_TCP_SELECT_TIMEOUT;
     caglobals.tcp.listenBacklog = CA_TCP_LISTEN_BACKLOG;
     caglobals.tcp.svrlist = NULL;
@@ -274,6 +272,10 @@ CAResult_t CAStartTCP()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
+    // Specific the port number received from application.
+    caglobals.tcp.ipv4.port = caglobals.ports.tcp.u4;
+    caglobals.tcp.ipv6.port = caglobals.ports.tcp.u6;
+
 #ifndef SINGLE_THREAD
     if (CA_STATUS_OK != CATCPInitializeQueueHandles())
     {
index 87116e1..3ee7165 100644 (file)
@@ -615,6 +615,15 @@ static void CAInitializePipe(int *fds)
     }
 }
 
+#define NEWSOCKET(FAMILY, NAME) \
+    caglobals.tcp.NAME.fd = CACreateAcceptSocket(FAMILY, &caglobals.tcp.NAME); \
+    if (caglobals.tcp.NAME.fd == -1) \
+    { \
+        caglobals.tcp.NAME.port = 0; \
+        caglobals.tcp.NAME.fd = CACreateAcceptSocket(FAMILY, &caglobals.tcp.NAME); \
+    } \
+    CHECKFD(caglobals.tcp.NAME.fd);
+
 CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool)
 {
     if (caglobals.tcp.started)
@@ -651,11 +660,8 @@ CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool)
 
     if (caglobals.server)
     {
-        caglobals.tcp.ipv4.fd = CACreateAcceptSocket(AF_INET, &caglobals.tcp.ipv4);
-        CHECKFD(caglobals.tcp.ipv4.fd);
-        caglobals.tcp.ipv6.fd = CACreateAcceptSocket(AF_INET6, &caglobals.tcp.ipv6);
-        CHECKFD(caglobals.tcp.ipv6.fd);
-
+        NEWSOCKET(AF_INET, ipv4);
+        NEWSOCKET(AF_INET6, ipv6);
         OIC_LOG_V(DEBUG, TAG, "IPv4 socket fd=%d, port=%d",
                   caglobals.tcp.ipv4.fd, caglobals.tcp.ipv4.port);
         OIC_LOG_V(DEBUG, TAG, "IPv6 socket fd=%d, port=%d",
index 046ace4..35c21b7 100644 (file)
@@ -114,6 +114,104 @@ CAResult_t CAUnsetAutoConnectionDeviceInfo(const char *address)
 #endif
 }
 
+CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
+                                   CATransportFlags_t flag, uint16_t port)
+{
+    uint16_t *targetPort = 0;
+
+    if (CA_ADAPTER_IP & adapter)
+    {
+        if (CA_SECURE & flag)
+        {
+            if (CA_IPV6 & flag)
+            {
+                targetPort = &caglobals.ports.udp.u6s;
+            }
+            else if (CA_IPV4 & flag)
+            {
+                targetPort = &caglobals.ports.udp.u4s;
+            }
+        }
+        else
+        {
+            if (CA_IPV6 & flag)
+            {
+                targetPort = &caglobals.ports.udp.u6;
+            }
+            else if (CA_IPV4 & flag)
+            {
+                targetPort = &caglobals.ports.udp.u4;
+            }
+        }
+    }
+#ifdef TCP_ADAPTER
+    if (CA_ADAPTER_TCP & adapter)
+    {
+        if (CA_IPV6 & flag)
+        {
+            targetPort = &caglobals.ports.tcp.u6;
+        }
+        else if (CA_IPV4 & flag)
+        {
+            targetPort = &caglobals.ports.tcp.u4;
+        }
+    }
+#endif
+
+    if (targetPort)
+    {
+        *targetPort = port;
+        return CA_STATUS_OK;
+    }
+
+    return CA_NOT_SUPPORTED;
+}
+
+uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag)
+{
+    OIC_LOG(DEBUG, TAG, "CAGetAssignedPortNumber");
+
+    if (CA_ADAPTER_IP & adapter)
+    {
+        if (CA_SECURE & flag)
+        {
+            if (CA_IPV6 & flag)
+            {
+                return caglobals.ip.u6s.port;
+            }
+            else if (CA_IPV4 & flag)
+            {
+                return caglobals.ip.u4s.port;
+            }
+        }
+        else
+        {
+            if (CA_IPV6 & flag)
+            {
+                return caglobals.ip.u6.port;
+            }
+            else if (CA_IPV4 & flag)
+            {
+                return caglobals.ip.u4.port;
+            }
+        }
+    }
+#ifdef TCP_ADAPTER
+    if (CA_ADAPTER_TCP & adapter)
+    {
+        if (CA_IPV6 & flag)
+        {
+            return caglobals.tcp.ipv6.port;
+        }
+        else if (CA_IPV4 & flag)
+        {
+            return caglobals.tcp.ipv4.port;
+        }
+    }
+#endif
+    return 0;
+}
+
 #ifdef __ANDROID__
 /**
  * initialize client connection manager
index 0a69743..9872f5d 100644 (file)
@@ -49,6 +49,24 @@ namespace OC
         */
         OCStackResult setNetworkMonitorHandler(AdapterChangedCallback adapterHandler,
                                                ConnectionChangedCallback connectionHandler);
+
+        /**
+        * Set port number to use.
+        * @param adapter transport adapter type to assign the specified port number.
+        * @param flag transport flag information.
+        * @param port the specified port number to use.
+        * @return Returns ::OC_STACK_OK if success.
+        */
+        OCStackResult setPortNumberToAssign(OCTransportAdapter adapter,
+                                            OCTransportFlags flag, uint16_t port);
+
+        /**
+        * Get the assigned port number.
+        * @param adapter transport adapter type to get the opened port number.
+        * @param flag   transport flag information.
+        * @return Returns currently assigned port number.
+        */
+        uint16_t getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag);
     }
 }
 
index cafcfa9..740ded3 100644 (file)
@@ -37,6 +37,23 @@ namespace
         CAManager::ConnectionChangedCallback g_connectionHandler = NULL;
 }
 
+OCStackResult convertCAResultToOCResult(CAResult_t caResult)
+{
+    switch (caResult)
+    {
+        case CA_STATUS_OK:
+            return OC_STACK_OK;
+        case CA_STATUS_INVALID_PARAM:
+            return OC_STACK_INVALID_PARAM;
+        case CA_STATUS_FAILED:
+            return OC_STACK_ERROR;
+        case CA_NOT_SUPPORTED:
+            return OC_STACK_NOTIMPL;
+        default:
+            return OC_STACK_ERROR;
+    }
+}
+
 void DefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
 {
     if (g_adapterHandler)
@@ -63,13 +80,19 @@ OCStackResult CAManager::setNetworkMonitorHandler(AdapterChangedCallback adapter
     CAResult_t ret = CARegisterNetworkMonitorHandler(DefaultAdapterStateChangedHandler,
                                                      DefaultConnectionStateChangedHandler);
 
-    switch (ret)
-    {
-        case CA_STATUS_OK:
-            return OC_STACK_OK;
-        case CA_NOT_SUPPORTED:
-            return OC_STACK_NOTIMPL;
-        default:
-            return OC_STACK_ERROR;
-    }
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::setPortNumberToAssign(OCTransportAdapter adapter,
+                                               OCTransportFlags flag, uint16_t port)
+{
+    CAResult_t ret = CASetPortNumberToAssign((CATransportAdapter_t) adapter,
+                                             (CATransportFlags_t) flag, port);
+
+    return convertCAResultToOCResult(ret);
+}
+
+uint16_t CAManager::getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag)
+{
+    return CAGetAssignedPortNumber((CATransportAdapter_t) adapter, (CATransportFlags_t) flag);
 }