fix some bug

This commit is contained in:
wjyLearn
2025-10-24 17:20:44 +08:00
parent 81ea36fdd8
commit 82268132e9
352 changed files with 33179 additions and 13515 deletions

View File

@@ -41,6 +41,9 @@ static std::string MachineBedTypeString[6] = {
"suprtack"
};
static wxString nozzle_not_set_text = _L("The printer nozzle information has not been set.\nPlease configure it before proceeding with the calibration.");
static wxString nozzle_volume_type_not_match_text = _L("The nozzle type does not match the actual printer nozzle type.\nPlease click the Sync button above and restart the calibration.");
std::vector<std::string> not_support_auto_pa_cali_filaments = {
"GFU03", // TPU 90A
"GFU04" // TPU 85A
@@ -84,6 +87,70 @@ wxString get_nozzle_volume_type_name(NozzleVolumeType type)
return wxString();
}
void update_speed_parameter( const std::string& key)
{
auto preset_bundle = wxGetApp().preset_bundle;
auto& printer_config = preset_bundle->printers.get_edited_preset().config;
auto& filament_config = preset_bundle->filaments.get_edited_preset().config;
auto& print_config = preset_bundle->prints.get_edited_preset().config;
int extruder_nums = preset_bundle->get_printer_extruder_count();
std::vector<int> extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type")->values;
std::vector<int> nozzle_volume_types = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values;
float nozzle_diameter = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->values[0];
float layer_height = print_config.option<ConfigOptionFloat>("layer_height")->value;
float line_width = print_config.get_abs_value("line_width");
Flow flow = Flow(line_width, layer_height, nozzle_diameter);
for (size_t i = 0; i < extruder_nums; ++i) {
int index = get_index_for_extruder_parameter(filament_config, "filament_max_volumetric_speed", i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloatsNullable>("filament_max_volumetric_speed")->get_at(index);
double max_speed = filament_max_volumetric_speed / flow.mm3_per_mm();
index = get_index_for_extruder_parameter(print_config, key, i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
ConfigOptionFloatsNullable *speed_opt = print_config.option<ConfigOptionFloatsNullable>(key);
speed_opt->values[index] = max_speed;
}
}
std::vector<double> generate_max_speed_parameter_value(const std::string &key)
{
auto preset_bundle = wxGetApp().preset_bundle;
auto &printer_config = preset_bundle->printers.get_edited_preset().config;
auto &filament_config = preset_bundle->filaments.get_edited_preset().config;
auto &print_config = preset_bundle->prints.get_edited_preset().config;
int extruder_nums = preset_bundle->get_printer_extruder_count();
std::vector<int> extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type")->values;
std::vector<int> nozzle_volume_types = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values;
float nozzle_diameter = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->values[0];
float layer_height = print_config.option<ConfigOptionFloat>("layer_height")->value;
float line_width = print_config.get_abs_value("line_width");
Flow flow = Flow(line_width, layer_height, nozzle_diameter);
std::vector<double> speed_values;
speed_values.resize(extruder_nums * nozzle_volume_types.size());
for (size_t i = 0; i < extruder_nums; ++i) {
int index = get_index_for_extruder_parameter(filament_config, "filament_max_volumetric_speed", i, ExtruderType(extruder_types[i]),
NozzleVolumeType(nozzle_volume_types[i]));
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloatsNullable>("filament_max_volumetric_speed")->get_at(index);
double max_speed = filament_max_volumetric_speed / flow.mm3_per_mm();
index = get_index_for_extruder_parameter(print_config, key, i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
ConfigOptionFloatsNullable *speed_opt = print_config.option<ConfigOptionFloatsNullable>(key);
double speed_value = std::floor(std::min(speed_opt->values[index], max_speed));
for (size_t v_id = 0; v_id < nozzle_volume_types.size(); ++v_id) {
speed_values.emplace_back(speed_value);
}
}
return speed_values;
}
static int get_physical_extruder_idx(std::vector<int> physical_extruder_maps, int extruder_id)
{
for (size_t index = 0; index < physical_extruder_maps.size(); ++index) {
@@ -164,6 +231,8 @@ static wxString to_wstring_name(std::string name)
return _L("Stainless Steel");
} else if (name == "tungsten_carbide") {
return _L("Tungsten Carbide");
} else if (name == "brass") {
return _L("Brass");
}
return wxEmptyString;
@@ -294,6 +363,7 @@ static void init_multi_extruder_params_for_cali(DynamicPrintConfig& config, cons
{
nozzle_volume_types[index] = (int) calib_info.nozzle_volume_type;
extruder_id = index + 1;
break;
}
}
@@ -870,6 +940,7 @@ void CalibUtils::set_for_auto_pa_model_and_config(const std::vector<CalibInfo> &
_wall_generator->value = PerimeterGeneratorType::Arachne;
print_config.option<ConfigOptionBool>("enable_prime_tower")->value = false;
print_config.option<ConfigOptionBool>("enable_wrapping_detection")->value = false;
auto get_new_filament_id = [&sorted_calib_infos](int index) -> int {
for (size_t i = 0; i < sorted_calib_infos.size(); ++i) {
@@ -913,6 +984,7 @@ void CalibUtils::set_for_auto_pa_model_and_config(const std::vector<CalibInfo> &
for (size_t index = 0; index < extruder_count; ++index) {
if (physical_extruder_maps[index] == extruder_id) {
extruder_id = index;
break;
}
}
nozzle_volume_types[extruder_id] = (int)calib_info.nozzle_volume_type;
@@ -988,17 +1060,24 @@ bool CalibUtils::calib_generic_auto_pa_cali(const std::vector<CalibInfo> &calib_
Preset printer_preset = *calib_infos[0].printer_prest;
Preset print_preset = *calib_infos[0].print_prest;
std::vector<CalibInfo> sorted_calib_infos = calib_infos;
std::sort(sorted_calib_infos.begin(), sorted_calib_infos.end(), [](const CalibInfo &left_item, const CalibInfo &right_item) {
return left_item.index < right_item.index;
});
std::vector<Preset> filament_presets;
std::vector<int> filament_map;
filament_map.resize(calib_infos.size());
filament_map.resize(sorted_calib_infos.size());
std::vector<int> physical_extruder_maps = dynamic_cast<ConfigOptionInts *>(printer_config.option("physical_extruder_map", true))->values;
for (size_t i = 0; i < calib_infos.size(); ++i) {
CalibInfo calib_info = calib_infos[i];
for (size_t i = 0; i < sorted_calib_infos.size(); ++i) {
CalibInfo calib_info = sorted_calib_infos[i];
calib_info.filament_prest->config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
filament_presets.emplace_back(*calib_info.filament_prest);
for (size_t index = 0; index < physical_extruder_maps.size(); ++index) {
if (physical_extruder_maps[index] == calib_info.extruder_id) {
filament_map[i] = index;
break;
}
}
}
@@ -1006,7 +1085,7 @@ bool CalibUtils::calib_generic_auto_pa_cali(const std::vector<CalibInfo> &calib_
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
DynamicPrintConfig full_config = PresetBundle::construct_full_config(printer_preset, print_preset, preset_bundle->project_config, filament_presets, false, filament_map);
set_for_auto_pa_model_and_config(calib_infos, full_config, model);
set_for_auto_pa_model_and_config(sorted_calib_infos, full_config, model);
if (!process_and_store_3mf(&model, full_config, params, error_message))
return false;
@@ -1036,7 +1115,7 @@ bool CalibUtils::calib_generic_auto_pa_cali(const std::vector<CalibInfo> &calib_
agent->track_event("cali", js.dump());
} catch (...) {}
send_to_print(calib_infos, error_message);
send_to_print(sorted_calib_infos, error_message);
return true;
}
@@ -1430,20 +1509,12 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
}
bool is_multi_extruder = obj->is_multi_extruders();
std::vector<NozzleFlowType> nozzle_volume_types;
if (is_multi_extruder) {
for (const DevExtder& extruder : obj->GetExtderSystem()->GetExtruders()) {
nozzle_volume_types.emplace_back(extruder.GetNozzleFlowType());
}
}
Preset *printer_preset = get_printer_preset(obj);
for (const auto &cali_info : cali_infos.calib_datas) {
wxString name = _L("left");
if (cali_info.extruder_id == 0) {
name = _L("right");
}
wxString name = "";
if (is_multi_extruder) { name = cali_info.extruder_id == MAIN_EXTRUDER_ID ? _L("right") + " ": _L("left") + " "; }
float cali_diameter = cali_info.nozzle_diameter;
int extruder_id = cali_info.extruder_id;
@@ -1452,7 +1523,14 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return false;
}
if (is_approx(double(cali_info.nozzle_diameter), 0.2) && !obj->is_series_x()) {
error_message = wxString::Format(_L("The nozzle diameter of %sextruder is 0.2mm which does not support automatic Flow Dynamics calibration."), name);
return false;
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(extruder_id);
if (!is_approx(cali_info.nozzle_diameter, diameter)) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle diameter of %s extruder does not match the actual nozzle diameter.\n"
@@ -1463,18 +1541,21 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return false;
}
if (is_multi_extruder) {
if (nozzle_volume_types[cali_info.extruder_id] == NozzleFlowType::NONE_FLOWTYPE) {
if (nozzle_volume_type == NozzleFlowType::NONE_FLOWTYPE) {
if (is_multi_extruder)
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
return false;
}
else
error_message = nozzle_not_set_text;
return false;
}
if (NozzleVolumeType(nozzle_volume_types[cali_info.extruder_id] - 1) != cali_info.nozzle_volume_type) {
if (NozzleVolumeType(nozzle_volume_type - 1) != cali_info.nozzle_volume_type) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle type of %s extruder does not match the actual printer nozzle type.\n"
"Please click the Sync button above and restart the calibration."), name);
return false;
}
"Please click the Sync button above and restart the calibration."), name);
else
error_message = nozzle_volume_type_not_match_text;
return false;
}
}
return true;
@@ -1490,61 +1571,62 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
if (cali_infos.empty())
return true;
float cali_diameter = cali_infos[0].nozzle_diameter;
int extruder_id = cali_infos[0].extruder_id;
bool is_multi_extruder = obj->is_multi_extruders();
Preset *printer_preset = get_printer_preset(obj);
for (const auto &cali_info : cali_infos) {
if (cali_infos[0].params.mode == CalibMode::Calib_Auto_PA_Line && !is_support_auto_pa_cali(cali_info.filament_prest->filament_id)) {
wxString name = "";
if (is_multi_extruder) { name = cali_info.extruder_id == MAIN_EXTRUDER_ID ? _L("right") + " " : _L("left") + " "; }
if (cali_info.params.mode == CalibMode::Calib_Auto_PA_Line && !is_support_auto_pa_cali(cali_info.filament_prest->filament_id)) {
error_message = _L("TPU 90A/TPU 85A is too soft and does not support automatic Flow Dynamics calibration.");
return false;
}
if (!is_approx(cali_diameter, cali_info.nozzle_diameter)) {
error_message = _L("Automatic calibration only supports cases where the left and right nozzle diameters are identical.");
if (is_approx(double(cali_info.nozzle_diameter), 0.2) && !obj->is_series_x()) {
error_message = wxString::Format(_L("The nozzle diameter of %sextruder is 0.2mm which does not support automatic Flow Dynamics calibration."), name);
return false;
}
}
if (extruder_id >= obj->GetExtderSystem()->GetExtruders().size()) {
error_message = _L("The number of printer extruders and the printer selected for calibration does not match.");
return false;
}
float cali_diameter = cali_info.nozzle_diameter;
int extruder_id = cali_info.extruder_id;
if (extruder_id >= obj->GetExtderSystem()->GetTotalExtderSize()) {
error_message = _L("The number of printer extruders and the printer selected for calibration does not match.");
return false;
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(extruder_id);
bool is_multi_extruder = obj->is_multi_extruders();
std::vector<NozzleFlowType> nozzle_volume_types;
if (is_multi_extruder) {
for (auto &extruder : obj->GetExtderSystem()->GetExtruders()) { nozzle_volume_types.emplace_back(extruder.GetNozzleFlowType()); }
}
for (const auto &cali_info : cali_infos) {
wxString name = _L("left");
if (cali_info.extruder_id == 0) { name = _L("right"); }
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(cali_info.extruder_id);
if (!is_approx(cali_info.nozzle_diameter, diameter)) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle diameter of %s extruder does not match the actual nozzle diameter.\n"
"Please click the Sync button above and restart the calibration."),
name);
"Please click the Sync button above and restart the calibration."), name);
else
error_message = _L("The nozzle diameter does not match the actual printer nozzle diameter.\n"
"Please click the Sync button above and restart the calibration.");
return false;
}
if (is_multi_extruder) {
if (nozzle_volume_types[cali_info.extruder_id] == NozzleFlowType::NONE_FLOWTYPE) {
if (nozzle_volume_type == NozzleFlowType::NONE_FLOWTYPE) {
if (is_multi_extruder)
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
return false;
}
else
error_message = nozzle_not_set_text;
return false;
}
if (NozzleVolumeType(nozzle_volume_types[cali_info.extruder_id] - 1) != cali_info.nozzle_volume_type) {
if (NozzleVolumeType(nozzle_volume_type - 1) != cali_info.nozzle_volume_type) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle type of %s extruder does not match the actual printer nozzle type.\n"
"Please click the Sync button above and restart the calibration."),
name);
return false;
}
"Please click the Sync button above and restart the calibration."), name);
else
error_message = nozzle_volume_type_not_match_text;
return false;
}
}
return true;
}
@@ -1558,20 +1640,16 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject* obj, co
const ConfigOptionFloatsNullable *nozzle_diameter_config = cali_info.printer_prest->config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
float nozzle_diameter = nozzle_diameter_config->values[0];
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(cali_info.extruder_id);
bool is_multi_extruder = obj->is_multi_extruders();
std::vector<NozzleFlowType> nozzle_volume_types;
if (is_multi_extruder) {
for (const DevExtder& extruder : obj->GetExtderSystem()->GetExtruders()) {
nozzle_volume_types.emplace_back(extruder.GetNozzleFlowType());
}
}
wxString name = _L("left");
if (cali_info.extruder_id == 0) {
name = _L("right");
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(cali_info.extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(cali_info.extruder_id);
if (!is_approx(nozzle_diameter, diameter)) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle diameter of %s extruder does not match the actual nozzle diameter.\n"
@@ -1582,17 +1660,22 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject* obj, co
return false;
}
if (is_multi_extruder) {
if (nozzle_volume_types[cali_info.extruder_id] == NozzleFlowType::NONE_FLOWTYPE) {
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
return false;
}
if (NozzleVolumeType(nozzle_volume_types[cali_info.extruder_id] - 1) != cali_info.nozzle_volume_type) {
if (nozzle_volume_type == NozzleFlowType::NONE_FLOWTYPE) {
if (is_multi_extruder)
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
else
error_message = nozzle_not_set_text;
return false;
}
if (NozzleVolumeType(nozzle_volume_type - 1) != cali_info.nozzle_volume_type) {
if (is_multi_extruder)
error_message = wxString::Format(_L("The currently selected nozzle type of %s extruder does not match the actual printer nozzle type.\n"
"Please click the Sync button above and restart the calibration."), name);
return false;
}
"Please click the Sync button above and restart the calibration."), name);
else
error_message = nozzle_volume_type_not_match_text;
return false;
}
return true;
@@ -1871,6 +1954,7 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess
print_job->set_calibration_task(true);
print_job->has_sdcard = obj_->GetStorage()->get_sdcard_state() == DevStorage::HAS_SDCARD_NORMAL;
print_job->could_emmc_print = obj_->is_support_print_with_emmc;
print_job->set_print_config(MachineBedTypeString[bed_type], true, false, false, false, true, false, 0, 0, 0, 0);
print_job->set_print_job_finished_event(wxGetApp().plater()->get_send_calibration_finished_event(), print_job->m_project_name);
@@ -1987,6 +2071,7 @@ void CalibUtils::send_to_print(const std::vector<CalibInfo> &calib_infos, wxStri
print_job->set_calibration_task(true);
print_job->has_sdcard = obj_->GetStorage()->get_sdcard_state() == DevStorage::HAS_SDCARD_NORMAL;
print_job->could_emmc_print = obj_->is_support_print_with_emmc;
print_job->set_print_config(MachineBedTypeString[bed_type], true, true, false, false, true, false, 0, 1, 0, 0);
print_job->set_print_job_finished_event(wxGetApp().plater()->get_send_calibration_finished_event(), print_job->m_project_name);

View File

@@ -98,6 +98,8 @@ extern void get_default_k_n_value(const std::string &filament_id, float &k, floa
extern wxString get_nozzle_volume_type_name(NozzleVolumeType type);
extern bool is_pa_params_valid(const Calib_Params &params);
extern void update_speed_parameter(const std::string &key);
extern std::vector<double> generate_max_speed_parameter_value(const std::string &key);
}
}

