lgq
3 天以前 081f12a52906abe6c2d139fdc144135978681009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import dxCommonUtils from '../../dxmodules/dxCommonUtils.js';
import dxOs from "../../dxmodules/dxOs.js";
import log from '../../dxmodules/dxLogger.js'
import qrRule from '../../dxmodules/dxQrRule.js'
import config from '../../dxmodules/dxConfig.js'
import dxMap from '../../dxmodules/dxMap.js'
import ota from "../../dxmodules/dxOta.js";
import sqliteService from "./sqliteService.js";
import driver from '../driver.js';
import utils from '../common/utils/utils.js';
import configConst from '../common/consts/configConst.js';
import configService from './configService.js';
import accessService from './accessService.js';
const codeService = {}
 
codeService.receiveMsg = function (data) {
    log.info('[codeService] receiveMsg :' + JSON.stringify(data.data))
    let str = dxCommonUtils.codec.utf8HexToStr(dxCommonUtils.codec.arrayBufferToHex(data.data))
    this.code(str)
}
 
codeService.code = function (data) {
    log.info('[codeService] code :' + data)
    data = qrRule.formatCode(data, sqliteService)
    if (data.type == 'config' || data.code.startsWith("___VF102_CONFIG_V1.1.0___") || data.code.startsWith("___VBAR_ID_ACTIVE_V")) {
        handleSpecialCodes(data);
    } else {
        log.info("access:" + JSON.stringify(data))
        accessService.access(data);
    }
}
 
function handleSpecialCodes (data) {
    if (data.code.startsWith("___VBAR_ID_ACTIVE_V")) {
        //云证激活
        let activeResute = driver.nfc.eidActive(data.code);
        if (activeResute === 0) {
            log.info("[codeService] code: activeResute " + activeResute + " 云证激活成功")
        } else {
            log.info("[codeService] code: activeResute " + activeResute + " 云证激活失败")
        }
    } else {
        // 配置码
        configCode(data.code);
    }
}
 
// 配置码处理
function configCode (code) {
    // 1. 校验签名
    if (!checkConfigCode(code)) {
        log.error("[codeService] configCode: 配置码校验失败")
        return
    }
    // 2. 解析JSON
    let json = utils.parseString(code)
    if (Object.keys(json).length <= 0) {
        try {
            json = JSON.parse(code.slice(code.indexOf("{"), code.lastIndexOf("}") + 1))
        } catch (error) {
            log.error(error)
        }
    }
    log.info("[codeService] configCode: 解析配置码 ", JSON.stringify(json))
    // 3. 执行各类操作
    if (json.update_flag === 1) { // ota升级
        return handleOtaUpdate(json);
    }
    // 4. 设备配置相关
    processDeviceConfig(json)
    
}
 
function processDeviceConfig(json) {
    let configData = {}
    for (const [key, value] of Object.entries(json)) {
        let transKey = configConst.getValueByKey(key);
        if (!transKey) continue;
        const [parentKey, childKey] = transKey.split('.');
        if (!configData[parentKey]) {
            configData[parentKey] = {};
        }
        configData[parentKey][childKey] = json[key];
    }
    const handleConfigResult = (success) => {
        if (success) {
            log.info("[codeService] configCode: 配置成功");
        } else {
            log.error("[codeService] configCode: 配置失败");
        }
    };
    if (Object.keys(configData).length > 0) {
        const result = configService.configVerifyAndSave(configData)
        if (typeof result != 'boolean') {
            log.error(result)
            return
        }
        handleConfigResult(result);
    } else {
        handleConfigResult(false);
    }
}
 
// ota升级
function handleOtaUpdate (json) {
    const net_map = dxMap.get("NET")
    let map = dxMap.get("UPDATE")
    if (net_map.get("NET_STATUS") != "connected") {
        codeService.showUpdateStatus('failed', "Please check the network")
        return
    }
    if (map.get("updateFlag")) return
    map.put("updateFlag", true)
    try {
        codeService.showUpdateStatus('begin')
        ota.updateHttp(json.update_addr, json.update_md5, 300)
        codeService.showUpdateStatus('success')
        dxOs.asyncReboot(1)
    } catch (error) {
        codeService.showUpdateStatus('failed', error.message);
    } finally {
        map.del("updateFlag")
    }
}
 
//校验配置码
function checkConfigCode (code) {
    let password = config.get('sysInfo.com_passwd') || '1234567887654321'
    let lastIndex = code.lastIndexOf("--");
    let DELIMITER = "--"
    if (lastIndex < 0) {
        lastIndex = code.lastIndexOf("__");
        DELIMITER = "__"
    }
    // 分隔符未找到
    if (lastIndex === -1) {
        log.error(`Delimiter "${DELIMITER}" not found in code: ${code}`);
        return false;
    }
    const dataPart = code.substring(0, lastIndex);
    const signaturePart = code.substring(lastIndex + DELIMITER.length);
    let expectedSignature
    try {
 
        expectedSignature = dxCommonUtils.codec.arrayBufferToBase64(dxCommonUtils.codec.hexToArrayBuffer(dxCommonUtils.crypto.hmacMd5(dataPart, password)))
    } catch (error) {
        log.error(error)
        return false
    }
    return expectedSignature == signaturePart;
}
 
const UPDATE_MESSAGES = {
    begin: {
        en: "Start Upgrading",
        zh: "开始升级"
    },
    success: {
        en: "Upgrade Successfully",
        zh: "升级成功"
    },
    failed: {
        en: (detail) => `Upgrade Failed: ${detail || "Upgrade package download failed"}`,
        zh: (detail) => `升级失败: ${codeService.errorMsgMap[detail] || "下载失败,请检查网址"}`
    }
};
 
/**
 * 显示升级状态提示
 * @param {string} status - 状态类型: 'begin' | 'success' | 'failed'
 * @param {string} [errorMsg] - 失败时的错误信息(仅 status='failed' 时有效)
 */
codeService.showUpdateStatus = function (status, errorMsg) {
    let defaultErrorMsg = 'Upgrade package download failed';
    if (status !== 'failed') {
        errorMsg = null;
    }
    // 获取当前语言
    const isEn = config.get("base.language") === "EN";
    const langKey = isEn ? 'en' : 'zh';
    // 获取对应状态的消息模板或文本
    const msgConfig = UPDATE_MESSAGES[status];
    if (!msgConfig) {
        return;
    }
    let message;
    if (typeof msgConfig[langKey] === 'function') {
        // 对于 failed,使用函数生成动态消息
        const displayError = errorMsg && errorMsg.includes("Download failed")
            ? defaultErrorMsg
            : errorMsg;
        message = msgConfig[langKey](displayError);
    } else {
        // 其他状态直接取文本
        message = msgConfig[langKey];
    }
};
 
codeService.errorMsgMap = {
    "The 'url' and 'md5' param should not be null": "“url”和“md5”参数不能为空",
    "The 'size' param should be a number": "“size” 参数应该是一个数字",
    "The upgrade package is too large, and not be enough space on the disk to download it": "升级包过大,磁盘空间不足,无法下载",
    "Download failed, please check the url:": "下载失败,请检查网址",
    "Download failed with wrong md5 value": "下载失败,md5 值错误",
    "Build shell file failed": "构建 shell 文件失败",
    "Upgrade package download failed": "升级包下载失败",
    "Please check the network": "请检查网络"
}
 
export default codeService