209 lines
5.3 KiB
C#
209 lines
5.3 KiB
C#
using log4net;
|
|
using log4net.Repository.Hierarchy;
|
|
using skyscraper5.Skyscraper.IO.TunerInterface;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace skyscraper8.Ietf.Rfc4566_SDP
|
|
{
|
|
public class SdpAttributeCollection : IEnumerable<SdpAttribute>
|
|
{
|
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
|
private Dictionary<string, SdpAttribute> _attributes;
|
|
|
|
internal void SetHint(string args)
|
|
{
|
|
if (_attributes == null)
|
|
_attributes = new Dictionary<string, SdpAttribute>();
|
|
|
|
int indexOf = args.IndexOf(':');
|
|
string key = args.Substring(0, indexOf);
|
|
string value = args.Substring(indexOf + 1);
|
|
switch (key)
|
|
{
|
|
case "mbms-mode":
|
|
_attributes.Add(key, new MbmsMode(value));
|
|
break;
|
|
case "source-filter":
|
|
if (!_attributes.ContainsKey(key))
|
|
_attributes.Add(key, new SourceFilter());
|
|
SourceFilter sourceFilter = _attributes[key] as SourceFilter;
|
|
sourceFilter.SetHint(value);
|
|
break;
|
|
case "flute-tsi":
|
|
_attributes.Add(key, new FluteTsi(value));
|
|
break;
|
|
default:
|
|
logger.ErrorFormat("Unknown SDP Attribute: \"{0}\" - please consider sharing a sample of this stream for further analysis.", key);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public IEnumerator<SdpAttribute> GetEnumerator()
|
|
{
|
|
return _attributes.Values.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return _attributes.Values.GetEnumerator();
|
|
}
|
|
}
|
|
|
|
internal class FluteTsi : SdpAttribute
|
|
{
|
|
public FluteTsi(string value) : base("flute-tsi")
|
|
{
|
|
TSI = long.Parse(value);
|
|
}
|
|
|
|
public long TSI { get; private set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return TSI.ToString();
|
|
}
|
|
}
|
|
|
|
internal class SourceFilter : SdpAttribute
|
|
{
|
|
public SourceFilter() : base("source-filter")
|
|
{
|
|
}
|
|
|
|
public void SetHint(string value)
|
|
{
|
|
if (_filterChain == null)
|
|
_filterChain = new List<SourceFilterChainLink>();
|
|
_filterChain.Add(new SourceFilterChainLink(value.Split(' ',StringSplitOptions.RemoveEmptyEntries)));
|
|
}
|
|
|
|
private List<SourceFilterChainLink> _filterChain;
|
|
|
|
class SourceFilterChainLink
|
|
{
|
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
|
|
|
public SourceFilterChainLink(string[] args)
|
|
{
|
|
if (args[0].Equals("incl"))
|
|
{
|
|
Include = true;
|
|
}
|
|
else if (args[0].Equals("excl"))
|
|
{
|
|
Include = false;
|
|
}
|
|
else
|
|
{
|
|
logger.ErrorFormat("Unknown Filter Mode \"{0}\", assuming exclusion just to be sure.", args[0]);
|
|
}
|
|
|
|
if (!SdpNetworkType.TryParse(args[1], true, out _networkType))
|
|
{
|
|
logger.ErrorFormat("Unknown Network Type \"{0}\", assuming \"IN\" - please consider sharing a sample of this stream so this can be implemented.", args[1]);
|
|
_networkType = SdpNetworkType.IN;
|
|
}
|
|
|
|
if (!SdpAddressType.TryParse(args[2], true, out _addressType))
|
|
{
|
|
logger.ErrorFormat("Unknown Address Type \"{0}\", assuming \"IP4\" - please consider sharing a sample of this stream so this can be implemented.", args[2]);
|
|
_addressType = SdpAddressType.IP4;
|
|
}
|
|
|
|
DestinationAddress = args[3];
|
|
|
|
int numSources = args.Length - 4;
|
|
Sources = new string[numSources];
|
|
Array.Copy(args, 4, Sources, 0, numSources);
|
|
}
|
|
|
|
/// <summary>
|
|
/// If this is true, an incoming packet is accepted, if not it gets discarded.
|
|
/// </summary>
|
|
public bool Include { get; private set; }
|
|
|
|
public string[] Sources { get; private set; }
|
|
public string DestinationAddress { get; private set; }
|
|
private SdpAddressType _addressType;
|
|
public SdpAddressType AddressType
|
|
{
|
|
get => _addressType;
|
|
}
|
|
|
|
private SdpNetworkType _networkType;
|
|
public SdpNetworkType NetworkType
|
|
{
|
|
get => _networkType;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal class MbmsMode : SdpAttribute
|
|
{
|
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
|
|
|
public MbmsMode(string value)
|
|
: base("mbms-mode")
|
|
{
|
|
string[] args = value.Split(' ');
|
|
if (args[0].Equals("broadcast-mbsfn"))
|
|
{
|
|
BigInteger tmgi = BigInteger.Parse(args[1]);
|
|
this.Tmgi = tmgi.ToByteArray();
|
|
}
|
|
else if (args[0].Equals("broadcast"))
|
|
{
|
|
BigInteger tmgi = BigInteger.Parse(args[1]);
|
|
this.Tmgi = tmgi.ToByteArray();
|
|
this.MbmsCountingIndication = int.Parse(args[2]);
|
|
}
|
|
else
|
|
{
|
|
logger.ErrorFormat("Unknown MBMS Mode: {0} - please consider a sharing a sample of this stream if you'd like the developer to look further into this.", args[0]);
|
|
}
|
|
}
|
|
|
|
public int? MbmsCountingIndication { get; private set; }
|
|
|
|
public byte[] Tmgi { get; private set; }
|
|
|
|
internal enum MbmsBearerMode
|
|
{
|
|
Unknown,
|
|
Broadcast,
|
|
BroadcastMbsfn
|
|
}
|
|
|
|
public MbmsBearerMode BearerMode
|
|
{
|
|
get
|
|
{
|
|
if (Tmgi == null)
|
|
return MbmsBearerMode.Unknown;
|
|
if (MbmsCountingIndication == null)
|
|
return MbmsBearerMode.BroadcastMbsfn;
|
|
else
|
|
return MbmsBearerMode.Broadcast;
|
|
}
|
|
}
|
|
}
|
|
|
|
public abstract class SdpAttribute
|
|
{
|
|
protected SdpAttribute(string key)
|
|
{
|
|
this.SdpAttributeName = key;
|
|
}
|
|
|
|
public string SdpAttributeName { get; private set; }
|
|
}
|
|
}
|