View File

@@ -0,0 +1,301 @@
#include "CertificateVerify.hpp"
#include <array>
#include <optional>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <boost/log/trivial.hpp>
namespace Slic3r {
#if defined(_WIN32)
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <wincrypt.h>
static std::wstring utf8_to_w(const std::string& s) {
if (s.empty()) return L"";
int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), nullptr, 0);
std::wstring w(n, L'\0');
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), w.data(), n);
return w;
}
static std::wstring wself_path() {
wchar_t buf[MAX_PATH];
DWORD n = GetModuleFileNameW(nullptr, buf, MAX_PATH);
return std::wstring(buf, buf + n);
}
static bool sha256_win(const BYTE* data, DWORD len, std::array<uint8_t, 32>& out) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
return false;
bool ok = false;
if (CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
if (CryptHashData(hHash, data, len, 0)) {
DWORD cb = (DWORD)out.size();
ok = (CryptGetHashParam(hHash, HP_HASHVAL, out.data(), &cb, 0) && cb == out.size());
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
return ok;
}
static std::string wide_to_utf8(const std::wstring& w) {
if (w.empty()) return {};
int n = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), (int)w.size(), nullptr, 0, nullptr, nullptr);
std::string s(n, '\0');
WideCharToMultiByte(CP_UTF8, 0, w.c_str(), (int)w.size(), s.data(), n, nullptr, nullptr);
return s;
}
static std::optional<SignerSummary> summarize_file_win(const std::wstring& path) {
HCERTSTORE hStore = nullptr;
HCRYPTMSG hMsg = nullptr;
if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
path.c_str(),
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY,
0, nullptr, nullptr, nullptr,
&hStore, &hMsg, nullptr)) {
return std::nullopt;
}
DWORD cb = 0;
if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, nullptr, &cb) || cb == 0) {
CryptMsgClose(hMsg); CertCloseStore(hStore, 0);
return std::nullopt;
}
std::vector<BYTE> v(cb);
if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, v.data(), &cb)) {
CryptMsgClose(hMsg); CertCloseStore(hStore, 0);
return std::nullopt;
}
auto* si = reinterpret_cast<PCMSG_SIGNER_INFO>(v.data());
CERT_INFO ci{};
ci.Issuer = si->Issuer;
ci.SerialNumber = si->SerialNumber;
PCCERT_CONTEXT pCert = CertFindCertificateInStore(
hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
CERT_FIND_SUBJECT_CERT, &ci, nullptr);
if (!pCert) {
CryptMsgClose(hMsg); CertCloseStore(hStore, 0);
return std::nullopt;
}
SignerSummary s{};
// 1) cert_sha256
DWORD cbHash = (DWORD)s.cert_sha256.size();
if (!CertGetCertificateContextProperty(
pCert, CERT_SHA256_HASH_PROP_ID,
s.cert_sha256.data(), &cbHash) || cbHash != s.cert_sha256.size()) {
sha256_win(pCert->pbCertEncoded, pCert->cbCertEncoded, s.cert_sha256);
}
// 2) spki_sha256 SPKI -> DER -> hash
DWORD cbSpki = 0;
if (!CryptEncodeObjectEx(
X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
&pCert->pCertInfo->SubjectPublicKeyInfo,
0, nullptr, nullptr, &cbSpki)) {
return std::nullopt;
}
std::vector<BYTE> spki(cbSpki);
if (!CryptEncodeObjectEx(
X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
&pCert->pCertInfo->SubjectPublicKeyInfo,
0, nullptr, spki.data(), &cbSpki)) {
return std::nullopt;
}
sha256_win(spki.data(), cbSpki, s.spki_sha256);
// 3) subject/issuer
{
wchar_t buf[1024];
DWORD n1 = CertGetNameStringW(pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nullptr, buf, 1024);
if (n1 > 0) s.subject_dn = wide_to_utf8(std::wstring(buf, buf + (n1 ? n1 - 1 : 0)));
DWORD n2 = CertGetNameStringW(pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG,
nullptr, buf, 1024);
if (n2 > 0) s.issuer_dn = wide_to_utf8(std::wstring(buf, buf + (n2 ? n2 - 1 : 0)));
}
CertFreeCertificateContext(pCert);
CryptMsgClose(hMsg);
CertCloseStore(hStore, 0);
return s;
}
std::optional<SignerSummary> SummarizeSelf() {
try {
return summarize_file_win(wself_path());
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << e.what();
return std::nullopt;
}
}
std::optional<SignerSummary> SummarizeModule(const std::string& path_utf8) {
try {
return summarize_file_win(utf8_to_w(path_utf8));
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << e.what();
return std::nullopt;
}
}
#elif defined(__APPLE__)
#include <cstring>
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#include <CommonCrypto/CommonCrypto.h>
static bool sha256_mac(const void* data, size_t len, std::array<uint8_t, 32>& out) {
CC_SHA256_CTX ctx; CC_SHA256_Init(&ctx);
CC_SHA256_Update(&ctx, data, (CC_LONG)len);
CC_SHA256_Final(out.data(), &ctx);
return true;
}
static std::string cfstr(CFStringRef s) {
if (!s) return {};
CFIndex len = CFStringGetLength(s);
CFIndex max = CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8);
std::string out(static_cast<size_t>(max) + 1, '\0');
if (CFStringGetCString(s, out.data(), max, kCFStringEncodingUTF8)) {
out.resize(strlen(out.c_str()));
return out;
}
return {};
}
static std::string dn_from_cert(SecCertificateRef cert) {
CFStringRef s = SecCertificateCopySubjectSummary(cert);
std::string out = cfstr(s);
if (s) CFRelease(s);
return out;
}
static bool fill_from_static_code(SecStaticCodeRef code, SignerSummary& s) {
CFDictionaryRef info = nullptr;
auto copy_inf_ret = SecCodeCopySigningInformation(code, kSecCSSigningInformation | kSecCSRequirementInformation | kSecCSInternalInformation, &info);
if (copy_inf_ret != errSecSuccess) {
return false;
}
if (!info) {
return false;
}
if (auto tid = (CFStringRef)CFDictionaryGetValue(info, kSecCodeInfoTeamIdentifier)) {
s.team_id = cfstr(tid);
}
// cert chain
CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(info, kSecCodeInfoCertificates);
if (!certs || CFArrayGetCount(certs) == 0) {
CFRelease(info);
return false;
}
SecCertificateRef leaf = (SecCertificateRef)CFArrayGetValueAtIndex(certs, 0);
// 1) cert_sha256
if (auto der = SecCertificateCopyData(leaf)) {
sha256_mac(CFDataGetBytePtr(der), CFDataGetLength(der), s.cert_sha256);
CFRelease(der);
}
// 2) spki_sha256
if (auto pk = SecCertificateCopyKey(leaf)) {
CFDataRef raw = SecKeyCopyExternalRepresentation(pk, nullptr);
if (raw) {
sha256_mac(CFDataGetBytePtr(raw), CFDataGetLength(raw), s.spki_sha256);
CFRelease(raw);
}
CFRelease(pk);
}
// 3) subject / issuer
s.subject_dn = dn_from_cert(leaf);
if (CFArrayGetCount(certs) >= 2) {
SecCertificateRef iss = (SecCertificateRef)CFArrayGetValueAtIndex(certs, 1);
s.issuer_dn = dn_from_cert(iss);
}
CFRelease(info);
return true;
}
std::optional<SignerSummary> SummarizeSelf() {
try {
SecCodeRef dyn = nullptr;
auto copy_ret = SecCodeCopySelf(kSecCSDefaultFlags, &dyn);
if (copy_ret != errSecSuccess) {
return std::nullopt;
}
if (!dyn) {
return std::nullopt;
}
SecStaticCodeRef st = nullptr;
auto copy_static_ret = SecCodeCopyStaticCode(dyn, kSecCSDefaultFlags, &st);
CFRelease(dyn);
if (!st) {
return std::nullopt;
}
SignerSummary s{};
bool ok = fill_from_static_code(st, s);
CFRelease(st);
return ok ? std::optional<SignerSummary>(s) : std::nullopt;
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << e.what();
return std::nullopt;
}
}
std::optional<SignerSummary> SummarizeModule(const std::string& path_utf8) {
try {
CFURLRef url = CFURLCreateFromFileSystemRepresentation(nullptr, (const UInt8 *) path_utf8.c_str(), path_utf8.size(), false);
if (!url) return std::nullopt;
SecStaticCodeRef code = nullptr;
OSStatus st = SecStaticCodeCreateWithPath(url, kSecCSDefaultFlags, &code);
CFRelease(url);
if (st != errSecSuccess || !code) return std::nullopt;
SignerSummary s{};
bool ok = fill_from_static_code(code, s);
CFRelease(code);
return ok ? std::optional<SignerSummary>(s) : std::nullopt;
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << e.what();
return std::nullopt;
}
}
#else
std::optional<SignerSummary> SummarizeSelf() { return std::nullopt; }
std::optional<SignerSummary> SummarizeModule(const std::string&) { return std::nullopt; }
#endif
bool IsSamePublisher(const SignerSummary& a, const SignerSummary& b)
{
if (!a.team_id.empty() && a.team_id == b.team_id) return true;
if (a.spki_sha256 == b.spki_sha256) return true;
if (a.cert_sha256 == b.cert_sha256) return true;
return false;
}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <array>
#include <string>
#include <optional>
namespace Slic3r {
struct SignerSummary {
// generic
std::array<uint8_t, 32> cert_sha256;
std::array<uint8_t, 32> spki_sha256;
std::string subject_dn;
std::string issuer_dn;
// macOS only
std::string team_id;
SignerSummary() {
cert_sha256.fill(0);
spki_sha256.fill(0);
}
std::string as_print() const {
std::stringstream ss;
ss << " subject_dn: " << subject_dn << " issuer_dn: " << issuer_dn << " team_id: " << team_id;
return ss.str();
}
};
bool IsSamePublisher(const SignerSummary& a, const SignerSummary& b);
std::optional<SignerSummary> SummarizeSelf();
std::optional<SignerSummary> SummarizeModule(const std::string& path_utf8);
}

