This commit is contained in:
qingjiao 2025-12-05 16:46:23 +08:00
parent 6fdbaa0016
commit 0364bfd97d
14 changed files with 433 additions and 25 deletions

View File

@ -2,8 +2,17 @@
#define CC_H
#pragma once
#define CC_ARM_ defined(__arm__) || defined(__aarch64__)
#define CC_X86_ defined(__i386) || defined(__x86_64__)
#if defined(__arm__) || defined(__aarch64__)
#define IS_ARM 1
#if defined(__aarch64__)
#define IS_ARM64 1
#else
#define IS_ARM32 1
#endif
#else
#define IS_ARM 0
#endif
#define CCTime_Day_S 86400
#define CCTime_Points_S 60

View File

@ -246,7 +246,7 @@ void CTL::Application::StartDaemon(int argc, char **argv) {
SetFileReadPermission(AppNamePathBat);
const auto cmd = String::format("nohup {} &",AppNamePathBat.c_str());
process.Command(cmd);
DaemonFlag = process.Start(false);
DaemonFlag = process.Start(true);
#endif
}

View File

@ -354,7 +354,7 @@ CTL::String CTL::System::GetMac() {
// 获取第一个物理适配器的MAC地址
char macStr[18] = {0};
sprintf_s(macStr, sizeof(macStr), "%02X-%02X-%02X-%02X-%02X-%02X",
sprintf_s(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
pAdapter->Address[0], pAdapter->Address[1],
pAdapter->Address[2], pAdapter->Address[3],
pAdapter->Address[4], pAdapter->Address[5]);
@ -403,7 +403,7 @@ CTL::String CTL::System::GetMac() {
mac[3] != 0 || mac[4] != 0 || mac[5] != 0) {
char macStr[18] = {0};
sprintf(macStr, "%02X-%02X-%02X-%02X-%02X-%02X",
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
macAddress = macStr;
break;

View File

@ -21,6 +21,7 @@ add_executable(Distribution_Service main.cpp
Server/Task/TaskInfo.h
Server/Task/PushFlowTask.h
Server/Task/PushFlowTask.cpp
Server/NetInfo/NetWork.h
)
set_target_properties(Distribution_Service PROPERTIES

View File

@ -2,6 +2,10 @@
#include "BS_Log.h"
#include "CCFIleInStream.h"
#include "CCFileOutStream.h"
#include "CCProcess.h"
#include "ConnectionService.h"
#include "NetInfo/NetWork.h"
#include "PortService/ByteTool.h"
void Config::Save() {
const auto Setting = getConfig();
@ -34,13 +38,13 @@ void Config::Init() {
Setting->ID = Json["ID"];
Setting->Name = Json["Name"];
}
}
catch (CCException& e) {
BS_Log::Error("Config::Init Error: {}",e.what());
}
Setting->IP = GetIP();
BS_Log::Log("Local IP: {}",Setting->IP.c_str());
BS_Log::Log("Local ID: {}",Setting->ID);
}
Config * Config::getConfig() {
@ -54,6 +58,12 @@ bool Config::IsRunning() {
CTL::String Config::GetIP() {
const auto Setting = Config::getConfig();
try {
Setting->MacAddr = CTL::System::GetMac();
Setting->TermIPGw = NetWorkInfo::getGw();
Setting->TermIPNm = NetWorkInfo::getNm();
}
catch (...){}
const auto List = CTL::Socket::GetLocalIP(Setting->IP_x);
CCVector<CTL::String> IPList;
for (const auto IP : List) {
@ -66,3 +76,101 @@ CTL::String Config::GetIP() {
}
return IPList.empty() ? "127.0.0.1" : IPList[0];
}
ConfigTerm * Config::getThisInfo() {
const auto Setting = getConfig();
const auto Data = new ConfigTerm;
std::strcpy(Data->termIDnVerStr,Setting->Ver.c_str());
std::strcpy(Data->macStr,Setting->MacAddr.c_str());
std::strcpy(Data->macChkStr,Setting->MacAddr.c_str());
std::strcpy(Data->servIPAddrStr,Setting->ServerIP.c_str());
std::strcpy(Data->termIPAddrStr,Setting->IP.c_str());
std::strcpy(Data->termIPGwStr,Setting->TermIPGw.c_str());
std::strcpy(Data->termIPNmStr,Setting->TermIPNm.c_str());
std::strcpy(Data->termCmdPortStr,CC::to_String(Setting->OrderPort).c_str());
std::strcpy(Data->servCmdPortStr,CC::to_String(Setting->ServerPort).c_str());
std::strcpy(Data->termStmPortStr,CC::to_String(Setting->StreamPort).c_str());
std::strcpy(Data->workModeStr,"");
std::strcpy(Data->btNameStr,"");
std::strcpy(Data->dhcpFlagStr,CC::to_String(1).c_str());
std::strcpy(Data->btPwdStr,"");
std::strcpy(Data->termTypeStr,CC::to_String(1).c_str());
std::strcpy(Data->sipUsrNameStr,"");
std::strcpy(Data->sipUsrPwdStr,"");
std::strcpy(Data->sipProxyRealmStr,"");
std::strcpy(Data->cmdFlagByteStr,CC::to_String("").c_str());
std::strcpy(Data->onlineFlagStr,CC::to_String(Setting->isConnect).c_str());
return Data;
}
void Config::groupBroadcast(const CTL::ByteArray &data, int port) {
std::shared_lock lock(m_mutex_udp_tool);
const auto Setting = getConfig();
if (Setting->m_socket_udp_tool) {
CTL::DatagramPacket packet;
packet.setPort(port);
packet.setData(data);
Setting->m_socket_udp_tool->broadcast(packet);
}
}
void Config::SetNetWorkInfo(const CTL::String& IP,const CTL::String& GW,const CTL::String& Mask) {
try{
//获取当前网络名称
CTL::String GetNetName = ("nmcli -t -f NAME,TYPE,DEVICE,STATE con show --active");
CTL::Process Process;
Process.Command(GetNetName);
Process.Start();
auto NetName = Process.ReadLineBuffer().toString();
NetName = CTL::String(NetName.substr(0,NetName.find(":")).c_str());
BS_Log::Log("[fun-configure|MainConfigure] NetName: %s",NetName.c_str());
Process.Stop();
//设置为手动
CTL::String SetManual = ("sudo nmcli con modify '" + NetName + "' ipv4.method manual");
CTL::System::Execute(SetManual);
//设置IP与子网掩码
CTL::String SetIP = ("sudo nmcli con modify '" + NetName + "' ipv4.addresses " + IP +"/" + GetNetMaskCIDR(Mask));
CTL::System::Execute(SetIP);
//设置默认网关
CTL::String SetGateway = ("sudo nmcli con modify '" + NetName + "' ipv4.gateway " + GW);
CTL::System::Execute(SetGateway);
//重启网络
CTL::String NetDown = ("sudo nmcli con down '" + NetName + "'");
CTL::System::Execute(NetDown);
CTL::String NetUp = ("sudo nmcli con up '" + NetName + "'");
CTL::System::Execute(NetUp);
}
catch (CCException& e){
BS_Log::Error("[fun-configure|MainConfigure] NetInit Error: {}",e.what());
}
}
void Config::CloseService() {
const auto Setting = getConfig();
const auto sock = ConnectionService::getSocket();
const auto IDS = APPTool::GetBytes(Setting->ID);
sock->SendBinary({0x66,0xAB,0xA1,0x00,IDS[0],IDS[1],0x01,0x00});
CTL::Thread::SleepMS(500);
sock->Stop();
}
CTL::String Config::GetNetMaskCIDR(const CTL::String& Mask) {
std::vector<int> octets;
std::stringstream ss(Mask);
std::string segment;
while (std::getline(ss, segment, '.')){
octets.push_back(std::stoi(segment));
}
// 转换每个八位组为二进制并计算连续的 1 的数量
int cidr = 0;
for (int octet : octets){
while (octet > 0){
cidr += (octet & 1); // 统计每一位是否为 1
octet >>= 1;
}
}
CTL::String cidr_str = CTL::String::format("%d",cidr);
return cidr_str;
}

View File

@ -6,6 +6,29 @@
#include "CCJSONObject.h"
#include "CCString.h"
struct ConfigTerm{
char macChkStr[20]; //终端Mac
char termIDnVerStr[20]; //发送的是软件版本接收的是终端ID
char macStr[20]; //终端Mac地址
char servIPAddrStr[20]; //服务器IP地址
char termIPAddrStr[20]; //终端IP
char termIPGwStr[20]; //终端IP网关
char termIPNmStr[20]; //子网掩码
char termCmdPortStr[6]; //终端指令端口号
char servCmdPortStr[6]; //服务器指令端口号
char termStmPortStr[6]; //终端码流端口号
char workModeStr[2]; //工作模式
char btNameStr[32]; //蓝牙音频名称
char dhcpFlagStr[2]; //DHCP开关标识
char btPwdStr[5]; //蓝牙音频密码
char termTypeStr[6]; //终端类型
char sipUsrNameStr[30]; //SIP用户名称
char sipUsrPwdStr[30]; //SIP用户密码
char sipProxyRealmStr[30]; //SIP服务器IP地址/域名
char cmdFlagByteStr[3]; //指令标识
char onlineFlagStr[2]; //在线状态标志
};
class Config {
JSON_TYPE_INTRUSIVE(Config,IP,OrderPort,StreamPort,HttpPort,Flag,ServerID,ServerIP,ServerPort,ID
,Name);
@ -18,11 +41,19 @@ public:
CTL::String ServerIP = "192.168.2.208"; // 目标主服务器IP
int ServerPort = 10060; // 目标主服务器端口
int OrderPort = 10050; // 10060
int ConfigPort = 22060; // 22060
int StreamPort = 10062;
bool isConnect = false;
int HttpPort = 9090;
bool Flag = false;
CTL::String MacAddr;
CTL::String TermIPGw;
CTL::String TermIPNm;
CTL::String Ver = "DS:V0.11(251205A)";
inline static std::shared_mutex m_mutex_udp;
CTL::DatagramSocket* m_socket_udp = nullptr;
inline static std::shared_mutex m_mutex_udp_tool;
CTL::DatagramSocket* m_socket_udp_tool = nullptr;
CTL::IPVX IP_x = CTL::IPV4;
private:
public:
@ -47,6 +78,11 @@ public:
return CCFile::NormalizePath(root + "/Setting.json");
}
static CTL::String GetIP();
static ConfigTerm *getThisInfo();
static void groupBroadcast(const CTL::ByteArray& data,int port);
static void SetNetWorkInfo(const CTL::String& IP,const CTL::String& GW,const CTL::String& Mask);
static void CloseService();
static CTL::String GetNetMaskCIDR(const CTL::String& Mask);/*获取CIDR格式子网掩码*/
};

84
Server/NetInfo/NetWork.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef DISTRIBUTION_SERVICE_NETWORK_H
#define DISTRIBUTION_SERVICE_NETWORK_H
#include "CCString.h"
#include "Socket/CCSocket.h"
#ifdef _WIN32
#elif __linux__
#include <sys/ioctl.h>
#endif
class NetWorkInfo {
public:
static CTL::String getGw() {
#ifdef _WIN32
// Windows实现
return CTL::String("");
#elif __linux__
// Linux实现从/proc/net/route读取默认网关
std::ifstream routeFile("/proc/net/route");
std::string line;
// 跳过标题行
std::getline(routeFile, line);
while (std::getline(routeFile, line)) {
std::istringstream iss(line);
std::string iface, dest, gateway;
if (iss >> iface >> dest >> gateway) {
// 查找默认路由(目标地址为00000000)
if (dest == "00000000" && gateway != "00000000") {
// 将十六进制网关地址转换为点分十进制格式
unsigned int gw;
std::stringstream ss;
ss << std::hex << gateway;
ss >> gw;
// 注意字节序转换
gw = (gw & 0xFF) << 24 | ((gw >> 8) & 0xFF) << 16 |
((gw >> 16) & 0xFF) << 8 | (gw >> 24) & 0xFF;
in_addr addr;
addr.s_addr = htonl(gw);
return CTL::String(inet_ntoa(addr));
}
}
}
return CTL::String("");
#endif
} // 获取网关
static CTL::String getNm() {
#ifdef _WIN32
// Windows实现
return CTL::String("");
#elif __linux__
// Linux实现尝试从常见网络接口获取子网掩码
const char* interfaces[] = {"eth0", "wlan0", "enp0s3", "ens33","enp4s0"};
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
return CTL::String("");
}
for (int i = 0; i < 5; i++) {
struct ifreq ifr{};
strncpy(ifr.ifr_name, interfaces[i], IFNAMSIZ - 1);
// 获取子网掩码
if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
struct sockaddr_in* netmask = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_netmask);
close(sock);
return CTL::String(inet_ntoa(netmask->sin_addr));
}
}
close(sock);
return CTL::String("");
#endif
} // 获取子网掩码
};
#endif

View File

@ -3,6 +3,8 @@
#include "DataPacket.h"
#include "ByteTool.h"
#include "CCApplication.h"
#include "ConnectionService.h"
#include "../Configuration/BS_Log.h"
#include "Terminal/Terminal.h"
#include "TaskModel/Transmitter.h"
@ -83,6 +85,54 @@ public:
static void Function_0xA4(const DataPacket& packet){
}
static void Function_0xF2(const DataPacket& packet){
const auto Setting = Config::getConfig();
if (packet.Parameter1 == 0x00 && packet.Parameter2 == 0x00 && packet.Parameter3 == 0x45
&& packet.Parameter4 == 0x4E && packet.Parameter5 == 0x44) {
const auto IDS = APPTool::GetBytes(Setting->ID);
CTL::ByteArray data = {0x55,0xAA,0xF2,0x00,IDS[0],IDS[1],0x00,0x00};
const auto t = Config::getThisInfo();
CTL::AutoDestruct autoDestruct(t);
CTL::ByteArray a;
a.Conversion(t,sizeof(ConfigTerm));
data.append(a);
Config::groupBroadcast(data,22058);
}
}
static void Function_0xF4(const DataPacket& packet){
const auto Setting = Config::getConfig();
const ConfigTerm* t = CTL::ByteArray::Conversion<ConfigTerm>(packet.AdditionalData);
CTL::AutoDestruct autoDestruct(t);
if (t) {
const auto TMac = CTL::String(t->macStr);
if (TMac == Setting->MacAddr) {
const int ID = CTL::String(t->termIDnVerStr).to_int();
const auto ServerIP = CTL::String(t->servIPAddrStr);
const auto ServerPort = CTL::String(t->servCmdPortStr).to_int();
const auto Port = CTL::String(t->termCmdPortStr).to_int();
const auto DataPort = CTL::String(t->termStmPortStr).to_int();
// -----------------------------------------------------------------
const auto IP = CTL::String(t->termIPAddrStr);
const auto GW = CTL::String(t->termIPGwStr);
const auto NM = CTL::String(t->termIPNmStr);
// -----------------------------------------------------------------
Setting->ID = ID;
Setting->ServerIP = ServerIP;
Setting->ServerPort = ServerPort;
Setting->OrderPort = Port;
Setting->StreamPort = DataPort;
Setting->IP = IP;
#if IS_ARM
Config::SetNetWorkInfo(IP,GW,NM);
#endif
Config::Save();
Config::CloseService();
CTL::Application::ReleaseLock();
CTL::Thread::SleepMS(1000);
std::terminate();
}
}
}
};
#endif

View File

@ -25,6 +25,14 @@ public:
Setting->ID = ID;
BS_Log::Log("Function_0x02 ID Change to {}", ID);
}
else if (packet.Parameter1 == 0x03) {
const auto IDS = APPTool::GetBytes(Setting->ID);
const CTL::ByteArray data = {0x66,0xAB,0x02,0x03,IDS[0],IDS[1],0x00,0x00};
if (packet.AimWS && packet.IsTCP) {
packet.AimWS->SendBinary(data);
}
return;
}
const auto IDS = APPTool::GetBytes(Setting->ID);
const CTL::ByteArray data = {0x66,0xAB,0x09,0x00,IDS[0],IDS[1],0x00,0x00};
if (packet.AimWS && packet.IsTCP) {
@ -89,18 +97,21 @@ public:
static void Function_0x09(const DataPacket& packet) {
try {
const auto str = packet.AdditionalData.toString();
CTL::JSONObject Json = CTL::JSONObject::parse(str);
const auto taskInfo = new TaskInfo;
taskInfo->TaskID = Json.get("TaskID");
taskInfo->TaskType = Json.get("TaskType");
taskInfo->ServerPort = Json.get("ServerPort");
const auto TermList = Json.get("Terms").get<CCVector<int>>();
for (const auto& TID : TermList) {
taskInfo->Terms.put(TID, TID);
CTL::JSONObject Json_t = CTL::JSONObject::parse(str);
const auto TaskList = Json_t.get("TaskList").get<CCVector<Dist_Tasks>>();
for (const auto& Task : TaskList) {
const auto taskInfo = new TaskInfo;
taskInfo->TaskID = Task.TaskID;
taskInfo->TaskType = Task.TaskType;
taskInfo->ServerPort = Task.ServerPort;
const auto TermList = Task.Terms;
for (const auto& TID : TermList) {
taskInfo->Terms.put(TID, TID);
}
taskInfo->pushFlowTask = new PushFlowTask(taskInfo->TaskID);
TaskInfo::Start(taskInfo);
taskInfo->pushFlowTask->start();
}
taskInfo->pushFlowTask = new PushFlowTask(taskInfo->TaskID);
TaskInfo::Start(taskInfo);
taskInfo->pushFlowTask->start();
}
catch (CCException& e) {
BS_Log::Error("Function_0x09 Error: {}",e.what());
@ -108,7 +119,18 @@ public:
}
static void Function_0x10(const DataPacket& packet) {
try {
const auto TID = APPTool::GetInt(packet.Parameter2, packet.Parameter3);
const auto task = TaskInfo::getData(packet.Parameter4);
if (task) {
if (task->Type == 0 && task->pushFlowTask) {
if (packet.Parameter1 == 0x01) {
task->pushFlowTask->addTID(TID);
}
else if (packet.Parameter1 == 0x00) {
task->pushFlowTask->removeTID(TID);
}
}
}
}
catch (CCException& e) {
BS_Log::Error("Function_0x10 Error: {}",e.what());
@ -116,12 +138,40 @@ public:
}
static void Function_0x11(const DataPacket& packet) {
try {
const auto task = TaskInfo::getData(packet.Parameter2);
const auto str = packet.AdditionalData.toString();
CTL::JSONObject Json = CTL::JSONObject::parse(str);
if (task) {
const auto TermList = Json.get("TermList").get<CCVector<int>>();
if (task->Type == 0 && task->pushFlowTask) {
if (packet.Parameter1 == 0x00) {
for (const auto& TID : TermList) {
task->pushFlowTask->removeTID(TID);
}
}
else if (packet.Parameter1 == 0x01) {
for (const auto& TID : TermList) {
task->pushFlowTask->addTID(TID);
}
}
}
}
}
catch (CCException& e) {
BS_Log::Error("Function_0x11 Error: {}",e.what());
}
}
static void Function_0x13(const DataPacket& packet) {
try {
if (packet.Parameter1 == 0x00) {
Config::CloseService();
CTL::System::Execute("sudo reboot");
}
}
catch (CCException& e) {
BS_Log::Error("Function_0x13 Error: {}",e.what());
}
}
};
#endif

View File

@ -31,6 +31,14 @@ void Routing::RoutingFunction(const DataPacket &packet) {
R_Order_AA::Function_0xA4(packet);
break;
}
case 0xF2: {
R_Order_AA::Function_0xF2(packet);
break;
}
case 0xF4: {
R_Order_AA::Function_0xF4(packet);
break;
}
default: {
R_Order_AA::Function(packet);
break;

View File

@ -33,6 +33,14 @@ void PushFlowTask::addBuffer(const CTL::ByteArray &buffer) {
taskAllocator.AddBuffer(buffer);
}
void PushFlowTask::addTID(const int ID) {
taskAllocator.AddTerm(ID,{});
}
void PushFlowTask::removeTID(const int ID) {
taskAllocator.RemoveTerm(ID,{});
}
void PushFlowTask::run() {
BS_Log::Log("PushFlowTask::run Start TaskID: {}",TaskID);
while (Flag) {

View File

@ -14,6 +14,8 @@ public:
void start();
void stop();
void addBuffer(const CTL::ByteArray& buffer);
void addTID(int ID);
void removeTID(int ID);
private:
void run();
};

View File

@ -6,6 +6,16 @@
#include "TL/Map.h"
#include "PushFlowTask.h"
struct Dist_Tasks {
JSON_TYPE_INTRUSIVE(Dist_Tasks,TaskID,TaskType,Terms,AimIP,AimPort,ServerPort);
int TaskID = -1;
int TaskType = 0;
CTL::String AimIP;
int AimPort = 10062;
int ServerPort = 10060;
CCVector<int> Terms;
};
class TaskInfo {
inline static CTL::Map<int,TaskInfo*> TaskInfoMap;
inline static CTL::DatagramSocket* socket = nullptr;

View File

@ -55,30 +55,70 @@ private:
}
BS_Log::Warning("orderRun End");
}
void ConfigTool() {
const auto Setting = Config::getConfig();
#ifdef _WIN32
const CTL::InetAddress address(Setting->ServerIP);
#else
const CTL::InetAddress address = CTL::InetAddress::getAnyAddress();
#endif
{
std::unique_lock lock(Config::m_mutex_udp_tool);
Setting->m_socket_udp_tool = new CTL::DatagramSocket(Setting->ConfigPort,address);
}
BS_Log::Log("ConfigTool Start");
bool F = Setting->m_socket_udp_tool->setSockOpt(BROADCAST);
while (!Setting->m_socket_udp_tool->isClosed() && F) {
if (Setting->m_socket_udp_tool->available()) {
CTL::DatagramPacket packet;
Setting->m_socket_udp_tool->receive(packet);
CCHostInfo hostInfo{};
hostInfo.IPAddress = packet.getAddress().getHostAddress();
hostInfo.Port = packet.getPort();
DataPacket packet_t(packet.getData(), packet.getLength(),&hostInfo);
m_threadPool.AddTask(Routing::RoutingFunction, packet_t);
}
else {
CTL::Thread::SleepMS(1);
}
}
{
std::unique_lock lock(Config::m_mutex_udp_tool);
delete Setting->m_socket_udp_tool;
Setting->m_socket_udp_tool = nullptr;
}
BS_Log::Warning("ConfigTool End");
}
static void ConnectService() {
const auto Setting = Config::getConfig();
const auto sock = ConnectionService::getSocket();
bool isConnect = true;
bool IsConn = true;
while (Setting->Flag) {
if (sock) {
const auto wsUrl = CTL::String::format("ws://{}:{}/Order",
Setting->ServerIP.c_str(),Setting->ServerPort);
bool F = sock->Connect(wsUrl);
if (F) {
Setting->isConnect = sock->Connect(wsUrl);
if (Setting->isConnect) {
BS_Log::Log("ConnectService OK");
sock->Running();
isConnect = true;
IsConn = true;
}
else {
if (isConnect) {
if (IsConn) {
BS_Log::Log("ConnectService Failure");
isConnect = false;
IsConn = false;
}
}
}
CTL::Thread::SleepMS(3 * 1000);
}
}
static bool CloseFun() {
CTL::Application::StopDaemon();
CTL::Application::ReleaseLock();
std::terminate();
return true;
}
public:
static ThreadMain* getInstance() {
static ThreadMain instance;
@ -92,7 +132,9 @@ public:
TaskExecutor::InitPool();
TaskInfo::thread_pool.InitStart(255, 1024, 1000);
ConnectionService::init();
CC::SetCloseFun(CloseFun);
m_threadPool.AddTask(&ThreadMain::orderRun,this);
m_threadPool.AddTask(&ThreadMain::ConfigTool,this);
m_threadPool.AddTask(ThreadMain::ConnectService);
m_threadPool.AddTask(TaskInfo::InitSocket);
}