4
Fork 0
AutoPatch/SVXLink/echolink/BrandMeisterBridge.cpp
Artem Prilutskiy f9bcb35800 ..
2017-01-05 21:35:55 +03:00

151 lines
3.5 KiB
C++

// Copyright 2015 by Artem Prilutskiy
#include "BrandMeisterBridge.h"
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <stdio.h>
#define ECHOLINK_DEFAULT_USER_CALL "N0CALL Unknown call"
#define ECHOLINK_DEFAULT_USER_NUMBER 1
#define DELETE(object) \
if (object) \
delete object;
BrandMeisterBridge::BrandMeisterBridge()
{
proxy = NULL;
store = NULL;
talker = NULL;
unknown = ECHOLINK_DEFAULT_USER_NUMBER;
}
BrandMeisterBridge::~BrandMeisterBridge()
{
DELETE(proxy);
DELETE(store);
free(talker);
}
// Interface methods for ModuleEchoLink
void BrandMeisterBridge::setDefaultConfiguration(const char* configuration)
{
unknown = strtol(configuration, NULL, 10);
}
void BrandMeisterBridge::setProxyConfiguration(const char* configuration)
{
char* pointer = const_cast<char*>(configuration);
// <Network ID>:<PatchCord ID>
uint32_t network = strtol(pointer + 0, &pointer, 10);
uint32_t link = strtol(pointer + 1, &pointer, 10);
proxy = new PatchCordProxy(network, link);
}
void BrandMeisterBridge::setStoreConfiguration(const char* configuration)
{
store = new UserDataStore(configuration);
}
const char* BrandMeisterBridge::getTalker()
{
if ((proxy == NULL) ||
(store == NULL))
{
syslog(LOG_ERR, "BrandMeister bridge is not configured");
return ECHOLINK_DEFAULT_USER_CALL;
}
free(talker);
uint32_t number = proxy->getTalkerID();
char call[LONG_CALLSIGN_LENGTH];
char text[SLOW_DATA_TEXT_LENGTH];
if ((number != 0) &&
(store->getCredentialsForID(number, call, text)))
{
asprintf(&talker, "%s %s", call, text);
return talker;
}
asprintf(&talker, "DMR ID: %d", number);
return talker;
}
void BrandMeisterBridge::setTalker(const char* call, const char* name)
{
if ((proxy == NULL) ||
(store == NULL))
{
syslog(LOG_ERR, "BrandMeister bridge is not configured");
return;
}
if (*call == '*')
{
// Do not process conference call-sign
return;
}
const char* delimiter1 = strpbrk(call, " -\n");
const char* delimiter2 = strpbrk(name, "\n");
if (delimiter1 != NULL)
{
// Remove characters after call-sign
size_t length = delimiter1 - call;
char* buffer = (char*)alloca(length + sizeof(uint32_t));
strncpy(buffer, call, length);
call = buffer;
}
if (delimiter2 != NULL)
{
// Remove characters after talker name
size_t length = delimiter2 - name;
char* buffer = (char*)alloca(length + sizeof(uint32_t));
strncpy(buffer, name, length);
name = buffer;
}
uint32_t number = store->getPrivateIDForCall(call);
if (number == 0)
number = unknown;
syslog(LOG_INFO, "Set talker ID to %d for call-sign %s (%s)", number, call, name);
proxy->setTalkerID(number);
proxy->setTalkerAlias(name);
}
void BrandMeisterBridge::handleChatMessage(const char* text)
{
// CONF Russian Reflector, Open 24/7, Contacts: rv3dhc.link@qip.ru * Call CQ / Use pauses 2sec * [28/500]
// R3ABM-L *DSTAR.SU DMR Bridge*
// UB3AMO Moscow T I N A O
// ->UA0LQE-L USSURIISK
if ((proxy == NULL) ||
(store == NULL))
{
syslog(LOG_ERR, "BrandMeister bridge is not configured");
return;
}
if (strncmp(text, "CONF ", 5) == 0)
{
const char* delimiter = strstr(text, "\n->");
if (delimiter != NULL)
{
const char* call = delimiter + 3;
setTalker(call, call);
}
else
{
syslog(LOG_INFO, "Set talker ID to %d (call-sign was not fit into chat message)", unknown);
proxy->setTalkerID(unknown);
proxy->setTalkerAlias("<unknown>");
}
}
}