View File

@@ -0,0 +1,219 @@
#include <wx/wx.h>
#include <type_traits>
#include "FileTransferUtils.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/DeviceCore/DevManager.h"
namespace Slic3r {
FileTransferModule::FileTransferModule(ModuleHandle networking_module, int required_abi_version) : networking_(networking_module)
{
// basic
ft_abi_version = sym_lookup<fn_ft_abi_version>(networking_, "ft_abi_version");
ft_free = sym_lookup<fn_ft_free>(networking_, "ft_free");
ft_job_result_destroy = sym_lookup<fn_ft_job_result_destroy>(networking_, "ft_job_result_destroy");
ft_job_msg_destroy = sym_lookup<fn_ft_job_msg_destroy>(networking_, "ft_job_msg_destroy");
// tunnel
ft_tunnel_create = sym_lookup<fn_ft_tunnel_create>(networking_, "ft_tunnel_create");
ft_tunnel_retain = sym_lookup<fn_ft_tunnel_retain>(networking_, "ft_tunnel_retain");
ft_tunnel_release = sym_lookup<fn_ft_tunnel_release>(networking_, "ft_tunnel_release");
ft_tunnel_start_connect = sym_lookup<fn_ft_tunnel_start_connect>(networking_, "ft_tunnel_start_connect");
ft_tunnel_sync_connect = sym_lookup<fn_ft_tunnel_sync_connect>(networking_, "ft_tunnel_sync_connect");
ft_tunnel_set_status_cb = sym_lookup<fn_ft_tunnel_set_status_cb>(networking_, "ft_tunnel_set_status_cb");
ft_tunnel_shutdown = sym_lookup<fn_ft_tunnel_shutdown>(networking_, "ft_tunnel_shutdown");
// job
ft_job_create = sym_lookup<fn_ft_job_create>(networking_, "ft_job_create");
ft_job_retain = sym_lookup<fn_ft_job_retain>(networking_, "ft_job_retain");
ft_job_release = sym_lookup<fn_ft_job_release>(networking_, "ft_job_release");
ft_job_set_result_cb = sym_lookup<fn_ft_job_set_result_cb>(networking_, "ft_job_set_result_cb");
ft_job_get_result = sym_lookup<fn_ft_job_get_result>(networking_, "ft_job_get_result");
ft_tunnel_start_job = sym_lookup<fn_ft_tunnel_start_job>(networking_, "ft_tunnel_start_job");
ft_job_cancel = sym_lookup<fn_ft_job_cancel>(networking_, "ft_job_cancel");
ft_job_set_msg_cb = sym_lookup<fn_ft_job_set_msg_cb>(networking_, "ft_job_set_msg_cb");
ft_job_try_get_msg = sym_lookup<fn_ft_job_try_get_msg>(networking_, "ft_job_try_get_msg");
ft_job_get_msg = sym_lookup<fn_ft_job_get_msg>(networking_, "ft_job_get_msg");
}
FileTransferTunnel::FileTransferTunnel(FileTransferModule &m, const std::string &url) : m_(&m)
{
FT_TunnelHandle *h{};
if (m_->ft_tunnel_create(url.c_str(), &h) != 0 || !h) {
}
h_ = h;
// C API: ft_status_cb(void* user, int old_status, int new_status, int err, const char* msg)
auto tramp = [](void *user, int old_status, int new_status, int err_code, const char *msg) noexcept {
auto *self = reinterpret_cast<FileTransferTunnel *>(user);
self->status_ = new_status;
if (!self->status_cb_) return;
try {
self->status_cb_(old_status, new_status, err_code, std::string(msg ? msg : ""));
} catch (...) {}
};
if (m_->ft_tunnel_set_status_cb(h_, tramp, this) == ft_err::FT_EXCEPTION) { throw std::runtime_error("ft_tunnel_set_status_cb failed"); }
}
void FileTransferTunnel::start_connect()
{
// C API: ft_conn_cb(void* user, int ok, int err, const char* msg)
auto tramp = [](void *user, int ok, int ec, const char *msg) noexcept {
auto *pcb = reinterpret_cast<ConnectionCb *>(user);
if (!pcb) return;
try {
(*pcb)(ok == 0, ec, std::string(msg ? msg : ""));
} catch (...) {}
};
if (m_->ft_tunnel_start_connect(h_, tramp, &conn_cb_) == ft_err::FT_EXCEPTION) { throw std::runtime_error("ft_tunnel_start_connect failed"); }
}
bool FileTransferTunnel::sync_start_connect()
{
return m_->ft_tunnel_sync_connect(h_) == FT_OK;
}
void FileTransferTunnel::on_connection(ConnectionCb cb) { conn_cb_ = std::move(cb); }
void FileTransferTunnel::on_status(TunnelStatusCb cb) { status_cb_ = std::move(cb); }
void FileTransferTunnel::shutdown()
{
if (m_->ft_tunnel_shutdown) (void) m_->ft_tunnel_shutdown(h_);
}
FileTransferJob::FileTransferJob(FileTransferModule &m, const std::string &params_json) : m_(&m)
{
FT_JobHandle *h{};
if (m_->ft_job_create(params_json.c_str(), &h) != 0 || !h) {
}
h_ = h;
// C API: ft_job_result_cb(void* user, int tunnel_err, ft_job_result result)
auto tramp = [](void *user, ft_job_result r) noexcept {
auto *self = reinterpret_cast<FileTransferJob *>(user);
if (!self) return;
try {
self->finished_ = true;
self->solve_result(r);
if (self->result_cb_) self->result_cb_(self->res_, self->resp_ec_, self->res_json_, self->res_bin_);
self->m_->ft_job_result_destroy(&r);
} catch (...) {
// swallow
}
try {
if (auto *mod = self ? self->m_ : nullptr) {
if (mod->ft_job_result_destroy)
mod->ft_job_result_destroy(&r);
else if (mod->ft_free) {
if (r.json) mod->ft_free((void *) r.json);
if (r.bin) mod->ft_free((void *) r.bin);
}
}
} catch (...) {}
};
if (m_->ft_job_set_result_cb(h_, tramp, this) == ft_err::FT_EXCEPTION) { throw std::runtime_error("ft_job_set_result_cb failed"); }
}
void FileTransferJob::on_result(ResultCb cb) { result_cb_ = std::move(cb); }
bool FileTransferJob::get_result(int &ec, int &resp_ec, std::string &json, std::vector<std::byte> &bin, uint32_t timeout_ms)
{
if (!h_) throw std::runtime_error("job handle invalid");
ft_job_result result;
if (m_->ft_job_get_result(h_, timeout_ms, &result) == ft_err::FT_EXCEPTION) return false;
solve_result(result);
m_->ft_job_result_destroy(&result);
ec = res_;
resp_ec = res_;
json = res_json_;
bin = res_bin_;
return true;
}
void FileTransferJob::start_on(FileTransferTunnel &t)
{
if (!h_) throw std::runtime_error("job handle invalid");
if (m_->ft_tunnel_start_job(t.native(), h_) == ft_err::FT_EXCEPTION) { throw std::runtime_error("ft_tunnel_start_job failed"); }
}
void FileTransferJob::on_msg(MsgCb cb)
{
msg_cb_ = std::move(cb);
if (!h_) return;
// C API: ft_job_msg_cb(void* user, ft_job_msg msg)
auto tramp = [](void *user, ft_job_msg m) noexcept {
auto *self = reinterpret_cast<FileTransferJob *>(user);
if (!self) return;
try {
if (self->msg_cb_) { self->msg_cb_(m.kind, std::string(m.json ? m.json : "")); }
} catch (...) {}
try {
if (auto *mod = self->m_) {
if (mod->ft_job_msg_destroy)
mod->ft_job_msg_destroy(&m);
else if (mod->ft_free && m.json)
mod->ft_free((void *) m.json);
}
} catch (...) {}
};
if (m_->ft_job_set_msg_cb(h_, tramp, this) == ft_err::FT_EXCEPTION) { throw std::runtime_error("ft_job_set_msg_cb failed"); }
}
bool FileTransferJob::try_get_msg(int &kind, std::string &json)
{
if (!h_) return false;
ft_job_msg m{};
int rc = m_->ft_job_try_get_msg(h_, &m);
if (rc != 0) return false;
kind = m.kind;
json.assign(m.json ? m.json : "");
if (m_->ft_job_msg_destroy)
m_->ft_job_msg_destroy(&m);
else if (m_->ft_free && m.json)
m_->ft_free((void *) m.json);
return true;
}
bool FileTransferJob::get_msg(uint32_t timeout_ms, int &kind, std::string &json)
{
if (!h_) return false;
ft_job_msg m{};
int rc = m_->ft_job_get_msg(h_, timeout_ms, &m);
if (rc != 0) return false;
kind = m.kind;
json.assign(m.json ? m.json : "");
if (m_->ft_job_msg_destroy)
m_->ft_job_msg_destroy(&m);
else if (m_->ft_free && m.json)
m_->ft_free((void *) m.json);
return true;
}
void FileTransferJob::solve_result(ft_job_result result)
{
res_ = result.ec;
resp_ec_ = result.resp_ec;
res_bin_.clear();
if (result.bin && result.bin_size) res_bin_.assign(reinterpret_cast<const std::byte *>(result.bin),
reinterpret_cast<const std::byte *>(result.bin) + result.bin_size);
res_json_.assign(result.json ? result.json : "");
}
} // namespace Slic3r

