BxCmdFileWrite.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package bx
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "github.com/sirupsen/logrus"
  6. "time"
  7. )
  8. // 普通文本文件
  9. type bxFile struct {
  10. type_ byte //默认0x00
  11. name string //4字节ASCII
  12. len uint32
  13. content string
  14. Priority byte
  15. DisplayType uint16 //播放方式节目播放方式,0——顺序播放,其他——定长播放的 时间,单位为秒
  16. PlayTimes byte
  17. //节目生命周期,发送顺序为:起始年(2)+起始月(1)+起
  18. //始日(1)+结束年(2)+结束月(1)+结束日(1)注:1. 时间均
  19. //采用 BCD 码的方式2. 年范围为 0x1900—0x2099,
  20. //0xffff 为永久有效,先发送 LSB,后发送 MSB
  21. ProgramLife string
  22. //节目的星期属性
  23. //1. Bit0 为 1 表示一周中的每一天都播放。
  24. //2. Bit0 为 0 时,需判断 bit1-bit7 的来决定每天播放,
  25. //bit1-bit7依次表示周一到周日。
  26. //3.比特为0表示禁止播放,为 1 表示播放。
  27. ProgramWeek byte
  28. //定时节目位 0 非定时,注:为 0 时则播放时段组数设 置为 0
  29. ProgramTime byte
  30. //节目播放时段组数,最多支持一组,当为 0 时 PlayPeriodSetting
  31. PlayPeriodGrpNum byte
  32. //6Byte 播放组0,发送顺序为:起始小时(1)+起始分钟(1)+起始秒(1)+结束小时(1)+结束分钟(1)+结束秒(1)
  33. //PlayPeriodSetting0 time.Time
  34. Areas []BxArea
  35. }
  36. // NewBxFile diedLine 节目过期时间 "2006-01-02", 传"" 永不过期
  37. func NewBxFile(fileName string, diedLine string, areas []BxArea) bxFile {
  38. return bxFile{
  39. name: fileName,
  40. Areas: areas,
  41. ProgramLife: diedLine,
  42. Priority: 0xff,
  43. PlayTimes: 1,
  44. ProgramWeek: 1,
  45. }
  46. }
  47. func (f bxFile) NewCmdWriteFile() *CmdWriteFile {
  48. return &CmdWriteFile{
  49. baseBxCmd: newBaseCmd(CMD_WRITE_FILE.group, CMD_WRITE_FILE.code),
  50. file: &f,
  51. LastBlockFlag: 1,
  52. }
  53. }
  54. func (f bxFile) encodeProgramLife() []byte {
  55. if f.ProgramLife == "" {
  56. return []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
  57. }
  58. w := bufPoll.Get().(*bytes.Buffer)
  59. now := time.Now()
  60. y := Uint2BCD(uint64(now.Year()), false)
  61. m := Uint2BCD(uint64(now.Month()), false)
  62. d := Uint2BCD(uint64(now.Day()), false)
  63. binary.Write(w, binary.BigEndian, y)
  64. binary.Write(w, binary.BigEndian, m)
  65. binary.Write(w, binary.BigEndian, d)
  66. end, err := time.Parse("2006-01-02", f.ProgramLife)
  67. if err != nil {
  68. logrus.Error("时间解析错误:", err)
  69. return nil
  70. }
  71. endY := Uint2BCD(uint64(end.Year()), false)
  72. endM := Uint2BCD(uint64(end.Month()), false)
  73. endD := Uint2BCD(uint64(end.Day()), false)
  74. binary.Write(w, binary.BigEndian, endY)
  75. binary.Write(w, binary.BigEndian, endM)
  76. binary.Write(w, binary.BigEndian, endD)
  77. return w.Bytes()
  78. }
  79. //func (f bxFile) Build() []byte {
  80. // w := bytes.NewBuffer(make([]byte, 0, 1024))
  81. // return w.Bytes()
  82. //}
  83. type CmdWriteFile struct {
  84. baseBxCmd
  85. state byte
  86. file *bxFile
  87. LastBlockFlag byte
  88. BlockNum uint16 //包号,如果是单包发送,则默认为 0x00。
  89. BlockLen uint16 //包长,若是单包发送,此处为文件长度。
  90. BlockAddr uint32 //本包数据在文件中的起始位置,如果是单包发送,此处默认为 0。
  91. temp []byte
  92. }
  93. func (cmd *CmdWriteFile) Build() []byte {
  94. if cmd.state == 0 {
  95. //先计算区域数据及长度
  96. w0 := bytes.NewBuffer(make([]byte, 0, 1024))
  97. for _, v := range cmd.file.Areas {
  98. b := v.Build()
  99. binary.Write(w0, binary.LittleEndian, uint32(len(b))+4)
  100. binary.Write(w0, binary.LittleEndian, b)
  101. }
  102. l := w0.Len() + 27
  103. cmd.BlockLen = uint16(l)
  104. cmd.file.len = uint32(l)
  105. //Write File
  106. w1 := bytes.NewBuffer(make([]byte, 0, 1024))
  107. //文件描述数据
  108. binary.Write(w1, binary.LittleEndian, cmd.Group())
  109. binary.Write(w1, binary.LittleEndian, cmd.Cmd())
  110. binary.Write(w1, binary.LittleEndian, byte(0x01))
  111. binary.Write(w1, binary.LittleEndian, []byte{0x00, 0x00})
  112. binary.Write(w1, binary.BigEndian, []byte(cmd.file.name))
  113. binary.Write(w1, binary.LittleEndian, cmd.LastBlockFlag) //是否是最后一包,0x00——不是最后一包 0x01——最后一包。
  114. binary.Write(w1, binary.LittleEndian, cmd.BlockNum) //包号,单包为0x00
  115. binary.Write(w1, binary.LittleEndian, cmd.BlockLen) //包长,若是单包发送,此处为文件长度。
  116. binary.Write(w1, binary.LittleEndian, cmd.BlockAddr) //本包数据在文件中的偏移量,单包为0x00
  117. //文件内容数据
  118. w2 := bytes.NewBuffer(make([]byte, 0, 1024))
  119. binary.Write(w2, binary.LittleEndian, cmd.file.type_)
  120. binary.Write(w2, binary.BigEndian, []byte(cmd.file.name))
  121. binary.Write(w2, binary.LittleEndian, cmd.file.len)
  122. binary.Write(w2, binary.LittleEndian, cmd.file.Priority)
  123. binary.Write(w2, binary.LittleEndian, cmd.file.DisplayType)
  124. binary.Write(w2, binary.LittleEndian, cmd.file.PlayTimes)
  125. binary.Write(w2, binary.BigEndian, cmd.file.encodeProgramLife())
  126. binary.Write(w2, binary.LittleEndian, cmd.file.ProgramWeek)
  127. binary.Write(w2, binary.LittleEndian, cmd.file.ProgramTime)
  128. binary.Write(w2, binary.LittleEndian, cmd.file.PlayPeriodGrpNum)
  129. //binary.Write(w, binary.LittleEndian, cmd.file.PlayPeriodSetting0)
  130. binary.Write(w2, binary.LittleEndian, byte(len(cmd.file.Areas)))
  131. binary.Write(w2, binary.LittleEndian, w0.Bytes())
  132. b2 := w2.Bytes()
  133. binary.Write(w1, binary.BigEndian, b2)
  134. crc16 := CRC16(b2, 0, w2.Len())
  135. binary.Write(w1, binary.LittleEndian, crc16)
  136. cmd.temp = w1.Bytes()
  137. //Start Write File "开始写文件",写文件前先检查内存是否够用
  138. w3 := bytes.NewBuffer(make([]byte, 0, 64))
  139. binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.group)
  140. binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.code)
  141. binary.Write(w3, binary.LittleEndian, byte(0x01))
  142. binary.Write(w3, binary.LittleEndian, []byte{0x00, 0x00})
  143. binary.Write(w3, binary.LittleEndian, byte(0x01)) //同名是否覆盖,0不覆盖,1覆盖
  144. binary.Write(w3, binary.BigEndian, []byte(cmd.file.name))
  145. binary.Write(w3, binary.LittleEndian, cmd.file.len)
  146. cmd.state = 1
  147. return w3.Bytes()
  148. } else {
  149. return cmd.temp
  150. }
  151. }
  152. type cmdFileBeginWrite struct {
  153. baseBxCmd
  154. }
  155. func NewCmdFileBeginWrite() cmdFileBeginWrite {
  156. return cmdFileBeginWrite{
  157. baseBxCmd: newBaseCmd(CMD_START_WRITE_FILE.group, CMD_START_WRITE_FILE.code),
  158. }
  159. }