daemon_service.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /**
  2. * @file daemon_service.cpp
  3. * @brief D-Bus 服务实现
  4. */
  5. #include "daemon_service.h"
  6. #include "core/CoreService.h"
  7. #include "soft_bus_core/soft_bus_core.h"
  8. #include "api/SoftBusAPI.h"
  9. #include "manage_serial/serial_manager.h"
  10. #include "can_manager/can_manager.h"
  11. #include <QCoreApplication>
  12. #include <QDBusConnection>
  13. #include <QDateTime>
  14. #include "utils/logging.h"
  15. #include <QJsonDocument>
  16. #include <QJsonObject>
  17. #include <QJsonArray>
  18. #include <QTimer>
  19. #include <QSerialPortInfo>
  20. #include <QSerialPort>
  21. #include <QByteArray>
  22. #include <QSet>
  23. #include <unistd.h>
  24. DaemonService::DaemonService(CoreService* coreService, QObject* parent)
  25. : QObject(parent)
  26. , m_coreService(coreService)
  27. , m_loadInfoTimer(nullptr)
  28. , m_totalMessagesProcessed(0)
  29. , m_lastMessageCount(0)
  30. {
  31. initializeLoadInfo();
  32. // 定时更新负载信息(每5秒)
  33. m_loadInfoTimer = new QTimer(this);
  34. connect(m_loadInfoTimer, &QTimer::timeout, this, &DaemonService::updateLoadInfo);
  35. m_loadInfoTimer->start(5000);
  36. updateLoadInfo(); // 立即更新一次
  37. // 延迟连接硬件资源信号(确保 SoftBusAPI 已初始化)
  38. QTimer::singleShot(100, this, [this]() {
  39. SoftBusAPI* api = SoftBusAPI::instance();
  40. if (api && api->isInitialized()) {
  41. // 连接串口信号(使用队列连接确保线程安全)
  42. connect(api, &SoftBusAPI::serialDataReceived,
  43. this, [this](const QString& portName, const QByteArray& data) {
  44. QString base64Data = QString::fromUtf8(data.toBase64());
  45. emit serialDataReceived(portName, base64Data);
  46. }, Qt::QueuedConnection);
  47. // 连接CAN信号(使用队列连接确保线程安全)
  48. connect(api, &SoftBusAPI::canDataReceived,
  49. this, [this](const QString& deviceName, int canPort, unsigned int canId,
  50. const QByteArray& data, bool isExtendedId) {
  51. QString base64Data = QString::fromUtf8(data.toBase64());
  52. emit canDataReceived(deviceName, canPort, canId, base64Data, isExtendedId);
  53. }, Qt::QueuedConnection);
  54. }
  55. });
  56. }
  57. DaemonService::~DaemonService()
  58. {
  59. if (m_loadInfoTimer) {
  60. m_loadInfoTimer->stop();
  61. }
  62. }
  63. bool DaemonService::isRunning() const
  64. {
  65. return m_coreService && m_coreService->isInitialized();
  66. }
  67. QString DaemonService::getStatus() const
  68. {
  69. QJsonObject status;
  70. if (!m_coreService || !m_coreService->isInitialized()) {
  71. status["running"] = false;
  72. status["status"] = "stopped";
  73. } else {
  74. status["running"] = true;
  75. status["status"] = "running";
  76. status["initialized"] = m_coreService->isInitialized();
  77. DeviceBusCore* busCore = m_coreService->getDeviceBusCore();
  78. if (busCore) {
  79. QList<DeviceInfo> devices = busCore->getAllDevices();
  80. status["deviceCount"] = devices.size();
  81. int onlineCount = 0;
  82. for (const auto& device : devices) {
  83. if (device.status == "online" && device.isActive) {
  84. onlineCount++;
  85. }
  86. }
  87. status["onlineDeviceCount"] = onlineCount;
  88. }
  89. }
  90. // 添加客户端列表
  91. QJsonArray clientsArray;
  92. for (const QString& id : m_registeredClients) {
  93. clientsArray.append(id);
  94. }
  95. status["clients"] = clientsArray;
  96. return QJsonDocument(status).toJson(QJsonDocument::Compact);
  97. }
  98. QString DaemonService::getLoadInfo() const
  99. {
  100. QJsonObject loadInfo;
  101. if (!m_coreService || !m_coreService->isInitialized()) {
  102. loadInfo["cpuUsage"] = 0.0;
  103. loadInfo["memoryUsage"] = 0.0;
  104. loadInfo["messageRate"] = 0.0;
  105. return QJsonDocument(loadInfo).toJson(QJsonDocument::Compact);
  106. }
  107. // 计算消息处理速率(每秒处理的消息数)
  108. qint64 elapsed = m_lastUpdateTime.msecsTo(QDateTime::currentDateTime());
  109. double messageRate = 0.0;
  110. if (elapsed > 0) {
  111. qint64 messageDelta = m_totalMessagesProcessed - m_lastMessageCount;
  112. messageRate = (messageDelta * 1000.0) / elapsed;
  113. }
  114. loadInfo["messageRate"] = messageRate;
  115. loadInfo["totalMessagesProcessed"] = m_totalMessagesProcessed;
  116. loadInfo["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
  117. // TODO: 添加实际的 CPU 和内存使用率监控
  118. // 可以使用 QProcess 调用系统命令或使用系统 API
  119. loadInfo["cpuUsage"] = 0.0; // 占位符
  120. loadInfo["memoryUsage"] = 0.0; // 占位符
  121. return QJsonDocument(loadInfo).toJson(QJsonDocument::Compact);
  122. }
  123. int DaemonService::getDeviceCount() const
  124. {
  125. if (!m_coreService || !m_coreService->isInitialized()) {
  126. return 0;
  127. }
  128. DeviceBusCore* busCore = m_coreService->getDeviceBusCore();
  129. if (!busCore) {
  130. return 0;
  131. }
  132. return busCore->getAllDevices().size();
  133. }
  134. QString DaemonService::getAllDevices() const
  135. {
  136. QJsonArray devicesArray;
  137. if (!m_coreService || !m_coreService->isInitialized()) {
  138. QJsonObject result;
  139. result["devices"] = devicesArray;
  140. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  141. }
  142. DeviceBusCore* busCore = m_coreService->getDeviceBusCore();
  143. if (!busCore) {
  144. QJsonObject result;
  145. result["devices"] = devicesArray;
  146. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  147. }
  148. QList<DeviceInfo> devices = busCore->getAllDevices();
  149. for (const DeviceInfo& device : devices) {
  150. QJsonObject deviceObj;
  151. deviceObj["id"] = device.id;
  152. deviceObj["portname"] = device.portname;
  153. deviceObj["name"] = device.name;
  154. deviceObj["type"] = device.type;
  155. deviceObj["address"] = device.address;
  156. deviceObj["protocol"] = device.protocol;
  157. deviceObj["protocol_detail"] = device.protocol_detail;
  158. deviceObj["status"] = device.status;
  159. deviceObj["isActive"] = device.isActive;
  160. if (device.lastSeen.isValid()) {
  161. deviceObj["lastSeen"] = device.lastSeen.toString(Qt::ISODate);
  162. }
  163. deviceObj["properties"] = device.properties;
  164. devicesArray.append(deviceObj);
  165. }
  166. QJsonObject result;
  167. result["devices"] = devicesArray;
  168. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  169. }
  170. QString DaemonService::getMessageStats() const
  171. {
  172. QJsonObject stats;
  173. if (!m_coreService || !m_coreService->isInitialized()) {
  174. stats["totalMessages"] = 0;
  175. stats["messageRate"] = 0.0;
  176. return QJsonDocument(stats).toJson(QJsonDocument::Compact);
  177. }
  178. qint64 elapsed = m_lastUpdateTime.msecsTo(QDateTime::currentDateTime());
  179. double messageRate = 0.0;
  180. if (elapsed > 0) {
  181. qint64 messageDelta = m_totalMessagesProcessed - m_lastMessageCount;
  182. messageRate = (messageDelta * 1000.0) / elapsed;
  183. }
  184. stats["totalMessages"] = m_totalMessagesProcessed;
  185. stats["messageRate"] = messageRate;
  186. stats["lastUpdateTime"] = m_lastUpdateTime.toString(Qt::ISODate);
  187. return QJsonDocument(stats).toJson(QJsonDocument::Compact);
  188. }
  189. qint64 DaemonService::getPid() const
  190. {
  191. return static_cast<qint64>(getpid());
  192. }
  193. void DaemonService::shutdown()
  194. {
  195. LOG_DEBUG() << "DaemonService shutdown requested";
  196. emit statusChanged("", "shutting_down"); // 空字符串表示系统状态
  197. if (m_loadInfoTimer) {
  198. m_loadInfoTimer->stop();
  199. }
  200. QCoreApplication::quit();
  201. }
  202. bool DaemonService::registerClient(const QString& clientId)
  203. {
  204. if (clientId.isEmpty()) {
  205. return false;
  206. }
  207. m_registeredClients.insert(clientId);
  208. LOG_INFO() << "Client registered:" << clientId << "Total clients:" << m_registeredClients.size();
  209. // 通知所有客户端有新客户端注册(发送包含所有客户端列表的状态)
  210. QString statusJson = getStatus();
  211. QJsonDocument doc = QJsonDocument::fromJson(statusJson.toUtf8());
  212. if (doc.isObject()) {
  213. QJsonObject obj = doc.object();
  214. QJsonArray clientsArray;
  215. for (const QString& id : m_registeredClients) {
  216. clientsArray.append(id);
  217. }
  218. obj["clients"] = clientsArray;
  219. statusJson = QJsonDocument(obj).toJson(QJsonDocument::Compact);
  220. }
  221. // 广播给所有客户端(空字符串表示系统状态变化)
  222. emit statusChanged("", statusJson);
  223. return true;
  224. }
  225. void DaemonService::unregisterClient(const QString& clientId)
  226. {
  227. if (m_registeredClients.remove(clientId)) {
  228. LOG_INFO() << "Client unregistered:" << clientId << "Remaining clients:" << m_registeredClients.size();
  229. // 通知所有客户端有客户端注销
  230. QString statusJson = getStatus();
  231. QJsonDocument doc = QJsonDocument::fromJson(statusJson.toUtf8());
  232. if (doc.isObject()) {
  233. QJsonObject obj = doc.object();
  234. QJsonArray clientsArray;
  235. for (const QString& id : m_registeredClients) {
  236. clientsArray.append(id);
  237. }
  238. obj["clients"] = clientsArray;
  239. statusJson = QJsonDocument(obj).toJson(QJsonDocument::Compact);
  240. }
  241. // 广播给所有客户端
  242. emit statusChanged("", statusJson);
  243. }
  244. }
  245. QString DaemonService::getRegisteredClients() const
  246. {
  247. QJsonArray clientsArray;
  248. for (const QString& id : m_registeredClients) {
  249. clientsArray.append(id);
  250. }
  251. QJsonObject result;
  252. result["clients"] = clientsArray;
  253. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  254. }
  255. void DaemonService::updateLoadInfo()
  256. {
  257. // 更新消息计数(这里需要从实际的消息处理中获取)
  258. // 目前使用占位符,实际应该从 DeviceBusCore 或消息处理模块获取
  259. // 发出负载信息更新信号(空字符串表示系统更新,所有客户端都会收到)
  260. emit loadInfoUpdated("", getLoadInfo());
  261. // 更新统计时间
  262. m_lastMessageCount = m_totalMessagesProcessed;
  263. m_lastUpdateTime = QDateTime::currentDateTime();
  264. }
  265. void DaemonService::initializeLoadInfo()
  266. {
  267. m_totalMessagesProcessed = 0;
  268. m_lastMessageCount = 0;
  269. m_lastUpdateTime = QDateTime::currentDateTime();
  270. }
  271. // ========== 硬件资源管理接口实现 ==========
  272. bool DaemonService::openSerialPort(const QString& portName, int baudRate, int dataBits,
  273. int parity, int stopBits, int flowControl)
  274. {
  275. if (!m_coreService || !m_coreService->isInitialized()) {
  276. return false;
  277. }
  278. SoftBusAPI* api = SoftBusAPI::instance();
  279. if (!api || !api->isInitialized()) {
  280. LOG_WARNING() << "SoftBusAPI not initialized";
  281. return false;
  282. }
  283. // 查找串口信息
  284. QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
  285. for (const QSerialPortInfo& info : ports) {
  286. if (info.portName() == portName) {
  287. // 设置串口配置
  288. SerialManager::SerialConfig config;
  289. config.baudRate = static_cast<QSerialPort::BaudRate>(baudRate);
  290. config.dataBits = static_cast<QSerialPort::DataBits>(dataBits);
  291. config.parity = static_cast<QSerialPort::Parity>(parity);
  292. config.stopBits = static_cast<QSerialPort::StopBits>(stopBits);
  293. config.flowControl = static_cast<QSerialPort::FlowControl>(flowControl);
  294. api->setSerialConfig(config);
  295. // 打开串口
  296. bool success = api->openSerialPort(info);
  297. if (success) {
  298. emit serialPortStatusChanged(portName, true);
  299. }
  300. return success;
  301. }
  302. }
  303. LOG_WARNING() << "Serial port not found:" << portName;
  304. return false;
  305. }
  306. void DaemonService::closeSerialPort(const QString& portName)
  307. {
  308. SoftBusAPI* api = SoftBusAPI::instance();
  309. if (api && api->isInitialized()) {
  310. api->closeSerialPort(portName);
  311. emit serialPortStatusChanged(portName, false);
  312. }
  313. }
  314. QString DaemonService::getOpenedSerialPorts() const
  315. {
  316. QJsonArray ports;
  317. SoftBusAPI* api = SoftBusAPI::instance();
  318. if (api && api->isInitialized()) {
  319. QStringList portList = api->getOpenedSerialPorts();
  320. for (const QString& port : portList) {
  321. ports.append(port);
  322. }
  323. }
  324. QJsonObject result;
  325. result["ports"] = ports;
  326. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  327. }
  328. QString DaemonService::getAvailableSerialPorts() const
  329. {
  330. QJsonArray ports;
  331. SoftBusAPI* api = SoftBusAPI::instance();
  332. if (api && api->isInitialized()) {
  333. QStringList portList = api->getAvailableSerialPorts();
  334. for (const QString& port : portList) {
  335. ports.append(port);
  336. }
  337. }
  338. QJsonObject result;
  339. result["ports"] = ports;
  340. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  341. }
  342. bool DaemonService::writeSerialData(const QString& portName, const QString& data)
  343. {
  344. SoftBusAPI* api = SoftBusAPI::instance();
  345. if (!api || !api->isInitialized()) {
  346. return false;
  347. }
  348. // Base64 解码
  349. QByteArray byteData = QByteArray::fromBase64(data.toUtf8());
  350. return api->sendSerialData(portName, byteData);
  351. }
  352. bool DaemonService::openCanDevice(int comPort, int baudRate)
  353. {
  354. if (!m_coreService || !m_coreService->isInitialized()) {
  355. return false;
  356. }
  357. SoftBusAPI* api = SoftBusAPI::instance();
  358. if (!api || !api->isInitialized()) {
  359. LOG_WARNING() << "SoftBusAPI not initialized";
  360. return false;
  361. }
  362. bool success = api->openCanDevice(comPort);
  363. if (success) {
  364. QString deviceName = QString("CAN_%1").arg(comPort);
  365. emit canDeviceStatusChanged(deviceName, true);
  366. }
  367. return success;
  368. }
  369. void DaemonService::closeCanDevice(const QString& deviceName)
  370. {
  371. SoftBusAPI* api = SoftBusAPI::instance();
  372. if (api && api->isInitialized()) {
  373. api->closeCanDevice(deviceName);
  374. emit canDeviceStatusChanged(deviceName, false);
  375. }
  376. }
  377. QString DaemonService::getOpenedCanDevices() const
  378. {
  379. QJsonArray devices;
  380. SoftBusAPI* api = SoftBusAPI::instance();
  381. if (api && api->isInitialized()) {
  382. QStringList deviceList = api->getOpenedCanDevices();
  383. for (const QString& device : deviceList) {
  384. devices.append(device);
  385. }
  386. }
  387. QJsonObject result;
  388. result["devices"] = devices;
  389. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  390. }
  391. QString DaemonService::getAvailableCanDevices() const
  392. {
  393. QJsonArray devices;
  394. SoftBusAPI* api = SoftBusAPI::instance();
  395. if (api && api->isInitialized()) {
  396. QList<int> deviceList = api->getAvailableCanDevices();
  397. for (int comPort : deviceList) {
  398. devices.append(comPort);
  399. }
  400. }
  401. QJsonObject result;
  402. result["devices"] = devices;
  403. return QJsonDocument(result).toJson(QJsonDocument::Compact);
  404. }
  405. bool DaemonService::sendCanData(const QString& deviceName, int canPort, unsigned int canId,
  406. const QString& data, bool isExtendedId)
  407. {
  408. SoftBusAPI* api = SoftBusAPI::instance();
  409. if (!api || !api->isInitialized()) {
  410. return false;
  411. }
  412. // Base64 解码
  413. QByteArray byteData = QByteArray::fromBase64(data.toUtf8());
  414. return api->sendCanData(deviceName, canPort, canId, byteData, isExtendedId);
  415. }