- refactoring

This commit is contained in:
Dmytro Bogovych 2023-04-21 09:59:13 +03:00
parent 7db4c8cb53
commit 76aa7861f5
16 changed files with 329 additions and 171 deletions

View File

@ -81,7 +81,7 @@ bool WavFileReader::open(const std::tstring& filename)
#ifdef WIN32 #ifdef WIN32
mHandle = _wfopen(filename.c_str(), L"rb"); mHandle = _wfopen(filename.c_str(), L"rb");
#else #else
mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "rb"); mHandle = fopen(strx::makeUtf8(filename).c_str(), "rb");
#endif #endif
if (NULL == mHandle) if (NULL == mHandle)
{ {
@ -287,11 +287,11 @@ bool WavFileWriter::open(const std::tstring& filename, int rate, int channels)
#ifdef WIN32 #ifdef WIN32
mHandle = _wfopen(filename.c_str(), L"wb"); mHandle = _wfopen(filename.c_str(), L"wb");
#else #else
mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "wb"); mHandle = fopen(strx::makeUtf8(filename).c_str(), "wb");
#endif #endif
if (nullptr == mHandle) if (nullptr == mHandle)
{ {
ICELogError(<< "Failed to create .wav file: filename = " << StringHelper::makeUtf8(filename) << " , error = " << errno); ICELogError(<< "Failed to create .wav file: filename = " << strx::makeUtf8(filename) << " , error = " << errno);
return false; return false;
} }

View File

@ -312,7 +312,7 @@ namespace Calc
{ {
// Dot is here - is it float // Dot is here - is it float
bool isFloat = false; bool isFloat = false;
StringHelper::toFloat(mCurrentLexem.mValue, 0.0f, &isFloat); strx::toFloat(mCurrentLexem.mValue, 0.0f, &isFloat);
if (isFloat) if (isFloat)
mCurrentLexem.mType = LexemType::Float; mCurrentLexem.mType = LexemType::Float;
else else
@ -488,7 +488,7 @@ namespace Calc
case LexemType::Hex: case LexemType::Hex:
result->mType = Ast::Type::Number; result->mType = Ast::Type::Number;
result->mValue = StringHelper::fromHex2Int(l.mValue); result->mValue = strx::fromHex2Int(l.mValue);
break; break;
case LexemType::Float: case LexemType::Float:

View File

@ -20,10 +20,10 @@ bool CsvReader::readLine(std::vector<std::string>& cells)
std::string line; std::string line;
if (!std::getline(mInputStream, line)) if (!std::getline(mInputStream, line))
return false; return false;
StringHelper::trim(line); strx::trim(line);
if (line.empty()) if (line.empty())
return false; return false;
StringHelper::split(line, cells, ",;"); strx::split(line, cells, ",;");
return true; return true;
} }

View File

@ -287,7 +287,7 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
if (d != std::string::npos) if (d != std::string::npos)
{ {
if (line_callback) if (line_callback)
line_callback(StringHelper::trim(lines.substr(p, d-p))); line_callback(strx::trim(lines.substr(p, d-p)));
p = d + 1; p = d + 1;
} }
} }

View File

