This commit is contained in:
flowerstonezl
2026-03-11 11:21:53 +08:00
parent 993581b2a4
commit fef874e0e3
5 changed files with 163 additions and 7 deletions

View File

@@ -1,8 +1,10 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QDBusConnection>
#include <signal.h> #include <signal.h>
#include "src/utils/logs/logging.h" #include "src/utils/logs/logging.h"
#include "src/core/CoreService.h" #include "src/core/CoreService.h"
#include "src/api/ipc_dbus/IpcDBus.h"
void signalHandler(int signal) void signalHandler(int signal)
{ {
@@ -12,24 +14,109 @@ void signalHandler(int signal)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// ==================================
// 创建并配置 Qt 应用程序对象
// ==================================
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
app.setApplicationName("soft_bus_daemon"); app.setApplicationName("soft_bus_daemon");
app.setApplicationVersion("1.0.0"); app.setApplicationVersion("1.0.0");
app.setOrganizationName("soft_bus"); app.setOrganizationName("soft_bus");
// ==================================
// 设置 Qt 应用程序信息
// ==================================
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("Soft Bus Daemon")); parser.setApplicationDescription(QStringLiteral("Soft Bus Daemon"));
parser.addHelpOption(); parser.addHelpOption();
parser.addVersionOption(); parser.addVersionOption();
QCommandLineOption roleOption(QStringLiteral("role"), QStringLiteral("Daemon role (CoreRouter, CollectorSerial, CollectorCan, Collector, SqlServer)"));
parser.addOption(roleOption);
parser.process(app); parser.process(app);
LOG_INFO() << "Starting Soft Bus Daemon";
const QString roleString = parser.value(roleOption).trimmed();
CoreService::Role role = CoreService::Role::CoreRouter; // 默认角色
if (roleString == QStringLiteral("CoreRouter")) {
role = CoreService::Role::CoreRouter;
} else if (roleString == QStringLiteral("CollectorSerial")) {
role = CoreService::Role::CollectorSerial;
} else if (roleString == QStringLiteral("CollectorCan")) {
role = CoreService::Role::CollectorCan;
} else if (roleString == QStringLiteral("Collector")) {
role = CoreService::Role::Collector;
} else if (roleString == QStringLiteral("SqlServer")) {
role = CoreService::Role::SqlServer;
} else {
LOG_ERROR() << "Invalid role:" << roleString
<< "valid roles are: CoreRouter, CollectorSerial, CollectorCan, Collector, SqlServer";
return 1;
}
// ========================================================================
// 创建并注册 D-Bus 服务(仅在 core_router 角色中启用)
// ========================================================================
if (role == CoreService::Role::CoreRouter) {
// D-Bus 是 Linux 系统的进程间通信机制,允许外部客户端访问守护进程
// I 实现了具体的 D-Bus 接口,提供状态查询、硬件操作等功能
// 创建 DaemonService 实例,传入 CoreService 以便访问核心功能
// 父对象设置为 app确保在应用程序退出时自动销毁
g_daemonService = new DaemonService(coreService, &app);
// 连接系统 D-BussystemBus而不是会话 D-BussessionBus
// 系统 D-Bus 是系统级服务,可以在所有用户会话中访问
// 会话 D-Bus 只能在同一用户会话中访问
QDBusConnection connection = QDBusConnection::systemBus();
if (!connection.isConnected()) {
LOG_ERROR() << "Cannot connect to system D-Bus";
LOG_ERROR() << "Please ensure D-Bus is running and proper permissions are configured";
return 1; // 无法连接 D-Bus守护进程无法提供服务
}
// 注册 D-Bus 服务名称
// 服务名称格式:反向域名格式(如 "com.softbus.Daemon"
// 其他进程可以通过此名称找到守护进程
if (!connection.registerService("com.softbus.Daemon")) {
LOG_ERROR() << "Failed to register D-Bus service:" << connection.lastError().message();
LOG_ERROR() << "Possible causes:";
LOG_ERROR() << " 1. Service name already in use";
LOG_ERROR() << " 2. Insufficient D-Bus permissions";
LOG_ERROR() << " 3. D-Bus configuration issue";
return 1; // 服务注册失败,无法提供 D-Bus 接口
}
// 注册 D-Bus 对象路径和方法
// 对象路径:"/com/softbus/Daemon" - 类似于文件系统中的路径
// ExportAllSlots: 导出所有 public slots 作为 D-Bus 方法
// ExportAllSignals: 导出所有 signals 作为 D-Bus 信号
// 这样外部客户端就可以调用守护进程的方法和接收信号
if (!connection.registerObject("/com/softbus/Daemon", g_daemonService,
QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals)) {
LOG_ERROR() << "Failed to register D-Bus object:" << connection.lastError().message();
return 1; // 对象注册失败D-Bus 接口无法使用
}
// 打印成功启动信息,便于调试和监控
LOG_INFO() << "Soft Bus Daemon started successfully";
LOG_INFO() << "D-Bus service: com.softbus.Daemon";
LOG_INFO() << "D-Bus object: /com/softbus/Daemon";
LOG_INFO() << "Ready to accept D-Bus requests";
}
// ==================================
// 处理系统信号,确保在接收到 SIGINT 或 SIGTERM 时能够优雅地退出
// ==================================
signal(SIGINT, signalHandler); signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler); signal(SIGTERM, signalHandler);
CoreService::instance()->initialize(); CoreService::instance()->initialize();
int ret = app.exec();
CoreService::instance()->shutdown(); CoreService::instance()->shutdown();
int ret = app.exec();
return ret; return ret;
} }

