2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file MessagePortProxy.cpp
20 * @brief This is the implementation file for the MessagePortProxy class.
25 #include <sys/types.h>
29 #include <package_manager.h>
31 #include "message-port.h"
32 #include "message-port-messages.h"
33 #include "message-port-log.h"
35 #include "IpcClient.h"
36 #include "MessagePortProxy.h"
40 static const char MESSAGE_TYPE[] = "MESSAGE_TYPE";
42 static const char LOCAL_APPID[] = "LOCAL_APPID";
43 static const char LOCAL_PORT[] = "LOCAL_PORT";
44 static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL";
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";
51 static const int MAX_MESSAGE_SIZE = 8 * 1024;
53 MessagePortProxy::MessagePortProxy(void)
59 MessagePortProxy::~MessagePortProxy(void)
61 pthread_mutex_destroy(__pMutex);
65 MessagePortProxy::Construct(void)
67 IpcClient* pIpcClient = new (std::nothrow) IpcClient();
68 if (pIpcClient == NULL)
70 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
73 int ret = pIpcClient->Construct("message-port-server", this);
78 _LOGE("Failed to create ipc client: %d.", ret);
80 return MESSAGEPORT_ERROR_IO_ERROR;
83 pthread_mutex_t* pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
86 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
89 pthread_mutex_init(pMutex, NULL);
92 __pIpcClient = pIpcClient;
93 __appId = pIpcClient->GetAppId();
99 MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
101 _LOGD("Message received, type %d", message.type());
103 IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
104 IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
105 IPC_END_MESSAGE_MAP_EX()
109 MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted, messageport_message_cb callback)
111 _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
115 // Check the message port is already registed
116 if (IsLocalPortRegisted(localPort, isTrusted, id))
120 __listeners[localPort] = callback;
124 __trustedListeners[localPort] = callback;
130 bundle *b = bundle_create();
134 bundle_add(b, TRUSTED_LOCAL, "FALSE");
138 bundle_add(b, TRUSTED_LOCAL, "TRUE");
141 bundle_add(b, LOCAL_APPID, __appId.c_str());
142 bundle_add(b, LOCAL_PORT, localPort.c_str());
145 // Create Bundle Buffer from bundle
150 int return_value = 0;
152 IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
156 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
159 ret = __pIpcClient->SendRequest(pMsg);
167 _LOGE("Failed to send a request: %d.", ret);
169 return MESSAGEPORT_ERROR_IO_ERROR;
179 __listeners[localPort] = callback;
180 __idFromString[localPort] = id;
181 __ids[id] = localPort;
187 __trustedListeners[localPort] = callback;
188 __trustedIdFromString[localPort] = id;
189 __trustedIds[id] = localPort;
196 MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist)
198 _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
202 // Check the certificate
205 // Check the preloaded
206 if (!IsPreloaded(remoteAppId))
208 ret = CheckCertificate(remoteAppId);
216 bundle *b = bundle_create();
217 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
218 bundle_add(b, REMOTE_PORT, remotePort.c_str());
222 bundle_add(b, TRUSTED_REMOTE, "FALSE");
226 bundle_add(b, TRUSTED_REMOTE, "TRUE");
233 int return_value = 0;
234 IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value);
239 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
242 ret = __pIpcClient->SendRequest(pMsg);
250 _LOGE("Failed to send a request: %d.", ret);
252 return MESSAGEPORT_ERROR_IO_ERROR;
255 if (return_value < 0)
257 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
264 _LOGE("Failed to check the remote messge port: %d.", return_value);
265 return MESSAGEPORT_ERROR_IO_ERROR;
274 MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
276 _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
280 // Check the certificate
283 // Check the preloaded
284 if (!IsPreloaded(remoteAppId))
286 ret = CheckCertificate(remoteAppId);
294 bundle_add(data, MESSAGE_TYPE, "UNI-DIR");
296 bundle_add(data, REMOTE_APPID, remoteAppId.c_str());
297 bundle_add(data, REMOTE_PORT, remotePort.c_str());
301 bundle_add(data, TRUSTED_MESSAGE, "FALSE");
305 bundle_add(data, TRUSTED_MESSAGE, "TRUE");
311 ret = SendMessageInternal(buffer);
317 MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
319 _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str());
323 // Check the certificate
326 // Check the preloaded
327 if (!IsPreloaded(remoteAppId))
329 ret = CheckCertificate(remoteAppId);
337 bundle_add(data, MESSAGE_TYPE, "BI-DIR");
339 bundle_add(data, LOCAL_APPID, __appId.c_str());
340 bundle_add(data, LOCAL_PORT, localPort.c_str());
344 bundle_add(data, TRUSTED_LOCAL, "FALSE");
348 bundle_add(data, TRUSTED_LOCAL, "TRUE");
351 bundle_add(data, REMOTE_APPID, remoteAppId.c_str());
352 bundle_add(data, REMOTE_PORT, remotePort.c_str());
356 bundle_add(data, TRUSTED_MESSAGE, "FALSE");
360 bundle_add(data, TRUSTED_MESSAGE, "TRUE");
366 ret = SendMessageInternal(buffer);
372 MessagePortProxy::SendMessageInternal(const BundleBuffer& buffer)
376 IPC::Message* pMsg = new MessagePort_sendMessage(buffer, &ret);
379 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
382 // Check the message size
384 bundle_raw* raw = NULL;
385 bundle_encode(buffer.b, &raw, &len);
387 bundle_free_encoded_rawdata(&raw);
389 if (len > MAX_MESSAGE_SIZE)
391 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
392 return MESSAGEPORT_ERROR_MAX_EXCEEDED;
395 ret = __pIpcClient->SendRequest(pMsg);
400 _LOGE("Failed to send a request: %d.", ret);
401 return MESSAGEPORT_ERROR_IO_ERROR;
408 MessagePortProxy::GetLocalPortNameN(int id)
412 map<int, std::string>::iterator it;
415 if (it == __ids.end())
417 it = __trustedIds.find(id);
418 if (it == __ids.end())
424 value = __trustedIds[id];
425 return strdup(value.c_str());
431 return strdup(value.c_str());
438 MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
440 map<int, std::string>::iterator it;
443 if (it == __ids.end())
445 it = __trustedIds.find(id);
446 if (it == __ids.end())
448 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
462 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
466 MessagePortProxy::GetProxy(void)
468 static MessagePortProxy* pProxy = NULL;
472 MessagePortProxy* p = new MessagePortProxy();
478 int ret = p->Construct();
491 MessagePortProxy::GetNextId(void)
493 static int count = 0;
495 pthread_mutex_lock(__pMutex);
497 pthread_mutex_unlock(__pMutex);
503 MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
507 map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
508 if (port_it == __listeners.end())
514 for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
516 if (localPort.compare(it->second) == 0)
526 map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
527 if (port_it == __trustedListeners.end())
533 for (map<int, string>::iterator it = __ids.begin(); it != __trustedIds.end(); ++it)
535 if (localPort.compare(it->second) == 0)
548 MessagePortProxy::CheckCertificate(const std::string& remoteAppId)
550 package_manager_compare_result_type_e res;
551 int ret = package_manager_compare_app_cert_info(__appId.c_str(), remoteAppId.c_str(), &res);
555 if (res != PACAKGE_MANAGER_COMPARE_MATCH)
557 _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
558 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
563 _LOGE("Failed to check the certificate: %d.", ret);
564 return MESSAGEPORT_ERROR_IO_ERROR;
571 MessagePortProxy::IsPreloaded(const std::string& remoteAppId)
573 bool preload_local = false;
574 bool preload_remote = false;
576 if (package_manager_is_preload_package_by_app_id(__appId.c_str(), &preload_local) == 0)
578 if (package_manager_is_preload_package_by_app_id(remoteAppId.c_str(), &preload_remote) == 0)
580 if (preload_local && preload_remote)
587 _LOGE("Failed to check the preloaded application.");
592 _LOGE("Failed to check the preloaded application.");
599 MessagePortProxy::OnSendMessageInternal(const BundleBuffer& buffer)
601 bundle* b = buffer.b;
603 const char* pRemoteAppId = bundle_get_val(b, REMOTE_APPID);
604 const char* pRemotePort = bundle_get_val(b, REMOTE_PORT);
605 string trustedMessage = bundle_get_val(b, TRUSTED_MESSAGE);
607 string messageType = bundle_get_val(b, MESSAGE_TYPE);
609 _LOGD("Message received to AppId: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
612 messageport_message_cb callback;
614 if (trustedMessage.compare("FALSE") == 0)
616 callback = __listeners[pRemotePort];
617 id = __idFromString[pRemotePort];
621 callback = __trustedListeners[pRemotePort];
622 id = __trustedIdFromString[pRemotePort];
628 // remove system data
629 bundle_del(b, REMOTE_APPID);
630 bundle_del(b, REMOTE_PORT);
631 bundle_del(b, TRUSTED_MESSAGE);
632 bundle_del(b, MESSAGE_TYPE);
634 if (messageType.compare("UNI-DIR") == 0)
636 callback(id, NULL, NULL, false, b);
640 string localAppId = bundle_get_val(b, LOCAL_APPID);
641 string localPort = bundle_get_val(b, LOCAL_PORT);
642 string trustedLocal = bundle_get_val(b, TRUSTED_LOCAL);
644 _LOGD("From AppId: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
646 bool trustedPort = (trustedLocal.compare("TRUE") == 0);
648 // remove system data
649 bundle_del(b, LOCAL_APPID);
650 bundle_del(b, LOCAL_PORT);
651 bundle_del(b, TRUSTED_LOCAL);
653 callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, b);
658 _LOGD("No callback");