// Copyright 2015 by Artem Prilutskiy #include "PatchCordProxy.h" #include #include #include #include #define INTERFACE_NAME "me.burnaway.BrandMeister" #define SERVICE_NAME INTERFACE_NAME #define OBJECT_PATH "/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 PatchCordProxy::PatchCordProxy(uint32_t network, uint32_t link) { banner = NULL; number = link; asprintf(&path, OBJECT_PATH "/%d", network); connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); } PatchCordProxy::~PatchCordProxy() { dbus_connection_unref(connection); free(banner); free(path); } void PatchCordProxy::setTalkerID(uint32_t value) { getContextBanner(); setVendorSpecificValue(VALUE_CORD_OUTGOING_SOURCE_ID, value); } uint32_t PatchCordProxy::getTalkerID() { getContextBanner(); return getVendorSpecificValue(VALUE_CORD_INCOMING_SOURCE_ID); } void PatchCordProxy::getContextBanner() { DBusMessage* message = dbus_message_new_method_call( SERVICE_NAME, 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::setVendorSpecificValue(uint32_t key, uint32_t value) { DBusMessage* message = dbus_message_new_method_call( SERVICE_NAME, path, INTERFACE_NAME, "setVendorSpecificValue"); 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::getVendorSpecificValue(uint32_t key) { DBusMessage* message = dbus_message_new_method_call( SERVICE_NAME, 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; }