79a50d7b7b710398f6127284471bf57a14a93c58
[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         {
39                 callback(local_port_id, remote_app_id, remote_port, trusted_remote_port, message, user_data);
40                 bundle_free(message);
41         }
42         else
43         {
44                 _LOGI("Ignored");
45         }
46 }
47
48 static void message_dispatcher(int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message)
49 {
50         _SECURE_LOGI("A message has been received to specific local port id (%d) from%s remote port (%s):(%s).",
51                         local_port_id, trusted_remote_port ? " trusted" : "", remote_app_id, remote_port);
52
53         message_port_callback_item *item =
54                 (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
55         do_callback(item->callback, local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data);
56 }
57
58 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)
59 {
60         _SECURE_LOGI("A message has been received to specific trusted local port id (%d) from%s remote port (%s):(%s).",
61                         trusted_local_port_id, trusted_remote_port ? " trusted" : "", remote_app_id, remote_port);
62         message_port_callback_item *item =
63                 (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
64         do_callback(item->callback, trusted_local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data);
65 }
66
67 int message_port_register_local_port(const char *local_port, message_port_message_cb callback, void *user_data)
68 {
69         if (local_port == NULL || callback == NULL)
70         {
71                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
72                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
73         }
74
75         int local_port_id = messageport_register_local_port(local_port, message_dispatcher);
76         if (local_port_id > 0)
77         {
78                 _SECURE_LOGI("Register local port ID (%d).", local_port_id);
79
80                 if (__listeners == NULL) {
81                         __listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
82                 }
83                 pthread_mutex_lock(&__mutex);
84                 message_port_callback_item *item =
85                         (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
86                 if (item == NULL) {
87                         item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item));
88                         if (item == NULL) {
89                                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
90                         }
91                         g_hash_table_insert(__listeners, GINT_TO_POINTER(local_port_id), item);
92                 }
93
94
95                 item->callback = callback;
96                 item->user_data = user_data;
97                 pthread_mutex_unlock(&__mutex);
98
99         } else {
100                 _SECURE_LOGI("Register local port fail (%d).", local_port_id);
101
102         }
103         return convert_to_tizen_error((messageport_error_e)local_port_id);
104 }
105
106 int message_port_register_trusted_local_port(const char *local_port, message_port_trusted_message_cb callback, void *user_data)
107 {
108         if (local_port == NULL || callback == NULL)
109         {
110                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
111                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
112         }
113
114         int trusted_local_port_id = messageport_register_trusted_local_port(local_port, trusted_message_dispatcher);
115         if (trusted_local_port_id > 0)
116         {
117                 _SECURE_LOGI("Register trusted local port ID (%d).", trusted_local_port_id);
118
119                 if (__trusted_listeners == NULL) {
120                         __trusted_listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
121                 }
122                 pthread_mutex_lock(&__mutex);
123                 message_port_callback_item *item =
124                         (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
125                 if (item == NULL) {
126                         item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item));
127                         if (item == NULL) {
128                                 return MESSAGE_PORT_ERROR_OUT_OF_MEMORY;
129                         }
130                         g_hash_table_insert(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id), item);
131                 }
132
133                 item->callback = callback;
134                 item->user_data = user_data;
135                 pthread_mutex_unlock(&__mutex);
136         } else {
137                 _SECURE_LOGI("Register trusted local port fail (%d).", trusted_local_port_id);
138
139         }
140
141         return convert_to_tizen_error((messageport_error_e)trusted_local_port_id);
142 }
143
144 int message_port_unregister_local_port(int local_port_id)
145 {
146         int res = MESSAGE_PORT_ERROR_NONE;
147         if (local_port_id <= 0)
148         {
149                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
150                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
151         }
152         else {
153                 res = messageport_unregister_local_port(local_port_id, false);
154                 g_hash_table_remove(__listeners, GINT_TO_POINTER(local_port_id));
155         }
156         return convert_to_tizen_error((messageport_error_e)res);
157 }
158
159 int message_port_unregister_trusted_local_port(int trusted_local_port_id)
160 {
161
162         int res = MESSAGE_PORT_ERROR_NONE;
163         if (trusted_local_port_id <= 0)
164         {
165                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
166                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
167         }
168         else {
169                 res = messageport_unregister_local_port(trusted_local_port_id, true);
170                 g_hash_table_remove(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id));
171         }
172
173         return convert_to_tizen_error((messageport_error_e)res);
174 }
175
176 int message_port_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist)
177 {
178         if (remote_app_id == NULL || remote_port == NULL)
179         {
180                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
181                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
182         }
183         _SECURE_LOGI("Check remote port (%s):(%s).", remote_app_id, remote_port);
184         return convert_to_tizen_error((messageport_error_e)messageport_check_remote_port(remote_app_id, remote_port, exist));
185 }
186
187 int message_port_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool *exist)
188 {
189         if (remote_app_id == NULL || remote_port == NULL)
190         {
191                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
192                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
193         }
194         _SECURE_LOGI("Check trusted remote port (%s):(%s).", remote_app_id, remote_port);
195         return convert_to_tizen_error((messageport_error_e)messageport_check_trusted_remote_port(remote_app_id, remote_port, exist));
196 }
197
198 int message_port_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
199 {
200         if (remote_app_id == NULL || remote_port == NULL || message == NULL)
201         {
202                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
203                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
204         }
205         _SECURE_LOGI("Send a message to the remote port (%s):(%s).", remote_app_id, remote_port);
206         return convert_to_tizen_error((messageport_error_e)messageport_send_message(remote_app_id, remote_port, message));
207 }
208
209 int message_port_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
210 {
211         if (remote_app_id == NULL || remote_port == NULL || message == NULL)
212         {
213                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
214                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
215         }
216         _SECURE_LOGI("Send a trusted message to the remote port (%s):(%s).", remote_app_id, remote_port);
217         return convert_to_tizen_error((messageport_error_e)messageport_send_trusted_message(remote_app_id, remote_port, message));
218 }
219
220 int message_port_send_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id)
221 {
222         if (remote_app_id == NULL || remote_port == NULL || message == NULL)
223         {
224                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
225                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
226         }
227         else if (local_port_id <= 0)
228         {
229                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
230                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
231         }
232         else {
233
234                 message_port_callback_item *item = NULL;
235                 message_port_callback_item *trusted_item = NULL;
236
237                 if (__listeners != NULL) {
238                         item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
239                 }
240                 if (item == NULL && __trusted_listeners != NULL) {
241                         trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id));
242
243                 }
244
245                 if (item == NULL && trusted_item == NULL)
246                 {
247                         _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id);
248                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
249                 }
250         }
251
252         _SECURE_LOGI("Send a message to (%s):(%s) and listen at the local port ID (%d).", remote_app_id, remote_port, local_port_id);
253         return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_message(local_port_id, remote_app_id, remote_port, message));
254 }
255
256 int message_port_send_trusted_message_with_local_port(const char* remote_app_id, const char *remote_port, bundle* message, int local_port_id)
257 {
258         if (remote_app_id == NULL || remote_port == NULL || message == NULL)
259         {
260                 _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed.");
261                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
262         }
263         else if (local_port_id <= 0)
264         {
265                 _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed.");
266                 return MESSAGE_PORT_ERROR_INVALID_PARAMETER;
267         }
268         else {
269                 message_port_callback_item *item = NULL;
270                 message_port_callback_item *trusted_item = NULL;
271
272                 if (__listeners != NULL) {
273                         item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id));
274                 }
275                 if (item == NULL && __trusted_listeners != NULL) {
276                         trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id));
277
278                 }
279
280                 if (item == NULL && trusted_item == NULL)
281                 {
282                         _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id);
283                         return MESSAGE_PORT_ERROR_PORT_NOT_FOUND;
284                 }
285         }
286
287         _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);
288         return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_trusted_message(local_port_id, remote_app_id, remote_port, message));
289 }
290