Files
archery/cpp_ext/archery_netcore.cpp
linyimin c3f1cfdea0 feat: TCP协议支持protobuf序列化,保留JSON兼容
- 新增 tcp_messages_pb2.py protobuf Python绑定
- msg_handler.cpp: 新增 make_packet_pb/raw bytes打包, parse_packet_raw/raw解析
- archery_netcore.cpp: 注册 make_packet_pb/parse_packet_raw
- network.py: 新增 _use_proto 标志,_make_send_packet/_parse_recv 自动选择proto/JSON
- 登录version加+proto后缀标识proto模式
- protobuf序列化/反序列化失败时自动回退JSON
2026-09-16 09:30:26 +08:00

124 lines
3.8 KiB
C++

#include <pybind11/pybind11.h>
#include <pybind11/stl.h> // 支持 std::vector, std::map 等
#include <nlohmann/json.hpp>
#include <cstring>
#include <cstdint>
#include <vector>
#include <string>
#include <fstream>
#include <array>
#include "msg_handler.hpp"
#include "native_logger.hpp"
#include "decrypt_ota_file.hpp"
#include "utils.hpp"
#include "tcp_ssl_password.hpp"
namespace py = pybind11;
using json = nlohmann::json;
namespace {
// 配置项
const std::string _cfg_server_ip = "www.shelingxingqiu.com";
const int _cfg_server_port = 50005;
const std::string _cfg_device_id_file = "/device_key";
}
// 定义获取配置的函数
py::dict get_config() {
py::dict config;
config["SERVER_IP"] = _cfg_server_ip;
config["SERVER_PORT"] = _cfg_server_port;
return config;
}
PYBIND11_MODULE(archery_netcore, m) {
m.doc() = "Archery net core (native, pybind11).";
// Optional: configure native logger from Python.
// Default log file: /maixapp/apps/t11/netcore.log
m.def("set_log_file", [](const std::string& path) { netcore::set_log_file(path); }, py::arg("path"));
m.def("set_log_level", [](int level) {
if (level < 0) level = 0;
if (level > 3) level = 3;
netcore::set_log_level(static_cast<netcore::LogLevel>(level));
}, py::arg("level"));
m.def("log_test", [](const std::string& msg) {
netcore::log_info(std::string("log_test: ") + msg);
}, py::arg("msg"));
m.def("make_packet", &netcore::make_packet,
"Pack TCP packet: header (len+type+checksum) + JSON body",
py::arg("msg_type"), py::arg("body_dict"));
m.def("make_packet_pb", &netcore::make_packet_pb,
"Pack TCP packet: header (len+type+checksum) + raw bytes body (for protobuf)",
py::arg("msg_type"), py::arg("body_bytes"));
m.def("parse_packet", &netcore::parse_packet,
"Parse TCP packet, return (msg_type, body_dict)");
m.def("parse_packet_raw", &netcore::parse_packet_raw,
"Parse TCP packet, return (msg_type, body_bytes) without JSON parsing");
m.def("get_config", &get_config, "Get system configuration");
m.def(
"calculate_tcp_ssl_password",
&netcore::calculate_tcp_ssl_password,
"Calculate TCP SSL password: hex(md5(hex(md5(device_id)) + iccid))",
py::arg("device_id"),
py::arg("iccid")
);
m.def(
"decrypt_ota_file",
[](const std::string& input_path, const std::string& output_zip_path) {
netcore::log_info(std::string("decrypt_ota_file in=") + input_path + " out=" + output_zip_path);
return netcore::decrypt_ota_file_impl(input_path, output_zip_path);
},
py::arg("input_path"),
py::arg("output_zip_path"),
"Decrypt OTA encrypted file (MAGIC|nonce|ciphertext|tag) to plaintext zip."
);
// Minimal demo: return actions for inner_cmd=41 (manual trigger + ack)
m.def("actions_for_inner_cmd", [](int inner_cmd) {
py::list actions;
if (inner_cmd == 41) {
// 1) set manual trigger flag
{
py::dict a;
a["type"] = "SET_FLAG";
py::dict args;
args["name"] = "manual_trigger_flag";
args["value"] = true;
a["args"] = args;
actions.append(a);
}
// 2) enqueue trigger_ack
{
py::dict a;
a["type"] = "ENQUEUE";
py::dict args;
args["msg_type"] = 2;
args["high"] = false;
py::dict body;
body["result"] = "trigger_ack";
args["body"] = body;
a["args"] = args;
actions.append(a);
}
}
return actions;
});
}