chann.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package proto
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "strconv"
  6. "github.com/pion/stun"
  7. )
  8. // ChannelNumber represents CHANNEL-NUMBER attribute.
  9. //
  10. // The CHANNEL-NUMBER attribute contains the number of the channel.
  11. //
  12. // RFC 5766 Section 14.1
  13. type ChannelNumber uint16 // encoded as uint16
  14. func (n ChannelNumber) String() string { return strconv.Itoa(int(n)) }
  15. // 16 bits of uint + 16 bits of RFFU = 0.
  16. const channelNumberSize = 4
  17. // AddTo adds CHANNEL-NUMBER to message.
  18. func (n ChannelNumber) AddTo(m *stun.Message) error {
  19. v := make([]byte, channelNumberSize)
  20. binary.BigEndian.PutUint16(v[:2], uint16(n))
  21. // v[2:4] are zeroes (RFFU = 0)
  22. m.Add(stun.AttrChannelNumber, v)
  23. return nil
  24. }
  25. // GetFrom decodes CHANNEL-NUMBER from message.
  26. func (n *ChannelNumber) GetFrom(m *stun.Message) error {
  27. v, err := m.Get(stun.AttrChannelNumber)
  28. if err != nil {
  29. return err
  30. }
  31. if err = stun.CheckSize(stun.AttrChannelNumber, len(v), channelNumberSize); err != nil {
  32. return err
  33. }
  34. _ = v[channelNumberSize-1] // asserting length
  35. *n = ChannelNumber(binary.BigEndian.Uint16(v[:2]))
  36. // v[2:4] is RFFU and equals to 0.
  37. return nil
  38. }
  39. // See https://tools.ietf.org/html/rfc5766#section-11:
  40. //
  41. // 0x4000 through 0x7FFF: These values are the allowed channel
  42. // numbers (16,383 possible values).
  43. const (
  44. MinChannelNumber = 0x4000
  45. MaxChannelNumber = 0x7FFF
  46. )
  47. // ErrInvalidChannelNumber means that channel number is not valid as by RFC 5766 Section 11.
  48. var ErrInvalidChannelNumber = errors.New("channel number not in [0x4000, 0x7FFF]")
  49. // isChannelNumberValid returns true if c in [0x4000, 0x7FFF].
  50. func isChannelNumberValid(c uint16) bool {
  51. return c >= MinChannelNumber && c <= MaxChannelNumber
  52. }
  53. // Valid returns true if channel number has correct value that complies RFC 5766 Section 11 range.
  54. func (n ChannelNumber) Valid() bool {
  55. return isChannelNumberValid(uint16(n))
  56. }