#include "Config.h" #include "BS_Log.h" #include "CCFIleInStream.h" #include "CCFileOutStream.h" #include "CCProcess.h" #include "ConnectionService.h" #include "NetInfo/NetWork.h" #include "PortService/ByteTool.h" std::shared_mutex Config::m_mutex_udp; std::shared_mutex Config::m_mutex_udp_tool; void Config::Save() { const auto Setting = getConfig(); try { const JSON Json(*Setting); const auto Path = GetSettingDB(); CTL::FileOutStream::WriteFile(Path,Json.dump()); } catch (CCException& e) { BS_Log::Error("Config::Save Error: {}",e.what()); } } void Config::Init() { const auto Setting = getConfig(); try { const auto Path = GetSettingDB(); const CCFile file(Path); if (file.isExists()) { const auto str = CTL::FileInputStream::ReadFileDataAll(Path); CTL::JSONObject Json = CTL::JSONObject::parse(str); Setting->IP = Json["IP"]; Setting->OrderPort = Json["OrderPort"]; Setting->StreamPort = Json["StreamPort"]; Setting->HttpPort = Json["HttpPort"]; Setting->Flag = Json["Flag"]; Setting->ServerID = Json["ServerID"]; Setting->ServerIP = Json["ServerIP"]; Setting->ServerPort = Json["ServerPort"]; Setting->ID = Json["ID"]; Setting->Name = Json["Name"]; Setting->WorkingMode = Json["WorkingMode"]; Setting->TermNumber = Json["TermNumber"]; Setting->DHCPFlag = Json["DHCPFlag"]; Setting->TermIPGw = Json["TermIPGw"]; Setting->TermIPNm = Json["TermIPNm"]; } } catch (CCException& e) { BS_Log::Error("Config::Init Error: {}",e.what()); } #ifdef IS_ARM32 if (Setting->IP.empty()) { try { Setting->MacAddr = CTL::System::GetMac(); } catch (...){} Setting->IP = "192.168.1.108"; Setting->TermIPNm = "255.255.255.0"; Setting->TermIPGw = "192.168.1.1"; } SetNetWorkInfo(Setting->IP,Setting->TermIPGw,Setting->TermIPNm); #else Setting->IP = GetIP(); #endif BS_Log::Log("Local IP: {}",Setting->IP.c_str()); BS_Log::Log("Local ID: {}",Setting->ID); } Config * Config::getConfig() { static Config config; return &config; } bool Config::IsRunning() { return getConfig()->Flag; } 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 IPList; for (const auto IP : List) { if (IP != "127.0.0.1") { IPList.push_back(IP); } if (IP == Setting->IP) { return IP; } } return IPList.empty() ? "127.0.0.1" : IPList[0]; } ConfigTerm * Config::getThisInfo() { const auto Setting = getConfig(); const auto Data = new ConfigTerm; std::memset(Data, 0, sizeof(ConfigTerm)); #define SAFE_STRNCPY(dest, src, size) do { \ const auto& s = (src); \ if (!s.empty()) { \ std::strncpy((dest), s.c_str(), (size) - 1); \ (dest)[(size) - 1] = '\0'; \ } \ } while(0) try { SAFE_STRNCPY(Data->termIDnVerStr, Setting->Ver, sizeof(Data->termIDnVerStr)); SAFE_STRNCPY(Data->macStr, Setting->MacAddr, sizeof(Data->macStr)); SAFE_STRNCPY(Data->macChkStr, Setting->MacAddr, sizeof(Data->macChkStr)); SAFE_STRNCPY(Data->servIPAddrStr, Setting->ServerIP, sizeof(Data->servIPAddrStr)); SAFE_STRNCPY(Data->termIPAddrStr, Setting->IP, sizeof(Data->termIPAddrStr)); SAFE_STRNCPY(Data->termIPGwStr, Setting->TermIPGw, sizeof(Data->termIPGwStr)); SAFE_STRNCPY(Data->termIPNmStr, Setting->TermIPNm, sizeof(Data->termIPNmStr)); const auto termCmdPortStr = CC::to_String(Setting->OrderPort); SAFE_STRNCPY(Data->termCmdPortStr, termCmdPortStr, sizeof(Data->termCmdPortStr)); const auto servCmdPortStr = CC::to_String(Setting->ServerPort); SAFE_STRNCPY(Data->servCmdPortStr, servCmdPortStr, sizeof(Data->servCmdPortStr)); const auto termStmPortStr = CC::to_String(Setting->StreamPort); SAFE_STRNCPY(Data->termStmPortStr, termStmPortStr, sizeof(Data->termStmPortStr)); Data->workModeStr[0] = getTermWorkInfo(Setting->WorkingMode); Data->workModeStr[1] = '\0'; std::strncpy(Data->btNameStr, "", sizeof(Data->btNameStr) - 1); Data->btNameStr[sizeof(Data->btNameStr) - 1] = '\0'; const auto dhcpFlagStr = CC::to_String(Setting->DHCPFlag); SAFE_STRNCPY(Data->dhcpFlagStr, dhcpFlagStr, sizeof(Data->dhcpFlagStr)); std::strncpy(Data->btPwdStr, "", sizeof(Data->btPwdStr) - 1); Data->btPwdStr[sizeof(Data->btPwdStr) - 1] = '\0'; const auto termTypeStr = CC::to_String(Setting->TermNumber); SAFE_STRNCPY(Data->termTypeStr, termTypeStr, sizeof(Data->termTypeStr)); std::strncpy(Data->sipUsrNameStr, "", sizeof(Data->sipUsrNameStr) - 1); Data->sipUsrNameStr[sizeof(Data->sipUsrNameStr) - 1] = '\0'; std::strncpy(Data->sipUsrPwdStr, "", sizeof(Data->sipUsrPwdStr) - 1); Data->sipUsrPwdStr[sizeof(Data->sipUsrPwdStr) - 1] = '\0'; std::strncpy(Data->sipProxyRealmStr, "", sizeof(Data->sipProxyRealmStr) - 1); Data->sipProxyRealmStr[sizeof(Data->sipProxyRealmStr) - 1] = '\0'; std::strncpy(Data->cmdFlagByteStr, "", sizeof(Data->cmdFlagByteStr) - 1); Data->cmdFlagByteStr[sizeof(Data->cmdFlagByteStr) - 1] = '\0'; const auto onlineFlagStr = CC::to_String(Setting->isConnect); SAFE_STRNCPY(Data->onlineFlagStr, onlineFlagStr, sizeof(Data->onlineFlagStr)); } catch (...) { BS_Log::Error("getThisInfo: String copy exception"); delete Data; return nullptr; } #undef SAFE_STRNCPY 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) { #ifdef IS_ARM32 try{ CTL::String str = CTL::String::format("ifconfig eth0 down"); CTL::System::Execute(str); CTL::Thread::SleepMS(5); str = CTL::String::format("ifconfig eth0 up"); CTL::System::Execute(str); CTL::Thread::SleepMS(5); str = CTL::String::format("ifconfig eth0 {} netmask {}",IP.c_str(),Mask.c_str()); CTL::System::Execute(str); CTL::Thread::SleepMS(5); str = CTL::String::format("route add default gw {}",GW.c_str()); CTL::System::Execute(str); } catch (CCException& e){ BS_Log::Error("[fun-configure|MainConfigure] NetInit Error: {}",e.what()); } #elif IS_ARM try{ //获取当前网络名称 const 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()); } #endif } 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 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; } char Config::getTermWorkInfo(const char index) { static constexpr char mappings[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', }; const auto size = std::size(mappings) - 1; if (index >= 0 && index <= size) { return mappings[index]; } return 0x30; }