// plugin/etc/pages/deviceUpgrade/deviceUpgrade.js import { starSearch, stopSearch } from "../../../utils/blue-related-tools/blue_tool.js" import { HOME_DIRECTORY, OBU_SYSTEM_FILE, RANDOM_NUMBER, APPLICATION_DIRECTORY, CMD_READBINARY, CMD_GETBALANCE } from '../../../utils/cmdConfig' import { transCmd, transCmdArrAfter, transCmdAfter } from '../../../utils/etc-sdk-tool/etc-sdk-tool' import { ActiveDevice, DisConnectDevice, EquipmentDetection } from "../../../utils/active-tools/active-device-tools.js" import { formatCardNumber } from "../../../utils/obj-tools.js" import { API } from '../../../network/etcApi' Page({ /** * 页面的初始数据 */ data: { isLoading: false, showType: 1, showPopDevice: false, devList: [], searchFailMsg: "请检查手机蓝牙、ETC蓝牙是否均已打开,连接过程中将手机和ETC设备尽量靠近", searchFailTitle: "未检测到ETC设备", deviceInfo: "", cardIdStr: "", obuInfo: { version: '', obuId: '', chipSn: '' }, cardInfo: { version: '', cardId: '' } }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { }, // 设备升级 devipdeUpgrade () { }, // 点击开始搜索 tapStar() { this.configNavTitle() this.setData({ showPopDevice: false, devList: [], showType: 1, }) wx.showLoading({ title: '正在搜索设备...', }) let self = this; starSearch((DevResult) => { console.log(DevResult); wx.hideLoading() if (DevResult.code == 0) { self.configNavTitle("验证设备") self.setData({ devList: DevResult.data, showPopDevice: true, }); } else { self.configSearchFail(DevResult.code) } }, false, "", false); }, // 确认升级 async tapOwner(e) { // stopSearch(false); let device = e.detail; this.data.deviceInfo = JSON.stringify(e) wx.showToast({ title: '已选择设备', }) const res = await this.configActive(device); }, // 设备连接 async configActive (device) { const that = this; const rt = await EquipmentDetection({ device, disconnectCallback: () => { that.configSearchFail(250) }, }) if (rt.code !== 0) { return rt } else { this.getObjDetail() return res } }, // 配置搜索失败 configSearchFail(code) { let failMsg = "请检查手机蓝牙、ETC蓝牙是否均已打开,连接过程中将手机和ETC设备尽量靠近" let failTitle = "未检测到ETC设备" if (code == -111 || code == -112) { failMsg = code == -111 ? "手机蓝牙权限未授权,无法读取蓝牙是否开启状态,请打开蓝牙" : "手机定位权限获取失败,请前往手机系统设置开启手机定位服务" failTitle = "蓝牙状态异常" } this.setData({ showType: 2, searchFailMsg: failMsg, searchFailTitle: failTitle, }) }, // 获取Obu设备详情 async getObjDetail () { let cmdArr = [HOME_DIRECTORY, OBU_SYSTEM_FILE, RANDOM_NUMBER] let res = await transCmd(cmdArr, '20') console.log('设备卡签信息:1111') console.log(res) let cmdResult = res.cmdResult ? res.cmdResult.split(',') : [] if (cmdResult && cmdResult.length) { var status = cmdResult[1].substring(cmdResult[1].length - 4, cmdResult[1].length); //第一次获取随机数 if (status == "9000") { this.data.obuInfo.obuId = cmdResult[1].substring(20, 36); this.data.obuInfo.version = cmdResult[1].substring(18, 20); this.data.obuInfo.chipSn = cmdResult[1].substring(0, 8) console.log(this.data.obuInfo) this.getCardId() } else { wx.showToast('获取设备信息错误!') } } else { wx.showToast('获取设备信息错误!') } }, // 获取卡信息 async getCardId () { let cmdArr = [HOME_DIRECTORY, APPLICATION_DIRECTORY, CMD_READBINARY, CMD_GETBALANCE]; let res = await transCmd(cmdArr, '10') let cmdResult = res.cmdResult ? res.cmdResult.split(',') : [] let str = cmdResult[2].substring(cmdResult[2].length - 4, cmdResult[2].length); //判断是否为9000 let str3 = cmdResult[3].substring(cmdResult[3].length - 4, cmdResult[3].length); //判断是否为9000 if (str == "9000" || str3 == "9000") { if (cmdResult[2].length > 86 || cmdResult[3] >= 12) { this.data.cardInfo.cardId = cmdResult[2].substring(20, 40); this.data.cardInfo.version = cmdResult[2].substring(18, 20) console.log(this.data.cardInfo) this.devideUpgrade() } else { wx.showModal({ title: '提示', content: "CMD_READBINARY指令长度不符" + cmdResult }) } return; } }, // 设备升级 async devideUpgrade () { if (this.data.obuInfo.version == '48' || this.data.obuInfo.version == '49' || this.data.cardInfo.version == '48' || this.data.cardInfo.version == '49') { let params = { contractSN: this.data.obuInfo.obuId, //OBU合同序列号 16位 chipSn: this.data.obuInfo.chipSn, //OBU晶片序列号 8位 issueMode: 'UPG', //发行模式 issueType: 'SCOBU', //发行发行类型 cardVersion: this.data.cardInfo.version, //卡版本号 obuVersion: this.data.obuInfo.version //OBU版本号 } let applyData = await this.apply4Upgrade(params) if (!applyData || (applyData && applyData.code !== 200)) return false if (this.data.obuInfo.version == '48' || this.data.obuInfo.version == '49') { const updateEsDat = await this.updateEs('GEN_OBEIC_UPG', applyData); if (!updateEsDat) return false; } if (this.data.cardInfo.version == '48' || this.data.cardInfo.version == '49') { const updateEsDatTwo = await this.updateEs('GEN_OBESAM_UPG', applyData); if (!updateEsDatTwo) return false; } const upgradeDoneData = await API.ETC.vfjUpgradeDone({ issueSerialNo: applyData.issueSerialNo, //发行订单号 }); if (!upgradeDoneData || (upgradeDoneData && upgradeDoneData.code !== 200)) return false; // 升级完成后完成后重新写入 const cardres = await this.getCardIdAfter(); if(!cardres || (cardres && cardres.code !== 200)) return; const obures = await this.getObuIdAfter(); if(!obures || (obures && obures.code !== 200)) return; wx.showModal({ title: '提示', content: '设备升级完成', showCancel: false, complete: (res) => { if (res.confirm) { wx.navigateBack() } } }) } else { DisConnectDevice() wx.showModal({ title: '提示', content: "设备版本暂时不需要升级", showCancel: false, success: () => { wx.navigateBack() } }) } }, // 获取发行指令脚本 async updateEs (type, applyData) { wx.showLoading({ title: '设备升级中' }) let getCommanData = await API.ETC.getVfjGetCommands({ cardNo: applyData.cardNo, //卡片序列号 wareId: type, //OBU的物料代码 OBE-SAM通道 GEN_OBESAM_UPG OBE-IC通道 GEN_OBEIC_UPG issueSerialNo: applyData.issueSerialNo, //发行订单号 }) if (!getCommanData || (getCommanData && getCommanData.code !== 200)) return false; //指令解析 const result = getCommanData.commands; const array = result.split('~'); let cmdType = type == 'GEN_OBESAM_UPG' ? '20' : '10'; for (const element of array) { console.log('updateEs', element, cmdType); // 让出主线程,确保UI更新 await new Promise(resolve => setTimeout(resolve, 0)); console.log("进来了", element.charAt(0), ) if (element.charAt(0) === 'D' || element.charAt(0) === 'R') { await this.processDirectCommand(element, cmdType); } else if (element.charAt(0) === 'K') { await this.processKeyExchange(element, cmdType, applyData); } else if (element.charAt(0) === 'E') { await this.processExtAuth(element, cmdType, applyData); } else if (element === 'SESAM') { cmdType = '20'; } else { cmdType = '10'; } } return true; }, processDirectCommand(element, cmdType) { // 添加随机延迟,避免连续请求 return transCmdArrAfter(element.substring(1), cmdType); }, async processKeyExchange(element, cmdType, applyData) { const ranData = await transCmdArrAfter('0084000004', cmdType); console.log("ranData", ranData) const exchangeKeyData = API.ETC.vfjExchangeKey({ key: element.substring(1), random: ranData['0084000004'][0].substring(0, 8), issueSerialNo: applyData.issueSerialNo }); if (!exchangeKeyData) throw new Error('密钥置换失败'); console.log("exchangeKeyData", exchangeKeyData) return transCmdArrAfter(exchangeKeyData.apdu, cmdType); }, async processExtAuth(element, cmdType, applyData) { const ranData = await transCmdArrAfter('0084000004', cmdType); const extAuth4IssData = API.ETC.vfjExtAuth4Iss({ keyType: element.substring(1), random: ranData['0084000004'][0].substring(0, 8), issueSerialNo: applyData.issueSerialNo, }); console.log("extAuth4IssData", extAuth4IssData) if (!extAuth4IssData) throw new Error('外部认证失败'); return transCmdArrAfter(extAuth4IssData.apdu, cmdType); }, // 获取设备升级指令 apply4Upgrade(params) { return API.ETC.getVfjApply4Upgrade(params) }, // 读卡 async getCardIdAfter () { return new Promise(async (resolve, reject) =>{ try{ let cmdArr = [HOME_DIRECTORY, APPLICATION_DIRECTORY, CMD_READBINARY, CMD_GETBALANCE]; const res = await transCmdAfter(cmdArr, "10"); let cmdResult = res.cmdResult ? res.cmdResult.split(',') : [] let str = cmdResult[2].substring(cmdResult[2].length - 4, cmdResult[2].length); //判断是否为9000 let str3 = cmdResult[3].substring(cmdResult[3].length - 4, cmdResult[3].length); //判断是否为9000 if (str == "9000" || str3 == "9000") { if (cmdResult[2].length > 86 || cmdResult[3] >= 12) { card.cardId = cmdResult[2].substring(20, 40); // card.cardId = '52012511110201724155'; this.data.cardInfo.version = cmdResult[2].substring(18, 20), console.log(9999999) console.log(this.data.cardInfo) wx.hideLoading() resolve(true); return } else { console.log("CMD_READBINARY指令长度不符" + cmdResult[2]); this.showModals("CMD_READBINARY指令长度不符" + cmdResult[2]) resolve(false); return } } console.log("CMD_READBINARY指令长度不符" + cmdResult[2]); this.showModals("CMD_READBINARY指令长度不符" + cmdResult[2]) resolve(false); return } catch (e) { //TODO handle the exception console.log('错误错误', e); reject(e); } }) }, // 读取签 getObuIdAfter(){ return new Promise(async (resolve, reject) =>{ try{ let cmdArray = [HOME_DIRECTORY, OBU_SYSTEM_FILE, RANDOM_NUMBER]; const res = await transCmdAfter(cmdArray, "20"); let cmdResult = res.cmdResult ? res.cmdResult.split(',') : [] var status = cmdResult[1].substring(cmdResult[1].length - 4, cmdResult[1].length); console.log('获取OBU号执行结果' + status, cmdResult) //第一次获取随机数 if (status == "9000") { this.data.obuInfo.obuId = cmdResult[1].substring(20, 36); this.data.obuInfo.version = cmdResult[1].substring(18, 20); this.data.obuInfo.chipSn = cmdResult[1].substring(0, 8) resolve(true); console.log("success") return } else { this.showModals('获取设备信息错误!') resolve(false); return } } catch (e) { //TODO handle the exception console.log('错误错误', e); reject(e); } }) }, showModals (content) { wx.showModal({ title: '提示', content: content, showCancel: false }) }, /// 配置导航栏标题 configNavTitle(title = "设备搜索") { wx.setNavigationBarTitle({ title: title, }) }, // 参数缺失处理 paramsMiss (content) { wx.showModal({ title: '参数缺失', content: content, showCancel: false, success: () => { wx.navigateBack() } }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { } })