From 7e8470061762b7cb9ac7d4ebcff1d697f3a5ca23 Mon Sep 17 00:00:00 2001 From: Jihoon Jung Date: Tue, 26 Feb 2019 13:48:46 +0900 Subject: [PATCH] Added 'End-point' functionality. - 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 | 32 +++++++- include/mdg_internal.h | 14 ---- src/mdg.c | 183 ++++++++++++++++++++++++++----------------- src/mdg_dbus.c | 184 +++++++++++++++++++++++++++++++++++--------- src/mdg_gdbus.xml | 5 ++ src/mdg_private.h | 52 ++++++------- src/mdg_util.c | 7 +- src/mdg_util.h | 3 +- test/mdg-manager.c | 205 +++++++++++++++++++++++++++++-------------------- 9 files changed, 449 insertions(+), 236 deletions(-) mode change 100644 => 100755 test/mdg-manager.c diff --git a/include/mdg.h b/include/mdg.h index c1deaac..8b017e2 100755 --- a/include/mdg.h +++ b/include/mdg.h @@ -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); + /** * @} */ diff --git a/include/mdg_internal.h b/include/mdg_internal.h index 3df8650..e3fe622 100755 --- a/include/mdg_internal.h +++ b/include/mdg_internal.h @@ -23,20 +23,6 @@ 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 diff --git a/src/mdg.c b/src/mdg.c index 3fccf4c..301d52f 100755 --- 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; } diff --git a/src/mdg_dbus.c b/src/mdg_dbus.c index e32dd34..f10dd00 100755 --- a/src/mdg_dbus.c +++ b/src/mdg_dbus.c @@ -20,6 +20,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -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; diff --git a/src/mdg_gdbus.xml b/src/mdg_gdbus.xml index 966828b..e657f2f 100755 --- a/src/mdg_gdbus.xml +++ b/src/mdg_gdbus.xml @@ -102,6 +102,11 @@ + + + + + diff --git a/src/mdg_private.h b/src/mdg_private.h index 53f2e84..cb43781 100755 --- a/src/mdg_private.h +++ b/src/mdg_private.h @@ -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__ */ diff --git a/src/mdg_util.c b/src/mdg_util.c index 3d602f6..37b0f13 100755 --- a/src/mdg_util.c +++ b/src/mdg_util.c @@ -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); diff --git a/src/mdg_util.h b/src/mdg_util.h index c3dde47..47619d3 100755 --- a/src/mdg_util.h +++ b/src/mdg_util.h @@ -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); diff --git a/test/mdg-manager.c b/test/mdg-manager.c old mode 100644 new mode 100755 index 2deaffd..cec9ac7 --- a/test/mdg-manager.c +++ b/test/mdg-manager.c @@ -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 }; -- 2.7.4