Improves code coverage
[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 #include <poll.h>
28
29 #include <glib.h>
30 #include <gio/gio.h>
31 #include <gio/gunixfdlist.h>
32 #include <glib-unix.h>
33
34 #include "message_port_log.h"
35 #include "message_port.h"
36 #include "message_port_remote.h"
37 #include "message_port_common.h"
38
39 #define MAX_RETRY_CNT 10
40 #define SOCK_PAIR_SENDER 0
41 #define SOCK_PAIR_RECEIVER 1
42
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;
47
48 enum __certificate_info_type {
49         UNKNOWN = 0,
50         CERTIFICATE_MATCH,
51         CERTIFICATE_NOT_MATCH,
52 };
53
54 typedef struct message_port_remote_port_info {
55         char *remote_app_id;
56         int certificate_info;
57         GList *port_list;
58 } message_port_remote_app_info_s;
59
60 typedef struct port_list_info {
61         message_port_remote_app_info_s *remote_app_info;
62         char *port_name;
63         char *encoded_bus_name;
64         bool is_trusted;
65         int send_sock_fd;
66         bool exist;
67         GIOChannel *gio_read;
68         int g_src_id;
69         GList *delayed_message_list;
70         unsigned int delayed_message_size;
71         int delay_src_id;
72 } port_list_info_s;
73
74 typedef struct port_key_info {
75         char *remote_app_id;
76         char *port_name;
77         bool is_trusted;
78 } port_key_info_s;
79
80 typedef struct delay_port_info {
81         port_key_info_s *key_info;
82         port_list_info_s *port_info;
83 } delay_port_info;
84
85 typedef struct registered_callback_info {
86         char *remote_app_id;
87         char *remote_port;
88         bool is_trusted;
89         int watcher_id;
90         void *user_data;
91         message_port_registration_event_cb registered_cb;
92         message_port_registration_event_cb unregistered_cb;
93 } registered_callback_info_s;
94
95 enum transmission_sequence {
96         SEQUENCE_START = 0,
97         SEQUENCE_PORT_LEN,
98         SEQUENCE_PORT_NAME,
99         SEQUENCE_BIDIRECTION,
100         SEQUENCE_TRUSTED,
101         SEQUENCE_DTAT_LEN,
102         SEQUENCE_DATA,
103         SEQUENCE_END
104 };
105
106 typedef struct delay_message {
107         unsigned int size;
108         unsigned int sent_bytes;
109         int sequence;
110         int local_port_len;
111         char *local_port_name;
112         bool is_bidirection;
113         bool local_trusted;
114         int data_len;
115         bundle_raw *data;
116 } delay_message_info_s;
117
118 /* LCOV_EXCL_START */
119 static void __free_delay_message_info(delay_message_info_s *message)
120 {
121         if (message != NULL) {
122                 FREE_AND_NULL(message->local_port_name);
123                 FREE_AND_NULL(message->data);
124                 FREE_AND_NULL(message);
125         }
126 }
127 /* LCOV_EXCL_STOP */
128
129 /* LCOV_EXCL_START */
130 static void __free_list_delay_message_info(gpointer data)
131 {
132         delay_message_info_s *message = (delay_message_info_s *)data;
133
134         if (message != NULL)
135                 __free_delay_message_info(message);
136 }
137 /* LCOV_EXCL_STOP */
138
139 /* LCOV_EXCL_START */
140 static void __clear_disconnect_socket(port_list_info_s *port_info)
141 {
142         GError *error = NULL;
143
144         if (port_info == NULL)
145                 return;
146
147         if (port_info->gio_read != NULL) {
148                 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
149                 if (error) {
150                         _LOGE("g_io_channel_shutdown error : %s", error->message);
151                         g_error_free(error);
152                 }
153                 g_io_channel_unref(port_info->gio_read);
154                 port_info->gio_read = NULL;
155         }
156
157         if (port_info->g_src_id != 0) {
158                 g_source_remove(port_info->g_src_id);
159                 port_info->g_src_id = 0;
160         }
161
162         if (port_info->delay_src_id != 0) {
163                 g_source_remove(port_info->delay_src_id);
164                 port_info->delay_src_id = 0;
165         }
166
167         if (port_info->delayed_message_list != NULL) {
168                 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
169                 /* can be reused */
170                 port_info->delayed_message_list = NULL;
171         }
172
173         port_info->delayed_message_size = 0;
174         port_info->send_sock_fd = 0;
175 }
176 /* LCOV_EXCL_STOP */
177
178 /* LCOV_EXCL_START */
179 static void __free_port_info(gpointer data)
180 {
181         port_list_info_s *port_info = (port_list_info_s *)data;
182         message_port_remote_app_info_s *remote_app_info;
183
184         if (port_info == NULL)
185                 return;
186
187         remote_app_info = port_info->remote_app_info;
188
189         _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
190                         remote_app_info->remote_app_id,
191                         port_info->port_name);
192
193         remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
194                         port_info);
195
196         __clear_disconnect_socket(port_info);
197
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);
202
203         free(port_info);
204
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);
208         }
209 }
210 /* LCOV_EXCL_STOP */
211
212 /* LCOV_EXCL_START */
213 static void __hash_destory_remote_value(gpointer data)
214 {
215         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
216         if (mri) {
217                 FREE_AND_NULL(mri->remote_app_id);
218                 if (mri->port_list)
219                         g_list_free_full(mri->port_list, __free_port_info);
220
221                 free(mri);
222         }
223 }
224 /* LCOV_EXCL_STOP */
225
226 static void __registered_callback_info_free(gpointer data)
227 {
228         registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
229         if (callback_info == NULL)
230                 return;
231
232         if (callback_info->remote_app_id)
233                 free(callback_info->remote_app_id);
234
235         if (callback_info->remote_port)
236                 free(callback_info->remote_port);
237
238         free(callback_info);
239 }
240
241 static bool __initialize(void)
242 {
243         if (!initialized_common) {
244                 if (!initialize_common())
245                         return false;
246         }
247
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");
251         }
252
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");
256         }
257
258         _initialized = true;
259
260         return true;
261 }
262
263 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
264 {
265         port_list_info_s *key1 = (port_list_info_s *)a;
266         port_list_info_s *key2 = (port_list_info_s *)b;
267
268         if (key1->is_trusted == key2->is_trusted)
269                 return strcmp(key1->port_name, key2->port_name);
270
271         return 1;
272 }
273
274 static int __key_compare_cb(gconstpointer a, gconstpointer b)
275 {
276         port_list_info_s *key1 = (port_list_info_s *)a;
277         port_key_info_s *key2 = (port_key_info_s *)b;
278
279         if (key1->is_trusted == key2->is_trusted)
280                 return strcmp(key1->port_name, key2->port_name);
281
282         return 1;
283 }
284
285 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
286 {
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));
289
290         if (!port_info) {
291 /* LCOV_EXCL_START */
292                 ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
293                 goto out;
294 /* LCOV_EXCL_STOP */
295         }
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;
300                 goto out;
301 /* LCOV_EXCL_STOP */
302         }
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;
308                 goto out;
309 /* LCOV_EXCL_STOP */
310         }
311         port_info->send_sock_fd = 0;
312 out:
313 /* LCOV_EXCL_START */
314         if (ret_val != MESSAGE_PORT_ERROR_NONE) {
315                 if (port_info) {
316                         FREE_AND_NULL(port_info->port_name);
317                         FREE_AND_NULL(port_info->encoded_bus_name);
318                         free(port_info);
319                 }
320                 return NULL;
321         }
322 /* LCOV_EXCL_STOP */
323         return port_info;
324 }
325
326 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
327 {
328         message_port_remote_app_info_s *remote_app_info = NULL;
329         int ret_val = MESSAGE_PORT_ERROR_NONE;
330
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;
335                 goto out;
336 /* LCOV_EXCL_STOP */
337         }
338
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;
343                 goto out;
344 /* LCOV_EXCL_STOP */
345         }
346
347 out:
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);
352                 }
353                 return NULL;
354         }
355         return remote_app_info;
356 }
357
358
359 static void __free_port_info_by_key(port_key_info_s *key_info)
360 {
361         port_list_info_s *found_port_info;
362         message_port_remote_app_info_s *found_remote_port_info;
363         GList *cb_list;
364
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)
369                 goto release;
370
371         cb_list = g_list_find_custom(found_remote_port_info->port_list, key_info,
372                                         (GCompareFunc)__key_compare_cb);
373         if (cb_list == NULL)
374                 goto release;
375
376         found_port_info = (port_list_info_s *)cb_list->data;
377         __free_port_info(found_port_info);
378
379         return;
380
381 release:
382         _LOGE("Not found port_info");
383 }
384
385 static void __free_key_info(port_key_info_s *key_info)
386 {
387         FREE_AND_NULL(key_info->port_name);
388         FREE_AND_NULL(key_info->remote_app_id);
389         FREE_AND_NULL(key_info);
390 }
391
392 static gboolean __socket_disconnect_handler(GIOChannel *gio,
393                 GIOCondition cond,
394                 gpointer data)
395 {
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();
400
401         return FALSE;
402 }
403
404 static void __socket_destroy_handler(gpointer data)
405 {
406         _LOGI("__socket_destroy_handler");
407
408         port_key_info_s *key_info = (port_key_info_s *)data;
409         __free_key_info(key_info);
410 }
411
412 /* LCOV_EXCL_START */
413 static void __delay_socket_destroy_handler(gpointer data)
414 {
415         _LOGI("__delay_socket_destroy_handler");
416         delay_port_info *delay_info = (delay_port_info *)data;
417
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);
421         free(delay_info);
422 }
423 /* LCOV_EXCL_STOP */
424
425 static int __create_port_key_info(
426                 port_list_info_s *port_info,
427                 port_key_info_s **key_info)
428 {
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");
436                 goto out;
437 /* LCOV_EXCL_STOP */
438         }
439
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");
445                 goto out;
446 /* LCOV_EXCL_STOP */
447         }
448
449         _key_info->is_trusted = port_info->is_trusted;
450
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");
456                 goto out;
457         }
458
459 out:
460         if (ret_val == MESSAGE_PORT_ERROR_NONE) {
461                 *key_info = _key_info;
462         } else {
463                 if (_key_info) {
464                         FREE_AND_NULL(_key_info->port_name);
465                         FREE_AND_NULL(_key_info->remote_app_id);
466                         free(_key_info);
467                 }
468         }
469 /* LCOV_EXCL_STOP */
470
471         return ret_val;
472 }
473
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)
476 {
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;
481
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);
485
486                 if (remote_app_info == NULL) {
487 /* LCOV_EXCL_START */
488                         ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
489                         goto out;
490 /* LCOV_EXCL_STOP */
491                 }
492                 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
493         }
494         *mri = remote_app_info;
495
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;
500                 goto out;
501 /* LCOV_EXCL_STOP */
502         }
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);
510                 if (tmp == NULL) {
511 /* LCOV_EXCL_START */
512                         ret_val = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
513                         goto out;
514 /* LCOV_EXCL_STOP */
515                 }
516                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
517                 tmp->remote_app_info = remote_app_info;
518                 *pli = tmp;
519         } else {
520                 *pli = (port_list_info_s *)cb_list->data;
521         }
522 out:
523
524         return ret_val;
525 }
526
527 int check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
528 {
529         _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
530
531         GVariant *result = NULL;
532         GError *err = 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;
540
541         if (!_initialized) {
542                 if (!__initialize())
543                         return MESSAGE_PORT_ERROR_IO_ERROR;
544         }
545
546         _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
547
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)
550                 return ret_val;
551
552         /* self check */
553         if (strcmp(remote_app_id, app_id) == 0) {
554
555                 _LOGD("__is_local_port_registed ");
556                 if (!is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
557                         *exist = false;
558                 else
559                         *exist = true;
560
561                 _LOGD("__is_local_port_registed : %d ", *exist);
562                 return MESSAGE_PORT_ERROR_NONE;
563         }
564
565         port_info->exist = false;
566         bus_name = port_info->encoded_bus_name;
567
568         result = g_dbus_connection_call_sync(
569                         gdbus_conn,
570                         DBUS_SERVICE_DBUS,
571                         DBUS_PATH_DBUS,
572                         DBUS_INTERFACE_DBUS,
573                         "NameHasOwner",
574                         g_variant_new("(s)", bus_name),
575                         G_VARIANT_TYPE("(b)"),
576                         G_DBUS_CALL_FLAGS_NONE,
577                         -1,
578                         NULL,
579                         &err);
580
581         if (err || (result == NULL)) {
582                 if (err) {
583                         _LOGE("No reply. error = %s", err->message);
584                         g_error_free(err);
585                 }
586                 ret_val = MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE;
587         } else {
588                 g_variant_get(result, "(b)", &name_exist);
589
590                 if (!name_exist) {
591                         _LOGI("Name not exist %s", bus_name);
592                         *exist = false;
593                         ret_val = MESSAGE_PORT_ERROR_NONE;
594                 } else {
595
596                         if (is_trusted) {
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;
601                                                         goto out;
602                                                 }
603                                         }
604                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
605                                 }
606                         }
607                         port_info->exist = true;
608                         *exist = true;
609                         ret_val = MESSAGE_PORT_ERROR_NONE;
610                 }
611         }
612 out:
613         if (result)
614                 g_variant_unref(result);
615
616         if (ret_val != MESSAGE_PORT_ERROR_NONE || !name_exist)
617                 __free_port_info((gpointer)port_info);
618
619         return ret_val;
620 }
621
622 /* LCOV_EXCL_START */
623 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
624 {
625         unsigned int nb = 0;
626         int sequence = message->sequence - 1;
627         int ret = MESSAGE_PORT_ERROR_NONE;
628         bool is_startline = true;
629         int offset = 0;
630
631         _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
632                 sockfd, message->sequence, message->sent_bytes);
633
634         switch (message->sequence) {
635         case SEQUENCE_START:
636                 sequence++;
637                 is_startline = false;
638
639         case SEQUENCE_PORT_LEN:
640                 if (is_startline)
641                         offset = message->sent_bytes;
642
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");
647                         goto out;
648                 }
649                 offset = 0;
650                 is_startline = false;
651
652         case SEQUENCE_PORT_NAME:
653                 if (is_startline)
654                         offset = message->sent_bytes;
655
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);
659                 else
660                         sequence++;
661
662                 if (ret != MESSAGE_PORT_ERROR_NONE) {
663                         _LOGE("write local_port fail");
664                         goto out;
665                 }
666                 offset = 0;
667                 is_startline = false;
668
669         case SEQUENCE_BIDIRECTION:
670                 if (is_startline)
671                         offset = message->sent_bytes;
672
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");
677                         goto out;
678                 }
679                 offset = 0;
680                 is_startline = false;
681
682         case SEQUENCE_TRUSTED:
683                 if (is_startline)
684                         offset = message->sent_bytes;
685
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");
690                         goto out;
691                 }
692                 offset = 0;
693                 is_startline = false;
694
695         case SEQUENCE_DTAT_LEN:
696                 if (is_startline)
697                         offset = message->sent_bytes;
698
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");
703                         goto out;
704                 }
705                 offset = 0;
706                 is_startline = false;
707
708         case SEQUENCE_DATA:
709                 if (is_startline)
710                         offset = message->sent_bytes;
711
712                 ret = write_socket(sockfd, (char *)message->data + offset,
713                         message->data_len - offset, &nb, &sequence);
714
715                 if (ret != MESSAGE_PORT_ERROR_NONE) {
716                         _LOGE("write data fail");
717                         goto out;
718                 }
719                 offset = 0;
720                 is_startline = false;
721
722         default:
723                 ret = MESSAGE_PORT_ERROR_NONE;
724
725         }
726
727 out:
728         if (ret == MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE) {
729                 if (is_startline)
730                         message->sent_bytes += nb;
731                 else
732                         message->sent_bytes = nb;
733
734                 message->sequence = sequence;
735                 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
736                         sockfd, message->sequence, message->sent_bytes);
737         }
738
739         return ret;
740
741 }
742 /* LCOV_EXCL_STOP */
743
744 static bool __validate_delay_port_info(delay_port_info *delay_info)
745 {
746         message_port_remote_app_info_s *found_remote_port_info;
747         GList *cb_list;
748
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)
753                 return false;
754
755         cb_list = g_list_find(found_remote_port_info->port_list, delay_info->port_info);
756         if (cb_list == NULL)
757                 return false;
758
759         return true;
760 }
761
762 /* LCOV_EXCL_START */
763 static int __pop_delayed_message(port_list_info_s *port_info)
764 {
765         delay_message_info_s *message;
766         int ret;
767
768         if (port_info->delayed_message_list == NULL)
769                 return MESSAGE_PORT_ERROR_NONE;
770
771         message = g_list_nth_data(port_info->delayed_message_list, 0);
772         ret = __send_delayed_message(port_info->send_sock_fd, message);
773
774         if (ret != MESSAGE_PORT_ERROR_NONE)
775                 return ret;
776
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));
782
783         __free_delay_message_info(message);
784
785         return MESSAGE_PORT_ERROR_NONE;
786
787 }
788
789 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
790 {
791         delay_port_info *delay_info = (delay_port_info *)data;
792         port_list_info_s *port_info = delay_info->port_info;
793
794         int ret;
795
796         if (port_info == NULL)
797                 return G_SOURCE_REMOVE;
798
799         message_port_lock_mutex();
800
801         if (__validate_delay_port_info(delay_info) == false) {
802                 message_port_unlock_mutex();
803                 return G_SOURCE_REMOVE;
804         }
805
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;
811         } else {
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;
820                 }
821         }
822
823         message_port_unlock_mutex();
824
825         return G_SOURCE_CONTINUE;
826 }
827 /* LCOV_EXCL_STOP */
828
829 /* LCOV_EXCL_START */
830 static int __push_delayed_message(port_list_info_s *port_info,
831         int sequence,
832         bundle_raw *kb_data,
833         int data_len,
834         unsigned int sent_bytes,
835         const char *local_port,
836         bool local_trusted,
837         bool is_bidirection)
838 {
839 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
840
841         unsigned int tmp_size;
842         unsigned int message_size;
843         int ret = MESSAGE_PORT_ERROR_NONE;
844         delay_port_info *delay_info;
845
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;
850         }
851
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");
854
855         message_size = (unsigned int)sizeof(delay_message_info_s);
856
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;
865                 goto out;
866         }
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;
875                 goto out;
876         }
877
878
879         message->sent_bytes = sent_bytes;
880         message->size = message_size;
881         port_info->delayed_message_size += message_size;
882
883         port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
884
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;
890                         goto out;
891                 }
892
893                 ret = __create_port_key_info(port_info, &delay_info->key_info);
894                 if (ret != MESSAGE_PORT_ERROR_NONE) {
895                         free(delay_info);
896                         goto out;
897                 }
898
899                 delay_info->port_info = port_info;
900
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);
904         }
905
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);
910
911 out:
912         if (ret != MESSAGE_PORT_ERROR_NONE)
913                 __free_delay_message_info(message);
914
915         return ret;
916 }
917
918 static bool __can_write(int fd)
919 {
920         struct pollfd fds[1];
921         fds[0].fd = fd;
922         fds[0].events = POLLOUT;
923         fds[0].revents = 0;
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" : "");
928                 return false;
929         }
930
931         return true;
932 }
933 /* LCOV_EXCL_STOP */
934
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)
937 {
938         int ret = 0;
939         int data_len;
940         unsigned int nb = 0;
941         bundle_raw *kb_data = NULL;
942         int sequence = SEQUENCE_START;
943
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;
948                 goto out;
949         }
950
951         if (data_len > MAX_MESSAGE_SIZE) {
952                 _LOGE("bigger than max size\n");
953                 ret = MESSAGE_PORT_ERROR_MAX_EXCEEDED;
954                 goto out;
955         }
956
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));
961                 goto out;
962         }
963
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");
968                 goto out;
969         }
970
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");
975                 goto out;
976         }
977
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");
982                 goto out;
983         }
984
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");
989                 goto out;
990         }
991
992 out:
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) {
998                         if (kb_data)
999                                 free(kb_data);
1000                         return MESSAGE_PORT_ERROR_IO_ERROR;
1001                 }
1002
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;
1012                                         }
1013                                         break;
1014                                 }
1015                         }
1016                 }
1017         }
1018 /* LCOV_EXCL_STOP */
1019         if (kb_data)
1020                 free(kb_data);
1021
1022         return ret;
1023 }
1024
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)
1027 {
1028
1029         int ret = MESSAGE_PORT_ERROR_NONE;
1030         GUnixFDList *fd_list = NULL;
1031
1032         int len = 0;
1033         bundle_raw *raw = NULL;
1034         char *bus_name = NULL;
1035         char *interface_name = NULL;
1036
1037         message_port_remote_app_info_s *remote_app_info = NULL;
1038         port_list_info_s *port_info = NULL;
1039         GDBusMessage *msg = NULL;
1040         GError *err = NULL;
1041         GVariant *body = NULL;
1042         int sock_pair[2] = {0,};
1043         char buf[1024];
1044         port_key_info_s *__key_info;
1045
1046         if (!_initialized) {
1047                 if (!__initialize())
1048                         return MESSAGE_PORT_ERROR_IO_ERROR;
1049         }
1050
1051         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1052         if (ret != MESSAGE_PORT_ERROR_NONE)
1053                 return ret;
1054
1055         if (port_info->exist == false) {
1056                 bool 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) {
1060                         return ret;
1061                 } else if (!exist) {
1062                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
1063                 }
1064         }
1065
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);
1069         } else {
1070
1071                 bus_name = port_info->encoded_bus_name;
1072                 interface_name = bus_name;
1073
1074                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1075                         ret = MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1076                         goto out;
1077                 }
1078
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;
1082                         goto out;
1083                 }
1084
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 */
1088
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");
1092                         } else {
1093
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);
1098                                 if (err != NULL) {
1099                                         _LOGE("g_unix_fd_list_append [%s]", err->message);
1100                                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1101                                         g_error_free(err);
1102                                         goto out;
1103                                 }
1104
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;
1108
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;
1113                                         goto out;
1114                                 }
1115
1116                                 ret = __create_port_key_info(port_info, &__key_info);
1117                                 if (ret != MESSAGE_PORT_ERROR_NONE) {
1118                                         _LOGE("out of memory");
1119                                         goto out;
1120                                 }
1121
1122                                 port_info->g_src_id = g_io_add_watch_full(
1123                                                 port_info->gio_read,
1124                                                 G_PRIORITY_DEFAULT,
1125                                                 G_IO_IN | G_IO_HUP,
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);
1133                                         goto out;
1134                                 }
1135
1136                         }
1137                 }
1138
1139                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1140                 if (!msg) {
1141                         _LOGE("Can't allocate new method call");
1142                         ret = MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
1143                         goto out;
1144                 }
1145
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);
1149                 if (err != NULL) {
1150                         _LOGE("No reply. error = %s", err->message);
1151                         g_error_free(err);
1152                         ret = MESSAGE_PORT_ERROR_IO_ERROR;
1153                         goto out;
1154                 }
1155         }
1156
1157 out:
1158         if (msg)
1159                 g_object_unref(msg);
1160         if (raw)
1161                 bundle_free_encoded_rawdata(&raw);
1162         if (fd_list)
1163                 g_object_unref(fd_list);
1164
1165         if (ret != MESSAGE_PORT_ERROR_NONE
1166                         && ret != MESSAGE_PORT_ERROR_MAX_EXCEEDED) {
1167                 __key_info = NULL;
1168                 __create_port_key_info(port_info, &__key_info);
1169
1170                 if (__key_info != NULL) {
1171                         __free_port_info_by_key(__key_info);
1172                         __free_key_info(__key_info);
1173                 }
1174
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]);
1179         }
1180
1181         return ret;
1182 }
1183
1184 int send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1185 {
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)
1189                 return ret;
1190
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);
1194 }
1195
1196 static void __name_registered(GDBusConnection *connection,
1197                 const gchar *name,
1198                 const gchar *name_owner,
1199                 gpointer user_data)
1200 {
1201
1202         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1203         if (info == NULL) {
1204                 LOGE("NULL registered_callback_info");
1205                 return;
1206         }
1207
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);
1211 }
1212
1213 static void __name_unregistered(GDBusConnection *connection,
1214                 const gchar *name,
1215                 gpointer user_data)
1216 {
1217
1218         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1219         if (info == NULL) {
1220                 LOGE("NULL registered_callback_info");
1221                 return;
1222         }
1223
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);
1227 }
1228
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)
1230 {
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;
1234
1235         if (!_initialized) {
1236                 if (!__initialize())
1237                         return MESSAGE_PORT_ERROR_IO_ERROR;
1238         }
1239         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, app_id);
1240
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);
1244                 return ret_val;
1245         }
1246
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");
1249
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 */
1260         }
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 */
1269         }
1270
1271         registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
1272                         gdbus_conn,
1273                         port_info->encoded_bus_name,
1274                         G_BUS_NAME_WATCHER_FLAGS_NONE,
1275                         __name_registered,
1276                         __name_unregistered,
1277                         registered_cb_info,
1278                         NULL);
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 */
1287         }
1288
1289         g_hash_table_insert(__registered_callback_info_hash,
1290                         GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
1291
1292         *watcher_id = registered_cb_info->watcher_id;
1293         return MESSAGE_PORT_ERROR_NONE;
1294 }
1295
1296 int remove_registration_event_cb(int watcher_id)
1297 {
1298         registered_callback_info_s *registered_cb_info = NULL;
1299         gboolean remove_result = FALSE;
1300
1301         if (watcher_id < 1)
1302                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
1303
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;
1307
1308         _LOGI("unwatch_remote_port [%s : %s : %d] ", registered_cb_info->remote_app_id,
1309                 registered_cb_info->remote_port, watcher_id);
1310
1311         remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
1312         if (!remove_result)
1313                 return MESSAGE_PORT_ERROR_IO_ERROR;
1314
1315         g_bus_unwatch_name(watcher_id);
1316
1317         return MESSAGE_PORT_ERROR_NONE;
1318 }
1319