Moved from MySQL to new set of D-BUS methods to retreive station call / ID
This commit is contained in:
parent
f9bcb35800
commit
b99aeaa581
17 changed files with 294 additions and 424 deletions
|
@ -4,8 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include <pcre.h>
|
||||
|
||||
#include "PatchCordProxy.h"
|
||||
#include "UserDataStore.h"
|
||||
#include "PatchCord.h"
|
||||
|
||||
#define VECTORS_COUNT 16
|
||||
#define DEFAULT_USER_NUMBER 1
|
||||
|
@ -17,7 +16,7 @@ int main(int argc, const char* argv[])
|
|||
{
|
||||
printf("\n");
|
||||
printf("CallCapture for BrandMeister DMR Master Server\n");
|
||||
printf("Copyright 2015 Artem Prilutskiy (R3ABM, cyanide.burnout@gmail.com)\n");
|
||||
printf("Copyright 2015-2017 Artem Prilutskiy (R3ABM, cyanide.burnout@gmail.com)\n");
|
||||
printf("\n");
|
||||
|
||||
// Start up
|
||||
|
@ -25,7 +24,6 @@ int main(int argc, const char* argv[])
|
|||
struct option options[] =
|
||||
{
|
||||
{ "expression", required_argument, NULL, 'e' },
|
||||
{ "connection", required_argument, NULL, 'c' },
|
||||
{ "identity", required_argument, NULL, 'i' },
|
||||
{ "network", required_argument, NULL, 'n' },
|
||||
{ "unknown", required_argument, NULL, 'u' },
|
||||
|
@ -34,7 +32,6 @@ int main(int argc, const char* argv[])
|
|||
};
|
||||
|
||||
pcre* expression = NULL;
|
||||
const char* file = NULL;
|
||||
uint32_t network = 0;
|
||||
uint32_t unknown = DEFAULT_USER_NUMBER;
|
||||
uint32_t link = DEFAULT_LINK_NUMBER;
|
||||
|
@ -43,17 +40,13 @@ int main(int argc, const char* argv[])
|
|||
const char* error = NULL;
|
||||
|
||||
int selection = 0;
|
||||
while ((selection = getopt_long(argc, const_cast<char* const*>(argv), "e:c:u:n:l:", options, NULL)) != EOF)
|
||||
while ((selection = getopt_long(argc, const_cast<char* const*>(argv), "e:u:n:l:", options, NULL)) != EOF)
|
||||
switch (selection)
|
||||
{
|
||||
case 'e':
|
||||
expression = pcre_compile(optarg, 0, &error, &position, NULL);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
file = optarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
openlog(optarg, 0, LOG_USER);
|
||||
break;
|
||||
|
@ -79,13 +72,11 @@ int main(int argc, const char* argv[])
|
|||
}
|
||||
|
||||
if ((expression == NULL) ||
|
||||
(network == 0) ||
|
||||
(file == NULL))
|
||||
(network == 0))
|
||||
{
|
||||
printf(
|
||||
"Usage: %s\n"
|
||||
" --expression <regular expression>\n"
|
||||
" --connection <path to configuration file>\n"
|
||||
" [--unknown <ID for unknown call-signs>]\n"
|
||||
" --network <network number>\n"
|
||||
" --link <link number>\n"
|
||||
|
@ -100,8 +91,7 @@ int main(int argc, const char* argv[])
|
|||
|
||||
// Main
|
||||
|
||||
UserDataStore store(file);
|
||||
PatchCordProxy proxy(network, link);
|
||||
PatchCord proxy(network, link);
|
||||
|
||||
char* line = NULL;
|
||||
size_t length = 0;
|
||||
|
@ -122,7 +112,7 @@ int main(int argc, const char* argv[])
|
|||
pcre_get_named_substring(expression, line, vectors, count, "call", &call);
|
||||
pcre_get_named_substring(expression, line, vectors, count, "alias", &alias);
|
||||
|
||||
uint32_t number = store.getPrivateIDForCall(call);
|
||||
uint32_t number = proxy.getPrivateIDForCall(call); // This method moved from MySQL connector to proxt
|
||||
|
||||
if (number == 0)
|
||||
number = unknown;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
OBJECTS = \
|
||||
PatchCordProxy.o \
|
||||
UserDataStore.o \
|
||||
PatchCord.o \
|
||||
CallCapture.o
|
||||
|
||||
LIBRARIES = \
|
||||
mysqlclient \
|
||||
pcre
|
||||
|
||||
DEPENDENCIES = \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2015-2016 by Artem Prilutskiy
|
||||
|
||||
#include "PatchCordProxy.h"
|
||||
#include "PatchCord.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
#define VALUE_CORD_INCOMING_SOURCE_ID 4
|
||||
#define VALUE_CORD_TALKER_ALIAS 7
|
||||
|
||||
PatchCordProxy::PatchCordProxy(uint32_t network, uint32_t link)
|
||||
PatchCord::PatchCord(uint32_t network, uint32_t link)
|
||||
{
|
||||
banner = NULL;
|
||||
number = link;
|
||||
|
@ -27,26 +27,26 @@ PatchCordProxy::PatchCordProxy(uint32_t network, uint32_t link)
|
|||
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
|
||||
}
|
||||
|
||||
PatchCordProxy::~PatchCordProxy()
|
||||
PatchCord::~PatchCord()
|
||||
{
|
||||
dbus_connection_unref(connection);
|
||||
free(banner);
|
||||
free(name);
|
||||
}
|
||||
|
||||
void PatchCordProxy::setTalkerID(uint32_t value)
|
||||
void PatchCord::setTalkerID(uint32_t value)
|
||||
{
|
||||
getContextBanner();
|
||||
setSpecificValue(VALUE_CORD_OUTGOING_SOURCE_ID, value);
|
||||
}
|
||||
|
||||
uint32_t PatchCordProxy::getTalkerID()
|
||||
uint32_t PatchCord::getTalkerID()
|
||||
{
|
||||
getContextBanner();
|
||||
return getSpecificValue(VALUE_CORD_INCOMING_SOURCE_ID);
|
||||
}
|
||||
|
||||
void PatchCordProxy::setTalkerAlias(const char* value)
|
||||
void PatchCord::setTalkerAlias(const char* value)
|
||||
{
|
||||
char* buffer;
|
||||
asprintf(&buffer, "set alias %s", value);
|
||||
|
@ -57,7 +57,7 @@ void PatchCordProxy::setTalkerAlias(const char* value)
|
|||
free(buffer);
|
||||
}
|
||||
|
||||
void PatchCordProxy::getContextBanner()
|
||||
void PatchCord::getContextBanner()
|
||||
{
|
||||
DBusMessage* message = dbus_message_new_method_call(
|
||||
name, OBJECT_PATH, INTERFACE_NAME, "getContextList");
|
||||
|
@ -92,7 +92,7 @@ void PatchCordProxy::getContextBanner()
|
|||
dbus_message_unref(message);
|
||||
}
|
||||
|
||||
void PatchCordProxy::invokeCommand(const char* command)
|
||||
void PatchCord::invokeCommand(const char* command)
|
||||
{
|
||||
DBusMessage* message = dbus_message_new_method_call(
|
||||
name, OBJECT_PATH, INTERFACE_NAME, "invokeCommand");
|
||||
|
@ -117,7 +117,7 @@ void PatchCordProxy::invokeCommand(const char* command)
|
|||
banner = NULL;
|
||||
}
|
||||
|
||||
void PatchCordProxy::setSpecificValue(uint32_t key, uint32_t value)
|
||||
void PatchCord::setSpecificValue(uint32_t key, uint32_t value)
|
||||
{
|
||||
DBusMessage* message = dbus_message_new_method_call(
|
||||
name, OBJECT_PATH, INTERFACE_NAME, "setSpecificValue");
|
||||
|
@ -143,7 +143,7 @@ void PatchCordProxy::setSpecificValue(uint32_t key, uint32_t value)
|
|||
banner = NULL;
|
||||
}
|
||||
|
||||
uint32_t PatchCordProxy::getSpecificValue(uint32_t key)
|
||||
uint32_t PatchCord::getSpecificValue(uint32_t key)
|
||||
{
|
||||
DBusMessage* message = dbus_message_new_method_call(
|
||||
name, OBJECT_PATH, INTERFACE_NAME, "getContextData");
|
||||
|
@ -160,7 +160,9 @@ uint32_t PatchCordProxy::getSpecificValue(uint32_t key)
|
|||
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;
|
||||
|
@ -168,6 +170,7 @@ uint32_t PatchCordProxy::getSpecificValue(uint32_t key)
|
|||
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,
|
||||
|
@ -178,6 +181,7 @@ uint32_t PatchCordProxy::getSpecificValue(uint32_t key)
|
|||
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &values, &count,
|
||||
DBUS_TYPE_INVALID))
|
||||
value = values[key];
|
||||
|
||||
dbus_pending_call_unref(pending);
|
||||
}
|
||||
|
||||
|
@ -188,3 +192,113 @@ uint32_t PatchCordProxy::getSpecificValue(uint32_t key)
|
|||
|
||||
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);
|
||||
|
||||
uint32_t number;
|
||||
uint32_t algorithm;
|
||||
uint32_t key;
|
||||
uint32_t interval;
|
||||
uint32_t capabilities;
|
||||
const char* language;
|
||||
uint32_t station;
|
||||
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);
|
||||
|
||||
uint32_t number;
|
||||
uint32_t algorithm;
|
||||
uint32_t key;
|
||||
uint32_t interval;
|
||||
uint32_t capabilities;
|
||||
const char* language;
|
||||
uint32_t station;
|
||||
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;
|
||||
}
|
|
@ -6,17 +6,24 @@
|
|||
#include <stdint.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
class PatchCordProxy
|
||||
class PatchCord
|
||||
{
|
||||
public:
|
||||
|
||||
PatchCordProxy(uint32_t network, uint32_t link);
|
||||
~PatchCordProxy();
|
||||
PatchCord(uint32_t network, uint32_t link);
|
||||
~PatchCord();
|
||||
|
||||
// Primary methods to manage PatchCord instance
|
||||
|
||||
void setTalkerID(uint32_t value);
|
||||
void setTalkerAlias(const char* value);
|
||||
uint32_t getTalkerID();
|
||||
|
||||
// Supplimentary methods to access cached data from database
|
||||
|
||||
uint32_t getPrivateIDForCall(const char* call);
|
||||
bool getCredentialsForID(uint32_t number, char* call, char* text);
|
||||
|
||||
private:
|
||||
|
||||
DBusConnection* connection;
|
|
@ -1,137 +0,0 @@
|
|||
// Copyright 2015 by Artem Prilutskiy
|
||||
|
||||
#include "UserDataStore.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#define GET_ID_FOR_CALL 0
|
||||
#define GET_CREDENTIALS_FOR_ID 1
|
||||
|
||||
UserDataStore::UserDataStore(const char* file) :
|
||||
connection(NULL)
|
||||
{
|
||||
const char* queries[] =
|
||||
{
|
||||
// GET_ID_FOR_CALL
|
||||
"SELECT `ID`"
|
||||
" FROM Users"
|
||||
" WHERE `Call` = ?"
|
||||
" ORDER BY `Priority`"
|
||||
" LIMIT 1",
|
||||
// GET_CREDENTIALS_FOR_ID
|
||||
"SELECT `Call`, `Text`"
|
||||
" FROM Users"
|
||||
" WHERE `ID` = ?",
|
||||
};
|
||||
|
||||
connection = mysql_init(NULL);
|
||||
|
||||
mysql_options(connection, MYSQL_READ_DEFAULT_FILE, realpath(file, NULL));
|
||||
mysql_real_connect(connection, NULL, NULL, NULL, NULL, 0, NULL, CLIENT_REMEMBER_OPTIONS);
|
||||
|
||||
my_bool active = true;
|
||||
mysql_options(connection, MYSQL_OPT_RECONNECT, &active);
|
||||
|
||||
for (size_t index = 0; index < PREPARED_STATEMENT_COUNT; index ++)
|
||||
{
|
||||
const char* query = queries[index];
|
||||
statements[index] = mysql_stmt_init(connection);
|
||||
mysql_stmt_prepare(statements[index], query, strlen(query));
|
||||
}
|
||||
|
||||
const char* error = mysql_error(connection);
|
||||
if ((error != NULL) && (*error != '\0'))
|
||||
syslog(LOG_CRIT, "MySQL error: %s\n", error);
|
||||
}
|
||||
|
||||
UserDataStore::~UserDataStore()
|
||||
{
|
||||
for (size_t index = 0; index < PREPARED_STATEMENT_COUNT; index ++)
|
||||
mysql_stmt_close(statements[index]);
|
||||
|
||||
mysql_close(connection);
|
||||
}
|
||||
|
||||
// Public methods
|
||||
|
||||
uint32_t UserDataStore::getPrivateIDForCall(const char* call)
|
||||
{
|
||||
uint32_t number;
|
||||
size_t length = strlen(call);
|
||||
|
||||
return
|
||||
execute(GET_ID_FOR_CALL, 1, 1,
|
||||
MYSQL_TYPE_STRING, call, length,
|
||||
MYSQL_TYPE_LONG, &number) *
|
||||
number;
|
||||
}
|
||||
|
||||
|
||||
bool UserDataStore::getCredentialsForID(uint32_t number, char* call, char* text)
|
||||
{
|
||||
return
|
||||
execute(GET_CREDENTIALS_FOR_ID, 1, 2,
|
||||
MYSQL_TYPE_LONG, &number,
|
||||
MYSQL_TYPE_STRING, call, LONG_CALLSIGN_LENGTH + 1,
|
||||
MYSQL_TYPE_STRING, text, SLOW_DATA_TEXT_LENGTH + 1);
|
||||
}
|
||||
|
||||
// Internals
|
||||
|
||||
MYSQL_BIND* UserDataStore::bind(int count, va_list* arguments)
|
||||
{
|
||||
MYSQL_BIND* bindings = NULL;
|
||||
if (count > 0)
|
||||
{
|
||||
bindings = (MYSQL_BIND*)calloc(count, sizeof(MYSQL_BIND));
|
||||
for (int index = 0; index < count; index ++)
|
||||
{
|
||||
int type = va_arg(*arguments, int);
|
||||
bindings[index].buffer_type = (enum_field_types)type;
|
||||
bindings[index].buffer = va_arg(*arguments, void*);
|
||||
if ((type == MYSQL_TYPE_STRING) ||
|
||||
(type == MYSQL_TYPE_DATETIME))
|
||||
{
|
||||
bindings[index].buffer_length = va_arg(*arguments, int);
|
||||
bindings[index].length = &bindings[index].buffer_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindings;
|
||||
}
|
||||
|
||||
bool UserDataStore::execute(int index, int count1, int count2, ...)
|
||||
{
|
||||
bool result = true;
|
||||
MYSQL_STMT* statement = statements[index];
|
||||
|
||||
va_list arguments;
|
||||
va_start(arguments, count2);
|
||||
MYSQL_BIND* parameters = bind(count1, &arguments);
|
||||
MYSQL_BIND* columns = bind(count2, &arguments);
|
||||
va_end(arguments);
|
||||
|
||||
if ((parameters && mysql_stmt_bind_param(statement, parameters)) ||
|
||||
(columns && mysql_stmt_bind_result(statement, columns)) ||
|
||||
mysql_stmt_execute(statement) ||
|
||||
(columns && mysql_stmt_store_result(statement)))
|
||||
{
|
||||
const char* error = mysql_stmt_error(statement);
|
||||
syslog(LOG_CRIT, "MySQL error while processing statement %d: %s\n", index, error);
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result && columns)
|
||||
{
|
||||
result = !mysql_stmt_fetch(statement);
|
||||
mysql_stmt_free_result(statement);
|
||||
}
|
||||
|
||||
free(columns);
|
||||
free(parameters);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2015 by Artem Prilutskiy
|
||||
|
||||
#ifndef USERDATASTORE_H
|
||||
#define USERDATASTORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
#define PREPARED_STATEMENT_COUNT 2
|
||||
|
||||
#define LONG_CALLSIGN_LENGTH 8
|
||||
#define SLOW_DATA_TEXT_LENGTH 20
|
||||
|
||||
class UserDataStore
|
||||
{
|
||||
public:
|
||||
|
||||
UserDataStore(const char* file);
|
||||
~UserDataStore();
|
||||
|
||||
uint32_t getPrivateIDForCall(const char* call);
|
||||
bool getCredentialsForID(uint32_t number, char* call, char* text);
|
||||
|
||||
protected:
|
||||
|
||||
MYSQL* connection;
|
||||
MYSQL_STMT* statements[PREPARED_STATEMENT_COUNT];
|
||||
|
||||
MYSQL_BIND* bind(int count, va_list* arguments);
|
||||
bool execute(int index, int count1, int count2, ...);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue