Added 'End-point' functionality. 05/200605/2 accepted/tizen/unified/20190422.050004 submit/tizen/20190409.053417 submit/tizen/20190409.053454 submit/tizen/20190419.025325
authorJihoon Jung <jh8801.jung@samsung.com>
Tue, 26 Feb 2019 04:48:46 +0000 (13:48 +0900)
committersaerome kim <saerome.kim@samsung.com>
Tue, 9 Apr 2019 05:31:59 +0000 (14:31 +0900)
- Request remote apps to open end-point.
- Once end-point created, client app can send binary data through the
  end-point.

Change-Id: I77f5eb7b9e772b27b0008a77e35de100f410bc40

include/mdg.h
include/mdg_internal.h
src/mdg.c
src/mdg_dbus.c
src/mdg_gdbus.xml
src/mdg_private.h
src/mdg_util.c
src/mdg_util.h
test/mdg-manager.c [changed mode: 0644->0755]

index c1deaac..8b017e2 100755 (executable)
@@ -110,6 +110,13 @@ typedef void *mdg_group_h; /**< Group handle */
  */
 
 /**
+ * @brief Channel handle.
+ *
+ * @since_tizen 5.0
+ */
+typedef void *mdg_channel_h; /**< Device handle */
+
+/**
  * @brief Initializes mdg-manager.
  * @since_tizen 5.0
  * @privlevel public
@@ -690,6 +697,11 @@ typedef enum {
        MDG_DEVICE_TYPE_REMOTE = 2, /**< Remote device */
 } mdg_device_type_e;
 
+typedef enum {
+       MDG_CHANNEL_TYPE_CLIENT = 1,  /**< Client Channel */
+       MDG_CHANNEL_TYPE_SERVER = 2, /**< Server Channel */
+} mdg_channel_type_e;
+
 /**
  * @brief Called after mdg_device_find().
  * @details This function can receive a device found.
@@ -795,12 +807,12 @@ int mdg_device_find(mdg_h handle, int timeout, bool is_invited,
                    mdg_device_found_cb found_cb, mdg_device_find_finish_cb finish_cb,
                    void *user_data);
 
-typedef void (*mdg_receive_data_cb)(int result, char *device_id, char *channel_id,
+typedef void (*mdg_channel_receive_data_cb)(int result, char *device_id, char *channel_id,
                                    int msg_id, unsigned char *data, int len, void *user_data);
 
 /* Server Side */
 int mdg_device_regist_channel(mdg_h handle, char *channel_id,
-                             mdg_receive_data_cb receive_data_cb, void *user_data);
+                             mdg_channel_receive_data_cb receive_data_cb, void *user_data);
 
 /* In 5 seconds */
 int mdg_device_send_response(mdg_h handle, char *device_id, char *channel_id,
@@ -979,6 +991,22 @@ int mdg_device_info_is_invited(mdg_device_h device, bool *is_invited);
 int mdg_device_info_get_type(mdg_device_h device,
                             mdg_device_type_e *device_type);
 
+
+typedef void (*mdg_channel_opened_cb)(int result, mdg_channel_h channel, void *user_data);
+
+//client side
+int mdg_request_channel_open(mdg_h handle, mdg_device_h device, char *channel_id,
+       mdg_channel_opened_cb opened_cb, void *user_data);
+
+//server side
+int mdg_set_channel_opened_callback(mdg_h handle, char *channel_id,
+       mdg_channel_opened_cb opened_cb, void *user_data);
+
+int mdg_channel_write(mdg_channel_h handle, unsigned char *data, int len);
+
+//polling when write function from another side
+int mdg_channel_read(mdg_channel_h handle, unsigned char **data, int *len);
+
 /**
  * @}
  */
index 3df8650..e3fe622 100755 (executable)
 extern "C" {
 #endif
 
-/* File transfer for Client Side */
-typedef void (*mdg_send_file_progress_cb)(const char *file_path, long long send_size,
-                                         long long total_size, int percent, void *user_data);
-typedef void (*mdg_send_file_finish_cb)(int result, mdg_device_h device, void *user_data);
-
-int mdg_device_send_file(mdg_h handle, mdg_device_h device, char *file_path,
-                        mdg_send_file_progress_cb progress_cb, mdg_send_file_finish_cb finish_cb, void *user_data);
-
-/* File transfer for Server Side */
-typedef void (*mdg_receive_file_cb)(int result, char *device_id,
-                                   const char *file_path, void *user_data);
-
-int mdg_set_receive_file_cb(mdg_h handle, mdg_receive_file_cb receive_cb, void *user_data);
-int mdg_unset_receive_file_cb(mdg_h handle);
 int mdg_set_preconfigured_pin(mdg_h handle, char *password);
 
 #ifdef __cplusplus
index 3fccf4c..301d52f 100755 (executable)
--- a/src/mdg.c
+++ b/src/mdg.c
@@ -174,27 +174,27 @@ EXPORT_API int mdg_device_find(mdg_h handle, int timeout, bool is_invited,
 /**
  * Companion Manager CAPI
  */
-int __add_channel_cb(mdg_manager_s *handle, char *channel_id, mdg_receive_data_cb channel_cb, void *user_data)
+int __add_channel_cb(mdg_manager_s *handle, char *channel_id, mdg_channel_receive_data_cb channel_cb, void *user_data)
 {
-       channel_cb_s *channel_s;
+       mdg_channel_cb_s *channel_s;
 
        GSList *l1, *l2;
        for (l1 = handle_list; l1 != NULL; l1 = l1->next) {
                mdg_manager_s *tmp_handle = (mdg_manager_s *)l1->data;
                for (l2 = tmp_handle->channel_cb_list; l2 != NULL; l2 = l2->next) {
-                       channel_cb_s *tmp_channel = (channel_cb_s *)l2->data;
+                       mdg_channel_cb_s *tmp_channel = (mdg_channel_cb_s *)l2->data;
                        if (g_strcmp0(tmp_channel->channel_id, channel_id) == 0)
                                return MDG_ERROR_OPERATION_FAILED;
                }
        }
 
-       channel_s = g_try_new0(channel_cb_s, 1);
+       channel_s = g_try_new0(mdg_channel_cb_s, 1);
        if (channel_s == NULL)
                return MDG_ERROR_OUT_OF_MEMORY;
 
        channel_s->channel_id = g_strdup(channel_id);
-       channel_s->cb = channel_cb;
-       channel_s->user_data = user_data;
+       channel_s->receive_data_cb = channel_cb;
+       channel_s->receive_data_cb_user_data = user_data;
 
        handle->channel_cb_list = g_slist_prepend(handle->channel_cb_list, channel_s);
 
@@ -202,7 +202,7 @@ int __add_channel_cb(mdg_manager_s *handle, char *channel_id, mdg_receive_data_c
 }
 
 EXPORT_API int mdg_device_regist_channel(mdg_h handle, char *channel_id,
-       mdg_receive_data_cb receive_data_cb, void *user_data)
+       mdg_channel_receive_data_cb receive_data_cb, void *user_data)
 {
        int ret = MDG_ERROR_NONE;
        GError *error = NULL;
@@ -299,7 +299,7 @@ EXPORT_API int mdg_device_unregist_channel(mdg_h handle, char *channel_id)
 
        GSList *l;
        for (l = _handle->channel_cb_list; l != NULL; l = l->next) {
-               channel_cb_s *tmp_channel = (channel_cb_s *)l->data;
+               mdg_channel_cb_s *tmp_channel = (mdg_channel_cb_s *)l->data;
                if (g_strcmp0(tmp_channel->channel_id, channel_id) == 0) {
                        g_free(tmp_channel->channel_id);
                        _handle->channel_cb_list = g_slist_remove_link(_handle->channel_cb_list, l);
@@ -325,15 +325,11 @@ EXPORT_API int mdg_device_unregist_channel(mdg_h handle, char *channel_id)
        return ret;
 }
 
-EXPORT_API int mdg_device_send_data(mdg_h handle,
-       mdg_device_h device, char *channel_id, unsigned char *data, int len,
-       mdg_device_send_data_finish_cb finish_cb, void *user_data, int *msg_id)
+//client side
+EXPORT_API int mdg_request_channel_open(mdg_h handle, mdg_device_h device, char *channel_id,
+       mdg_channel_opened_cb opened_cb, void *user_data)
 {
        int ret = MDG_ERROR_NONE;
-       unsigned char *buf = NULL;
-       GVariantBuilder *bytearray_builder = NULL;
-       int i;
-       GVariant *params = NULL;
        GError *error = NULL;
 
        CHECK_FEATURE_SUPPORTED(MDG_FEATURE);
@@ -343,115 +339,162 @@ EXPORT_API int mdg_device_send_data(mdg_h handle,
        mdg_device_s *dev = (mdg_device_s *)device;
        mdg_check_null_ret_error("dev", dev, MDG_ERROR_INVALID_PARAMETER);
        mdg_check_null_ret_error("channel_id", channel_id, MDG_ERROR_INVALID_PARAMETER);
-       mdg_check_null_ret_error("data", data, MDG_ERROR_INVALID_PARAMETER);
-       cond_expr_ret(len <= 0, MDG_ERROR_INVALID_PARAMETER);
        CHECK_HANDLE_IS_VALID(handle);
 
        cond_expr_ret(dev->type == MDG_DEVICE_TYPE_LOCAL, MDG_ERROR_NOT_PROPER_DEVICE);
 
-       buf = g_try_malloc0(len + 1);
-       if (NULL == buf) {
-               /* LCOV_EXCL_START */
-               _ERR("g_malloc0 is failed");
-               return MDG_ERROR_OUT_OF_MEMORY;
-               /* LCOV_EXCL_STOP */
-       }
-       memcpy(buf, data, len);
-
-       bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
-       for (i = 0; i < len; i++)
-               g_variant_builder_add(bytearray_builder, "y", buf[i]);
-
-       params = g_variant_new("(iay)", len, bytearray_builder);
-       g_variant_builder_unref(bytearray_builder);
-
        mdg_device_h cloned_device = NULL;
        mdg_device_info_clone(&cloned_device, device);
 
-       _handle->send_data_finish_cb.finish_cb = finish_cb;
-       _handle->send_data_finish_cb.user_data = user_data;
-       _handle->send_data_finish_cb.device = cloned_device;
+       _handle->request_channel_open_finish_cb.channel_opened_cb = opened_cb;
+       _handle->request_channel_open_finish_cb.user_data = user_data;
+       _handle->request_channel_open_finish_cb.device = cloned_device;
 
-       group_call_send_data_sync(_handle->group_proxy, dev->device_id,
-               channel_id, params, &ret, msg_id, NULL, &error);
+       group_call_request_channel_open_sync(_handle->group_proxy, dev->device_id,
+               channel_id, &ret, NULL, &error);
        if (error) {
                _ERR("Failed DBus call [%s]", error->message);
                g_error_free(error);
                ret = MDG_ERROR_IO_ERROR;
        }
 
-       g_free(buf);
-       buf = NULL;
-
        return ret;
 }
 
-EXPORT_API int mdg_device_send_file(mdg_h handle, mdg_device_h device,
-       char *file_path, mdg_send_file_progress_cb progress_cb, mdg_send_file_finish_cb finish_cb, void *user_data)
+//server side
+EXPORT_API int mdg_set_channel_opened_callback(mdg_h handle, char *channel_id,
+       mdg_channel_opened_cb opened_cb, void *user_data)
 {
        int ret = MDG_ERROR_NONE;
-       GError *error = NULL;
 
        CHECK_FEATURE_SUPPORTED(MDG_FEATURE);
 
        mdg_manager_s *_handle = handle;
        mdg_check_null_ret_error("handle", handle, MDG_ERROR_INVALID_PARAMETER);
+       mdg_check_null_ret_error("channel_id", channel_id, MDG_ERROR_INVALID_PARAMETER);
        CHECK_HANDLE_IS_VALID(handle);
 
-       mdg_device_s *dev = (mdg_device_s *)device;
-       mdg_check_null_ret_error("dev", dev, MDG_ERROR_INVALID_PARAMETER);
-       mdg_check_null_ret_error("file_path", file_path, MDG_ERROR_INVALID_PARAMETER);
+       mdg_channel_cb_s *channel = NULL;
 
-       cond_expr_ret(dev->type == MDG_DEVICE_TYPE_LOCAL, MDG_ERROR_NOT_PROPER_DEVICE);
+       GSList *l;
+       for (l = _handle->channel_cb_list; l != NULL; l = l->next) {
+               mdg_channel_cb_s *tmp_channel = (mdg_channel_cb_s *)l->data;
+               if (g_strcmp0(tmp_channel->channel_id, channel_id) == 0) {
+                       channel = tmp_channel;
+                       break;
+               }
+       }
 
-       mdg_device_h cloned_device = NULL;
-       mdg_device_info_clone(&cloned_device, device);
+       if (channel == NULL) {
+               _ERR("The channel is not registered");
+               return MDG_ERROR_NO_DATA;
+       }
 
-       _handle->send_file_cb.finish_cb = finish_cb;
-       _handle->send_file_cb.progress_cb = progress_cb;
-       _handle->send_file_cb.device = cloned_device;
-       _handle->send_file_cb.user_data = user_data;
+       channel->opened_cb = opened_cb;
+       channel->opened_cb_user_data = user_data;
 
-       group_call_send_file_sync(_handle->group_proxy, dev->device_id, file_path, &ret, NULL, &error);
-       if (error) {
-               _ERR("Failed DBus call [%s]", error->message);
-               g_error_free(error);
-               ret = MDG_ERROR_IO_ERROR;
+       return ret;
+}
+
+EXPORT_API int mdg_channel_write(mdg_channel_h channel, unsigned char *data, int len)
+{
+       int ret = MDG_ERROR_NONE;
+
+       CHECK_FEATURE_SUPPORTED(MDG_FEATURE);
+
+       mdg_channel_s *_channel = channel;
+       mdg_check_null_ret_error("channel", channel, MDG_ERROR_INVALID_PARAMETER);
+
+       ret = write(_channel->client_sockfd, data, len);
+       if (ret == -1) {
+               char buf[128];
+               strerror_r(errno, buf, 128);
+               _ERR("write() error : %s", buf);
+               ret = MDG_ERROR_OPERATION_FAILED;
        }
 
        return ret;
 }
 
-EXPORT_API int mdg_set_receive_file_cb(mdg_h handle,
-       mdg_receive_file_cb receive_cb, void *user_data)
+//polling function
+#define MAXBUF 1024
+EXPORT_API int mdg_channel_read(mdg_channel_h channel, unsigned char **data, int *len)
 {
        int ret = MDG_ERROR_NONE;
 
        CHECK_FEATURE_SUPPORTED(MDG_FEATURE);
 
-       mdg_manager_s *_handle = handle;
-       mdg_check_null_ret_error("handle", handle, MDG_ERROR_INVALID_PARAMETER);
-       mdg_check_null_ret_error("ejected_event_cb", receive_cb, MDG_ERROR_INVALID_PARAMETER);
-       CHECK_HANDLE_IS_VALID(handle);
+       mdg_channel_s *_channel = channel;
+       mdg_check_null_ret_error("channel", channel, MDG_ERROR_INVALID_PARAMETER);
 
-       _handle->receive_file_cb.receive_cb = receive_cb;
-       _handle->receive_file_cb.user_data = user_data;
+       *len = read(_channel->client_sockfd, *data, MAXBUF);
+       if (ret == -1) {
+               char buf[128];
+               strerror_r(errno, buf, 128);
+               _ERR("read() error : %s", buf);
+               ret = MDG_ERROR_OPERATION_FAILED;
+       }
 
        return ret;
 }
 
-EXPORT_API int mdg_unset_receive_file_cb(mdg_h handle)
+EXPORT_API int mdg_device_send_data(mdg_h handle,
+       mdg_device_h device, char *channel_id, unsigned char *data, int len,
+       mdg_device_send_data_finish_cb finish_cb, void *user_data, int *msg_id)
 {
        int ret = MDG_ERROR_NONE;
+       unsigned char *buf = NULL;
+       GVariantBuilder *bytearray_builder = NULL;
+       int i;
+       GVariant *params = NULL;
+       GError *error = NULL;
 
        CHECK_FEATURE_SUPPORTED(MDG_FEATURE);
 
        mdg_manager_s *_handle = handle;
        mdg_check_null_ret_error("handle", handle, MDG_ERROR_INVALID_PARAMETER);
+       mdg_device_s *dev = (mdg_device_s *)device;
+       mdg_check_null_ret_error("dev", dev, MDG_ERROR_INVALID_PARAMETER);
+       mdg_check_null_ret_error("channel_id", channel_id, MDG_ERROR_INVALID_PARAMETER);
+       mdg_check_null_ret_error("data", data, MDG_ERROR_INVALID_PARAMETER);
+       cond_expr_ret(len <= 0, MDG_ERROR_INVALID_PARAMETER);
        CHECK_HANDLE_IS_VALID(handle);
 
-       _handle->receive_file_cb.receive_cb = NULL;
-       _handle->receive_file_cb.user_data = NULL;
+       cond_expr_ret(dev->type == MDG_DEVICE_TYPE_LOCAL, MDG_ERROR_NOT_PROPER_DEVICE);
+
+       buf = g_try_malloc0(len + 1);
+       if (NULL == buf) {
+               /* LCOV_EXCL_START */
+               _ERR("g_malloc0 is failed");
+               return MDG_ERROR_OUT_OF_MEMORY;
+               /* LCOV_EXCL_STOP */
+       }
+       memcpy(buf, data, len);
+
+       bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+       for (i = 0; i < len; i++)
+               g_variant_builder_add(bytearray_builder, "y", buf[i]);
+
+       params = g_variant_new("(iay)", len, bytearray_builder);
+       g_variant_builder_unref(bytearray_builder);
+
+       mdg_device_h cloned_device = NULL;
+       mdg_device_info_clone(&cloned_device, device);
+
+       _handle->send_data_finish_cb.finish_cb = finish_cb;
+       _handle->send_data_finish_cb.user_data = user_data;
+       _handle->send_data_finish_cb.device = cloned_device;
+
+       group_call_send_data_sync(_handle->group_proxy, dev->device_id,
+               channel_id, params, &ret, msg_id, NULL, &error);
+       if (error) {
+               _ERR("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               ret = MDG_ERROR_IO_ERROR;
+       }
+
+       g_free(buf);
+       buf = NULL;
 
        return ret;
 }
index e32dd34..f10dd00 100755 (executable)
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
 
 #include <mdg.h>
 #include <mdg_dbus.h>
@@ -127,7 +132,7 @@ static void __event_cb(Group *object,
                char *device_id;
                char *channel_id;
 
-               mdg_get_channel_from_variant(va, &device_id, &channel_id);
+               mdg_get_channel_from_variant(va, &device_id, &channel_id, NULL);
                if (handle->request_channel_list_finish_cb.finish_cb) {
                        handle->request_channel_list_finish_cb.finish_cb(device_id, channel_id,
                                                                         handle->request_channel_list_finish_cb.user_data);
@@ -136,6 +141,56 @@ static void __event_cb(Group *object,
                }
                break;
        }
+       case MDG_EVENT_REQ_CHANNEL_OPEN_FINISH: {
+               int ret = MDG_ERROR_NONE;
+               char tempaddr[26] = {0,};
+               char *temp_for_strtok = NULL;
+               char *ret_ptr = NULL;
+               mdg_channel_s *channel = calloc(1, sizeof(mdg_channel_s));
+               if (NULL == channel) {
+                       _ERR("Memory allocation failed");
+                       ret = MDG_ERROR_OUT_OF_MEMORY;
+                       goto REQUEST_OPEN_CHANNEL_FINISH_EXIT;
+               }
+
+               mdg_get_channel_from_variant(va, &channel->device_id, &channel->channel_id,
+                       &channel->remote_address);
+
+               /* create socket */
+               struct sockaddr_in serveraddr;
+               channel->client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+               if (channel->client_sockfd < 0) {
+                       _ERR("socket() error");
+                       ret = MDG_ERROR_OPERATION_FAILED;
+                       goto REQUEST_OPEN_CHANNEL_FINISH_EXIT;
+               }
+               memset(&serveraddr, 0, sizeof(serveraddr));
+
+               serveraddr.sin_family = AF_INET;
+               serveraddr.sin_port = htons(8675);
+
+               sscanf(channel->remote_address, "coaps://%s", (char *)tempaddr);
+               ret_ptr = strtok_r(tempaddr, ":", &temp_for_strtok);
+               _ERR("Address is %s", ret_ptr);
+
+               inet_pton(AF_INET, ret_ptr, &serveraddr.sin_addr.s_addr);
+               ret = connect(channel->client_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
+
+               if (ret == -1) {
+                       _DBG("Connect error : %s", strerror(errno));
+               } else {
+                       _DBG("Success Connect to %s", ret_ptr);
+               }
+
+REQUEST_OPEN_CHANNEL_FINISH_EXIT:
+               if (handle->request_channel_open_finish_cb.channel_opened_cb) {
+                       handle->request_channel_open_finish_cb.channel_opened_cb(ret, channel,
+                                                                        handle->request_channel_open_finish_cb.user_data);
+               } else {
+                       _ERR("The callback not exists");
+               }
+               break;
+       }
        case MDG_EVENT_RECEIVE_DATA: {
                char *device_id;
                char *channel_id;
@@ -145,51 +200,17 @@ static void __event_cb(Group *object,
 
                mdg_get_data_from_variant(va, &device_id, &channel_id, &msg_id, &data, &data_len);
 
-               channel_cb_s *channel = NULL;
+               mdg_channel_cb_s *channel = NULL;
 
                GSList *l;
                for (l = handle->channel_cb_list; l != NULL; l = l->next) {
-                       channel_cb_s *tmp_channel = (channel_cb_s *)l->data;
+                       mdg_channel_cb_s *tmp_channel = (mdg_channel_cb_s *)l->data;
                        if (g_strcmp0(tmp_channel->channel_id, channel_id) == 0)
                                channel = tmp_channel;
                }
 
                if (channel != NULL)
-                       channel->cb(0, device_id, channel_id, msg_id, data, data_len, channel->user_data);
-               break;
-       }
-       case MDG_EVENT_SEND_FILE_PROGRESS: {
-               if (handle->send_file_cb.progress_cb) {
-                       int percent = 0;
-                       long long send_size, total_size;
-                       char *file_path;
-                       mdg_get_progress_from_variant(va, &file_path, &send_size, &total_size, &percent);
-                       handle->send_file_cb.progress_cb(file_path, send_size, total_size, percent,
-                                                        handle->send_file_cb.user_data);
-               } else {
-                       _ERR("The callback not exists");
-               }
-               break;
-       }
-       case MDG_EVENT_SEND_FILE_FINISH: {
-               if (handle->send_file_cb.finish_cb) {
-                       mdg_device_s *device = (mdg_device_s *)(handle->send_file_cb.device);
-                       handle->send_file_cb.finish_cb(ret, device, handle->send_file_cb.user_data);
-               } else {
-                       _ERR("The callback not exists");
-               }
-               break;
-       }
-       case MDG_EVENT_RECEIVE_FILE: {
-               if (handle->receive_file_cb.receive_cb) {
-                       char *device_id;
-                       char *file_path;
-                       mdg_get_receive_file_from_variant(va, &device_id, &file_path);
-                       handle->receive_file_cb.receive_cb(ret, device_id, file_path,
-                                                          handle->receive_file_cb.user_data);
-               } else {
-                       _ERR("The callback not exists");
-               }
+                       channel->receive_data_cb(0, device_id, channel_id, msg_id, data, data_len, channel->receive_data_cb_user_data);
                break;
        }
        case MDG_EVENT_INVITED: {
@@ -216,6 +237,93 @@ static void __event_cb(Group *object,
                }
                break;
        }
+       case MDG_EVENT_RECEIVE_OPEN_CHANNEL: {
+               int ret = MDG_ERROR_NONE;
+               mdg_channel_cb_s *channel_cb = NULL;
+               mdg_channel_s *channel = calloc(1, sizeof(mdg_channel_s));
+               if (NULL == channel) {
+                       _ERR("Memory allocation failed");
+                       ret = MDG_ERROR_OUT_OF_MEMORY;
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+               mdg_get_channel_from_variant(va, &channel->device_id, &channel->channel_id,
+                       &channel->remote_address);
+
+               GSList *l;
+               for (l = handle->channel_cb_list; l != NULL; l = l->next) {
+                       mdg_channel_cb_s *tmp_channel = (mdg_channel_cb_s *)l->data;
+                       if (g_strcmp0(tmp_channel->channel_id, channel->channel_id) == 0)
+                               channel_cb = tmp_channel;
+               }
+
+               if (channel_cb == NULL) {
+                       _ERR("[%s] The channel is not registered", channel->channel_id);
+                       ret = MDG_ERROR_NO_DATA;
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+               socklen_t client_len;
+               char buf[128];
+
+               struct linger ling;
+               struct timeval tv_timeo = {3, 0};
+
+               ling.l_onoff = 1;
+               ling.l_linger = 0;
+
+               struct sockaddr_in serveraddr, clientaddr;
+               char client_ipaddr[INET_ADDRSTRLEN];
+
+               channel->server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+               if (channel->server_sockfd == -1) {
+                       ret = MDG_ERROR_OPERATION_FAILED;
+                       strerror_r(errno, buf, 128);
+                       _ERR("socket error : %s", buf);
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+               setsockopt(channel->server_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, sizeof(tv_timeo));
+               setsockopt(channel->server_sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+
+               serveraddr.sin_family = AF_INET;
+               serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
+               serveraddr.sin_port = htons(8675);
+
+               if (bind(channel->server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
+                       ret = MDG_ERROR_OPERATION_FAILED;
+                       strerror_r(errno, buf, 128);
+                       _ERR("bind error : %s", buf);
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+               if (listen(channel->server_sockfd, 5) != 0) {
+                       ret = MDG_ERROR_OPERATION_FAILED;
+                       strerror_r(errno, buf, 128);
+                       _ERR("listen error : %s", buf);
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+               client_len = sizeof(clientaddr);
+               channel->client_sockfd = accept(channel->server_sockfd, (struct sockaddr *)&clientaddr, &client_len);
+               inet_ntop(AF_INET, &clientaddr.sin_addr.s_addr, client_ipaddr, sizeof(client_ipaddr));
+               _DBG("Accepted IP : %s, client socket : %d", client_ipaddr, channel->client_sockfd);
+
+               if (channel->client_sockfd == -1) {
+                       ret = MDG_ERROR_OPERATION_FAILED;
+                       strerror_r(errno, buf, 128);
+                       _ERR("socket error : %s", buf);
+                       goto RECEIVE_OPEN_CHANNEL_EXIT;
+               }
+
+RECEIVE_OPEN_CHANNEL_EXIT:
+               if (channel_cb && channel_cb->opened_cb) {
+                       channel_cb->opened_cb(ret, channel, channel_cb->opened_cb_user_data);
+               } else {
+                       _ERR("The callback not exists");
+               }
+               break;
+       }
        default:
                _ERR("Unknown Event");
                break;
index 966828b..e657f2f 100755 (executable)
                        <arg type="s" name="preconfigured_pin" direction="in" />
                        <arg type="i" name="result" direction="out" />
                </method>
+               <method name="RequestChannelOpen">
+                       <arg type="s" name="uuid" direction="in" />
+                       <arg type="s" name="channel_id" direction="in"/>
+                       <arg type="i" name="result" direction="out" />
+               </method>
                <!-- Signal (D-Bus) definitions -->
                <signal name="Event">
                        <arg type="i" name="type" direction="out" />
index 53f2e84..cb43781 100755 (executable)
@@ -121,22 +121,6 @@ typedef struct _send_data_finish_cb_t {
 } send_data_finish_cb_t;
 
 /**
- * @brief Sending data to the device done callback structure
- * @since_tizen 5.0
- */
-typedef struct _send_file_cb_t {
-       mdg_send_file_progress_cb progress_cb; /**< User callback to be called */
-       mdg_send_file_finish_cb finish_cb;     /**< User callback to be called */
-       mdg_device_h device;
-       void *user_data; /**< User data pointer */
-} send_file_cb_t;
-
-typedef struct _receive_file_cb_t {
-       mdg_receive_file_cb receive_cb; /**< User callback to be called */
-       void *user_data;                /**< User data pointer */
-} receive_file_cb_t;
-
-/**
  * @brief Sending internal commands to the device done callback structure
  * @since_tizen 5.0
  */
@@ -150,6 +134,12 @@ typedef struct _request_channel_list_finish_cb_t {
        void *user_data;                              /**< User data pointer */
 } request_channel_list_finish_cb_t;
 
+typedef struct _request_channel_open_finish_cb_t {
+       mdg_channel_opened_cb channel_opened_cb; /**< User callback to be called */
+       mdg_device_h device;
+       void *user_data;                       /**< User data pointer */
+} request_channel_open_finish_cb_t;
+
 typedef struct _invited_event_cb_t {
        mdg_invited_event_cb invited_event_cb; /**< User callback to be called */
        void *user_data;                       /**< User data pointer */
@@ -177,10 +167,9 @@ typedef struct _mdg_manager_s {
        device_invite_finish_cb_t device_invite_finish_cb;               /**< When it called after invinting a device done or timeout */
        device_eject_finish_cb_t device_eject_finish_cb;                 /**< When it called after ejecting the device done or timeout */
        send_data_finish_cb_t send_data_finish_cb;                       /**< When it called after sending the device done or timeout */
-       send_file_cb_t send_file_cb;                                     /**< When it called after sending the device done or timeout */
-       receive_file_cb_t receive_file_cb;                               /**< When it called after sending the device done or timeout */
        request_result_cb_t request_result_cb;                           /**< When it called after sending private commands or timeout */
        request_channel_list_finish_cb_t request_channel_list_finish_cb; /**< When it called after sending private commands or timeout */
+       request_channel_open_finish_cb_t request_channel_open_finish_cb;
        invited_event_cb_t invited_event_cb;
        ejected_event_cb_t ejected_event_cb;
 } mdg_manager_s;
@@ -216,11 +205,23 @@ typedef struct _mdg_device_s {
        mdg_device_type_e type; /**< Device Type */
 } mdg_device_s;
 
-typedef struct _channel_cb_s {
+typedef struct _mdg_channel_s {
+       char *device_id; /**< Device ID */
+       char *channel_id;
+       char *remote_address;
+       int server_sockfd;
+       int client_sockfd;
+       int remote_port;
+       mdg_channel_type_e type;
+} mdg_channel_s;
+
+typedef struct _mdg_channel_cb_s {
        char *channel_id;
-       mdg_receive_data_cb cb;
-       void *user_data;
-} channel_cb_s;
+       mdg_channel_receive_data_cb receive_data_cb;
+       void *receive_data_cb_user_data;
+       mdg_channel_opened_cb opened_cb;
+       void *opened_cb_user_data;
+} mdg_channel_cb_s;
 
 typedef enum {
        MDG_EVENT_GROUP_FOUND = 100,
@@ -232,10 +233,9 @@ typedef enum {
        MDG_EVENT_REQUEST_FINISH,
        MDG_EVENT_SEND_DATA_FINISH,
        MDG_EVENT_REQ_CHANNEL_LIST_FINISH,
-       MDG_EVENT_RECEIVE_DATA,
-       MDG_EVENT_RECEIVE_FILE = 110,
-       MDG_EVENT_SEND_FILE_PROGRESS,
-       MDG_EVENT_SEND_FILE_FINISH,
+       MDG_EVENT_REQ_CHANNEL_OPEN_FINISH,
+       MDG_EVENT_RECEIVE_DATA = 110,
+       MDG_EVENT_RECEIVE_OPEN_CHANNEL
 } mdg_private_event_type_e;
 
 #endif /* __TIZEN_NETWORK_COMMON_MDG_PRIVATE_H__ */
index 3d602f6..37b0f13 100755 (executable)
@@ -112,7 +112,8 @@ mdg_device_s *mdg_get_device_from_variant(GVariant *va)
        return device;
 }
 
-void mdg_get_channel_from_variant(GVariant *va, char **device_id, char **channel_id)
+void mdg_get_channel_from_variant(GVariant *va, char **device_id, char **channel_id,
+       char **remote_address)
 {
        GVariantIter *iter = NULL;
        const gchar *key;
@@ -124,6 +125,10 @@ void mdg_get_channel_from_variant(GVariant *va, char **device_id, char **channel
                        *device_id = (char *)g_variant_get_string(key_value, NULL);
                else if (g_strcmp0(key, "ChannelID") == 0)
                        *channel_id = (char *)g_variant_get_string(key_value, NULL);
+               else if (g_strcmp0(key, "RemoteAddress") == 0) {
+                       if (remote_address != NULL)
+                               *remote_address = (char *)g_variant_get_string(key_value, NULL);
+               }
        }
 
        g_variant_iter_free(iter);
index c3dde47..47619d3 100755 (executable)
@@ -27,7 +27,8 @@ extern "C" {
 GVariant *mdg_create_variant_device(mdg_device_s *device);
 mdg_device_s *mdg_get_device_from_variant(GVariant *va);
 mdg_group_s *mdg_get_group_from_variant(GVariant *va);
-void mdg_get_channel_from_variant(GVariant *va, char **device_id, char **channel_id);
+void mdg_get_channel_from_variant(GVariant *va, char **device_id, char **channel_id,
+       char **remote_address);
 void mdg_get_data_from_variant(GVariant *va, char **device_id, char **channel_id,
                               int *msg_id, unsigned char **data, int *data_len);
 void mdg_get_receive_file_from_variant(GVariant *va, char **device_id, char **file_path);
old mode 100644 (file)
new mode 100755 (executable)
index 2deaffd..cec9ac7
@@ -42,7 +42,6 @@ static char channel_idx[MENU_DATA_SIZE + 1] = "1";
 static char pin[MENU_DATA_SIZE + 1] = "12341234";
 static char message[MENU_DATA_SIZE + 1] = "Hello World!!";
 static char channel_id[MENU_DATA_SIZE + 1] = "Channel1";
-static char file_path[MENU_DATA_SIZE + 1] = "/path/to/file";
 
 static int run_group_find(MManager *mm, struct menu_data *menu);
 static int run_devices_find(MManager *mm, struct menu_data *menu);
@@ -595,11 +594,6 @@ void __ejected_event_cb(mdg_group_h group, void *user_data)
        g_free(name);
 }
 
-void __receive_file_cb(int result, char *device_id, const char *file_path, void *user_data)
-{
-       msgb("The %s is stored by %s", file_path, device_id);
-}
-
 int run_device_show_local_device(MManager *mm, struct menu_data *menu)
 {
        int ret = 0;
@@ -661,7 +655,6 @@ int run_device_show_local_device(MManager *mm, struct menu_data *menu)
 
        mdg_set_invited_event_cb(handle, __invited_event_cb, NULL);
        mdg_set_ejected_event_cb(handle, __ejected_event_cb, NULL);
-       mdg_set_receive_file_cb(handle, __receive_file_cb, NULL);
 
        return RET_SUCCESS;
 }
@@ -899,72 +892,6 @@ static int run_send_data(MManager *mm, struct menu_data *menu)
        return __send_data(devidx, chaidx);
 }
 
-void __send_file_progress_cb(const char *file_path, long long send_size,
-       long long total_size, int percent, void *user_data)
-{
-       msgp("%s  %d%% [%lld/%lld]", file_path, percent, send_size, total_size);
-}
-void __send_file_finish_cb(int result, mdg_device_h device, void *user_data)
-{
-       char *device_id;
-
-       mdg_device_info_get_device_id(device, &device_id);
-
-       msgp("Send file to %s Finished [%s]", device_id, mdg_error_to_string(result));
-
-       g_free(device_id);
-}
-
-static int __send_file(int devidx)
-{
-       int ret = 0;
-       char *deviceid = NULL;
-       mdg_device_h device = NULL;
-
-       if (found_invited_device_list) {
-               device = g_list_nth_data(found_invited_device_list, devidx - 1);
-               if (NULL == device) {
-                       msgr("Find local device first");
-                       return RET_FAILURE;
-               }
-       }
-
-       mdg_device_info_get_device_id(device, &deviceid);
-       msgp("Sent to [ID] %s", deviceid);
-       if (deviceid) {
-               free(deviceid);
-               deviceid = NULL;
-       }
-
-       ret = mdg_device_send_file(handle, device, file_path,
-               __send_file_progress_cb, __send_file_finish_cb, NULL);
-       if (MDG_ERROR_NONE != ret)
-               msgr("Failed to Send Data: [ID] %s", deviceid);
-
-       return ret;
-}
-
-static int run_send_file(MManager *mm, struct menu_data *menu)
-{
-       int devidx = 0;
-       int count = g_list_length(found_invited_device_list);
-
-       if (0 >= count) {
-               msgr("No Device");
-               return RET_SUCCESS;
-       }
-
-       if (strlen(device_idx)) {
-               devidx = (unsigned short)strtol(device_idx, NULL, 10);
-               if (0 >= devidx) {
-                       msgp("Invalid index. set to 1");
-                       devidx = 1;
-               }
-       }
-
-       return __send_file(devidx);
-}
-
 void _invited_device_finish_cb(int result, void *user_data)
 {
        msgb("\rFind My Owned Devices Finished ret: [0x%X] [%s]", result,
@@ -1252,14 +1179,30 @@ void __channel_cb(int result, char *device_id, char *channel_id, int msg_id,
        mdg_device_send_response(handle, device_id, channel_id, msg_id, (unsigned char *)"Ya, Hi", 6);
 }
 
+
+void __channel_opened_cb(int result, mdg_channel_h channel, void *user_data)
+{
+       msgb("result is %d", result);
+       if (result == MDG_ERROR_NONE)
+               msgb("channel opened callback is called. server socket is created");
+       else
+               msgb("channel opened callback is called. but server socket is not created");
+
+       unsigned char buf[256] = "SENDSEND";
+       mdg_channel_write(channel, buf, 256);
+       //write and recv using mdg_channel_write / mdg_channel_recv
+}
+
 static int run_regist_channel(MManager *mm, struct menu_data *menu)
 {
        int ret = 0;
 
        ret = mdg_device_regist_channel(handle, channel_id, __channel_cb, NULL);
-
        msg(" - mdg_device_regist_channel() ret: [0x%X] [%s]", ret, mdg_error_to_string(ret));
 
+       ret = mdg_set_channel_opened_callback(handle, channel_id, __channel_opened_cb, NULL);
+       msg(" - mdg_set_channel_opened_callback() ret: [0x%X] [%s]", ret, mdg_error_to_string(ret));
+
        return RET_SUCCESS;
 }
 
@@ -1285,6 +1228,99 @@ static int run_set_preconfigured_pin(MManager *mm, struct menu_data *menu)
        return RET_SUCCESS;
 }
 
+void _mdg_channel_client_opened_cb(int result, mdg_channel_h channel, void *user_data)
+{
+       msgp("Client Opened result : %d", result);
+
+       unsigned char *buf;
+       buf = (unsigned char *)malloc(1024);
+       int len;
+       mdg_channel_read(channel, &buf, &len);
+
+       msgp("Get Data : %s, %d", buf, len);
+}
+
+static int __request_open_channel(int devidx, int chaidx)
+{
+       int ret = 0;
+       char *deviceid = NULL;
+       mdg_device_h device = NULL;
+       channel_t *channel = NULL;
+
+       if (!found_invited_device_list || !found_channel_list) {
+                       msgr("Find local device first");
+                       return RET_FAILURE;
+       }
+
+       if (found_invited_device_list) {
+               device = g_list_nth_data(found_invited_device_list, devidx - 1);
+               if (NULL == device) {
+                       msgr("Find local device first");
+                       return RET_FAILURE;
+               }
+       }
+
+       if (found_channel_list) {
+               channel = g_list_nth_data(found_channel_list, chaidx - 1);
+               if (NULL == channel) {
+                       msgr("Find local device first");
+                       return RET_FAILURE;
+               }
+       }
+
+       if (NULL == device) {
+               msgr("device is NULL");
+               return RET_FAILURE;
+       }
+
+       if (NULL == channel) {
+               msgr("channel is NULL");
+               return RET_FAILURE;
+       }
+
+       mdg_device_info_get_device_id(device, &deviceid);
+       msgp("Open channel between [ID] %s [CHANNEL ID] %s", deviceid, channel->channel_id);
+       if (deviceid) {
+               free(deviceid);
+               deviceid = NULL;
+       }
+
+       ret = mdg_request_channel_open(handle, device, channel->channel_id,
+               _mdg_channel_client_opened_cb, NULL);
+       if (MDG_ERROR_NONE != ret)
+               msgr("Failed to Send Data: [ID] %s", deviceid);
+
+       return ret;
+}
+
+static int run_request_open_channel(MManager *mm, struct menu_data *menu)
+{
+       int devidx = 0;
+       int chaidx = 0;
+       int count = g_list_length(found_invited_device_list);
+
+       if (0 >= count) {
+               msgr("No Device");
+               return RET_SUCCESS;
+       }
+
+       if (strlen(device_idx)) {
+               devidx = (unsigned short)strtol(device_idx, NULL, 10);
+               if (0 >= devidx) {
+                       msgp("Invalid index. set to 1");
+                       devidx = 1;
+               }
+       }
+       if (strlen(channel_idx)) {
+               chaidx = (unsigned short)strtol(channel_idx, NULL, 10);
+               if (0 >= chaidx) {
+                       msgp("Invalid index. set to 1");
+                       chaidx = 1;
+               }
+       }
+       return __request_open_channel(devidx, chaidx);
+}
+
 static struct menu_data menu_group_create[] = {
        { "0", "Group Name", NULL, NULL, groupid },
        { "1", "Run", NULL, run_group_create, NULL },
@@ -1346,14 +1382,6 @@ static struct menu_data menu_send_data[] = {
        { NULL, NULL, },
 };
 
-static struct menu_data menu_send_file[] = {
-       { "0", "Show Found Invited Device(s)", NULL, run_invited_devices_show, NULL },
-       { "1", "File Path", NULL, NULL, file_path },
-       { "2", "Device Index", NULL, NULL, device_idx },
-       { "3", "Send", NULL, run_send_file, NULL },
-       { NULL, NULL, },
-};
-
 static struct menu_data menu_devices_find_invited_device[] = {
        { "0", "Timeout", NULL, NULL, timeout },
        { "1", "Run", NULL, run_devices_find_invited_device, NULL },
@@ -1412,6 +1440,15 @@ static struct menu_data menu_set_preconfigured_pin[] = {
        { NULL, NULL, },
 };
 
+static struct menu_data menu_request_open_channel[] = {
+       { "0", "Show Found Invited Device(s)", NULL, run_invited_devices_show, NULL },
+       { "1", "Show Channel List", NULL, run_channels_show, NULL },
+       { "2", "Device Index", NULL, NULL, device_idx },
+       { "3", "Channel Index", NULL, NULL, channel_idx },
+       { "4", "Run", NULL, run_request_open_channel, NULL },
+       { NULL, NULL, },
+};
+
 struct menu_data menu_mdg_manager[] = {
        { "1", "Show Local Device", NULL, run_device_show_local_device, NULL }, // O
        { "2", "Create Group", menu_group_create, NULL, NULL }, // 0
@@ -1432,6 +1469,6 @@ struct menu_data menu_mdg_manager[] = {
        { "17", "Regist Channel", menu_regist_channel, NULL, NULL },
        { "18", "Unregist Channel", menu_unregist_channel, NULL, NULL },
        { "19", "Send Message", menu_send_data, NULL, NULL }, // 0
-       { "20", "Send File", menu_send_file, NULL, NULL }, // 0
-       { "21", "Set Preconfigured PIN", menu_set_preconfigured_pin, NULL, NULL }, // 0
+       { "20", "Set Preconfigured PIN", menu_set_preconfigured_pin, NULL, NULL }, // 0
+       { "21", "Request Open Channel", menu_request_open_channel, NULL, NULL }, // 0
 };