添加debug重定向,添加命令行

This commit is contained in:
ranchuan
2023-12-02 11:27:25 +08:00
parent ae972b21aa
commit 66b9453255
19 changed files with 518 additions and 104 deletions

151
prot/prot_cmdline.cpp Normal file
View File

@@ -0,0 +1,151 @@
#include "prot_cmdline.h"
#include "base/mycfg.h"
#include "QNetworkConfigurationManager"
#include "QTimer"
prot_cmdline_cb cmdline_find(myarray name)
{
extern const int __start_cmdldef;
extern const int __stop_cmdldef;
cmdline_def *start = (cmdline_def *)&__start_cmdldef;
cmdline_def *end = (cmdline_def *)&__stop_cmdldef;
cmdline_def *item = 0;
for (item = start; item < end; item++)
{
if (item != nullptr)
{
if (name == item->cmd)
return item->fun;
// qDebug("if dev: %s",item->name);
}
}
qWarning("can not find cmdline named '%s'", name.data());
return nullptr;
}
// 获取本机地址
static QString get_local_ip()
{
QList<QNetworkInterface> network = QNetworkInterface::allInterfaces();
foreach (QNetworkInterface net, network)
{
QString netName = net.humanReadableName();
if (netName == "eth0")
{
QList<QNetworkAddressEntry> list = net.addressEntries(); // 获取IP地址与子掩码等
foreach (QNetworkAddressEntry address, list)
{
if (address.ip().protocol() == QAbstractSocket::IPv4Protocol) // 获取IPv4的地址
{
return address.ip().toString();
}
}
}
}
return QString();
}
void command::init_cb()
{
mycfg *cfg_ = syscfg();
if (get_local_ip().isEmpty())
{
qDebug("modify local ip addr.");
QString str = "ifconfig eth0 %1";
system(str.arg(cfg_->local_ip).toLocal8Bit().data());
str = "route add default gw %1";
system(str.arg(cfg_->gateway_ip).toLocal8Bit().data());
}
if (socket_ == nullptr)
{
socket_ = new QUdpSocket(this);
socket_->bind(QHostAddress::Any, cfg_->cmd_port);
connect(socket_, &QUdpSocket::readyRead, this, &command::ready_read_cb);
qInfo() << "udp command start.";
qInfo() << "cmd port=" << cfg_->cmd_port;
}
}
void command::send(QByteArray data)
{
if (socket_ == nullptr)
return;
if (data.back() != '\n')
{
data.append('\n');
}
socket_->writeDatagram(data, host_addr, port);
}
static void cmdline_help(QList<myarray> args);
void command::ready_read_cb()
{
recv_data.resize(socket_->bytesAvailable());
socket_->readDatagram(recv_data.data(), recv_data.size(), &host_addr, &port);
myarray cmd = recv_data.simplified();
QList<myarray> args=cmd.split(' ');
if(args.size()>0){
prot_cmdline_cb fun=cmdline_find(args[0]);
if(fun!=nullptr){
fun(args);
}else{
mystring str;
str=mystring::asprintf("can not find command: %s",cmd.data());
send(str.data());
cmdline_help(args);
}
}
qInfo() << "udp command." << cmd;
recv_data.clear();
}
static void cmdline_help(QList<myarray> args)
{
command *c=command_start();
extern const int __start_cmdldef;
extern const int __stop_cmdldef;
cmdline_def *start = (cmdline_def *)&__start_cmdldef;
cmdline_def *end = (cmdline_def *)&__stop_cmdldef;
cmdline_def *item = 0;
for (item = start; item < end; item++)
{
if (item != nullptr)
{
QByteArray send_data;
send_data.append(item->cmd);
send_data.append(30-send_data.size(),'.');
send_data.append(item->help);
c->send(send_data);
}
}
}
cmdline_export(help,cmdline_help,print help information.);
static command *g_command;
static QThread g_thread;
command *command_start()
{
if (g_command == nullptr)
{
g_command = new command();
g_command->moveToThread(&g_thread);
QTimer::singleShot(0, g_command, &command::init_cb);
g_thread.start();
}
return g_command;
}

66
prot/prot_cmdline.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef prot_cmdline_h__
#define prot_cmdline_h__
#include "QObject"
#include "base/base.h"
#include "QList"
#include "interface/codec.h"
#include "interface/interface.h"
#include "base/mycfg.h"
#include "QThread"
#include <QNetworkInterface>
#include <QUdpSocket>
// using namespace std;
// using namespace std::placeholders;
// typedef std::function<void(myarray data)> prot_cmdline_cb;
typedef void (*prot_cmdline_cb)(QList<myarray> data);
typedef struct
{
const char *cmd;
const char *help;
prot_cmdline_cb fun;
} cmdline_def;
#define cmdline_export(name_, fun_, help_) \
const static char __cmdline_##name_##_name[] __attribute__((section(".rodata.cmdlstr"))) = #name_; \
const static char __cmdline_##name_##_help[] __attribute__((section(".rodata.cmdlstr"))) = #help_; \
__attribute__((used)) static cmdline_def _cmdline_##name_ __attribute__((section("cmdldef"))) = { \
.cmd = __cmdline_##name_##_name, \
.help = __cmdline_##name_##_help, \
.fun = fun_, \
}
class command : public QObject
{
Q_OBJECT
public:
command()
{
socket_ = nullptr;
}
virtual ~command()
{
if (socket_ != nullptr)
delete socket_;
}
void send(QByteArray data);
void init_cb();
void ready_read_cb();
private:
QUdpSocket *socket_;
QByteArray recv_data;
QHostAddress host_addr;
quint16 port;
};
command *command_start();
#endif