2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <bundle_internal.h>
23 #include <sys/socket.h>
30 #include <gio/gunixfdlist.h>
31 #include <glib-unix.h>
33 #include "message_port_log.h"
34 #include "message_port.h"
35 #include "message_port_remote.h"
36 #include "message_port_common.h"
38 #define MAX_RETRY_CNT 10
39 #define SOCK_PAIR_SENDER 0
40 #define SOCK_PAIR_RECEIVER 1
42 static bool _initialized = false;
43 static GHashTable *__remote_app_info;
44 static GHashTable *__registered_callback_info_hash;
45 static const int MAX_MESSAGE_SIZE = 16 * 1024;
47 enum __certificate_info_type {
50 CERTIFICATE_NOT_MATCH,
53 typedef struct message_port_remote_port_info {
57 } message_port_remote_app_info_s;
59 typedef struct port_list_info {
60 message_port_remote_app_info_s *remote_app_info;
62 char *encoded_bus_name;
68 GList *delayed_message_list;
69 unsigned int delayed_message_size;
73 typedef struct registered_callback_info {
79 message_port_registration_event_cb registered_cb;
80 message_port_registration_event_cb unregistered_cb;
81 } registered_callback_info_s;
83 enum transmission_sequence {
94 typedef struct delay_message {
96 unsigned int sent_bytes;
99 char *local_port_name;
104 } delay_message_info_s;
106 extern pthread_mutex_t mutex;
108 /* LCOV_EXCL_START */
109 static void __free_delay_message_info(delay_message_info_s *message)
111 if (message != NULL) {
112 FREE_AND_NULL(message->local_port_name);
113 FREE_AND_NULL(message->data);
114 FREE_AND_NULL(message);
119 /* LCOV_EXCL_START */
120 static void __free_list_delay_message_info(gpointer data)
122 delay_message_info_s *message = (delay_message_info_s *)data;
125 __free_delay_message_info(message);
129 /* LCOV_EXCL_START */
130 static void __clear_disconnect_socket(port_list_info_s *port_info)
132 GError *error = NULL;
134 if (port_info == NULL)
137 if (port_info->gio_read != NULL) {
138 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
140 _LOGE("g_io_channel_shutdown error : %s", error->message);
143 g_io_channel_unref(port_info->gio_read);
144 port_info->gio_read = NULL;
147 if (port_info->g_src_id != 0) {
148 g_source_remove(port_info->g_src_id);
149 port_info->g_src_id = 0;
152 if (port_info->delay_src_id != 0) {
153 g_source_remove(port_info->delay_src_id);
154 port_info->delay_src_id = 0;
157 if (port_info->delayed_message_list != NULL) {
158 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
160 port_info->delayed_message_list = NULL;
163 port_info->delayed_message_size = 0;
164 port_info->send_sock_fd = 0;
168 /* LCOV_EXCL_START */
169 static void __free_port_info(gpointer data)
171 port_list_info_s *port_info = (port_list_info_s *)data;
172 message_port_remote_app_info_s *remote_app_info;
174 if (port_info == NULL)
177 remote_app_info = port_info->remote_app_info;
179 _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
180 remote_app_info->remote_app_id,
181 port_info->port_name);
183 remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
186 __clear_disconnect_socket(port_info);
188 if (port_info->encoded_bus_name)
189 free(port_info->encoded_bus_name);
190 if (port_info->port_name)
191 free(port_info->port_name);
195 if (g_list_length(remote_app_info->port_list) == 0) {
196 g_hash_table_remove(__remote_app_info,
197 remote_app_info->remote_app_id);
202 /* LCOV_EXCL_START */
203 static void __hash_destory_remote_value(gpointer data)
205 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
207 FREE_AND_NULL(mri->remote_app_id);
209 g_list_free_full(mri->port_list, __free_port_info);
216 static void __registered_callback_info_free(gpointer data)
218 registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
219 if (callback_info == NULL)
222 if (callback_info->remote_app_id)
223 free(callback_info->remote_app_id);
225 if (callback_info->remote_port)
226 free(callback_info->remote_port);
231 static bool __initialize(void)
233 if (!initialized_common) {
234 if (!initialize_common())
238 if (__remote_app_info == NULL) {
239 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
240 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
243 if (__registered_callback_info_hash == NULL) {
244 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __registered_callback_info_free);
245 retvm_if(!__registered_callback_info_hash, false, "fail to create __registered_callback_info_hash");
253 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
255 port_list_info_s *key1 = (port_list_info_s *)a;
256 port_list_info_s *key2 = (port_list_info_s *)b;
258 if (key1->is_trusted == key2->is_trusted)
259 return strcmp(key1->port_name, key2->port_name);
264 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
266 int ret_val = MESSAGE_PORT_ERROR_NONE;
267 port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
270 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
273 port_info->port_name = strdup(remote_port);
274 if (!port_info->port_name) {
275 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
278 port_info->is_trusted = is_trusted;
279 port_info->encoded_bus_name = get_encoded_name(remote_app_id, remote_port, is_trusted);
280 if (port_info->encoded_bus_name == NULL) {
281 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
284 port_info->send_sock_fd = 0;
286 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
288 FREE_AND_NULL(port_info->port_name);
289 FREE_AND_NULL(port_info->encoded_bus_name);
297 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
299 message_port_remote_app_info_s *remote_app_info = NULL;
300 int ret_val = MESSAGE_PORT_ERROR_NONE;
302 remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
303 if (!remote_app_info) {
304 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
308 remote_app_info->remote_app_id = strdup(remote_app_id);
309 if (remote_app_info->remote_app_id == NULL) {
310 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
315 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
316 if (remote_app_info) {
317 FREE_AND_NULL(remote_app_info->remote_app_id);
318 FREE_AND_NULL(remote_app_info);
322 return remote_app_info;
325 static gboolean __socket_disconnect_handler(GIOChannel *gio,
329 _LOGI("__socket_disconnect_handler %d", cond);
330 __free_port_info(data);
335 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
336 message_port_remote_app_info_s **mri, port_list_info_s **pli)
338 message_port_remote_app_info_s *remote_app_info = NULL;
339 port_list_info_s port_info;
340 GList *cb_list = NULL;
341 int ret_val = MESSAGE_PORT_ERROR_NONE;
343 remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
345 if (remote_app_info == NULL) {
346 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
348 if (remote_app_info == NULL) {
349 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
352 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
354 *mri = remote_app_info;
356 port_info.port_name = strdup(remote_port);
357 if (port_info.port_name == NULL) {
358 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
361 port_info.is_trusted = is_trusted;
362 cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
363 (GCompareFunc)__remote_port_compare_cb);
364 if (port_info.port_name)
365 free(port_info.port_name);
366 if (cb_list == NULL) {
367 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
369 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
372 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
373 tmp->remote_app_info = remote_app_info;
376 *pli = (port_list_info_s *)cb_list->data;
383 int check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
385 _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
387 GVariant *result = NULL;
389 int ret_val = MESSAGE_PORT_ERROR_NONE;
390 char *bus_name = NULL;
391 message_port_remote_app_info_s *remote_app_info = NULL;
392 port_list_info_s *port_info = NULL;
393 int local_reg_id = 0;
394 message_port_local_port_info_s *mi = NULL;
395 gboolean name_exist = false;
399 return MESSAGE_PORT_ERROR_IO_ERROR;
402 _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
404 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
405 if (ret_val != MESSAGE_PORT_ERROR_NONE)
409 if (strcmp(remote_app_id, app_id) == 0) {
411 _LOGD("__is_local_port_registed ");
412 if (!is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
417 _LOGD("__is_local_port_registed : %d ", *exist);
418 return MESSAGE_PORT_ERROR_NONE;
421 port_info->exist = false;
422 bus_name = port_info->encoded_bus_name;
424 result = g_dbus_connection_call_sync(
430 g_variant_new("(s)", bus_name),
431 G_VARIANT_TYPE("(b)"),
432 G_DBUS_CALL_FLAGS_NONE,
437 if (err || (result == NULL)) {
439 _LOGE("No reply. error = %s", err->message);
442 ret_val = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
444 g_variant_get(result, "(b)", &name_exist);
447 _LOGI("Name not exist %s", bus_name);
449 ret_val = MESSAGE_PORT_ERROR_NONE;
453 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
454 if (!is_preloaded(app_id, remote_app_id)) {
455 if (check_certificate(app_id, remote_app_id) != MESSAGE_PORT_ERROR_NONE) {
456 ret_val = MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
460 remote_app_info->certificate_info = CERTIFICATE_MATCH;
463 port_info->exist = true;
465 ret_val = MESSAGE_PORT_ERROR_NONE;
470 g_variant_unref(result);
472 if (ret_val != MESSAGE_PORT_ERROR_NONE || !name_exist)
473 __free_port_info((gpointer)port_info);
478 /* LCOV_EXCL_START */
479 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
482 int sequence = message->sequence - 1;
483 int ret = MESSAGE_PORT_ERROR_NONE;
484 bool is_startline = true;
487 _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
488 sockfd, message->sequence, message->sent_bytes);
490 switch (message->sequence) {
493 is_startline = false;
495 case SEQUENCE_PORT_LEN:
497 offset = message->sent_bytes;
499 ret = write_socket(sockfd, ((char *)&message->local_port_len) + offset,
500 sizeof(message->local_port_len) - offset, &nb, &sequence);
501 if (ret != MESSAGE_PORT_ERROR_NONE) {
502 _LOGE("write local_port_len fail");
506 is_startline = false;
508 case SEQUENCE_PORT_NAME:
510 offset = message->sent_bytes;
512 if (message->local_port_len > 0)
513 ret = write_socket(sockfd, message->local_port_name + offset,
514 message->local_port_len - offset , &nb, &sequence);
518 if (ret != MESSAGE_PORT_ERROR_NONE) {
519 _LOGE("write local_port fail");
523 is_startline = false;
525 case SEQUENCE_BIDIRECTION:
527 offset = message->sent_bytes;
529 ret = write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
530 sizeof(message->is_bidirection) - offset, &nb, &sequence);
531 if (ret != MESSAGE_PORT_ERROR_NONE) {
532 _LOGE("write is_bidirection fail");
536 is_startline = false;
538 case SEQUENCE_TRUSTED:
540 offset = message->sent_bytes;
542 ret = write_socket(sockfd, ((char *)&message->local_trusted) + offset,
543 sizeof(message->local_trusted) - offset, &nb, &sequence);
544 if (ret != MESSAGE_PORT_ERROR_NONE) {
545 _LOGE("write local_trusted fail");
549 is_startline = false;
551 case SEQUENCE_DTAT_LEN:
553 offset = message->sent_bytes;
555 ret = write_socket(sockfd, ((char *)&message->data_len) + offset,
556 sizeof(message->data_len) - offset, &nb, &sequence);
557 if (ret != MESSAGE_PORT_ERROR_NONE) {
558 _LOGE("write data_len fail");
562 is_startline = false;
566 offset = message->sent_bytes;
568 ret = write_socket(sockfd, (char *)message->data + offset,
569 message->data_len - offset, &nb, &sequence);
571 if (ret != MESSAGE_PORT_ERROR_NONE) {
572 _LOGE("write data fail");
576 is_startline = false;
579 ret = MESSAGE_PORT_ERROR_NONE;
584 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
586 message->sent_bytes += nb;
588 message->sent_bytes = nb;
590 message->sequence = sequence;
591 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
592 sockfd, message->sequence, message->sent_bytes);
600 /* LCOV_EXCL_START */
601 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
603 port_list_info_s *port_info = (port_list_info_s *)data;
604 delay_message_info_s *message;
607 if (port_info == NULL)
608 return G_SOURCE_REMOVE;
610 pthread_mutex_lock(&mutex);
612 if (port_info->delayed_message_list == NULL) {
613 port_info->delayed_message_size = 0;
614 port_info->delay_src_id = 0;
615 pthread_mutex_unlock(&mutex);
616 return G_SOURCE_REMOVE;
618 message = g_list_nth_data(port_info->delayed_message_list, 0);
619 ret = __send_delayed_message(port_info->send_sock_fd, message);
621 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
622 pthread_mutex_unlock(&mutex);
623 return G_SOURCE_CONTINUE;
624 } else if (ret == MESSAGE_PORT_ERROR_IO_ERROR) {
625 __free_port_info((gpointer)port_info);
626 pthread_mutex_unlock(&mutex);
627 return G_SOURCE_REMOVE;
630 port_info->delayed_message_size -= message->size;
632 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
633 __free_delay_message_info(message);
636 pthread_mutex_unlock(&mutex);
638 return G_SOURCE_CONTINUE;
642 /* LCOV_EXCL_START */
643 static int __insert_delayed_message(port_list_info_s *port_info,
647 unsigned int sent_bytes,
648 const char *local_port,
652 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
654 unsigned int tmp_size;
655 unsigned int message_size;
656 int ret = MESSAGE_PORT_ERROR_NONE;
658 if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
659 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
660 port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
661 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
664 delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
665 retvm_if(!message, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
667 message_size = sizeof(delay_message_info_s);
669 message->sequence = sequence;
670 tmp_size = strlen(local_port) + 1;
671 message_size += tmp_size;
672 message->local_port_len = tmp_size;
673 message->local_port_name = strdup(local_port);
674 if (message->local_port_name == NULL) {
675 _LOGE("local_port_name strdup fail");
676 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
679 message->is_bidirection = is_bidirection;
680 message->local_trusted = local_trusted;
681 message_size += data_len;
682 message->data_len = data_len;
683 message->data = (bundle_raw *)strdup((const char *)kb_data);
684 if (message->data == NULL) {
685 _LOGE("data strdup fail");
686 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
691 message->sent_bytes = sent_bytes;
692 message->size = message_size;
693 port_info->delayed_message_size += message_size;
695 port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
697 if (port_info->delay_src_id == 0) {
698 port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
699 port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
703 _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
704 port_info->port_name, port_info->send_sock_fd, message_size,
705 port_info->delayed_message_size,
706 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
711 if (ret != MESSAGE_PORT_ERROR_NONE)
712 __free_delay_message_info(message);
718 static int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
719 bool local_trusted, bool is_bidirection)
724 bundle_raw *kb_data = NULL;
725 int sequence = SEQUENCE_START;
727 bundle_encode(kb, &kb_data, &data_len);
728 if (kb_data == NULL) {
729 _LOGE("bundle encode fail");
730 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
734 if (data_len > MAX_MESSAGE_SIZE) {
735 _LOGE("bigger than max size\n");
736 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
740 if (g_list_length(port_info->delayed_message_list) > 0) {
741 ret = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
742 _LOGE("There are messages in the delayed_message_list (count %d)",
743 g_list_length(port_info->delayed_message_list));
747 ret = write_string_to_socket(port_info->send_sock_fd, local_port,
748 strlen(local_port) + 1, &nb, &sequence);
749 if (ret != MESSAGE_PORT_ERROR_NONE) {
750 _LOGE("write local_port fail");
754 ret = write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
755 sizeof(is_bidirection), &nb, &sequence);
756 if (ret != MESSAGE_PORT_ERROR_NONE) {
757 _LOGE("write is_bidirection fail");
761 ret = write_socket(port_info->send_sock_fd, (char *)&local_trusted,
762 sizeof(local_trusted), &nb, &sequence);
763 if (ret != MESSAGE_PORT_ERROR_NONE) {
764 _LOGE("write local_trusted fail");
768 ret = write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
769 data_len, &nb, &sequence);
770 if (ret != MESSAGE_PORT_ERROR_NONE) {
771 _LOGE("write kb_data fail");
776 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
777 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
778 local_port, local_trusted, is_bidirection);
779 if (ret != MESSAGE_PORT_ERROR_NONE)
780 ret = MESSAGE_PORT_ERROR_IO_ERROR;
789 int send_message(const char *remote_appid, const char *remote_port,
790 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
793 int ret = MESSAGE_PORT_ERROR_NONE;
794 GUnixFDList *fd_list = NULL;
797 bundle_raw *raw = NULL;
798 char *bus_name = NULL;
799 char *interface_name = NULL;
801 message_port_remote_app_info_s *remote_app_info = NULL;
802 port_list_info_s *port_info = NULL;
803 GDBusMessage *msg = NULL;
805 GVariant *body = NULL;
806 int sock_pair[2] = {0,};
811 return MESSAGE_PORT_ERROR_IO_ERROR;
814 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
815 if (ret != MESSAGE_PORT_ERROR_NONE)
818 if (port_info->exist == false) {
820 _LOGD("port exist check !!");
821 ret = check_remote_port(remote_appid, remote_port, trusted_message, &exist);
822 if (ret != MESSAGE_PORT_ERROR_NONE)
825 return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
828 if (port_info->send_sock_fd > 0) {
829 ret = __message_port_send_async(port_info, message,
830 (local_port) ? local_port : "", local_trusted, bi_dir);
833 bus_name = port_info->encoded_bus_name;
834 interface_name = bus_name;
836 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
837 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
841 if (MAX_MESSAGE_SIZE < len) {
842 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
843 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
847 body = g_variant_new("(ssbbssbus)", app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
848 remote_appid, remote_port, trusted_message, len, raw);
849 if (strcmp(remote_appid, app_id) != 0) { /* self send */
851 /* if message-port fail to get socket pair, communicate using GDBus */
852 if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
853 _LOGE("error create socket pair");
856 _LOGI("sock pair : %d, %d",
857 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
858 fd_list = g_unix_fd_list_new();
859 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
861 _LOGE("g_unix_fd_list_append [%s]", err->message);
862 ret = MESSAGE_PORT_ERROR_IO_ERROR;
867 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
868 close(sock_pair[SOCK_PAIR_RECEIVER]);
869 sock_pair[SOCK_PAIR_RECEIVER] = 0;
871 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
872 if (!port_info->gio_read) {
873 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
874 ret = MESSAGE_PORT_ERROR_IO_ERROR;
878 port_info->g_src_id = g_io_add_watch(
881 __socket_disconnect_handler,
882 (gpointer)port_info);
883 if (port_info->g_src_id == 0) {
884 _LOGE("fail to add watch on socket");
885 ret = MESSAGE_PORT_ERROR_IO_ERROR;
892 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
894 _LOGE("Can't allocate new method call");
895 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
899 g_dbus_message_set_unix_fd_list(msg, fd_list);
900 g_dbus_message_set_body(msg, body);
901 g_dbus_connection_send_message(gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
903 _LOGE("No reply. error = %s", err->message);
905 ret = MESSAGE_PORT_ERROR_IO_ERROR;
914 bundle_free_encoded_rawdata(&raw);
916 g_object_unref(fd_list);
918 if (ret != MESSAGE_PORT_ERROR_NONE) {
919 __free_port_info((gpointer)port_info);
920 if (sock_pair[SOCK_PAIR_SENDER])
921 close(sock_pair[SOCK_PAIR_SENDER]);
922 if (sock_pair[SOCK_PAIR_RECEIVER])
923 close(sock_pair[SOCK_PAIR_RECEIVER]);
929 int send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
931 message_port_local_port_info_s *local_info;
932 int ret = get_local_port_info(id, &local_info);
933 if (ret != MESSAGE_PORT_ERROR_NONE)
936 _LOGD("bidirectional_message %s", local_info->port_name);
937 return send_message(remote_app_id, remote_port,
938 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
941 static void __name_registered(GDBusConnection *connection,
943 const gchar *name_owner,
947 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
949 LOGE("NULL registered_callback_info");
953 _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
954 if (info->registered_cb)
955 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
958 static void __name_unregistered(GDBusConnection *connection,
963 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
965 LOGE("NULL registered_callback_info");
969 _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
970 if (info->unregistered_cb)
971 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
974 int watch_remote_port(int *watcher_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, message_port_registration_event_cb registered_cb, message_port_registration_event_cb unregistered_cb, void *user_data)
976 int ret_val = MESSAGE_PORT_ERROR_NONE;
977 message_port_remote_app_info_s *remote_app_info = NULL;
978 port_list_info_s *port_info = NULL;
982 return MESSAGE_PORT_ERROR_IO_ERROR;
984 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
986 ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
987 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
988 _LOGE("Failed to get remote_port_info %d", ret_val);
992 registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
993 retvm_if(!registered_cb_info, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
995 registered_cb_info->registered_cb = registered_cb;
996 registered_cb_info->unregistered_cb = unregistered_cb;
997 registered_cb_info->user_data = user_data;
998 registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
999 if (registered_cb_info->remote_app_id == NULL) {
1000 free(registered_cb_info);
1001 _LOGE("Failed to alloc memory");
1002 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1004 registered_cb_info->remote_port = strdup(port_info->port_name);
1005 if (registered_cb_info->remote_port == NULL) {
1006 free(registered_cb_info->remote_app_id);
1007 free(registered_cb_info);
1008 _LOGE("Failed to alloc memory");
1009 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1012 registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
1014 port_info->encoded_bus_name,
1015 G_BUS_NAME_WATCHER_FLAGS_NONE,
1017 __name_unregistered,
1020 if (registered_cb_info->watcher_id == 0) {
1021 free(registered_cb_info->remote_app_id);
1022 free(registered_cb_info->remote_port);
1023 free(registered_cb_info);
1024 _LOGE("Failed to watch name");
1025 return MESSAGE_PORT_ERROR_IO_ERROR;
1028 g_hash_table_insert(__registered_callback_info_hash,
1029 GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
1031 *watcher_id = registered_cb_info->watcher_id;
1032 return MESSAGE_PORT_ERROR_NONE;
1035 int remove_registration_event_cb(int watcher_id)
1037 registered_callback_info_s *registered_cb_info = NULL;
1038 gboolean remove_result = FALSE;
1041 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1043 registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1044 if (registered_cb_info == NULL)
1045 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1047 remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1049 return MESSAGE_PORT_ERROR_IO_ERROR;
1051 g_bus_unwatch_name(watcher_id);
1053 return MESSAGE_PORT_ERROR_NONE;