View File

@@ -0,0 +1,254 @@
#pragma once
#include <string>
#include <functional>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <utility>
#include <cstring>
#include <memory>
#ifdef _WIN32
#include <windows.h>
#define FT_CALL __cdecl
using ModuleHandle = HMODULE;
#else
#include <dlfcn.h>
#define FT_CALL
using ModuleHandle = void *;
#endif
namespace Slic3r {
extern "C" {
struct ft_job_result
{
int ec;
int resp_ec;
const char *json;
const void *bin;
uint32_t bin_size;
};
struct ft_job_msg
{
int kind;
const char *json;
};
struct FT_TunnelHandle;
struct FT_JobHandle;
typedef enum { FT_OK = 0, FT_EINVAL = -1, FT_ESTATE = -2, FT_EIO = -3, FT_ETIMEOUT = -4, FT_ECANCELLED = -5, FT_EXCEPTION = -6, FT_EUNKNOWN = -128 } ft_err;
}
inline void *sym_lookup_raw(ModuleHandle mh, const char *name)
{
#ifdef _WIN32
return mh ? reinterpret_cast<void *>(::GetProcAddress(mh, name)) : nullptr;
#else
return mh ? ::dlsym(mh, name) : nullptr;
#endif
}
template<class T> inline T sym_lookup(ModuleHandle mh, const char *name)
{
void *p = sym_lookup_raw(mh, name);
if (p) {
return reinterpret_cast<T>(p);
}
else {
BOOST_LOG_TRIVIAL(info) << std::string("symbol not found: ") + name;
return nullptr;
}
}
using fn_ft_abi_version = int(FT_CALL *)();
using fn_ft_free = void(FT_CALL *)(void *);
using fn_ft_job_result_destroy = void(FT_CALL *)(ft_job_result *);
using fn_ft_job_msg_destroy = void(FT_CALL *)(ft_job_msg *);
using fn_ft_tunnel_create = ft_err(FT_CALL *)(const char *url, FT_TunnelHandle **out);
using fn_ft_tunnel_retain = void(FT_CALL *)(FT_TunnelHandle *);
using fn_ft_tunnel_release = void(FT_CALL *)(FT_TunnelHandle *);
using fn_ft_tunnel_start_connect = ft_err(FT_CALL *)(FT_TunnelHandle *, void(FT_CALL *)(void *user, int ok, int err, const char *msg), void *user);
using fn_ft_tunnel_sync_connect = ft_err(FT_CALL *)(FT_TunnelHandle *);
using fn_ft_tunnel_set_status_cb = ft_err(FT_CALL *)(FT_TunnelHandle *, void(FT_CALL *)(void *user, int old_status, int new_status, int err, const char *msg), void *user);
using fn_ft_tunnel_shutdown = ft_err(FT_CALL *)(FT_TunnelHandle *);
using fn_ft_job_create = ft_err(FT_CALL *)(const char *params_json, FT_JobHandle **out);
using fn_ft_job_retain = void(FT_CALL *)(FT_JobHandle *);
using fn_ft_job_release = void(FT_CALL *)(FT_JobHandle *);
using fn_ft_job_set_result_cb = ft_err(FT_CALL *)(FT_JobHandle *, void(FT_CALL *)(void *user, ft_job_result result), void *user);
using fn_ft_job_get_result = ft_err(FT_CALL *)(FT_JobHandle *, uint32_t timeout_ms, ft_job_result *out_result);
using fn_ft_tunnel_start_job = ft_err(FT_CALL *)(FT_TunnelHandle *, FT_JobHandle *);
using fn_ft_job_cancel = ft_err(FT_CALL *)(FT_JobHandle *);
using fn_ft_job_msg_destroy = void(FT_CALL *)(ft_job_msg *);
using fn_ft_job_set_msg_cb = ft_err(FT_CALL *)(FT_JobHandle *, void(FT_CALL *)(void *user, ft_job_msg msg), void *user);
using fn_ft_job_try_get_msg = ft_err(FT_CALL *)(FT_JobHandle *, ft_job_msg *out_msg);
using fn_ft_job_get_msg = ft_err(FT_CALL *)(FT_JobHandle *, uint32_t timeout_ms, ft_job_msg *out_msg);
/// <summary>
/// FileTransferModule, support file operations on printer
/// </summary>
struct FileTransferModule
{
fn_ft_abi_version ft_abi_version{};
fn_ft_free ft_free{};
fn_ft_job_result_destroy ft_job_result_destroy{};
fn_ft_job_msg_destroy ft_job_msg_destroy{};
// tunnel(connection)
fn_ft_tunnel_create ft_tunnel_create{};
fn_ft_tunnel_retain ft_tunnel_retain{};
fn_ft_tunnel_release ft_tunnel_release{};
fn_ft_tunnel_start_connect ft_tunnel_start_connect{};
fn_ft_tunnel_sync_connect ft_tunnel_sync_connect{};
fn_ft_tunnel_set_status_cb ft_tunnel_set_status_cb{};
fn_ft_tunnel_shutdown ft_tunnel_shutdown{};
// job(operation)
fn_ft_job_create ft_job_create{};
fn_ft_job_retain ft_job_retain{};
fn_ft_job_release ft_job_release{};
fn_ft_job_set_result_cb ft_job_set_result_cb{};
fn_ft_job_get_result ft_job_get_result{};
fn_ft_tunnel_start_job ft_tunnel_start_job{};
fn_ft_job_cancel ft_job_cancel{};
fn_ft_job_set_msg_cb ft_job_set_msg_cb{};
fn_ft_job_try_get_msg ft_job_try_get_msg{};
fn_ft_job_get_msg ft_job_get_msg{};
ModuleHandle networking_{};
explicit FileTransferModule(ModuleHandle networking_module, int required_abi_version = 1);
FileTransferModule(const FileTransferModule &) = delete;
FileTransferModule &operator=(const FileTransferModule &) = delete;
};
class FileTransferTunnel
{
public:
using ConnectionCb = std::function<void(bool is_success, int err_code, std::string error_msg)>;
using TunnelStatusCb = std::function<void(int old_status, int new_status, int err_code, std::string error_msg)>;
explicit FileTransferTunnel(FileTransferModule &m, const std::string &url);
~FileTransferTunnel() { reset(); }
FileTransferTunnel(const FileTransferTunnel &) = delete;
FileTransferTunnel &operator=(const FileTransferTunnel &) = delete;
FileTransferTunnel(FileTransferTunnel &&) = delete;
FileTransferTunnel &operator=(FileTransferTunnel &&) = delete;
void start_connect();
bool sync_start_connect();
void on_connection(ConnectionCb cb);
void on_status(TunnelStatusCb cb);
void shutdown();
int get_status() const { return status_; }
bool check_valid() const { return h_ != nullptr; }
FT_TunnelHandle *native() const noexcept { return h_; }
private:
void reset() noexcept
{
if (h_) {
m_->ft_tunnel_release(h_);
h_ = nullptr;
}
}
int status_{};
FileTransferModule *m_{};
FT_TunnelHandle *h_{};
ConnectionCb conn_cb_{};
TunnelStatusCb status_cb_{};
};
class FileTransferJob
{
public:
using ResultCb = std::function<void(int res, int resp_ec, std::string json_res, std::vector<std::byte> bin_res)>;
using MsgCb = std::function<void(int kind, std::string json)>;
explicit FileTransferJob(FileTransferModule &m, const std::string &params_json);
~FileTransferJob() { reset(); }
FileTransferJob(const FileTransferJob &) = delete;
FileTransferJob &operator=(const FileTransferJob &) = delete;
FileTransferJob(FileTransferJob &&) = delete;
FileTransferJob &operator=(FileTransferJob &&) = delete;
void on_result(ResultCb cb);
bool get_result(int &ec, int &resp_ec, std::string &json, std::vector<std::byte> &bin, uint32_t timeout_ms);
void start_on(FileTransferTunnel &t);
void on_msg(MsgCb cb);
bool try_get_msg(int &kind, std::string &json);
bool get_msg(uint32_t timeout_ms, int &kind, std::string &json);
FT_JobHandle *native() const noexcept { return h_; }
bool check_valid() const { return h_ != nullptr; }
bool finished() const { return finished_; }
void cancel()
{
if (m_->ft_job_cancel && h_) m_->ft_job_cancel(h_);
}
private:
void reset() noexcept
{
if (h_) {
m_->ft_job_release(h_);
h_ = nullptr;
}
}
void solve_result(ft_job_result result);
FileTransferModule *m_{};
FT_JobHandle *h_{};
ResultCb result_cb_{};
MsgCb msg_cb_{};
bool finished_ = false;
int res_ = 0;
int resp_ec_ = 0;
std::string res_json_;
std::vector<std::byte> res_bin_;
};
namespace detail {
inline FileTransferModule *g_mod = nullptr;
}
inline void InitFTModule(ModuleHandle networking_module, int abi_required = 1)
{
if (detail::g_mod) throw std::runtime_error("Slic3r::InitFTModule called twice");
detail::g_mod = new FileTransferModule(networking_module, abi_required);
}
inline void UnloadFTModule() noexcept
{
delete detail::g_mod;
detail::g_mod = nullptr;
}
inline FileTransferModule &module()
{
if (!detail::g_mod) throw std::runtime_error("Slic3r::FTModule not initialized. Call Init() first.");
return *detail::g_mod;
}
} // namespace Slic3r

