, __invocation(inv)
, __binaryLength(binaryLength)
, __binary(binary)
+ , __isConnect(false)
{
}
, __client(client)
, __subject(subj)
, __description(desc)
+ , __isConnect(false)
{
}
, __creds(creds)
, __sender(sender)
, __invocation(inv)
+ , __isConnect(false)
{
}
{
if ( __creds != NULL ) {
delete __creds;
+ __creds = NULL;
}
}
+void conv::Request::setType(int type)
+{
+ __type = type;
+}
+
int conv::Request::getType()
{
return __type;
return __description;
}
+void conv::Request::setCreds(Credentials* creds)
+{
+ __creds = creds;
+}
+
conv::Credentials* conv::Request::getCreds()
{
return __creds;
}
+GDBusMethodInvocation* conv::Request::getInvocation()
+{
+ return __invocation;
+}
+
bool conv::Request::reply(int error)
{
IF_FAIL_RETURN(__invocation, true);
_I("Reply %#x", error);
- g_dbus_method_invocation_return_value(__invocation, g_variant_new("(i)", error));
- __invocation = NULL;
- _D("Reply done");
+ if (!__isConnect) {
+ g_dbus_method_invocation_return_value(__invocation, g_variant_new("(i)", error));
+ __invocation = NULL;
+ _D("Reply done");
+ }
return true;
}
_D("info : binary length %d", binaryLength);
_D("info : description %s", __description.str().c_str());
- conv::dbus_server::publish(__sender.c_str(), __reqId, __subject.c_str(), error, dataStr, binaryLength, binary);
+ if (!__isConnect) {
+ _I("REPLY");
+ conv::dbus_server::publish(__sender.c_str(), __reqId, __subject.c_str(), error, dataStr, binaryLength, binary);
+ }
g_free(dataStr);
return true;
{
__communicationInfo = communicationInfo;
}
+
+bool conv::Request::getIsConnect()
+{
+ return __isConnect;
+}
+
+void conv::Request::setIsConnect(bool state)
+{
+ __isConnect = state;
+}
+
+conv::Request* conv::Request::clone()
+{
+ conv::Request *instance = new conv::Request(*this);
+ instance->setCreds(NULL);
+ return instance;
+}
\ No newline at end of file
int binaryLength, const unsigned char* binary);
~Request();
+ void setType(int type);
int getType();
int getId();
int getBinaryLength();
const unsigned char *getBinary();
Json& getDescription();
Credentials *getCreds();
+ void setCreds(Credentials* creds);
+ GDBusMethodInvocation* getInvocation();
+
bool reply(int error);
bool publish(int error, Json &data, int binaryLength, const unsigned char* binary);
void setServiceInfo(IServiceInfo* serviceInfo);
void setCommunicationInfo(ICommunicationInfo* communicationInfo);
+ void setIsConnect(bool state);
+ bool getIsConnect();
+
+ Request* clone();
+
protected:
int __type;
int __reqId;
std::string __client;
std::string __subject;
Json __description;
- Credentials *__creds;
+ Credentials *__creds = NULL;
std::string __sender;
- GDBusMethodInvocation *__invocation;
+ GDBusMethodInvocation *__invocation = NULL;
+
+ IServiceInfo* __serviceInfo = NULL;
+ ICommunicationInfo* __communicationInfo = NULL;
+ int __binaryLength = 0;
+ const unsigned char* __binary = NULL;
- IServiceInfo* __serviceInfo;
- ICommunicationInfo* __communicationInfo;
- int __binaryLength;
- const unsigned char* __binary;
+ bool __isConnect;
};
}
} else {
_D("state : APP_COMM_STATE_FAILED");
state = APP_COMM_STATE_FAILED;
+ if (!isLocal && application != NULL) {
+ application->disconnect();
+ }
}
if ((*requestObj) != NULL) {
using namespace std;
+static std::map<std::string, guint> dbus_listener_info_map;
+
static void vconf_update_cb(keynode_t *node, void* user_data)
{
conv::AppCommServiceProvider* instance = static_cast<conv::AppCommServiceProvider*>(user_data);
conv::AppCommServiceProvider::~AppCommServiceProvider()
{
+ dbus_listener_info_map.clear();
}
int conv::AppCommServiceProvider::init()
return CONV_ERROR_NONE;
}
+static int stop_request(conv::Request* requestObj);
+
+static void _dbusDisconnectListenerFreeCallback(gpointer userData)
+{
+ conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+ if (_requestObj != NULL) {
+ delete _requestObj;
+ _requestObj = NULL;
+ }
+}
+
+static void _dbusDisconnectListener(GDBusConnection* conn, const gchar* sender, const gchar* path, const gchar* iface, const gchar* name, GVariant* param, gpointer userData)
+{
+ conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+
+ char* disconnectName;
+ g_variant_get_child(param, 0, "&s", &disconnectName);
+
+ if (!strcmp(disconnectName, _requestObj->getSender())) {
+ _D("Detected the dbus disconnection.");
+ stop_request(_requestObj);
+
+ std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+ iter = dbus_listener_info_map.find(_requestObj->getSender());
+ if (iter != dbus_listener_info_map.end()) {
+ guint listener_id = reinterpret_cast<guint>(iter->second);
+ dbus_listener_info_map.erase(iter);
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+ g_dbus_connection_signal_unsubscribe(conn, listener_id);
+ _D("Unsubscribe the dbus signal. id = %d", listener_id);
+
+ conv::AppCommServiceInfo *svcInfo = reinterpret_cast<conv::AppCommServiceInfo*>(_requestObj->getServiceInfo());
+ if (svcInfo->registeredRequest != NULL) {
+ delete svcInfo->registeredRequest;
+ svcInfo->registeredRequest = NULL;
+ }
+ if (_requestObj != NULL) {
+ delete _requestObj;
+ _requestObj = NULL;
+ }
+ }
+ } else {
+ _E("Not found dbus disconnect listener.");
+ }
+}
+
+static void registDbusDisconnectListener(conv::Request* requestObj)
+{
+ std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+ iter = dbus_listener_info_map.find(requestObj->getSender());
+ if (iter != dbus_listener_info_map.end()) {
+ guint listener_id = reinterpret_cast<guint>(iter->second);
+ dbus_listener_info_map.erase(iter);
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(requestObj->getInvocation());
+ g_dbus_connection_signal_unsubscribe(conn, listener_id);
+ _D("Unsubscribe the dbus signal. id = %d", listener_id);
+ }
+ conv::Request *_requestObj = requestObj->clone();
+ _requestObj->setIsConnect(true);
+
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+ guint listener_id = g_dbus_connection_signal_subscribe(conn, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus",
+ _requestObj->getSender(), G_DBUS_SIGNAL_FLAGS_NONE, _dbusDisconnectListener, _requestObj, _dbusDisconnectListenerFreeCallback);
+
+ if (listener_id == 0) {
+ _E("Dbus signal listener registration failed.");
+ delete _requestObj;
+ _requestObj = NULL;
+ } else {
+ _D("Subscribe the dbus signal. id = %d", listener_id);
+ dbus_listener_info_map[_requestObj->getSender()] = listener_id;
+ }
+}
+
int conv::AppCommServiceProvider::startRequest(Request* requestObj)
{
_D("communcation/start requested");
svcInfo->applicationInstanceList.push_back(appInfo);
}
+
+ registDbusDisconnectListener(requestObj);
+
_D("connect requested");
return CONV_ERROR_NONE;
int conv::AppCommServiceProvider::stopRequest(Request* requestObj)
{
_D("communcation/stop requested");
- AppCommServiceInfo *svcInfo = reinterpret_cast<AppCommServiceInfo*>(requestObj->getServiceInfo());
+ return stop_request(requestObj);
+}
- Json channel;
+static int stop_request(conv::Request* requestObj)
+{
+ conv::AppCommServiceInfo *svcInfo = reinterpret_cast<conv::AppCommServiceInfo*>(requestObj->getServiceInfo());
+
+ conv::Json channel;
requestObj->getChannelFromDescription(&channel);
string uri, channelId;
IF_FAIL_RETURN_TAG(!uri.empty() || svcInfo->isLocal, CONV_ERROR_INVALID_PARAMETER, _E, "uri is empty");
IF_FAIL_RETURN_TAG(!channelId.empty(), CONV_ERROR_INVALID_PARAMETER, _E, "channelId is empty");
- for (ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
+ for (conv::ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
_D("%s, %s", (*iter)->uri.c_str(), (*iter)->channelId.c_str());
if ( (*iter) != NULL && !(*iter)->uri.compare(uri) && !(*iter)->channelId.compare(channelId) ) {
if ( (*iter)->state == APP_COMM_STATE_STARTED ) {
_D("stopping the application");
- AppCommServiceApplication *appInfo = *iter;
+ conv::AppCommServiceApplication *appInfo = *iter;
_D("COMMUNCATION_STOP : uri : %s, channel_id : %s", uri.c_str(), channelId.c_str());
return CONV_ERROR_NONE;
}
-
int conv::AppCommServiceProvider::readRequest(Request* requestObj)
{
_D("communcation/get requested");
#include "RemoteAppControlServiceProvider.h"
#include "../ClientManager.h"
#include "../Util.h"
+#include "../Server.h"
#if defined(_D2D_INTERNAL_ACL_)
#include "../access_control/ACLManager.h"
static std::map<long long, app_control_cb_info_s> app_control_cb_map;
static std::map<int, response_cb_info_s> response_cb_map;
+static std::map<std::string, guint> dbus_listener_info_map;
static void vconf_update_cb(keynode_t *node, void* user_data)
{
{
app_control_cb_map.clear();
response_cb_map.clear();
+ dbus_listener_info_map.clear();
#if !defined(_D2D_INTERNAL_ACL_)
int error = rdm_deinit();
_send_response(cb_info.request_handle, rep, IOTCON_RESPONSE_OK);
_D("Response sent");
+ iotcon_attributes_destroy(attributes);
+ iotcon_representation_destroy(rep);
+
bundle_free(p_bundle);
bundle_free(p_bundle_request);
app_control_cb_map.erase(find_iter);
iotcon_resource_types_add(resource_types, __resourceType.c_str());
error = iotcon_resource_interfaces_create(&resource_ifaces);
-
- IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
+ IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
-
error = iotcon_resource_create(CONV_URI_REMOTE_APP_CONTROL, resource_types, resource_ifaces, properties, __iotcon_request_cb, NULL, &iotcon_resource);
- IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource creation failed");
+ IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "resource creation failed");
+ _D("RemoteAppControlServiceProvider init done");
+CATCH:
iotcon_resource_types_destroy(resource_types);
iotcon_resource_interfaces_destroy(resource_ifaces);
+ IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
- _D("RemoteAppControlServiceProvider init done");
} else {
_D("RemoteAppControlServiceProvider is already initiated");
}
}
#endif
+static int stop_request(conv::Request* requestObj);
+
+static void _dbusDisconnectListenerFreeCallback(gpointer userData)
+{
+ conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+ if (_requestObj != NULL) {
+ delete _requestObj;
+ _requestObj = NULL;
+ }
+}
+
+static void _dbusDisconnectListener(GDBusConnection* conn, const gchar* sender, const gchar* path, const gchar* iface, const gchar* name, GVariant* param, gpointer userData)
+{
+ conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+
+ char* disconnectName;
+ g_variant_get_child(param, 0, "&s", &disconnectName);
+
+ if (!strcmp(disconnectName, _requestObj->getSender())) {
+ _D("Detected the dbus disconnection.");
+ stop_request(_requestObj);
+
+ std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+ iter = dbus_listener_info_map.find(_requestObj->getSender());
+
+ if (iter != dbus_listener_info_map.end()) {
+
+ guint listener_id = reinterpret_cast<guint>(iter->second);
+ dbus_listener_info_map.erase(iter);
+
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+ g_dbus_connection_signal_unsubscribe(conn, listener_id);
+ _D("Delete dbus disconnect listener.");
+
+ conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(_requestObj->getServiceInfo());
+ if (svcInfo->registeredRequest != NULL) {
+ delete svcInfo->registeredRequest;
+ svcInfo->registeredRequest = NULL;
+ }
+ if (_requestObj != NULL) {
+ delete _requestObj;
+ _requestObj = NULL;
+ }
+ }
+ } else {
+ _D("Not found dbus disconnect listener.");
+ }
+}
+
+static void registDbusDisconnectListener(conv::Request* requestObj)
+{
+ std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+ iter = dbus_listener_info_map.find(requestObj->getSender());
+
+ if (iter != dbus_listener_info_map.end()) {
+
+ guint listener_id = reinterpret_cast<guint>(iter->second);
+ dbus_listener_info_map.erase(iter);
+
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(requestObj->getInvocation());
+ g_dbus_connection_signal_unsubscribe(conn, listener_id);
+ _D("Delete dbus disconnect listener.");
+ }
+
+ conv::Request *_requestObj = requestObj->clone();
+ _requestObj->setIsConnect(true);
+
+ GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+
+ guint listener_id = g_dbus_connection_signal_subscribe(conn, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus",
+ _requestObj->getSender(), G_DBUS_SIGNAL_FLAGS_NONE, _dbusDisconnectListener, _requestObj, _dbusDisconnectListenerFreeCallback);
+
+ if (listener_id == 0) {
+ _E("Dbus signal listener registration failed.");
+ delete _requestObj;
+ _requestObj = NULL;
+ } else {
+ dbus_listener_info_map[_requestObj->getSender()] = listener_id;
+ _D("Subscribe the dbus signal. id = %d", listener_id);
+ }
+}
+
int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
{
_D("communcation/start requested");
iotcon_resource_types_add(resource_types, svcInfo->iotconInfoObj.resourceType.c_str());
error = iotcon_resource_interfaces_create(&resource_ifaces);
-
- IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
+ IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
&(svcInfo->iotconInfoObj.iotconResourceHandle));
_D("remote resource created : %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
+ IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
- IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
+ registDbusDisconnectListener(requestObj);
+CATCH:
iotcon_resource_types_destroy(resource_types);
iotcon_resource_interfaces_destroy(resource_ifaces);
+ IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
//send message for access request
iotcon_representation_h representation;
int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
{
_D("communcation/stop requested");
- Json result;
+ return stop_request(requestObj);
+}
- RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
+static int stop_request(conv::Request* requestObj)
+{
+ conv::Json result;
+ conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
_D("not even started");
iotcon_remote_resource_destroy(svcInfo->iotconInfoObj.iotconResourceHandle);
svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
- sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
+ sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
return CONV_ERROR_NONE;
}
it->second = cbInfo;
}
}
-
delete svcInfo->registeredRequest;
}
svcInfo->registeredRequest = requestObj;
it->second = cbInfo;
}
}
-
delete svcInfo->registeredRequest;
svcInfo->registeredRequest = NULL;
requestObj->reply(CONV_ERROR_NONE);
return CONV_ERROR_NONE;
}
-
int conv::RemoteAppControlServiceProvider::loadServiceInfo(Request* requestObj)
{
string client;
return;
}
+ conv_error_e conv_error;
_conv_service_callback_info* callback_info = it->second;
conv_service_h service_handle = new(std::nothrow) _conv_service_handle();
if (!channel.isEmpty()) {
channel_handle = new(std::nothrow) _conv_channel_handle();
- IF_FAIL_VOID_TAG(channel_handle, _E, "Memory allocation failed");
+ IF_FAIL_CATCH_TAG(channel_handle, _E, "Memory allocation failed");
channel_handle->jchannel = channel;
}
if (!payload.isEmpty() || binary_length > 0) {
payload_handle = new(std::nothrow) _conv_payload_handle();
- IF_FAIL_VOID_TAG(payload_handle, _E, "Memory allocation failed");
+ IF_FAIL_CATCH_TAG(payload_handle, _E, "Memory allocation failed");
payload_handle->jpayload = payload;
payload_handle->binary_length = binary_length;
payload_handle->binary = binary;
}
- conv_error_e conv_error = (conv_error_e)error;
+ conv_error = (conv_error_e)error;
callback_info->cb(service_handle, channel_handle, conv_error, payload_handle, callback_info->user_data);
+CATCH:
if (payload_handle) {
delete payload_handle;
}
_conv_service_callback_info* callback_info = it->second;
delete callback_info;
- callback_map.erase(it);
+ callback_map.erase(it);
return CONV_ERROR_NONE;
}