Refactor project structure
This commit is contained in:
2864
modules/ANSUtilities/ANSAWSS3.cpp
Normal file
2864
modules/ANSUtilities/ANSAWSS3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
953
modules/ANSUtilities/ANSUtilities.cpp
Normal file
953
modules/ANSUtilities/ANSUtilities.cpp
Normal file
@@ -0,0 +1,953 @@
|
||||
#include "ANSUtilities.h"
|
||||
#include <iostream>
|
||||
#include <CkFileAccess.h>
|
||||
#include <CkAuthGoogle.h>
|
||||
#include <CkSocket.h>
|
||||
#include <CkGlobal.h>
|
||||
#include <CkMailMan.h>
|
||||
#include <CkEmail.h>
|
||||
#include <CkMht.h>
|
||||
#include <vector>
|
||||
|
||||
static bool ansutilityLicenceValid = false;
|
||||
static std::once_flag ansutilityLicenseOnceFlag;
|
||||
std::timed_mutex timeImageMutex;
|
||||
|
||||
namespace ANSCENTER
|
||||
{
|
||||
static void VerifyGlobalANSUltilityLicense(const std::string& licenseKey) {
|
||||
try {
|
||||
static const std::vector<std::pair<int, std::string>> licenseChecks = {
|
||||
{1000, "ANNHUB-LV"},
|
||||
{1001, "DLHUB-LV"},
|
||||
{1002, "ODHUB-LV"},
|
||||
{1003, "ANSVIS"},
|
||||
{1004, "ANSFR"},
|
||||
{1005, "ANSOCR"},
|
||||
{1006, "ANSALPR"},
|
||||
{1007, "ANSCV"},
|
||||
{1008, "ANSSRT"}
|
||||
};
|
||||
ansutilityLicenceValid = false;
|
||||
for (const auto& [productId, productName] : licenseChecks) {
|
||||
if (ANSCENTER::ANSLicenseHelper::LicenseVerification(licenseKey, productId, productName)) {
|
||||
ansutilityLicenceValid = true;
|
||||
break; // Stop at the first valid license
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
ansutilityLicenceValid = false;
|
||||
}
|
||||
}
|
||||
ANSUtilities::ANSUtilities() {
|
||||
_unlockCode = "ANSDRC.CB1122026_MEQCIFwO1IFQCG0BhZwsXFO68QUU6mDB5uge4duOsqOJanEyAiAB67ahqnXin4SRy0vIegISgbFlpldmbuS5gbU21GYVqA==";// "ANSDRC.CB1082025_Ax6P3M7F8B3d";//
|
||||
_fireBaseSessionToken = "";
|
||||
_proxyHost = "";
|
||||
_proxyPort = 0;
|
||||
_proxyUsername = "";
|
||||
_proxyPassword = "";
|
||||
_bProxy = false;
|
||||
}
|
||||
void ANSUtilities::CheckLicense() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// Check once globally
|
||||
std::call_once(ansutilityLicenseOnceFlag, [this]() {
|
||||
VerifyGlobalANSUltilityLicense(_licenseKey);
|
||||
});
|
||||
// Update this instance's local license flag
|
||||
_isLicenseValid = ansutilityLicenceValid;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogFatal("ANSUtilities::CheckLicense. Error:", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
void ANSUtilities::CheckUnlockCode() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkGlobal glob;
|
||||
_unlockCode = "ANSDRC.CB1122026_MEQCIFwO1IFQCG0BhZwsXFO68QUU6mDB5uge4duOsqOJanEyAiAB67ahqnXin4SRy0vIegISgbFlpldmbuS5gbU21GYVqA==";// "ANSDRC.CB1082025_Ax6P3M7F8B3d";
|
||||
_isUnlockCodeValid = glob.UnlockBundle(_unlockCode.c_str());
|
||||
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::CheckUnlockCode", glob.lastErrorText(), __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
int status = glob.get_UnlockStatus();
|
||||
if (status != 2) {
|
||||
_logger.LogDebug("ANSUtilities::CheckUnlockCode", "Unlocked in trial mode.", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::CheckUnlockCode", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
ANSUtilities::~ANSUtilities()
|
||||
{
|
||||
_fireBaseSessionToken = "";
|
||||
}
|
||||
bool ANSUtilities::Initialize(const std::string& licenseKey) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_licenseKey = licenseKey;
|
||||
CheckLicense();
|
||||
CheckUnlockCode();
|
||||
return _isLicenseValid && _isUnlockCodeValid;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::Initialize", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
bool ANSUtilities::SetServerProxy(const std::string& proxyHost, int proxyPort, const std::string& proxyUsername, const std::string& proxyPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_proxyHost = proxyHost;
|
||||
_proxyPort = proxyPort;
|
||||
_proxyUsername = proxyUsername;
|
||||
_proxyPassword = proxyPassword;
|
||||
_bProxy = false;
|
||||
|
||||
if (!_proxyHost.empty() && (_proxyPort > 0)) {
|
||||
_bProxy = true;
|
||||
}
|
||||
else {
|
||||
_bProxy = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::SetServerProxy", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::GetFirebaseCloudMessageAcccessToken(std::string privateKey)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isLicenseValid) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
if (!_isUnlockCodeValid) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
try {
|
||||
|
||||
auto currentTime = std::chrono::system_clock::now();
|
||||
|
||||
// Check if we need to generate a new token
|
||||
bool needNewToken = false;
|
||||
|
||||
if (!tokenInitialized) {
|
||||
std::cout << "First time calling getToken(), generating initial token..." << std::endl;
|
||||
needNewToken = true;
|
||||
}
|
||||
else {
|
||||
// Calculate time difference in seconds since token was generated
|
||||
auto timeDiff = std::chrono::duration_cast<std::chrono::seconds>(currentTime - tokenGeneratedTime);
|
||||
long secondsElapsed = timeDiff.count();
|
||||
|
||||
std::cout << "Time since token generated: " << secondsElapsed << " seconds" << std::endl;
|
||||
|
||||
if (secondsElapsed >= TOKEN_EXPIRY_SECONDS) {
|
||||
std::cout << "Token expired (" << secondsElapsed << "s >= " << TOKEN_EXPIRY_SECONDS << "s), regenerating..." << std::endl;
|
||||
needNewToken = true;
|
||||
}
|
||||
else {
|
||||
long remainingTime = TOKEN_EXPIRY_SECONDS - secondsElapsed;
|
||||
std::cout << "Token still valid, " << remainingTime << " seconds remaining" << std::endl;
|
||||
}
|
||||
}
|
||||
if (needNewToken) {
|
||||
CkFileAccess fac;
|
||||
const char* jsonKey = "{"
|
||||
"\"type\": \"service_account\","
|
||||
"\"project_id\": \"ansaiboxpushnotifications\","
|
||||
"\"private_key_id\": \"62f7485c308b9ea613866c24c98736fec498d47d\","
|
||||
"\"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSwXb/N4vPkANa\\nA7nwOTxS9NVCup/9mIdyR7FRYJNV8uHY7699I8LCCvG5rIhWGZ/Rb4Z9ocJKuuj9\\nRelsjTDEWeBU/o8ip41Ru8K3KlOO25HIVDckyhbmfDzzlf8Ham1HhOUZmfDUfQ2d\\n5YoUXflqoCyvOi8aqUgfcP9uZuIpEhyQvjqDfY0d0B36NoXpilFE8IuIlBsnpfZn\\nYkeHs/Cl6CDaKxGeUZmrqinyMH5f7m4Nz30V5s8Xdl4WZdoYhVatn1or57Zjy/zl\\ng+4rWeHRbYrBUJlMb8/7IaaZ7KuDkh0awEFIDvLuNvjXkaGKJT33vxKSsaH4yrhg\\nYiR5OVY3AgMBAAECggEADiUS5f0l4ofhWbS/UXqd7FlnSMO6wivvB0H9ih8ntFCJ\\nTOSFTCpOw3Q1lgcY3WJ54fYQujTVk+togLsk9/af68W2cy3kkGhbaT1nS6DJG+Dr\\nr1zLmKoBkHWNJ7IM/EPt0qt+LtIwoipEdDD4K/bEqx3V8eq/R5RN9WJBmnjIPAZO\\nXYGtTBu66yTjMVX9AFqYGJwaW96mHAi3lI5Mso5wTmFA8tSBiWmiYgpDDUNzu+4w\\nPnbDJabMbv4xnC6UtiqLIvv+P3BWWyLz0bzZ7W9P2fGK9Rz04leTXZlNcfC/IIAr\\nXDPVZfF7E5Wici53Cwc/QnxoCVH9n9hqsyTTUrKYbQKBgQD9WuCLVZRwKnAsW2Wx\\nZjh8Z92aGjIoc/lJTYaFsYGT7Hx496izhmg18kUillUDe/L9gHuDJPIMv89irjV1\\n07jN+z+tANyFT+h/NHCSxreG8FDbo8F88snekMEsBym3CicE/P6aWVx+lIig8rPS\\nHAqA1WOwdFzto/rG4zFKIiajYwKBgQDU9LxgERHwoy8mt2U5h/hg4oiKlycFJCFV\\nsgEqhVFN7Cs8jlov4tJh9863tVeYYGSKrP1HS9dVUE+7VY2qgPbyAtR5QZeHIV+b\\nzMx8o4HVLN4ffmld+/mYiAzIQiQeZOoC0mczakQpRDE8sghQQoYLwEcKXcTkLr75\\nk1XIpT4cHQKBgQCmMSzGeZbrlQsMLdAhdHptMPzuj2yDmL/X0+EAZhYn4KMt/tdN\\nHEfTy16Kd67AoFge7l8XAe89ab0ycDBlYEMD62IzrDL7yBUtDEskHPJas912lo7f\\n1auSMcZliTVV+nTqEsM4oJHJ/sk5Oru2gepp5JCGOW6T/FMOkA3PIWPTHQKBgQCG\\n456Om0Fp03OCaphLoLzLYbJrVuL4drJGvcHPVTLy0K1yZhjqTBpGw9jEtLEPa79D\\nt9+W0YtMFtrqJn7diWLiWLiNNebtSU5uOYMtT8Rla04nVMMZLQoke8jc8EhAmFtB\\n/lQwVRdnrDIj6AEsFXci6mAVSN/2SUXegFzOAx0cYQKBgBYCGGKWd/EFvszO5VS6\\nnegR3fpx4GRShA4iWfbQhPcjPunKthUAUguN4m+FfQuSA6xaBsz+om9hRiSCHe2l\\nGio/U7z2QYznnl/furGXEhS6yE+u3cSN82N0PV/c4XY0DUqKycE6cx9GVTOmx7NP\\n897fh7f103RrGgIRivtM1g3g\\n-----END PRIVATE KEY-----\\n\","
|
||||
"\"client_email\": \"firebase-adminsdk-tcw8f@ansaiboxpushnotifications.iam.gserviceaccount.com\","
|
||||
"\"client_id\": \"108921284506387607836\","
|
||||
"\"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\","
|
||||
"\"token_uri\": \"https://oauth2.googleapis.com/token\","
|
||||
"\"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\","
|
||||
"\"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-tcw8f%40ansaiboxpushnotifications.iam.gserviceaccount.com\","
|
||||
"\"universe_domain\": \"googleapis.com\""
|
||||
"}";
|
||||
if (!_isLicenseValid) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
if (!_isUnlockCodeValid) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
if (privateKey != "62f7485c308b9ea613866c24c98736fec498d47d") {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", "Error: Invalid private key", __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return "Error: Invalid private key";
|
||||
}
|
||||
CkAuthGoogle gAuth;
|
||||
gAuth.put_JsonKey(jsonKey);
|
||||
gAuth.put_Scope("https://www.googleapis.com/auth/cloud-platform");
|
||||
gAuth.put_ExpireNumSeconds(TOKEN_EXPIRY_SECONDS);
|
||||
gAuth.put_SubEmailAddress("");
|
||||
CkSocket tlsSock;
|
||||
bool success = tlsSock.Connect("www.googleapis.com", 443, true, 5000);
|
||||
if (success != true) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", tlsSock.lastErrorText(), __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return std::string("Error:") + tlsSock.lastErrorText();
|
||||
}
|
||||
success = gAuth.ObtainAccessToken(tlsSock);
|
||||
if (success != true) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", gAuth.lastErrorText(), __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return std::string("Error:") + tlsSock.lastErrorText();
|
||||
}
|
||||
_fireBaseSessionToken = gAuth.accessToken();
|
||||
tokenGeneratedTime = currentTime; // Reset the time when token is generated
|
||||
tokenInitialized = true;
|
||||
}
|
||||
return _fireBaseSessionToken;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSUtilities::GetFirebaseCloudMessageAcccessToken()", e.what(), __FILE__, __LINE__);
|
||||
_fireBaseSessionToken = "";
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
|
||||
}
|
||||
std::string ANSUtilities::CreateAWSSNSTopic(const std::string& topicName) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::CreateAWSSNSTopic", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::CreateAWSSNSTopic", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "CreateTopic");
|
||||
_rest.AddQueryParam("Name", topicName.c_str());
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogFatal("ANSUtilities::CreateAWSSNSTopic", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::CreateAWSSNSTopic", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
return xml.chilkatPath("CreateTopicResult|TopicArn|*");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::CreateAWSSNSTopic", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::DeleteAWSSNSTopic(const std::string& topicARN) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::DeleteAWSSNSTopic", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::DeleteAWSSNSTopic", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "DeleteTopic");
|
||||
_rest.AddQueryParam("TopicArn", topicARN.c_str());
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogFatal("ANSUtilities::DeleteAWSSNSTopic", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::DeleteAWSSNSTopic", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::DeleteAWSSNSTopic", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::SubcribeSMSPhoneNumber(const std::string& topicARN, const std::string& phoneNumber) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeSMSPhoneNumber", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeSMSPhoneNumber", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "Subscribe");
|
||||
_rest.AddQueryParam("Endpoint", phoneNumber.c_str()); // Phone number in E.164 format
|
||||
_rest.AddQueryParam("Protocol", "sms");
|
||||
_rest.AddQueryParam("TopicArn", topicARN.c_str());
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::SubscribeSMSPhoneNumber", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::SubscribeSMSPhoneNumber", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
|
||||
return xml.chilkatPath("SubscribeResult|SubscriptionArn|*");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeSMSPhoneNumber", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::SubscribeEmailAddress(const std::string& topicARN, const std::string& emailAddress) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeEmailAddress", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeEmailAddress", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "Subscribe");
|
||||
_rest.AddQueryParam("Endpoint", emailAddress.c_str());
|
||||
_rest.AddQueryParam("Protocol", "email");
|
||||
_rest.AddQueryParam("TopicArn", topicARN.c_str());
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::SubscribeEmailAddress", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::SubscribeEmailAddress", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
return xml.chilkatPath("SubscribeResult|SubscriptionArn|*"); // Usually "pending confirmation"
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::SubscribeEmailAddress", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::SendMessageToTopic(const std::string& topicARN, const std::string& subjectContent, const std::string& messageContent) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToTopic", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToTopic", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "Publish");
|
||||
_rest.AddQueryParam("TopicArn", topicARN.c_str());
|
||||
_rest.AddQueryParam("Subject", subjectContent.c_str()); // Subject line for emails
|
||||
_rest.AddQueryParam("Message", messageContent.c_str()); // The message body
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::SendMessageToTopic", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::SendMessageToTopic", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
|
||||
return xml.chilkatPath("PublishResult|MessageId|*"); // Return the MessageId
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToTopic", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::SendMessageToPhoneNumber(const std::string& phoneNumber, const std::string& messageContent) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToPhoneNumber", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToPhoneNumber", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "Publish");
|
||||
_rest.AddQueryParam("PhoneNumber", phoneNumber.c_str());
|
||||
_rest.AddQueryParam("Message", messageContent.c_str());
|
||||
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::SendMessageToPhoneNumber", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::SendMessageToPhoneNumber", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
|
||||
return xml.chilkatPath("PublishResult|MessageId|*"); // Return the MessageId
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::SendMessageToPhoneNumber", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::ListAWSSNSTopic() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::ListAWSSNSTopic", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return "Error: Invalid unlock code";
|
||||
}
|
||||
|
||||
if (!_isLicenseValid) {
|
||||
_logger.LogFatal("ANSUtilities::ListAWSSNSTopic", "Error: Invalid license key", __FILE__, __LINE__);
|
||||
return "Error: Invalid license key";
|
||||
}
|
||||
|
||||
try {
|
||||
CkRest _rest;
|
||||
_rest.AddQueryParam("Action", "ListTopics");
|
||||
const char* responseXml = _rest.fullRequestNoBody("GET", "/");
|
||||
if (!_rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::ListAWSSNSTopic", _rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.lastErrorText());
|
||||
}
|
||||
|
||||
if (_rest.get_ResponseStatusCode() != 200) {
|
||||
_logger.LogError("ANSUtilities::ListAWSSNSTopic", _rest.responseHeader(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(_rest.responseHeader());
|
||||
}
|
||||
|
||||
CkXml xml;
|
||||
xml.LoadXml(responseXml);
|
||||
|
||||
// Move to Topics list
|
||||
xml.chilkatPath("ListTopicsResult|Topics|$");
|
||||
|
||||
int numTopics = xml.get_NumChildren();
|
||||
std::vector<std::string> topics;
|
||||
topics.reserve(numTopics); // Slight optimization
|
||||
|
||||
for (int i = 0; i < numTopics; ++i) {
|
||||
xml.GetChild2(i);
|
||||
topics.emplace_back(xml.getChildContent("TopicArn"));
|
||||
xml.GetParent2();
|
||||
}
|
||||
|
||||
if (topics.empty()) {
|
||||
_logger.LogError("ANSUtilities::ListAWSSNSTopic", "No topics found", __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
|
||||
// Concatenate topics with ';'
|
||||
std::string topicsStr;
|
||||
for (size_t i = 0; i < topics.size(); ++i) {
|
||||
topicsStr += topics[i];
|
||||
if (i + 1 != topics.size()) {
|
||||
topicsStr += ";";
|
||||
}
|
||||
}
|
||||
|
||||
return topicsStr;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::ListAWSSNSTopic", e.what(), __FILE__, __LINE__);
|
||||
return "Error: " + std::string(e.what());
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::AuthenticateGCS(const std::string& jsonKeyFile) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::AuthenticateGCS", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_isAuthenticated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
_authGoogle.put_JsonKey(jsonKeyFile.c_str());
|
||||
_authGoogle.put_Scope("https://www.googleapis.com/auth/cloud-platform");
|
||||
_authGoogle.put_ExpireNumSeconds(3600); // 1 hour token
|
||||
_authGoogle.put_SubEmailAddress("");
|
||||
|
||||
CkSocket tlsSock;
|
||||
bool success = tlsSock.Connect("www.googleapis.com", 443, true, 5000);
|
||||
if (!success) {
|
||||
_logger.LogError("ANSUtilities::AuthenticateGCS", tlsSock.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
success = _authGoogle.ObtainAccessToken(tlsSock);
|
||||
if (!success) {
|
||||
_logger.LogError("ANSUtilities::AuthenticateGCS", _authGoogle.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_authGoogle.accessToken()) {
|
||||
_logger.LogError("ANSUtilities::AuthenticateGCS", _authGoogle.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
_isAuthenticated = true;
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::AuthenticateGCS", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::UploadMatToGCS(const std::string& bucketName, const std::string& objectName, const cv::Mat& image) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isAuthenticated) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", "Not authenticated. Call AuthenticateGCS() first.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
CkRest rest;
|
||||
CkSocket _gcsSocket;
|
||||
|
||||
std::string gcsHost = "www.googleapis.com";
|
||||
bool bTls = true;
|
||||
bool autoReconnect = true;
|
||||
int port = 443;
|
||||
int maxWaitMs = 15000;
|
||||
if (_bProxy) {
|
||||
if (!_proxyHost.empty() && (_proxyPort > 0)) {
|
||||
_gcsSocket.put_HttpProxyHostname(_proxyHost.c_str());
|
||||
_gcsSocket.put_HttpProxyPort(_proxyPort);
|
||||
_gcsSocket.put_HttpProxyUsername(_proxyUsername.c_str());
|
||||
_gcsSocket.put_HttpProxyPassword(_proxyPassword.c_str());
|
||||
_gcsSocket.put_HttpProxyForHttp(true);
|
||||
|
||||
if (!_gcsSocket.Connect(gcsHost.c_str(), port, bTls, maxWaitMs)) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", _gcsSocket.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind socket to rest
|
||||
if (!rest.UseConnection(_gcsSocket, autoReconnect)) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
rest.SetAuthGoogle(_authGoogle);
|
||||
}
|
||||
else {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", "Invalid proxy hostname and port", __FILE__, __LINE__);
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
else { // No proxy
|
||||
rest.SetAuthGoogle(_authGoogle);
|
||||
// Connect to Google Cloud Storage REST API
|
||||
if (!rest.Connect(gcsHost.c_str(), port, bTls, autoReconnect)) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Convert cv::Mat to JPEG binary
|
||||
std::vector<uchar> jpegBuffer;
|
||||
std::vector<int> compressionParams = { cv::IMWRITE_JPEG_QUALITY, 90 };
|
||||
if (!cv::imencode(".jpg", image, jpegBuffer, compressionParams)) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", "Failed to encode cv::Mat as JPEG.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
// Convert std::vector<uchar> to CkByteData
|
||||
CkByteData jpegBytes;
|
||||
if (!jpegBuffer.empty()) {
|
||||
jpegBytes.append2(jpegBuffer.data(), static_cast<unsigned long>(jpegBuffer.size()));
|
||||
}
|
||||
|
||||
// Prepare the HTTP request to upload the file
|
||||
std::string urlPath = "/upload/storage/v1/b/" + bucketName + "/o?uploadType=media&name=" + objectName;
|
||||
rest.AddHeader("Content-Type", "image/jpeg");
|
||||
|
||||
// Upload the JPEG data to GCS
|
||||
std::string jsonResponse = rest.fullRequestBinary("POST", urlPath.c_str(), jpegBytes);
|
||||
if (!rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int statusCode = rest.get_ResponseStatusCode();
|
||||
if (statusCode != 200) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.responseHeader(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogDebug("ANSUtilities::UploadMatToGCS", "Upload successful. Status Code: " + std::to_string(statusCode), __FILE__, __LINE__);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSUtilities::UploadMatToGCS(const std::string& bucketName, const std::string& objectName, unsigned char* jpeg_string, int32 bufferLength) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", "Error: Invalid unlock code", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isAuthenticated) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", "Not authenticated. Call AuthenticateGCS() first.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
if(bufferLength<=0) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", "Invalid buffer length", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
CkRest rest;
|
||||
CkSocket _gcsSocket;
|
||||
std::string gcsHost = "www.googleapis.com";
|
||||
bool bTls = true;
|
||||
bool autoReconnect = true;
|
||||
int port = 443;
|
||||
int maxWaitMs = 15000;
|
||||
if (_bProxy) {
|
||||
if (!_proxyHost.empty() && (_proxyPort > 0)) {
|
||||
_gcsSocket.put_HttpProxyHostname(_proxyHost.c_str());
|
||||
_gcsSocket.put_HttpProxyPort(_proxyPort);
|
||||
_gcsSocket.put_HttpProxyUsername(_proxyUsername.c_str());
|
||||
_gcsSocket.put_HttpProxyPassword(_proxyPassword.c_str());
|
||||
_gcsSocket.put_HttpProxyForHttp(true);
|
||||
|
||||
if (!_gcsSocket.Connect(gcsHost.c_str(), port, bTls, maxWaitMs)) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", _gcsSocket.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
// Bind socket to rest
|
||||
if (!rest.UseConnection(_gcsSocket, autoReconnect)) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
rest.SetAuthGoogle(_authGoogle);
|
||||
}
|
||||
else {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", "Invalid proxy hostname and port", __FILE__, __LINE__);
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
else { // No proxy
|
||||
rest.SetAuthGoogle(_authGoogle);
|
||||
// Connect to Google Cloud Storage REST API
|
||||
if (!rest.Connect(gcsHost.c_str(), port, bTls, autoReconnect)) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert std::vector<uchar> to CkByteData
|
||||
CkByteData jpegBytes;
|
||||
jpegBytes.append2(jpeg_string, static_cast<unsigned long>(bufferLength));
|
||||
|
||||
// Prepare the HTTP request to upload the file
|
||||
std::string urlPath = "/upload/storage/v1/b/" + bucketName + "/o?uploadType=media&name=" + objectName;
|
||||
rest.AddHeader("Content-Type", "image/jpeg");
|
||||
|
||||
// Upload the JPEG data to GCS
|
||||
std::string jsonResponse = rest.fullRequestBinary("POST", urlPath.c_str(), jpegBytes);
|
||||
if (!rest.get_LastMethodSuccess()) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.lastErrorText(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int statusCode = rest.get_ResponseStatusCode();
|
||||
if (statusCode != 200) {
|
||||
_logger.LogError("ANSUtilities::UploadMatToGCS", rest.responseHeader(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogDebug("ANSUtilities::UploadMatToGCS", "Upload successful. Status Code: " + std::to_string(statusCode), __FILE__, __LINE__);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSUtilities::UploadMatToGCS", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::SendEmail(const std::string& smtpServer, int port,
|
||||
const std::string& userName, const std::string& password,
|
||||
const std::string& subjectContent,
|
||||
const std::string& bodyHTMLContent,
|
||||
const std::string& bodyTextContent,
|
||||
const std::string& fromEmailSender,
|
||||
const std::vector<std::string>& toEmails,
|
||||
const std::vector<std::string>& ccEmails,
|
||||
const std::vector<std::string>& bccEmails)
|
||||
|
||||
{
|
||||
std::unique_lock<std::timed_mutex> lock(timeImageMutex, std::defer_lock);
|
||||
if (!lock.try_lock_for(std::chrono::milliseconds(45000))) {
|
||||
std::cerr << "Error: Mutex timeout in ANSUtilities::SendEmail!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!CheckUnlockCode_S()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// The mailman object is used for sending and receiving email.
|
||||
CkMailMan mailman;
|
||||
mailman.put_SmtpHost(smtpServer.c_str());
|
||||
mailman.put_SmtpPort(port);
|
||||
mailman.put_StartTLS(true);//STARTTLS
|
||||
// Set the SMTP login/password
|
||||
mailman.put_SmtpUsername(userName.c_str());
|
||||
mailman.put_SmtpPassword(password.c_str());
|
||||
|
||||
CkEmail email;
|
||||
if (!bodyHTMLContent.empty()) {
|
||||
CkMht mht;
|
||||
mht.put_UseCids(true);
|
||||
const char* mime = 0;
|
||||
mime = mht.htmlToEML(bodyHTMLContent.c_str());
|
||||
bool setmime = email.SetFromMimeText(mime);
|
||||
email.ConvertInlineImages();
|
||||
}
|
||||
email.put_Subject(subjectContent.c_str());
|
||||
if (!bodyTextContent.empty())
|
||||
email.put_Body(bodyTextContent.c_str());
|
||||
email.put_From(fromEmailSender.c_str());
|
||||
for (const auto& toEmail : toEmails) {
|
||||
email.AddTo("", toEmail.c_str());
|
||||
}
|
||||
for (const auto& ccEmail : ccEmails) {
|
||||
email.AddCC("", ccEmail.c_str());
|
||||
}
|
||||
for (const auto& bccEmail : bccEmails) {
|
||||
email.AddBcc("", bccEmail.c_str());
|
||||
}
|
||||
|
||||
bool success = mailman.SendEmail(email);
|
||||
if (success != true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
success = mailman.CloseSmtpConnection();
|
||||
if (success != true) {
|
||||
}
|
||||
return success;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::CheckUnlockCode_S() {
|
||||
static std::once_flag unlockOnceFlag;
|
||||
static bool isUnlockValid = false;
|
||||
try {
|
||||
std::call_once(unlockOnceFlag, []() {
|
||||
CkGlobal glob;
|
||||
const std::string unlockCode = "ANSDRC.CB1122026_MEQCIFwO1IFQCG0BhZwsXFO68QUU6mDB5uge4duOsqOJanEyAiAB67ahqnXin4SRy0vIegISgbFlpldmbuS5gbU21GYVqA==";// "ANSDRC.CB1082025_Ax6P3M7F8B3d";
|
||||
if (glob.UnlockBundle(unlockCode.c_str()) && glob.get_UnlockStatus() == 2) {
|
||||
isUnlockValid = true;
|
||||
}
|
||||
});
|
||||
return isUnlockValid;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::AESEncryption(const std::string& inputString, const std::string& inputKey) {
|
||||
if (!CheckUnlockCode_S()) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
CkCrypt2 crypt;
|
||||
// AES is also known as Rijndael.
|
||||
crypt.put_CryptAlgorithm("aes");
|
||||
// CipherMode may be "ecb", "cbc", "ofb", "cfb", "gcm", etc.
|
||||
crypt.put_CipherMode("cbc");
|
||||
// KeyLength may be 128, 192, 256
|
||||
crypt.put_KeyLength(256);
|
||||
// The padding scheme determines the contents of the bytes
|
||||
// that are added to pad the result to a multiple of the
|
||||
// encryption algorithm's block size. AES has a block
|
||||
// size of 16 bytes, so encrypted output is always
|
||||
// a multiple of 16.
|
||||
crypt.put_PaddingScheme(0); // 0 = RFC 1423 padding scheme
|
||||
// EncodingMode specifies the encoding of the output for
|
||||
// encryption, and the input for decryption.
|
||||
// It may be "hex", "url", "base64", or "quoted-printable".
|
||||
crypt.put_EncodingMode("base64");
|
||||
|
||||
// Ensure inputKey is exactly 16 characters for IV.
|
||||
std::string ivKey = inputKey.substr(0, std::min<size_t>(16, inputKey.size()));
|
||||
if (ivKey.size() < 16) {
|
||||
ivKey.append(16 - ivKey.size(), 'A'); // Pad with spaces if less than 16 characters
|
||||
}
|
||||
crypt.SetEncodedIV(ivKey.c_str(), "ascii");
|
||||
|
||||
// The secret key must equal the size of the key. For
|
||||
// 256-bit encryption, the binary secret key is 32 bytes.
|
||||
// For 128-bit encryption, the binary secret key is 16 bytes.
|
||||
std::string secreteKey = inputKey.substr(0, std::min<size_t>(32, inputKey.size()));
|
||||
if (secreteKey.size() < 32) {
|
||||
secreteKey.append(32 - secreteKey.size(), 'A'); // Pad with spaces if less than 32 characters
|
||||
}
|
||||
crypt.SetEncodedKey(secreteKey.c_str(), "ascii");
|
||||
const char* encStr = crypt.encryptStringENC(inputString.c_str());
|
||||
return encStr ? std::string(encStr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
// Optional: If you want logging, consider static logging in static functions
|
||||
return "";
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::AESDecryption(const std::string& encryptString, const std::string& inputKey) {
|
||||
if (!CheckUnlockCode_S()) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
CkCrypt2 crypt;
|
||||
// AES is also known as Rijndael.
|
||||
crypt.put_CryptAlgorithm("aes");
|
||||
// CipherMode may be "ecb", "cbc", "ofb", "cfb", "gcm", etc.
|
||||
crypt.put_CipherMode("cbc");
|
||||
// KeyLength may be 128, 192, 256
|
||||
crypt.put_KeyLength(256);
|
||||
// The padding scheme determines the contents of the bytes
|
||||
// that are added to pad the result to a multiple of the
|
||||
// encryption algorithm's block size. AES has a block
|
||||
// size of 16 bytes, so encrypted output is always
|
||||
// a multiple of 16.
|
||||
crypt.put_PaddingScheme(0); // 0 = RFC 1423 padding scheme
|
||||
// EncodingMode specifies the encoding of the output for
|
||||
// encryption, and the input for decryption.
|
||||
// It may be "hex", "url", "base64", or "quoted-printable".
|
||||
crypt.put_EncodingMode("base64");
|
||||
|
||||
// Ensure inputKey is exactly 16 characters for IV.
|
||||
std::string ivKey = inputKey.substr(0, std::min<size_t>(16, inputKey.size()));
|
||||
if (ivKey.size() < 16) {
|
||||
ivKey.append(16 - ivKey.size(), 'A'); // Pad with spaces if less than 16 characters
|
||||
}
|
||||
crypt.SetEncodedIV(ivKey.c_str(), "ascii");
|
||||
|
||||
// The secret key must equal the size of the key. For
|
||||
// 256-bit encryption, the binary secret key is 32 bytes.
|
||||
// For 128-bit encryption, the binary secret key is 16 bytes.
|
||||
std::string secreteKey = inputKey.substr(0, std::min<size_t>(32, inputKey.size()));
|
||||
if (secreteKey.size() < 32) {
|
||||
secreteKey.append(32 - secreteKey.size(), 'A'); // Pad with spaces if less than 32 characters
|
||||
}
|
||||
crypt.SetEncodedKey(secreteKey.c_str(), "ascii");
|
||||
const char* decStr = crypt.decryptStringENC(encryptString.c_str());
|
||||
return decStr ? std::string(decStr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
// Optional: If you want logging, consider static logging in static functions
|
||||
return "";
|
||||
}
|
||||
}
|
||||
std::string ANSUtilities::MD5HashFile(const std::string& inputFilePath) {
|
||||
if (!CheckUnlockCode_S()) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
CkCrypt2 crypt;
|
||||
|
||||
// Set the name of the hash algorithm.
|
||||
// Other choices include "sha1", "sha256", "sha384", "sha512", "md2", "md5", and "haval".
|
||||
crypt.put_HashAlgorithm("md5");
|
||||
|
||||
// EncodingMode specifies the encoding of the hash output.
|
||||
// It may be "hex", "url", "base64", or "quoted-printable".
|
||||
crypt.put_EncodingMode("hex");
|
||||
|
||||
// Files of any type may be hashed -- it doesn't matter
|
||||
// if the file is binary or text...
|
||||
const char* hashStr = nullptr;
|
||||
hashStr = crypt.hashFileENC(inputFilePath.c_str());
|
||||
return hashStr ? std::string(hashStr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
// Optional: If you want logging, consider static logging in static functions
|
||||
return "";
|
||||
}
|
||||
}
|
||||
bool ANSUtilities::RestartPC() {
|
||||
try {
|
||||
return system("shutdown /r /t 0") == 0;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
282
modules/ANSUtilities/ANSUtilities.h
Normal file
282
modules/ANSUtilities/ANSUtilities.h
Normal file
@@ -0,0 +1,282 @@
|
||||
#ifndef ANSULT_H
|
||||
#define ANSULT_H
|
||||
#define ANSULT_API __declspec(dllexport)
|
||||
#pragma once
|
||||
#include "LabVIEWHeader/extcode.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "ANSLicense.h"
|
||||
#include <CkRest.h>
|
||||
#include "CkAuthGoogle.h"
|
||||
#include "CkByteData.h"
|
||||
#include <CkAuthAws.h>
|
||||
#include <CkXml.h>
|
||||
#include <CkCrypt2.h>
|
||||
#include <CkSocket.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace ANSCENTER {
|
||||
class ANSULT_API ANSUtilities {
|
||||
private:
|
||||
// Protects all shared mutable data
|
||||
mutable std::recursive_mutex _mutex;
|
||||
bool _isUnlockCodeValid{ false};
|
||||
bool _isLicenseValid{ false};
|
||||
std::string _licenseKey;
|
||||
std::string _unlockCode;
|
||||
std::string _proxyHost;
|
||||
int _proxyPort{ 0 };
|
||||
std::string _proxyUsername;
|
||||
std::string _proxyPassword;
|
||||
bool _bProxy{ false };
|
||||
|
||||
std::string _fireBaseSessionToken;
|
||||
|
||||
bool _bTls{ true };
|
||||
int _port{ 443 };
|
||||
bool _bAutoReconnect{ true };
|
||||
bool _isAWSConnected{ false };
|
||||
|
||||
|
||||
// Google Cloud Storage Authentication
|
||||
CkAuthGoogle _authGoogle;
|
||||
bool _isAuthenticated{ false };
|
||||
|
||||
SPDLogger& _logger = SPDLogger::GetInstance("ANSUtilities", false);
|
||||
|
||||
|
||||
std::chrono::system_clock::time_point tokenGeneratedTime;
|
||||
bool tokenInitialized = false;
|
||||
static const int TOKEN_EXPIRY_SECONDS = 3600;
|
||||
public:
|
||||
ANSUtilities();
|
||||
~ANSUtilities();
|
||||
[[nodiscard]] bool Initialize(const std::string& licenseKey);
|
||||
void CheckLicense();
|
||||
void CheckUnlockCode();
|
||||
[[nodiscard]] bool SetServerProxy(const std::string& proxyHost, int proxyPort, const std::string& proxyUsername, const std::string& proxyPassword);
|
||||
|
||||
[[nodiscard]] std::string GetFirebaseCloudMessageAcccessToken(std::string privateKey);
|
||||
//AWS SNS Functions
|
||||
[[nodiscard]] std::string CreateAWSSNSTopic(const std::string& topicName); // Will return the ARN of the topic
|
||||
[[nodiscard]] bool DeleteAWSSNSTopic(const std::string& topicARN); // Will return the ARN of the topic
|
||||
[[nodiscard]] std::string ListAWSSNSTopic(); // Will return the list ARN of the topic in string with ; concatenated
|
||||
[[nodiscard]] std::string SubcribeSMSPhoneNumber(const std::string& topicARN, const std::string& phoneNumber);
|
||||
[[nodiscard]] std::string SubscribeEmailAddress(const std::string& topicARN, const std::string& emailAddress);
|
||||
[[nodiscard]] std::string SendMessageToTopic(const std::string& topicARN, const std::string& subjectContent, const std::string& messageContent);// Return the message ID
|
||||
[[nodiscard]] std::string SendMessageToPhoneNumber(const std::string& phoneNumber, const std::string& messageContent);// Return the message ID
|
||||
// Google Cloud Storage Upload using Chilkat
|
||||
[[nodiscard]] bool AuthenticateGCS(const std::string& jsonKeyString);
|
||||
[[nodiscard]] bool UploadMatToGCS(const std::string& bucketName, const std::string& objectName, const cv::Mat& image);
|
||||
[[nodiscard]] bool UploadMatToGCS(const std::string& bucketName, const std::string& objectName, unsigned char* jpeg_string, int32 bufferLength);
|
||||
|
||||
[[nodiscard]] static bool CheckUnlockCode_S();
|
||||
[[nodiscard]] static std::string AESEncryption(const std::string& inputString, const std::string& inputKey);
|
||||
[[nodiscard]] static std::string AESDecryption(const std::string& encryptString, const std::string& inputKey);
|
||||
[[nodiscard]] static std::string MD5HashFile(const std::string& inputFilePath);
|
||||
// SMTP for office360 email sending
|
||||
[[nodiscard]] static bool SendEmail(const std::string& smtpServer, int port,
|
||||
const std::string& userName, const std::string& password,
|
||||
const std::string& subjectContent,
|
||||
const std::string& bodyHTMLContent,
|
||||
const std::string& bodyTextContent,
|
||||
const std::string& fromEmailSender,
|
||||
const std::vector<std::string>& toEmails,
|
||||
const std::vector<std::string>& ccEmails,
|
||||
const std::vector<std::string>& bccEmails);
|
||||
|
||||
// Restart PC
|
||||
[[nodiscard]] static bool RestartPC();
|
||||
};
|
||||
// Connection bundle for pool
|
||||
struct S3Connection {
|
||||
CkRest rest;
|
||||
CkSocket socket;
|
||||
CkAuthAws authAws;
|
||||
};
|
||||
|
||||
class ANSULT_API ANSAWSS3 {
|
||||
private:
|
||||
bool _isUnlockCodeValid{ false };
|
||||
bool _isLicenseValid{ false };
|
||||
bool _bConnected{ false };
|
||||
bool _bAwsPath{ true }; // true = virtual-hosted (AWS), false = path-style (MinIO)
|
||||
std::string _licenseKey;
|
||||
std::string _unlockCode;
|
||||
|
||||
// ── Connection pool (replaces single _rest/_socket/_authAws) ──
|
||||
std::mutex _poolMutex;
|
||||
std::vector<std::unique_ptr<S3Connection>> _pool;
|
||||
|
||||
// ── Config (read-only after setup, protected by _configMutex) ──
|
||||
std::mutex _configMutex;
|
||||
std::string _fullAWSURL; // AWS S3 service URL
|
||||
bool _bTls{ true };
|
||||
int _port{ 443 };
|
||||
bool _bAutoReconnect{ true };
|
||||
|
||||
std::string _serviceName;
|
||||
std::string _bucketRegion;
|
||||
std::string _baseDomain;
|
||||
std::string _accessKey;
|
||||
std::string _secretKey;
|
||||
bool _authReady{ false };
|
||||
|
||||
// Proxy settings
|
||||
std::string _proxyHost;
|
||||
int _proxyPort{ 0 };
|
||||
std::string _proxyUsername;
|
||||
std::string _proxyPassword;
|
||||
bool _bProxy{ false };
|
||||
SPDLogger& _logger = SPDLogger::GetInstance("ANSAWSS3", false);
|
||||
|
||||
// Pool helpers
|
||||
std::unique_ptr<S3Connection> CreateConnection();
|
||||
std::unique_ptr<S3Connection> AcquireConnection();
|
||||
void ReleaseConnection(std::unique_ptr<S3Connection> conn);
|
||||
|
||||
std::string ExtractFileName(const std::string& filePath);
|
||||
std::string GetContentType(const std::string& filePath);
|
||||
|
||||
// Background retry
|
||||
std::thread _retryThread;
|
||||
std::atomic<bool> _stopRetry{ false };
|
||||
std::atomic<bool> _retryInProgress{ false };
|
||||
void StopRetry();
|
||||
void RetryLoop();
|
||||
bool TryConnect(bool& awsPath);
|
||||
|
||||
public:
|
||||
ANSAWSS3();
|
||||
~ANSAWSS3();
|
||||
[[nodiscard]] bool Initialize(const std::string& licenseKey);
|
||||
void CheckLicense();
|
||||
void CheckUnlockCode();
|
||||
[[nodiscard]] bool SetServerProxy(const std::string& proxyHost, int proxyPort, const std::string& proxyUsername, const std::string& proxyPassword);
|
||||
// Returns: 1 = connected, 0 = failed (bad auth/URL), 2 = no internet (background retry started)
|
||||
[[nodiscard]] int Connect(const std::string& baseDomain, const std::string& bucketRegion, const std::string& serviceName, int port, bool bTls, bool autoReconnect, bool& awsPath);
|
||||
[[nodiscard]] bool SetAuthentication(const std::string& accessKey, const std::string& secretKey);
|
||||
[[nodiscard]] std::vector<std::string> ListBuckets();
|
||||
[[nodiscard]] std::vector<std::string> ListBucketObjects(const std::string& bucketName);
|
||||
[[nodiscard]] std::vector<std::string> ListBucketObjectsWithPrefix(const std::string& bucketName, const std::string& prefix);
|
||||
[[nodiscard]] bool CreateBucket(const std::string& bucketName);
|
||||
[[nodiscard]] bool DeleteBucket(const std::string& bucketName);
|
||||
|
||||
[[nodiscard]] bool CreateFolder(const std::string& bucketName, const std::string& prefix);
|
||||
[[nodiscard]] bool DeleteFolder(const std::string& bucketName, const std::string& prefix);
|
||||
[[nodiscard]] bool DeleteBucketObject(const std::string& bucketName, const std::string& objectName);
|
||||
[[nodiscard]] std::string GetBucketRegion(const std::string& bucketName);
|
||||
|
||||
// Upload data to AWS S3
|
||||
[[nodiscard]] bool UploadTextData(const std::string& bucketName, const std::string &textFilePath, std::string& uploadedFilePath);
|
||||
[[nodiscard]] bool UploadFileStream(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath);
|
||||
|
||||
[[nodiscard]] bool UploadBinaryData(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath);
|
||||
[[nodiscard]] bool UploadPrefixBinaryData(const std::string& bucketName, const std::string& prefix, const std::string& dataFilePath, const std::string& objectName, std::string& uploadedFilePath);
|
||||
|
||||
[[nodiscard]] bool UploadMultipartData(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath, int partSize=5242880);
|
||||
[[nodiscard]] bool UploadPrefixMultipartData(const std::string& bucketName, const std::string& prefix, const std::string& dataFilePath, const std::string& fileName, std::string& uploadedFilePath, int partSize= 5242880);
|
||||
|
||||
[[nodiscard]] bool UploadPrefixJpegImage(const std::string& bucketName, const std::string& prefix, unsigned char* jpeg_string, int32 bufferLength, const std::string& fileName, std::string& uploadedFilePath);
|
||||
[[nodiscard]] bool UploadJpegImage(const std::string& bucketName, unsigned char* jpeg_string, int32 bufferLength, const std::string& fileName, std::string& uploadedFilePath);
|
||||
[[nodiscard]] bool DownloadFile(const std::string& bucketName, const std::string& objectName, const std::string& saveFilePath);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern "C" ANSULT_API int CreateANSUtilityHandle(ANSCENTER::ANSUtilities** Handle, const char* licenseKey);
|
||||
extern "C" ANSULT_API int ReleaseANSUtilityHandle(ANSCENTER::ANSUtilities** Handle);
|
||||
extern "C" ANSULT_API int GetFCMAccessToken(ANSCENTER::ANSUtilities** Handle, const char* privateKey, LStrHandle accessToken);
|
||||
extern "C" ANSULT_API int CreateAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, LStrHandle arnTopic);
|
||||
extern "C" ANSULT_API int DeleteAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* arnTopic);
|
||||
extern "C" ANSULT_API int ListASWTopics(ANSCENTER::ANSUtilities** Handle, LStrHandle arnTopics);
|
||||
extern "C" ANSULT_API int AESEncryption(const char* inputString, const char* inputKey, LStrHandle encryptionMessage);
|
||||
extern "C" ANSULT_API int AESDecryption(const char* encryptedString, const char* inputKey, LStrHandle decryptionMessage);
|
||||
extern "C" ANSULT_API int MD5HashFile(const char* filePath, LStrHandle decryptionMessage);
|
||||
|
||||
extern "C" ANSULT_API int SubcribeSMSPhoneNumberAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* phoneNumber, LStrHandle subscribedARN);
|
||||
extern "C" ANSULT_API int SubcribeEmailAddressAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* emailAddress, LStrHandle subscribedARN);
|
||||
extern "C" ANSULT_API int SendMessageToAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* subjectContent,const char * messageContent, LStrHandle messageId);
|
||||
extern "C" ANSULT_API int SendMessageToPhoneNumber(ANSCENTER::ANSUtilities** Handle, const char* phoneNumber, const char* messageContent, LStrHandle messageId);
|
||||
|
||||
extern "C" ANSULT_API int GetFCMAccessTokenCpp(ANSCENTER::ANSUtilities** Handle, const char* privateKey, std::string &accessToken);
|
||||
extern "C" ANSULT_API int CreateAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, std::string& arnTopic);
|
||||
extern "C" ANSULT_API int SubcribeSMSPhoneNumberAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* phoneNumber, std::string& subscribedARN);
|
||||
extern "C" ANSULT_API int SubcribeEmailAddressAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* emailAddress, std::string& subscribedARN);
|
||||
extern "C" ANSULT_API int SendMessageToAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* subjectContent, const char* messageContent, std::string& messageId);
|
||||
extern "C" ANSULT_API int SendMessageToPhoneNumberCpp(ANSCENTER::ANSUtilities** Handle, const char* phoneNumber, const char* messageContent, std::string& messageId);
|
||||
extern "C" ANSULT_API int ListASWTopicsCpp(ANSCENTER::ANSUtilities** Handle, std::string& arnTopics);
|
||||
|
||||
// Static functions
|
||||
extern "C" ANSULT_API int AESEncryptionCpp(const char* inputString, const char* inputKey, std::string& encryptedString);
|
||||
extern "C" ANSULT_API int AESDecryptionCpp(const char* encryptedString, const char* inputKey, std::string& decryptionMessage);
|
||||
|
||||
// Google Cloud Storage
|
||||
extern "C" ANSULT_API int SetupServerProxy(ANSCENTER::ANSUtilities** Handle, const char* hostName, int port, const char* userName, const char* passWord);
|
||||
extern "C" ANSULT_API int AuthenticateGCS(ANSCENTER::ANSUtilities** Handle, const char* jsonKeyString);
|
||||
extern "C" ANSULT_API int UploadMatToGCS(ANSCENTER::ANSUtilities** Handle, const char* bucketName, const char* objectName, unsigned char* jpeg_string, int32 bufferLength);
|
||||
extern "C" ANSULT_API int UploadImageToGCS(ANSCENTER::ANSUtilities** Handle, const char* bucketName, const char* objectName, cv::Mat image);
|
||||
extern "C" ANSULT_API int SendEmail(const char* smtpServer, int port,
|
||||
const char* userName, const char* password,
|
||||
const char* title, const char* bodyHTMLContent,
|
||||
const char* bodyTextContent,
|
||||
const char* fromEmailSender,
|
||||
const char* toEmails,
|
||||
const char* ccEmails,
|
||||
const char* bccEmails);
|
||||
|
||||
extern "C" ANSULT_API int RebootSystem();
|
||||
|
||||
|
||||
// AWS S3 class
|
||||
|
||||
extern "C" ANSULT_API int CreateANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* licenseKey);
|
||||
extern "C" ANSULT_API int ReleaseANSAWSHandle(ANSCENTER::ANSAWSS3** Handle);
|
||||
|
||||
extern "C" ANSULT_API int ConnectANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* baseDomain, const char* bucketRegion, const char* serviceName, int port, int bTls, int autoReconnect, int* awsPath);
|
||||
extern "C" ANSULT_API int SetProxyANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* proxyHost, int proxyPort, const char* proxyUsername, const char* proxyPassword);
|
||||
extern "C" ANSULT_API int SetAuthenticationANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* accessKey, const char* secretKey);
|
||||
|
||||
extern "C" ANSULT_API int ListBucketANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, std::string &bucketList);
|
||||
extern "C" ANSULT_API int ListBucketObjectsANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, std::string& bucketNameList);
|
||||
extern "C" ANSULT_API int ListBucketObjectsWithPrefixANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, std::string& bucketNameList);
|
||||
extern "C" ANSULT_API int GetRegionANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, std::string& region);
|
||||
|
||||
extern "C" ANSULT_API int ListBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, LStrHandle bucketList);
|
||||
extern "C" ANSULT_API int ListBucketObjectsANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, LStrHandle bucketNameList);
|
||||
extern "C" ANSULT_API int ListBucketObjectsWithPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, LStrHandle bucketNameList);
|
||||
|
||||
extern "C" ANSULT_API int GetRegionANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, LStrHandle region);
|
||||
extern "C" ANSULT_API int CreateBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName);
|
||||
extern "C" ANSULT_API int DeleteBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName);
|
||||
extern "C" ANSULT_API int CreateBucketPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char *prefix);
|
||||
extern "C" ANSULT_API int DeleteBucketPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix);
|
||||
extern "C" ANSULT_API int DeleteBucketObjectANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* bucketObject);
|
||||
|
||||
extern "C" ANSULT_API int UploadTextDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* textDataPath, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadBinaryDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* binaryDataPath, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadFileStreamDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadMultiPartDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, int fileSize, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadJpegImageANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, LStrHandle uploadedFilePath);
|
||||
|
||||
extern "C" ANSULT_API int UploadPrefixBinaryDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* binaryDataPath, const char* objectName, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadPrefixMultiPartDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* fileDataPath, const char* objectName, int fileSize, LStrHandle uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadPrefixJpegImageANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, LStrHandle uploadedFilePath);
|
||||
|
||||
extern "C" ANSULT_API int DownloadFileStreamANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* objectName, const char* savedFilePath);
|
||||
|
||||
// C++ test APIs (use std::string& instead of LStrHandle)
|
||||
extern "C" ANSULT_API int UploadTextDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* textDataPath, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadBinaryDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* binaryDataPath, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadFileStreamDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadMultiPartDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, int fileSize, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadJpegImageANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadPrefixBinaryDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* binaryDataPath, const char* objectName, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadPrefixMultiPartDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* fileDataPath, const char* objectName, int fileSize, std::string& uploadedFilePath);
|
||||
extern "C" ANSULT_API int UploadPrefixJpegImageANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, std::string& uploadedFilePath);
|
||||
|
||||
|
||||
#endif
|
||||
28
modules/ANSUtilities/CMakeLists.txt
Normal file
28
modules/ANSUtilities/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# ANSUtilities — Utility DLL (AWS S3, common helpers)
|
||||
add_library(ANSUtilities SHARED
|
||||
ANSUtilities.cpp
|
||||
ANSUtilities.h
|
||||
ANSAWSS3.cpp
|
||||
dllmain.cpp
|
||||
pch.cpp
|
||||
pch.h
|
||||
framework.h
|
||||
)
|
||||
|
||||
target_include_directories(ANSUtilities PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(ANSUtilities
|
||||
PRIVATE ANSLicensingSystem
|
||||
PRIVATE labview
|
||||
PRIVATE opencv
|
||||
PRIVATE chilkat
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(ANSUtilities PRIVATE ${WIN_COMMON_LIBS} crypt32)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(ANSUtilities PRIVATE UNICODE _UNICODE ANSUTILITIES_EXPORTS)
|
||||
target_precompile_headers(ANSUtilities PRIVATE pch.h)
|
||||
2205
modules/ANSUtilities/dllmain.cpp
Normal file
2205
modules/ANSUtilities/dllmain.cpp
Normal file
File diff suppressed because it is too large
Load Diff
7
modules/ANSUtilities/framework.h
Normal file
7
modules/ANSUtilities/framework.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#define NOMINMAX // Prevent windows.h from defining min/max macros
|
||||
// which break std::min / std::max (C2589)
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
5
modules/ANSUtilities/pch.cpp
Normal file
5
modules/ANSUtilities/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
13
modules/ANSUtilities/pch.h
Normal file
13
modules/ANSUtilities/pch.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// pch.h: This is a precompiled header file.
|
||||
// Files listed below are compiled only once, improving build performance for future builds.
|
||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
Reference in New Issue
Block a user