private void cbNewRtp_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == 13) { Rtp rtp; try { rtp = Rtp.FromString(cbNewRtp.Text, lbColor.BackColor); if (!new System.IO.DirectoryInfo(rtp.Path).Exists) { return; } cbNewRtp.Text = ""; EditingRtps.Add(rtp); RtpList.Items.Add(rtp); RtpList.Color.ActualValue.Add(rtp.Color); RtpList.SelectedIndex = RtpList.Items.Count - 1; RtpList.Focus(); } catch { return; } } else if (e.KeyChar == 26) { cbNewRtp.Text = ""; lbColor.BackColor = Color.Gray; } }
/// <summary> /// Encodes, encrypts, and sends the provided PCM data to the connected voice channel. /// </summary> /// <param name="pcmData">PCM data to encode, encrypt, and send.</param> /// <param name="blockSize">Millisecond length of the PCM data.</param> /// <param name="bitRate">Bitrate of the PCM data.</param> /// <returns>Task representing the sending operation.</returns> public async Task SendAsync(byte[] pcmData, int blockSize, int bitRate = 16) { if (!IsInitialized) { throw new InvalidOperationException("The connection is not initialized"); } await PlaybackSemaphore.WaitAsync().ConfigureAwait(false); var rtp = Rtp.Encode(Sequence, Timestamp, SSRC); var dat = Opus.Encode(pcmData, 0, pcmData.Length, bitRate); dat = Sodium.Encode(dat, Rtp.MakeNonce(rtp), Key); dat = Rtp.Encode(rtp, dat); await SendSpeakingAsync(true).ConfigureAwait(false); // works: //await UdpClient.SendAsync(dat, dat.Length).ConfigureAwait(false); await UdpClient.SendNativelyAsync(dat, dat.Length).ConfigureAwait(false); Sequence++; Timestamp += 48 * (uint)blockSize; PlaybackSemaphore.Release(); }
private void RtpList_SelectedIndexChanged(object sender, EventArgs e) { int index = RtpList.SelectedIndex; if (index >= RtpList.Items.Count || index < 0) { return; } Rtp rtp = (Rtp)RtpList.Items[index]; System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(rtp.Path); if (!dir.Exists) { return; } RtpInnerList.Clear(); RtpInnerList.Items.Clear(); RtpInnerList.AddChildDirectory(dir, rtp.Color, false); RtpInnerList.AddChildFile(dir, rtp.Color); ViewingRtp = rtp; // ==== 移动处理 ==== btUp.Enabled = !(RtpList.SelectedIndex == 0); btDown.Enabled = !(RtpList.SelectedIndex >= EditingRtps.Count - 1); btDel.Enabled = !rtp.IsFromReg; // ==== 赋予处理 ==== Strtb.Text = rtp.FullString(); cbNewRtp.Text = rtp.Path; lbColor.BackColor = rtp.Color; // ================== }
/// <summary> /// Encodes, encrypts, and sends the provided PCM data to the connected voice channel. /// </summary> /// <param name="pcmData">PCM data to encode, encrypt, and send.</param> /// <param name="blockSize">Millisecond length of the PCM data.</param> /// <param name="bitRate">Bitrate of the PCM data.</param> /// <returns>Task representing the sending operation.</returns> public async Task SendAsync(byte[] pcmData, int blockSize, int bitRate = 16) { if (!IsInitialized) { throw new InvalidOperationException("The connection is not initialized"); } await PlaybackSemaphore.WaitAsync().ConfigureAwait(false); var rtp = Rtp.Encode(Sequence, Timestamp, SSRC); var dat = Opus.Encode(pcmData, 0, pcmData.Length, bitRate); dat = Sodium.Encode(dat, Rtp.MakeNonce(rtp), Key); dat = Rtp.Encode(rtp, dat); if (SynchronizerTicks == 0) { SynchronizerTicks = Stopwatch.GetTimestamp(); SynchronizerResolution = (Stopwatch.Frequency * 0.02); TickResolution = 10_000_000.0 / Stopwatch.Frequency; Discord.DebugLogger.LogMessage(LogLevel.Debug, "VoiceNext", $"Timer accuracy: {Stopwatch.Frequency.ToString("#,##0", CultureInfo.InvariantCulture)}/{SynchronizerResolution.ToString(CultureInfo.InvariantCulture)} (high resolution? {Stopwatch.IsHighResolution})", DateTime.Now); } else { // Provided by Laura#0090 (214796473689178133); this is Python, but adaptable: // // delay = max(0, self.delay + ((start_time + self.delay * loops) + - time.time())) // // self.delay // sample size // start_time // time since streaming started // loops // number of samples sent // time.time() // DateTime.Now var cts = Math.Max(Stopwatch.GetTimestamp() - SynchronizerTicks, 0); if (cts < SynchronizerResolution) { await Task.Delay(TimeSpan.FromTicks((long)((SynchronizerResolution - cts) * TickResolution))).ConfigureAwait(false); } SynchronizerTicks += SynchronizerResolution; } await SendSpeakingAsync(true).ConfigureAwait(false); await UdpClient.SendAsync(dat, dat.Length).ConfigureAwait(false); Sequence++; Timestamp += 48 * (uint)blockSize; PlaybackSemaphore.Release(); }
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { Discord = client; Guild = guild; Channel = channel; TransmittingSSRCs = new ConcurrentDictionary <uint, AudioSender>(); _userSpeaking = new AsyncEvent <UserSpeakingEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_SPEAKING"); _userJoined = new AsyncEvent <VoiceUserJoinEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_JOINED"); _userLeft = new AsyncEvent <VoiceUserLeaveEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_LEFT"); _voiceReceived = new AsyncEvent <VoiceReceiveEventArgs>(Discord.EventErrorHandler, "VNEXT_VOICE_RECEIVED"); _voiceSocketError = new AsyncEvent <SocketErrorEventArgs>(Discord.EventErrorHandler, "VNEXT_WS_ERROR"); TokenSource = new CancellationTokenSource(); Configuration = config; Opus = new Opus(AudioFormat); //this.Sodium = new Sodium(); Rtp = new Rtp(); ServerData = server; StateData = state; var eps = ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 80; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } ConnectionEndpoint = new ConnectionEndpoint { Hostname = eph, Port = epp }; ReadyWait = new TaskCompletionSource <bool>(); IsInitialized = false; IsDisposed = false; PlayingWait = null; PacketQueue = new ConcurrentQueue <VoicePacket>(); KeepaliveTimestamps = new ConcurrentDictionary <ulong, long>(); UdpClient = Discord.Configuration.UdpClientFactory(); VoiceWs = Discord.Configuration.WebSocketClientFactory(Discord.Configuration.Proxy); VoiceWs.Disconnected += VoiceWS_SocketClosed; VoiceWs.MessageRecieved += VoiceWS_SocketMessage; VoiceWs.Connected += VoiceWS_SocketOpened; VoiceWs.Errored += VoiceWs_SocketErrored; }
protected void SearchFile(Rtp rtp, string path) { string full = System.IO.Path.Combine(rtp.Path, path); System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(full); if (!dir.Exists) { return; } fileList.AddChildFile(dir, rtp.Color); }
protected void Page_Load(object sender, EventArgs e) { if (Session["Login"] == null) { Response.Redirect("LogIn.aspx"); } int Pid = int.Parse(Request["pid"]); var ArrProd = Application["ArrP"] as List <Product>; Rtp.DataSource = GlobalFunc.GetSomeProd(Pid); Rtp.DataBind(); var Arruser = Application["ArrU"] as User[]; }
internal void PreparePacket(ReadOnlySpan <byte> pcm, ref Memory <byte> target) { var audioFormat = AudioFormat; var packetArray = ArrayPool <byte> .Shared.Rent(Rtp.CalculatePacketSize(audioFormat.SampleCountToSampleSize(audioFormat.CalculateMaximumFrameSize()), SelectedEncryptionMode)); var packet = packetArray.AsSpan(); Rtp.EncodeHeader(Sequence, Timestamp, SSRC, packet); var opus = packet.Slice(Rtp.HeaderSize, pcm.Length); Opus.Encode(pcm, ref opus); Sequence++; Timestamp += (uint)audioFormat.CalculateFrameSize(audioFormat.CalculateSampleDuration(pcm.Length)); Span <byte> nonce = new byte[Sodium.NonceSize]; switch (SelectedEncryptionMode) { case EncryptionMode.XSalsa20_Poly1305: Sodium.GenerateNonce(packet.Slice(0, Rtp.HeaderSize), nonce); break; case EncryptionMode.XSalsa20_Poly1305_Suffix: Sodium.GenerateNonce(nonce); break; case EncryptionMode.XSalsa20_Poly1305_Lite: Sodium.GenerateNonce(Nonce++, nonce); break; default: ArrayPool <byte> .Shared.Return(packetArray); throw new Exception("Unsupported encryption mode."); } Span <byte> encrypted = new byte[Sodium.CalculateTargetSize(opus)]; Sodium.Encrypt(opus, encrypted, nonce); encrypted.CopyTo(packet.Slice(Rtp.HeaderSize)); packet = packet.Slice(0, Rtp.CalculatePacketSize(encrypted.Length, SelectedEncryptionMode)); Sodium.AppendNonce(nonce, packet, SelectedEncryptionMode); target = target.Slice(0, packet.Length); packet.CopyTo(target.Span); ArrayPool <byte> .Shared.Return(packetArray); }
/// <summary> /// Disconnects and disposes this voice connection. /// </summary> public void Dispose() { if (IsDisposed) { return; } IsDisposed = true; IsInitialized = false; TokenSource.Cancel(); SenderTokenSource.Cancel(); if (Configuration.EnableIncoming) { ReceiverTokenSource.Cancel(); } try { VoiceWs.DisconnectAsync(null).ConfigureAwait(false).GetAwaiter().GetResult(); UdpClient.Close(); } catch (Exception) { } Opus?.Dispose(); Opus = null; Sodium?.Dispose(); Sodium = null; Rtp?.Dispose(); Rtp = null; if (VoiceDisconnected != null) { VoiceDisconnected(Guild); } }
private bool ProcessPacket(ReadOnlySpan <byte> data, ref Memory <byte> opus, ref Memory <byte> pcm, IList <ReadOnlyMemory <byte> > pcmPackets, out AudioSender voiceSender, out AudioFormat outputFormat) { voiceSender = null; outputFormat = default; if (!Rtp.IsRtpHeader(data)) { return(false); } Rtp.DecodeHeader(data, out var sequence, out var timestamp, out var ssrc, out var hasExtension); var vtx = TransmittingSSRCs[ssrc]; voiceSender = vtx; if (sequence <= vtx.LastSequence) // out-of-order packet; discard { return(false); } var gap = vtx.LastSequence != 0 ? sequence - 1 - vtx.LastSequence : 0; if (gap >= 5) { Discord.DebugLogger.LogMessage(LogLevel.Warning, "VNext RX", "5 or more voice packets were dropped when receiving", DateTime.Now); } Span <byte> nonce = new byte[Sodium.NonceSize]; Sodium.GetNonce(data, nonce, SelectedEncryptionMode); Rtp.GetDataFromPacket(data, out var encryptedOpus, SelectedEncryptionMode); var opusSize = Sodium.CalculateSourceSize(encryptedOpus); opus = opus.Slice(0, opusSize); var opusSpan = opus.Span; try { Sodium.Decrypt(encryptedOpus, opusSpan, nonce); // Strip extensions, if any if (hasExtension) { // RFC 5285, 4.2 One-Byte header // http://www.rfcreader.com/#rfc5285_line186 if (opusSpan[0] == 0xBE && opusSpan[1] == 0xDE) { var headerLen = opusSpan[2] << 8 | opusSpan[3]; var i = 4; for (; i < headerLen + 4; i++) { var @byte = opusSpan[i]; // ID is currently unused since we skip it anyway //var id = (byte)(@byte >> 4); var length = (byte)(@byte & 0x0F) + 1; i += length; } // Strip extension padding too while (opusSpan[i] == 0) { i++; } opusSpan = opusSpan.Slice(i); } // TODO: consider implementing RFC 5285, 4.3. Two-Byte Header } if (gap == 1) { var lastSampleCount = Opus.GetLastPacketSampleCount(vtx.Decoder); var fecpcm = new byte[AudioFormat.SampleCountToSampleSize(lastSampleCount)]; var fecpcmMem = fecpcm.AsSpan(); Opus.Decode(vtx.Decoder, opusSpan, ref fecpcmMem, true, out _); pcmPackets.Add(fecpcm.AsMemory(0, fecpcmMem.Length)); } else if (gap > 1) { var lastSampleCount = Opus.GetLastPacketSampleCount(vtx.Decoder); for (var i = 0; i < gap; i++) { var fecpcm = new byte[AudioFormat.SampleCountToSampleSize(lastSampleCount)]; var fecpcmMem = fecpcm.AsSpan(); Opus.ProcessPacketLoss(vtx.Decoder, lastSampleCount, ref fecpcmMem); pcmPackets.Add(fecpcm.AsMemory(0, fecpcmMem.Length)); } } var pcmSpan = pcm.Span; Opus.Decode(vtx.Decoder, opusSpan, ref pcmSpan, false, out outputFormat); pcm = pcm.Slice(0, pcmSpan.Length); } finally { vtx.LastSequence = sequence; } return(true); }
public virtual void Depacketize(Rtp.RtpFrame rtpFrame) { DisposeBuffer(); this.Buffer = new MemoryStream(); //Get all packets in the frame foreach (Rtp.RtpPacket packet in rtpFrame) ProcessPacket(packet); //Order by DON? this.Buffer.Position = 0; }
private async Task VoiceReceiverTask() { var token = ReceiverToken; var client = UdpClient; while (!token.IsCancellationRequested) { if (client.DataAvailable <= 0) { continue; } byte[] data = null, header = null; ushort seq = 0; uint ts = 0, ssrc = 0; try { data = await client.ReceiveAsync().ConfigureAwait(false); header = new byte[RtpCodec.SIZE_HEADER]; data = Rtp.Decode(data, header); var nonce = Rtp.MakeNonce(header); data = Sodium.Decode(data, nonce, Key); // following is thanks to code from Eris // https://github.com/abalabahaha/eris/blob/master/lib/voice/VoiceConnection.js#L623 var doff = 0; Rtp.Decode(header, out seq, out ts, out ssrc, out var has_ext); if (has_ext) { if (data[0] == 0xBE && data[1] == 0xDE) { // RFC 5285, 4.2 One-Byte header // http://www.rfcreader.com/#rfc5285_line186 var hlen = data[2] << 8 | data[3]; var i = 4; for (; i < hlen + 4; i++) { var b = data[i]; // This is unused(?) //var id = (b >> 4) & 0x0F; var len = (b & 0x0F) + 1; i += len; } while (data[i] == 0) { i++; } doff = i; } // TODO: consider implementing RFC 5285, 4.3. Two-Byte Header } data = Opus.Decode(data, doff, data.Length - doff); } catch { continue; } // TODO: wait for ssrc map? DiscordUser user = null; if (SSRCMap.ContainsKey(ssrc)) { var id = SSRCMap[ssrc]; if (Guild != null) { user = Guild._members.FirstOrDefault(xm => xm.Id == id) ?? await Guild.GetMemberAsync(id).ConfigureAwait(false); } if (user == null) { user = Discord.InternalGetCachedUser(id); } if (user == null) { user = new DiscordUser { Discord = Discord, Id = id } } ; } await _voiceReceived.InvokeAsync(new VoiceReceiveEventArgs(Discord) { SSRC = ssrc, Voice = new ReadOnlyCollection <byte>(data), VoiceLength = 20, User = user }).ConfigureAwait(false); } }
/// <summary> /// Depacketizes a single packet. /// </summary> /// <param name="packet"></param> /// <param name="containsSps"></param> /// <param name="containsPps"></param> /// <param name="containsSei"></param> /// <param name="containsSlice"></param> /// <param name="isIdr"></param> protected internal virtual void ProcessPacket(Rtp.RtpPacket packet) { //Starting at offset 0 int offset = 0; //Obtain the data of the packet (without source list or padding) byte[] packetData = packet.PayloadData.ToArray(); //Cache the length int count = packetData.Length; //Must have at least 2 bytes if (count <= 2) return; //Determine if the forbidden bit is set and the type of nal from the first byte byte firstByte = packetData[offset]; //bool forbiddenZeroBit = ((firstByte & 0x80) >> 7) != 0; byte nalUnitType = (byte)(firstByte & Common.Binary.FiveBitMaxValue); //TODO //o The F bit MUST be cleared if all F bits of the aggregated NAL units are zero; otherwise, it MUST be set. //if (forbiddenZeroBit && nalUnitType <= 23 && nalUnitType > 29) throw new InvalidOperationException("Forbidden Zero Bit is Set."); //Optomize setting out parameters, could be done with a label or with a static function. //Determine what to do switch (nalUnitType) { //Reserved - Ignore case Media.Codecs.Video.H264.NalUnitType.Unknown: case Media.Codecs.Video.H264.NalUnitType.PayloadContentScalabilityInformation: case Media.Codecs.Video.H264.NalUnitType.Reserved: { //May have 4 byte NAL header. //Do not handle return; } case Media.Codecs.Video.H264.NalUnitType.SingleTimeAggregationA: //STAP - A case Media.Codecs.Video.H264.NalUnitType.SingleTimeAggregationB: //STAP - B case Media.Codecs.Video.H264.NalUnitType.MultiTimeAggregation16: //MTAP - 16 case Media.Codecs.Video.H264.NalUnitType.MultiTimeAggregation24: //MTAP - 24 { //Move to Nal Data ++offset; //Todo Determine if need to Order by DON first. //EAT DON for ALL BUT STAP - A if (nalUnitType != Media.Codecs.Video.H264.NalUnitType.SingleTimeAggregationA) offset += 2; //Consume the rest of the data from the packet while (offset < count) { //Determine the nal unit size which does not include the nal header int tmp_nal_size = Common.Binary.Read16(packetData, offset, BitConverter.IsLittleEndian); offset += 2; //If the nal had data then write it if (tmp_nal_size > 0) { //Store the nalType contained m_ContainedNalTypes.Add(nalUnitType); //For DOND and TSOFFSET switch (nalUnitType) { case Media.Codecs.Video.H264.NalUnitType.MultiTimeAggregation16:// MTAP - 16 { //SKIP DOND and TSOFFSET offset += 3; goto default; } case Media.Codecs.Video.H264.NalUnitType.MultiTimeAggregation24:// MTAP - 24 { //SKIP DOND and TSOFFSET offset += 4; goto default; } default: { //Read the nal header but don't move the offset byte nalHeader = (byte)(packetData[offset] & Common.Binary.FiveBitMaxValue); //Store the nalType contained m_ContainedNalTypes.Add(nalHeader); if (nalHeader == 6 || nalHeader == 7 || nalHeader == 8) Buffer.WriteByte(0); //Done reading break; } } //Write the start code Buffer.Write(Media.Codecs.Video.H264.NalUnitType.StartCode, 0, 3); //Write the nal header and data Buffer.Write(packetData, offset, tmp_nal_size); //Move the offset past the nal offset += tmp_nal_size; } } return; } case Media.Codecs.Video.H264.NalUnitType.FragmentationUnitA: //FU - A case Media.Codecs.Video.H264.NalUnitType.FragmentationUnitB: //FU - B { /* Informative note: When an FU-A occurs in interleaved mode, it always follows an FU-B, which sets its DON. * Informative note: If a transmitter wants to encapsulate a single NAL unit per packet and transmit packets out of their decoding order, STAP-B packet type can be used. */ //Need 2 bytes if (count > 2) { //Read the Header byte FUHeader = packetData[++offset]; bool Start = ((FUHeader & 0x80) >> 7) > 0; //bool End = ((FUHeader & 0x40) >> 6) > 0; //bool Receiver = (FUHeader & 0x20) != 0; //if (Receiver) throw new InvalidOperationException("Receiver Bit Set"); //Move to data ++offset; //Todo Determine if need to Order by DON first. //DON Present in FU - B if (nalUnitType == 29) offset += 2; //Determine the fragment size int fragment_size = count - offset; //If the size was valid if (fragment_size > 0) { //If the start bit was set if (Start) { //Reconstruct the nal header //Use the first 3 bits of the first byte and last 5 bites of the FU Header byte nalHeader = (byte)((firstByte & 0xE0) | (FUHeader & Common.Binary.FiveBitMaxValue)); //Store the nalType contained m_ContainedNalTypes.Add(nalHeader); if (nalHeader == 6 || nalHeader == 7 || nalHeader == 8) Buffer.WriteByte(0); //Write the start code Buffer.Write(Media.Codecs.Video.H264.NalUnitType.StartCode, 0, 3); //Write the re-construced header Buffer.WriteByte(nalHeader); } //Allow If End to Write End Sequence? //Write the data of the fragment. Buffer.Write(packetData, offset, fragment_size); } } return; } default: { //Store the nalType contained m_ContainedNalTypes.Add(nalUnitType); if (nalUnitType == 6 || nalUnitType == 7 || nalUnitType == 8) Buffer.WriteByte(0); //Write the start code Buffer.Write(Media.Codecs.Video.H264.NalUnitType.StartCode, 0, 3); //Write the nal heaer and data data Buffer.Write(packetData, offset, count - offset); return; } } }
public RFC5404Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC5993Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC6184Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC4867Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC5577Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC2190Frame(Rtp.RtpFrame existing) : base(existing) { }
public RFC4629Frame(Rtp.RtpFrame existing) : base(existing) { }
/// <summary> /// Prepares a text description which is compatible with 'rtpsend' among other 'rtp tools'. /// </summary> /// <param name="format">The <see cref="FileFormat"/> to output.</param> /// <param name="packet">The <see cref="Rtp.RtpPacket"/> to describe</param> /// <param name="time">Timeoffset from when recoding began, should be 0 for the first packet.</param> /// <param name="source">The <see cref="System.Net.IPEndPoint"/> from which the packet was received.</param> /// <returns>The text which describes the packet if the <paramref name="format"/> is a text format, otherwise an empty string</returns> public static string ToTextualConvention(FileFormat format, Rtp.RtpPacket packet, TimeSpan time, System.Net.IPEndPoint source) { //StringBuilder? //If the format is Short (Vat or Rtp Data in tablular form) if (format == FileFormat.Short) { //Then return that format return string.Format(RtpSend.ShortFormat, //0 time.TotalSeconds.ToString("0.000000"), //1 (packet.Marker ? (-packet.SequenceNumber) : packet.SequenceNumber).ToString(), //2 source.Port.ToString()); } StringBuilder builder = new StringBuilder(64); //All Rtp are described with this format builder.Append(string.Format(RtpSend.Format, //0 time.TotalSeconds.ToString("0.000000"), //1 string.Format(RtpSend.RtpPacketFormat, //0 packet.Length, //Packet size in bytes including header //1 source.Address.ToString() + ':' + source.Port.ToString(), //2 packet.Version.ToString(), //3 packet.Padding ? "1" : "0", //4 packet.Extension ? "1" : "0", //5 packet.ContributingSourceCount.ToString(), //6 packet.Marker ? "1" : "0", //7 packet.PayloadType, //8 (Format description) string.Format(RtpSend.PayloadDescriptionFormat, packet.PayloadType, RtpSendExtensions.PayloadDescription(packet)), //9 packet.SequenceNumber, //10 packet.SynchronizationSourceIdentifier, //11 packet.Timestamp ))); //Write the textual representation of the items in the sourceList if (packet.ContributingSourceCount > 0) { //Note //http://www.cs.columbia.edu/irt/software/rtptools/ChangeLog.html //States the format is not hex when in the format csrc[n] //However - //http://www.cs.columbia.edu/irt/software/rtptools/#rtpsend //States that the format is : //cc=<CSRC count> //csrc=<CSRC> //This is basically the same thing and a parsing semantic. using (Media.RFC3550.SourceList sl = new Media.RFC3550.SourceList(packet)) { if (sl == null) { builder.Append("#Incomplete Source List Not Included"); builder.Append((char)Common.ASCII.LineFeed); } else { //csrc= while (sl.MoveNext()) { builder.Append(string.Format(RtpSend.HexFormat, "csrc", HexSpecifier, sl.CurrentSource.ToString("X"), (char)Common.ASCII.LineFeed)); } } } } //Write the textual representation of the Extension if (packet.Extension) { using (var rtpExtension = packet.GetExtension()) { if (rtpExtension == null) { builder.Append("#Incomplete Extension Not Included"); builder.Append((char)Common.ASCII.LineFeed); } else { builder.Append(string.Format(RtpSend.HexFormat, "ext_type", HexSpecifier + rtpExtension.Flags.ToString("X"), (char)Common.ASCII.LineFeed)); builder.Append(string.Format(RtpSend.NonQuotedFormat, "ext_len", rtpExtension.LengthInWords)); builder.Append((char)Common.ASCII.LineFeed); builder.Append(string.Format(RtpSend.HexFormat, "ext_data", BitConverter.ToString(rtpExtension.Data.ToArray()).Replace("-", string.Empty), (char)Common.ASCII.LineFeed)); } } } //If the format is hex then add the payload dump if (format == FileFormat.Hex) { var data = packet.PayloadData; if (data.Any()) builder.Append(string.Format(RtpSend.HexFormat, "data", BitConverter.ToString(data.ToArray()).Replace("-", string.Empty), (char)Common.ASCII.LineFeed)); else builder.Append(string.Format(HexFormat, "data", NullSpecifier, (char)Common.ASCII.LineFeed)); } //Return the result return builder.ToString(); }
protected void Page_Load(object sender, EventArgs e) { if (Request["pid"] == null) { Response.Redirect("Default.aspx"); } int Pid = int.Parse(Request["pid"]); int tot = 0; var ArrProd = Application["ArrP"] as List <Product>; Rtp.DataSource = ArrProd; Rtp.DataBind(); var Arruser = Application["ArrU"] as User[]; if (Session["Login"] == null) { Response.Redirect("LogIn.aspx"); } string WhatToDo = (string)Request["op"]; if (WhatToDo == "remove") { var Cart = Session["Cart"] as Cart; if (Cart != null) { Cart.RemoveFromCart(Pid); Session["cart"] = Cart; Response.Redirect("Mycart.aspx"); } } else if (WhatToDo == "empty") { var Cart = Session["Cart"] as Cart; if (Cart != null) { Cart.EmptyCart(); Session["Cart"] = Cart; Response.Redirect("Mycart.aspx"); } } else if (WhatToDo == "ed") { var Cart = Session["Cart"] as Cart; if (Cart != null) { for (int i = 0; i < ArrProd.Count; i++) { Item ed = new Item(Pid, ArrProd[i].Pname, 1, ArrProd[i].Price, ArrProd[i].Picname); Cart.removone(ed); Session["Cart"] = Cart; Response.Redirect("Mycart.aspx"); } } } else if (WhatToDo == "add") { var Cart = Session["Cart"] as Cart; if (Cart != null) { for (int i = 0; i < ArrProd.Count; i++) { Item ad = new Item(Pid, ArrProd[i].Pname, 1, ArrProd[i].Price, ArrProd[i].Picname); Cart.adding(ad); Session["Cart"] = Cart; Response.Redirect("Mycart.aspx"); } } } for (int i = 0; i < ArrProd.Count; i++) { if (ArrProd[i].Pid == Pid) { tot++; var Cart = Session["Cart"] as Cart; if (Cart == null) { Cart = new Cart(); } Item tmp = new Item(Pid, ArrProd[i].Pname, 1, ArrProd[i].Price, ArrProd[i].Picname); Cart.AddtoCart(tmp); Session["Cart"] = Cart; Response.Redirect("MyCart.aspx"); } } }