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 <app_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 = 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;
97 ret = app_manager_get_app_id(pid, &pAppId);
100 _LOGE("Failed to get_app_id: %d", ret);
102 return MESSAGEPORT_ERROR_IO_ERROR;
113 MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
115 IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
116 IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
117 IPC_END_MESSAGE_MAP_EX()
121 MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted, messageport_message_cb callback)
123 _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
127 // Check the message port is already registed
128 if (IsLocalPortRegisted(localPort, isTrusted, id))
132 __listeners[localPort] = callback;
136 __trustedListeners[localPort] = callback;
142 bundle *b = bundle_create();
146 bundle_add(b, TRUSTED_LOCAL, "FALSE");
150 bundle_add(b, TRUSTED_LOCAL, "TRUE");
153 bundle_add(b, LOCAL_APPID, __appId.c_str());
154 bundle_add(b, LOCAL_PORT, localPort.c_str());
157 // Create Bundle Buffer from bundle
162 int return_value = 0;
164 IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
169 _LOGE("Out of memory");
170 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
173 ret = __pIpcClient->SendRequest(pMsg);
181 _LOGE("Failed to send a request: %d.", ret);
183 return MESSAGEPORT_ERROR_IO_ERROR;
192 __listeners[localPort] = callback;
193 __idFromString[localPort] = id;
194 __ids[id] = localPort;
200 __trustedListeners[localPort] = callback;
201 __trustedIdFromString[localPort] = id;
202 __trustedIds[id] = localPort;
209 MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist)
211 _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
213 bundle *b = bundle_create();
215 bundle_add(b, LOCAL_APPID, __appId.c_str());
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 _LOGE("Out of memory");
240 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
243 int ret = __pIpcClient->SendRequest(pMsg);
251 _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)
259 _LOGE("The remote message port (%s) is not found.", remotePort.c_str());
264 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
266 _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
269 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
273 _LOGE("Failed to check the remote messge port: %d.", return_value);
274 return MESSAGEPORT_ERROR_IO_ERROR;
283 MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
285 _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
289 bundle *b = bundle_create();
290 bundle_add(b, MESSAGE_TYPE, "UNI-DIR");
292 bundle_add(b, LOCAL_APPID, __appId.c_str());
294 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
295 bundle_add(b, REMOTE_PORT, remotePort.c_str());
299 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
303 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
306 BundleBuffer metadata;
312 ret = SendMessageInternal(metadata, buffer);
320 MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
322 _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str());
326 bundle *b = bundle_create();
327 bundle_add(b, MESSAGE_TYPE, "BI-DIR");
329 bundle_add(b, LOCAL_APPID, __appId.c_str());
330 bundle_add(b, LOCAL_PORT, localPort.c_str());
334 bundle_add(b, TRUSTED_LOCAL, "FALSE");
338 bundle_add(b, TRUSTED_LOCAL, "TRUE");
341 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
342 bundle_add(b, REMOTE_PORT, remotePort.c_str());
346 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
350 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
353 BundleBuffer metadata;
359 ret = SendMessageInternal(metadata, buffer);
367 MessagePortProxy::SendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
369 int return_value = 0;
370 IPC::Message* pMsg = new MessagePort_sendMessage(metadata, buffer, &return_value);
373 _LOGE("Out of memory");
374 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
377 // Check the message size
379 bundle_raw* raw = NULL;
380 bundle_encode(buffer.b, &raw, &len);
382 bundle_free_encoded_rawdata(&raw);
384 if (len > MAX_MESSAGE_SIZE)
386 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
387 return MESSAGEPORT_ERROR_MAX_EXCEEDED;
390 int ret = __pIpcClient->SendRequest(pMsg);
395 _LOGE("Failed to send a request: %d.", ret);
396 return MESSAGEPORT_ERROR_IO_ERROR;
399 if (return_value < 0)
401 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
403 _LOGE("The remote message port is not found.");
405 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
407 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
409 _LOGE("The remote application is not signed with the same certificate.");
411 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
415 _LOGE("Failed to check the remote messge port: %d.", return_value);
417 return MESSAGEPORT_ERROR_IO_ERROR;
425 MessagePortProxy::GetLocalPortNameN(int id)
429 map<int, std::string>::iterator it;
432 if (it == __ids.end())
434 it = __trustedIds.find(id);
435 if (it == __ids.end())
437 _LOGE("Invalid value %d", id);
442 value = __trustedIds[id];
443 return strdup(value.c_str());
449 return strdup(value.c_str());
456 MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
458 map<int, std::string>::iterator it;
461 if (it == __ids.end())
463 it = __trustedIds.find(id);
464 if (it == __ids.end())
466 _LOGE("Invalid value %d", id);
467 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
481 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
485 MessagePortProxy::GetProxy(void)
487 static MessagePortProxy* pProxy = NULL;
491 MessagePortProxy* p = new MessagePortProxy();
494 _LOGE("Out of memory");
498 int ret = p->Construct();
511 MessagePortProxy::GetNextId(void)
513 static int count = 0;
515 pthread_mutex_lock(__pMutex);
517 pthread_mutex_unlock(__pMutex);
523 MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
527 map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
528 if (port_it == __listeners.end())
534 for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
536 if (localPort.compare(it->second) == 0)
546 map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
547 if (port_it == __trustedListeners.end())
553 for (map<int, string>::iterator it = __ids.begin(); it != __trustedIds.end(); ++it)
555 if (localPort.compare(it->second) == 0)
568 MessagePortProxy::OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
570 bundle* b = metadata.b;
572 const char* pRemoteAppId = bundle_get_val(b, REMOTE_APPID);
573 const char* pRemotePort = bundle_get_val(b, REMOTE_PORT);
574 string trustedMessage = bundle_get_val(b, TRUSTED_MESSAGE);
576 string messageType = bundle_get_val(b, MESSAGE_TYPE);
578 _LOGD("Message received to App: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
581 messageport_message_cb callback;
583 if (trustedMessage.compare("FALSE") == 0)
585 callback = __listeners[pRemotePort];
586 id = __idFromString[pRemotePort];
590 callback = __trustedListeners[pRemotePort];
591 id = __trustedIdFromString[pRemotePort];
597 if (messageType.compare("UNI-DIR") == 0)
599 callback(id, NULL, NULL, false, buffer.b);
603 string localAppId = bundle_get_val(b, LOCAL_APPID);
604 string localPort = bundle_get_val(b, LOCAL_PORT);
605 string trustedLocal = bundle_get_val(b, TRUSTED_LOCAL);
607 _LOGD("From App: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
609 bool trustedPort = (trustedLocal.compare("TRUE") == 0);
611 callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, buffer.b);
617 _LOGD("No callback");