Fix update user data bug
[platform/core/appfw/message-port.git] / src / message_port_local.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #define _GNU_SOURCE
18
19 #include <bundle.h>
20 #include <bundle_internal.h>
21 #include <aul.h>
22
23 #include <sys/socket.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <pthread.h>
27
28 #include <glib.h>
29 #include <gio/gio.h>
30 #include <gio/gunixfdlist.h>
31 #include <glib-unix.h>
32
33 #include "message_port_log.h"
34 #include "message_port.h"
35 #include "message_port_remote.h"
36 #include "message_port_common.h"
37
38 #define MAX_RETRY_CNT 10
39 #define SOCK_PAIR_SENDER 0
40 #define SOCK_PAIR_RECEIVER 1
41
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;
46
47 enum __certificate_info_type {
48         UNKNOWN = 0,
49         CERTIFICATE_MATCH,
50         CERTIFICATE_NOT_MATCH,
51 };
52
53 typedef struct message_port_remote_port_info {
54         char *remote_app_id;
55         int certificate_info;
56         GList *port_list;
57 } message_port_remote_app_info_s;
58
59 typedef struct port_list_info {
60         message_port_remote_app_info_s *remote_app_info;
61         char *port_name;
62         char *encoded_bus_name;
63         bool is_trusted;
64         int send_sock_fd;
65         bool exist;
66         GIOChannel *gio_read;
67         int g_src_id;
68         GList *delayed_message_list;
69         unsigned int delayed_message_size;
70         int delay_src_id;
71 } port_list_info_s;
72
73 typedef struct port_key_info {
74         char *remote_app_id;
75         char *port_name;
76         bool is_trusted;
77 } port_key_info_s;
78
79 typedef struct delay_port_info {
80         port_key_info_s *key_info;
81         port_list_info_s *port_info;
82 } delay_port_info;
83
84 typedef struct registered_callback_info {
85         char *remote_app_id;
86         char *remote_port;
87         bool is_trusted;
88         int watcher_id;
89         void *user_data;
90         message_port_registration_event_cb registered_cb;
91         message_port_registration_event_cb unregistered_cb;
92 } registered_callback_info_s;
93
94 enum transmission_sequence {
95         SEQUENCE_START = 0,
96         SEQUENCE_PORT_LEN,
97         SEQUENCE_PORT_NAME,
98         SEQUENCE_BIDIRECTION,
99         SEQUENCE_TRUSTED,
100         SEQUENCE_DTAT_LEN,
101         SEQUENCE_DATA,
102         SEQUENCE_END
103 };
104
105 typedef struct delay_message {
106         unsigned int size;
107         unsigned int sent_bytes;
108         int sequence;
109         int local_port_len;
110         char *local_port_name;
111         bool is_bidirection;
112         bool local_trusted;
113         int data_len;
114         bundle_raw *data;
115 } delay_message_info_s;
116
117 extern pthread_mutex_t mutex;
118
119 /* LCOV_EXCL_START */
120 static void __free_delay_message_info(delay_message_info_s *message)
121 {
122         if (message != NULL) {
123                 FREE_AND_NULL(message->local_port_name);
124                 FREE_AND_NULL(message->data);
125                 FREE_AND_NULL(message);
126         }
127 }
128 /* LCOV_EXCL_STOP */
129
130 /* LCOV_EXCL_START */
131 static void __free_list_delay_message_info(gpointer data)
132 {
133         delay_message_info_s *message = (delay_message_info_s *)data;
134
135         if (message != NULL)
136                 __free_delay_message_info(message);
137 }
138 /* LCOV_EXCL_STOP */
139
140 /* LCOV_EXCL_START */
141 static void __clear_disconnect_socket(port_list_info_s *port_info)
142 {
143         GError *error = NULL;
144
145         if (port_info == NULL)
146                 return;
147
148         if (port_info->gio_read != NULL) {
149                 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
150                 if (error) {
151                         _LOGE("g_io_channel_shutdown error : %s", error->message);
152                         g_error_free(error);
153                 }
154                 g_io_channel_unref(port_info->gio_read);
155                 port_info->gio_read = NULL;
156         }
157
158         if (port_info->g_src_id != 0) {
159                 g_source_remove(port_info->g_src_id);
160                 port_info->g_src_id = 0;
161         }
162
163         if (port_info->delay_src_id != 0) {
164                 g_source_remove(port_info->delay_src_id);
165                 port_info->delay_src_id = 0;
166         }
167
168         if (port_info->delayed_message_list != NULL) {
169                 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
170                 /* can be reused */
171                 port_info->delayed_message_list = NULL;
172         }
173
174         port_info->delayed_message_size = 0;
175         port_info->send_sock_fd = 0;
176 }
177 /* LCOV_EXCL_STOP */
178
179 /* LCOV_EXCL_START */
180 static void __free_port_info(gpointer data)
181 {
182         port_list_info_s *port_info = (port_list_info_s *)data;
183         message_port_remote_app_info_s *remote_app_info;
184
185         if (port_info == NULL)
186                 return;
187
188         remote_app_info = port_info->remote_app_info;
189
190         _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
191                         remote_app_info->remote_app_id,
192                         port_info->port_name);
193
194         remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
195                         port_info);
196
197         __clear_disconnect_socket(port_info);
198
199         if (port_info->encoded_bus_name)
200                 free(port_info->encoded_bus_name);
201         if (port_info->port_name)
202                 free(port_info->port_name);
203
204         free(port_info);
205
206         if (g_list_length(remote_app_info->port_list) == 0) {
207                 g_hash_table_remove(__remote_app_info,
208                                 remote_app_info->remote_app_id);
209         }
210 }
211 /* LCOV_EXCL_STOP */
212
213 /* LCOV_EXCL_START */
214 static void __hash_destory_remote_value(gpointer data)
215 {
216         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
217         if (mri) {
218                 FREE_AND_NULL(mri->remote_app_id);
219                 if (mri->port_list)
220                         g_list_free_full(mri->port_list, __free_port_info);
221
222                 free(mri);
223         }
224 }
225 /* LCOV_EXCL_STOP */
226
227 static void __registered_callback_info_free(gpointer data)
228 {
229         registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
230         if (callback_info == NULL)
231                 return;
232
233         if (callback_info->remote_app_id)
234                 free(callback_info->remote_app_id);
235
236         if (callback_info->remote_port)
237                 free(callback_info->remote_port);
238
239         free(callback_info);
240 }
241
242 static bool __initialize(void)
243 {
244         if (!initialized_common) {
245                 if (!initialize_common())
246                         return false;
247         }
248
249         if (__remote_app_info == NULL) {
250                 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
251                 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
252         }
253
254         if (__registered_callback_info_hash == NULL) {
255                 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __registered_callback_info_free);
256                 retvm_if(!__registered_callback_info_hash, false, "fail to create __registered_callback_info_hash");
257         }
258
259         _initialized = true;
260
261         return true;
262 }
263
264 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
265 {
266         port_list_info_s *key1 = (port_list_info_s *)a;
267         port_list_info_s *key2 = (port_list_info_s *)b;
268
269         if (key1->is_trusted == key2->is_trusted)
270                 return strcmp(key1->port_name, key2->port_name);
271
272         return 1;
273 }
274
275 static int __key_compare_cb(gconstpointer a, gconstpointer b)
276 {
277         port_list_info_s *key1 = (port_list_info_s *)a;
278         port_key_info_s *key2 = (port_key_info_s *)b;
279
280         if (key1->is_trusted == key2->is_trusted)
281                 return strcmp(key1->port_name, key2->port_name);
282
283         return 1;
284 }
285
286 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
287 {
288         int ret_val = MESSAGE_PORT_ERROR_NONE;
289         port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
290
291         if (!port_info) {
292                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
293                 goto out;
294         }
295         port_info->port_name = strdup(remote_port);
296         if (!port_info->port_name) {
297                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
298                 goto out;
299         }
300         port_info->is_trusted = is_trusted;
301         port_info->encoded_bus_name = get_encoded_name(remote_app_id, remote_port, is_trusted);
302         if (port_info->encoded_bus_name == NULL) {
303                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
304                 goto out;
305         }
306         port_info->send_sock_fd = 0;
307 out:
308         if (ret_val != MESSAGE_PORT_ERROR_NONE) {
309                 if (port_info) {
310                         FREE_AND_NULL(port_info->port_name);
311                         FREE_AND_NULL(port_info->encoded_bus_name);
312                         free(port_info);
313                 }
314                 return NULL;
315         }
316         return port_info;
317 }
318
319 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
320 {
321         message_port_remote_app_info_s *remote_app_info = NULL;
322         int ret_val = MESSAGE_PORT_ERROR_NONE;
323
324         remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
325         if (!remote_app_info) {
326                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
327                 goto out;
328         }
329
330         remote_app_info->remote_app_id = strdup(remote_app_id);
331         if (remote_app_info->remote_app_id == NULL) {
332                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
333                 goto out;
334         }
335
336 out:
337         if (ret_val != MESSAGE_PORT_ERROR_NONE) {
338                 if (remote_app_info) {
339                         FREE_AND_NULL(remote_app_info->remote_app_id);
340                         FREE_AND_NULL(remote_app_info);
341                 }
342                 return NULL;
343         }
344         return remote_app_info;
345 }
346
347
348 static void __free_port_info_by_key(port_key_info_s *key_info)
349 {
350         port_list_info_s *found_port_info;
351         message_port_remote_app_info_s *found_remote_port_info;
352         GList *cb_list;
353
354         found_remote_port_info =
355                 (message_port_remote_app_info_s *)g_hash_table_lookup(
356                                 __remote_app_info, key_info->remote_app_id);
357         if (found_remote_port_info == NULL)
358                 goto release;
359
360         cb_list = g_list_find_custom(found_remote_port_info->port_list, key_info,
361                                         (GCompareFunc)__key_compare_cb);
362         if (cb_list == NULL)
363                 goto release;
364
365         found_port_info = (port_list_info_s *)cb_list->data;
366         __free_port_info(found_port_info);
367
368         return;
369
370 release:
371         _LOGE("Not found port_info");
372 }
373
374 static void __free_key_info(port_key_info_s *key_info)
375 {
376         FREE_AND_NULL(key_info->port_name);
377         FREE_AND_NULL(key_info->remote_app_id);
378         FREE_AND_NULL(key_info);
379 }
380
381 static gboolean __socket_disconnect_handler(GIOChannel *gio,
382                 GIOCondition cond,
383                 gpointer data)
384 {
385         _LOGI("__socket_disconnect_handler %d", cond);
386         pthread_mutex_lock(&mutex);
387         __free_port_info_by_key((port_key_info_s *)data);
388         pthread_mutex_unlock(&mutex);
389
390         return FALSE;
391 }
392
393 static void __socket_destroy_handler(gpointer data)
394 {
395         _LOGI("__socket_destroy_handler");
396
397         port_key_info_s *key_info = (port_key_info_s *)data;
398         __free_key_info(key_info);
399 }
400
401
402 static void __delay_socket_destroy_handler(gpointer data)
403 {
404         _LOGI("__delay_socket_destroy_handler");
405         delay_port_info *delay_info = (delay_port_info *)data;
406
407         FREE_AND_NULL(delay_info->key_info->port_name);
408         FREE_AND_NULL(delay_info->key_info->remote_app_id);
409         FREE_AND_NULL(delay_info->key_info);
410         free(delay_info);
411 }
412
413 static int __create_port_key_info(
414                 port_list_info_s *port_info,
415                 port_key_info_s **key_info)
416 {
417         int ret_val = MESSAGE_PORT_ERROR_NONE;
418         port_key_info_s *_key_info = (port_key_info_s *)
419                 calloc(1, sizeof(port_key_info_s));
420         if (_key_info == NULL) {
421                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
422                 _LOGE("out of memory");
423                 goto out;
424         }
425
426         _key_info->port_name = strdup(port_info->port_name);
427         if (_key_info->port_name == NULL) {
428                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
429                 _LOGE("out of memory");
430                 goto out;
431         }
432
433         _key_info->is_trusted = port_info->is_trusted;
434
435         _key_info->remote_app_id = strdup(port_info->remote_app_info->remote_app_id);
436         if (_key_info->remote_app_id == NULL) {
437                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
438                 _LOGE("out of memory");
439                 goto out;
440         }
441
442 out:
443         if (ret_val == MESSAGE_PORT_ERROR_NONE) {
444                 *key_info = _key_info;
445         } else {
446                 if (_key_info) {
447                         FREE_AND_NULL(_key_info->port_name);
448                         FREE_AND_NULL(_key_info->remote_app_id);
449                         free(_key_info);
450                 }
451         }
452         return ret_val;
453 }
454
455 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
456                 message_port_remote_app_info_s **mri, port_list_info_s **pli)
457 {
458         message_port_remote_app_info_s *remote_app_info = NULL;
459         port_list_info_s port_info;
460         GList *cb_list = NULL;
461         int ret_val = MESSAGE_PORT_ERROR_NONE;
462
463         remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
464         if (remote_app_info == NULL) {
465                 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
466
467                 if (remote_app_info == NULL) {
468                         ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
469                         goto out;
470                 }
471                 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
472         }
473         *mri = remote_app_info;
474
475         port_info.port_name = strdup(remote_port);
476         if (port_info.port_name == NULL) {
477                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
478                 goto out;
479         }
480         port_info.is_trusted = is_trusted;
481         cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
482                                         (GCompareFunc)__remote_port_compare_cb);
483         if (port_info.port_name)
484                 free(port_info.port_name);
485         if (cb_list == NULL) {
486                 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
487                 if (tmp == NULL) {
488                         ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
489                         goto out;
490                 }
491                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
492                 tmp->remote_app_info = remote_app_info;
493                 *pli = tmp;
494         } else {
495                 *pli = (port_list_info_s *)cb_list->data;
496         }
497 out:
498
499         return ret_val;
500 }
501
502 int check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
503 {
504         _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
505
506         GVariant *result = NULL;
507         GError *err = NULL;
508         int ret_val = MESSAGE_PORT_ERROR_NONE;
509         char *bus_name = NULL;
510         message_port_remote_app_info_s *remote_app_info = NULL;
511         port_list_info_s *port_info = NULL;
512         int local_reg_id = 0;
513         message_port_local_port_info_s *mi = NULL;
514         gboolean name_exist = false;
515
516         if (!_initialized) {
517                 if (!__initialize())
518                         return MESSAGE_PORT_ERROR_IO_ERROR;
519         }
520
521         _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
522
523         ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
524         if (ret_val != MESSAGE_PORT_ERROR_NONE)
525                 return ret_val;
526
527         /* self check */
528         if (strcmp(remote_app_id, app_id) == 0) {
529
530                 _LOGD("__is_local_port_registed ");
531                 if (!is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
532                         *exist = false;
533                 else
534                         *exist = true;
535
536                 _LOGD("__is_local_port_registed : %d ", *exist);
537                 return MESSAGE_PORT_ERROR_NONE;
538         }
539
540         port_info->exist = false;
541         bus_name = port_info->encoded_bus_name;
542
543         result = g_dbus_connection_call_sync(
544                         gdbus_conn,
545                         DBUS_SERVICE_DBUS,
546                         DBUS_PATH_DBUS,
547                         DBUS_INTERFACE_DBUS,
548                         "NameHasOwner",
549                         g_variant_new("(s)", bus_name),
550                         G_VARIANT_TYPE("(b)"),
551                         G_DBUS_CALL_FLAGS_NONE,
552                         -1,
553                         NULL,
554                         &err);
555
556         if (err || (result == NULL)) {
557                 if (err) {
558                         _LOGE("No reply. error = %s", err->message);
559                         g_error_free(err);
560                 }
561                 ret_val = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
562         } else {
563                 g_variant_get(result, "(b)", &name_exist);
564
565                 if (!name_exist) {
566                         _LOGI("Name not exist %s", bus_name);
567                         *exist = false;
568                         ret_val = MESSAGE_PORT_ERROR_NONE;
569                 } else {
570
571                         if (is_trusted) {
572                                 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
573                                         if (!is_preloaded(app_id, remote_app_id)) {
574                                                 if (check_certificate(app_id, remote_app_id) != MESSAGE_PORT_ERROR_NONE) {
575                                                         ret_val = MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH;
576                                                         goto out;
577                                                 }
578                                         }
579                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
580                                 }
581                         }
582                         port_info->exist = true;
583                         *exist = true;
584                         ret_val = MESSAGE_PORT_ERROR_NONE;
585                 }
586         }
587 out:
588         if (result)
589                 g_variant_unref(result);
590
591         if (ret_val != MESSAGE_PORT_ERROR_NONE || !name_exist)
592                 __free_port_info((gpointer)port_info);
593
594         return ret_val;
595 }
596
597 /* LCOV_EXCL_START */
598 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
599 {
600         unsigned int nb = 0;
601         int sequence = message->sequence - 1;
602         int ret = MESSAGE_PORT_ERROR_NONE;
603         bool is_startline = true;
604         int offset = 0;
605
606         _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
607                 sockfd, message->sequence, message->sent_bytes);
608
609         switch (message->sequence) {
610         case SEQUENCE_START:
611                 sequence++;
612                 is_startline = false;
613
614         case SEQUENCE_PORT_LEN:
615                 if (is_startline)
616                         offset = message->sent_bytes;
617
618                 ret = write_socket(sockfd, ((char *)&message->local_port_len) + offset,
619                                 sizeof(message->local_port_len) - offset, &nb, &sequence);
620                 if (ret != MESSAGE_PORT_ERROR_NONE) {
621                         _LOGE("write local_port_len fail");
622                         goto out;
623                 }
624                 offset = 0;
625                 is_startline = false;
626
627         case SEQUENCE_PORT_NAME:
628                 if (is_startline)
629                         offset = message->sent_bytes;
630
631                 if (message->local_port_len > 0)
632                         ret = write_socket(sockfd, message->local_port_name + offset,
633                                 message->local_port_len - offset , &nb, &sequence);
634                 else
635                         sequence++;
636
637                 if (ret != MESSAGE_PORT_ERROR_NONE) {
638                         _LOGE("write local_port fail");
639                         goto out;
640                 }
641                 offset = 0;
642                 is_startline = false;
643
644         case SEQUENCE_BIDIRECTION:
645                 if (is_startline)
646                         offset = message->sent_bytes;
647
648                 ret = write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
649                                 sizeof(message->is_bidirection) - offset, &nb, &sequence);
650                 if (ret != MESSAGE_PORT_ERROR_NONE) {
651                         _LOGE("write is_bidirection fail");
652                         goto out;
653                 }
654                 offset = 0;
655                 is_startline = false;
656
657         case SEQUENCE_TRUSTED:
658                 if (is_startline)
659                         offset = message->sent_bytes;
660
661                 ret = write_socket(sockfd, ((char *)&message->local_trusted) + offset,
662                                 sizeof(message->local_trusted) - offset, &nb, &sequence);
663                 if (ret != MESSAGE_PORT_ERROR_NONE) {
664                         _LOGE("write local_trusted fail");
665                         goto out;
666                 }
667                 offset = 0;
668                 is_startline = false;
669
670         case SEQUENCE_DTAT_LEN:
671                 if (is_startline)
672                         offset = message->sent_bytes;
673
674                 ret = write_socket(sockfd, ((char *)&message->data_len) + offset,
675                                 sizeof(message->data_len) - offset, &nb, &sequence);
676                 if (ret != MESSAGE_PORT_ERROR_NONE) {
677                         _LOGE("write data_len fail");
678                         goto out;
679                 }
680                 offset = 0;
681                 is_startline = false;
682
683         case SEQUENCE_DATA:
684                 if (is_startline)
685                         offset = message->sent_bytes;
686
687                 ret = write_socket(sockfd, (char *)message->data + offset,
688                         message->data_len - offset, &nb, &sequence);
689
690                 if (ret != MESSAGE_PORT_ERROR_NONE) {
691                         _LOGE("write data fail");
692                         goto out;
693                 }
694                 offset = 0;
695                 is_startline = false;
696
697         default:
698                 ret = MESSAGE_PORT_ERROR_NONE;
699
700         }
701
702 out:
703         if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
704                 if (is_startline)
705                         message->sent_bytes += nb;
706                 else
707                         message->sent_bytes = nb;
708
709                 message->sequence = sequence;
710                 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
711                         sockfd, message->sequence, message->sent_bytes);
712         }
713
714         return ret;
715
716 }
717 /* LCOV_EXCL_STOP */
718
719 static bool __validate_delay_port_info(delay_port_info *delay_info)
720 {
721         message_port_remote_app_info_s *found_remote_port_info;
722         GList *cb_list;
723
724         found_remote_port_info =
725                 (message_port_remote_app_info_s *)g_hash_table_lookup(
726                                 __remote_app_info, delay_info->key_info->remote_app_id);
727         if (found_remote_port_info == NULL)
728                 return false;
729
730         cb_list = g_list_find(found_remote_port_info->port_list, delay_info->port_info);
731         if (cb_list == NULL)
732                 return false;
733
734         return true;
735 }
736 /* LCOV_EXCL_START */
737 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
738 {
739         delay_port_info *delay_info = (delay_port_info *)data;
740         port_list_info_s *port_info = delay_info->port_info;
741         delay_message_info_s *message;
742         int ret;
743
744         if (port_info == NULL)
745                 return G_SOURCE_REMOVE;
746
747         pthread_mutex_lock(&mutex);
748
749         if (__validate_delay_port_info(delay_info) == false) {
750                 pthread_mutex_unlock(&mutex);
751                 return G_SOURCE_REMOVE;
752         }
753
754         if (port_info->delayed_message_list == NULL) {
755                 port_info->delayed_message_size = 0;
756                 port_info->delay_src_id = 0;
757                 pthread_mutex_unlock(&mutex);
758                 return G_SOURCE_REMOVE;
759         } else {
760                 message = g_list_nth_data(port_info->delayed_message_list, 0);
761                 ret = __send_delayed_message(port_info->send_sock_fd, message);
762
763                 if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
764                         pthread_mutex_unlock(&mutex);
765                         return G_SOURCE_CONTINUE;
766                 } else if (ret == MESSAGE_PORT_ERROR_IO_ERROR) {
767                         port_info->delay_src_id = 0;
768                         pthread_mutex_unlock(&mutex);
769                         return G_SOURCE_REMOVE;
770                 }
771
772                 port_info->delayed_message_size -= message->size;
773
774                 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
775                 __free_delay_message_info(message);
776         }
777
778         pthread_mutex_unlock(&mutex);
779
780         return G_SOURCE_CONTINUE;
781 }
782 /* LCOV_EXCL_STOP */
783
784 /* LCOV_EXCL_START */
785 static int __insert_delayed_message(port_list_info_s *port_info,
786         int sequence,
787         bundle_raw *kb_data,
788         int data_len,
789         unsigned int sent_bytes,
790         const char *local_port,
791         bool local_trusted,
792         bool is_bidirection)
793 {
794 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
795
796         unsigned int tmp_size;
797         unsigned int message_size;
798         int ret = MESSAGE_PORT_ERROR_NONE;
799         delay_port_info *delay_info;
800
801         if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
802                 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
803                         port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
804                 return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
805         }
806
807         delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
808         retvm_if(!message, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
809
810         message_size = sizeof(delay_message_info_s);
811
812         message->sequence = sequence;
813         tmp_size = strlen(local_port) + 1;
814         message_size += tmp_size;
815         message->local_port_len = tmp_size;
816         message->local_port_name = strdup(local_port);
817         if (message->local_port_name == NULL) {
818                 _LOGE("local_port_name strdup fail");
819                 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
820                 goto out;
821         }
822         message->is_bidirection = is_bidirection;
823         message->local_trusted = local_trusted;
824         message_size += data_len;
825         message->data_len = data_len;
826         message->data = (bundle_raw *)strdup((const char *)kb_data);
827         if (message->data == NULL) {
828                 _LOGE("data strdup fail");
829                 ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
830                 goto out;
831         }
832
833
834         message->sent_bytes = sent_bytes;
835         message->size = message_size;
836         port_info->delayed_message_size += message_size;
837
838         port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
839
840         if (port_info->delay_src_id == 0) {
841                 delay_info = (delay_port_info *)calloc(1, sizeof(delay_port_info));
842                 if (delay_info == NULL) {
843                         _LOGE("out of memory");
844                         ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
845                         goto out;
846                 }
847
848                 ret = __create_port_key_info(port_info, &delay_info->key_info);
849                 if (ret != MESSAGE_PORT_ERROR_NONE) {
850                         free(delay_info);
851                         goto out;
852                 }
853
854                 delay_info->port_info = port_info;
855
856                 port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
857                                                 port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
858                                                 delay_info, __delay_socket_destroy_handler);
859         }
860
861         _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
862                 port_info->port_name, port_info->send_sock_fd, message_size,
863                 port_info->delayed_message_size,
864                 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
865
866 out:
867         if (ret != MESSAGE_PORT_ERROR_NONE)
868                 __free_delay_message_info(message);
869
870         return ret;
871 }
872 /* LCOV_EXCL_STOP */
873
874 static int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
875                 bool local_trusted, bool is_bidirection)
876 {
877         int ret = 0;
878         int data_len;
879         unsigned int nb = 0;
880         bundle_raw *kb_data = NULL;
881         int sequence = SEQUENCE_START;
882
883         bundle_encode(kb, &kb_data, &data_len);
884         if (kb_data == NULL) {
885                 _LOGE("bundle encode fail");
886                 ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
887                 goto out;
888         }
889
890         if (data_len > MAX_MESSAGE_SIZE) {
891                 _LOGE("bigger than max size\n");
892                 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
893                 goto out;
894         }
895
896         if (g_list_length(port_info->delayed_message_list) > 0) {
897                 ret = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
898                 _LOGE("There are messages in the delayed_message_list (count %d)",
899                         g_list_length(port_info->delayed_message_list));
900                 goto out;
901         }
902
903         ret = write_string_to_socket(port_info->send_sock_fd, local_port,
904                         strlen(local_port) + 1, &nb, &sequence);
905         if (ret != MESSAGE_PORT_ERROR_NONE) {
906                 _LOGE("write local_port fail");
907                 goto out;
908         }
909
910         ret = write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
911                         sizeof(is_bidirection), &nb, &sequence);
912         if (ret != MESSAGE_PORT_ERROR_NONE) {
913                 _LOGE("write is_bidirection fail");
914                 goto out;
915         }
916
917         ret = write_socket(port_info->send_sock_fd, (char *)&local_trusted,
918                         sizeof(local_trusted), &nb, &sequence);
919         if (ret != MESSAGE_PORT_ERROR_NONE) {
920                 _LOGE("write local_trusted fail");
921                 goto out;
922         }
923
924         ret = write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
925                         data_len, &nb, &sequence);
926         if (ret != MESSAGE_PORT_ERROR_NONE) {
927                 _LOGE("write kb_data fail");
928                 goto out;
929         }
930
931 out:
932         if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
933                 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
934                         local_port, local_trusted, is_bidirection);
935                 if (ret != MESSAGE_PORT_ERROR_NONE)
936                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
937         }
938
939         if (kb_data)
940                 free(kb_data);
941
942         return ret;
943 }
944
945 int send_message(const char *remote_appid, const char *remote_port,
946                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
947 {
948
949         int ret = MESSAGE_PORT_ERROR_NONE;
950         GUnixFDList *fd_list = NULL;
951
952         int len = 0;
953         bundle_raw *raw = NULL;
954         char *bus_name = NULL;
955         char *interface_name = NULL;
956
957         message_port_remote_app_info_s *remote_app_info = NULL;
958         port_list_info_s *port_info = NULL;
959         GDBusMessage *msg = NULL;
960         GError *err = NULL;
961         GVariant *body = NULL;
962         int sock_pair[2] = {0,};
963         char buf[1024];
964         port_key_info_s *__key_info;
965
966         if (!_initialized) {
967                 if (!__initialize())
968                         return MESSAGE_PORT_ERROR_IO_ERROR;
969         }
970
971         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
972         if (ret != MESSAGE_PORT_ERROR_NONE)
973                 return ret;
974
975         if (port_info->exist == false) {
976                 bool exist = false;
977                 _LOGD("port exist check !!");
978                 ret =  check_remote_port(remote_appid, remote_port, trusted_message, &exist);
979                 if (ret != MESSAGE_PORT_ERROR_NONE) {
980                         return ret;
981                 } else if (!exist) {
982                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
983                 }
984         }
985
986         if (port_info->send_sock_fd > 0) {
987                 ret = __message_port_send_async(port_info, message,
988                                 (local_port) ? local_port : "", local_trusted, bi_dir);
989         } else {
990
991                 bus_name = port_info->encoded_bus_name;
992                 interface_name = bus_name;
993
994                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
995                         ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
996                         goto out;
997                 }
998
999                 if (MAX_MESSAGE_SIZE < len) {
1000                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1001                         ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
1002                         goto out;
1003                 }
1004
1005                 body = g_variant_new("(ssbbssbus)", app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1006                                 remote_appid, remote_port, trusted_message, len, raw);
1007                 if (strcmp(remote_appid, app_id) != 0) { /* self send */
1008
1009                         /*  if message-port fail to get socket pair, communicate using GDBus */
1010                         if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1011                                 _LOGE("error create socket pair");
1012                         } else {
1013
1014                                 _LOGI("sock pair : %d, %d",
1015                                                 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1016                                 fd_list = g_unix_fd_list_new();
1017                                 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1018                                 if (err != NULL) {
1019                                         _LOGE("g_unix_fd_list_append [%s]", err->message);
1020                                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1021                                         g_error_free(err);
1022                                         goto out;
1023                                 }
1024
1025                                 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1026                                 close(sock_pair[SOCK_PAIR_RECEIVER]);
1027                                 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1028
1029                                 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1030                                 if (!port_info->gio_read) {
1031                                         _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1032                                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1033                                         goto out;
1034                                 }
1035
1036                                 ret = __create_port_key_info(port_info, &__key_info);
1037                                 if (ret != MESSAGE_PORT_ERROR_NONE) {
1038                                         _LOGE("out of memory");
1039                                         goto out;
1040                                 }
1041
1042                                 port_info->g_src_id = g_io_add_watch_full(
1043                                                 port_info->gio_read,
1044                                                 G_PRIORITY_DEFAULT,
1045                                                 G_IO_IN | G_IO_HUP,
1046                                                 __socket_disconnect_handler,
1047                                                 (gpointer)__key_info,
1048                                                 __socket_destroy_handler);
1049                                 if (port_info->g_src_id == 0) {
1050                                         _LOGE("fail to add watch on socket");
1051                                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1052                                         __free_key_info(__key_info);
1053                                         goto out;
1054                                 }
1055
1056                         }
1057                 }
1058
1059                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1060                 if (!msg) {
1061                         _LOGE("Can't allocate new method call");
1062                         ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1063                         goto out;
1064                 }
1065
1066                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1067                 g_dbus_message_set_body(msg, body);
1068                 g_dbus_connection_send_message(gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1069                 if (err != NULL) {
1070                         _LOGE("No reply. error = %s", err->message);
1071                         g_error_free(err);
1072                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1073                         goto out;
1074                 }
1075         }
1076
1077 out:
1078         if (msg)
1079                 g_object_unref(msg);
1080         if (raw)
1081                 bundle_free_encoded_rawdata(&raw);
1082         if (fd_list)
1083                 g_object_unref(fd_list);
1084
1085         if (ret != MESSAGE_PORT_ERROR_NONE) {
1086                 __key_info = NULL;
1087                 __create_port_key_info(port_info, &__key_info);
1088
1089                 if (__key_info != NULL) {
1090                         __free_port_info_by_key(__key_info);
1091                         __free_key_info(__key_info);
1092                 }
1093
1094                 if (sock_pair[SOCK_PAIR_SENDER])
1095                         close(sock_pair[SOCK_PAIR_SENDER]);
1096                 if (sock_pair[SOCK_PAIR_RECEIVER])
1097                         close(sock_pair[SOCK_PAIR_RECEIVER]);
1098         }
1099
1100         return ret;
1101 }
1102
1103 int send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1104 {
1105         message_port_local_port_info_s *local_info;
1106         int ret = get_local_port_info(id, &local_info);
1107         if (ret != MESSAGE_PORT_ERROR_NONE)
1108                 return ret;
1109
1110         _LOGD("bidirectional_message %s", local_info->port_name);
1111         return send_message(remote_app_id, remote_port,
1112                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1113 }
1114
1115 static void __name_registered(GDBusConnection *connection,
1116                 const gchar *name,
1117                 const gchar *name_owner,
1118                 gpointer user_data)
1119 {
1120
1121         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1122         if (info == NULL) {
1123                 LOGE("NULL registered_callback_info");
1124                 return;
1125         }
1126
1127         _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1128         if (info->registered_cb)
1129                 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1130 }
1131
1132 static void __name_unregistered(GDBusConnection *connection,
1133                 const gchar *name,
1134                 gpointer user_data)
1135 {
1136
1137         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1138         if (info == NULL) {
1139                 LOGE("NULL registered_callback_info");
1140                 return;
1141         }
1142
1143         _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
1144         if (info->unregistered_cb)
1145                 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1146 }
1147
1148 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)
1149 {
1150         int ret_val = MESSAGE_PORT_ERROR_NONE;
1151         message_port_remote_app_info_s *remote_app_info = NULL;
1152         port_list_info_s *port_info = NULL;
1153
1154         if (!_initialized) {
1155                 if (!__initialize())
1156                         return MESSAGE_PORT_ERROR_IO_ERROR;
1157         }
1158         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
1159
1160         ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
1161         if (ret_val != MESSAGE_PORT_ERROR_NONE) {
1162                 _LOGE("Failed to get remote_port_info %d", ret_val);
1163                 return ret_val;
1164         }
1165
1166         registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
1167         retvm_if(!registered_cb_info, MESSAGE_PORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1168
1169         registered_cb_info->registered_cb = registered_cb;
1170         registered_cb_info->unregistered_cb = unregistered_cb;
1171         registered_cb_info->user_data = user_data;
1172         registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
1173         if (registered_cb_info->remote_app_id == NULL) {
1174                 free(registered_cb_info);
1175                 _LOGE("Failed to alloc memory");
1176                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1177         }
1178         registered_cb_info->remote_port = strdup(port_info->port_name);
1179         if (registered_cb_info->remote_port == NULL) {
1180                 free(registered_cb_info->remote_app_id);
1181                 free(registered_cb_info);
1182                 _LOGE("Failed to alloc memory");
1183                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1184         }
1185
1186         registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
1187                         gdbus_conn,
1188                         port_info->encoded_bus_name,
1189                         G_BUS_NAME_WATCHER_FLAGS_NONE,
1190                         __name_registered,
1191                         __name_unregistered,
1192                         registered_cb_info,
1193                         NULL);
1194         if (registered_cb_info->watcher_id == 0) {
1195                 free(registered_cb_info->remote_app_id);
1196                 free(registered_cb_info->remote_port);
1197                 free(registered_cb_info);
1198                 _LOGE("Failed to watch name");
1199                 return MESSAGE_PORT_ERROR_IO_ERROR;
1200         }
1201
1202         g_hash_table_insert(__registered_callback_info_hash,
1203                         GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
1204
1205         *watcher_id = registered_cb_info->watcher_id;
1206         return MESSAGE_PORT_ERROR_NONE;
1207 }
1208
1209 int remove_registration_event_cb(int watcher_id)
1210 {
1211         registered_callback_info_s *registered_cb_info = NULL;
1212         gboolean remove_result = FALSE;
1213
1214         if (watcher_id < 1)
1215                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1216
1217         registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1218         if (registered_cb_info == NULL)
1219                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1220
1221         remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1222         if (!remove_result)
1223                 return MESSAGE_PORT_ERROR_IO_ERROR;
1224
1225         g_bus_unwatch_name(watcher_id);
1226
1227         return MESSAGE_PORT_ERROR_NONE;
1228 }
1229