Separate the metadata
[platform/core/appfw/message-port.git] / src / MessagePortProxy.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        MessagePortProxy.cpp
20  * @brief       This is the implementation file for the MessagePortProxy class.
21  *
22  */
23
24
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <sstream>
28
29 #include "message-port.h"
30 #include "message-port-messages.h"
31 #include "message-port-log.h"
32
33 #include "IpcClient.h"
34 #include "MessagePortProxy.h"
35
36 using namespace std;
37
38 static const char MESSAGE_TYPE[] = "MESSAGE_TYPE";
39
40 static const char LOCAL_APPID[] = "LOCAL_APPID";
41 static const char LOCAL_PORT[] = "LOCAL_PORT";
42 static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL";
43
44 static const char REMOTE_APPID[] = "REMOTE_APPID";
45 static const char REMOTE_PORT[] = "REMOTE_PORT";
46 static const char TRUSTED_REMOTE[] = "TRUSTED_REMOTE";
47 static const char TRUSTED_MESSAGE[] = "TRUSTED_MESSAGE";
48
49 static const int MAX_MESSAGE_SIZE = 16 * 1024;
50
51 MessagePortProxy::MessagePortProxy(void)
52         : __pIpcClient(NULL)
53         , __pMutex(NULL)
54 {
55 }
56
57 MessagePortProxy::~MessagePortProxy(void)
58 {
59         pthread_mutex_destroy(__pMutex);
60 }
61
62 int
63 MessagePortProxy::Construct(void)
64 {
65         IpcClient* pIpcClient = new (std::nothrow) IpcClient();
66         if (pIpcClient == NULL)
67         {
68                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
69         }
70
71         int ret = pIpcClient->Construct("message-port-server", this);
72         if (ret != 0)
73         {
74                 delete pIpcClient;
75
76                 _LOGE("Failed to create ipc client: %d.", ret);
77
78                 return MESSAGEPORT_ERROR_IO_ERROR;
79         }
80
81         pthread_mutex_t* pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
82         if (pMutex == NULL)
83         {
84                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
85         }
86
87         pthread_mutex_init(pMutex, NULL);
88
89         __pMutex = pMutex;
90         __pIpcClient = pIpcClient;
91         __appId = pIpcClient->GetAppId();
92
93         return 0;
94 }
95
96 void
97 MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
98 {
99         IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
100         IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
101         IPC_END_MESSAGE_MAP_EX()
102 }
103
104 int
105 MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted,  messageport_message_cb callback)
106 {
107         _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
108
109         int id = 0;
110
111         // Check the message port is already registed
112         if (IsLocalPortRegisted(localPort, isTrusted, id))
113         {
114                 if (!isTrusted)
115                 {
116                         __listeners[localPort] = callback;
117                 }
118                 else
119                 {
120                         __trustedListeners[localPort] = callback;
121                 }
122
123                 return id;
124         }
125
126         bundle *b = bundle_create();
127
128         if (!isTrusted)
129         {
130                 bundle_add(b, TRUSTED_LOCAL, "FALSE");
131         }
132         else
133         {
134                 bundle_add(b, TRUSTED_LOCAL, "TRUE");
135         }
136
137         bundle_add(b, LOCAL_APPID, __appId.c_str());
138         bundle_add(b, LOCAL_PORT, localPort.c_str());
139
140
141         // Create Bundle Buffer from bundle
142         BundleBuffer buffer;
143         buffer.b = b;
144
145         int ret = 0;
146         int return_value = 0;
147
148         IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
149         if (pMsg == NULL)
150         {
151                 bundle_free(b);
152                 return  MESSAGEPORT_ERROR_OUT_OF_MEMORY;
153         }
154
155         ret = __pIpcClient->SendRequest(pMsg);
156
157         delete pMsg;
158
159         bundle_free(b);
160
161         if (ret != 0)
162         {
163                 _LOGE("Failed to send a request: %d.", ret);
164
165                 return MESSAGEPORT_ERROR_IO_ERROR;
166         }
167
168         // Add a listener
169         if (!isTrusted)
170         {
171                 // Local port id
172                 id = GetNextId();
173
174                 __listeners[localPort] = callback;
175                 __idFromString[localPort] = id;
176                 __ids[id] = localPort;
177         }
178         else
179         {
180                 id = GetNextId();
181
182                 __trustedListeners[localPort] = callback;
183                 __trustedIdFromString[localPort] = id;
184                 __trustedIds[id] = localPort;
185         }
186
187         return id;
188 }
189
190 int
191 MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort,  bool isTrusted, bool *exist)
192 {
193         _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
194
195         bundle *b = bundle_create();
196
197         bundle_add(b, LOCAL_APPID, __appId.c_str());
198
199         bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
200         bundle_add(b, REMOTE_PORT, remotePort.c_str());
201
202         if (!isTrusted)
203         {
204                 bundle_add(b, TRUSTED_REMOTE, "FALSE");
205         }
206         else
207         {
208                 bundle_add(b, TRUSTED_REMOTE, "TRUE");
209         }
210
211         // To Bundle Buffer
212         BundleBuffer buffer;
213         buffer.b = b;
214
215         int return_value = 0;
216         IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value);
217         if (pMsg == NULL)
218         {
219                 bundle_free(b);
220
221                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
222         }
223
224         int ret = __pIpcClient->SendRequest(pMsg);
225
226         delete pMsg;
227
228         bundle_free(b);
229
230         if (ret < 0)
231         {
232                 _LOGE("Failed to send a request: %d.", ret);
233
234                 return MESSAGEPORT_ERROR_IO_ERROR;
235         }
236
237         if (return_value < 0)
238         {
239                 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
240                 {
241                         _LOGE("The remote message port (%s) is not found.", remotePort.c_str());
242
243                         *exist = false;
244                         return 0;
245                 }
246                 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
247                 {
248                         _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
249
250                         *exist = true;
251                         return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
252                 }
253                 else
254                 {
255                         _LOGE("Failed to check the remote messge port: %d.", return_value);
256                         return MESSAGEPORT_ERROR_IO_ERROR;
257                 }
258         }
259
260         *exist = true;
261         return 0;
262 }
263
264 int
265 MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
266 {
267         _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
268
269         int ret = 0;
270
271         bundle *b = bundle_create();
272         bundle_add(b, MESSAGE_TYPE, "UNI-DIR");
273
274         bundle_add(b, LOCAL_APPID, __appId.c_str());
275
276         bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
277         bundle_add(b, REMOTE_PORT, remotePort.c_str());
278
279         if (!trustedMessage)
280         {
281                 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
282         }
283         else
284         {
285                 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
286         }
287
288         BundleBuffer metadata;
289         metadata.b = b;
290
291         BundleBuffer buffer;
292         buffer.b = data;
293
294         ret = SendMessageInternal(metadata, buffer);
295
296         bundle_free(b);
297
298         return ret;
299 }
300
301 int
302 MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
303 {
304         _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str());
305
306         int ret = 0;
307
308         bundle *b = bundle_create();
309         bundle_add(b, MESSAGE_TYPE, "BI-DIR");
310
311         bundle_add(b, LOCAL_APPID, __appId.c_str());
312         bundle_add(b, LOCAL_PORT, localPort.c_str());
313
314         if (!trustedPort)
315         {
316                 bundle_add(b, TRUSTED_LOCAL, "FALSE");
317         }
318         else
319         {
320                 bundle_add(b, TRUSTED_LOCAL, "TRUE");
321         }
322
323         bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
324         bundle_add(b, REMOTE_PORT, remotePort.c_str());
325
326         if (!trustedMessage)
327         {
328                 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
329         }
330         else
331         {
332                 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
333         }
334
335         BundleBuffer metadata;
336         metadata.b = b;
337
338         BundleBuffer buffer;
339         buffer.b = data;
340
341         ret = SendMessageInternal(metadata, buffer);
342
343         bundle_free(b);
344
345         return ret;
346 }
347
348 int
349 MessagePortProxy::SendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
350 {
351         int return_value = 0;
352         IPC::Message* pMsg = new MessagePort_sendMessage(metadata, buffer, &return_value);
353         if (pMsg == NULL)
354         {
355                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
356         }
357
358         // Check the message size
359         int len = 0;
360         bundle_raw* raw = NULL;
361         bundle_encode(buffer.b, &raw, &len);
362
363         bundle_free_encoded_rawdata(&raw);
364
365         if (len > MAX_MESSAGE_SIZE)
366         {
367                 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
368                 return MESSAGEPORT_ERROR_MAX_EXCEEDED;
369         }
370
371         int ret = __pIpcClient->SendRequest(pMsg);
372         delete pMsg;
373
374         if (ret < 0)
375         {
376                 _LOGE("Failed to send a request: %d.", ret);
377
378                 return MESSAGEPORT_ERROR_IO_ERROR;
379         }
380
381         if (return_value < 0)
382         {
383                 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
384                 {
385                         _LOGE("The remote message port is not found.");
386
387                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
388                 }
389                 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
390                 {
391                         _LOGE("The remote application is not signed with the same certificate.");
392
393                         return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
394                 }
395                 else
396                 {
397                         _LOGE("Failed to check the remote messge port: %d.", return_value);
398
399                         return MESSAGEPORT_ERROR_IO_ERROR;
400                 }
401         }
402
403         return 0;
404 }
405
406 char*
407 MessagePortProxy::GetLocalPortNameN(int id)
408 {
409         string value;
410
411         map<int, std::string>::iterator it;
412
413         it = __ids.find(id);
414         if (it == __ids.end())
415         {
416                 it = __trustedIds.find(id);
417                 if (it == __ids.end())
418                 {
419                         return NULL;
420                 }
421                 else
422                 {
423                         value = __trustedIds[id];
424                         return strdup(value.c_str());
425                 }
426         }
427         else
428         {
429                 value = __ids[id];
430                 return strdup(value.c_str());
431         }
432
433         return NULL;
434 }
435
436 int
437 MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
438 {
439         map<int, std::string>::iterator it;
440
441         it = __ids.find(id);
442         if (it == __ids.end())
443         {
444                 it = __trustedIds.find(id);
445                 if (it == __ids.end())
446                 {
447                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
448                 }
449                 else
450                 {
451                         *trusted = true;
452                         return 0;
453                 }
454         }
455         else
456         {
457                 *trusted = false;
458                 return 0;
459         }
460
461         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
462 }
463
464 MessagePortProxy*
465 MessagePortProxy::GetProxy(void)
466 {
467         static MessagePortProxy* pProxy = NULL;
468
469         if (pProxy == NULL)
470         {
471                 MessagePortProxy* p = new MessagePortProxy();
472                 if (p == NULL)
473                 {
474                         return NULL;
475                 }
476
477                 int ret = p->Construct();
478                 if (ret < 0)
479                 {
480                         return NULL;
481                 }
482
483                 pProxy = p;
484         }
485
486         return pProxy;
487 }
488
489 int
490 MessagePortProxy::GetNextId(void)
491 {
492         static int count = 0;
493
494         pthread_mutex_lock(__pMutex);
495         ++count;
496         pthread_mutex_unlock(__pMutex);
497
498         return count;
499 }
500
501 bool
502 MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
503 {
504         if (!trusted)
505         {
506                 map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
507                 if (port_it == __listeners.end())
508                 {
509                         return false;
510                 }
511                 else
512                 {
513                         for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
514                         {
515                                 if (localPort.compare(it->second) == 0)
516                                 {
517                                         id = it->first;
518                                         return true;
519                                 }
520                         }
521                 }
522         }
523         else
524         {
525                 map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
526                 if (port_it == __trustedListeners.end())
527                 {
528                         return false;
529                 }
530                 else
531                 {
532                         for (map<int, string>::iterator it = __ids.begin(); it != __trustedIds.end(); ++it)
533                         {
534                                 if (localPort.compare(it->second) == 0)
535                                 {
536                                         id = it->first;
537                                         return true;
538                                 }
539                         }
540                 }
541         }
542
543         return false;
544 }
545
546 bool
547 MessagePortProxy::OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
548 {
549         bundle* b = metadata.b;
550
551         const char* pRemoteAppId = bundle_get_val(b, REMOTE_APPID);
552         const char* pRemotePort = bundle_get_val(b, REMOTE_PORT);
553         string trustedMessage = bundle_get_val(b, TRUSTED_MESSAGE);
554
555         string messageType = bundle_get_val(b, MESSAGE_TYPE);
556
557         _LOGD("Message received to AppId: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
558
559         int id = 0;
560         messageport_message_cb callback;
561
562         if (trustedMessage.compare("FALSE") == 0)
563         {
564                 callback = __listeners[pRemotePort];
565                 id = __idFromString[pRemotePort];
566         }
567         else
568         {
569                 callback = __trustedListeners[pRemotePort];
570                 id = __trustedIdFromString[pRemotePort];
571         }
572
573
574         if (callback)
575         {
576                 if (messageType.compare("UNI-DIR") == 0)
577                 {
578                         callback(id, NULL, NULL, false, buffer.b);
579                 }
580                 else
581                 {
582                         string localAppId = bundle_get_val(b, LOCAL_APPID);
583                         string localPort = bundle_get_val(b, LOCAL_PORT);
584                         string trustedLocal = bundle_get_val(b, TRUSTED_LOCAL);
585
586                         _LOGD("From AppId: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
587
588                         bool trustedPort = (trustedLocal.compare("TRUE") == 0);
589
590                         callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, buffer.b);
591                 }
592
593         }
594         else
595         {
596                 _LOGD("No callback");
597         }
598
599         bundle_free(b);
600
601         return true;
602 }
603