Adjust coding rules
[platform/core/appfw/message-port.git] / src / message_port.c
1 /*
2  * Copyright (c) 2014 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 #include <glib.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <pthread.h>
21 #include <message-port.h>
22 #include "message_port_internal.h"
23 #include "message_port_log.h"
24 #include "message_port.h"
25
26 typedef struct message_port_callback_item_s {
27         message_port_message_cb callback;
28         void *user_data;
29 } message_port_callback_item;
30
31 static GHashTable *__listeners;
32 static GHashTable *__trusted_listeners;
33 static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
34
35 static void do_callback(message_port_message_cb callback, int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message, void *user_data)
36 {
37         if (callback) {
38                 callback(local_port_id, remote_app_id, remote_port, trusted_remote_port, message, user_data);
39                 bundle_free(message);
40         } else {
41                 _LOGI("Ignored");
42         }
43 }
44
45 static void message_dispatcher(int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message, void *user_data)
46 {
47         message_port_callback_item *item =
48                 (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
49         do_callback(item->callback, local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data);
50 }
51
52 static void trusted_message_dispatcher(int trusted_local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message, void *user_data)
53 {
54         message_port_callback_item *item =
55                 (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
56         do_callback(item->callback, trusted_local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data);
57 }
58
59 int message_port_register_local_port(const char *local_port, message_port_message_cb callback, void *user_data)
60 {
61         if (local_port == NULL || callback == NULL) {
62                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
63                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
64         }
65
66         int local_port_id = messageport_register_local_port(local_port, message_dispatcher);
67         if (local_port_id > 0) {
68                 _SECURE_LOGI("Register local port ID (%d).", local_port_id);
69
70                 if (__listeners == NULL)
71                         __listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
72
73                 pthread_mutex_lock(&__mutex);
74                 message_port_callback_item *item =
75                         (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
76                 if (item == NULL) {
77                         item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item));
78                         if (item == NULL) {
79                                 pthread_mutex_unlock(&__mutex);
80                                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
81                         }
82
83                         g_hash_table_insert(__listeners, GINT_TO_POINTER(local_port_id), item);
84                 }
85
86                 item->callback = callback;
87                 item->user_data = user_data;
88                 pthread_mutex_unlock(&__mutex);
89
90         } else {
91                 _SECURE_LOGI("Register local port fail (%d).", local_port_id);
92         }
93
94         return convert_to_tizen_error((messageport_error_e)local_port_id);
95 }
96
97 int message_port_register_trusted_local_port(const char *local_port, message_port_trusted_message_cb callback, void *user_data)
98 {
99         if (local_port == NULL || callback == NULL) {
100                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
101                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
102         }
103
104         int trusted_local_port_id = messageport_register_trusted_local_port(local_port, trusted_message_dispatcher);
105         if (trusted_local_port_id > 0) {
106                 _SECURE_LOGI("Register trusted local port ID (%d).", trusted_local_port_id);
107
108                 if (__trusted_listeners == NULL)
109                         __trusted_listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
110
111                 pthread_mutex_lock(&__mutex);
112                 message_port_callback_item *item =
113                         (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
114                 if (item == NULL) {
115                         item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item));
116                         if (item == NULL) {
117                                 pthread_mutex_unlock(&__mutex);
118                                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
119                         }
120
121                         g_hash_table_insert(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id), item);
122                 }
123
124                 item->callback = callback;
125                 item->user_data = user_data;
126                 pthread_mutex_unlock(&__mutex);
127         } else {
128                 _SECURE_LOGI("Register trusted local port fail (%d).", trusted_local_port_id);
129         }
130
131         return convert_to_tizen_error((messageport_error_e)trusted_local_port_id);
132 }
133
134 int message_port_unregister_local_port(int local_port_id)
135 {
136         int res = MESSAGE_PORT_ERROR_NONE;
137         if (local_port_id <= 0) {
138                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
139                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
140         } else {
141                 res = messageport_unregister_local_port(local_port_id, false);
142                 g_hash_table_remove(__listeners, GINT_TO_POINTER(local_port_id));
143         }
144         return convert_to_tizen_error((messageport_error_e)res);
145 }
146
147 int message_port_unregister_trusted_local_port(int trusted_local_port_id)
148 {
149
150         int res = MESSAGE_PORT_ERROR_NONE;
151         if (trusted_local_port_id <= 0) {
152                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
153                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
154         } else {
155                 res = messageport_unregister_local_port(trusted_local_port_id, true);
156                 g_hash_table_remove(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
157         }
158
159         return convert_to_tizen_error((messageport_error_e)res);
160 }
161
162 int message_port_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
163 {
164         if (remote_app_id == NULL || remote_port == NULL) {
165                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
166                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
167         }
168         _SECURE_LOGI("Check remote port (%s):(%s).", remote_app_id, remote_port);
169         return convert_to_tizen_error((messageport_error_e)messageport_check_remote_port(remote_app_id, remote_port, exist));
170 }
171
172 int message_port_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
173 {
174         if (remote_app_id == NULL || remote_port == NULL) {
175                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
176                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
177         }
178         _SECURE_LOGI("Check trusted remote port (%s):(%s).", remote_app_id, remote_port);
179         return convert_to_tizen_error((messageport_error_e)messageport_check_trusted_remote_port(remote_app_id, remote_port, exist));
180 }
181
182 int message_port_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
183 {
184         if (remote_app_id == NULL || remote_port == NULL || message == NULL) {
185                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
186                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
187         }
188         return convert_to_tizen_error((messageport_error_e)messageport_send_message(remote_app_id, remote_port, message));
189 }
190
191 int message_port_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
192 {
193         if (remote_app_id == NULL || remote_port == NULL || message == NULL) {
194                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
195                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
196         }
197         return convert_to_tizen_error((messageport_error_e)messageport_send_trusted_message(remote_app_id, remote_port, message));
198 }
199
200 int message_port_send_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id)
201 {
202         if (remote_app_id == NULL || remote_port == NULL || message == NULL) {
203                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
204                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
205         } else if (local_port_id <= 0) {
206                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
207                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
208         } else {
209
210                 message_port_callback_item *item = NULL;
211                 message_port_callback_item *trusted_item = NULL;
212
213                 if (__listeners != NULL)
214                         item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
215
216                 if (item == NULL && __trusted_listeners != NULL)
217                         trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id));
218
219
220                 if (item == NULL && trusted_item == NULL) {
221                         _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id);
222                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
223                 }
224         }
225
226         _SECURE_LOGI("Send a message to (%s):(%s) and listen at the local port ID (%d).", remote_app_id, remote_port, local_port_id);
227         return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_message(local_port_id, remote_app_id, remote_port, message));
228 }
229
230 int message_port_send_trusted_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id)
231 {
232         if (remote_app_id == NULL || remote_port == NULL || message == NULL) {
233                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
234                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
235         } else if (local_port_id <= 0) {
236                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
237                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
238         } else {
239                 message_port_callback_item *item = NULL;
240                 message_port_callback_item *trusted_item = NULL;
241
242                 if (__listeners != NULL)
243                         item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
244
245                 if (item == NULL && __trusted_listeners != NULL)
246                         trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id));
247
248                 if (item == NULL && trusted_item == NULL) {
249                         _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id);
250                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
251                 }
252         }
253
254         _SECURE_LOGI("Send a trusted message to (%s):(%s) and listen at the local port ID (%d).", remote_app_id, remote_port, local_port_id);
255         return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_trusted_message(local_port_id, remote_app_id, remote_port, message));
256 }
257