PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/sipsorcery-core/SIPSorcery.SIP.App/SIPAssets/SIPDialPlan.cs

https://github.com/thecc4re/sipsorcery-mono
C# | 329 lines | 255 code | 38 blank | 36 comment | 27 complexity | dbdc1b55e923f0161d76ddbd09caab18 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. // ============================================================================
  2. // FileName: SIPDialPlan.cs
  3. //
  4. // Description:
  5. // Represents a user dialplan that can be passed to the SIPDialPlanEngine to process
  6. // the user's calls.
  7. //
  8. // Author(s):
  9. // Aaron Clauson
  10. //
  11. // History:
  12. // 28 Sep 2008 Aaron Clauson Created.
  13. //
  14. // License:
  15. // This software is licensed under the BSD License http://www.opensource.org/licenses/bsd-license.php
  16. //
  17. // Copyright (c) 2006-2008 Aaron Clauson (aaronc@blueface.ie), Blue Face Ltd, Dublin, Ireland (www.blueface.ie)
  18. // All rights reserved.
  19. //
  20. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that
  21. // the following conditions are met:
  22. //
  23. // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  24. // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
  25. // disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Blue Face Ltd.
  26. // nor the names of its contributors may be used to endorse or promote products derived from this software without specific
  27. // prior written permission.
  28. //
  29. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  30. // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  31. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  32. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  33. // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  34. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. // POSSIBILITY OF SUCH DAMAGE.
  36. // ============================================================================
  37. using System;
  38. using System.Collections;
  39. using System.Collections.Generic;
  40. using System.ComponentModel;
  41. using System.Net;
  42. using System.Net.Sockets;
  43. using System.Runtime.Serialization;
  44. using System.Text.RegularExpressions;
  45. using System.Threading;
  46. using System.Xml;
  47. using System.Xml.Serialization;
  48. using SIPSorcery.Persistence;
  49. using SIPSorcery.Sys;
  50. using log4net;
  51. #if !SILVERLIGHT
  52. using System.Data;
  53. using System.Data.Linq;
  54. using System.Data.Linq.Mapping;
  55. #endif
  56. #if UNITTEST
  57. using NUnit.Framework;
  58. #endif
  59. namespace SIPSorcery.SIP.App
  60. {
  61. [Table(Name = "sipdialplans")]
  62. [DataContractAttribute]
  63. public class SIPDialPlan : INotifyPropertyChanged, ISIPAsset
  64. {
  65. public const string XML_DOCUMENT_ELEMENT_NAME = "sipdialplans";
  66. public const string XML_ELEMENT_NAME = "sipdialplan";
  67. public const string DEFAULT_DIALPLAN_NAME = "default"; // The default name a dialplan will be assigned if the owner's first dialplan and the name is not set.
  68. public const int DEFAULT_MAXIMUM_EXECUTION_COUNT = 3; // The default value for the maximum allowed simultaneous executions of a dial plan.
  69. public const string ALL_APPS_AUTHORISED = "*"; // Used in the priviled application authorisation field when the dialplan is authorised for all applications.
  70. public const string PROPERTY_EXECUTIONCOUNT_NAME = "ExecutionCount";
  71. private static string m_newLine = AppState.NewLine;
  72. private ILog logger = AppState.logger;
  73. public static int TimeZoneOffsetMinutes;
  74. private Guid m_id; // Dial plan id used by the system. This is the database primary key and is not important for XML.
  75. [Column(Name = "id", DbType = "varchar(36)", IsPrimaryKey = true, CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  76. [DataMember]
  77. public Guid Id
  78. {
  79. get { return m_id; }
  80. set { m_id = value; }
  81. }
  82. private string m_owner; // The username of the dialplan owner.
  83. [Column(Name = "owner", DbType = "varchar(32)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  84. [DataMember]
  85. public string Owner
  86. {
  87. get { return m_owner; }
  88. set
  89. {
  90. m_owner = value;
  91. NotifyPropertyChanged("Owner");
  92. }
  93. }
  94. [Column(Name = "adminmemberid", DbType = "varchar(32)", CanBeNull = true, UpdateCheck = UpdateCheck.Never)]
  95. public string AdminMemberId { get; set; } // If set it designates this asset as a belonging to a user with the matching adminid.
  96. private string m_dialPlanName; // The name of the dialplan assigned by the owner, owner/name combinations must be unique
  97. [Column(Name = "dialplanname", DbType = "varchar(64)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  98. [DataMember]
  99. public string DialPlanName {
  100. get { return m_dialPlanName; }
  101. set {
  102. m_dialPlanName = value;
  103. NotifyPropertyChanged("DialPlanName");
  104. }
  105. }
  106. private string m_traceEmailAddress; // Optional email address to send dialplan traces to. if empty traces will not be used.
  107. [Column(Name = "traceemailaddress", DbType = "varchar(256)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  108. [DataMember]
  109. public string TraceEmailAddress
  110. {
  111. get { return m_traceEmailAddress; }
  112. set
  113. {
  114. m_traceEmailAddress = value;
  115. NotifyPropertyChanged("TraceEmailAddress");
  116. }
  117. }
  118. private string m_dialPlanScript; // The string representing the dialplan script (or asterisk extension lines).
  119. [Column(Name = "dialplanscript", DbType = "varchar(8000)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  120. [DataMember]
  121. public string DialPlanScript
  122. {
  123. get { return m_dialPlanScript; }
  124. set
  125. {
  126. m_dialPlanScript = value;
  127. NotifyPropertyChanged("DialPlanScript");
  128. }
  129. }
  130. private string m_scriptTypeDescription; // Silverlight can't handle enum types across WCF boundaries.
  131. [Column(Name = "scripttypedescription", DbType = "varchar(12)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  132. [DataMember]
  133. public string ScriptTypeDescription
  134. {
  135. get { return m_scriptTypeDescription; }
  136. set
  137. {
  138. m_scriptTypeDescription = value;
  139. NotifyPropertyChanged("ScriptTypeDescription");
  140. }
  141. }
  142. public SIPDialPlanScriptTypesEnum ScriptType
  143. {
  144. get { return SIPDialPlanScriptTypes.GetSIPDialPlanScriptType(m_scriptTypeDescription); }
  145. }
  146. private DateTimeOffset m_lastUpdate;
  147. [Column(Name = "lastupdate", DbType = "datetimeoffset", CanBeNull = true, UpdateCheck = UpdateCheck.Never)]
  148. [DataMember]
  149. public DateTimeOffset LastUpdate
  150. {
  151. get { return m_lastUpdate; }
  152. set
  153. {
  154. m_lastUpdate = value.ToUniversalTime();
  155. NotifyPropertyChanged("LastUpdate");
  156. }
  157. }
  158. public DateTimeOffset LastUpdateLocal {
  159. get { return LastUpdate.AddMinutes(TimeZoneOffsetMinutes); }
  160. }
  161. private DateTimeOffset m_inserted;
  162. [Column(Name = "inserted", DbType = "datetimeoffset", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  163. [DataMember]
  164. public DateTimeOffset Inserted {
  165. get { return m_inserted; }
  166. set { m_inserted = value.ToUniversalTime(); }
  167. }
  168. public DateTimeOffset InsertedLocal {
  169. get { return Inserted.AddMinutes(TimeZoneOffsetMinutes); }
  170. }
  171. private int m_maxExecutionCount = DEFAULT_MAXIMUM_EXECUTION_COUNT;
  172. [DataMember]
  173. [Column(Name = "maxexecutioncount", DbType = "int", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  174. public int MaxExecutionCount
  175. {
  176. get { return m_maxExecutionCount; }
  177. set { m_maxExecutionCount = value;}
  178. }
  179. private int m_executionCount;
  180. [DataMember]
  181. [Column(Name = "executioncount", DbType = "int", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  182. public int ExecutionCount
  183. {
  184. get { return m_executionCount; }
  185. set { m_executionCount = value; }
  186. }
  187. private string m_authorisedApps; // A semi-colon delimited list of privileged apps that this dialplan is authorised to use.
  188. [DataMember]
  189. [Column(Name = "authorisedapps", DbType = "varchar(2048)", CanBeNull = true, UpdateCheck = UpdateCheck.Never)]
  190. public string AuthorisedApps {
  191. get { return m_authorisedApps; }
  192. set {
  193. m_authorisedApps = value;
  194. NotifyPropertyChanged("AuthorisedApps");
  195. }
  196. }
  197. public event PropertyChangedEventHandler PropertyChanged;
  198. public SIPDialPlan() { }
  199. public SIPDialPlan(string owner, string dialPlanName, string traceEmailAddress, string script, SIPDialPlanScriptTypesEnum scriptType)
  200. {
  201. m_id = Guid.NewGuid();
  202. m_owner = owner;
  203. m_dialPlanName = (dialPlanName != null && dialPlanName.Trim().Length > 0) ? dialPlanName : DEFAULT_DIALPLAN_NAME;
  204. m_traceEmailAddress = traceEmailAddress;
  205. m_dialPlanScript = script;
  206. m_scriptTypeDescription = scriptType.ToString();
  207. Inserted = DateTimeOffset.UtcNow;
  208. LastUpdate = DateTimeOffset.UtcNow;
  209. }
  210. #if !SILVERLIGHT
  211. public SIPDialPlan(DataRow dialPlanRow) {
  212. Load(dialPlanRow);
  213. }
  214. public DataTable GetTable() {
  215. DataTable table = new DataTable();
  216. table.Columns.Add(new DataColumn("id", typeof(String)));
  217. table.Columns.Add(new DataColumn("owner", typeof(String)));
  218. table.Columns.Add(new DataColumn("adminmemberid", typeof(String)));
  219. table.Columns.Add(new DataColumn("dialplanname", typeof(String)));
  220. table.Columns.Add(new DataColumn("dialplanscript", typeof(String)));
  221. table.Columns.Add(new DataColumn("scripttypedescription", typeof(String)));
  222. table.Columns.Add(new DataColumn("traceemailaddress", typeof(String)));
  223. table.Columns.Add(new DataColumn("maxexecutioncount", typeof(Int32)));
  224. table.Columns.Add(new DataColumn("executioncount", typeof(Int32)));
  225. table.Columns.Add(new DataColumn("authorisedapps", typeof(String)));
  226. table.Columns.Add(new DataColumn("inserted", typeof(DateTimeOffset)));
  227. table.Columns.Add(new DataColumn("lastupdate", typeof(DateTimeOffset)));
  228. return table;
  229. }
  230. public void Load(DataRow dialPlanRow) {
  231. try {
  232. m_id = (dialPlanRow.Table.Columns.Contains("id") && dialPlanRow["id"] != null) ? new Guid(dialPlanRow["id"] as string) : Guid.NewGuid();
  233. m_owner = dialPlanRow["owner"] as string;
  234. AdminMemberId = (dialPlanRow.Table.Columns.Contains("adminmemberid") && dialPlanRow["adminmemberid"] != null) ? dialPlanRow["adminmemberid"] as string : null;
  235. m_dialPlanName = (dialPlanRow["dialplanname"] != null && dialPlanRow["dialplanname"].ToString().Trim().Length > 0) ? dialPlanRow["dialplanname"].ToString().Trim() : null;
  236. m_traceEmailAddress = (dialPlanRow.Table.Columns.Contains("traceemailaddress") && dialPlanRow["traceemailaddress"] != null) ? dialPlanRow["traceemailaddress"] as string : null;
  237. m_dialPlanScript = (dialPlanRow["dialplanscript"] as string).Trim();
  238. m_scriptTypeDescription = (dialPlanRow.Table.Columns.Contains("scripttypedescription") && dialPlanRow["scripttypedescription"] != null) ? SIPDialPlanScriptTypes.GetSIPDialPlanScriptType(dialPlanRow["scripttypedescription"] as string).ToString() : SIPDialPlanScriptTypesEnum.Ruby.ToString();
  239. m_maxExecutionCount = (dialPlanRow.Table.Columns.Contains("maxexecutioncount") && dialPlanRow["maxexecutioncount"] != null) ? Convert.ToInt32(dialPlanRow["maxexecutioncount"]) : DEFAULT_MAXIMUM_EXECUTION_COUNT;
  240. m_executionCount = (dialPlanRow.Table.Columns.Contains("executioncount") && dialPlanRow["executioncount"] != null) ? Convert.ToInt32(dialPlanRow["executioncount"]) : DEFAULT_MAXIMUM_EXECUTION_COUNT;
  241. m_authorisedApps = (dialPlanRow.Table.Columns.Contains("authorisedapps") && dialPlanRow["authorisedapps"] != null) ? dialPlanRow["authorisedapps"] as string : null;
  242. Inserted = (dialPlanRow.Table.Columns.Contains("inserted")&& dialPlanRow["inserted"] != null && dialPlanRow["inserted"] != DBNull.Value) ? DateTimeOffset.Parse(dialPlanRow["inserted"] as string) : DateTimeOffset.UtcNow;
  243. LastUpdate = (dialPlanRow.Table.Columns.Contains("lastupdate") && dialPlanRow["lastupdate"] != null && dialPlanRow["lastupdate"] != DBNull.Value) ? DateTimeOffset.Parse(dialPlanRow["lastupdate"] as string) : DateTimeOffset.UtcNow;
  244. }
  245. catch (Exception excp) {
  246. logger.Error("Exception DialPlan Load. " + excp);
  247. throw excp;
  248. }
  249. }
  250. public Dictionary<Guid, object> Load(XmlDocument dom) {
  251. return SIPAssetXMLPersistor<SIPDialPlan>.LoadAssetsFromXMLRecordSet(dom);
  252. }
  253. #endif
  254. public string ToXML()
  255. {
  256. string dialPlanXML =
  257. " <" + XML_ELEMENT_NAME + ">" + m_newLine +
  258. ToXMLNoParent() +
  259. " </" + XML_ELEMENT_NAME + ">" + m_newLine;
  260. return dialPlanXML;
  261. }
  262. public string ToXMLNoParent()
  263. {
  264. string dialPlanXML =
  265. " <id>" + m_id + "</id>" + m_newLine +
  266. " <owner>" + m_owner + "</owner>" + m_newLine +
  267. " <adminmemberid>" + AdminMemberId + "</adminmemberid>" + m_newLine +
  268. " <dialplanname>" + m_dialPlanName + "</dialplanname>" + m_newLine +
  269. " <traceemailaddress>" + m_traceEmailAddress + "</traceemailaddress>" + m_newLine +
  270. " <dialplanscript><![CDATA[" + m_dialPlanScript + "]]></dialplanscript>" + m_newLine +
  271. " <scripttype>" + m_scriptTypeDescription + "</scripttype>" + m_newLine +
  272. " <maxexecutioncount>" + m_maxExecutionCount + "</maxexecutioncount>" + m_newLine +
  273. " <executioncount>" + m_executionCount + "</executioncount>" + m_newLine +
  274. " <authorisedapps>" + m_authorisedApps + "</authorisedapps>" + m_newLine +
  275. " <inserted>" + m_inserted.ToString("o") + "</inserted>" + m_newLine +
  276. " <lastupdate>" + m_lastUpdate.ToString("o") + "</lastupdate>" + m_newLine;
  277. return dialPlanXML;
  278. }
  279. public string GetXMLElementName() {
  280. return XML_ELEMENT_NAME;
  281. }
  282. public string GetXMLDocumentElementName() {
  283. return XML_DOCUMENT_ELEMENT_NAME;
  284. }
  285. private void NotifyPropertyChanged(string propertyName) {
  286. if (PropertyChanged != null) {
  287. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  288. }
  289. }
  290. }
  291. }