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 port_key_info {
79 typedef struct delay_port_info {
80 port_key_info_s *key_info;
81 port_list_info_s *port_info;
84 typedef struct registered_callback_info {
90 message_port_registration_event_cb registered_cb;
91 message_port_registration_event_cb unregistered_cb;
92 } registered_callback_info_s;
94 enum transmission_sequence {
105 typedef struct delay_message {
107 unsigned int sent_bytes;
110 char *local_port_name;
115 } delay_message_info_s;
117 /* LCOV_EXCL_START */
118 static void __free_delay_message_info(delay_message_info_s *message)
120 if (message != NULL) {
121 FREE_AND_NULL(message->local_port_name);
122 FREE_AND_NULL(message->data);
123 FREE_AND_NULL(message);
128 /* LCOV_EXCL_START */
129 static void __free_list_delay_message_info(gpointer data)
131 delay_message_info_s *message = (delay_message_info_s *)data;
134 __free_delay_message_info(message);
138 /* LCOV_EXCL_START */
139 static void __clear_disconnect_socket(port_list_info_s *port_info)
141 GError *error = NULL;
143 if (port_info == NULL)
146 if (port_info->gio_read != NULL) {
147 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
149 _LOGE("g_io_channel_shutdown error : %s", error->message);
152 g_io_channel_unref(port_info->gio_read);
153 port_info->gio_read = NULL;
156 if (port_info->g_src_id != 0) {
157 g_source_remove(port_info->g_src_id);
158 port_info->g_src_id = 0;
161 if (port_info->delay_src_id != 0) {
162 g_source_remove(port_info->delay_src_id);
163 port_info->delay_src_id = 0;
166 if (port_info->delayed_message_list != NULL) {
167 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
169 port_info->delayed_message_list = NULL;
172 port_info->delayed_message_size = 0;
173 port_info->send_sock_fd = 0;
177 /* LCOV_EXCL_START */
178 static void __free_port_info(gpointer data)
180 port_list_info_s *port_info = (port_list_info_s *)data;
181 message_port_remote_app_info_s *remote_app_info;
183 if (port_info == NULL)
186 remote_app_info = port_info->remote_app_info;
188 _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
189 remote_app_info->remote_app_id,
190 port_info->port_name);
192 remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
195 __clear_disconnect_socket(port_info);
197 if (port_info->encoded_bus_name)
198 free(port_info->encoded_bus_name);
199 if (port_info->port_name)
200 free(port_info->port_name);
204 if (g_list_length(remote_app_info->port_list) == 0) {
205 g_hash_table_remove(__remote_app_info,
206 remote_app_info->remote_app_id);
211 /* LCOV_EXCL_START */
212 static void __hash_destory_remote_value(gpointer data)
214 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
216 FREE_AND_NULL(mri->remote_app_id);
218 g_list_free_full(mri->port_list, __free_port_info);
225 static void __registered_callback_info_free(gpointer data)
227 registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
228 if (callback_info == NULL)
231 if (callback_info->remote_app_id)
232 free(callback_info->remote_app_id);
234 if (callback_info->remote_port)
235 free(callback_info->remote_port);
240 static bool __initialize(void)
242 if (!initialized_common) {
243 if (!initialize_common())
247 if (__remote_app_info == NULL) {
248 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
249 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
252 if (__registered_callback_info_hash == NULL) {
253 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __registered_callback_info_free);
254 retvm_if(!__registered_callback_info_hash, false, "fail to create __registered_callback_info_hash");
262 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
264 port_list_info_s *key1 = (port_list_info_s *)a;
265 port_list_info_s *key2 = (port_list_info_s *)b;
267 if (key1->is_trusted == key2->is_trusted)
268 return strcmp(key1->port_name, key2->port_name);
273 static int __key_compare_cb(gconstpointer a, gconstpointer b)
275 port_list_info_s *key1 = (port_list_info_s *)a;
276 port_key_info_s *key2 = (port_key_info_s *)b;
278 if (key1->is_trusted == key2->is_trusted)
279 return strcmp(key1->port_name, key2->port_name);
284 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
286 int ret_val = MESSAGE_PORT_ERROR_NONE;
287 port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
290 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
293 port_info->port_name = strdup(remote_port);
294 if (!port_info->port_name) {
295 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
298 port_info->is_trusted = is_trusted;
299 port_info->encoded_bus_name = get_encoded_name(remote_app_id, remote_port, is_trusted);
300 if (port_info->encoded_bus_name == NULL) {
301 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
304 port_info->send_sock_fd = 0;
306 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
308 FREE_AND_NULL(port_info->port_name);
309 FREE_AND_NULL(port_info->encoded_bus_name);
317 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
319 message_port_remote_app_info_s *remote_app_info = NULL;
320 int ret_val = MESSAGE_PORT_ERROR_NONE;
322 remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
323 if (!remote_app_info) {
324 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
328 remote_app_info->remote_app_id = strdup(remote_app_id);
329 if (remote_app_info->remote_app_id == NULL) {
330 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
335 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
336 if (remote_app_info) {
337 FREE_AND_NULL(remote_app_info->remote_app_id);
338 FREE_AND_NULL(remote_app_info);
342 return remote_app_info;
346 static void __free_port_info_by_key(port_key_info_s *key_info)
348 port_list_info_s *found_port_info;
349 message_port_remote_app_info_s *found_remote_port_info;
352 found_remote_port_info =
353 (message_port_remote_app_info_s *)g_hash_table_lookup(
354 __remote_app_info, key_info->remote_app_id);
355 if (found_remote_port_info == NULL)
358 cb_list = g_list_find_custom(found_remote_port_info->port_list, key_info,
359 (GCompareFunc)__key_compare_cb);
363 found_port_info = (port_list_info_s *)cb_list->data;
364 __free_port_info(found_port_info);
369 _LOGE("Not found port_info");
372 static void __free_key_info(port_key_info_s *key_info)
374 FREE_AND_NULL(key_info->port_name);
375 FREE_AND_NULL(key_info->remote_app_id);
376 FREE_AND_NULL(key_info);
379 static gboolean __socket_disconnect_handler(GIOChannel *gio,
383 _LOGI("__socket_disconnect_handler %d", cond);
384 message_port_lock_mutex();
385 __free_port_info_by_key((port_key_info_s *)data);
386 message_port_unlock_mutex();
391 static void __socket_destroy_handler(gpointer data)
393 _LOGI("__socket_destroy_handler");
395 port_key_info_s *key_info = (port_key_info_s *)data;
396 __free_key_info(key_info);
400 static void __delay_socket_destroy_handler(gpointer data)
402 _LOGI("__delay_socket_destroy_handler");
403 delay_port_info *delay_info = (delay_port_info *)data;
405 FREE_AND_NULL(delay_info->key_info->port_name);
406 FREE_AND_NULL(delay_info->key_info->remote_app_id);
407 FREE_AND_NULL(delay_info->key_info);
411 static int __create_port_key_info(
412 port_list_info_s *port_info,
413 port_key_info_s **key_info)
415 int ret_val = MESSAGE_PORT_ERROR_NONE;
416 port_key_info_s *_key_info = (port_key_info_s *)
417 calloc(1, sizeof(port_key_info_s));
418 if (_key_info == NULL) {
419 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
420 _LOGE("out of memory");
424 _key_info->port_name = strdup(port_info->port_name);
425 if (_key_info->port_name == NULL) {
426 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
427 _LOGE("out of memory");
431 _key_info->is_trusted = port_info->is_trusted;
433 _key_info->remote_app_id = strdup(port_info->remote_app_info->remote_app_id);
434 if (_key_info->remote_app_id == NULL) {
435 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
436 _LOGE("out of memory");
441 if (ret_val == MESSAGE_PORT_ERROR_NONE) {
442 *key_info = _key_info;
445 FREE_AND_NULL(_key_info->port_name);
446 FREE_AND_NULL(_key_info->remote_app_id);
453 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
454 message_port_remote_app_info_s **mri, port_list_info_s **pli)
456 message_port_remote_app_info_s *remote_app_info = NULL;
457 port_list_info_s port_info;
458 GList *cb_list = NULL;
459 int ret_val = MESSAGE_PORT_ERROR_NONE;
461 remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
462 if (remote_app_info == NULL) {
463 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
465 if (remote_app_info == NULL) {
466 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
469 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
471 *mri = remote_app_info;
473 port_info.port_name = strdup(remote_port);
474 if (port_info.port_name == NULL) {
475 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
478 port_info.is_trusted = is_trusted;
479 cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
480 (GCompareFunc)__remote_port_compare_cb);
481 if (port_info.port_name)
482 free(port_info.port_name);
483 if (cb_list == NULL) {
484 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
486 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
489 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
490 tmp->remote_app_info = remote_app_info;
493 *pli = (port_list_info_s *)cb_list->data;
500 int check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
502 _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
504 GVariant *result = NULL;
506 int ret_val = MESSAGE_PORT_ERROR_NONE;
507 char *bus_name = NULL;
508 message_port_remote_app_info_s *remote_app_info = NULL;
509 port_list_info_s *port_info = NULL;
510 int local_reg_id = 0;
511 message_port_local_port_info_s *mi = NULL;
512 gboolean name_exist = false;
516 return MESSAGE_PORT_ERROR_IO_ERROR;
519 _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
521 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
522 if (ret_val != MESSAGE_PORT_ERROR_NONE)
526 if (strcmp(remote_app_id, app_id) == 0) {
528 _LOGD("__is_local_port_registed ");
529 if (!is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
534 _LOGD("__is_local_port_registed : %d ", *exist);
535 return MESSAGE_PORT_ERROR_NONE;
538 port_info->exist = false;
539 bus_name = port_info->encoded_bus_name;
541 result = g_dbus_connection_call_sync(
547 g_variant_new("(s)", bus_name),
548 G_VARIANT_TYPE("(b)"),
549 G_DBUS_CALL_FLAGS_NONE,
554 if (err || (result == NULL)) {
556 _LOGE("No reply. error = %s", err->message);
559 ret_val = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
561 g_variant_get(result, "(b)", &name_exist);
564 _LOGI("Name not exist %s", bus_name);
566 ret_val = MESSAGE_PORT_ERROR_NONE;
570 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
571 if (!is_preloaded(app_id, remote_app_id)) {
572 if (check_certificate(app_id, remote_app_id) != MESSAGE_PORT_ERROR_NONE) {
573 ret_val = MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
577 remote_app_info->certificate_info = CERTIFICATE_MATCH;
580 port_info->exist = true;
582 ret_val = MESSAGE_PORT_ERROR_NONE;
587 g_variant_unref(result);
589 if (ret_val != MESSAGE_PORT_ERROR_NONE || !name_exist)
590 __free_port_info((gpointer)port_info);
595 /* LCOV_EXCL_START */
596 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
599 int sequence = message->sequence - 1;
600 int ret = MESSAGE_PORT_ERROR_NONE;
601 bool is_startline = true;
604 _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
605 sockfd, message->sequence, message->sent_bytes);
607 switch (message->sequence) {
610 is_startline = false;
612 case SEQUENCE_PORT_LEN:
614 offset = message->sent_bytes;
616 ret = write_socket(sockfd, ((char *)&message->local_port_len) + offset,
617 sizeof(message->local_port_len) - offset, &nb, &sequence);
618 if (ret != MESSAGE_PORT_ERROR_NONE) {
619 _LOGE("write local_port_len fail");
623 is_startline = false;
625 case SEQUENCE_PORT_NAME:
627 offset = message->sent_bytes;
629 if (message->local_port_len > 0)
630 ret = write_socket(sockfd, message->local_port_name + offset,
631 message->local_port_len - offset , &nb, &sequence);
635 if (ret != MESSAGE_PORT_ERROR_NONE) {
636 _LOGE("write local_port fail");
640 is_startline = false;
642 case SEQUENCE_BIDIRECTION:
644 offset = message->sent_bytes;
646 ret = write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
647 sizeof(message->is_bidirection) - offset, &nb, &sequence);
648 if (ret != MESSAGE_PORT_ERROR_NONE) {
649 _LOGE("write is_bidirection fail");
653 is_startline = false;
655 case SEQUENCE_TRUSTED:
657 offset = message->sent_bytes;
659 ret = write_socket(sockfd, ((char *)&message->local_trusted) + offset,
660 sizeof(message->local_trusted) - offset, &nb, &sequence);
661 if (ret != MESSAGE_PORT_ERROR_NONE) {
662 _LOGE("write local_trusted fail");
666 is_startline = false;
668 case SEQUENCE_DTAT_LEN:
670 offset = message->sent_bytes;
672 ret = write_socket(sockfd, ((char *)&message->data_len) + offset,
673 sizeof(message->data_len) - offset, &nb, &sequence);
674 if (ret != MESSAGE_PORT_ERROR_NONE) {
675 _LOGE("write data_len fail");
679 is_startline = false;
683 offset = message->sent_bytes;
685 ret = write_socket(sockfd, (char *)message->data + offset,
686 message->data_len - offset, &nb, &sequence);
688 if (ret != MESSAGE_PORT_ERROR_NONE) {
689 _LOGE("write data fail");
693 is_startline = false;
696 ret = MESSAGE_PORT_ERROR_NONE;
701 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
703 message->sent_bytes += nb;
705 message->sent_bytes = nb;
707 message->sequence = sequence;
708 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
709 sockfd, message->sequence, message->sent_bytes);
717 static bool __validate_delay_port_info(delay_port_info *delay_info)
719 message_port_remote_app_info_s *found_remote_port_info;
722 found_remote_port_info =
723 (message_port_remote_app_info_s *)g_hash_table_lookup(
724 __remote_app_info, delay_info->key_info->remote_app_id);
725 if (found_remote_port_info == NULL)
728 cb_list = g_list_find(found_remote_port_info->port_list, delay_info->port_info);
734 /* LCOV_EXCL_START */
735 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
737 delay_port_info *delay_info = (delay_port_info *)data;
738 port_list_info_s *port_info = delay_info->port_info;
739 delay_message_info_s *message;
742 if (port_info == NULL)
743 return G_SOURCE_REMOVE;
745 message_port_lock_mutex();
747 if (__validate_delay_port_info(delay_info) == false) {
748 message_port_unlock_mutex();
749 return G_SOURCE_REMOVE;
752 if (port_info->delayed_message_list == NULL) {
753 port_info->delayed_message_size = 0;
754 port_info->delay_src_id = 0;
755 message_port_unlock_mutex();
756 return G_SOURCE_REMOVE;
758 message = g_list_nth_data(port_info->delayed_message_list, 0);
759 ret = __send_delayed_message(port_info->send_sock_fd, message);
761 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
762 message_port_unlock_mutex();
763 return G_SOURCE_CONTINUE;
764 } else if (ret == MESSAGE_PORT_ERROR_IO_ERROR) {
765 port_info->delay_src_id = 0;
766 message_port_unlock_mutex();
767 return G_SOURCE_REMOVE;
770 port_info->delayed_message_size -= message->size;
772 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
773 __free_delay_message_info(message);
776 message_port_unlock_mutex();
778 return G_SOURCE_CONTINUE;
782 /* LCOV_EXCL_START */
783 static int __insert_delayed_message(port_list_info_s *port_info,
787 unsigned int sent_bytes,
788 const char *local_port,
792 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
794 unsigned int tmp_size;
795 unsigned int message_size;
796 int ret = MESSAGE_PORT_ERROR_NONE;
797 delay_port_info *delay_info;
799 if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
800 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
801 port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
802 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
805 delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
806 retvm_if(!message, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
808 message_size = sizeof(delay_message_info_s);
810 message->sequence = sequence;
811 tmp_size = strlen(local_port) + 1;
812 message_size += tmp_size;
813 message->local_port_len = tmp_size;
814 message->local_port_name = strdup(local_port);
815 if (message->local_port_name == NULL) {
816 _LOGE("local_port_name strdup fail");
817 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
820 message->is_bidirection = is_bidirection;
821 message->local_trusted = local_trusted;
822 message_size += data_len;
823 message->data_len = data_len;
824 message->data = (bundle_raw *)strdup((const char *)kb_data);
825 if (message->data == NULL) {
826 _LOGE("data strdup fail");
827 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
832 message->sent_bytes = sent_bytes;
833 message->size = message_size;
834 port_info->delayed_message_size += message_size;
836 port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
838 if (port_info->delay_src_id == 0) {
839 delay_info = (delay_port_info *)calloc(1, sizeof(delay_port_info));
840 if (delay_info == NULL) {
841 _LOGE("out of memory");
842 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
846 ret = __create_port_key_info(port_info, &delay_info->key_info);
847 if (ret != MESSAGE_PORT_ERROR_NONE) {
852 delay_info->port_info = port_info;
854 port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
855 port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
856 delay_info, __delay_socket_destroy_handler);
859 _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
860 port_info->port_name, port_info->send_sock_fd, message_size,
861 port_info->delayed_message_size,
862 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
865 if (ret != MESSAGE_PORT_ERROR_NONE)
866 __free_delay_message_info(message);
872 static int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
873 bool local_trusted, bool is_bidirection)
878 bundle_raw *kb_data = NULL;
879 int sequence = SEQUENCE_START;
881 bundle_encode(kb, &kb_data, &data_len);
882 if (kb_data == NULL) {
883 _LOGE("bundle encode fail");
884 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
888 if (data_len > MAX_MESSAGE_SIZE) {
889 _LOGE("bigger than max size\n");
890 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
894 if (g_list_length(port_info->delayed_message_list) > 0) {
895 ret = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
896 _LOGE("There are messages in the delayed_message_list (count %d)",
897 g_list_length(port_info->delayed_message_list));
901 ret = write_string_to_socket(port_info->send_sock_fd, local_port,
902 strlen(local_port) + 1, &nb, &sequence);
903 if (ret != MESSAGE_PORT_ERROR_NONE) {
904 _LOGE("write local_port fail");
908 ret = write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
909 sizeof(is_bidirection), &nb, &sequence);
910 if (ret != MESSAGE_PORT_ERROR_NONE) {
911 _LOGE("write is_bidirection fail");
915 ret = write_socket(port_info->send_sock_fd, (char *)&local_trusted,
916 sizeof(local_trusted), &nb, &sequence);
917 if (ret != MESSAGE_PORT_ERROR_NONE) {
918 _LOGE("write local_trusted fail");
922 ret = write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
923 data_len, &nb, &sequence);
924 if (ret != MESSAGE_PORT_ERROR_NONE) {
925 _LOGE("write kb_data fail");
930 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
931 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
932 local_port, local_trusted, is_bidirection);
933 if (ret != MESSAGE_PORT_ERROR_NONE)
934 ret = MESSAGE_PORT_ERROR_IO_ERROR;
943 int send_message(const char *remote_appid, const char *remote_port,
944 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
947 int ret = MESSAGE_PORT_ERROR_NONE;
948 GUnixFDList *fd_list = NULL;
951 bundle_raw *raw = NULL;
952 char *bus_name = NULL;
953 char *interface_name = NULL;
955 message_port_remote_app_info_s *remote_app_info = NULL;
956 port_list_info_s *port_info = NULL;
957 GDBusMessage *msg = NULL;
959 GVariant *body = NULL;
960 int sock_pair[2] = {0,};
962 port_key_info_s *__key_info;
966 return MESSAGE_PORT_ERROR_IO_ERROR;
969 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
970 if (ret != MESSAGE_PORT_ERROR_NONE)
973 if (port_info->exist == false) {
975 _LOGD("port exist check !!");
976 ret = check_remote_port(remote_appid, remote_port, trusted_message, &exist);
977 if (ret != MESSAGE_PORT_ERROR_NONE) {
980 return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
984 if (port_info->send_sock_fd > 0) {
985 ret = __message_port_send_async(port_info, message,
986 (local_port) ? local_port : "", local_trusted, bi_dir);
989 bus_name = port_info->encoded_bus_name;
990 interface_name = bus_name;
992 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
993 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
997 if (MAX_MESSAGE_SIZE < len) {
998 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
999 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
1003 body = g_variant_new("(ssbbssbus)", app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1004 remote_appid, remote_port, trusted_message, len, raw);
1005 if (strcmp(remote_appid, app_id) != 0) { /* self send */
1007 /* if message-port fail to get socket pair, communicate using GDBus */
1008 if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1009 _LOGE("error create socket pair");
1012 _LOGI("sock pair : %d, %d",
1013 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1014 fd_list = g_unix_fd_list_new();
1015 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1017 _LOGE("g_unix_fd_list_append [%s]", err->message);
1018 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1023 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1024 close(sock_pair[SOCK_PAIR_RECEIVER]);
1025 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1027 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1028 if (!port_info->gio_read) {
1029 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1030 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1034 ret = __create_port_key_info(port_info, &__key_info);
1035 if (ret != MESSAGE_PORT_ERROR_NONE) {
1036 _LOGE("out of memory");
1040 port_info->g_src_id = g_io_add_watch_full(
1041 port_info->gio_read,
1044 __socket_disconnect_handler,
1045 (gpointer)__key_info,
1046 __socket_destroy_handler);
1047 if (port_info->g_src_id == 0) {
1048 _LOGE("fail to add watch on socket");
1049 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1050 __free_key_info(__key_info);
1057 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1059 _LOGE("Can't allocate new method call");
1060 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1064 g_dbus_message_set_unix_fd_list(msg, fd_list);
1065 g_dbus_message_set_body(msg, body);
1066 g_dbus_connection_send_message(gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1068 _LOGE("No reply. error = %s", err->message);
1070 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1077 g_object_unref(msg);
1079 bundle_free_encoded_rawdata(&raw);
1081 g_object_unref(fd_list);
1083 if (ret != MESSAGE_PORT_ERROR_NONE) {
1085 __create_port_key_info(port_info, &__key_info);
1087 if (__key_info != NULL) {
1088 __free_port_info_by_key(__key_info);
1089 __free_key_info(__key_info);
1092 if (sock_pair[SOCK_PAIR_SENDER])
1093 close(sock_pair[SOCK_PAIR_SENDER]);
1094 if (sock_pair[SOCK_PAIR_RECEIVER])
1095 close(sock_pair[SOCK_PAIR_RECEIVER]);
1101 int send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
1103 message_port_local_port_info_s *local_info;
1104 int ret = get_local_port_info(id, &local_info);
1105 if (ret != MESSAGE_PORT_ERROR_NONE)
1108 _LOGD("bidirectional_message %s", local_info->port_name);
1109 return send_message(remote_app_id, remote_port,
1110 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1113 static void __name_registered(GDBusConnection *connection,
1115 const gchar *name_owner,
1119 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1121 LOGE("NULL registered_callback_info");
1125 _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1126 if (info->registered_cb)
1127 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1130 static void __name_unregistered(GDBusConnection *connection,
1135 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1137 LOGE("NULL registered_callback_info");
1141 _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
1142 if (info->unregistered_cb)
1143 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1146 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)
1148 int ret_val = MESSAGE_PORT_ERROR_NONE;
1149 message_port_remote_app_info_s *remote_app_info = NULL;
1150 port_list_info_s *port_info = NULL;
1152 if (!_initialized) {
1153 if (!__initialize())
1154 return MESSAGE_PORT_ERROR_IO_ERROR;
1156 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
1158 ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
1159 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
1160 _LOGE("Failed to get remote_port_info %d", ret_val);
1164 registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
1165 retvm_if(!registered_cb_info, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1167 registered_cb_info->registered_cb = registered_cb;
1168 registered_cb_info->unregistered_cb = unregistered_cb;
1169 registered_cb_info->user_data = user_data;
1170 registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
1171 if (registered_cb_info->remote_app_id == NULL) {
1172 free(registered_cb_info);
1173 _LOGE("Failed to alloc memory");
1174 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1176 registered_cb_info->remote_port = strdup(port_info->port_name);
1177 if (registered_cb_info->remote_port == NULL) {
1178 free(registered_cb_info->remote_app_id);
1179 free(registered_cb_info);
1180 _LOGE("Failed to alloc memory");
1181 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1184 registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
1186 port_info->encoded_bus_name,
1187 G_BUS_NAME_WATCHER_FLAGS_NONE,
1189 __name_unregistered,
1192 if (registered_cb_info->watcher_id == 0) {
1193 free(registered_cb_info->remote_app_id);
1194 free(registered_cb_info->remote_port);
1195 free(registered_cb_info);
1196 _LOGE("Failed to watch name");
1197 return MESSAGE_PORT_ERROR_IO_ERROR;
1200 g_hash_table_insert(__registered_callback_info_hash,
1201 GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
1203 *watcher_id = registered_cb_info->watcher_id;
1204 return MESSAGE_PORT_ERROR_NONE;
1207 int remove_registration_event_cb(int watcher_id)
1209 registered_callback_info_s *registered_cb_info = NULL;
1210 gboolean remove_result = FALSE;
1213 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1215 registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1216 if (registered_cb_info == NULL)
1217 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1219 remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1221 return MESSAGE_PORT_ERROR_IO_ERROR;
1223 g_bus_unwatch_name(watcher_id);
1225 return MESSAGE_PORT_ERROR_NONE;