// Copyright 2015 by Artem Prilutskiy #include "BrandMeisterBridge.h" #include #include #include #include #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(configuration); // : 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* delimiter = strpbrk(call, " -\n"); if (delimiter != NULL) { // Remove characters after call-sign size_t length = delimiter - call; char* buffer = (char*)alloca(length + sizeof(uint32_t)); strncpy(buffer, call, length); call = buffer; } uint32_t number = store->getPrivateIDForCall(call); if (number == 0) number = unknown; syslog(LOG_INFO, "Set talker ID to %d for call-sign %s", number, call); proxy->setTalkerID(number); proxy->setTalkerAlias(call); } 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, NULL); } else { syslog(LOG_INFO, "Set talker ID to %d (call-sign was not fit into chat message)", unknown); proxy->setTalkerID(unknown); } } }