add file transfer impl (Not reliable) 01/184601/1
authorJihoon Jung <jh8801.jung@samsung.com>
Thu, 19 Jul 2018 06:39:23 +0000 (15:39 +0900)
committerJihoon Jung <jh8801.jung@samsung.com>
Thu, 19 Jul 2018 06:40:11 +0000 (15:40 +0900)
Change-Id: Ib39aeb0ad1c0a976a8da9f58be116e37008f6c49
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
src/mdg-manager/include/mdgd_typedef.h
src/mdg-manager/src/mdgd_group.c
src/mdg-manager/src/mdgd_iot_client.cpp
src/mdg-manager/src/mdgd_iot_server.cpp

index a30d1590fb59323d1f8e8a7cbc42e171cbec40f3..b9203a8818a0469e64c17a42ee58a5f03f96f3f6 100755 (executable)
@@ -104,6 +104,7 @@ typedef enum {
        MDGD_REQ_INVITE_DEVICE, /**< Invite Device */
        MDGD_REQ_EJECT_DEVICE, /**< Eject Device */
        MDGD_REQ_CHANNEL_LIST, /**< Channel List */
+       MDGD_REQ_SEND_FILE,
 } mdgd_request_type_e;
 
 typedef enum {
@@ -124,6 +125,7 @@ typedef struct {
        char *host_addr; /**< IP Address of remote device */
        char *group_name; /**< Group name */
        mdgd_group_type_e type; /**< Group type */
+       char *sender;
 } mdgd_group_t;
 
 typedef struct {
@@ -176,6 +178,7 @@ typedef struct _mdgd_command_t {
        mdgd_request_type_e command; /**< Comments set for group management */
        gchar *uuid; /**< Device UUID */
        gchar *host; /**< Host address + Port */
+       gchar *addr; /**< Host address + Port */
        gchar *sender; /**< Dbus Sender */
        gchar *arg1; /**< Arguement #1 */
        gchar *arg2; /**< Arguement #2 */
index 6f6fb6c122e5c08dec3828ec1d7b83f3fa2b0f94..186a64a36f1bc56e9d52ecde6f064aa6e96c6888 100755 (executable)
@@ -255,10 +255,24 @@ int mdgd_group_send_data(char *sender, char *uuid, char *addr, int port, char *c
        cmd->command = MDGD_REQ_SEND_DATA;
        cmd->uuid = g_strdup(uuid);
        cmd->sender = g_strdup(sender);
-
+       cmd->addr = g_strdup(addr);
        cmd->host = mdgd_addr2host(addr, port, true);
        cmd->arg1 = g_strdup(channel_id);
 
+       if (data[0] == '/') {
+               cmd->command = MDGD_REQ_SEND_FILE;
+               cmd->arg2 = g_try_malloc0(len + 1);
+               if (NULL == cmd->arg2) {
+                       ret = MDGD_ERROR_OUT_OF_MEMORY;
+                       LOG_ERR("Send File Fail to uuid = %s host %s error=%s",
+                               cmd->uuid, cmd->host, mdgd_log_get_error_string(ret));
+                       return ret;
+               }
+               memcpy(cmd->arg2, data, len);
+               cmd->arg2[len] = '\0';
+       } else {
+
+
 #ifdef SUPPORT_BASE64_ENCODING
        cmd->data = g_try_malloc0(len + 1);
        if (NULL == cmd->data) {
@@ -282,7 +296,7 @@ int mdgd_group_send_data(char *sender, char *uuid, char *addr, int port, char *c
        memcpy(cmd->arg2, data, len);
        cmd->arg2[len] = '\0';
 #endif
-
+       }
        LOG_DEBUG("UUID %s host %s", cmd->uuid, cmd->host);
 
        ret = mdgd_iot_send_data(MDGD_RESOURCE_TYPE_DATA, cmd);
index 347ae6faa399717230eb87a6f712573beda06fc0..ad52555b77271ffb009bb10cc7e8278f3bbce902 100755 (executable)
 #include "OCPlatform.h"
 #include "OCApi.h"
 
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
 using namespace OC;
 using namespace std;
 
+#define PORT 8675
+#define MAXBUF 1024
+
+/* FILE Send in thread */
+static gpointer file_send_thread_func(gpointer user_data)
+{
+       LOG_BEGIN();
+       int sock;
+       struct sockaddr_in6 serveraddr;
+       int retval;
+       mdgd_command_t *cmd = (mdgd_command_t *)user_data;
+
+       sock = socket(AF_INET6, SOCK_STREAM, 0);
+       if(sock == -1)
+               LOG_ERR("socket() error");
+
+       serveraddr.sin6_family = AF_INET6;
+       serveraddr.sin6_port = htons(PORT);
+       serveraddr.sin6_flowinfo = 0;
+       LOG_DEBUG("AF_INET6 default scope : %d", serveraddr.sin6_scope_id);
+       serveraddr.sin6_scope_id = if_nametoindex("wlan0");
+       LOG_DEBUG("AF_INET6 set scope : %d", serveraddr.sin6_scope_id);
+
+       char tempaddr[26] = {0,};
+       strncpy(tempaddr, cmd->addr, 25);
+       LOG_DEBUG("AF_INET6 addr : %s", cmd->addr);
+       LOG_DEBUG("AF_INET6 addr : %s", tempaddr);
+       inet_pton(AF_INET6, tempaddr, &serveraddr.sin6_addr);
+       retval = connect(sock, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
+       if(retval == -1) {
+               LOG_ERR("connect() error : %s", strerror(errno));
+       }
+
+       char filename[MAXBUF];
+       strcpy(filename, cmd->arg2);
+       retval = write(sock, filename, sizeof(filename));
+       if(retval == -1)
+               LOG_ERR("write() error");
+
+       FILE *fp = fopen(cmd->arg2, "rb");
+       if(fp == NULL)
+               LOG_ERR("fopen() error");
+
+       fseek(fp, 0, SEEK_END);
+       int totalbytes = ftell(fp);
+       rewind(fp);
+
+       char buf[MAXBUF];
+       int numread;
+       int numtotal = 0;
+
+       while(1) {
+               numread = fread(buf, 1, MAXBUF, fp);
+               if(numread > 0) {
+                       retval = write(sock, buf, numread);
+                       if(retval == -1)
+                               LOG_ERR("write() error!");
+                       numtotal += numread;
+               }
+               else if(numread == 0 && numtotal == totalbytes) {
+                       LOG_ERR("file trans complete : %d bytes\n", numtotal);
+                       break;
+               }
+               else {
+                       LOG_ERR("file I/O error");
+               }
+       }
+       fclose(fp);
+       close(sock);
+
+       LOG_END();
+
+       g_thread_exit(NULL);
+
+       return NULL;
+}
+
 void __get_group_information(const HeaderOptions& headerOptions,
        const OCRepresentation& rep, const int eCode, void *user_data)
 {
@@ -59,8 +145,7 @@ void __get_group_information(const HeaderOptions& headerOptions,
                if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED ||
                        eCode == OC_STACK_RESOURCE_CHANGED) {
                        mdgd_check_null_ret("user_data", user_data);
-                       mdgd_command_t *cmd = (mdgd_command_t *)user_data;
-                       mdgd_group_t *group = (mdgd_group_t *)cmd->user_data;
+                       mdgd_group_t *group = (mdgd_group_t *)user_data;
                        std::map<std::string, AttributeValue> groups = rep.getValues();
                        std::map<std::string, AttributeValue>::iterator iter;
 
@@ -69,7 +154,7 @@ void __get_group_information(const HeaderOptions& headerOptions,
                                group->group_name = g_strdup(group_name.c_str());
                                LOG_DEBUG("Group Found : %s, Type : %d", group->group_name, group->type);
 
-                               mdgd_group_notify_event(cmd->sender, MDGD_EVENT_GROUP_FOUND, MDGD_ERROR_NONE, (void *)group);
+                               mdgd_group_notify_event(group->sender, MDGD_EVENT_GROUP_FOUND, MDGD_ERROR_NONE, (void *)group);
 
                                g_free(group->group_name);
                                group->group_name = NULL;
@@ -116,15 +201,15 @@ static bool _found_resource(std::shared_ptr<OCResource> resource,
                                mdgd_group_t *group = (mdgd_group_t *)g_try_malloc0(sizeof(mdgd_group_t));
                                group->device_id = g_strdup(resource->sid().c_str());
                                group->host_addr = g_strdup(resource->host().c_str());
-                               if (g_strcmp0(resource->sid().c_str(), mdgd_ctx->device_uuid) != 0) {
+                               group->sender = g_strdup(cmd->sender);
+                               if (g_strcmp0(group->device_id, mdgd_ctx->device_uuid) != 0) {
                                        group->type = MDGD_GROUP_TYPE_REMOTE;
                                } else {
                                        group->type = MDGD_GROUP_TYPE_LOCAL;
                                }
-                               cmd->user_data = (void *)group;
 
                                resource->get(QueryParamsMap(), std::bind(&__get_group_information,
-                                       std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, cmd));
+                                       std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, group));
                        }
                }
                else {
@@ -283,6 +368,9 @@ static void __send_data_finish(const HeaderOptions&,
                                }
                        } else if (cmd->command == MDGD_REQ_SEND_DATA) {
                                mdgd_group_notify_event(cmd->sender, MDGD_EVENT_SEND_DATA_FINISH, ret, NULL);
+                       } else if (cmd->command == MDGD_REQ_SEND_FILE) {
+                               GError *error = NULL;
+                               g_thread_try_new("file_send_thread", file_send_thread_func, cmd, &error);
                        }
                } else {
                        LOG_ERR("__get_device_description Response error %d", eCode);
@@ -328,6 +416,9 @@ int mdgd_iot_send_data(mdgd_resource_type_e resource_type, mdgd_command_t *cmd)
                char *b64Buf;
 #endif
                switch (cmd->command) {
+               case MDGD_REQ_SEND_FILE:
+                       rep.setValue("phase", std::string("START"));
+                       break;
                case MDGD_REQ_SEND_DATA:
                        rep.setValue("channel_id", std::string(cmd->arg1));
 #ifdef SUPPORT_BASE64_ENCODING
index d9330f3442d8dd2abefba25d708a40b096d3fb41..34e136070282e5bff5017d3eb09fe47fa48ea1ed 100755 (executable)
 #include "OCPlatform.h"
 #include "OCApi.h"
 
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
 using namespace OC;
 using namespace std;
 
+#define PORT 8675
+#define MAXBUF 1024
+
+/* FILE Receive in thread */
+static gpointer file_receive_thread_func(gpointer user_data)
+{
+       LOG_BEGIN();
+
+       int server_sockfd;
+       int client_sockfd;
+       int des_fd;
+       struct sockaddr_in6 serveraddr, clientaddr;
+       int read_len, file_read_len; // length
+       socklen_t client_len;
+       char buf[MAXBUF];
+       int check_bind;
+
+       client_len = sizeof(clientaddr);
+
+       /* socket() */
+       server_sockfd = socket(AF_INET6, SOCK_STREAM, 0);
+       if(server_sockfd == -1) {
+               LOG_ERR("socket error");
+               g_thread_exit(NULL);
+
+               return NULL;
+       }
+       LOG_DEBUG("socket created");
+
+       bzero(&serveraddr, sizeof(serveraddr));
+       serveraddr.sin6_family = AF_INET6;
+       serveraddr.sin6_addr = in6addr_any;
+       serveraddr.sin6_port = htons(PORT);
+       serveraddr.sin6_flowinfo = 0;
+       serveraddr.sin6_scope_id = if_nametoindex("wlan0");
+       if (bind(server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
+               LOG_ERR("bind error");
+               g_thread_exit(NULL);
+
+               return NULL;
+       }
+       LOG_DEBUG("socket binded");
+
+       LOG_DEBUG("listen start");
+       if (listen(server_sockfd, 5) != 0) {
+               LOG_ERR("listen error : ");
+               g_thread_exit(NULL);
+
+               return NULL;
+       }
+       LOG_DEBUG("listen end");
+
+       while(1) {
+               char file_name[MAXBUF]; // local val
+               memset(buf, 0x00, MAXBUF);
+               char client_ipaddr[INET6_ADDRSTRLEN];
+               /* accept() */
+               LOG_DEBUG("accept start");
+               client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, &client_len);
+               inet_ntop(AF_INET6, &clientaddr.sin6_addr, client_ipaddr, sizeof(client_ipaddr));
+
+               LOG_DEBUG("Accepted : %s", client_ipaddr);
+
+               /* file name */
+               read_len = read(client_sockfd, buf, MAXBUF);
+               if(read_len > 0) {
+                       strcpy(file_name, buf);
+                       LOG_DEBUG("%s > %s", client_ipaddr, file_name);
+               } else {
+                       LOG_DEBUG("read failed");
+                       close(client_sockfd);
+                       break;
+               }
+
+               /* create file */
+FILE_OPEN:
+               des_fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL, 0700);
+               if(!des_fd) {
+                       perror("file open error : ");
+                       break;
+               }
+               if(errno == EEXIST) {
+                       close(des_fd);
+                       size_t len = strlen(file_name);
+                       file_name[len++] = '_';
+                       file_name[len++] = 'n';
+                       file_name[len] = '\0';
+                       goto FILE_OPEN;
+               }
+               LOG_DEBUG("file created");
+
+               /* file save */
+               while(1) {
+                       memset(buf, 0x00, MAXBUF);
+                       file_read_len = read(client_sockfd, buf, MAXBUF);
+                       write(des_fd, buf, file_read_len);
+                       if(file_read_len == EOF | file_read_len == 0) {
+                               LOG_DEBUG("finish file\n");
+                               break;
+                       }
+               }
+               close(client_sockfd);
+               close(des_fd);
+       }
+
+       close(server_sockfd);
+
+       LOG_END();
+
+       g_thread_exit(NULL);
+
+       return NULL;
+
+}
+
 OCEntityHandlerResult _request_handler(std::shared_ptr<OCResourceRequest> request)
 {
        LOG_BEGIN();
@@ -127,6 +251,14 @@ OCEntityHandlerResult _request_handler(std::shared_ptr<OCResourceRequest> reques
                                        LOG_DEBUG("device_id received %s", requester_id.c_str());
 
                                switch(cmd) {
+                               case MDGD_REQ_SEND_FILE:
+                               {
+                                       /* socket server create */
+                                       GError *error = NULL;
+                                       g_thread_try_new("file_receive_thread", file_receive_thread_func, NULL, &error);
+
+                                       break;
+                               }
                                case MDGD_REQ_SEND_DATA:
                                {
                                        LOG_DEBUG("Receive Data");
@@ -255,6 +387,7 @@ OCEntityHandlerResult _request_handler(std::shared_ptr<OCResourceRequest> reques
                        LOG_ERR("Invalid Request Type");
                }
 
+               sleep(2);
                pResponse->setRequestHandle(request->getRequestHandle());
                pResponse->setResourceHandle(request->getResourceHandle());
                pResponse->setErrorCode(200);