Ejemplo n.º 1
0
        /// <summary>
        /// Parses the an DCEP open message from a buffer.
        /// </summary>
        /// <param name="buffer">The buffer to parse the message from.</param>
        /// <param name="posn">The position in the buffer to start parsing from.</param>
        /// <returns>A new DCEP open message instance.</returns>
        public static DataChannelOpenMessage Parse(byte[] buffer, int posn)
        {
            if (buffer.Length < DCEP_OPEN_FIXED_PARAMETERS_LENGTH)
            {
                throw new ApplicationException("The buffer did not contain the minimum number of bytes for a DCEP open message.");
            }

            var dcepOpen = new DataChannelOpenMessage();

            dcepOpen.MessageType = buffer[posn];
            dcepOpen.ChannelType = buffer[posn + 1];
            dcepOpen.Priority    = NetConvert.ParseUInt16(buffer, posn + 2);
            dcepOpen.Reliability = NetConvert.ParseUInt32(buffer, posn + 4);

            ushort labelLength    = NetConvert.ParseUInt16(buffer, posn + 8);
            ushort protocolLength = NetConvert.ParseUInt16(buffer, posn + 10);

            if (labelLength > 0)
            {
                dcepOpen.Label = Encoding.UTF8.GetString(buffer, 12, labelLength);
            }

            if (protocolLength > 0)
            {
                dcepOpen.Protocol = Encoding.UTF8.GetString(buffer, 12 + labelLength, protocolLength);
            }

            return(dcepOpen);
        }
        /// <summary>
        /// Event handler for a DATA chunk being received. The chunk can be either a DCEP message or data channel data
        /// payload.
        /// </summary>
        /// <param name="dataFrame">The received data frame which could represent one or more chunks depending
        /// on fragmentation..</param>
        private void OnDataFrameReceived(SctpDataFrame dataFrame)
        {
            switch (dataFrame)
            {
            case var frame when frame.PPID == (uint)DataChannelPayloadProtocols.WebRTC_DCEP:
                switch (frame.UserData[0])
                {
                case (byte)DataChannelMessageTypes.ACK:
                    OnDataChannelOpened?.Invoke(frame.StreamID);
                    break;

                case (byte)DataChannelMessageTypes.OPEN:
                    var dcepOpen = DataChannelOpenMessage.Parse(frame.UserData, 0);

                    logger.LogDebug($"DCEP OPEN channel type {dcepOpen.ChannelType}, priority {dcepOpen.Priority}, " +
                                    $"reliability {dcepOpen.Reliability}, label {dcepOpen.Label}, protocol {dcepOpen.Protocol}.");

                    DataChannelTypes channelType = DataChannelTypes.DATA_CHANNEL_RELIABLE;
                    if (Enum.IsDefined(typeof(DataChannelTypes), dcepOpen.ChannelType))
                    {
                        channelType = (DataChannelTypes)dcepOpen.ChannelType;
                    }
                    else
                    {
                        logger.LogWarning($"DECP OPEN channel type of {dcepOpen.ChannelType} not recognised, defaulting to {channelType}.");
                    }

                    OnNewDataChannel?.Invoke(
                        frame.StreamID,
                        channelType,
                        dcepOpen.Priority,
                        dcepOpen.Reliability,
                        dcepOpen.Label,
                        dcepOpen.Protocol);

                    break;

                default:
                    logger.LogWarning($"DCEP message type {frame.UserData[0]} not recognised, ignoring.");
                    break;
                }
                break;

            default:
                OnDataChannelData?.Invoke(dataFrame);
                break;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Sends an OPEN Data Channel Establishment Protocol (DCEP) message
        /// to open a data channel on the remote peer for send/receive.
        /// </summary>
        internal void SendDcepOpen()
        {
            var dcepOpen = new DataChannelOpenMessage()
            {
                MessageType = (byte)DataChannelMessageTypes.OPEN,
                ChannelType = (byte)DataChannelTypes.DATA_CHANNEL_RELIABLE_UNORDERED,
                Label       = label
            };

            lock (this)
            {
                _transport.RTCSctpAssociation.SendData(id.GetValueOrDefault(),
                                                       (uint)DataChannelPayloadProtocols.WebRTC_DCEP,
                                                       dcepOpen.GetBytes());
            }
        }