You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
3.6 KiB

  1. package lifx
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "git.aiterp.net/lucifer/new-server/internal/lerrors"
  6. "log"
  7. "net"
  8. )
  9. func createPacket() Packet {
  10. p := make(Packet, 36)
  11. p.Reset()
  12. return p
  13. }
  14. type Packet []byte
  15. func (p *Packet) Reset() {
  16. p.ensureHeader()
  17. copy(*p, blankHeader)
  18. }
  19. func (p *Packet) Size() int {
  20. return int(binary.LittleEndian.Uint16((*p)[0:2]))
  21. }
  22. func (p *Packet) Protocol() int {
  23. return int(binary.LittleEndian.Uint16((*p)[2:3]) & 0b00001111_11111111)
  24. }
  25. func (p *Packet) SetTagged(v bool) {
  26. if v {
  27. (*p)[3] |= uint8(0b00100000)
  28. } else {
  29. (*p)[3] &= ^uint8(0b00100000)
  30. }
  31. }
  32. func (p *Packet) Source() uint32 {
  33. return binary.LittleEndian.Uint32((*p)[4:8])
  34. }
  35. func (p *Packet) Target() net.HardwareAddr {
  36. return net.HardwareAddr((*p)[8:14])
  37. }
  38. func (p *Packet) SetSource(v uint32) {
  39. binary.LittleEndian.PutUint32((*p)[4:8], v)
  40. }
  41. func (p *Packet) CopyTargetFrom(other Packet) {
  42. copy((*p)[8:14], other[8:14])
  43. }
  44. func (p *Packet) SetTarget(v string) error {
  45. addr, err := net.ParseMAC(v)
  46. if err != nil {
  47. return err
  48. }
  49. if len(addr) != 6 {
  50. return lerrors.ErrInvalidAddress
  51. }
  52. copy((*p)[8:], addr)
  53. return nil
  54. }
  55. func (p *Packet) SetResRequired(v bool) {
  56. if v {
  57. (*p)[22] |= uint8(0b00000001)
  58. } else {
  59. (*p)[22] &= ^uint8(0b00000001)
  60. }
  61. }
  62. func (p *Packet) SetAckRequired(v bool) {
  63. if v {
  64. (*p)[22] |= uint8(0b00000010)
  65. } else {
  66. (*p)[22] &= ^uint8(0b00000010)
  67. }
  68. }
  69. func (p *Packet) Sequence() uint8 {
  70. return (*p)[23]
  71. }
  72. func (p *Packet) SetSequence(v uint8) {
  73. (*p)[23] = v
  74. }
  75. func (p *Packet) PacketType() uint16 {
  76. return binary.LittleEndian.Uint16((*p)[32:34])
  77. }
  78. func (p *Packet) SetRawPayload(packetType uint16, data []byte) {
  79. p.ensureSize(36 + len(data))
  80. copy((*p)[36:], data)
  81. binary.LittleEndian.PutUint16(*p, uint16(36+len(data)))
  82. binary.LittleEndian.PutUint16((*p)[32:34], packetType)
  83. }
  84. func (p *Packet) Payload() (res Payload, err error) {
  85. switch p.PacketType() {
  86. case 2:
  87. res = &GetService{}
  88. case 3:
  89. res = &StateService{}
  90. err = res.Decode((*p)[36:])
  91. case 14:
  92. res = &GetHostFirmware{}
  93. case 15:
  94. res = &StateHostFirmware{}
  95. err = res.Decode((*p)[36:])
  96. case 32:
  97. res = &GetVersion{}
  98. case 33:
  99. res = &StateVersion{}
  100. err = res.Decode((*p)[36:])
  101. case 45:
  102. res = &Acknowledgement{}
  103. case 101:
  104. res = &GetColor{}
  105. case 102:
  106. res = &SetColor{}
  107. err = res.Decode((*p)[36:])
  108. case 107:
  109. res = &LightState{}
  110. err = res.Decode((*p)[36:])
  111. case 117:
  112. res = &SetLightPower{}
  113. err = res.Decode((*p)[36:])
  114. default:
  115. err = lerrors.ErrUnrecognizedPacketType
  116. }
  117. if err != nil {
  118. res = nil
  119. }
  120. if res != nil && res.PacketType() != p.PacketType() {
  121. log.Println("BUG Incorrect packet type used in Packet.Payload")
  122. log.Println("BUG Payload Type:", p.PacketType())
  123. log.Println("BUG Panic Packet Type:", res.PacketType())
  124. log.Println("BUG Panic Payload:", res.String())
  125. }
  126. return
  127. }
  128. func (p *Packet) SetPayload(payload Payload) {
  129. ackRequired, resRequired := payload.Flags()
  130. p.SetRawPayload(payload.PacketType(), payload.Encode())
  131. p.SetAckRequired(ackRequired)
  132. p.SetResRequired(resRequired)
  133. }
  134. func (p *Packet) ensureHeader() {
  135. p.ensureSize(36)
  136. }
  137. func (p *Packet) ensureSize(size int) {
  138. if len(*p) < size {
  139. newData := make([]byte, size)
  140. copy(newData, *p)
  141. *p = newData
  142. }
  143. }
  144. type Payload interface {
  145. fmt.Stringer
  146. Decode(data []byte) error
  147. Encode() []byte
  148. PacketType() uint16
  149. Flags() (ackRequired bool, resRequired bool)
  150. }
  151. var blankHeader = []byte{
  152. 0x24, 0x00, 0x00, 0x14,
  153. 0x00, 0x00, 0x00, 0x00,
  154. 0x00, 0x00, 0x00, 0x00,
  155. 0x00, 0x00, 0x00, 0x00,
  156. 0x00, 0x00, 0x00, 0x00,
  157. 0x00, 0x00, 0x00, 0x00,
  158. 0x00, 0x00, 0x00, 0x00,
  159. 0x00, 0x00, 0x00, 0x00,
  160. 0x00, 0x00, 0x00, 0x00,
  161. }