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>
31 #include <gio/gunixfdlist.h>
32 #include <glib-unix.h>
34 #include "message_port_log.h"
35 #include "message_port.h"
36 #include "message_port_remote.h"
37 #include "message_port_common.h"
39 #define MAX_RETRY_CNT 10
40 #define SOCK_PAIR_SENDER 0
41 #define SOCK_PAIR_RECEIVER 1
43 static bool _initialized = false;
44 static GHashTable *__remote_app_info;
45 static GHashTable *__registered_callback_info_hash;
46 static const int MAX_MESSAGE_SIZE = 16 * 1024;
48 enum __certificate_info_type {
51 CERTIFICATE_NOT_MATCH,
54 typedef struct message_port_remote_port_info {
58 } message_port_remote_app_info_s;
60 typedef struct port_list_info {
61 message_port_remote_app_info_s *remote_app_info;
63 char *encoded_bus_name;
69 GList *delayed_message_list;
70 unsigned int delayed_message_size;
74 typedef struct port_key_info {
80 typedef struct delay_port_info {
81 port_key_info_s *key_info;
82 port_list_info_s *port_info;
85 typedef struct registered_callback_info {
91 message_port_registration_event_cb registered_cb;
92 message_port_registration_event_cb unregistered_cb;
93 } registered_callback_info_s;
95 enum transmission_sequence {
106 typedef struct delay_message {
108 unsigned int sent_bytes;
111 char *local_port_name;
116 } delay_message_info_s;
118 /* LCOV_EXCL_START */
119 static void __free_delay_message_info(delay_message_info_s *message)
121 if (message != NULL) {
122 FREE_AND_NULL(message->local_port_name);
123 FREE_AND_NULL(message->data);
124 FREE_AND_NULL(message);
129 /* LCOV_EXCL_START */
130 static void __free_list_delay_message_info(gpointer data)
132 delay_message_info_s *message = (delay_message_info_s *)data;
135 __free_delay_message_info(message);
139 /* LCOV_EXCL_START */
140 static void __clear_disconnect_socket(port_list_info_s *port_info)
142 GError *error = NULL;
144 if (port_info == NULL)
147 if (port_info->gio_read != NULL) {
148 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
150 _LOGE("g_io_channel_shutdown error : %s", error->message);
153 g_io_channel_unref(port_info->gio_read);
154 port_info->gio_read = NULL;
157 if (port_info->g_src_id != 0) {
158 g_source_remove(port_info->g_src_id);
159 port_info->g_src_id = 0;
162 if (port_info->delay_src_id != 0) {
163 g_source_remove(port_info->delay_src_id);
164 port_info->delay_src_id = 0;
167 if (port_info->delayed_message_list != NULL) {
168 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
170 port_info->delayed_message_list = NULL;
173 port_info->delayed_message_size = 0;
174 port_info->send_sock_fd = 0;
178 /* LCOV_EXCL_START */
179 static void __free_port_info(gpointer data)
181 port_list_info_s *port_info = (port_list_info_s *)data;
182 message_port_remote_app_info_s *remote_app_info;
184 if (port_info == NULL)
187 remote_app_info = port_info->remote_app_info;
189 _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
190 remote_app_info->remote_app_id,
191 port_info->port_name);
193 remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
196 __clear_disconnect_socket(port_info);
198 if (port_info->encoded_bus_name)
199 free(port_info->encoded_bus_name);
200 if (port_info->port_name)
201 free(port_info->port_name);
205 if (g_list_length(remote_app_info->port_list) == 0) {
206 g_hash_table_remove(__remote_app_info,
207 remote_app_info->remote_app_id);
212 /* LCOV_EXCL_START */
213 static void __hash_destory_remote_value(gpointer data)
215 message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
217 FREE_AND_NULL(mri->remote_app_id);
219 g_list_free_full(mri->port_list, __free_port_info);
226 static void __registered_callback_info_free(gpointer data)
228 registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
229 if (callback_info == NULL)
232 if (callback_info->remote_app_id)
233 free(callback_info->remote_app_id);
235 if (callback_info->remote_port)
236 free(callback_info->remote_port);
241 static bool __initialize(void)
243 if (!initialized_common) {
244 if (!initialize_common())
248 if (__remote_app_info == NULL) {
249 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
250 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
253 if (__registered_callback_info_hash == NULL) {
254 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __registered_callback_info_free);
255 retvm_if(!__registered_callback_info_hash, false, "fail to create __registered_callback_info_hash");
263 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
265 port_list_info_s *key1 = (port_list_info_s *)a;
266 port_list_info_s *key2 = (port_list_info_s *)b;
268 if (key1->is_trusted == key2->is_trusted)
269 return strcmp(key1->port_name, key2->port_name);
274 static int __key_compare_cb(gconstpointer a, gconstpointer b)
276 port_list_info_s *key1 = (port_list_info_s *)a;
277 port_key_info_s *key2 = (port_key_info_s *)b;
279 if (key1->is_trusted == key2->is_trusted)
280 return strcmp(key1->port_name, key2->port_name);
285 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
287 int ret_val = MESSAGE_PORT_ERROR_NONE;
288 port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
291 /* LCOV_EXCL_START */
292 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
296 port_info->port_name = strdup(remote_port);
297 if (!port_info->port_name) {
298 /* LCOV_EXCL_START */
299 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
303 port_info->is_trusted = is_trusted;
304 port_info->encoded_bus_name = get_encoded_name(remote_app_id, remote_port, is_trusted);
305 if (port_info->encoded_bus_name == NULL) {
306 /* LCOV_EXCL_START */
307 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
311 port_info->send_sock_fd = 0;
313 /* LCOV_EXCL_START */
314 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
316 FREE_AND_NULL(port_info->port_name);
317 FREE_AND_NULL(port_info->encoded_bus_name);
326 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
328 message_port_remote_app_info_s *remote_app_info = NULL;
329 int ret_val = MESSAGE_PORT_ERROR_NONE;
331 remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
332 if (!remote_app_info) {
333 /* LCOV_EXCL_START */
334 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
339 remote_app_info->remote_app_id = strdup(remote_app_id);
340 if (remote_app_info->remote_app_id == NULL) {
341 /* LCOV_EXCL_START */
342 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
348 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
349 if (remote_app_info) {
350 FREE_AND_NULL(remote_app_info->remote_app_id);
351 FREE_AND_NULL(remote_app_info);
355 return remote_app_info;
359 static void __free_port_info_by_key(port_key_info_s *key_info)
361 port_list_info_s *found_port_info;
362 message_port_remote_app_info_s *found_remote_port_info;
365 found_remote_port_info =
366 (message_port_remote_app_info_s *)g_hash_table_lookup(
367 __remote_app_info, key_info->remote_app_id);
368 if (found_remote_port_info == NULL)
371 cb_list = g_list_find_custom(found_remote_port_info->port_list, key_info,
372 (GCompareFunc)__key_compare_cb);
376 found_port_info = (port_list_info_s *)cb_list->data;
377 __free_port_info(found_port_info);
382 _LOGE("Not found port_info");
385 static void __free_key_info(port_key_info_s *key_info)
387 FREE_AND_NULL(key_info->port_name);
388 FREE_AND_NULL(key_info->remote_app_id);
389 FREE_AND_NULL(key_info);
392 static gboolean __socket_disconnect_handler(GIOChannel *gio,
396 _LOGI("__socket_disconnect_handler %d", cond);
397 message_port_lock_mutex();
398 __free_port_info_by_key((port_key_info_s *)data);
399 message_port_unlock_mutex();
404 static void __socket_destroy_handler(gpointer data)
406 _LOGI("__socket_destroy_handler");
408 port_key_info_s *key_info = (port_key_info_s *)data;
409 __free_key_info(key_info);
412 /* LCOV_EXCL_START */
413 static void __delay_socket_destroy_handler(gpointer data)
415 _LOGI("__delay_socket_destroy_handler");
416 delay_port_info *delay_info = (delay_port_info *)data;
418 FREE_AND_NULL(delay_info->key_info->port_name);
419 FREE_AND_NULL(delay_info->key_info->remote_app_id);
420 FREE_AND_NULL(delay_info->key_info);
425 static int __create_port_key_info(
426 port_list_info_s *port_info,
427 port_key_info_s **key_info)
429 int ret_val = MESSAGE_PORT_ERROR_NONE;
430 port_key_info_s *_key_info = (port_key_info_s *)
431 calloc(1, sizeof(port_key_info_s));
432 if (_key_info == NULL) {
433 /* LCOV_EXCL_START */
434 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
435 _LOGE("out of memory");
440 _key_info->port_name = strdup(port_info->port_name);
441 if (_key_info->port_name == NULL) {
442 /* LCOV_EXCL_START */
443 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
444 _LOGE("out of memory");
449 _key_info->is_trusted = port_info->is_trusted;
451 _key_info->remote_app_id = strdup(port_info->remote_app_info->remote_app_id);
452 if (_key_info->remote_app_id == NULL) {
453 /* LCOV_EXCL_START */
454 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
455 _LOGE("out of memory");
460 if (ret_val == MESSAGE_PORT_ERROR_NONE) {
461 *key_info = _key_info;
464 FREE_AND_NULL(_key_info->port_name);
465 FREE_AND_NULL(_key_info->remote_app_id);
474 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
475 message_port_remote_app_info_s **mri, port_list_info_s **pli)
477 message_port_remote_app_info_s *remote_app_info = NULL;
478 port_list_info_s port_info;
479 GList *cb_list = NULL;
480 int ret_val = MESSAGE_PORT_ERROR_NONE;
482 remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
483 if (remote_app_info == NULL) {
484 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
486 if (remote_app_info == NULL) {
487 /* LCOV_EXCL_START */
488 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
492 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
494 *mri = remote_app_info;
496 port_info.port_name = strdup(remote_port);
497 if (port_info.port_name == NULL) {
498 /* LCOV_EXCL_START */
499 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
503 port_info.is_trusted = is_trusted;
504 cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
505 (GCompareFunc)__remote_port_compare_cb);
506 if (port_info.port_name)
507 free(port_info.port_name);
508 if (cb_list == NULL) {
509 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
511 /* LCOV_EXCL_START */
512 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
516 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
517 tmp->remote_app_info = remote_app_info;
520 *pli = (port_list_info_s *)cb_list->data;
527 int check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
529 _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
531 GVariant *result = NULL;
533 int ret_val = MESSAGE_PORT_ERROR_NONE;
534 char *bus_name = NULL;
535 message_port_remote_app_info_s *remote_app_info = NULL;
536 port_list_info_s *port_info = NULL;
537 int local_reg_id = 0;
538 message_port_local_port_info_s *mi = NULL;
539 gboolean name_exist = false;
543 return MESSAGE_PORT_ERROR_IO_ERROR;
546 _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
548 ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
549 if (ret_val != MESSAGE_PORT_ERROR_NONE)
553 if (strcmp(remote_app_id, app_id) == 0) {
555 _LOGD("__is_local_port_registed ");
556 if (!is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
561 _LOGD("__is_local_port_registed : %d ", *exist);
562 return MESSAGE_PORT_ERROR_NONE;
565 port_info->exist = false;
566 bus_name = port_info->encoded_bus_name;
568 result = g_dbus_connection_call_sync(
574 g_variant_new("(s)", bus_name),
575 G_VARIANT_TYPE("(b)"),
576 G_DBUS_CALL_FLAGS_NONE,
581 if (err || (result == NULL)) {
583 _LOGE("No reply. error = %s", err->message);
586 ret_val = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
588 g_variant_get(result, "(b)", &name_exist);
591 _LOGI("Name not exist %s", bus_name);
593 ret_val = MESSAGE_PORT_ERROR_NONE;
597 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
598 if (!is_preloaded(app_id, remote_app_id)) {
599 if (check_certificate(app_id, remote_app_id) != MESSAGE_PORT_ERROR_NONE) {
600 ret_val = MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
604 remote_app_info->certificate_info = CERTIFICATE_MATCH;
607 port_info->exist = true;
609 ret_val = MESSAGE_PORT_ERROR_NONE;
614 g_variant_unref(result);
616 if (ret_val != MESSAGE_PORT_ERROR_NONE || !name_exist)
617 __free_port_info((gpointer)port_info);
622 /* LCOV_EXCL_START */
623 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
626 int sequence = message->sequence - 1;
627 int ret = MESSAGE_PORT_ERROR_NONE;
628 bool is_startline = true;
631 _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
632 sockfd, message->sequence, message->sent_bytes);
634 switch (message->sequence) {
637 is_startline = false;
639 case SEQUENCE_PORT_LEN:
641 offset = message->sent_bytes;
643 ret = write_socket(sockfd, ((char *)&message->local_port_len) + offset,
644 sizeof(message->local_port_len) - offset, &nb, &sequence);
645 if (ret != MESSAGE_PORT_ERROR_NONE) {
646 _LOGE("write local_port_len fail");
650 is_startline = false;
652 case SEQUENCE_PORT_NAME:
654 offset = message->sent_bytes;
656 if (message->local_port_len > 0)
657 ret = write_socket(sockfd, message->local_port_name + offset,
658 message->local_port_len - offset , &nb, &sequence);
662 if (ret != MESSAGE_PORT_ERROR_NONE) {
663 _LOGE("write local_port fail");
667 is_startline = false;
669 case SEQUENCE_BIDIRECTION:
671 offset = message->sent_bytes;
673 ret = write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
674 sizeof(message->is_bidirection) - offset, &nb, &sequence);
675 if (ret != MESSAGE_PORT_ERROR_NONE) {
676 _LOGE("write is_bidirection fail");
680 is_startline = false;
682 case SEQUENCE_TRUSTED:
684 offset = message->sent_bytes;
686 ret = write_socket(sockfd, ((char *)&message->local_trusted) + offset,
687 sizeof(message->local_trusted) - offset, &nb, &sequence);
688 if (ret != MESSAGE_PORT_ERROR_NONE) {
689 _LOGE("write local_trusted fail");
693 is_startline = false;
695 case SEQUENCE_DTAT_LEN:
697 offset = message->sent_bytes;
699 ret = write_socket(sockfd, ((char *)&message->data_len) + offset,
700 sizeof(message->data_len) - offset, &nb, &sequence);
701 if (ret != MESSAGE_PORT_ERROR_NONE) {
702 _LOGE("write data_len fail");
706 is_startline = false;
710 offset = message->sent_bytes;
712 ret = write_socket(sockfd, (char *)message->data + offset,
713 message->data_len - offset, &nb, &sequence);
715 if (ret != MESSAGE_PORT_ERROR_NONE) {
716 _LOGE("write data fail");
720 is_startline = false;
723 ret = MESSAGE_PORT_ERROR_NONE;
728 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
730 message->sent_bytes += nb;
732 message->sent_bytes = nb;
734 message->sequence = sequence;
735 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
736 sockfd, message->sequence, message->sent_bytes);
744 static bool __validate_delay_port_info(delay_port_info *delay_info)
746 message_port_remote_app_info_s *found_remote_port_info;
749 found_remote_port_info =
750 (message_port_remote_app_info_s *)g_hash_table_lookup(
751 __remote_app_info, delay_info->key_info->remote_app_id);
752 if (found_remote_port_info == NULL)
755 cb_list = g_list_find(found_remote_port_info->port_list, delay_info->port_info);
762 /* LCOV_EXCL_START */
763 static int __pop_delayed_message(port_list_info_s *port_info)
765 delay_message_info_s *message;
768 if (port_info->delayed_message_list == NULL)
769 return MESSAGE_PORT_ERROR_NONE;
771 message = g_list_nth_data(port_info->delayed_message_list, 0);
772 ret = __send_delayed_message(port_info->send_sock_fd, message);
774 if (ret != MESSAGE_PORT_ERROR_NONE)
777 port_info->delayed_message_size -= message->size;
778 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
779 _LOGI("pop : delayed_message_size (%d), count(%d)",
780 port_info->delayed_message_size,
781 g_list_length(port_info->delayed_message_list));
783 __free_delay_message_info(message);
785 return MESSAGE_PORT_ERROR_NONE;
789 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
791 delay_port_info *delay_info = (delay_port_info *)data;
792 port_list_info_s *port_info = delay_info->port_info;
796 if (port_info == NULL)
797 return G_SOURCE_REMOVE;
799 message_port_lock_mutex();
801 if (__validate_delay_port_info(delay_info) == false) {
802 message_port_unlock_mutex();
803 return G_SOURCE_REMOVE;
806 if (port_info->delayed_message_list == NULL) {
807 port_info->delayed_message_size = 0;
808 port_info->delay_src_id = 0;
809 message_port_unlock_mutex();
810 return G_SOURCE_REMOVE;
812 ret = __pop_delayed_message(port_info);
813 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
814 message_port_unlock_mutex();
815 return G_SOURCE_CONTINUE;
816 } else if (ret == MESSAGE_PORT_ERROR_IO_ERROR) {
817 port_info->delay_src_id = 0;
818 message_port_unlock_mutex();
819 return G_SOURCE_REMOVE;
823 message_port_unlock_mutex();
825 return G_SOURCE_CONTINUE;
829 /* LCOV_EXCL_START */
830 static int __push_delayed_message(port_list_info_s *port_info,
834 unsigned int sent_bytes,
835 const char *local_port,
839 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
841 unsigned int tmp_size;
842 unsigned int message_size;
843 int ret = MESSAGE_PORT_ERROR_NONE;
844 delay_port_info *delay_info;
846 if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
847 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
848 port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
849 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
852 delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
853 retvm_if(!message, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
855 message_size = (unsigned int)sizeof(delay_message_info_s);
857 message->sequence = sequence;
858 tmp_size = (unsigned int)strlen(local_port) + 1;
859 message_size += tmp_size;
860 message->local_port_len = tmp_size;
861 message->local_port_name = strdup(local_port);
862 if (message->local_port_name == NULL) {
863 _LOGE("local_port_name strdup fail");
864 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
867 message->is_bidirection = is_bidirection;
868 message->local_trusted = local_trusted;
869 message_size += data_len;
870 message->data_len = data_len;
871 message->data = (bundle_raw *)strdup((const char *)kb_data);
872 if (message->data == NULL) {
873 _LOGE("data strdup fail");
874 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
879 message->sent_bytes = sent_bytes;
880 message->size = message_size;
881 port_info->delayed_message_size += message_size;
883 port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
885 if (port_info->delay_src_id == 0) {
886 delay_info = (delay_port_info *)calloc(1, sizeof(delay_port_info));
887 if (delay_info == NULL) {
888 _LOGE("out of memory");
889 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
893 ret = __create_port_key_info(port_info, &delay_info->key_info);
894 if (ret != MESSAGE_PORT_ERROR_NONE) {
899 delay_info->port_info = port_info;
901 port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
902 port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
903 delay_info, __delay_socket_destroy_handler);
906 _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
907 port_info->port_name, port_info->send_sock_fd, message_size,
908 port_info->delayed_message_size,
909 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
912 if (ret != MESSAGE_PORT_ERROR_NONE)
913 __free_delay_message_info(message);
918 static bool __can_write(int fd)
920 struct pollfd fds[1];
922 fds[0].events = POLLOUT;
924 int ret = poll(fds, 1, 100);
925 if (ret == 0 || ret < 0) {
926 _LOGI("poll() is failed. fd(%d), ret(%d) error(%s)",
927 fd, ret, ret == 0 ? "timed out" : "");
935 static int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
936 bool local_trusted, bool is_bidirection)
941 bundle_raw *kb_data = NULL;
942 int sequence = SEQUENCE_START;
944 bundle_encode(kb, &kb_data, &data_len);
945 if (kb_data == NULL) {
946 _LOGE("bundle encode fail");
947 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
951 if (data_len > MAX_MESSAGE_SIZE) {
952 _LOGE("bigger than max size\n");
953 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
957 if (g_list_length(port_info->delayed_message_list) > 0) {
958 ret = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
959 _LOGE("There are messages in the delayed_message_list (count %d)",
960 g_list_length(port_info->delayed_message_list));
964 ret = write_string_to_socket(port_info->send_sock_fd, local_port,
965 strlen(local_port) + 1, &nb, &sequence);
966 if (ret != MESSAGE_PORT_ERROR_NONE) {
967 _LOGE("write local_port fail");
971 ret = write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
972 sizeof(is_bidirection), &nb, &sequence);
973 if (ret != MESSAGE_PORT_ERROR_NONE) {
974 _LOGE("write is_bidirection fail");
978 ret = write_socket(port_info->send_sock_fd, (char *)&local_trusted,
979 sizeof(local_trusted), &nb, &sequence);
980 if (ret != MESSAGE_PORT_ERROR_NONE) {
981 _LOGE("write local_trusted fail");
985 ret = write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
986 data_len, &nb, &sequence);
987 if (ret != MESSAGE_PORT_ERROR_NONE) {
988 _LOGE("write kb_data fail");
993 /* LCOV_EXCL_START */
994 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
995 ret = __push_delayed_message(port_info, sequence, kb_data, data_len, nb,
996 local_port, local_trusted, is_bidirection);
997 if (ret != MESSAGE_PORT_ERROR_NONE) {
1000 return MESSAGE_PORT_ERROR_IO_ERROR;
1003 if (__can_write(port_info->send_sock_fd)) {
1004 while (g_list_length(port_info->delayed_message_list) != 0) {
1005 ret = __pop_delayed_message(port_info);
1006 if (ret != MESSAGE_PORT_ERROR_NONE) {
1007 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
1008 ret = MESSAGE_PORT_ERROR_NONE;
1009 } else if (ret == MESSAGE_PORT_ERROR_IO_ERROR) {
1010 g_source_remove(port_info->delay_src_id);
1011 port_info->delay_src_id = 0;
1018 /* LCOV_EXCL_STOP */
1025 int send_message(const char *remote_appid, const char *remote_port,
1026 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1029 int ret = MESSAGE_PORT_ERROR_NONE;
1030 GUnixFDList *fd_list = NULL;
1033 bundle_raw *raw = NULL;
1034 char *bus_name = NULL;
1035 char *interface_name = NULL;
1037 message_port_remote_app_info_s *remote_app_info = NULL;
1038 port_list_info_s *port_info = NULL;
1039 GDBusMessage *msg = NULL;
1041 GVariant *body = NULL;
1042 int sock_pair[2] = {0,};
1044 port_key_info_s *__key_info;
1046 if (!_initialized) {
1047 if (!__initialize())
1048 return MESSAGE_PORT_ERROR_IO_ERROR;
1051 ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1052 if (ret != MESSAGE_PORT_ERROR_NONE)
1055 if (port_info->exist == false) {
1057 _LOGD("port exist check !!");
1058 ret = check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1059 if (ret != MESSAGE_PORT_ERROR_NONE) {
1061 } else if (!exist) {
1062 return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
1066 if (port_info->send_sock_fd > 0) {
1067 ret = __message_port_send_async(port_info, message,
1068 (local_port) ? local_port : "", local_trusted, bi_dir);
1071 bus_name = port_info->encoded_bus_name;
1072 interface_name = bus_name;
1074 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1075 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1079 if (MAX_MESSAGE_SIZE < len) {
1080 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1081 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
1085 body = g_variant_new("(ssbbssbus)", app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1086 remote_appid, remote_port, trusted_message, len, raw);
1087 if (strcmp(remote_appid, app_id) != 0) { /* self send */
1089 /* if message-port fail to get socket pair, communicate using GDBus */
1090 if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1091 _LOGE("error create socket pair");
1094 _LOGI("sock pair : %d, %d",
1095 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1096 fd_list = g_unix_fd_list_new();
1097 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1099 _LOGE("g_unix_fd_list_append [%s]", err->message);
1100 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1105 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1106 close(sock_pair[SOCK_PAIR_RECEIVER]);
1107 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1109 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1110 if (!port_info->gio_read) {
1111 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1112 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1116 ret = __create_port_key_info(port_info, &__key_info);
1117 if (ret != MESSAGE_PORT_ERROR_NONE) {
1118 _LOGE("out of memory");
1122 port_info->g_src_id = g_io_add_watch_full(
1123 port_info->gio_read,
1126 __socket_disconnect_handler,
1127 (gpointer)__key_info,
1128 __socket_destroy_handler);
1129 if (port_info->g_src_id == 0) {
1130 _LOGE("fail to add watch on socket");
1131 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1132 __free_key_info(__key_info);
1139 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1141 _LOGE("Can't allocate new method call");
1142 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1146 g_dbus_message_set_unix_fd_list(msg, fd_list);
1147 g_dbus_message_set_body(msg, body);
1148 g_dbus_connection_send_message(gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1150 _LOGE("No reply. error = %s", err->message);
1152 ret = MESSAGE_PORT_ERROR_IO_ERROR;
1159 g_object_unref(msg);
1161 bundle_free_encoded_rawdata(&raw);
1163 g_object_unref(fd_list);
1165 if (ret != MESSAGE_PORT_ERROR_NONE
1166 && ret != MESSAGE_PORT_ERROR_MAX_EXCEEDED) {
1168 __create_port_key_info(port_info, &__key_info);
1170 if (__key_info != NULL) {
1171 __free_port_info_by_key(__key_info);
1172 __free_key_info(__key_info);
1175 if (sock_pair[SOCK_PAIR_SENDER])
1176 close(sock_pair[SOCK_PAIR_SENDER]);
1177 if (sock_pair[SOCK_PAIR_RECEIVER])
1178 close(sock_pair[SOCK_PAIR_RECEIVER]);
1184 int send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message)
1186 message_port_local_port_info_s *local_info;
1187 int ret = get_local_port_info(id, &local_info);
1188 if (ret != MESSAGE_PORT_ERROR_NONE)
1191 _LOGD("bidirectional_message %s", local_info->port_name);
1192 return send_message(remote_app_id, remote_port,
1193 local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1196 static void __name_registered(GDBusConnection *connection,
1198 const gchar *name_owner,
1202 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1204 LOGE("NULL registered_callback_info");
1208 _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1209 if (info->registered_cb)
1210 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1213 static void __name_unregistered(GDBusConnection *connection,
1218 registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1220 LOGE("NULL registered_callback_info");
1224 _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
1225 if (info->unregistered_cb)
1226 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1229 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)
1231 int ret_val = MESSAGE_PORT_ERROR_NONE;
1232 message_port_remote_app_info_s *remote_app_info = NULL;
1233 port_list_info_s *port_info = NULL;
1235 if (!_initialized) {
1236 if (!__initialize())
1237 return MESSAGE_PORT_ERROR_IO_ERROR;
1239 _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
1241 ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
1242 if (ret_val != MESSAGE_PORT_ERROR_NONE) {
1243 _LOGE("Failed to get remote_port_info %d", ret_val);
1247 registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
1248 retvm_if(!registered_cb_info, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1250 registered_cb_info->registered_cb = registered_cb;
1251 registered_cb_info->unregistered_cb = unregistered_cb;
1252 registered_cb_info->user_data = user_data;
1253 registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
1254 if (registered_cb_info->remote_app_id == NULL) {
1255 /* LCOV_EXCL_START */
1256 free(registered_cb_info);
1257 _LOGE("Failed to alloc memory");
1258 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1259 /* LCOV_EXCL_STOP */
1261 registered_cb_info->remote_port = strdup(port_info->port_name);
1262 if (registered_cb_info->remote_port == NULL) {
1263 /* LCOV_EXCL_START */
1264 free(registered_cb_info->remote_app_id);
1265 free(registered_cb_info);
1266 _LOGE("Failed to alloc memory");
1267 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1268 /* LCOV_EXCL_STOP */
1271 registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
1273 port_info->encoded_bus_name,
1274 G_BUS_NAME_WATCHER_FLAGS_NONE,
1276 __name_unregistered,
1279 if (registered_cb_info->watcher_id == 0) {
1280 /* LCOV_EXCL_START */
1281 free(registered_cb_info->remote_app_id);
1282 free(registered_cb_info->remote_port);
1283 free(registered_cb_info);
1284 _LOGE("Failed to watch name");
1285 return MESSAGE_PORT_ERROR_IO_ERROR;
1286 /* LCOV_EXCL_STOP */
1289 g_hash_table_insert(__registered_callback_info_hash,
1290 GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
1292 *watcher_id = registered_cb_info->watcher_id;
1293 return MESSAGE_PORT_ERROR_NONE;
1296 int remove_registration_event_cb(int watcher_id)
1298 registered_callback_info_s *registered_cb_info = NULL;
1299 gboolean remove_result = FALSE;
1302 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1304 registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1305 if (registered_cb_info == NULL)
1306 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1308 _LOGI("unwatch_remote_port [%s : %s : %d] ", registered_cb_info->remote_app_id,
1309 registered_cb_info->remote_port, watcher_id);
1311 remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1313 return MESSAGE_PORT_ERROR_IO_ERROR;
1315 g_bus_unwatch_name(watcher_id);
1317 return MESSAGE_PORT_ERROR_NONE;