View File

View File

@@ -0,0 +1,62 @@
/**
* @file Ipc_dbus.h
* @brief D-Bus 服务接口 - 提供核心服务状态和负载查询
*/
#ifndef IPC_DBUS_H
#define IPC_DBUS_H
#include <QObject>
/**
* @brief D-Bus 服务适配器 - 暴露核心服务接口
*/
class IpcDBus : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "com.softbus.Daemon")
public:
explicit IpcDBus(CoreService* coreService, QObject* parent = nullptr);
~IpcDBus();
public slots:
/**
* @brief 检查核心服务是否运行
* @return true 如果核心服务正在运行
*/
bool isRunning() const;
/**
* @brief 获取核心服务状态信息
* @return JSON 格式的状态信息
*/
QString getStatus() const;
/**
* @brief 获取守护进程的进程ID
* @return 进程ID如果无法获取则返回0
*/
qint64 getPid() const;
/**
* @brief 关闭守护进程
*/
void shutdown();
private slots:
void updateLoadInfo();
private:
};
#endif // IPC_DBUS_H

View File

@@ -7,6 +7,13 @@ class CoreService : public QObject {
public: public:
static CoreService* instance(); static CoreService* instance();
enum Role {
CoreRouter, // 核心路由器,负责设备发现、连接管理和数据转发
Collector, // 数据收集器,负责从设备收集数据
CollectorSerial, // 串口数据收集器
CollectorCan, // CAN总线数据收集器
SqlServer, // SQL服务器负责存储设备数据
};
bool initialize(); bool initialize();
void shutdown(); void shutdown();

View File

@@ -16,21 +16,21 @@
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
// 构建来源字符串的辅助宏 // 构建来源字符串的辅助宏
#define __LOG_SOURCE__ (QString(__FILENAME__) + "." + QString(__FUNCTION__)) // #define __LOG_SOURCE__ (QString(__FILENAME__) + "." + QString(__FUNCTION__))
// 日志宏,格式:[文件名.函数名] 消息 // 日志宏,格式:[文件名.函数名] 消息
#define LOG_DEBUG() \ #define LOG_DEBUG() \
qDebug() << "[" << "SYSTEM" << "DEBUG" << __LOG_SOURCE__ << "[" << __FILENAME__ << "." << __FUNCTION__ << "]" qDebug() << "[" << __FILENAME__ << "/" << __FUNCTION__ << "]"
#define LOG_ERROR() \ #define LOG_ERROR() \
qCritical() << "[" << "SYSTEM" << "ERROR" << __LOG_SOURCE__ << "[" << __FILENAME__ << "." << __FUNCTION__ << "]" qCritical() << "[" << __FILENAME__ << "/" << __FUNCTION__ << "]"
#define LOG_INFO() \ #define LOG_INFO() \
qInfo() << "[" << "SYSTEM" << "INFO" << __LOG_SOURCE__ << "[" << __FILENAME__ << "." << __FUNCTION__ << "]" qInfo() << "[" << __FILENAME__ << "/" << __FUNCTION__ << "]"
#define LOG_WARNING() \ #define LOG_WARNING() \
qWarning() << "[" << "SYSTEM" << "WARNING" << __LOG_SOURCE__ << "[" << __FILENAME__ << "." << __FUNCTION__ << "]" qWarning() << "[" << __FILENAME__ << "/" << __FUNCTION__ << "]"
#endif // LOGGING_H #endif // LOGGING_H