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