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