Add CASetCloudAddressForProxy method 52/201652/1
authorRobert Chudek <r.chudek@partner.samsung.com>
Tue, 12 Feb 2019 10:36:39 +0000 (11:36 +0100)
committerAbhishek Sansanwal <abhishek.s94@samsung.com>
Mon, 18 Mar 2019 09:38:48 +0000 (05:38 -0400)
[Model] IoTivity
[BinType] AP
[Customer] IoT-Core

[Issue#] CONPRO-1393
[Request] Robert Chudek / r.chudek
[Occurrence Version] n/a

[Problem] IoT-Core needs a method to set cloud address for proxy.
[Cause & Measure] Cause: No such method implemented.
[Checking Method] n/a

[Team] IoT Connection
[Developer] Robert Chudek / r.chudek
[Solution company] Samsung
[Change Type] new feature

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/415
(cherry picked from 0689b92fdb5dc0018768cf36b1723f2f55a9395c)

Change-Id: Icc3f706a5e929fcddb32ffebea20070db2ba5680
Signed-off-by: Abhishek Sansanwal <abhishek.s94@samsung.com>
resource/csdk/connectivity/api/cautilinterface.h
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c

index 341fdbb..28fc94e 100644 (file)
@@ -169,6 +169,24 @@ CAResult_t CASetScanResponseData(const char* data, int length);
 
 #endif
 
+#if defined(__TIZEN__)
+/**
+ * This function sets uri being used for proxy.
+ *
+ * @param uri            NULL terminated resource uri for SAP Proxy.
+ *
+ *
+ * @return  ::CA_STATUS_OK or ::CA_STATUS_INVALID_PARAM
+ */
+CAResult_t CASetCloudAddressForProxy(const char *uri);
+/**
+ * This function gets proxy uri.
+ *
+ * @return  resource uri or NULL
+ */
+const char *CAGetCloudAddressForProxy();
+#endif
+
 #ifdef __APPLE__
 /**
  * initialize client connection manager
index ba1d224..13b3080 100644 (file)
@@ -129,6 +129,26 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem);
 static void CATCPInitializeSocket();
 static CATCPSessionInfo_t *CAGetSessionInfoFromFDAsOwner(int fd, size_t *index);
 
+#if defined(__TIZEN__)
+static char g_cloudproxyUri[CA_MAX_URI_LENGTH];
+
+CAResult_t CASetCloudAddressForProxy(const char *uri)
+{
+    if (uri == NULL)
+        memset(g_cloudproxyUri, '\0', sizeof (g_cloudproxyUri));
+    else
+        OICStrcpy(g_cloudproxyUri, sizeof (g_cloudproxyUri), uri);
+    return CA_STATUS_OK;
+}
+
+const char *CAGetCloudAddressForProxy()
+{
+    if (g_cloudproxyUri[0] == '\0')
+        return NULL;
+    return g_cloudproxyUri;
+}
+#endif
+
 #define CHECKFD(FD) \
     if (FD > caglobals.tcp.maxfd) \
         caglobals.tcp.maxfd = FD;
@@ -828,6 +848,19 @@ static CAResult_t CATCPConvertNameToAddr(int family, const char *host, uint16_t
     return CA_STATUS_OK;
 }
 
+static int __get_status_code_from_response(char * response) {
+    char *resp, *code_plus, *ptrSave;
+    int ret = -1;
+
+    resp = strdup(response);
+    strtok_r(resp, " ", &ptrSave);  /* skip HTTP version */
+    code_plus = strtok_r(NULL, " ", &ptrSave);
+
+    ret = code_plus ? atoi(code_plus) : -1;
+    free(resp);
+    return ret;
+}
+
 static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
 {
     VERIFY_NON_NULL(svritem, TAG, "svritem is NULL");
@@ -835,6 +868,9 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
     OIC_LOG_V(INFO, TAG, "try to connect with [%s:%u]",
               svritem->sep.endpoint.addr, svritem->sep.endpoint.port);
 
+    char *proxy_addr = CAGetCloudAddressForProxy();
+    OIC_LOG_V(INFO, TAG, "Proxy : '%s'", proxy_addr ? proxy_addr : "(nil)");
+
     // #1. create tcp socket.
     int fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
     if (-1 == fd)
@@ -888,6 +924,50 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
         OIC_LOG(ERROR, TAG, "wakeup receive thread failed");
         return CA_SOCKET_OPERATION_FAILED;
     }
+
+    // #5. Send HTTP CONNECT to proxy if proxy
+
+    const char *cloud_address = CAGetCloudAddressForProxy();
+
+    if(cloud_address && *cloud_address) {
+        char message[4096];
+        int len = sprintf(message,
+                "CONNECT %s HTTP/1.1\r\n"
+                "Host: %s\r\n\r\n", cloud_address, cloud_address
+        );
+
+
+
+        ssize_t l = send(fd, message, len, 0);
+        if(l != len) {
+            OIC_LOG_V(INFO, TAG, "failed to send HTTP CONNECT data (expected %d bytes, ret %d)", len, l);
+            close(fd);
+            svritem->fd = -1;
+            return CA_SOCKET_OPERATION_FAILED;
+        }
+
+        // maybe this should be called in other thread, it causes bottleneck.
+        OIC_LOG_V(INFO, TAG, "Message sent is : '%s'\n", message);
+
+        *message = '\0';
+        OIC_LOG_V(INFO, TAG, "Receiving response to CONNECT from proxy...");
+
+        l = recv(fd, message, 4096, 0);
+
+        OIC_LOG_V(INFO, TAG, "Received data : '%s'", message);
+        OIC_LOG_V(INFO, TAG, "Received len = %d", l);
+
+        int status_code = __get_status_code_from_response(message);
+
+        OIC_LOG_V(INFO, TAG, "HTTP status_code : %d", status_code);
+        if(status_code < 200 || status_code > 299) {
+            OIC_LOG_V(ERROR, TAG, "Error, __get_status_code_from_response => %d", status_code);
+            close(fd);
+            svritem->fd = -1;
+            return CA_SOCKET_OPERATION_FAILED;
+        }
+    }
+
     return CA_STATUS_OK;
 }