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.

87 lines
2.1 KiB

  1. package packet
  2. // Length of the fixed header of the UNSUBACK Packet
  3. const lenUNSUBACKFixedHeader = 2
  4. // Length of the variable header of the UNSUBACK Packet
  5. const lenUNSUBACKVariableHeader = 2
  6. // UNSUBACK represents an UNSUBACK Packet.
  7. type UNSUBACK struct {
  8. base
  9. // PacketID is the Packet Identifier of the variable header.
  10. PacketID uint16
  11. }
  12. // NewUNSUBACKFromBytes creates an UNSUBACK Packet
  13. // from the byte data and returns it.
  14. func NewUNSUBACKFromBytes(fixedHeader FixedHeader, variableHeader []byte) (Packet, error) {
  15. // Validate the byte data.
  16. if err := validateUNSUBACKBytes(fixedHeader, variableHeader); err != nil {
  17. return nil, err
  18. }
  19. // Decode the Packet Identifier.
  20. // No error occur because of the precedent validation and
  21. // the returned error is not be taken care of.
  22. packetID, _ := decodeUint16(variableHeader)
  23. // Create a PUBACK Packet.
  24. p := &UNSUBACK{
  25. PacketID: packetID,
  26. }
  27. // Set the fixed header to the Packet.
  28. p.fixedHeader = fixedHeader
  29. // Set the variable header to the Packet.
  30. p.variableHeader = variableHeader
  31. // Return the Packet.
  32. return p, nil
  33. }
  34. // validateUNSUBACKBytes validates the fixed header and the variable header.
  35. func validateUNSUBACKBytes(fixedHeader FixedHeader, variableHeader []byte) error {
  36. // Extract the MQTT Control Packet type.
  37. ptype, err := fixedHeader.ptype()
  38. if err != nil {
  39. return err
  40. }
  41. // Check the length of the fixed header.
  42. if len(fixedHeader) != lenUNSUBACKFixedHeader {
  43. return ErrInvalidFixedHeaderLen
  44. }
  45. // Check the MQTT Control Packet type.
  46. if ptype != TypeUNSUBACK {
  47. return ErrInvalidPacketType
  48. }
  49. // Check the reserved bits of the fixed header.
  50. if fixedHeader[0]<<4 != 0x00 {
  51. return ErrInvalidFixedHeader
  52. }
  53. // Check the Remaining Length of the fixed header.
  54. if fixedHeader[1] != lenUNSUBACKVariableHeader {
  55. return ErrInvalidRemainingLength
  56. }
  57. // Check the length of the variable header.
  58. if len(variableHeader) != lenUNSUBACKVariableHeader {
  59. return ErrInvalidVariableHeaderLen
  60. }
  61. // Extract the Packet Identifier.
  62. packetID, _ := decodeUint16(variableHeader)
  63. // Check the Packet Identifier.
  64. if packetID == 0 {
  65. return ErrInvalidPacketID
  66. }
  67. return nil
  68. }