BxCmdFileWrite.go 6.2 KB

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