// Copyright 2015-2016 by Artem Prilutskiy #include "PatchCordProxy.h" #include #include #include #include #define SERVICE_NAME "me.burnaway.BrandMeister" #define OBJECT_PATH "/me/burnaway/BrandMeister" #define INTERFACE_NAME "me.burnaway.BrandMeister" // From AutoPatch.cpp #define AUTOPATCH_LINK_NAME "AutoPatch" // From PatchCord.h #define VALUE_CORD_OUTGOING_SOURCE_ID 1 #define VALUE_CORD_INCOMING_SOURCE_ID 4 #define VALUE_CORD_TALKER_ALIAS 7 PatchCordProxy::PatchCordProxy(uint32_t network, uint32_t link) { banner = NULL; number = link; asprintf(&name, SERVICE_NAME ".N%d", network); connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); } PatchCordProxy::~PatchCordProxy() { dbus_connection_unref(connection); free(banner); free(name); } void PatchCordProxy::setTalkerID(uint32_t value) { getContextBanner(); setSpecificValue(VALUE_CORD_OUTGOING_SOURCE_ID, value); } uint32_t PatchCordProxy::getTalkerID() { getContextBanner(); return getSpecificValue(VALUE_CORD_INCOMING_SOURCE_ID); } void PatchCordProxy::setTalkerAlias(const char* value) { size_t length = strlen(value); const uint32_t* data = (const uint32_t*)value; size_t index = VALUE_CORD_TALKER_ALIAS; size_t count = (length / sizeof(uint32_t)) + ((length % sizeof(uint32_t)) > 0); getContextBanner(); while (count > 0) { setSpecificValue(index, *data); count --; index ++; data ++; } } void PatchCordProxy::getContextBanner() { DBusMessage* message = dbus_message_new_method_call( name, OBJECT_PATH, INTERFACE_NAME, "getContextList"); const char* name = AUTOPATCH_LINK_NAME; dbus_message_append_args(message, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &number, DBUS_TYPE_INVALID); DBusPendingCall* pending; if (dbus_connection_send_with_reply(connection, message, &pending, -1)) { dbus_connection_flush(connection); dbus_message_unref(message); dbus_pending_call_block(pending); message = dbus_pending_call_steal_reply(pending); char** array; int count; if ((dbus_message_get_args(message, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, &count, DBUS_TYPE_INVALID)) && (count > 0)) { free(banner); banner = strdup(*array); dbus_free_string_array(array); } dbus_pending_call_unref(pending); } dbus_message_unref(message); } void PatchCordProxy::setSpecificValue(uint32_t key, uint32_t value) { DBusMessage* message = dbus_message_new_method_call( name, OBJECT_PATH, INTERFACE_NAME, "setSpecificValue"); dbus_message_append_args(message, DBUS_TYPE_STRING, &banner, DBUS_TYPE_UINT32, &key, DBUS_TYPE_UINT32, &value, DBUS_TYPE_INVALID); DBusPendingCall* pending; if (dbus_connection_send_with_reply(connection, message, &pending, -1)) { dbus_connection_flush(connection); dbus_message_unref(message); dbus_pending_call_block(pending); message = dbus_pending_call_steal_reply(pending); dbus_pending_call_unref(pending); } dbus_message_unref(message); // Each call of dbus_message_unref removes banner from the heap banner = NULL; } uint32_t PatchCordProxy::getSpecificValue(uint32_t key) { DBusMessage* message = dbus_message_new_method_call( name, OBJECT_PATH, INTERFACE_NAME, "getContextData"); dbus_message_append_args(message, DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID); uint32_t value = 0; DBusPendingCall* pending; if (dbus_connection_send_with_reply(connection, message, &pending, -1)) { dbus_connection_flush(connection); dbus_message_unref(message); dbus_pending_call_block(pending); message = dbus_pending_call_steal_reply(pending); const char* name; const char* address; dbus_uint32_t type; dbus_uint32_t state; dbus_uint32_t number; dbus_uint32_t* values; int count; if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &banner, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &type, DBUS_TYPE_UINT32, &number, DBUS_TYPE_STRING, &address, DBUS_TYPE_UINT32, &state, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &values, &count, DBUS_TYPE_INVALID)) value = values[key]; dbus_pending_call_unref(pending); } dbus_message_unref(message); // Each call of dbus_message_unref removes banner from the heap banner = NULL; return value; }