bool DBUSCommunicator::start()
{
- LOG_DEBUG("DBUSCommunicator", "Starting up dbus connector");
-
+ LOG_DEBUG("DBUSCommunicator", "Starting up dbus connector");
+ bool result = true;
g_pDbusMessage = new DBUSMessageHandler();
LOG_DEBUG("DBUSCommunicator","registering for dbus path " << DBUS_SERVICE_OBJECT_PATH);
bool registered = g_pDbusMessage->registerPathFunction(DBUSCommunicator::processMessageFunc,
- DBUSCommunicator::unregisterMessageFunc,
- this);
+ DBUSCommunicator::unregisterMessageFunc,
+ this);
if (!registered)
{
+
LOG_ERROR("DBUSCommunicator","Register Message Callbacks failed");
- exit(-1);
+ result = false;
+ }
+ else
+ {
+ registered = g_pDbusMessage->registerMessageFilter(DBUSCommunicator::processMessageFunc,this);
+ if (!registered)
+ {
+
+ LOG_ERROR("DBUSCommunicator","Register Message Filter failed");
+ result = false;
+ }
}
-
LOG_INFO("DBUSCommunicator", "Started dbus connector");
- return true;
+ return result;
}
void DBUSCommunicator::stop()
void DBUSCommunicator::ServiceConnect(DBusConnection* conn, DBusMessage* msg)
{
- (void)conn; // TODO: remove, only prevents warning
g_pDbusMessage->initReceive(msg);
u_int32_t processId = g_pDbusMessage->getUInt();
char* owner = strdup(dbus_message_get_sender(msg));
m_executor->addApplicationReference(new IApplicationReference(owner,processId));
+ AddClientWatch(conn,owner);
g_pDbusMessage->initReply(msg);
g_pDbusMessage->closeReply();
}
-
void DBUSCommunicator::ServiceDisconnect(DBusConnection* conn, DBusMessage* msg)
{
IApplicationReference* reference = NULL;
g_pDbusMessage->initReceive(msg);
char* owner = strdup(dbus_message_get_sender(msg));
u_int32_t processId = g_pDbusMessage->getUInt();
- ApplicationReferenceMapIterator iter = m_executor->getApplicationReferenceMap()->find(IApplicationReference::generateApplicationHash(owner));
- ApplicationReferenceMapIterator iterEnd = m_executor->getApplicationReferenceMap()->end();
-
- if ( iter != iterEnd )
- {
- m_executor->removeApplicationReference((*iter).second);
- }
-
+ RemoveApplicationReference(owner);
g_pDbusMessage->initReply(msg);
g_pDbusMessage->closeReply();
}
}
}
+void DBUSCommunicator::RemoveApplicationReference(char* owner)
+{
+ ApplicationReferenceMapIterator iter = m_executor->getApplicationReferenceMap()->find(IApplicationReference::generateApplicationHash(owner));
+ ApplicationReferenceMapIterator iterEnd = m_executor->getApplicationReferenceMap()->end();
+
+ if ( iter != iterEnd )
+ {
+ m_executor->removeApplicationReference((*iter).second);
+ }
+}
+
+
+void DBUSCommunicator::AddClientWatch(DBusConnection *conn, char* sender)
+{
+ DBusError err;
+ char rule[1024];
+ sprintf(rule,"type='signal',sender='%s',interface='%s',member='%s',arg0='%s'",DBUS_INTERFACE_DBUS,DBUS_INTERFACE_DBUS,"NameOwnerChanged",sender);
+
+ dbus_bus_add_match(conn,rule,&err);
+ if (dbus_error_is_set(&err))
+ {
+ LOG_ERROR("DBUSCommunicator", "Could not add client watch "<< err.message);
+ dbus_error_free(&err);
+ }
+}
+
DBusHandlerResult DBUSCommunicator::delegateMessage(DBusConnection* conn, DBusMessage* msg)
{
DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
{
- LOG_DEBUG("DBUSCommunicator", "Introspection called");
+ LOG_DEBUG("DBUSCommunicator", "Introspection called");
DBUSIntrospection introspectionString(manager_methods);
introspectionString.process(conn, msg);
g_pDbusMessage->setConnection(conn);
found = true; // TODO: always true
}
-
+
+ if (dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
+ {
+ char *name, *oldName, *newName;
+ LOG_DEBUG("DBUSCommunicator","NameOwner Changed detected ");
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &oldName,
+ DBUS_TYPE_STRING, &newName,
+ DBUS_TYPE_INVALID))
+ {
+ LOG_WARNING("DBUSCommunicator","Invalid arguments for NameOwnerChanged signal");
+ } else if ( *newName == '\0' )
+ {
+ LOG_DEBUG("DBUSCommunicator","Client Disconnect detected " << name);
+ RemoveApplicationReference(name);
+ }
+ }
if (!found)
{
result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
char* useSessionBus = getenv("LM_USE_SESSION_BUS");
if ( NULL != useSessionBus && strcmp(useSessionBus,"enable") == 0 )
{
- LOG_INFO("DBUSCommunicator", "Using Session Bus");
+ LOG_INFO("DBUSMessageHandler", "Using Session Bus");
m_pConnection = dbus_bus_get(DBUS_BUS_SESSION, &m_err);
}
else
{
- LOG_INFO("DBUSCommunicator", "Using System Bus");
+ LOG_INFO("DBUSMessageHandler", "Using System Bus");
m_pConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &m_err);
}
if (dbus_error_is_set(&m_err))
{
- LOG_ERROR("DBUSCommunicator","Connection error");
+ LOG_ERROR("DBUSMessageHandler","Connection error");
dbus_error_free(&m_err);
}
if (NULL == m_pConnection)
{
- LOG_ERROR("DBUSCommunicator","Connection is null");
+ LOG_ERROR("DBUSMessageHandler","Connection is null");
exit(1);
}
if (dbus_error_is_set(&m_err))
{
- LOG_ERROR("DBUSCommunicator", "Name Error "<< m_err.message);
+ LOG_ERROR("DBUSMessageHandler", "Name Error "<< m_err.message);
dbus_error_free(&m_err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret)
{
- LOG_ERROR("DBUSCommunicator", "Not Primary Owner "<< ret);
+ LOG_ERROR("DBUSMessageHandler", "Not Primary Owner "<< ret);
exit(1);
}
}
bool errorset = dbus_error_is_set(&err);
if (errorset)
{
- LOG_ERROR("DBUSCommunicator","there was an dbus error");
+ LOG_ERROR("DBUSMessageHandler","there was an dbus error");
}
dbus_connection_unregister_object_path(m_pConnection,DBUS_SERVICE_OBJECT_PATH);
- LOG_INFO("DBUSCommunicator","Ask about owner name");
+ LOG_INFO("DBUSMessageHandler","Ask about owner name");
dbus_bus_name_has_owner(m_pConnection, DBUS_SERVICE_PREFIX, &err);
errorset = dbus_error_is_set(&err);
if (errorset)
{
- LOG_ERROR("DBUSCommunicator","there was an dbus error");
+ LOG_ERROR("DBUSMessageHandler","there was an dbus error");
}
dbus_error_init(&err);
dbus_bus_release_name(m_pConnection, DBUS_SERVICE_PREFIX, &err);
}
+bool DBUSMessageHandler::registerMessageFilter( DBusHandleMessageFunction fMessageFunc,
+ void* comInstance )
+{
+ bool result = true;
+ if ( !dbus_connection_add_filter ( m_pConnection , fMessageFunc, comInstance, NULL) )
+ {
+ result = false;
+ }
+ return result;
+}
+
+
bool DBUSMessageHandler::registerPathFunction( DBusObjectPathMessageFunction fMessageFunc,
DBusObjectPathUnregisterFunction fUnregisterFunc,
void* comInstance)
void DBUSMessageHandler::initReceive(DBusMessage* msg)
{
- LOG_DEBUG("DBUSCommunicator","Message " << dbus_message_get_member(msg) << " was sent by " << dbus_message_get_sender(msg) );
+ LOG_DEBUG("DBUSMessageHandler","Message " << dbus_message_get_member(msg) << " was sent by " << dbus_message_get_sender(msg) );
if (!dbus_message_iter_init(msg, &m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Message has no arguments!");
+ LOG_ERROR("DBUSMessageHandler", "Message has no arguments!");
}
}
// send the reply && flush the connection
if (!dbus_connection_send(m_pConnection, m_pReply, &m_serial))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
- LOG_DEBUG("DBUSCommunicator", "sending reply");
+ LOG_DEBUG("DBUSMessageHandler", "sending reply");
dbus_connection_flush(m_pConnection);
// free the reply
// send the reply && flush the connection
if (!dbus_connection_send(m_pConnection, m_pReply, &m_serial))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
- LOG_INFO("DBUSCommunicator", "sending reply with error");
+ LOG_INFO("DBUSMessageHandler", "sending reply with error");
dbus_connection_flush(m_pConnection);
// free the reply
if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not string!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not string!");
}
else
{
if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not bool!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not bool!");
}
else
{
if (DBUS_TYPE_BYTE != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not byte!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not byte!");
}
else
{
if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not uint32!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not uint32!");
}
else
{
if (DBUS_TYPE_DOUBLE != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator","Argument is not double!");
+ LOG_ERROR("DBUSMessageHandler","Argument is not double!");
}
else
{
{
if (DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator","Argument is not an array!");
+ LOG_ERROR("DBUSMessageHandler","Argument is not an array!");
return;
}
{
if (DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type(&m_MessageIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not an array!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not an array!");
return;
}
{
if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&arrayIter))
{
- LOG_ERROR("DBUSCommunicator", "Argument is not an string!");
+ LOG_ERROR("DBUSMessageHandler", "Argument is not an string!");
}
char* param;
dbus_message_iter_get_basic(&arrayIter, ¶m);
{
if (!dbus_message_iter_append_basic(&m_MessageIter, DBUS_TYPE_BOOLEAN, &toAppend))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
}
{
if (!dbus_message_iter_append_basic(&m_MessageIter, DBUS_TYPE_UINT32, &toAppend))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
}
{
if (!dbus_message_iter_append_basic(&m_MessageIter, DBUS_TYPE_DOUBLE, &toAppend))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
}
{
if (!dbus_message_iter_append_basic(&m_MessageIter, DBUS_TYPE_BYTE, &toAppend))
{
- LOG_ERROR("DBUSCommunicator", "Out Of Memory!");
+ LOG_ERROR("DBUSMessageHandler", "Out Of Memory!");
exit(1);
}
}