2
0

TransportCommands.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Xml.Linq;
  7. using Emby.Dlna.Common;
  8. using Emby.Dlna.Ssdp;
  9. namespace Emby.Dlna.PlayTo
  10. {
  11. public class TransportCommands
  12. {
  13. private const string CommandBase = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<SOAP-ENV:Body>" + "<m:{0} xmlns:m=\"{1}\">" + "{2}" + "</m:{0}>" + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
  14. private List<StateVariable> _stateVariables = new List<StateVariable>();
  15. private List<ServiceAction> _serviceActions = new List<ServiceAction>();
  16. public List<StateVariable> StateVariables => _stateVariables;
  17. public List<ServiceAction> ServiceActions => _serviceActions;
  18. public static TransportCommands Create(XDocument document)
  19. {
  20. var command = new TransportCommands();
  21. var actionList = document.Descendants(UPnpNamespaces.Svc + "actionList");
  22. foreach (var container in actionList.Descendants(UPnpNamespaces.Svc + "action"))
  23. {
  24. command.ServiceActions.Add(ServiceActionFromXml(container));
  25. }
  26. var stateValues = document.Descendants(UPnpNamespaces.ServiceStateTable).FirstOrDefault();
  27. if (stateValues != null)
  28. {
  29. foreach (var container in stateValues.Elements(UPnpNamespaces.Svc + "stateVariable"))
  30. {
  31. command.StateVariables.Add(FromXml(container));
  32. }
  33. }
  34. return command;
  35. }
  36. private static ServiceAction ServiceActionFromXml(XElement container)
  37. {
  38. var serviceAction = new ServiceAction
  39. {
  40. Name = container.GetValue(UPnpNamespaces.Svc + "name"),
  41. };
  42. var argumentList = serviceAction.ArgumentList;
  43. foreach (var arg in container.Descendants(UPnpNamespaces.Svc + "argument"))
  44. {
  45. argumentList.Add(ArgumentFromXml(arg));
  46. }
  47. return serviceAction;
  48. }
  49. private static Argument ArgumentFromXml(XElement container)
  50. {
  51. if (container == null)
  52. {
  53. throw new ArgumentNullException(nameof(container));
  54. }
  55. return new Argument
  56. {
  57. Name = container.GetValue(UPnpNamespaces.Svc + "name"),
  58. Direction = container.GetValue(UPnpNamespaces.Svc + "direction"),
  59. RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable")
  60. };
  61. }
  62. private static StateVariable FromXml(XElement container)
  63. {
  64. var allowedValues = new List<string>();
  65. var element = container.Descendants(UPnpNamespaces.Svc + "allowedValueList")
  66. .FirstOrDefault();
  67. if (element != null)
  68. {
  69. var values = element.Descendants(UPnpNamespaces.Svc + "allowedValue");
  70. allowedValues.AddRange(values.Select(child => child.Value));
  71. }
  72. return new StateVariable
  73. {
  74. Name = container.GetValue(UPnpNamespaces.Svc + "name"),
  75. DataType = container.GetValue(UPnpNamespaces.Svc + "dataType"),
  76. AllowedValues = allowedValues.ToArray()
  77. };
  78. }
  79. public string BuildPost(ServiceAction action, string xmlNamespace)
  80. {
  81. var stateString = string.Empty;
  82. foreach (var arg in action.ArgumentList)
  83. {
  84. if (arg.Direction == "out")
  85. {
  86. continue;
  87. }
  88. if (arg.Name == "InstanceID")
  89. {
  90. stateString += BuildArgumentXml(arg, "0");
  91. }
  92. else
  93. {
  94. stateString += BuildArgumentXml(arg, null);
  95. }
  96. }
  97. return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamespace, stateString);
  98. }
  99. public string BuildPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "")
  100. {
  101. var stateString = string.Empty;
  102. foreach (var arg in action.ArgumentList)
  103. {
  104. if (arg.Direction == "out")
  105. {
  106. continue;
  107. }
  108. if (arg.Name == "InstanceID")
  109. {
  110. stateString += BuildArgumentXml(arg, "0");
  111. }
  112. else
  113. {
  114. stateString += BuildArgumentXml(arg, value.ToString(), commandParameter);
  115. }
  116. }
  117. return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
  118. }
  119. public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary<string, string> dictionary)
  120. {
  121. var stateString = string.Empty;
  122. foreach (var arg in action.ArgumentList)
  123. {
  124. if (arg.Name == "InstanceID")
  125. {
  126. stateString += BuildArgumentXml(arg, "0");
  127. }
  128. else if (dictionary.ContainsKey(arg.Name))
  129. {
  130. stateString += BuildArgumentXml(arg, dictionary[arg.Name]);
  131. }
  132. else
  133. {
  134. stateString += BuildArgumentXml(arg, value.ToString());
  135. }
  136. }
  137. return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
  138. }
  139. private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
  140. {
  141. var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase));
  142. if (state != null)
  143. {
  144. var sendValue = state.AllowedValues.FirstOrDefault(a => string.Equals(a, commandParameter, StringComparison.OrdinalIgnoreCase)) ??
  145. (state.AllowedValues.Count > 0 ? state.AllowedValues[0] : value);
  146. return string.Format(CultureInfo.InvariantCulture, "<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}</{0}>", argument.Name, state.DataType ?? "string", sendValue);
  147. }
  148. return string.Format(CultureInfo.InvariantCulture, "<{0}>{1}</{0}>", argument.Name, value);
  149. }
  150. }
  151. }