From dd0a9506164f2efef3f04cb495a1307e0b40fc46 Mon Sep 17 00:00:00 2001 From: Artem Prilutskiy Date: Sat, 16 Feb 2019 23:56:05 +0300 Subject: [PATCH] Added support of iconv --- SVXLink/ModuleEchoLink.conf | 1 + SVXLink/echolink/BrandMeisterBridge.cpp | 95 +++++++++++++++++-------- SVXLink/echolink/BrandMeisterBridge.h | 6 ++ SVXLink/echolink/ModuleEchoLink.cpp | 4 ++ 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/SVXLink/ModuleEchoLink.conf b/SVXLink/ModuleEchoLink.conf index a1ded6e..6658778 100644 --- a/SVXLink/ModuleEchoLink.conf +++ b/SVXLink/ModuleEchoLink.conf @@ -22,3 +22,4 @@ AUTOCON_TIME=30 BRIDGE_DEFAULT=9504 BRIDGE_PROXY=2501:10 +BRIDGE_ENCOFING=cp1251 diff --git a/SVXLink/echolink/BrandMeisterBridge.cpp b/SVXLink/echolink/BrandMeisterBridge.cpp index f4cc102..a843789 100644 --- a/SVXLink/echolink/BrandMeisterBridge.cpp +++ b/SVXLink/echolink/BrandMeisterBridge.cpp @@ -16,18 +16,25 @@ BrandMeisterBridge::BrandMeisterBridge() { proxy = NULL; + handle = NULL; talker = NULL; unknown = ECHOLINK_DEFAULT_USER_NUMBER; } BrandMeisterBridge::~BrandMeisterBridge() { + iconv_close(handle); DELETE(proxy); free(talker); } // Interface methods for ModuleEchoLink +void BrandMeisterBridge::setEncodingConfiguration(const char* configuration) +{ + handle = iconv_open("UTF-8", configuration); +} + void BrandMeisterBridge::setDefaultConfiguration(const char* configuration) { unknown = strtol(configuration, NULL, 10); @@ -76,39 +83,16 @@ void BrandMeisterBridge::setTalker(const char* call, const char* name) if (*call == '*') { - // Do not process conference call-sign + // Do not handle conference call-sign return; } - const char* delimiter1 = strpbrk(call, " -\n"); - const char* delimiter2 = strpbrk(name, "\n"); + size_t length = strlen(call) + strlen(name); + char* buffer = (char*)alloca(length + sizeof(uint32_t)); - 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); - buffer[length] = '\0'; - 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); - buffer[length] = '\0'; - name = buffer; - } + sprintf(buffer, "%s %s", call, name); - uint32_t number = proxy->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); + setTalkerData(call, buffer); } void BrandMeisterBridge::handleChatMessage(const char* text) @@ -130,14 +114,65 @@ void BrandMeisterBridge::handleChatMessage(const char* text) if (delimiter != NULL) { const char* call = delimiter + 3; - setTalker(call, call); + setTalkerData(call, call); } else { - syslog(LOG_INFO, "Set talker ID to %d (call-sign was not fit into chat message)", unknown); + syslog(LOG_INFO, "Set talker ID to %d (call-sign is not present in chat message)", unknown); proxy->setTalkerID(unknown); proxy->setTalkerAlias(""); } } } +void BrandMeisterBridge::setTalkerData(const char* call, const char* name) +{ + const char* delimiter1 = strpbrk(call, " -\n"); + const char* delimiter2 = strchr(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); + buffer[length] = '\0'; + 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); + buffer[length] = '\0'; + name = buffer; + } + + if (handle != NULL) + { + // Convert name to UTF8 + size_t length1 = strlen(name); + size_t length2 = length1 * 3; + char* buffer = (char*)alloca(length2); + char* pointer1 = const_cast(name); + char* pointer2 = buffer; + iconv(handle, &pointer1, &length1, &pointer2, &length2); + *pointer2 = '\0'; + name = buffer; + } + + uint32_t number = proxy->getPrivateIDForCall(call); + + if (number == 0) + { + // Use default value instead if ID not found + number = unknown; + } + + proxy->setTalkerID(number); + proxy->setTalkerAlias(name); + + syslog(LOG_INFO, "Set talker ID to %d for call-sign %s (%s)", number, call, name); +} diff --git a/SVXLink/echolink/BrandMeisterBridge.h b/SVXLink/echolink/BrandMeisterBridge.h index 465104a..9f9c0a4 100644 --- a/SVXLink/echolink/BrandMeisterBridge.h +++ b/SVXLink/echolink/BrandMeisterBridge.h @@ -3,6 +3,8 @@ #ifndef BRANDMEISTERBRIDGE_H #define BRANDMEISTERBRIDGE_H +#include + #include "PatchCord.h" class BrandMeisterBridge @@ -12,6 +14,7 @@ class BrandMeisterBridge BrandMeisterBridge(); ~BrandMeisterBridge(); + void setEncodingConfiguration(const char* configuration); void setDefaultConfiguration(const char* configuration); void setProxyConfiguration(const char* configuration); @@ -22,9 +25,12 @@ class BrandMeisterBridge private: PatchCord* proxy; + iconv_t handle; char* talker; int unknown; + void setTalkerData(const char* call, const char* name); + }; #endif \ No newline at end of file diff --git a/SVXLink/echolink/ModuleEchoLink.cpp b/SVXLink/echolink/ModuleEchoLink.cpp index e82128b..79c7ac1 100644 --- a/SVXLink/echolink/ModuleEchoLink.cpp +++ b/SVXLink/echolink/ModuleEchoLink.cpp @@ -420,6 +420,10 @@ bool ModuleEchoLink::initialize(void) { bridge.setDefaultConfiguration(value.c_str()); } + if (cfg().getValue(cfgName(), "BRIDGE_ENCODING", value)) + { + bridge.setEncodingConfiguration(value.c_str()); + } if (cfg().getValue(cfgName(), "BRIDGE_PROXY", value)) { bridge.setProxyConfiguration(value.c_str());