@ -16,7 +16,7 @@
# include <cctype> # include <cctype>
#endif #endif
std::string StringHelper::extractFilename(const std::string& path) std::string strx::extractFilename(const std::string& path)
{ {
if (path.empty()) if (path.empty())
return std::string(); return std::string();
@ -31,7 +31,7 @@ std::string StringHelper::extractFilename(const std::string& path)
return path.substr(p_bs + 1); return path.substr(p_bs + 1);
} }
std::string StringHelper::appendPath(const std::string& s1, const std::string& s2) std::string strx::appendPath(const std::string& s1, const std::string& s2)
{ {
std::string result = s1; std::string result = s1;
if (!endsWith(result, "/") && !endsWith(result, "\\")) if (!endsWith(result, "/") && !endsWith(result, "\\"))
@ -45,7 +45,7 @@ std::string StringHelper::appendPath(const std::string& s1, const std::string& s
return result + s2; return result + s2;
} }
std::string StringHelper::makeUtf8(const std::tstring &arg) std::string strx::makeUtf8(const std::tstring &arg)
{ {
#if defined(TARGET_WIN) #if defined(TARGET_WIN)
size_t required = WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, NULL, 0, NULL, NULL); size_t required = WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, NULL, 0, NULL, NULL);
@ -57,12 +57,12 @@ std::string StringHelper::makeUtf8(const std::tstring &arg)
#endif #endif
} }
std::string StringHelper::toUtf8(const std::tstring &arg) std::string strx::toUtf8(const std::tstring &arg)
{ {
return makeUtf8(arg); return makeUtf8(arg);
} }
std::tstring StringHelper::makeTstring(const std::string& arg) std::tstring strx::makeTstring(const std::string& arg)
{ {
#if defined(TARGET_WIN) #if defined(TARGET_WIN)
size_t count = MultiByteToWideChar(CP_UTF8, 0, arg.c_str(), -1, NULL, 0); size_t count = MultiByteToWideChar(CP_UTF8, 0, arg.c_str(), -1, NULL, 0);
@ -74,7 +74,7 @@ std::tstring StringHelper::makeTstring(const std::string& arg)
#endif #endif
} }
int StringHelper::toInt(const char *s, int defaultValue, bool* isOk) int strx::toInt(const char *s, int defaultValue, bool* isOk)
{ {
int result; int result;
if (sscanf(s, "%d", &result) != 1) if (sscanf(s, "%d", &result) != 1)
@ -90,7 +90,7 @@ int StringHelper::toInt(const char *s, int defaultValue, bool* isOk)
return result; return result;
} }
uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk) uint64_t strx::toUint64(const char* s, uint64_t def, bool *isOk)
{ {
uint64_t result = def; uint64_t result = def;
if (sscanf(s, "%" SCNu64, &result) != 1) if (sscanf(s, "%" SCNu64, &result) != 1)
@ -106,14 +106,14 @@ uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk)
return result; return result;
} }
std::string StringHelper::toHex(unsigned int value) std::string strx::toHex(unsigned int value)
{ {
char buffer[32]; char buffer[32];
sprintf(buffer, "%x", value); sprintf(buffer, "%x", value);
return buffer; return buffer;
} }
std::string StringHelper::toHex(const void *ptr) std::string strx::toHex(const void *ptr)
{ {
std::ostringstream oss; std::ostringstream oss;
oss << std::fixed << std::setw(8) << std::setfill('0') << std::hex << ptr; oss << std::fixed << std::setw(8) << std::setfill('0') << std::hex << ptr;
@ -123,7 +123,7 @@ std::string StringHelper::toHex(const void *ptr)
//must be lowercase for MD5 //must be lowercase for MD5
static const char hexmap[] = "0123456789abcdef"; static const char hexmap[] = "0123456789abcdef";
std::string StringHelper::toHex(const uint8_t* input, size_t inputLength) std::string strx::toHex(const uint8_t* input, size_t inputLength)
{ {
std::string result; result.resize(inputLength * 2); std::string result; result.resize(inputLength * 2);
@ -144,7 +144,7 @@ std::string StringHelper::toHex(const uint8_t* input, size_t inputLength)
return result; return result;
} }
std::string StringHelper::prefixLines(const std::string &source, const std::string &prefix) std::string strx::prefixLines(const std::string &source, const std::string &prefix)
{ {
// Read source line by line // Read source line by line
std::istringstream iss(source); std::istringstream iss(source);
@ -157,7 +157,7 @@ std::string StringHelper::prefixLines(const std::string &source, const std::stri
return oss.str(); return oss.str();
} }
std::string StringHelper::doubleToString(double value, int precision) std::string strx::doubleToString(double value, int precision)
{ {
std::stringstream ss; std::stringstream ss;
ss << std::fixed << std::setprecision(precision) << value; ss << std::fixed << std::setprecision(precision) << value;
@ -165,7 +165,7 @@ std::string StringHelper::doubleToString(double value, int precision)
} }
const char* StringHelper::findSubstring(const char* buffer, const char* substring, size_t bufferLength) const char* strx::findSubstring(const char* buffer, const char* substring, size_t bufferLength)
{ {
#if defined(TARGET_WIN) #if defined(TARGET_WIN)
return (const char*)strstr(buffer, substring); return (const char*)strstr(buffer, substring);
@ -175,7 +175,7 @@ const char* StringHelper::findSubstring(const char* buffer, const char* substrin
} }
void StringHelper::split(const std::string& src, std::vector<std::string>& dst, const std::string& delims) void strx::split(const std::string& src, std::vector<std::string>& dst, const std::string& delims)
{ {
dst.clear(); dst.clear();
std::string::size_type p = 0; std::string::size_type p = 0;
@ -199,21 +199,21 @@ void StringHelper::split(const std::string& src, std::vector<std::string>& dst,
} }
} }
std::vector<std::string> StringHelper::split(const std::string& src, const std::string& delims) std::vector<std::string> strx::split(const std::string& src, const std::string& delims)
{ {
std::vector<std::string> r; std::vector<std::string> r;
split(src, r, delims); split(src, r, delims);
return r; return r;
} }
std::pair<std::string, int> StringHelper::parseHost(const std::string& host, int defaultPort) std::pair<std::string, int> strx::parseHost(const std::string& host, int defaultPort)
{ {
std::pair<std::string, int> result; std::pair<std::string, int> result;
std::size_t p = host.find(':'); std::size_t p = host.find(':');
if (p != std::string::npos) if (p != std::string::npos)
{ {
result.first = host.substr(0, p); result.first = host.substr(0, p);
result.second = StringHelper::toInt(host.c_str() + p + 1, defaultPort); result.second = strx::toInt(host.c_str() + p + 1, defaultPort);
} }
else else
{ {
@ -223,15 +223,15 @@ std::pair<std::string, int> StringHelper::parseHost(const std::string& host, int
return result; return result;
} }
std::pair<std::string, std::string> StringHelper::parseAssignment(const std::string& s, bool trimQuotes) std::pair<std::string, std::string> strx::parseAssignment(const std::string& s, bool trimQuotes)
{ {
std::pair<std::string, std::string> result; std::pair<std::string, std::string> result;
std::string::size_type p = s.find('='); std::string::size_type p = s.find('=');
if (p != std::string::npos) if (p != std::string::npos)
{ {
result.first = StringHelper::trim(s.substr(0, p)); result.first = strx::trim(s.substr(0, p));
result.second = StringHelper::trim(s.substr(p+1)); result.second = strx::trim(s.substr(p+1));
if (trimQuotes && result.second.size() >= 2) if (trimQuotes && result.second.size() >= 2)
{ {
if ((result.second[0] == '"' && result.second[result.second.size()-1] == '"') || if ((result.second[0] == '"' && result.second[result.second.size()-1] == '"') ||
@ -240,19 +240,19 @@ std::pair<std::string, std::string> StringHelper::parseAssignment(const std::str
} }
} }
else else
result.first = StringHelper::trim(s); result.first = strx::trim(s);
return result; return result;
} }
std::string StringHelper::intToString(int value) std::string strx::intToString(int value)
{ {
char buffer[32]; char buffer[32];
sprintf(buffer, "%d", value); sprintf(buffer, "%d", value);
return buffer; return buffer;
} }
float StringHelper::toFloat(const std::string &s, float v, bool* isOk) float strx::toFloat(const std::string &s, float v, bool* isOk)
{ {
float result = 0.0; float result = 0.0;
int code = sscanf(s.c_str(), "%f", &result); int code = sscanf(s.c_str(), "%f", &result);
@ -271,14 +271,14 @@ float StringHelper::toFloat(const std::string &s, float v, bool* isOk)
return result; return result;
} }
std::string StringHelper::trim(const std::string &s) std::string strx::trim(const std::string &s)
{ {
auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }); auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; });
auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }).base(); auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }).base();
return (wsback <= wsfront ? std::string() : std::string(wsfront,wsback)); return (wsback <= wsfront ? std::string() : std::string(wsfront,wsback));
} }
std::string StringHelper::timeToString(time_t t) std::string strx::timeToString(time_t t)
{ {
char buffer[128] = ""; char buffer[128] = "";
struct tm lt; struct tm lt;
@ -292,12 +292,12 @@ std::string StringHelper::timeToString(time_t t)
return buffer; return buffer;
} }
std::string StringHelper::millisecondsToString(uint64_t t) std::string strx::millisecondsToString(uint64_t t)
{ {
return timeToString(t/1000); return timeToString(t/1000);
} }
int StringHelper::fromHex2Int(const std::string &s) int strx::fromHex2Int(const std::string &s)
{ {
int result = 0; int result = 0;
sscanf(s.c_str(), "%x", &result); sscanf(s.c_str(), "%x", &result);
@ -320,7 +320,7 @@ static int hex2code(const char* s)
return (hex2code(s[0]) << 4) + hex2code(s[1]); return (hex2code(s[0]) << 4) + hex2code(s[1]);
} }
std::string StringHelper::fromHex2String(const std::string& s) std::string strx::fromHex2String(const std::string& s)
{ {
std::string result; result.resize(s.size() / 2); std::string result; result.resize(s.size() / 2);
const char* t = s.c_str(); const char* t = s.c_str();
@ -330,7 +330,7 @@ std::string StringHelper::fromHex2String(const std::string& s)
return result; return result;
} }
std::string StringHelper::replace(const std::string& s, char f, char r) std::string strx::replace(const std::string& s, char f, char r)
{ {
std::string result(s); std::string result(s);
for (std::string::size_type i = 0; i < result.size(); i++) for (std::string::size_type i = 0; i < result.size(); i++)
@ -340,7 +340,7 @@ std::string StringHelper::replace(const std::string& s, char f, char r)
return result; return result;
} }
std::string StringHelper::replace(const std::string& s, const std::string& tmpl, const std::string& n) std::string strx::replace(const std::string& s, const std::string& tmpl, const std::string& n)
{ {
std::string result(s); std::string result(s);
std::string::size_type p = 0; std::string::size_type p = 0;
@ -353,7 +353,7 @@ std::string StringHelper::replace(const std::string& s, const std::string& tmpl,
return result; return result;
} }
std::string StringHelper::decodeUri(const std::string& s) std::string strx::decodeUri(const std::string& s)
{ {
std::string ret; std::string ret;
ret.reserve(s.size()); ret.reserve(s.size());
@ -376,19 +376,19 @@ std::string StringHelper::decodeUri(const std::string& s)
return ret; return ret;
} }
bool StringHelper::startsWith(const std::string& s, const std::string& prefix) bool strx::startsWith(const std::string& s, const std::string& prefix)
{ {
std::string::size_type p = s.find(prefix); std::string::size_type p = s.find(prefix);
return p == 0; return p == 0;
} }
bool StringHelper::endsWith(const std::string& s, const std::string& suffix) bool strx::endsWith(const std::string& s, const std::string& suffix)
{ {
std::string::size_type p = s.rfind(suffix); std::string::size_type p = s.rfind(suffix);
return (p == s.size() - suffix.size()); return (p == s.size() - suffix.size());
} }
int StringHelper::stringToDuration(const std::string& s) int strx::stringToDuration(const std::string& s)
{ {
if (endsWith(s, "ms")) if (endsWith(s, "ms"))
return std::stoi(s.substr(0, s.size()-2)); return std::stoi(s.substr(0, s.size()-2));
@ -402,92 +402,9 @@ int StringHelper::stringToDuration(const std::string& s)
return std::stoi(s) * 1000; return std::stoi(s) * 1000;
} }
#define XML_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" std::string strx::uppercase(const std::string& s)
// --------------------- XcapHelper -----------------
std::string XcapHelper::buildBuddyList(std::string listName, std::vector<std::string> buddies)
{ {
std::ostringstream result; std::string r(s);
result << XML_HEADER << std::transform(r.begin(), r.end(), r.begin(), ::toupper);
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" << return r;
"<list name=\"" << listName.c_str() << "\">";
// to test CT only!
//result << "<entry uri=\"" << "sip:dbogovych1@10.11.1.25" << "\"/>";
//result << "<entry uri=\"" << "sip:dbogovych2@10.11.1.25" << "\"/>";
for (unsigned i = 0; i<buddies.size(); i++)
{
result << "<entry uri=\"" << normalizeSipUri(buddies[i]).c_str() << "\"/>";
}
result << "</list></resource-lists>";
return result.str();
}
std::string XcapHelper::buildRules(std::vector<std::string> buddies)
{
std::ostringstream result;
result << XML_HEADER <<
"<ruleset xmlns=\"urn:ietf:params:xml:ns:common-policy\">" <<
"<rule id=\"presence_allow\">" <<
"<conditions>";
for (unsigned i = 0; i<buddies.size(); i++)
{
result << "<identity><one id=\"" <<
normalizeSipUri(buddies[i]).c_str() << "\"/></identity>";
}
result << "</conditions>" <<
"<actions>" <<
"<sub-handling xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"allow" <<
"</sub-handling>" <<
"</actions>" <<
"<transformations>" <<
"<provide-devices xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-devices/>" <<
"</provide-devices>" <<
"<provide-persons xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-persons/>" <<
"</provide-persons>" <<
"<provide-services xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-services/>" <<
"</provide-services>" <<
"</transformations>" <<
"</rule>" <<
"</ruleset>";
return result.str();
}
std::string XcapHelper::buildServices(std::string serviceUri, std::string listRef)
{
std::ostringstream result;
result << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl <<
"<rls-services xmlns=\"urn:ietf:params:xml:ns:rls-services\"" << std::endl <<
"xmlns:rl=\"urn:ietf:params:xml:ns:resource-lists\"" << std::endl <<
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl <<
"<service uri=\"" << normalizeSipUri(serviceUri).c_str() << "\">" << std::endl <<
"<resource-list>" << listRef.c_str() << "</resource-list>" << std::endl <<
"<packages>" << std::endl <<
"<package>presence</package>" << std::endl <<
"</packages>" << std::endl <<
"</service>" << std::endl <<
"</rls-services>";
return result.str();
}
std::string XcapHelper::normalizeSipUri(std::string uri)
{
if (uri.length())
{
if (uri[0] == '<')
uri.erase(0,1);
if (uri.length())
{
if (uri[uri.length()-1] == '>')
uri.erase(uri.length()-1, 1);
}
}
return uri;
} }

View File

@ -16,26 +16,31 @@
#endif #endif
class StringHelper class strx
{ {
public: public:
static std::string extractFilename(const std::string& path); static std::string makeUtf8(const std::tstring& arg);
static std::string appendPath(const std::string& s1, const std::string& s2); static std::string toUtf8(const std::tstring& arg);
static std::string makeUtf8(const std::tstring& arg);
static std::string toUtf8(const std::tstring& arg);
static std::tstring makeTstring(const std::string& arg); static std::tstring makeTstring(const std::string& arg);
static int toInt(const char* s, int defaultValue, bool* isOk = nullptr);
static uint64_t toUint64(const char* s, uint64_t def, bool *isOk = nullptr);
static std::string toHex(unsigned int value);
static std::string toHex(const void* ptr);
static std::string toHex(const uint8_t* input, size_t inputLength);
static std::string intToString(int value);
static std::string prefixLines(const std::string& source, const std::string& prefix);
static std::string doubleToString(double value, int precision);
static int toInt(const char* s, int defaultValue, bool* isOk = nullptr);
static uint64_t toUint64(const char* s, uint64_t def, bool *isOk = nullptr);
static std::string toHex(unsigned int value);
static std::string toHex(const void* ptr);
static std::string toHex(const uint8_t* input, size_t inputLength);
static std::string intToString(int value);
static std::string doubleToString(double value, int precision);
static int fromHex2Int(const std::string& s);
static std::string fromHex2String(const std::string& s);
static float toFloat(const std::string& s, float defaultValue = 0.0, bool* isOk = nullptr);
static std::string extractFilename(const std::string& path);
static std::string appendPath(const std::string& s1, const std::string& s2);
static std::string prefixLines(const std::string& source, const std::string& prefix);
static const char* findSubstring(const char* buffer, const char* substring, size_t bufferLength); static const char* findSubstring(const char* buffer, const char* substring, size_t bufferLength);
static void split(const std::string& src, std::vector<std::string>& dst, const std::string& delims);
static void split(const std::string& src, std::vector<std::string>& dst, const std::string& delims);
static std::vector<std::string> split(const std::string& src, const std::string& delims = "\n"); static std::vector<std::string> split(const std::string& src, const std::string& delims = "\n");
template <typename T> template <typename T>
@ -53,18 +58,17 @@ public:
static std::pair<std::string, int> parseHost(const std::string& host, int defaultPort); static std::pair<std::string, int> parseHost(const std::string& host, int defaultPort);
static std::pair<std::string, std::string> parseAssignment(const std::string& s, bool trimQuotes = true); static std::pair<std::string, std::string> parseAssignment(const std::string& s, bool trimQuotes = true);
static float toFloat(const std::string& s, float defaultValue = 0.0, bool* isOk = nullptr); static std::string trim(const std::string& s);
static std::string trim(const std::string& s); static std::string timeToString(time_t t);
static std::string timeToString(time_t t); static std::string millisecondsToString(uint64_t t);
static std::string millisecondsToString(uint64_t t); static std::string replace(const std::string& s, char f, char r);
static int fromHex2Int(const std::string& s); static std::string replace(const std::string& s, const std::string& tmpl, const std::string& n);
static std::string fromHex2String(const std::string& s); static std::string decodeUri(const std::string& s);
static std::string replace(const std::string& s, char f, char r); static bool startsWith(const std::string& s, const std::string& prefix);
static std::string replace(const std::string& s, const std::string& tmpl, const std::string& n); static bool endsWith(const std::string& s, const std::string& suffix);
static std::string decodeUri(const std::string& s); static int stringToDuration(const std::string& s);
static bool startsWith(const std::string& s, const std::string& prefix); static std::string uppercase(const std::string& s);
static bool endsWith(const std::string& s, const std::string& suffix);
static int stringToDuration(const std::string& s);
}; };
class XcapHelper class XcapHelper

View File

@ -0,0 +1,109 @@
/* Copyright(C) 2007-2023 VoIPobjects (voipobjects.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "HL_Xcap.h"
#include <sstream>
#include <iomanip>
#include <memory.h>
#include <algorithm>
#include <inttypes.h>
#ifdef TARGET_WIN
# include <WinSock2.h>
# include <Windows.h>
# include <cctype>
#endif
#define XML_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
// --------------------- XcapHelper -----------------
std::string XcapHelper::buildBuddyList(const std::string& listName, const std::vector<std::string>& buddies)
{
std::ostringstream result;
result << XML_HEADER <<
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" <<
"<list name=\"" << listName.c_str() << "\">";
// to test CT only!
//result << "<entry uri=\"" << "sip:dbogovych1@10.11.1.25" << "\"/>";
//result << "<entry uri=\"" << "sip:dbogovych2@10.11.1.25" << "\"/>";
for (unsigned i = 0; i<buddies.size(); i++)
{
result << "<entry uri=\"" << normalizeSipUri(buddies[i]).c_str() << "\"/>";
}
result << "</list></resource-lists>";
return result.str();
}
std::string XcapHelper::buildRules(const std::vector<std::string>& buddies)
{
std::ostringstream result;
result << XML_HEADER <<
"<ruleset xmlns=\"urn:ietf:params:xml:ns:common-policy\">" <<
"<rule id=\"presence_allow\">" <<
"<conditions>";
for (unsigned i = 0; i<buddies.size(); i++)
{
result << "<identity><one id=\"" <<
normalizeSipUri(buddies[i]).c_str() << "\"/></identity>";
}
result << "</conditions>" <<
"<actions>" <<
"<sub-handling xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"allow" <<
"</sub-handling>" <<
"</actions>" <<
"<transformations>" <<
"<provide-devices xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-devices/>" <<
"</provide-devices>" <<
"<provide-persons xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-persons/>" <<
"</provide-persons>" <<
"<provide-services xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
"<all-services/>" <<
"</provide-services>" <<
"</transformations>" <<
"</rule>" <<
"</ruleset>";
return result.str();
}
std::string XcapHelper::buildServices(const std::string& serviceUri, const std::string& listRef)
{
std::ostringstream result;
result << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl <<
"<rls-services xmlns=\"urn:ietf:params:xml:ns:rls-services\"" << std::endl <<
"xmlns:rl=\"urn:ietf:params:xml:ns:resource-lists\"" << std::endl <<
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl <<
"<service uri=\"" << normalizeSipUri(serviceUri).c_str() << "\">" << std::endl <<
"<resource-list>" << listRef.c_str() << "</resource-list>" << std::endl <<
"<packages>" << std::endl <<
"<package>presence</package>" << std::endl <<
"</packages>" << std::endl <<
"</service>" << std::endl <<
"</rls-services>";
return result.str();
}
std::string XcapHelper::normalizeSipUri(const std::string& uri)
{
std::string t(uri);
if (t.length())
{
if (t[0] == '<')
t.erase(0,1);
if (t.length())
{
if (t[t.length()-1] == '>')
t.erase(uri.length()-1, 1);
}
}
return t;
}

View File

@ -0,0 +1,23 @@
/* Copyright(C) 2007-2024 VoIPobjects (voipobjects.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __HELPER_STRING_H
#define __HELPER_STRING_H
#include <vector>
#include <string>
#include <sstream>
class XcapHelper
{
public:
static std::string buildBuddyList(const std::string& listName, const std::vector<std::string>& buddies);
static std::string buildRules(const std::vector<std::string>& buddies);
static std::string buildServices(const std::string& serviceUri, const std::string& listRef);
static std::string normalizeSipUri(const std::string& uri);
};
#endif

View File

@ -6,6 +6,7 @@ set (CMAKE_CXX_STANDARD_REQUIRED ON)
# Produce PIC code always # Produce PIC code always
set (CMAKE_POSITION_INDEPENDENT_CODE ON) set (CMAKE_POSITION_INDEPENDENT_CODE ON)
option (USE_RESIP_INTEGRATION "Use some resiprocate specific routines" OFF)
set (SOURCES set (SOURCES
MT_Statistics.cpp MT_Statistics.cpp

View File

@ -228,11 +228,11 @@ int G729Codec::plc(int lostFrames, void* output, int outputCapacity)
#if defined(USE_OPUS_CODEC) #if defined(USE_OPUS_CODEC)
// -------------- Opus ------------------- // -------------- Opus -------------------
#define OPUS_CODEC_NAME "OPUS" #define OPUS_CODEC_NAME "OPUS"
#define OPUS_CODEC_RATE 16000 #define OPUS_CODEC_RATE 16000
#define OPUS_TARGET_BITRATE 64000 #define OPUS_TARGET_BITRATE 64000
#define OPUS_PACKET_LOSS 30 #define OPUS_PACKET_LOSS 10
#define OPUS_CODEC_COMPLEXITY 2 #define OPUS_CODEC_COMPLEXITY 2
OpusCodec::Params::Params() OpusCodec::Params::Params()
:mUseDtx(false), mUseInbandFec(true), mStereo(true), mPtime(20) :mUseDtx(false), mUseInbandFec(true), mStereo(true), mPtime(20)
@ -321,7 +321,7 @@ void OpusCodec::Params::parse(const resip::Data &params)
mStereo = paramIter->mValue == "1"; mStereo = paramIter->mValue == "1";
else else
if (paramIter->mName == "ptime") if (paramIter->mName == "ptime")
mPtime = StringHelper::toInt(paramIter->mValue.c_str(), 20); mPtime = strx::toInt(paramIter->mValue.c_str(), 20);
} }
} }
#endif #endif

View File

@ -233,7 +233,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
unsigned seqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber(); unsigned seqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
// Gap between new packet and previous on // Gap between new packet and previous on
int gap = seqno - mFetchedPacket->rtp()->GetSequenceNumber() - 1; int gap = (int64_t)seqno - (int64_t)mFetchedPacket->rtp()->GetExtendedSequenceNumber() - 1;
gap = std::min(gap, 127); gap = std::min(gap, 127);
if (gap > 0 && mPacketList.empty()) if (gap > 0 && mPacketList.empty())
{ {
@ -354,6 +354,18 @@ AudioReceiver::~AudioReceiver()
mDecodedDump.reset(); mDecodedDump.reset();
} }
// Update codec settings
void AudioReceiver::setCodecSettings(const CodecList::Settings& codecSettings)
{
if (mCodecSettings == codecSettings)
return;
mCodecSettings = codecSettings;
mCodecMap.clear();
mCodecList.setSettings(mCodecSettings);
mCodecList.fillCodecMap(mCodecMap);
}
size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t output_capacity) size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t output_capacity)
{ {
// How much data was produced // How much data was produced

View File

@ -125,6 +125,9 @@ namespace MT
AudioReceiver(const CodecList::Settings& codecSettings, Statistics& stat); AudioReceiver(const CodecList::Settings& codecSettings, Statistics& stat);
~AudioReceiver(); ~AudioReceiver();
// Update codec settings
void setCodecSettings(const CodecList::Settings& codecSettings);
// Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding. // Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding.
// Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container). // Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container).
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr); bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);

View File

@ -22,7 +22,7 @@
using namespace MT; using namespace MT;
using strx = StringHelper; using strx = strx;
// ---------------- EvsSpec --------------- // ---------------- EvsSpec ---------------
@ -125,13 +125,80 @@ CodecList::Settings::OpusSpec CodecList::Settings::OpusSpec::parse(const std::st
return result; return result;
} }
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
{
CodecList::Settings r{DefaultSettings};
for (auto& c: codeclist)
{
std::string codec_name = strx::uppercase(c.getName().c_str());
int samplerate = c.getRate();
int ptype = c.payloadType();
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
if (codec_name == "OPUS")
{
// Check the parameters
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
auto params = c.parameters();
int channels = strx::toInt(enc_params.c_str(), 1);
r.mOpusSpec.push_back({ptype, samplerate, channels});
}
}
return r;
}
bool CodecList::Settings::operator == (const Settings& rhs) const
{
if (std::tie(mWrapIuUP, mSkipDecode, mIsac16KPayloadType, mIsac32KPayloadType, mIlbc20PayloadType, mIlbc30PayloadType, mGsmFrPayloadType, mGsmFrPayloadLength, mGsmEfrPayloadType, mGsmHrPayloadType) !=
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
return false;
if (mAmrNbOctetPayloadType != rhs.mAmrNbOctetPayloadType)
return false;
if (mAmrNbPayloadType != rhs.mAmrNbPayloadType)
return false;
if (mAmrWbOctetPayloadType != rhs.mAmrWbOctetPayloadType)
return false;
if (mAmrWbPayloadType != rhs.mAmrWbPayloadType)
return false;
// ToDo: compare EVS and Opus specs
if (mEvsSpec.size() != rhs.mEvsSpec.size())
return false;
for (size_t i = 0; i < mEvsSpec.size(); i++)
if (mEvsSpec[i] != rhs.mEvsSpec[i])
return false;
if (mOpusSpec.size() != rhs.mOpusSpec.size())
return false;
for (size_t i = 0; i < mOpusSpec.size(); i++)
if (mOpusSpec[i] != rhs.mOpusSpec[i])
return false;
return true;
}
// ---------------------------------------- // ----------------------------------------
CodecList::Settings CodecList::Settings::DefaultSettings; CodecList::Settings CodecList::Settings::DefaultSettings;
CodecList::CodecList(const Settings& settings) CodecList::CodecList(const Settings& settings)
:mSettings(settings) :mSettings(settings)
{ {
//mFactoryList.push_back(new OpusCodec::OpusFactory(16000, 1)); init(mSettings);
}
void CodecList::init(const Settings& settings)
{
for (auto f: mFactoryList)
delete f;
mFactoryList.clear();
#if defined(USE_OPUS_CODEC) #if defined(USE_OPUS_CODEC)
if (settings.mOpusSpec.empty()) if (settings.mOpusSpec.empty())
@ -191,8 +258,8 @@ CodecList::CodecList(const Settings& settings)
CodecList::~CodecList() CodecList::~CodecList()
{ {
for (FactoryList::size_type i=0; i<mFactoryList.size(); i++) for (auto f: mFactoryList)
delete mFactoryList[i]; delete f;
} }
int CodecList::count() const int CodecList::count() const
@ -217,10 +284,12 @@ int CodecList::findCodec(const std::string &name) const
void CodecList::fillCodecMap(CodecMap& cm) void CodecList::fillCodecMap(CodecMap& cm)
{ {
cm.clear();
for (auto& factory: mFactoryList) for (auto& factory: mFactoryList)
{ {
// Create codec here. Although they are not needed right now - they can be needed to find codec's info. // Create codec here. Although they are not needed right now - they can be needed to find codec's info.
cm[factory->payloadType()] = factory->create(); PCodec c = factory->create();
cm.insert({factory->payloadType(), c});
} }
} }

View File

@ -69,6 +69,10 @@ public:
Encoding mEncodingType = Encoding_MIME; Encoding mEncodingType = Encoding_MIME;
bool isValid() const; bool isValid() const;
static EvsSpec parse(const std::string& spec); static EvsSpec parse(const std::string& spec);
bool operator == (const EvsSpec& rhs) const { return std::tie(mPayloadType, mBandwidth, mEncodingType) == std::tie(rhs.mPayloadType, rhs.mBandwidth, rhs.mEncodingType);}
bool operator != (const EvsSpec& rhs) const { return ! (operator ==) (rhs);};
}; };
std::vector<EvsSpec> mEvsSpec; std::vector<EvsSpec> mEvsSpec;
@ -79,7 +83,14 @@ public:
int mRate = -1; int mRate = -1;
int mChannels = -1; int mChannels = -1;
OpusSpec(int ptype = -1, int rate = -1, int channels = -1)
:mPayloadType(ptype), mRate(rate), mChannels(channels)
{}
bool isValid() const; bool isValid() const;
bool operator == (const OpusSpec& rhs) const { return std::tie(mPayloadType, mRate, mChannels) == std::tie(rhs.mPayloadType, rhs.mRate, rhs.mChannels);}
bool operator != (const OpusSpec& rhs) const { return ! (operator ==) (rhs);};
static OpusSpec parse(const std::string& spec); static OpusSpec parse(const std::string& spec);
}; };
std::vector<OpusSpec> mOpusSpec; std::vector<OpusSpec> mOpusSpec;
@ -88,20 +99,29 @@ public:
std::string toString() const; std::string toString() const;
static Settings DefaultSettings; static Settings DefaultSettings;
#if defined(USE_RESIP_INTEGRATION)
static Settings parseSdp(const std::list<resip::Codec>& codeclist);
#endif
bool operator == (const Settings& rhs) const;
}; };
CodecList(const Settings& settings); CodecList(const Settings& settings);
~CodecList(); ~CodecList();
void setSettings(const Settings& settings) { init(settings); }
int count() const; int count() const;
Codec::Factory& codecAt(int index) const; Codec::Factory& codecAt(int index) const;
int findCodec(const std::string& name) const; int findCodec(const std::string& name) const;
void fillCodecMap(CodecMap& cm); void fillCodecMap(CodecMap& cm);
protected: protected:
typedef std::vector<Codec::Factory*> FactoryList; typedef std::vector<Codec::Factory*> FactoryList;
FactoryList mFactoryList; FactoryList mFactoryList;
Settings mSettings; Settings mSettings;
void init(const Settings& settings);
}; };
class CodecListPriority class CodecListPriority

View File

@ -203,8 +203,8 @@ NetworkAddress::NetworkAddress(const uint8_t* ip_6, uint16_t port)
mAddr6.sin6_port = port; mAddr6.sin6_port = port;
} }
NetworkAddress::NetworkAddress(const sockaddr& addr, unsigned addrLen) NetworkAddress::NetworkAddress(const sockaddr& addr, size_t addrLen)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
switch (addr.sa_family) switch (addr.sa_family)
{ {

View File

@ -35,7 +35,7 @@ namespace ice
NetworkAddress(const in6_addr& ip, unsigned short port); NetworkAddress(const in6_addr& ip, unsigned short port);
NetworkAddress(const in_addr& ip, unsigned short port); NetworkAddress(const in_addr& ip, unsigned short port);
NetworkAddress(const sockaddr& addr, unsigned addrLen); NetworkAddress(const sockaddr& addr, size_t addrLen);
NetworkAddress(const NetworkAddress& src); NetworkAddress(const NetworkAddress& src);
~NetworkAddress(); ~NetworkAddress();