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 "message-port.h"
30 #include "message-port-messages.h"
31 #include "message-port-log.h"
33 #include "IpcClient.h"
34 #include "MessagePortProxy.h"
38 static const char MESSAGE_TYPE[] = "MESSAGE_TYPE";
40 static const char LOCAL_APPID[] = "LOCAL_APPID";
41 static const char LOCAL_PORT[] = "LOCAL_PORT";
42 static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL";
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";
49 static const int MAX_MESSAGE_SIZE = 16 * 1024;
51 MessagePortProxy::MessagePortProxy(void)
57 MessagePortProxy::~MessagePortProxy(void)
59 pthread_mutex_destroy(__pMutex);
63 MessagePortProxy::Construct(void)
65 IpcClient* pIpcClient = new (std::nothrow) IpcClient();
66 if (pIpcClient == NULL)
68 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
71 int ret = pIpcClient->Construct("message-port-server", this);
76 _LOGE("Failed to create ipc client: %d.", ret);
78 return MESSAGEPORT_ERROR_IO_ERROR;
81 pthread_mutex_t* pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
84 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
87 pthread_mutex_init(pMutex, NULL);
90 __pIpcClient = pIpcClient;
91 __appId = pIpcClient->GetAppId();
97 MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
99 IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
100 IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
101 IPC_END_MESSAGE_MAP_EX()
105 MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted, messageport_message_cb callback)
107 _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
111 // Check the message port is already registed
112 if (IsLocalPortRegisted(localPort, isTrusted, id))
116 __listeners[localPort] = callback;
120 __trustedListeners[localPort] = callback;
126 bundle *b = bundle_create();
130 bundle_add(b, TRUSTED_LOCAL, "FALSE");
134 bundle_add(b, TRUSTED_LOCAL, "TRUE");
137 bundle_add(b, LOCAL_APPID, __appId.c_str());
138 bundle_add(b, LOCAL_PORT, localPort.c_str());
141 // Create Bundle Buffer from bundle
146 int return_value = 0;
148 IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
152 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
155 ret = __pIpcClient->SendRequest(pMsg);
163 _LOGE("Failed to send a request: %d.", ret);
165 return MESSAGEPORT_ERROR_IO_ERROR;
174 __listeners[localPort] = callback;
175 __idFromString[localPort] = id;
176 __ids[id] = localPort;
182 __trustedListeners[localPort] = callback;
183 __trustedIdFromString[localPort] = id;
184 __trustedIds[id] = localPort;
191 MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist)
193 _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
195 bundle *b = bundle_create();
197 bundle_add(b, LOCAL_APPID, __appId.c_str());
199 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
200 bundle_add(b, REMOTE_PORT, remotePort.c_str());
204 bundle_add(b, TRUSTED_REMOTE, "FALSE");
208 bundle_add(b, TRUSTED_REMOTE, "TRUE");
215 int return_value = 0;
216 IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value);
221 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
224 int ret = __pIpcClient->SendRequest(pMsg);
232 _LOGE("Failed to send a request: %d.", ret);
234 return MESSAGEPORT_ERROR_IO_ERROR;
237 if (return_value < 0)
239 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
241 _LOGE("The remote message port (%s) is not found.", remotePort.c_str());
246 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
248 _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
251 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
255 _LOGE("Failed to check the remote messge port: %d.", return_value);
256 return MESSAGEPORT_ERROR_IO_ERROR;
265 MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
267 _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
271 bundle *b = bundle_create();
272 bundle_add(b, MESSAGE_TYPE, "UNI-DIR");
274 bundle_add(b, LOCAL_APPID, __appId.c_str());
276 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
277 bundle_add(b, REMOTE_PORT, remotePort.c_str());
281 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
285 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
288 BundleBuffer metadata;
294 ret = SendMessageInternal(metadata, buffer);
302 MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
304 _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str());
308 bundle *b = bundle_create();
309 bundle_add(b, MESSAGE_TYPE, "BI-DIR");
311 bundle_add(b, LOCAL_APPID, __appId.c_str());
312 bundle_add(b, LOCAL_PORT, localPort.c_str());
316 bundle_add(b, TRUSTED_LOCAL, "FALSE");
320 bundle_add(b, TRUSTED_LOCAL, "TRUE");
323 bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
324 bundle_add(b, REMOTE_PORT, remotePort.c_str());
328 bundle_add(b, TRUSTED_MESSAGE, "FALSE");
332 bundle_add(b, TRUSTED_MESSAGE, "TRUE");
335 BundleBuffer metadata;
341 ret = SendMessageInternal(metadata, buffer);
349 MessagePortProxy::SendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
351 int return_value = 0;
352 IPC::Message* pMsg = new MessagePort_sendMessage(metadata, buffer, &return_value);
355 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
358 // Check the message size
360 bundle_raw* raw = NULL;
361 bundle_encode(buffer.b, &raw, &len);
363 bundle_free_encoded_rawdata(&raw);
365 if (len > MAX_MESSAGE_SIZE)
367 _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
368 return MESSAGEPORT_ERROR_MAX_EXCEEDED;
371 int ret = __pIpcClient->SendRequest(pMsg);
376 _LOGE("Failed to send a request: %d.", ret);
378 return MESSAGEPORT_ERROR_IO_ERROR;
381 if (return_value < 0)
383 if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
385 _LOGE("The remote message port is not found.");
387 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
389 else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH)
391 _LOGE("The remote application is not signed with the same certificate.");
393 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
397 _LOGE("Failed to check the remote messge port: %d.", return_value);
399 return MESSAGEPORT_ERROR_IO_ERROR;
407 MessagePortProxy::GetLocalPortNameN(int id)
411 map<int, std::string>::iterator it;
414 if (it == __ids.end())
416 it = __trustedIds.find(id);
417 if (it == __ids.end())
423 value = __trustedIds[id];
424 return strdup(value.c_str());
430 return strdup(value.c_str());
437 MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
439 map<int, std::string>::iterator it;
442 if (it == __ids.end())
444 it = __trustedIds.find(id);
445 if (it == __ids.end())
447 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
461 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
465 MessagePortProxy::GetProxy(void)
467 static MessagePortProxy* pProxy = NULL;
471 MessagePortProxy* p = new MessagePortProxy();
477 int ret = p->Construct();
490 MessagePortProxy::GetNextId(void)
492 static int count = 0;
494 pthread_mutex_lock(__pMutex);
496 pthread_mutex_unlock(__pMutex);
502 MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
506 map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
507 if (port_it == __listeners.end())
513 for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
515 if (localPort.compare(it->second) == 0)
525 map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
526 if (port_it == __trustedListeners.end())
532 for (map<int, string>::iterator it = __ids.begin(); it != __trustedIds.end(); ++it)
534 if (localPort.compare(it->second) == 0)
547 MessagePortProxy::OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer)
549 bundle* b = metadata.b;
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);
555 string messageType = bundle_get_val(b, MESSAGE_TYPE);
557 _LOGD("Message received to AppId: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
560 messageport_message_cb callback;
562 if (trustedMessage.compare("FALSE") == 0)
564 callback = __listeners[pRemotePort];
565 id = __idFromString[pRemotePort];
569 callback = __trustedListeners[pRemotePort];
570 id = __trustedIdFromString[pRemotePort];
576 if (messageType.compare("UNI-DIR") == 0)
578 callback(id, NULL, NULL, false, buffer.b);
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);
586 _LOGD("From AppId: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
588 bool trustedPort = (trustedLocal.compare("TRUE") == 0);
590 callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, buffer.b);
596 _LOGD("No callback");