123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- 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),
- }
- }
|