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.

129 lines
3.1 KiB

  1. package packet
  2. // Length of the fixed header of the PUBREC Packet
  3. const lenPUBRECFixedHeader = 2
  4. // Length of the variable header of the PUBREC Packet
  5. const lenPUBRECVariableHeader = 2
  6. // PUBREC represents a PUBREC Packet.
  7. type PUBREC struct {
  8. base
  9. // PacketID is the Packet Identifier of the variable header.
  10. PacketID uint16
  11. }
  12. // setFixedHeader sets the fixed header to the Packet.
  13. func (p *PUBREC) setFixedHeader() {
  14. // Append the first byte to the fixed header.
  15. p.fixedHeader = append(p.fixedHeader, TypePUBREC<<4)
  16. // Append the Remaining Length to the fixed header.
  17. p.appendRemainingLength()
  18. }
  19. // setVariableHeader sets the variable header to the Packet.
  20. func (p *PUBREC) setVariableHeader() {
  21. // Append the Packet Identifier to the variable header.
  22. p.variableHeader = append(p.variableHeader, encodeUint16(p.PacketID)...)
  23. }
  24. // NewPUBREC creates and returns a PUBACK Packet.
  25. func NewPUBREC(opts *PUBRECOptions) (Packet, error) {
  26. // Initialize the options.
  27. if opts == nil {
  28. opts = &PUBRECOptions{}
  29. }
  30. // Validate the options.
  31. if err := opts.validate(); err != nil {
  32. return nil, err
  33. }
  34. // Create a PUBREC Packet.
  35. p := &PUBREC{
  36. PacketID: opts.PacketID,
  37. }
  38. // Set the variable header to the Packet.
  39. p.setVariableHeader()
  40. // Set the Fixed header to the Packet.
  41. p.setFixedHeader()
  42. // Return the Packet.
  43. return p, nil
  44. }
  45. // NewPUBRECFromBytes creates a PUBREC Packet
  46. // from the byte data and returns it.
  47. func NewPUBRECFromBytes(fixedHeader FixedHeader, variableHeader []byte) (Packet, error) {
  48. // Validate the byte data.
  49. if err := validatePUBRECBytes(fixedHeader, variableHeader); err != nil {
  50. return nil, err
  51. }
  52. // Decode the Packet Identifier.
  53. // No error occur because of the precedent validation and
  54. // the returned error is not be taken care of.
  55. packetID, _ := decodeUint16(variableHeader)
  56. // Create a PUBREC Packet.
  57. p := &PUBREC{
  58. PacketID: packetID,
  59. }
  60. // Set the fixed header to the Packet.
  61. p.fixedHeader = fixedHeader
  62. // Set the variable header to the Packet.
  63. p.variableHeader = variableHeader
  64. // Return the Packet.
  65. return p, nil
  66. }
  67. // validatePUBRECBytes validates the fixed header and the variable header.
  68. func validatePUBRECBytes(fixedHeader FixedHeader, variableHeader []byte) error {
  69. // Extract the MQTT Control Packet type.
  70. ptype, err := fixedHeader.ptype()
  71. if err != nil {
  72. return err
  73. }
  74. // Check the length of the fixed header.
  75. if len(fixedHeader) != lenPUBRECFixedHeader {
  76. return ErrInvalidFixedHeaderLen
  77. }
  78. // Check the MQTT Control Packet type.
  79. if ptype != TypePUBREC {
  80. return ErrInvalidPacketType
  81. }
  82. // Check the reserved bits of the fixed header.
  83. if fixedHeader[0]<<4 != 0x00 {
  84. return ErrInvalidFixedHeader
  85. }
  86. // Check the Remaining Length of the fixed header.
  87. if fixedHeader[1] != lenPUBRECVariableHeader {
  88. return ErrInvalidRemainingLength
  89. }
  90. // Check the length of the variable header.
  91. if len(variableHeader) != lenPUBRECVariableHeader {
  92. return ErrInvalidVariableHeaderLen
  93. }
  94. // Extract the Packet Identifier.
  95. packetID, _ := decodeUint16(variableHeader)
  96. // Check the Packet Identifier.
  97. if packetID == 0 {
  98. return ErrInvalidPacketID
  99. }
  100. return nil
  101. }