message_channel_open.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package datachannel
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. )
  6. /*
  7. channelOpen represents a DATA_CHANNEL_OPEN Message
  8. 0 1 2 3
  9. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  10. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  11. | Message Type | Channel Type | Priority |
  12. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  13. | Reliability Parameter |
  14. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  15. | Label Length | Protocol Length |
  16. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  17. | |
  18. | Label |
  19. | |
  20. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  21. | |
  22. | Protocol |
  23. | |
  24. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  25. */
  26. type channelOpen struct {
  27. ChannelType ChannelType
  28. Priority uint16
  29. ReliabilityParameter uint32
  30. Label []byte
  31. Protocol []byte
  32. }
  33. const (
  34. channelOpenHeaderLength = 12
  35. )
  36. // ChannelType determines the reliability of the WebRTC DataChannel
  37. type ChannelType byte
  38. // ChannelType enums
  39. const (
  40. // ChannelTypeReliable determines the Data Channel provides a
  41. // reliable in-order bi-directional communication.
  42. ChannelTypeReliable ChannelType = 0x00
  43. // ChannelTypeReliableUnordered determines the Data Channel
  44. // provides a reliable unordered bi-directional communication.
  45. ChannelTypeReliableUnordered ChannelType = 0x80
  46. // ChannelTypePartialReliableRexmit determines the Data Channel
  47. // provides a partially-reliable in-order bi-directional communication.
  48. // User messages will not be retransmitted more times than specified in the Reliability Parameter.
  49. ChannelTypePartialReliableRexmit ChannelType = 0x01
  50. // ChannelTypePartialReliableRexmitUnordered determines
  51. // the Data Channel provides a partial reliable unordered bi-directional communication.
  52. // User messages will not be retransmitted more times than specified in the Reliability Parameter.
  53. ChannelTypePartialReliableRexmitUnordered ChannelType = 0x81
  54. // ChannelTypePartialReliableTimed determines the Data Channel
  55. // provides a partial reliable in-order bi-directional communication.
  56. // User messages might not be transmitted or retransmitted after
  57. // a specified life-time given in milli- seconds in the Reliability Parameter.
  58. // This life-time starts when providing the user message to the protocol stack.
  59. ChannelTypePartialReliableTimed ChannelType = 0x02
  60. // The Data Channel provides a partial reliable unordered bi-directional
  61. // communication. User messages might not be transmitted or retransmitted
  62. // after a specified life-time given in milli- seconds in the Reliability Parameter.
  63. // This life-time starts when providing the user message to the protocol stack.
  64. ChannelTypePartialReliableTimedUnordered ChannelType = 0x82
  65. )
  66. // ChannelPriority enums
  67. const (
  68. ChannelPriorityBelowNormal uint16 = 128
  69. ChannelPriorityNormal uint16 = 256
  70. ChannelPriorityHigh uint16 = 512
  71. ChannelPriorityExtraHigh uint16 = 1024
  72. )
  73. // Marshal returns raw bytes for the given message
  74. func (c *channelOpen) Marshal() ([]byte, error) {
  75. labelLength := len(c.Label)
  76. protocolLength := len(c.Protocol)
  77. totalLen := channelOpenHeaderLength + labelLength + protocolLength
  78. raw := make([]byte, totalLen)
  79. raw[0] = uint8(dataChannelOpen)
  80. raw[1] = byte(c.ChannelType)
  81. binary.BigEndian.PutUint16(raw[2:], c.Priority)
  82. binary.BigEndian.PutUint32(raw[4:], c.ReliabilityParameter)
  83. binary.BigEndian.PutUint16(raw[8:], uint16(labelLength))
  84. binary.BigEndian.PutUint16(raw[10:], uint16(protocolLength))
  85. endLabel := channelOpenHeaderLength + labelLength
  86. copy(raw[channelOpenHeaderLength:endLabel], c.Label)
  87. copy(raw[endLabel:endLabel+protocolLength], c.Protocol)
  88. return raw, nil
  89. }
  90. // Unmarshal populates the struct with the given raw data
  91. func (c *channelOpen) Unmarshal(raw []byte) error {
  92. if len(raw) < channelOpenHeaderLength {
  93. return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, channelOpenHeaderLength, len(raw))
  94. }
  95. c.ChannelType = ChannelType(raw[1])
  96. c.Priority = binary.BigEndian.Uint16(raw[2:])
  97. c.ReliabilityParameter = binary.BigEndian.Uint32(raw[4:])
  98. labelLength := binary.BigEndian.Uint16(raw[8:])
  99. protocolLength := binary.BigEndian.Uint16(raw[10:])
  100. if expectedLen := int(channelOpenHeaderLength + labelLength + protocolLength); len(raw) != expectedLen {
  101. return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, expectedLen, len(raw))
  102. }
  103. c.Label = raw[channelOpenHeaderLength : channelOpenHeaderLength+labelLength]
  104. c.Protocol = raw[channelOpenHeaderLength+labelLength : channelOpenHeaderLength+labelLength+protocolLength]
  105. return nil
  106. }