3
Fork 0
AutoPatch/SVXLink/echolink/PatchCord.cpp
2017-12-23 09:02:26 +03:00

305 lines
7.7 KiB
C++

// Copyright 2015-2016 by Artem Prilutskiy
#include "PatchCord.h"
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <stdio.h>
#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
PatchCord::PatchCord(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);
}
PatchCord::~PatchCord()
{
dbus_connection_unref(connection);
free(banner);
free(name);
}
void PatchCord::setTalkerID(uint32_t value)
{
getContextBanner();
setSpecificValue(VALUE_CORD_OUTGOING_SOURCE_ID, value);
}
uint32_t PatchCord::getTalkerID()
{
getContextBanner();
return getSpecificValue(VALUE_CORD_INCOMING_SOURCE_ID);
}
void PatchCord::setTalkerAlias(const char* value)
{
char* buffer;
asprintf(&buffer, "set alias %s", value);
getContextBanner();
invokeCommand(buffer);
free(buffer);
}
void PatchCord::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 PatchCord::invokeCommand(const char* command)
{
DBusMessage* message = dbus_message_new_method_call(
name, OBJECT_PATH, INTERFACE_NAME, "invokeCommand");
dbus_message_append_args(message,
DBUS_TYPE_STRING, &banner,
DBUS_TYPE_STRING, &command,
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;
}
void PatchCord::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 PatchCord::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;
}
uint32_t PatchCord::getPrivateIDForCall(const char* call)
{
DBusMessage* message = dbus_message_new_method_call(
name, OBJECT_PATH, INTERFACE_NAME, "getStationData");
dbus_message_append_args(message,
DBUS_TYPE_STRING, &call,
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);
dbus_uint32_t number;
dbus_uint32_t algorithm;
dbus_uint32_t key;
dbus_uint32_t interval;
dbus_uint32_t capabilities;
dbus_uint32_t station;
const char* language;
const char* call;
const char* text;
const char* symbol;
if (dbus_message_get_args(message, NULL,
DBUS_TYPE_UINT32, &number,
DBUS_TYPE_UINT32, &algorithm,
DBUS_TYPE_UINT32, &key,
DBUS_TYPE_UINT32, &interval,
DBUS_TYPE_UINT32, &capabilities,
DBUS_TYPE_STRING, &language,
DBUS_TYPE_UINT32, &station,
DBUS_TYPE_STRING, &call,
DBUS_TYPE_STRING, &text,
DBUS_TYPE_STRING, &symbol,
DBUS_TYPE_INVALID))
value = number;
dbus_pending_call_unref(pending);
}
dbus_message_unref(message);
return value;
}
bool PatchCord::getCredentialsForID(uint32_t number, char* call, char* text)
{
DBusMessage* message = dbus_message_new_method_call(
name, OBJECT_PATH, INTERFACE_NAME, "getStationData");
dbus_message_append_args(message,
DBUS_TYPE_UINT32, &number,
DBUS_TYPE_INVALID);
bool result = false;
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_uint32_t number;
dbus_uint32_t algorithm;
dbus_uint32_t key;
dbus_uint32_t interval;
dbus_uint32_t capabilities;
dbus_uint32_t station;
const char* language;
const char* value1;
const char* value2;
const char* symbol;
if (dbus_message_get_args(message, NULL,
DBUS_TYPE_UINT32, &number,
DBUS_TYPE_UINT32, &algorithm,
DBUS_TYPE_UINT32, &key,
DBUS_TYPE_UINT32, &interval,
DBUS_TYPE_UINT32, &capabilities,
DBUS_TYPE_STRING, &language,
DBUS_TYPE_UINT32, &station,
DBUS_TYPE_STRING, &value1,
DBUS_TYPE_STRING, &value2,
DBUS_TYPE_STRING, &symbol,
DBUS_TYPE_INVALID))
{
strcpy(call, value1);
strcpy(text, value2);
result = true;
}
dbus_pending_call_unref(pending);
}
dbus_message_unref(message);
return result;
}