package bx import ( "bytes" "encoding/binary" "fmt" "github.com/sirupsen/logrus" "time" ) // 普通文本文件 type bxFile struct { type_ byte //默认0x00 name string //4字节ASCII len uint32 content string Priority byte DisplayType uint16 //播放方式节目播放方式,0——顺序播放,其他——定长播放的 时间,单位为秒 PlayTimes byte //节目生命周期,发送顺序为:起始年(2)+起始月(1)+起 //始日(1)+结束年(2)+结束月(1)+结束日(1)注:1. 时间均 //采用 BCD 码的方式2. 年范围为 0x1900—0x2099, //0xffff 为永久有效,先发送 LSB,后发送 MSB ProgramLife string //节目的星期属性 //1. Bit0 为 1 表示一周中的每一天都播放。 //2. Bit0 为 0 时,需判断 bit1-bit7 的来决定每天播放, //bit1-bit7依次表示周一到周日。 //3.比特为0表示禁止播放,为 1 表示播放。 ProgramWeek byte //定时节目位 0 非定时,注:为 0 时则播放时段组数设 置为 0 ProgramTime byte //节目播放时段组数,最多支持一组,当为 0 时 PlayPeriodSetting PlayPeriodGrpNum byte //6Byte 播放组0,发送顺序为:起始小时(1)+起始分钟(1)+起始秒(1)+结束小时(1)+结束分钟(1)+结束秒(1) //PlayPeriodSetting0 time.Time Areas []BxArea } // NewBxFile diedLine 节目过期时间 "2006-01-02", 传"" 永不过期 func NewBxFile(fileName string, diedLine string, areas []BxArea) bxFile { return bxFile{ name: fileName, Areas: areas, ProgramLife: diedLine, Priority: 0xff, PlayTimes: 1, ProgramWeek: 1, } } func (f bxFile) NewCmdWriteFile() *CmdWriteFile { return &CmdWriteFile{ baseBxCmd: newBaseCmd(CMD_WRITE_FILE.group, CMD_WRITE_FILE.code), file: &f, LastBlockFlag: 1, } } func (f bxFile) encodeProgramLife() []byte { if f.ProgramLife == "" { return []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} } w := bufPoll.Get().(*bytes.Buffer) now := time.Now() y := Uint2BCD(uint64(now.Year()), false) m := Uint2BCD(uint64(now.Month()), false) d := Uint2BCD(uint64(now.Day()), false) binary.Write(w, binary.BigEndian, y) binary.Write(w, binary.BigEndian, m) binary.Write(w, binary.BigEndian, d) end, err := time.Parse("2006-01-02", f.ProgramLife) if err != nil { logrus.Error("时间解析错误:", err) return nil } endY := Uint2BCD(uint64(end.Year()), false) endM := Uint2BCD(uint64(end.Month()), false) endD := Uint2BCD(uint64(end.Day()), false) binary.Write(w, binary.BigEndian, endY) binary.Write(w, binary.BigEndian, endM) binary.Write(w, binary.BigEndian, endD) return w.Bytes() } //func (f bxFile) Build() []byte { // w := bytes.NewBuffer(make([]byte, 0, 1024)) // return w.Bytes() //} type CmdWriteFile struct { baseBxCmd state byte file *bxFile LastBlockFlag byte BlockNum uint16 //包号,如果是单包发送,则默认为 0x00。 BlockLen uint16 //包长,若是单包发送,此处为文件长度。 BlockAddr uint32 //本包数据在文件中的起始位置,如果是单包发送,此处默认为 0。 temp []byte } func (cmd *CmdWriteFile) Build() []byte { if cmd.state == 0 { //先计算区域数据及长度 w0 := bytes.NewBuffer(make([]byte, 0, 1024)) for _, v := range cmd.file.Areas { b := v.Build() binary.Write(w0, binary.LittleEndian, uint32(len(b))+4) binary.Write(w0, binary.LittleEndian, b) } l := w0.Len() + 27 cmd.BlockLen = uint16(l) cmd.file.len = uint32(l) fmt.Println("传输的长度:", l) //Write File w1 := bytes.NewBuffer(make([]byte, 0, 1024)) //文件描述数据 binary.Write(w1, binary.LittleEndian, cmd.Group()) binary.Write(w1, binary.LittleEndian, cmd.Cmd()) binary.Write(w1, binary.LittleEndian, byte(0x01)) binary.Write(w1, binary.LittleEndian, []byte{0x00, 0x00}) binary.Write(w1, binary.BigEndian, []byte(cmd.file.name)) binary.Write(w1, binary.LittleEndian, cmd.LastBlockFlag) //是否是最后一包,0x00——不是最后一包 0x01——最后一包。 binary.Write(w1, binary.LittleEndian, cmd.BlockNum) //包号,单包为0x00 binary.Write(w1, binary.LittleEndian, cmd.BlockLen) //包长,若是单包发送,此处为文件长度。 binary.Write(w1, binary.LittleEndian, cmd.BlockAddr) //本包数据在文件中的偏移量,单包为0x00 //文件内容数据 w2 := bytes.NewBuffer(make([]byte, 0, 1024)) binary.Write(w2, binary.LittleEndian, cmd.file.type_) binary.Write(w2, binary.BigEndian, []byte(cmd.file.name)) binary.Write(w2, binary.LittleEndian, cmd.file.len) binary.Write(w2, binary.LittleEndian, cmd.file.Priority) binary.Write(w2, binary.LittleEndian, cmd.file.DisplayType) binary.Write(w2, binary.LittleEndian, cmd.file.PlayTimes) binary.Write(w2, binary.BigEndian, cmd.file.encodeProgramLife()) binary.Write(w2, binary.LittleEndian, cmd.file.ProgramWeek) binary.Write(w2, binary.LittleEndian, cmd.file.ProgramTime) binary.Write(w2, binary.LittleEndian, cmd.file.PlayPeriodGrpNum) //binary.Write(w, binary.LittleEndian, cmd.file.PlayPeriodSetting0) binary.Write(w2, binary.LittleEndian, byte(len(cmd.file.Areas))) binary.Write(w2, binary.LittleEndian, w0.Bytes()) b2 := w2.Bytes() binary.Write(w1, binary.BigEndian, b2) crc16 := CRC16(b2, 0, w2.Len()) fmt.Printf("文件校验:% 02x\n", crc16) binary.Write(w1, binary.LittleEndian, crc16) cmd.temp = w1.Bytes() //Start Write File "开始写文件",写文件前先检查内存是否够用 w3 := bytes.NewBuffer(make([]byte, 0, 64)) binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.group) binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.code) binary.Write(w3, binary.LittleEndian, byte(0x01)) binary.Write(w3, binary.LittleEndian, []byte{0x00, 0x00}) binary.Write(w3, binary.LittleEndian, byte(0x01)) //同名是否覆盖,0不覆盖,1覆盖 binary.Write(w3, binary.BigEndian, []byte(cmd.file.name)) binary.Write(w3, binary.LittleEndian, cmd.file.len) cmd.state = 1 return w3.Bytes() } else { return cmd.temp } } type cmdFileBeginWrite struct { baseBxCmd } func NewCmdFileBeginWrite() cmdFileBeginWrite { return cmdFileBeginWrite{ baseBxCmd: newBaseCmd(CMD_START_WRITE_FILE.group, CMD_START_WRITE_FILE.code), } }