TransportCommands.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using System;
  2. using MediaBrowser.Dlna.Common;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Xml.Linq;
  6. namespace MediaBrowser.Dlna.PlayTo
  7. {
  8. public class TransportCommands
  9. {
  10. private List<StateVariable> _stateVariables = new List<StateVariable>();
  11. public List<StateVariable> StateVariables
  12. {
  13. get
  14. {
  15. return _stateVariables;
  16. }
  17. set
  18. {
  19. _stateVariables = value;
  20. }
  21. }
  22. private List<ServiceAction> _serviceActions = new List<ServiceAction>();
  23. public List<ServiceAction> ServiceActions
  24. {
  25. get
  26. {
  27. return _serviceActions;
  28. }
  29. set
  30. {
  31. _serviceActions = value;
  32. }
  33. }
  34. public static TransportCommands Create(XDocument document)
  35. {
  36. var command = new TransportCommands();
  37. var actionList = document.Descendants(uPnpNamespaces.svc + "actionList");
  38. foreach (var container in actionList.Descendants(uPnpNamespaces.svc + "action"))
  39. {
  40. command.ServiceActions.Add(ServiceActionFromXml(container));
  41. }
  42. var stateValues = document.Descendants(uPnpNamespaces.ServiceStateTable).FirstOrDefault();
  43. if (stateValues != null)
  44. {
  45. foreach (var container in stateValues.Elements(uPnpNamespaces.svc + "stateVariable"))
  46. {
  47. command.StateVariables.Add(FromXml(container));
  48. }
  49. }
  50. return command;
  51. }
  52. private static ServiceAction ServiceActionFromXml(XElement container)
  53. {
  54. var argumentList = new List<Argument>();
  55. foreach (var arg in container.Descendants(uPnpNamespaces.svc + "argument"))
  56. {
  57. argumentList.Add(ArgumentFromXml(arg));
  58. }
  59. return new ServiceAction
  60. {
  61. Name = container.GetValue(uPnpNamespaces.svc + "name"),
  62. ArgumentList = argumentList
  63. };
  64. }
  65. private static Argument ArgumentFromXml(XElement container)
  66. {
  67. if (container == null)
  68. {
  69. throw new ArgumentNullException("container");
  70. }
  71. return new Argument
  72. {
  73. Name = container.GetValue(uPnpNamespaces.svc + "name"),
  74. Direction = container.GetValue(uPnpNamespaces.svc + "direction"),
  75. RelatedStateVariable = container.GetValue(uPnpNamespaces.svc + "relatedStateVariable")
  76. };
  77. }
  78. public static StateVariable FromXml(XElement container)
  79. {
  80. var allowedValues = new List<string>();
  81. var element = container.Descendants(uPnpNamespaces.svc + "allowedValueList")
  82. .FirstOrDefault();
  83. if (element != null)
  84. {
  85. var values = element.Descendants(uPnpNamespaces.svc + "allowedValue");
  86. allowedValues.AddRange(values.Select(child => child.Value));
  87. }
  88. return new StateVariable
  89. {
  90. Name = container.GetValue(uPnpNamespaces.svc + "name"),
  91. DataType = container.GetValue(uPnpNamespaces.svc + "dataType"),
  92. AllowedValues = allowedValues
  93. };
  94. }
  95. public string BuildPost(ServiceAction action, string xmlNamespace)
  96. {
  97. var stateString = string.Empty;
  98. foreach (var arg in action.ArgumentList)
  99. {
  100. if (arg.Direction == "out")
  101. continue;
  102. if (arg.Name == "InstanceID")
  103. stateString += BuildArgumentXml(arg, "0");
  104. else
  105. stateString += BuildArgumentXml(arg, null);
  106. }
  107. return string.Format(CommandBase, action.Name, xmlNamespace, stateString);
  108. }
  109. public string BuildPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "")
  110. {
  111. var stateString = string.Empty;
  112. foreach (var arg in action.ArgumentList)
  113. {
  114. if (arg.Direction == "out")
  115. continue;
  116. if (arg.Name == "InstanceID")
  117. stateString += BuildArgumentXml(arg, "0");
  118. else
  119. stateString += BuildArgumentXml(arg, value.ToString(), commandParameter);
  120. }
  121. return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
  122. }
  123. public string BuildSearchPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "")
  124. {
  125. var stateString = string.Empty;
  126. foreach (var arg in action.ArgumentList)
  127. {
  128. if (arg.Direction == "out")
  129. continue;
  130. if (arg.Name == "ObjectID")
  131. stateString += BuildArgumentXml(arg, value.ToString());
  132. else if (arg.Name == "Filter")
  133. stateString += BuildArgumentXml(arg, "*");
  134. else if (arg.Name == "StartingIndex")
  135. stateString += BuildArgumentXml(arg, "0");
  136. else if (arg.Name == "RequestedCount")
  137. stateString += BuildArgumentXml(arg, "200");
  138. else if (arg.Name == "BrowseFlag")
  139. stateString += BuildArgumentXml(arg, null, "BrowseDirectChildren");
  140. else if (arg.Name == "SortCriteria")
  141. stateString += BuildArgumentXml(arg, "");
  142. else
  143. stateString += BuildArgumentXml(arg, value.ToString(), commandParameter);
  144. }
  145. return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
  146. }
  147. public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary<string, string> dictionary)
  148. {
  149. var stateString = string.Empty;
  150. foreach (var arg in action.ArgumentList)
  151. {
  152. if (arg.Name == "InstanceID")
  153. stateString += BuildArgumentXml(arg, "0");
  154. else if (dictionary.ContainsKey(arg.Name))
  155. stateString += BuildArgumentXml(arg, dictionary[arg.Name]);
  156. else
  157. stateString += BuildArgumentXml(arg, value.ToString());
  158. }
  159. return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
  160. }
  161. private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
  162. {
  163. var state = StateVariables.FirstOrDefault(a => a.Name == argument.RelatedStateVariable);
  164. if (state != null)
  165. {
  166. var sendValue = (state.AllowedValues.FirstOrDefault(a => a == commandParameter) ??
  167. state.AllowedValues.FirstOrDefault()) ??
  168. value;
  169. return string.Format("<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}</{0}>", argument.Name, state.DataType ?? "string", sendValue);
  170. }
  171. return string.Format("<{0}>{1}</{0}>", argument.Name, value);
  172. }
  173. 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>";
  174. }
  175. }