//升级模块 // 秒寻科技 // zt 2024-11-11 package upgrade import ( "bytes" "encoding/binary" "ipsomc/module/ps/psdl" "ipsomc/module/ps/psmodel" "ipsomc/module/ps/pspublic" "ipsomc/module/uploadfile/uploadfilemodel" "ipsomc/public" ) var ( Gupgrade_stManageParam OAM_UPGRADE_T //升级管理模块 Gupgrade_abyFileData []byte //升级文件 ) // 升级 type Upgrade struct { psDlApi psdl.PsDl } // 升级管理结构 type OAM_UPGRADE_T struct { UpgradeStatus uint8 `json:"upgrade_status"` //1:升级中,2:升级成功,3:升级失败,4:超时 FileSize uint32 `json:"file_size"` //升级文件大小 TotalTimes uint32 `json:"total_times"` //发送总次数 SendingTimes uint32 `json:"sending_times"` //当前发送次数 RemainderLen uint32 `json:"remainder_len"` //最后一次数据长度 } // 远程升级,接收文件 func (obj *Upgrade) UpgradeReceiveFile(dataModel *uploadfilemodel.UploadFileParam, dataList []byte, dwLen uint32) error { fileSize := dwLen //文件长度 //4字节对齐 remainderLen := fileSize % 4 //余数 if remainderLen > 0 { fileSize = fileSize + 4 - remainderLen } Gupgrade_stManageParam.FileSize = fileSize //文件字节数 //保存文件数据 Gupgrade_abyFileData = make([]byte, fileSize) copy(Gupgrade_abyFileData, dataList) //组织升级管理结构 totalTimes := fileSize / psmodel.PS_MCP_B_DATA_LEN remainderLen = fileSize % psmodel.PS_MCP_B_DATA_LEN if remainderLen > 0 { Gupgrade_stManageParam.TotalTimes = totalTimes + 1 Gupgrade_stManageParam.RemainderLen = remainderLen } else { Gupgrade_stManageParam.TotalTimes = totalTimes Gupgrade_stManageParam.RemainderLen = psmodel.PS_MCP_B_DATA_LEN } //切换工作模式 if err := obj.UpgradeSwitchSoftMode(dataModel, 1); err != nil { return err } return nil } // 组织设置LTV数据结构 func (obj *Upgrade) UpgradeOrganizeLtv(wLen uint16, wCmd uint16, value []byte, dataList *bytes.Buffer) { dataLen := wLen - 4 tmpSlice := make([]byte, dataLen) //定义该命令所需的数据切片 copy(tmpSlice, value) binary.Write(dataList, binary.LittleEndian, wLen) //长度 binary.Write(dataList, binary.LittleEndian, wCmd) //命令 binary.Write(dataList, binary.LittleEndian, tmpSlice) //数据 } // 切换升级模式 // dataModel:升级文件参数 // upgradeStatus:升级状态 func (obj *Upgrade) UpgradeSwitchSoftMode(dataModel *uploadfilemodel.UploadFileParam, upgradeStatus uint8) error { var dataList bytes.Buffer tmpBytes := make([]byte, 1) //组织参数 tmpBytes = append(tmpBytes, upgradeStatus) obj.UpgradeOrganizeLtv(5, uint16(pspublic.OAM_UPGRADE_SWITCH_SOFT_WORK_MODE), tmpBytes, &dataList) //切换软件模式 //发送数据给基站 if err := obj.psDlApi.PsDlSendOamDataToBts(int(dataModel.ProjectID), dataModel.BtsID, psmodel.MCP_B, psmodel.MCP_B_CONTROL, dataList.Bytes()); err != nil { obj.UpgradeDeinit() return err } Gupgrade_stManageParam.UpgradeStatus = 1 //升级中 Gupgrade_stManageParam.SendingTimes = 0 //发送次数复位 return nil } // 通知升级文件大小 // ProjectID:项目编号 // BtsID:基站编号 func (obj *Upgrade) UpgradeNoticeFileSize(ProjectID int, BtsID int) error { var dataList bytes.Buffer tmpBytes := make([]byte, 4) ////组织参数 binary.LittleEndian.PutUint32(tmpBytes, Gupgrade_stManageParam.FileSize) obj.UpgradeOrganizeLtv(8, uint16(pspublic.OAM_UPGRADE_NOTICE_FILE_SIZE_), tmpBytes, &dataList) //发送数据给基站 if err := obj.psDlApi.PsDlSendOamDataToBts(ProjectID, BtsID, psmodel.MCP_B, psmodel.MCP_B_CONTROL, dataList.Bytes()); err != nil { obj.UpgradeDeinit() return err } return nil } // 传输升级文件 // ProjectID:项目编号 // BtsID:基站编号 func (obj *Upgrade) UpgradeTransferFile(ProjectID int, BtsID int) error { var payloadLen uint32 = psmodel.PS_MCP_B_DATA_LEN //载荷长度 var dwStartIndex uint32 = 0 var dwStopIndex uint32 = 0 var dataList bytes.Buffer var dwLen uint32 = 0 var stUpgradeStatus public.PublicUpgradeStatus //升级状态管理结构 if Gupgrade_stManageParam.SendingTimes < Gupgrade_stManageParam.TotalTimes { if Gupgrade_stManageParam.SendingTimes == (Gupgrade_stManageParam.TotalTimes - 1) { payloadLen = Gupgrade_stManageParam.RemainderLen } payload := make([]byte, payloadLen) //载荷数据空间 //组织数据 dwStartIndex = Gupgrade_stManageParam.SendingTimes * psmodel.PS_MCP_B_DATA_LEN dwStopIndex = dwStartIndex + payloadLen copy(payload, Gupgrade_abyFileData[dwStartIndex:dwStopIndex]) Gupgrade_stManageParam.SendingTimes++ //组织ltv数据 dwLen = 8 + payloadLen binary.Write(&dataList, binary.LittleEndian, uint16(dwLen)) //长度 binary.Write(&dataList, binary.LittleEndian, uint16(pspublic.OAM_UPGRADE_SEND_UPGRADE_FILE)) //命令 binary.Write(&dataList, binary.LittleEndian, Gupgrade_stManageParam.SendingTimes) //帧号 binary.Write(&dataList, binary.LittleEndian, payload) //数据 //发送数据给基站 if err := obj.psDlApi.PsDlSendOamDataToBts(ProjectID, BtsID, psmodel.MCP_B, psmodel.MCP_B_FILE_TRANSFER, dataList.Bytes()); err != nil { obj.UpgradeDeinit() //反向初始化 stUpgradeStatus.Flag = 1 //失败 stUpgradeStatus.Percent = 0 public.Gpub_chanWebSocketMsg <- stUpgradeStatus //通过通道发送数据到http模块 return err } stUpgradeStatus.Flag = 2 //成功 stUpgradeStatus.Percent = uint8((Gupgrade_stManageParam.SendingTimes * 100) / Gupgrade_stManageParam.TotalTimes) public.Gpub_chanWebSocketMsg <- stUpgradeStatus //通过通道发送数据到http模块 } else { //通知升级结束 if err := obj.UpgradeNoticeOver(ProjectID, BtsID); err != nil { obj.UpgradeDeinit() //反向初始化 stUpgradeStatus.Flag = 1 //失败 stUpgradeStatus.Percent = 0 public.Gpub_chanWebSocketMsg <- stUpgradeStatus //通过通道发送数据到http模块 return err } obj.UpgradeDeinit() //反向初始化 } return nil } // 通知升级结束 // ProjectID:项目编号 // BtsID:基站编号 func (obj *Upgrade) UpgradeNoticeOver(ProjectID int, BtsID int) error { var dataList bytes.Buffer tmpBytes := make([]byte, 4) ////组织参数 binary.LittleEndian.PutUint32(tmpBytes, Gupgrade_stManageParam.FileSize) obj.UpgradeOrganizeLtv(8, uint16(pspublic.OAM_UPGRADE_NOTICE_UPGRADE_OVER), tmpBytes, &dataList) //发送数据给基站 if err := obj.psDlApi.PsDlSendOamDataToBts(ProjectID, BtsID, psmodel.MCP_B, psmodel.MCP_B_CONTROL, dataList.Bytes()); err != nil { obj.UpgradeDeinit() //反向初始化 return err } obj.UpgradeDeinit() //反向初始化 return nil } // 升级成功 func (obj *Upgrade) UpgradeSuccess() { obj.UpgradeDeinit() //反向初始化 } // 升级模块反向初始化 func (obj *Upgrade) UpgradeDeinit() { Gupgrade_stManageParam = OAM_UPGRADE_T{} }