/// *************************************************************************** /// This file and its related files are protected by copyright and intellectual /// property disclaimers. Use of it by you or your organisation must be covered /// by prior agreement, and may involve NDA and other restriction. Duplication, /// distribution or disclosure of any part of this file are likely prohibited, /// and violations of the licensing terms will be pursued by law. /// *************************************************************************** /// Further details of the stock LothianProductionsCommon usage agreement are /// available at: http://www.lothianproductions.co.uk/lpc/#license /// *************************************************************************** using System; using System.Collections.Generic; using System.Configuration; using System.Net; using System.Text; using System.Threading; using LothianProductions.Util; using LothianProductions.Util.Http; using LothianProductions.VoIP.Monitor; using LothianProductions.VoIP.State; namespace LothianProductions.VoIP.Monitor { /// /// The abstract web device monitor is a specific abstract implementation /// of the device monitor for devices that expose data over an HTTP or HTTPS /// interface. /// /// As well as providing a framework for updating a Device as in the superclass /// it also uses Device, Line and Property change objects to allow reporting of /// non-standard of device specific data and changes. /// public abstract class AbstractWebDeviceMonitor : DeviceMonitor { public override void Run() { int sleepTime = Int32.Parse( GetConfigurationValue( "PollInterval" ) ); String hostname = GetConfigurationValue( "Hostname" ); WebClient webClient = new WebClient(); webClient.Headers.Add( "User-Agent", "HVoIPM / " + this.GetType().Name ); if( GetConfigurationValue( "Username" ) != "" || GetConfigurationValue( "Password" ) != "" ) webClient.Credentials = new NetworkCredential( GetConfigurationValue( "Username" ), GetConfigurationValue( "Password" ) ); while( true ) { // Lock to prevent recursion synchronicity problems // caused by slow wgetting. lock (this) { String page; try { page = new UTF8Encoding().GetString( webClient.DownloadData( hostname ) ); } catch (WebException e) { if( e.Status == WebExceptionStatus.ProtocolError ) if( ( (HttpWebResponse) e.Response ).StatusCode == HttpStatusCode.Unauthorized ) throw new DeviceAccessUnauthorizedException( "Not authorized to request \"" + hostname + "\"; perhaps username and password are incorrect?", e ); throw new DeviceNotRespondingException( "The device \"" + hostname + "\" is not responding to status requests", e ); } IList deviceChanges = new List(); IList lineChanges = new List(); IList callChanges = new List(); AnalyseDevice( page, deviceChanges, lineChanges, callChanges ); if( deviceChanges.Count > 0 || lineChanges.Count > 0 || callChanges.Count > 0 ) StateManager.Instance().DeviceUpdated( this, deviceChanges, lineChanges, callChanges ); } Thread.Sleep( sleepTime ); } } protected abstract void AnalyseDevice( String page, IList deviceChanges, IList lineChanges, IList callChanges ); protected abstract void AnalyseLine( String page, Line line, IList lineChanges, IList callChanges ); protected abstract void AnalyseCall( String page, Call call, Line line, IList callChanges ); public static long ParseInt64( String parse ) { long value = 0L; try { if( parse != null && parse != "" ) value = Int64.Parse( parse ); } catch (FormatException) { // Safe to do nothing. } return value; } /// /// Simple string to enumeration mapping, calling the config file for lookups. /// public virtual CallType GetCallType( String type ) { String mapping = ConfigurationManager.AppSettings[ this.GetType().Name + ":CallType:" + type ]; if( mapping != null ) try { return (CallType) Enum.Parse( typeof(CallType), mapping ); } catch (ArgumentException) { } throw new DeviceConfigurationException( "CallType \"" + type + "\" incorrectly mapped to \"" + mapping + "\". Perhaps a configuration entry is missing?" ); } /// /// Simple string to enumeration mapping, calling the config file for lookups. /// public virtual Tone GetTone( String tone ) { String mapping = ConfigurationManager.AppSettings[ this.GetType().Name + ":Tone:" + tone ]; if( mapping != null ) try { return (Tone) Enum.Parse( typeof(Tone), mapping ); } catch (ArgumentException) { } throw new DeviceConfigurationException( "Tone \"" + tone + "\" incorrectly mapped to \"" + mapping + "\". Perhaps a configuration entry is missing?" ); } /// /// Simple string to enumeration mapping, calling the config file for lookups. /// public virtual Activity GetActivity( String activity ) { String mapping = ConfigurationManager.AppSettings[ this.GetType().Name + ":Activity:" + activity ]; if( mapping != null ) try { return (Activity) Enum.Parse( typeof(Activity), mapping ); } catch (ArgumentException) { } throw new DeviceConfigurationException( "Activity \"" + activity + "\" incorrectly mapped to \"" + mapping + "\". Perhaps a configuration entry is missing?" ); } /// /// Simple string to enumeration mapping, calling the config file for lookups. /// public virtual RegistrationState GetRegistrationState( String state ) { String mapping = ConfigurationManager.AppSettings[ this.GetType().Name + ":RegistrationState:" + state ]; if( mapping != null ) try { return (RegistrationState) Enum.Parse( typeof(RegistrationState), mapping ); } catch (ArgumentException) { } throw new DeviceConfigurationException( "Registration state \"" + state + "\" incorrectly mapped to \"" + mapping + "\". Perhaps a configuration entry is missing?" ); } } }