File diff suppressed because it is too large Load Diff

View File

@@ -31,19 +31,44 @@ class AppConfig;
class HelioQuery
{
public:
struct SimulationInput
{
float chamber_temp{ -1 };
};
struct OptimizationInput
{
bool outer_wall{false};
float chamber_temp{ -1 };
float min_velocity{ -1 };
float max_velocity{ -1 };
float min_volumetric_speed{ -1 };
float max_volumetric_speed{ -1 };
std::array<int, 2> layers_to_optimize = { -1, -1 };
bool isDefault() {
return (min_velocity == -1) &&
(max_velocity == -1) &&
(min_volumetric_speed == -1) &&
(max_volumetric_speed == -1);
}
};
struct PresignedURLResult
{
unsigned status;
std::string key;
std::string mimeType;
std::string url;
unsigned status;
std::string error;
std::string trace_id;
};
struct UploadFileResult
{
bool success;
std::string error;
std::string trace_id;
};
struct SupportedData
@@ -53,6 +78,13 @@ public:
std::string native_name;
};
struct PollResult {
std::string status_str;
int progress;
int sizeKb;
bool success;
};
struct CreateGCodeResult
{
unsigned status;
@@ -62,6 +94,12 @@ public:
std::string error;
vector<std::string> warning_flags;
vector<std::string> error_flags;
std::string trace_id;
// V2 API fields
float sizeKb;
std::string status_str;
float progress;
};
struct CreateSimulationResult
@@ -71,6 +109,33 @@ public:
std::string name;
std::string id;
std::string error;
std::string trace_id;
void reset() {
status = 0;
success = false;
name = "";
id = "";
error = "";
};
};
struct CreateOptimizationResult
{
unsigned status;
bool success;
std::string name;
std::string id;
std::string error;
std::string trace_id;
void reset() {
status = 0;
success = false;
name = "";
id = "";
error = "";
};
};
struct CheckSimulationProgressResult
@@ -82,16 +147,45 @@ public:
std::string name;
std::string url;
std::string error;
std::string trace_id;
};
struct CheckOptimizationResult
{
unsigned status;
bool is_finished;
float progress;
std::string id;
std::string name;
std::string url;
std::string error;
std::string trace_id;
std::string qualityMeanImprovement;
std::string qualityStdImprovement;
};
struct RatingData
{
int action = 0;
std::string qualityMeanImprovement;
std::string qualityStdImprovement;
};
static std::string get_helio_api_url();
static std::string get_helio_pat();
static void set_helio_pat(std::string pat);
static void request_support_machine(const std::string helio_api_url, const std::string helio_api_key, int page);
static void request_support_machine(const std::string helio_api_url, const std::string helio_api_key, int page);
static void request_support_material(const std::string helio_api_url, const std::string helio_api_key, int page);
static void request_pat_token(std::function<void(std::string)> func);
static void request_pat_token(std::function<void(std::string)> func);
static void optimization_feedback(const std::string helio_api_url, const std::string helio_api_key, std::string optimization_id, float rating, std::string comment);
static PresignedURLResult create_presigned_url(const std::string helio_api_url, const std::string helio_api_key);
static UploadFileResult upload_file_to_presigned_url(const std::string file_path_string, const std::string upload_url);
static PollResult poll_gcode_status(const std::string& helio_api_url,
const std::string& helio_api_key,
const std::string& gcode_id);
static CreateGCodeResult create_gcode(const std::string key,
const std::string helio_api_url,
const std::string helio_api_key,
@@ -110,18 +204,56 @@ public:
request_support_material(helio_api_url, helio_api_key, 1);
}
/*for helio simulation*/
static CreateSimulationResult create_simulation(const std::string helio_api_url,
const std::string helio_api_key,
const std::string gcode_id,
const float initial_room_airtemp,
const float layer_threshold,
const float object_proximity_airtemp);
SimulationInput sinput);
static void stop_simulation(const std::string helio_api_url,
const std::string helio_api_key,
const std::string simulation_id);
static CheckSimulationProgressResult check_simulation_progress(const std::string helio_api_url,
const std::string helio_api_key,
const std::string simulation_id);
static std::string generate_graphql_query(const std::string &gcode_id, float temperatureStabilizationHeight = -1, float airTemperatureAboveBuildPlate = -1, float stabilizedAirTemperature = -1);
/*for helio optimization*/
static CreateOptimizationResult create_optimization(const std::string helio_api_url,
const std::string helio_api_key,
const std::string gcode_id,
OptimizationInput oinput);
static void stop_optimization(const std::string helio_api_url,
const std::string helio_api_key,
const std::string optimization_id);
static CheckOptimizationResult check_optimization_progress(const std::string helio_api_url,
const std::string helio_api_key,
const std::string optimization_id);
static std::string create_optimization_default_get(const std::string helio_api_url, const std::string helio_api_key, const std::string gcode_id);
static std::string generate_default_optimization_query(const std::string& gcode_id);
static std::string generate_simulation_graphql_query(const std::string& gcode_id,
float temperatureStabilizationHeight = -1,
float airTemperatureAboveBuildPlate = -1,
float stabilizedAirTemperature = -1);
static std::string generate_optimization_graphql_query(const std::string& gcode_id,
bool outerwall,
float temperatureStabilizationHeight = -1,
float airTemperatureAboveBuildPlate = -1,
float stabilizedAirTemperature = -1,
double minVelocity = -1,
double maxVelocity = -1,
double minExtruderFlowRate = -1,
double maxExtruderFlowRate = -1,
int layersToOptimizeStart = -1,
int layersToOptimizeEnd = -1);
static std::string generateTimestampedString()
{
// Get the current UTC time
@@ -136,16 +268,17 @@ public:
static std::vector<SupportedData> global_supported_printers;
static std::vector<SupportedData> global_supported_materials;
static std::string last_simulation_trace_id;
static std::string last_optimization_trace_id;
static double convert_speed(float mm_per_second);
static double convert_volume_speed(float mm3_per_second);
/*user*/
static void request_remaining_optimizations(const std::string& helio_api_url, const std::string& helio_api_key, std::function<void(int, int)> func);
};
class HelioBackgroundProcess
{
public:
struct SimulationInput
{
float chamber_temp{-1};
};
public:
enum State {
// m_thread is not running yet, or it did not reach the STATE_IDLE yet (it does not wait on the condition yet).
@@ -169,19 +302,36 @@ public:
std::string printer_id;
std::string filament_id;
//for user input
SimulationInput simulation_input_data;
int action; //0-simulation 1-optimization
Slic3r::GCodeProcessorResult* m_gcode_result;
/*task data*/
HelioQuery::CreateSimulationResult current_simulation_result;
HelioQuery::CreateOptimizationResult current_optimization_result;
//for user input
HelioQuery::SimulationInput simulation_input_data;
HelioQuery::OptimizationInput optimization_input_data;
Slic3r::GCodeProcessorResult* m_gcode_result{nullptr};
Slic3r::GCodeProcessor m_gcode_processor;
Slic3r::GUI::Preview* m_preview;
std::function<void()> m_update_function;
void set_simulation_input_data(SimulationInput data)
void set_action(int ac)
{
action = ac;
}
void set_simulation_input_data(HelioQuery::SimulationInput data)
{
simulation_input_data = data;
}
void set_optimization_input_data(HelioQuery::OptimizationInput data)
{
optimization_input_data = data;
}
void stop()
{
m_mutex.lock();
@@ -222,6 +372,10 @@ public:
return state;
}
void stop_current_helio_action();
void feedback_current_helio_action(float rating, std::string commend);
void clear_helio_file_cache();
void helio_threaded_process_start(std::mutex& slicing_mutex,
std::condition_variable& slicing_condition,
BackgroundSlicingProcess::State& slicing_state,
@@ -271,12 +425,13 @@ public:
void set_helio_api_key(std::string api_key);
void set_gcode_result(Slic3r::GCodeProcessorResult* gcode_result);
void create_simulation_step(HelioQuery::CreateGCodeResult create_gcode_res,
std::unique_ptr<GUI::NotificationManager>& notification_manager);
void create_simulation_step(HelioQuery::CreateGCodeResult create_gcode_res,std::unique_ptr<GUI::NotificationManager>& notification_manager);
void create_optimization_step(HelioQuery::CreateGCodeResult create_gcode_res, std::unique_ptr<GUI::NotificationManager>& notification_manager);
void save_downloaded_gcode_and_load_preview(std::string file_download_url,
std::string simulated_gcode_path,
std::string helio_gcode_path,
std::string tmp_path,
std::unique_ptr<GUI::NotificationManager>& notification_manager);
std::unique_ptr<GUI::NotificationManager>& notification_manager,
HelioQuery::RatingData rating_data);
std::string create_path_for_simulated_gcode(std::string unsimulated_gcode_path)
{
@@ -292,7 +447,21 @@ public:
return (parent / new_filename).string();
}
void load_simulation_to_viwer(std::string file_path, std::string tmp_path);
std::string create_path_for_optimization_gcode(std::string unoptimized_gcode_path)
{
boost::filesystem::path p(unoptimized_gcode_path);
if (!p.has_filename()) {
throw std::runtime_error("Invalid path: No filename present.");
}
boost::filesystem::path parent = p.parent_path();
std::string new_filename = "optimized_" + p.filename().string();
return (parent / new_filename).string();
}
void load_helio_file_to_viwer(std::string file_path, std::string tmp_path, HelioQuery::RatingData rating_data);
};
} // namespace Slic3r
#endif

