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>
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 = 16 * 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 _LOGE("Out of memory");
71 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
74 int ret = pIpcClient->Construct("message-port-server", this);
79 _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 _LOGE("Out of memory");
87 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
90 pthread_mutex_init(pMutex, NULL);
93 __pIpcClient = pIpcClient;
96 char buffer[256] = {0, };
98 ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
101 _LOGE("Failed to get the application ID: %d", ret);
103 return MESSAGEPORT_ERROR_IO_ERROR;
108 return MESSAGEPORT_ERROR_NONE;
112 MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
114 IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
115 IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
116 IPC_END_MESSAGE_MAP_EX()
120 MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted, messageport_message_cb callback)
122 _SECURE_LOGI("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
126 // Check the message port is already registed
127 if (IsLocalPortRegisted(localPort, isTrusted, id))
131 __listeners[localPort] = callback;
135 __trustedListeners[localPort] = callback;
141 bundle *b = bundle_create();
145 bundle_add(b, TRUSTED_LOCAL, "FALSE");
149 bundle_add(b, TRUSTED_LOCAL, "TRUE");
152 bundle_add(b, LOCAL_APPID, __appId.c_str());
153 bundle_add(b, LOCAL_PORT, localPort.c_str());
156 // Create Bundle Buffer from bundle
161 int return_value = 0;
163 IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
168 _LOGE("Out of memory");
169 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
172 ret = __pIpcClient->SendRequest(pMsg);
180 _LOGE("Failed to send a request: %d.", ret);
182 return MESSAGEPORT_ERROR_IO_ERROR;
191 __listeners[localPort] = callback;
192 __idFromString[localPort] = id;
193 __ids[id] = localPort;
199 __trustedListeners[localPort] = callback;
200 __trustedIdFromString[localPort] = id;
201 __trustedIds[id] = localPort;
208 MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist)
210 _SECURE_LOGI("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
212 bundle *b = bundle_create();
214 bundle_add(b, LOCAL_APPID, __appId.c_str());
216 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
217 bundle_add(b, REMOTE_PORT, remotePort.c_str());
221 bundle_add(b, TRUSTED_REMOTE, "FALSE");
225 bundle_add(b, TRUSTED_REMOTE, "TRUE");
232 int return_value = 0;
233 IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value);
238 _LOGE("Out of memory");
239 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
242 int ret = __pIpcClient->SendRequest(pMsg);
250 _LOGE("Failed to send a request: %d.", ret);
251 return MESSAGEPORT_ERROR_IO_ERROR;
254 if (return_value < 0)
256 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
258 _LOGE("The remote message port (%s) is not found.", remotePort.c_str());
261 return MESSAGEPORT_ERROR_NONE;
263 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
265 _SECURE_LOGI("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
268 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
272 _LOGE("Failed to check the remote messge port: %d.", return_value);
273 return MESSAGEPORT_ERROR_IO_ERROR;
278 return MESSAGEPORT_ERROR_NONE;
282 MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
284 _SECURE_LOGI("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
288 bundle *b = bundle_create();
289 bundle_add(b, MESSAGE_TYPE, "UNI-DIR");
291 bundle_add(b, LOCAL_APPID, __appId.c_str());
293 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
294 bundle_add(b, REMOTE_PORT, remotePort.c_str());
298 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
302 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
305 BundleBuffer metadata;
311 ret = SendMessageInternal(metadata, buffer);
319 MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
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());
325 bundle *b = bundle_create();
326 bundle_add(b, MESSAGE_TYPE, "BI-DIR");
328 bundle_add(b, LOCAL_APPID, __appId.c_str());
329 bundle_add(b, LOCAL_PORT, localPort.c_str());
333 bundle_add(b, TRUSTED_LOCAL, "FALSE");
337 bundle_add(b, TRUSTED_LOCAL, "TRUE");
340 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
341 bundle_add(b, REMOTE_PORT, remotePort.c_str());
345 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
349 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
352 BundleBuffer metadata;
358 ret = SendMessageInternal(metadata, buffer);
366 MessagePortProxy::SendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
368 int return_value = 0;
369 IPC::Message* pMsg = new MessagePort_sendMessage(metadata, buffer, &return_value);
372 _LOGE("Out of memory");
373 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
376 // Check the message size
378 bundle_raw* raw = NULL;
379 bundle_encode_raw(buffer.b, &raw, &len);
381 bundle_free_encoded_rawdata(&raw);
383 if (len > MAX_MESSAGE_SIZE)
385 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
388 return MESSAGEPORT_ERROR_MAX_EXCEEDED;
391 int ret = __pIpcClient->SendRequest(pMsg);
396 _LOGE("Failed to send a request: %d.", ret);
397 return MESSAGEPORT_ERROR_IO_ERROR;
400 if (return_value < 0)
402 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
404 _LOGE("The remote message port is not found.");
406 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
408 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
410 _LOGE("The remote application is not signed with the same certificate.");
412 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
416 _LOGE("Failed to check the remote messge port: %d.", return_value);
418 return MESSAGEPORT_ERROR_IO_ERROR;
422 return MESSAGEPORT_ERROR_NONE;
426 MessagePortProxy::GetLocalPortNameN(int id)
430 map<int, std::string>::iterator it;
433 if (it == __ids.end())
435 it = __trustedIds.find(id);
436 if (it == __ids.end())
438 _LOGE("Invalid value %d", id);
443 value = __trustedIds[id];
444 return strdup(value.c_str());
450 return strdup(value.c_str());
457 MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
459 map<int, std::string>::iterator it;
462 if (it == __ids.end())
464 it = __trustedIds.find(id);
465 if (it == __ids.end())
467 _LOGE("Invalid value %d", id);
468 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
473 return MESSAGEPORT_ERROR_NONE;
479 return MESSAGEPORT_ERROR_NONE;
482 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
486 MessagePortProxy::GetProxy(void)
488 static MessagePortProxy* pProxy = NULL;
492 MessagePortProxy* p = new MessagePortProxy();
495 _LOGE("Out of memory");
499 int ret = p->Construct();
512 MessagePortProxy::GetNextId(void)
514 static int count = 0;
516 pthread_mutex_lock(__pMutex);
518 pthread_mutex_unlock(__pMutex);
524 MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
528 map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
529 if (port_it == __listeners.end())
535 _LOGI("MessagePort name is already registered.");
536 for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
538 if (localPort.compare(it->second) == 0)
548 map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
549 if (port_it == __trustedListeners.end())
555 _LOGI("MessagePort name is already registered.");
556 for (map<int, string>::iterator it = __trustedIds.begin(); it != __trustedIds.end(); ++it)
558 if (localPort.compare(it->second) == 0)
571 MessagePortProxy::OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
573 bundle* b = metadata.b;
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);
579 string messageType = bundle_get_val(b, MESSAGE_TYPE);
581 _SECURE_LOGI("Message received to App: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
584 messageport_message_cb callback;
586 if (trustedMessage.compare("FALSE") == 0)
588 callback = __listeners[pRemotePort];
589 id = __idFromString[pRemotePort];
593 callback = __trustedListeners[pRemotePort];
594 id = __trustedIdFromString[pRemotePort];
600 if (messageType.compare("UNI-DIR") == 0)
602 callback(id, NULL, NULL, false, buffer.b);
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);
610 _SECURE_LOGI("From App: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
612 bool trustedPort = (trustedLocal.compare("TRUE") == 0);
614 callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, buffer.b);
620 _LOGI("No callback");