diff --git a/reflector/Callsign.cpp b/reflector/Callsign.cpp index b0312e3..74a83d9 100644 --- a/reflector/Callsign.cpp +++ b/reflector/Callsign.cpp @@ -408,6 +408,8 @@ bool CCallsign::operator ==(const CCallsign &callsign) const CCallsign::operator const char *() const { + static char m_sz[CALLSIGN_LEN+CALLSUFFIX_LEN+5]; + // empty memset(m_sz, 0, sizeof(m_sz)); // callsign diff --git a/reflector/Callsign.h b/reflector/Callsign.h index e436891..6e5d734 100644 --- a/reflector/Callsign.h +++ b/reflector/Callsign.h @@ -95,7 +95,6 @@ protected: char m_Callsign[CALLSIGN_LEN]; char m_Suffix[CALLSUFFIX_LEN]; char m_Module; - mutable char m_sz[CALLSIGN_LEN+CALLSUFFIX_LEN+5]; uint32_t m_uiDmrid; uint16_t m_uiNXDNid; uint64_t m_coded; // M17 encoded callsign diff --git a/reflector/Configure.cpp b/reflector/Configure.cpp index 73b46f6..b59db6d 100644 --- a/reflector/Configure.cpp +++ b/reflector/Configure.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -28,6 +27,7 @@ #include #include "Global.h" +#include "CurlGet.h" // ini file keywords #define JAUTOLINKMODULE "AutoLinkModule" @@ -111,66 +111,6 @@ static inline void trim(std::string &s) { rtrim(s); } -// callback function writes data to a std::ostream -static size_t data_write(void* buf, size_t size, size_t nmemb, void* userp) -{ - if(userp) - { - std::ostream& os = *static_cast(userp); - std::streamsize len = size * nmemb; - if(os.write(static_cast(buf), len)) - return len; - } - - return 0; -} - -static CURLcode curl_read(const std::string& url, std::ostream& os, long timeout = 30) -{ - CURLcode code(CURLE_FAILED_INIT); - CURL* curl = curl_easy_init(); - - if(curl) - { - if(CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write)) - && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L)) - && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L)) - && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &os)) - && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout)) - && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str()))) - { - code = curl_easy_perform(curl); - } - curl_easy_cleanup(curl); - } - return code; -} - -void CConfigure::CurlAddresses(std::string &ipv4, std::string &ipv6) const -{ - std::ostringstream oss; - - curl_global_init(CURL_GLOBAL_ALL); - - if(CURLE_OK == curl_read("https://ipv4.icanhazip.com", oss)) - { - // Web page successfully written to string - ipv4.assign(oss.str()); - trim(ipv4); - oss.str(std::string()); - } - - if(CURLE_OK == curl_read("https://ipv6.icanhazip.com", oss)) - { - ipv6.assign(oss.str()); - trim(ipv6); - } - - curl_global_cleanup(); - -// std::cout << "IPv4=" << ipv4 << " IPv6=" << ipv6 << std::endl; -} - CConfigure::CConfigure() { IPv4RegEx = std::regex("^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3,3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]){1,1}$", std::regex::extended); @@ -194,7 +134,23 @@ bool CConfigure::ReadData(const std::string &path) } std::string ipv4, ipv6; - CurlAddresses(ipv4, ipv6); + + { + CCurlGet curl; + std::stringstream ss; + if (CURLE_OK == curl.GetURL("https://ipv4.icanhazip.com", ss)) + { + ipv4.assign(ss.str()); + trim(ipv4); + ss.clear(); + } + if (CURLE_OK == curl.GetURL("https://ipv6.icanhazip.com", ss)) + { + std::cout << ss.str(); + ipv6.assign(ss.str()); + trim(ipv6); + } + } std::string line; while (std::getline(cfgfile, line)) @@ -606,6 +562,7 @@ bool CConfigure::ReadData(const std::string &path) data[g_Keys.ip.ipv6address] = ipv6; else { + std::cout << ipv6; std::cerr << "ERROR: could not detect IPv6 address at this time" << std::endl; rval = true; } diff --git a/reflector/Configure.h b/reflector/Configure.h index 9686ed9..7395918 100644 --- a/reflector/Configure.h +++ b/reflector/Configure.h @@ -47,7 +47,6 @@ private: nlohmann::json data; std::regex IPv4RegEx, IPv6RegEx; - void CurlAddresses(std::string &v4, std::string &v6) const; std::string getDataRefreshType(ERefreshType t) const; unsigned getUnsigned(const std::string &value, const std::string &label, unsigned min, unsigned max, unsigned defaultvalue) const; void badParam(const std::string ¶m) const; diff --git a/reflector/CurlGet.cpp b/reflector/CurlGet.cpp new file mode 100644 index 0000000..5b11794 --- /dev/null +++ b/reflector/CurlGet.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 by Thomas A. Early N7TAE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "CurlGet.h" + +CCurlGet::CCurlGet() +{ + curl_global_init(CURL_GLOBAL_ALL); +} + +CCurlGet::~CCurlGet() +{ + curl_global_cleanup(); +} + +// callback function writes data to a std::ostream +size_t CCurlGet::data_write(void* buf, size_t size, size_t nmemb, void* userp) +{ + if(userp) + { + std::ostream& os = *static_cast(userp); + std::streamsize len = size * nmemb; + if(os.write(static_cast(buf), len)) + return len; + } + + return 0; +} + +CURLcode CCurlGet::GetURL(const std::string &url, std::stringstream &ss, long timeout) +{ + CURLcode code(CURLE_FAILED_INIT); + CURL* curl = curl_easy_init(); + + if(curl) + { + if(CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write)) + && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L)) + && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L)) + && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &ss)) + && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout)) + && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str()))) + { + code = curl_easy_perform(curl); + } + curl_easy_cleanup(curl); + } + if (code != CURLE_OK) + { + std::cout << "ERROR: was not able retrieve data at '" << url << "'\nCurl returned: " << code << std::endl; + } + return code; +} diff --git a/reflector/CurlGet.h b/reflector/CurlGet.h new file mode 100644 index 0000000..29aff4e --- /dev/null +++ b/reflector/CurlGet.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 by Thomas A. Early N7TAE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#pragma once + +#include +#include +#include + +class CCurlGet +{ +public: + CCurlGet(); + ~CCurlGet(); + // the contents of the URL will be appended to the stringstream. + CURLcode GetURL(const std::string &url, std::stringstream &ss, long timeout = 30); +private: + static size_t data_write(void* buf, size_t size, size_t nmemb, void* userp); +}; diff --git a/reflector/Lookup.cpp b/reflector/Lookup.cpp index fa85586..dcb8599 100644 --- a/reflector/Lookup.cpp +++ b/reflector/Lookup.cpp @@ -93,3 +93,13 @@ void CLookup::Thread() std::this_thread::sleep_for(std::chrono::seconds(3)); } } + +bool CLookup::Dump() +{ + CBuffer buf; + LoadParameters(); + auto rval = LoadContentHttp(buf); + if (rval) + std::cout << (const char *)buf.data(); + return rval; +} diff --git a/reflector/Lookup.h b/reflector/Lookup.h index 86ef905..db52d2e 100644 --- a/reflector/Lookup.h +++ b/reflector/Lookup.h @@ -53,6 +53,7 @@ public: // locks void Lock(void) { m_Mutex.lock(); } void Unlock(void) { m_Mutex.unlock(); } + bool Dump(void); protected: std::time_t GetLastModTime(); diff --git a/reflector/LookupDmr.cpp b/reflector/LookupDmr.cpp index 14c7363..3b6097f 100644 --- a/reflector/LookupDmr.cpp +++ b/reflector/LookupDmr.cpp @@ -77,10 +77,8 @@ bool CLookupDmr::LoadContentFile(CBuffer &buffer) buffer.resize((int)size+1); file.seekg(0, std::ios::beg); file.read((char *)buffer.data(), (int)size); - - // close file - file.close(); } + file.close(); } // done @@ -89,7 +87,7 @@ bool CLookupDmr::LoadContentFile(CBuffer &buffer) bool CLookupDmr::LoadContentHttp(CBuffer &buf) { - // get file from xlxapi server + // get file from http://xlxapi.rlx.lu/api/exportdmr.php return HttpGet(m_Host.c_str(), m_Suffix.c_str(), 80, buf); } diff --git a/reflector/LookupYsf.cpp b/reflector/LookupYsf.cpp index bb45b69..382229f 100644 --- a/reflector/LookupYsf.cpp +++ b/reflector/LookupYsf.cpp @@ -58,10 +58,8 @@ bool CLookupYsf::LoadContentFile(CBuffer &buffer) buffer.resize((int)size + 1); file.seekg(0, std::ios::beg); file.read((char *)buffer.data(), (int)size); - - // close file - file.close(); } + file.close(); } return buffer.size() > 0; } diff --git a/reflector/Makefile b/reflector/Makefile index 7930dff..333d07a 100644 --- a/reflector/Makefile +++ b/reflector/Makefile @@ -41,8 +41,8 @@ all : $(EXE) $(INICHECK) $(EXE) : $(OBJS) $(CXX) $^ -o $@ $(LDFLAGS) -$(INICHECK) : Configure.cpp Configure.h - $(CXX) -DINICHECK $(CFLAGS) $< -o $(INICHECK) -lcurl +$(INICHECK) : Configure.cpp CurlGet.cpp + $(CXX) -DINICHECK $(CFLAGS) Configure.cpp CurlGet.cpp -o $(INICHECK) -lcurl %.o : %.cpp $(CXX) $(CFLAGS) -c $< -o $@ diff --git a/reflector/example.ini b/reflector/example.ini index 98e24be..b404452 100644 --- a/reflector/example.ini +++ b/reflector/example.ini @@ -77,7 +77,7 @@ Port = 10017 Port = 34001 AutoLinkModule = A # comment out if you want to disable AL DefaultCallsign = ALLSTAR -ClientFilePath = /usr/local/etc/USRPClients.txt +ClientFilePath = /home/user/urfd/USRPClients.txt [YSF] Port = 42000 @@ -95,27 +95,27 @@ Hostname = xlxapi.rlx.lu Suffix = api/exportdmr.php Mode = http RefreshMin = 179 -FilePath = /usr/local/etc/dmrid.dat +FilePath = /home/user/urfd/dmrid.dat [NXDN ID DB] Hostname = www.dudetronics.com Suffix = ar-dns/NXDN.csv Mode = http RefreshMin = 181 -FilePath = /usr/local/etc/nxdn.dat +FilePath = /home/user/urfd/nxdn.dat [YSF TX/RX DB] Hostname = xlxapi.rlx.lu Suffix = api/exportysfrepeaters.php Mode = http RefreshMin = 191 -FilePath = /usr/local/etc/ysfnode.dat +FilePath = /home/user/urfd/ysfnode.dat ######### Other File locations [Files] -PidPath = /var/run/urfd.pid +PidPath = /var/run/urfd.pid JsonPath = /var/log/urfd.json -WhitelistPath = /usr/local/etc/urfd.whitelist -BlacklistPath = /usr/local/etc/urfd.blacklist -InterlinkPath = /usr/local/etc/urfd.interlink -G3TerminalPath = /usr/local/etc/urfd.terminal +WhitelistPath = /home/user/urfd/urfd.whitelist +BlacklistPath = /home/user/urfd/urfd.blacklist +InterlinkPath = /home/user/urfd/urfd.interlink +G3TerminalPath = /home/user/urfd/urfd.terminal diff --git a/reflector/example.mk b/reflector/example.mk new file mode 100644 index 0000000..641bc68 --- /dev/null +++ b/reflector/example.mk @@ -0,0 +1,6 @@ +# this is where the binary will be installed +BINDIR = /usr/local/bin + +# besides making an executable that gdb can use, +# this will also provide some additional log messsage +debug = false