View File

@@ -11,7 +11,8 @@
#include "slic3r/Utils/QDTUtil.hpp"
#include "NetworkAgent.hpp"
#include "slic3r/Utils/FileTransferUtils.hpp"
#include "slic3r/Utils/CertificateVerify.hpp"
using namespace QDT;
@@ -76,6 +77,7 @@ func_build_logout_cmd NetworkAgent::build_logout_cmd_ptr = nullptr
func_build_login_info NetworkAgent::build_login_info_ptr = nullptr;
func_ping_bind NetworkAgent::ping_bind_ptr = nullptr;
func_bind_detect NetworkAgent::bind_detect_ptr = nullptr;
func_report_consent NetworkAgent::report_consent_ptr = nullptr;
func_set_server_callback NetworkAgent::set_server_callback_ptr = nullptr;
func_bind NetworkAgent::bind_ptr = nullptr;
func_unbind NetworkAgent::unbind_ptr = nullptr;
@@ -115,6 +117,7 @@ func_get_model_mall_home_url NetworkAgent::get_model_mall_home_url_ptr =
func_get_model_mall_detail_url NetworkAgent::get_model_mall_detail_url_ptr = nullptr;
func_get_subtask NetworkAgent::get_subtask_ptr = nullptr;
func_get_my_profile NetworkAgent::get_my_profile_ptr = nullptr;
func_get_my_token NetworkAgent::get_my_token_ptr = nullptr;
func_track_enable NetworkAgent::track_enable_ptr = nullptr;
func_track_remove_files NetworkAgent::track_remove_files_ptr = nullptr;
func_track_event NetworkAgent::track_event_ptr = nullptr;
@@ -171,7 +174,7 @@ std::string NetworkAgent::get_libpath_in_current_directory(std::string library_n
}
int NetworkAgent::initialize_network_module(bool using_backup)
int NetworkAgent::initialize_network_module(bool using_backup, bool validate_cert)
{
//int ret = -1;
std::string library;
@@ -182,6 +185,13 @@ int NetworkAgent::initialize_network_module(bool using_backup)
if (using_backup) {
plugin_folder = plugin_folder/"backup";
}
std::optional<SignerSummary> self_cert_summary, module_cert_summary;
if (validate_cert)
self_cert_summary = SummarizeSelf();
else
BOOST_LOG_TRIVIAL(info) << "wouldn't validate networking dll cert";
if (!self_cert_summary)
BOOST_LOG_TRIVIAL(info) << "self cert not exist";
//first load the library
#if defined(_MSC_VER) || defined(_WIN32)
@@ -189,13 +199,18 @@ int NetworkAgent::initialize_network_module(bool using_backup)
wchar_t lib_wstr[128];
memset(lib_wstr, 0, sizeof(lib_wstr));
::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str())+1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0]));
netwoking_module = LoadLibrary(lib_wstr);
/*if (!netwoking_module) {
library = std::string(QIDI_NETWORK_LIBRARY) + ".dll";
memset(lib_wstr, 0, sizeof(lib_wstr));
::MultiByteToWideChar(CP_UTF8, NULL, library.c_str(), strlen(library.c_str()) + 1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0]));
if (self_cert_summary) {
module_cert_summary = SummarizeModule(library);
if (module_cert_summary) {
if (IsSamePublisher(*self_cert_summary, *module_cert_summary))
netwoking_module = LoadLibrary(lib_wstr);
else
BOOST_LOG_TRIVIAL(info) << "module is from another publisher:" << module_cert_summary->as_print();
}
else
BOOST_LOG_TRIVIAL(info) << "module_cert is null";
} else
netwoking_module = LoadLibrary(lib_wstr);
}*/
if (!netwoking_module) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", try load library directly from current directory");
@@ -204,10 +219,21 @@ int NetworkAgent::initialize_network_module(bool using_backup)
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", can not get path in current directory for %1%") % QIDI_NETWORK_LIBRARY;
return -1;
}
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", current path %1%")%library_path;
memset(lib_wstr, 0, sizeof(lib_wstr));
::MultiByteToWideChar(CP_UTF8, NULL, library_path.c_str(), strlen(library_path.c_str())+1, lib_wstr, sizeof(lib_wstr) / sizeof(lib_wstr[0]));
netwoking_module = LoadLibrary(lib_wstr);
if (self_cert_summary) {
module_cert_summary = SummarizeModule(library_path);
if (module_cert_summary) {
if (IsSamePublisher(*self_cert_summary, *module_cert_summary))
netwoking_module = LoadLibrary(lib_wstr);
else
BOOST_LOG_TRIVIAL(info) << "module is from another publisher:" << module_cert_summary->as_print();
}
else
BOOST_LOG_TRIVIAL(info) << "module_cert is null";
}
else
netwoking_module = LoadLibrary(lib_wstr);
}
#else
#if defined(__WXMAC__)
@@ -216,17 +242,24 @@ int NetworkAgent::initialize_network_module(bool using_backup)
library = plugin_folder.string() + "/" + std::string("lib") + std::string(QIDI_NETWORK_LIBRARY) + ".so";
#endif
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", line %1%, loading network module, using_backup %2%\n")%__LINE__ %using_backup;
netwoking_module = dlopen( library.c_str(), RTLD_LAZY);
module_cert_summary = SummarizeModule(library);
if (self_cert_summary) {
module_cert_summary = SummarizeModule(library);
if (module_cert_summary) {
if (IsSamePublisher(*self_cert_summary, *module_cert_summary))
netwoking_module = dlopen(library.c_str(), RTLD_LAZY);
else
BOOST_LOG_TRIVIAL(info) << "module is from another publisher:" << module_cert_summary->as_print();
}
else
BOOST_LOG_TRIVIAL(info) << "module_cert is null";
}
else
netwoking_module = dlopen( library.c_str(), RTLD_LAZY);
if (!netwoking_module) {
/*#if defined(__WXMAC__)
library = std::string("lib") + QIDI_NETWORK_LIBRARY + ".dylib";
#else
library = std::string("lib") + QIDI_NETWORK_LIBRARY + ".so";
#endif*/
//netwoking_module = dlopen( library.c_str(), RTLD_LAZY);
char* dll_error = dlerror();
printf("error, dlerror is %s\n", dll_error);
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", error, dlerror is %1%")%dll_error;
std::string err = dll_error ? std::string(dll_error) : std::string("(null)");
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", error, dlerror is %1%") % err;
}
printf("after dlopen, network_module is %p\n", netwoking_module);
#endif
@@ -237,6 +270,9 @@ int NetworkAgent::initialize_network_module(bool using_backup)
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", line %1%, successfully loaded library, using_backup %2%, module %3%")%__LINE__ %using_backup %netwoking_module;
// load file transfer interface
InitFTModule(netwoking_module);
//load the functions
check_debug_consistent_ptr = reinterpret_cast<func_check_debug_consistent>(get_network_function("qidi_network_check_debug_consistent"));
get_version_ptr = reinterpret_cast<func_get_version>(get_network_function("qidi_network_get_version"));
@@ -286,6 +322,7 @@ int NetworkAgent::initialize_network_module(bool using_backup)
build_login_info_ptr = reinterpret_cast<func_build_login_info>(get_network_function("qidi_network_build_login_info"));
ping_bind_ptr = reinterpret_cast<func_ping_bind>(get_network_function("qidi_network_ping_bind"));
bind_detect_ptr = reinterpret_cast<func_bind_detect>(get_network_function("qidi_network_bind_detect"));
report_consent_ptr = reinterpret_cast<func_report_consent>(get_network_function("qidi_network_report_consent"));
set_server_callback_ptr = reinterpret_cast<func_set_server_callback>(get_network_function("qidi_network_set_server_callback"));
bind_ptr = reinterpret_cast<func_bind>(get_network_function("qidi_network_bind"));
unbind_ptr = reinterpret_cast<func_unbind>(get_network_function("qidi_network_unbind"));
@@ -325,6 +362,7 @@ int NetworkAgent::initialize_network_module(bool using_backup)
get_model_mall_home_url_ptr = reinterpret_cast<func_get_model_mall_home_url>(get_network_function("qidi_network_get_model_mall_home_url"));
get_model_mall_detail_url_ptr = reinterpret_cast<func_get_model_mall_detail_url>(get_network_function("qidi_network_get_model_mall_detail_url"));
get_my_profile_ptr = reinterpret_cast<func_get_my_profile>(get_network_function("qidi_network_get_my_profile"));
get_my_token_ptr = reinterpret_cast<func_get_my_profile>(get_network_function("qidi_network_get_my_token"));
track_enable_ptr = reinterpret_cast<func_track_enable>(get_network_function("qidi_network_track_enable"));
track_remove_files_ptr = reinterpret_cast<func_track_remove_files>(get_network_function("qidi_network_track_remove_files"));
track_event_ptr = reinterpret_cast<func_track_event>(get_network_function("qidi_network_track_event"));
@@ -345,6 +383,7 @@ int NetworkAgent::initialize_network_module(bool using_backup)
int NetworkAgent::unload_network_module()
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", network module %1%")%netwoking_module;
UnloadFTModule();
#if defined(_MSC_VER) || defined(_WIN32)
if (netwoking_module) {
FreeLibrary(netwoking_module);
@@ -445,6 +484,7 @@ int NetworkAgent::unload_network_module()
get_model_mall_home_url_ptr = nullptr;
get_model_mall_detail_url_ptr = nullptr;
get_my_profile_ptr = nullptr;
get_my_token_ptr = nullptr;
track_enable_ptr = nullptr;
track_remove_files_ptr = nullptr;
track_event_ptr = nullptr;
@@ -1018,6 +1058,17 @@ int NetworkAgent::bind_detect(std::string dev_ip, std::string sec_link, detectRe
return ret;
}
int NetworkAgent::report_consent(std::string expand)
{
int ret = 0;
if (network_agent && report_consent_ptr) {
ret = report_consent_ptr(network_agent, expand);
if (ret)
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%") % network_agent % ret;
}
return ret;
}
int NetworkAgent::set_server_callback(OnServerErrFn fn)
{
int ret = 0;
@@ -1454,6 +1505,17 @@ int NetworkAgent::get_my_profile(std::string token, unsigned int *http_code, std
return ret;
}
int NetworkAgent::get_my_token(std::string ticket, unsigned int* http_code, std::string* http_body)
{
int ret = 0;
if (network_agent && get_my_token_ptr) {
ret = get_my_token_ptr(network_agent, ticket, http_code, http_body);
if (ret)
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format("error network_agnet=%1%, ret = %2%") % network_agent % ret;
}
return ret;
}
int NetworkAgent::track_enable(bool enable)
{
enable_track = enable;

View File

@@ -55,6 +55,7 @@ typedef std::string (*func_build_logout_cmd)(void *agent);
typedef std::string (*func_build_login_info)(void *agent);
typedef int (*func_ping_bind)(void *agent, std::string ping_code);
typedef int (*func_bind_detect)(void *agent, std::string dev_ip, std::string sec_link, detectResult& detect);
typedef int (*func_report_consent)(void *agent, std::string expand);
typedef int (*func_set_server_callback)(void *agent, OnServerErrFn fn);
typedef int (*func_bind)(void *agent, std::string dev_ip, std::string dev_id, std::string sec_link, std::string timezone, bool improved, OnUpdateStatusFn update_fn);
typedef int (*func_unbind)(void *agent, std::string dev_id);
@@ -94,6 +95,7 @@ typedef int (*func_get_subtask)(void *agent, QDTModelTask* task, OnGetSubTaskFn
typedef int (*func_get_model_mall_home_url)(void *agent, std::string* url);
typedef int (*func_get_model_mall_detail_url)(void *agent, std::string* url, std::string id);
typedef int (*func_get_my_profile)(void *agent, std::string token, unsigned int *http_code, std::string *http_body);
typedef int (*func_get_my_token)(void *agent, std::string ticket, unsigned int *http_code, std::string *http_body);
typedef int (*func_track_enable)(void *agent, bool enable);
typedef int (*func_track_remove_files)(void *agent);
typedef int (*func_track_event)(void *agent, std::string evt_key, std::string content);
@@ -116,7 +118,7 @@ class NetworkAgent
public:
static std::string get_libpath_in_current_directory(std::string library_name);
static int initialize_network_module(bool using_backup = false);
static int initialize_network_module(bool using_backup = false, bool validate_cert = true);
static int unload_network_module();
#if defined(_MSC_VER) || defined(_WIN32)
static HMODULE get_qidi_source_entry();
@@ -172,6 +174,7 @@ public:
std::string build_login_info();
int ping_bind(std::string ping_code);
int bind_detect(std::string dev_ip, std::string sec_link, detectResult& detect);
int report_consent(std::string expand);
int set_server_callback(OnServerErrFn fn);
int bind(std::string dev_ip, std::string dev_id, std::string sec_link, std::string timezone, bool improved, OnUpdateStatusFn update_fn);
int unbind(std::string dev_id);
@@ -211,6 +214,7 @@ public:
int get_model_mall_home_url(std::string* url);
int get_model_mall_detail_url(std::string* url, std::string id);
int get_my_profile(std::string token, unsigned int* http_code, std::string* http_body);
int get_my_token(std::string ticket, unsigned int* http_code, std::string* http_body);
int track_enable(bool enable);
int track_remove_files();
int track_event(std::string evt_key, std::string content);
@@ -279,6 +283,7 @@ private:
static func_build_login_info build_login_info_ptr;
static func_ping_bind ping_bind_ptr;
static func_bind_detect bind_detect_ptr;
static func_report_consent report_consent_ptr;
static func_set_server_callback set_server_callback_ptr;
static func_bind bind_ptr;
static func_unbind unbind_ptr;
@@ -318,6 +323,7 @@ private:
static func_get_model_mall_home_url get_model_mall_home_url_ptr;
static func_get_model_mall_detail_url get_model_mall_detail_url_ptr;
static func_get_my_profile get_my_profile_ptr;
static func_get_my_token get_my_token_ptr;
static func_track_enable track_enable_ptr;
static func_track_remove_files track_remove_files_ptr;
static func_track_event track_event_ptr;

View File

@@ -471,6 +471,8 @@ bool OctoPrint::send_command_to_printer(wxString& msg, wxString commond) const
auto url = make_url("printer/gcode/script");
bool successful = false;
Http http = Http::post(std::move(url));
//y72
set_auth(http);
http.header("Content-Type", "application/json")
.set_post_body(json_body)
.timeout_connect(4)
@@ -495,10 +497,12 @@ bool OctoPrint::send_timelapse_status(wxString& msg, std::string ip, bool status
{
const char* name = get_name();
std::string status_str = status ? "true" : "false";
std::string url = (boost::format("http://%1%:7125/machine/timelapse/settings?enabled=%2%") % ip % status_str).str();
std::string url = (boost::format("http://%1%/machine/timelapse/settings?enabled=%2%") % ip % status_str).str();
bool successful = false;
std::string json_body = "{}";
Http http = Http::post(std::move(url));
//y72
set_auth(http);
http.header("Content-Type", "application/json")
.set_post_body(json_body)
.timeout_connect(4)

View File

@@ -89,26 +89,33 @@ bool json_diff::load_compatible_settings(std::string const &type, std::string co
printer_version = version2;
}
settings_base.clear();
std::string config_file = Slic3r::data_dir() + "/printers/" + printer_type + ".json";
std::string config_file = Slic3r::resources_dir() + "/printers/" + printer_type + ".json";
boost::nowide::ifstream json_file(config_file.c_str());
try {
json versions;
if (json_file.is_open()) {
json_file >> versions;
for (auto iter = versions.begin(); iter != versions.end(); ++iter) {
if (iter.key() > printer_version)
if (iter.key() > printer_version) {
break;
}
merge_objects(*iter, settings_base);
}
if (!full_message.empty())
if (!full_message.empty()) {
diff2all_base_reset(full_message);
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": "<< type << " " << version << ", merged " << versions.dump(1);
return true;
} else {
//BOOST_LOG_TRIVIAL(error) << "load_compatible_settings failed, file = " << config_file;
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << type << " " << version << ", failed open file";
}
} catch (...) {
//BOOST_LOG_TRIVIAL(error) << "load_compatible_settings failed, file = " << config_file;
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << type << " " << version << ", unknown exception";
}
return false;
}
@@ -194,9 +201,9 @@ int json_diff::restore_append_objects(json const &in, json &out)
for (auto& el: in.items()) {
if (!out.contains(el.key()) ) {
// BOOST_LOG_TRIVIAL(trace) << "json_c append new " << el.key()
// << " type: " << el.value().type_name()
// << " value: " << el.value();
//BOOST_LOG_TRIVIAL(trace) << "json_c append new " << el.key()
// << " type: " << el.value().type_name()
// << " value: " << el.value();
out[el.key()] = el.value();
continue;
}
@@ -205,9 +212,9 @@ int json_diff::restore_append_objects(json const &in, json &out)
int recur_ret =
restore_append_objects(el.value(), out[el.key()]);
if (recur_ret != 0) {
// BOOST_LOG_TRIVIAL(trace) << "json_c append obj failed"
// << " key: " << el.key()
// << " value: " << el.value();
//BOOST_LOG_TRIVIAL(trace) << "json_c append obj failed"
// << " key: " << el.key()
// << " value: " << el.value();
return recur_ret;
}
}
@@ -258,10 +265,10 @@ void json_diff::compare_print(json &a, json &b)
<< " type: " << e.value().type_name();
}
if (e.value() != b[e.key()]) {
// BOOST_LOG_TRIVIAL(trace) << "json_c compare not equal: key: " << e.key()
// << " value: " << e.value();
// BOOST_LOG_TRIVIAL(trace) << "json_c compare vs value "
// << " vs value: " << b[e.key()];
//BOOST_LOG_TRIVIAL(trace) << "json_c compare not equal: key: " << e.key()
// << " value: " << e.value();
//BOOST_LOG_TRIVIAL(trace) << "json_c compare vs value "
// << " vs value: " << b[e.key()];
}
}

View File

@@ -97,7 +97,7 @@ namespace QDT {
#define QIDI_NETWORK_LIBRARY "qidi_networking"
#define QIDI_NETWORK_AGENT_NAME "qidi_network_agent"
#define QIDI_NETWORK_AGENT_VERSION "02.02.01.62"
#define QIDI_NETWORK_AGENT_VERSION "02.03.00.62"
//iot preset type strings
#define IOT_PRINTER_TYPE_STRING "printer"
@@ -201,6 +201,7 @@ struct PrintParams {
std::string ftp_folder;
std::string ftp_file;
std::string ftp_file_md5;
std::string nozzle_mapping;
std::string ams_mapping;
std::string ams_mapping2;
std::string ams_mapping_info;
@@ -235,6 +236,7 @@ struct PrintParams {
int auto_flow_cali{ 0 };
int auto_offset_cali{ 0 };
bool task_ext_change_assist;
bool try_emmc_print;
};
struct TaskQueryParams