otaController.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. const pool = require('../config/db');
  2. const logger = require('../logger');
  3. const fs = require('fs');
  4. const path = require('path');
  5. const multer = require('multer');
  6. const { v4: uuidv4 } = require('uuid');
  7. const crypto = require('crypto');
  8. const FIRMWARE_PATH = path.join(__dirname, '../sketch_feb24a.ino.bin');
  9. const LATEST_FIRMWARE_VERSION = "1.0.3";
  10. const upload = multer({ dest: 'uploads/' });
  11. // 固件签名验证函数
  12. const validateFirmwareSignature = (filePath) => {
  13. // 这里添加实际的签名验证逻辑
  14. return true; // 暂时返回true用于测试
  15. };
  16. // 新增固件版本查询方法
  17. module.exports = {
  18. // 原有检查更新方法
  19. checkUpdates: async (req, res) => {
  20. const { device_id, current_version } = req.body;
  21. logger.info(`OTA检查请求: 设备=${device_id}, 版本=${current_version}`);
  22. try {
  23. const [device] = await pool.promise().query(
  24. 'SELECT * FROM devices WHERE device_id = ?',
  25. [device_id]
  26. );
  27. if (!device.length) {
  28. return res.status(404).json({
  29. code: 404,
  30. message: '设备未注册'
  31. });
  32. }
  33. const requiresUpdate = current_version !== LATEST_FIRMWARE_VERSION;
  34. const updateInfo = {
  35. latest_version: LATEST_FIRMWARE_VERSION,
  36. release_notes: "1. 优化温控逻辑\n2. 修复安全漏洞",
  37. file_size: fs.statSync(FIRMWARE_PATH).size,
  38. mandatory: requiresUpdate
  39. };
  40. res.json({
  41. code: 200,
  42. requires_update: requiresUpdate,
  43. ...updateInfo
  44. });
  45. } catch (error) {
  46. logger.error('检查更新失败:', error);
  47. res.status(500).json({
  48. code: 500,
  49. message: '服务器内部错误'
  50. });
  51. }
  52. },
  53. // 原有下载方法
  54. downloadFirmware: (req, res) => {
  55. if (fs.existsSync(FIRMWARE_PATH)) {
  56. res.download(FIRMWARE_PATH);
  57. } else {
  58. res.status(404).send("固件文件未找到");
  59. }
  60. },
  61. // 新增上传处理方法
  62. uploadFirmware: upload,
  63. handleFirmwareUpload: async (req, res) => {
  64. if (!req.file) {
  65. return res.status(400).json({
  66. code: 400,
  67. message: '未选择固件文件'
  68. });
  69. }
  70. try {
  71. if (!validateFirmwareSignature(req.file.path)) {
  72. fs.unlinkSync(req.file.path);
  73. return res.status(403).json({
  74. code: 403,
  75. message: '固件签名验证失败'
  76. });
  77. }
  78. fs.renameSync(req.file.path, FIRMWARE_PATH);
  79. res.json({
  80. code: 200,
  81. message: '固件上传成功',
  82. version: LATEST_FIRMWARE_VERSION
  83. });
  84. } catch (error) {
  85. res.status(500).json({
  86. code: 500,
  87. message: '固件上传失败'
  88. });
  89. }
  90. },
  91. // 新增升级方法
  92. upgradeStatus: new Map(),
  93. startUpgrade: (req, res) => {
  94. const { device_id } = req.body;
  95. const upgradeId = uuidv4();
  96. // 修复this指向问题
  97. module.exports.upgradeStatus.set(upgradeId, {
  98. device_id,
  99. progress: 0,
  100. status: 'pending',
  101. start_time: Date.now()
  102. });
  103. res.json({
  104. code: 200,
  105. message: '升级已启动',
  106. upgrade_id: upgradeId
  107. });
  108. }, // ← 保持逗号分隔
  109. checkDeviceUpdate: async (req, res) => {
  110. const { deviceId, currentVersion } = req.body;
  111. try {
  112. const [versions] = await pool.promise().query(
  113. 'SELECT * FROM firmware_versions WHERE device_type = ? ORDER BY release_date DESC LIMIT 1',
  114. [deviceId]
  115. );
  116. // 添加缺失的闭合括号和错误处理
  117. const latest = versions[0] || { version_number: currentVersion };
  118. const hasUpdate = latest.version_number > currentVersion;
  119. res.json({
  120. code: 200,
  121. hasUpdate,
  122. latestVersion: latest.version_number
  123. });
  124. } catch (error) {
  125. logger.error('检查更新失败:', error);
  126. res.status(500).json({ code: 500, message: '服务器内部错误' });
  127. }
  128. }, // ← 添加逗号分隔
  129. getFirmwareVersions: async (req, res) => {
  130. try {
  131. const [results] = await pool.promise().query(
  132. 'SELECT * FROM firmware_versions ORDER BY release_date DESC'
  133. );
  134. res.json({ code: 200, data: results });
  135. } catch (error) {
  136. logger.error('获取固件版本失败:', error);
  137. res.status(500).json({ code: 500, message: '服务器内部错误' });
  138. }
  139. }
  140. }; // ← 确保对象正确闭合