From: <gre...@us...> - 2007-12-23 20:11:04
|
Revision: 1169 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=1169&view=rev Author: gregorvsf Date: 2007-12-23 12:10:59 -0800 (Sun, 23 Dec 2007) Log Message: ----------- Added Paths: ----------- trunk/plugins/AsteriskCallerID/ trunk/plugins/AsteriskCallerID/ACID/ trunk/plugins/AsteriskCallerID/ACID/ACID.csproj trunk/plugins/AsteriskCallerID/ACID/ACID.csproj.user trunk/plugins/AsteriskCallerID/ACID/AsteriskCID.cs trunk/plugins/AsteriskCallerID/ACID/Call.cs trunk/plugins/AsteriskCallerID/ACID/CallWatch.cs trunk/plugins/AsteriskCallerID/ACID/Properties/ trunk/plugins/AsteriskCallerID/ACID/Properties/AssemblyInfo.cs trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCID.png trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCIDDisabled.png trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.Designer.cs trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.resx trunk/plugins/AsteriskCallerID/ACID/Properties/asterisk_logo.png trunk/plugins/AsteriskCallerID/ACID/frmConfig.cs trunk/plugins/AsteriskCallerID/ACID/frmConfig.designer.cs trunk/plugins/AsteriskCallerID/ACID/frmConfig.resx trunk/plugins/AsteriskCallerID/ACID.sln trunk/plugins/AsteriskCallerID/ACID.suo trunk/plugins/AsteriskCallerID/References/ trunk/plugins/AsteriskCallerID/References/Asterisk.NET.dll Added: trunk/plugins/AsteriskCallerID/ACID/ACID.csproj =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/ACID.csproj (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/ACID.csproj 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,151 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.21022</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{2E40473B-F2A8-4B8C-A094-10DA0857682A}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>AsteriskCID</RootNamespace> + <AssemblyName>ACID</AssemblyName> + <FileUpgradeFlags> + </FileUpgradeFlags> + <OldToolsVersion>2.0</OldToolsVersion> + <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> + <UpgradeBackupLocation> + </UpgradeBackupLocation> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Asterisk.NET, Version=1.0.0.14, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\Asterisk.NET.dll</HintPath> + </Reference> + <Reference Include="Bass.Net, Version=2.3.1.2, Culture=neutral, PublicKeyToken=b7566c273e6ef480, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\Bass.Net.dll</HintPath> + </Reference> + <Reference Include="Core, Version=0.2.3.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\Core.dll</HintPath> + </Reference> + <Reference Include="Dialogs, Version=0.2.3.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\Dialogs.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + <Reference Include="Utils, Version=2.2.2.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\Utils.dll</HintPath> + </Reference> + <Reference Include="WindowPlugins, Version=0.2.3.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\References\WindowPlugins.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Call.cs" /> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="AsteriskCID.cs" /> + <Compile Include="CallWatch.cs" /> + <Compile Include="frmConfig.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="frmConfig.designer.cs"> + <DependentUpon>frmConfig.cs</DependentUpon> + </Compile> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Properties\AsteriskCID.png" /> + <EmbeddedResource Include="Properties\AsteriskCIDDisabled.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Properties\Resources.resx"> + <SubType>Designer</SubType> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <EmbeddedResource Include="frmConfig.resx"> + <DependentUpon>frmConfig.cs</DependentUpon> + <SubType>Designer</SubType> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> + <Content Include="Properties\asterisk_logo.png" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> + <Visible>False</Visible> + <ProductName>.NET Framework 2.0 %28x86%29</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.0"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.0 %28x86%29</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> + <Visible>False</Visible> + <ProductName>Windows Installer 3.1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <PropertyGroup> + <PostBuildEvent> + </PostBuildEvent> + </PropertyGroup> +</Project> \ No newline at end of file Added: trunk/plugins/AsteriskCallerID/ACID/ACID.csproj.user =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/ACID.csproj.user (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/ACID.csproj.user 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,16 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <PublishUrlHistory> + </PublishUrlHistory> + <InstallUrlHistory> + </InstallUrlHistory> + <SupportUrlHistory> + </SupportUrlHistory> + <UpdateUrlHistory> + </UpdateUrlHistory> + <BootstrapperUrlHistory> + </BootstrapperUrlHistory> + <FallbackCulture>en-US</FallbackCulture> + <VerifyUploadedFiles>false</VerifyUploadedFiles> + </PropertyGroup> +</Project> \ No newline at end of file Added: trunk/plugins/AsteriskCallerID/ACID/AsteriskCID.cs =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/AsteriskCID.cs (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/AsteriskCID.cs 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,220 @@ +#region Copyright (C)2007 Sanjin Tro\x9Aelj - Troky, Gregor Verweyen - GregorV + +/* + * Copyright (C)2007 Sanjin Tro\x9Aelj - Troky, Gregor Verweyen - GregorV + * tro...@ya..., gre...@gm... + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * + * Due credit is extended to the Team Media Portal crew for their great work + * on Media Portal. Elements of this code are lifted from the Media Portal ISDN + * and YAC Caller ID modules. + * + * This plugin is provided as-is. No warranty is extended or implied. Compatibility + * with untested systems is end users responsibility. + * + */ + +#endregion +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Sockets; +using System.Threading; +using System.Windows.Forms; +using System.Xml; +using System.Text; +using MediaPortal.Configuration; +using MediaPortal.Dialogs; +using MediaPortal.GUI.Library; +using MediaPortal.Player; +using MediaPortal.Util; + +namespace AsteriskCID +{ + [PluginIcons("AsteriskCID.Properties.AsteriskCID.png", "AsteriskCID.Properties.AsteriskCIDDisabled.png")] + public class AsteriskCID : IPlugin, ISetupForm + { + #region Variables/Constants + + // plugin constants + const string _version = "0.2.1.0"; + const string _author = "Troky/GregorV"; + const string _name = "AsteriskCID"; + const string _description = "Displays Asterisk CallerId"; + public const int _configversion = 2; + static int _oldversion; + #endregion + + #region Constructors/Destructors + + public AsteriskCID() + { + } + + #endregion + + #region Settings + + public static void LoadSettings() + { + Log.Info("AsteriskCID: LoadSettings"); + + using (MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml"))) + { + _oldversion = xmlreader.GetValueAsInt("AsteriskCID", "Configversion", 0); + + if (_oldversion < 2) // upgrade/cleanup old configuration if neccessary + { + Log.Info("AsteriskCID: Upgrading configuration {0} => 2", _oldversion); + xmlreader.RemoveEntry("AsteriskCID", "fulldebug"); + xmlreader.RemoveEntry("AsteriskCID", "stopMedia"); + xmlreader.RemoveEntry("AsteriskCID", "resumeMedia"); + xmlreader.RemoveEntry("AsteriskCID", "address"); + xmlreader.RemoveEntry("AsteriskCID", "secret"); // needed to avoid Exception on base64Decode + xmlreader.RemoveEntry("AsteriskCID", "port"); + xmlreader.RemoveEntry("AsteriskCID", "username"); + xmlreader.RemoveEntry("AsteriskCID", "channel"); + } + + //Asterisk manager interface settings + CallWatch.AMIAddress = xmlreader.GetValueAsString("AsteriskCID", "Address", "192.168.0.1"); + CallWatch.AMIPort = xmlreader.GetValueAsInt("AsteriskCID", "Port", 5038); + CallWatch.AMIUsername = xmlreader.GetValueAsString("AsteriskCID", "UserName", "maint"); + CallWatch.AMISecret = CallWatch.base64Decode(xmlreader.GetValueAsString("AsteriskCID", "Secret", "")); + // Filter items + CallWatch.Channels = CallWatch.comma2newline(xmlreader.GetValueAsString("AsteriskCID", "Channels", "")); + CallWatch.Extensions = CallWatch.comma2newline(xmlreader.GetValueAsString("AsteriskCID", "Extensions", "")); + + // media settings + CallWatch.MediaStop = xmlreader.GetValueAsBool("AsteriskCID", "MediaStop", true); + CallWatch.MediaResume = xmlreader.GetValueAsBool("AsteriskCID", "MediaResume", true); + CallWatch.MediaResumeReleased = xmlreader.GetValueAsBool("AsteriskCID", "MediaResumeReleased", false ); + // misc + CallWatch.debuglevel = xmlreader.GetValueAsInt("AsteriskCID", "DebugLevel", 0); + CallWatch.RemoveLeadingDigit = xmlreader.GetValueAsBool("AsteriskCID", "RemoveLeadingDigit", false); + CallWatch.LeadingDigit = xmlreader.GetValueAsInt("AsteriskCID", "LeadingDigit", 0); + CallWatch.timeOut = xmlreader.GetValueAsInt("AsteriskCID", "NotifyTimeout", 0); + } + } + + public static void SaveSettings() + { + Log.Info("AsteriskCID: SaveSettings"); + + using (MediaPortal.Profile.Settings xmlwriter = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml"))) + { + xmlwriter.SetValue("AsteriskCID", "Configversion", _configversion); + //Asterisk manager interface settings + xmlwriter.SetValue("AsteriskCID", "Address", CallWatch.AMIAddress); + xmlwriter.SetValue("AsteriskCID", "Port", CallWatch.AMIPort); + xmlwriter.SetValue("AsteriskCID", "UserName", CallWatch.AMIUsername); + xmlwriter.SetValue("AsteriskCID", "Secret", CallWatch.base64Encode(CallWatch.AMISecret)); + // Filter items + xmlwriter.SetValue("AsteriskCID", "Channels", CallWatch.newline2comma(CallWatch.Channels)); + xmlwriter.SetValue("AsteriskCID", "Extensions", CallWatch.newline2comma(CallWatch.Extensions)); + // media settings + xmlwriter.SetValueAsBool("AsteriskCID", "MediaStop", CallWatch.MediaStop); + xmlwriter.SetValueAsBool("AsteriskCID", "MediaResume", CallWatch.MediaResume); + xmlwriter.SetValueAsBool("AsteriskCID", "MediaResumeReleased", CallWatch.MediaResumeReleased); + // misc + xmlwriter.SetValue("AsteriskCID", "DebugLevel", CallWatch.debuglevel); + xmlwriter.SetValueAsBool("AsteriskCID", "RemoveLeadingDigit", CallWatch.RemoveLeadingDigit); + xmlwriter.SetValue("AsteriskCID", "LeadingDigit", CallWatch.LeadingDigit); + xmlwriter.SetValue("AsteriskCID", "NotifyTimeout", CallWatch.timeOut); + } + } + + #endregion + + #region IPlugin Interface + + public void Start() + { + Log.Info("AsteriskCID: Plugin {0} starting.", _version); + LoadSettings(); + CallWatch.Start(); + } + + public void Stop() + { + lock (this) + { + CallWatch.ast.Logoff(); + } + Log.Info("AsteriskCID: Plugin {0} stop.", _version); + } + + #endregion + + #region ISetupForm Interface + + public bool CanEnable() + { + return true; + } + + public string Description() + { + return _description; + } + + public bool DefaultEnabled() + { + return false; + } + + public int GetWindowId() + { + return -1; + } + + public bool GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage) + { + strButtonText = null; + strButtonImage = null; + strButtonImageFocus = null; + strPictureImage = null; + return false; + } + + public string Author() + { + return _author; + } + + public string PluginName() + { + return _name; + } + + public bool HasSetup() + { + return true; + } + + public void ShowPlugin() + { + Form setup = new frmConfig(); + setup.ShowDialog(); + } + + #endregion + + } +} Added: trunk/plugins/AsteriskCallerID/ACID/Call.cs =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/Call.cs (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/Call.cs 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AsteriskCID +{ + public class Call + { + string _callid; + string _callid2; + string _callidname; + string _uniqueID; + + public Call() + { + this._callid = string.Empty; + this._callid2 = string.Empty; + this._callidname = string.Empty; + this._uniqueID = string.Empty; + } + public string ID + { + get + { + return _uniqueID; + } + set + { + _uniqueID = value; + } + } + + public string CID + { + get + { + return _callid; + } + set + { + _callid = value; + } + } + + public string CID2 + { + get + { + return _callid2; + } + set + { + _callid2 = value; + } + } + + public string Name + { + get + { + return _callidname; + } + set + { + _callidname = value; + } + } + } +} Added: trunk/plugins/AsteriskCallerID/ACID/CallWatch.cs =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/CallWatch.cs (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/CallWatch.cs 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,401 @@ +using System; +using System.Windows.Forms; +using System.Collections; +using System.Collections.Generic; +using System.Drawing.Design; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.RegularExpressions; +using System.IO; +using System.ComponentModel; +using System.Security.Cryptography; +using System.Windows.Forms.Design; +using System.Threading; + +using MediaPortal.Configuration; +using MediaPortal.Dialogs; +using MediaPortal.GUI.Library; +using MediaPortal.Player; +using MediaPortal.Util; + +using Asterisk.NET.Manager; +using Asterisk.NET.FastAGI; + +namespace AsteriskCID +{ + class CallWatch + { + #region Class Variables/Constants + + // Asterisk manager interface settings + public static string AMIAddress; // the asterisk's host address + public static int AMIPort; // AMI port (specified in asterisk config) + public static string AMIUsername; // AMI user (specified in asterisk config) + public static string AMISecret; // AMI password (specified in asterisk config) + public static string Channels = String.Empty; // Asterisk trunk info + public static string Extensions = String.Empty; // Asterisk extensions + // media settings + public static bool MediaStop = true; // stop media when an event happend + public static bool MediaResume = true; // resume media when notify is closed + public static bool MediaResumeReleased = true; // resume media when notify is closed + // misc + public static int debuglevel = 0; + public static int timeOut = -1; // autoclose the dialog after the timeout expired + public static bool RemoveLeadingDigit = false; // flag to remove or not the leading digit from CID + public static int LeadingDigit = 0; // the leading digit can be set to 0 or 9 + static string TrunkInfo = String.Empty; // used to filter multiple messages for one call + static int CallStatus = 0; + public static AsteriskManager ast=null; // Asterisk.NET interface + public static GUIDialogNotify dialogNotify; // Handle to the caller ID notification + static object tmpdlg = null; + static bool IsShown = false; // is set true while message box is open + + #endregion + + #region Threads + + [STAThread] + public static void Start() // start thread watching for Asterisk events + { + if (debuglevel >= 1) + Log.Info("AsteriskCID: Starting CallWatchThread..."); // debuglevel 2 log + // get handle for message window + dialogNotify = (GUIDialogNotify)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_NOTIFY); + Thread workerThread = new Thread(new ThreadStart(CallWatchThread)); + workerThread.Start(); + } + + static void CallWatchThread() + { + ast = new AsteriskManager(AMIAddress,AMIPort,AMIUsername,AMISecret); // AMI connection + ast.Dial += new DialEventHandler(OnDial); // event handlers for dial, hangup, establish + ast.Hangup += new HangupEventHandler(OnHangup); + ast.Link += new LinkEventHandler(OnLink); + + try + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: Asterisk login..."); // debuglevel 2 log + ast.Login(); // try login + } + catch + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: Asterisk login failed!"); // debuglevel 2 log + ast.Logoff(); // do we need to logoff here ? + return; + } + } + + static void ShowMessageThread() + { + if (g_Player.Playing && !g_Player.Paused && MediaStop) // if media is playing & not paused & Stop flag = true + { + if (debuglevel >= 2) // debuglevel 2 log + Log.Info("AsteriskCID: Pause playback"); + MediaPortal.Player.g_Player.Pause(); // pause playing media + } + CallWatch.IsShown = true; // set show flag + + dialogNotify.DoModal(GUIWindowManager.ActiveWindow); // show Notify Window + // funktion stops here, until Window is closed + if (dialogNotify.IsVisible) // by timeout or OK click or closeWindow called + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: Message is closed"); // debuglevel 2 log + if ((g_Player.Paused) && (MediaResume | MediaResumeReleased)) // if media is paused & one of the flags is set + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: Resume playback"); // debuglevel 2 log + MediaPortal.Player.g_Player.Pause(); // continue play media + CallWatch.CallStatus = 0; // set callstatus to 'no call' + CallWatch.TrunkInfo = string.Empty; // clear trunk info from last call + CallWatch.IsShown = false; // clear show flag + } + } + } + + #endregion + + #region Event and Notify handlers + + static void OnDial(object sender, Asterisk.NET.Manager.Event.DialEvent e) // this event can be fired multiple times for a call + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: OnDial() event"); // debuglevel 2 log + if (CallWatch.CheckFilter(e.Src, Channels, Extensions, 1)) // check if event should be ignored + { + CallWatch.ShowMessage(e.CallerIdName, e.CallerId); // show message incoming call + } + } + + static void OnHangup(object sender, Asterisk.NET.Manager.Event.HangupEvent e) // for each dial event we will receive a hangup + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: OnHangup() event"); // debuglevel 2 log + if (CallWatch.CheckFilter(e.Channel, Channels, Extensions, 0)) // check if event should be ignored + { + CallWatch.ClearMessage(); // delete message box + } + } + + static void OnLink(object sender, Asterisk.NET.Manager.Event.LinkEvent e) // this should occur only once + { + string notifyText = GUILocalizeStrings.Get(909); // 909="Connecting..." (from strings_[country].xml + + if (debuglevel >= 2) + Log.Info("AsteriskCID: OnLink() event"); // debuglevel 2 log + if (CallWatch.CheckFilter(e.Channel1, Channels, Extensions, 2)) // check if event should be ignored + { + if (CallWatch.IsShown) // it only changes the message if it is currently shown + { + dialogNotify.SetText("\n" + notifyText + "\n" + e.CallerId2 + "\n\n"); // change notification text (extension that answered) + if (!CallWatch.MediaResumeReleased) // wait for hangup before closing & media resume + { // otherwise, if flag not set + Thread.Sleep(3000); // close message box after 3 seconds + CallWatch.ClearMessage(); // + } + } + } + } + + #endregion + + #region Message functions + + private static void ShowMessage(string CIDname, string CID) // pop up the message box + { + string notifyHeading = GUILocalizeStrings.Get(1023); // 1023="Incoming call" (from strings_[country].xml + string notifyText = String.Empty; // message text + string notifyImage = GetCallerImage(CIDname); // image (CIDname.jpg from \MediaPortal\thumbs\yac) + if (IsShown) // only do something if dialog is not open + return; + // if RemoveDigit is true and the first digit is + // equal to the configured digit + if ((RemoveLeadingDigit) && (string.Compare(Convert.ToString(LeadingDigit),0,CID,0,1) == 0)) + CID = CID.Substring (1); // remove frist char from CID + + if (dialogNotify != null) // if we have a valid window handle + { + if ((!string.IsNullOrEmpty(CIDname)) && (CIDname.ToLower() != "<unknown>")) // if there is a real caller name (from asterisk phonebook) + { + if (string.Compare("NA", 0, CIDname, 0, 2) == 0) // this is needed if Asterisk delivers "NA phonenumber" + notifyText = CIDname + "\n\n"; // for calls where the name cannot be found - show name only + else + notifyText = CIDname + "\n" + CID + "\n"; // show name and CID + } else + { + notifyText = CID + "\n\n"; // otherwise only the CID + } + if (debuglevel >= 3) + Log.Info("AsteriskCID: Notfiy Image=" + notifyImage); // debuglevel 3 log (show path for requested image) + + dialogNotify.SetHeading(notifyHeading); // set message box properties + dialogNotify.SetText(notifyText); + dialogNotify.SetImage(notifyImage); + dialogNotify.TimeOut = timeOut; + // check Mediaportal window is active + GUIWindow m_pParentWindow = GUIWindowManager.GetWindow(GUIWindowManager.ActiveWindow); + if (null == m_pParentWindow) + { + if (debuglevel >= 3) + Log.Info("AsteriskCID: m_pParentWIndow is null!"); // debuglevel 3 log error + return; + } + if (debuglevel >= 2) + Log.Info("AsteriskCID: ShowMessage(" + CIDname + ", " + CID + ")"); // debuglevel 2 log, message details + + tmpdlg = dialogNotify; + Thread showDialogThread = new Thread(new ThreadStart(ShowMessageThread)); // + showDialogThread.Start(); // pop up message box + } + } + + private static void ClearMessage() // close message box + { + if (debuglevel >= 3) + Log.Info("AsteriskCID: ClearMessage()"); // debuglevel 3 + // + Action closeTheWindow = new Action(Action.ActionType.ACTION_CLOSE_DIALOG, 0, 0); + dialogNotify.OnAction(closeTheWindow); // close box, this causes + } // ShowMessageThread()beeing called + + #endregion + + #region Helper functions + + public static bool CheckAsteriskConnection() // can we establish connection to Asterisk ? + { + bool b = false; + ast = new AsteriskManager(AMIAddress, AMIPort, AMIUsername, AMISecret); // connection object + try + { + ast.Login(); // try Asterisk AMI login + b = true; + } catch + { + b = false; + } + ast.Logoff(); // logoff & return success/fail + return b; + } + // here we check if we need to do something + private static bool CheckFilter(string str, string strChan, string strExts, int NewCallStatus) + { + if (CallStatus == NewCallStatus) // if Callstatus did not change, skip event. + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: skip event, CallStatus = " + CallStatus); // debuglevel 2 log + return false; + } + if ((CallStatus == 0) && (NewCallStatus != 1)) // if status is 0 and new status is not "dialed" + { // ignore further events for that call + if (debuglevel >= 2) + Log.Info("AsteriskCID: skip event, Message box is not open"); // debuglevel 2 log + return false; + } + string[] Efilters = Regex.Split(strExts, Environment.NewLine); // load all extensions into the Efiters list + if ((Efilters.GetUpperBound(0) == 0) && (debuglevel >= 3)) // if no extensions, debuglevel 3 log + Log.Info("AsteriskCID: no Extension configured " + str + " OK"); + foreach (string Efilter in Efilters) // search through the list + { + Regex r = new Regex(Efilter); // check extension, if a list item matches + if (r.IsMatch(str)) // then we need to do nothing + { + if (debuglevel >= 3) + Log.Info("AsteriskCID: skip event, Extension(" + Efilter + ") found:" + str); // debuglevel 3 log + return false; // return false + } + } + + if (string.IsNullOrEmpty(TrunkInfo)) // we store the trunk info for a new call + TrunkInfo = str; + if (TrunkInfo != str) // return false if different trunk info for same call + { + if (debuglevel >= 3) + Log.Info("AsteriskCID: skip event, different Trunk(" + str + ")"); // debuglevel 3 log + return false; // return false + } + + string[] Cfilters = Regex.Split(strChan, Environment.NewLine); // load all trunks into the Cfiters list + if (Cfilters.GetUpperBound(0) == 0) // if no trunks configured + { + if (debuglevel >= 3) + Log.Info("AsteriskCID: no Trunks/Channels configured " + str + " OK"); + CallStatus = NewCallStatus; // update CallStatus + return true; // no filter check required, return success + } + foreach (string Cfilter in Cfilters) // search through the list + { + Regex r = new Regex(Cfilter); + if (r.IsMatch(str)) // check trunk, if a list item matches + { + if (debuglevel >= 2) + Log.Info("AsteriskCID: Filter (" + Cfilter + ") MATCH: " + str); // debuglevel 2 log + CallStatus = NewCallStatus; // update CallStatus + return true; // trunk found, return success + } + else + { + if (debuglevel >= 3) // debuglevel 3 log + Log.Info("AsteriskCID: Filter (" + Cfilter + ") noMatch:" + str); + } + } // trunk not found, return false + if (debuglevel >= 2) + Log.Info("AsteriskCID: skip event, Trunk (" + str + ") not found"); + return false; + } + + private static string GetCallerImage(string name) // get image (CIDname.jpg from \MediaPortal\thumbs\yac) + { + if (string.Compare("NA", 0, name, 0, 2) == 0) // this is for a specific Asterisk setup. If the + name = "NA"; // caller name is not in the phonebook and also cannot + // be retrieved from the web, then the name is set to + // "NA phonenumber", so we look for an image NA.jpg + + if ((name == "<unknown>") || (name == "XX")) // for standard configuration and if anomymous calls + name = "unknown"; // set the name to "XX" we look for image unknown.jpg + string strImage = MediaPortal.Util.Utils.GetCoverArtName(Thumbs.Yac, name); // get image path + if (File.Exists(strImage)) // if the image file exists + return strImage; // return the image path + else + return string.Empty; // otherwise an empty string + } + + + public static string base64Encode(string data) + { + try + { + byte[] encData_byte = new byte[data.Length]; + encData_byte = System.Text.Encoding.UTF8.GetBytes(data); + string encodedData = Convert.ToBase64String(encData_byte); + return encodedData; + } + catch (Exception e) + { + throw new Exception("Error in base64Encode" + e.Message); + } + } + + public static string base64Decode(string data) + { + try + { + System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); + System.Text.Decoder utf8Decode = encoder.GetDecoder(); + + byte[] todecode_byte = Convert.FromBase64String(data); + int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length); + char[] decoded_char = new char[charCount]; + utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0); + string result = new String(decoded_char); + return result; + } + catch (Exception e) + { + throw new Exception("Error in base64Decode" + e.Message); + } + } + + public static string newline2comma(string data) + { + bool first_item = true; + string result = string.Empty ; + string[] items = Regex.Split(data, Environment.NewLine); + foreach (string item in items) + { + if (first_item) + { + result = item; + first_item = false; + } + else + result = result + ", " + item; + } + return result; + } + + public static string comma2newline(string data) + { + bool first_item = true; + string result = string.Empty; + string[] items = Regex.Split(data, ", "); + foreach (string item in items) + { + if (first_item) + { + result = item; + first_item = false; + } + else + result = result + Environment.NewLine + item; + } + return result; + } + + #endregion + + } +} Added: trunk/plugins/AsteriskCallerID/ACID/Properties/AssemblyInfo.cs =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/Properties/AssemblyInfo.cs (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/Properties/AssemblyInfo.cs 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ACID")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("---")] +[assembly: AssemblyProduct("ACID")] +[assembly: AssemblyCopyright("Copyright © --- 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("90329926-be63-447f-86b2-9c288f02c06b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Added: trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCID.png =================================================================== (Binary files differ) Property changes on: trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCID.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCIDDisabled.png =================================================================== (Binary files differ) Property changes on: trunk/plugins/AsteriskCallerID/ACID/Properties/AsteriskCIDDisabled.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.Designer.cs =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.Designer.cs (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.Designer.cs 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:2.0.50727.832 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace AsteriskCID.Properties { + using System; + + + /// <summary> + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// </summary> + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AsteriskCID.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static System.Drawing.Bitmap asterisk_logo { + get { + object obj = ResourceManager.GetObject("asterisk_logo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap AsteriskCID { + get { + object obj = ResourceManager.GetObject("AsteriskCID", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap AsteriskCIDDisabled { + get { + object obj = ResourceManager.GetObject("AsteriskCIDDisabled", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} Added: trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.resx =================================================================== --- trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.resx (rev 0) +++ trunk/plugins/AsteriskCallerID/ACID/Properties/Resources.resx 2007-12-23 20:10:59 UTC (rev 1169) @@ -0,0 +1,784 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="AsteriskCIDDisabled" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + 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 +</value> + </data> + <data name="AsteriskCID" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + 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 + HIuaRt4AAAAASUVORK5CYII= +</value> + </data> + <data name="asterisk_logo" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + iVBORw0KGgoAAAANSUhEUgAAAN4AAADKCAYAAADKIP46AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAie1JREFUeF7tnQeY + ZGWV/lEkKgw5Dz2Y8xjWvDjmuDrGXV3DiKur+zeMqGtYw5AkDjMDIiKIQzIjIyCCiowiKqA4MEzsPDnn + 7q6u/H9/t+r0nP763qpbnVuo53mfqq6uuvfWvef9zjnvOd93H1Mul/d59PGIOwOPqfGLHzWI0TAHiPco + JuQ5eIyu23jDo7aUkk+PnqiUJ2oMB6fxRq7BHs+jtuZs7dGTMb6IN1ijjvveYzVYDDeG8/hsW49IG3xE + /ugx9F5x53swxjzchBru7Q3mN/nv/NPb5T/9DxxnJON8N2KU9Qixr7Y3nlDvePl/I7+fz/5T2ug/5Y8a + hxcrjbElGW09Yj1Ov3c8oN5x1iJlmvPzTxWaPkq8kRtR0xhTaIxJxptErP1EurTYX59tFGm3bZ9LOs5a + pIwjZJpzN6Ftd0If/Dj0bPVCyTgjC40yNN44448j0AE6H2lxoD6bhLTb4HNxx5FE1jhSxhFyMESccHY8 + 4Q74n4BsjRAtNGxPijjiHKTzkwYH63NJSPN9PpOWuP43xJEyJGR4fkIi1vKGE8aeJ8yBTjDC1QshvbF5 + YzQjTSKYJ0VInMfrHIV4gt4bLsRtP468/hhDcvrflUTIWkRMS8Jxb9fj/gAnMOFqeTYjWy2imQGbcXvD + 92Q6ROfIcKheh5ik94aKuO36/fLaH5M/Vk9O+02ekEbGNET059STMMkLjlv7HrcHNoEIV8u7xXm2kGxm + hJ5oZrhmzCGxPJEO07kyHK7XHkfo7+FCuG3+9vu2Y/IkteOOI6URMiRjSEQfEdj5nPAEfJR46VTNep0h + 3hDSkq0e0cyAMeiQWEamI/U/cJTD0XptOEavhwt+u7z2+7TjsOMyktpxh6T0hLRBJo6ISST059jOfT0P + OK5sfVwdzDj0coMhXFIYiWcLyeY9GkQzA8VgMV5PMDN0jN7IdKxeg+OqOF7PhhP0OsSJei8t4r7vt2/7 + 5NmOw47LE9OTMo6Q/O4kInpvWI+EE4qAjxIv3uMNlXBmJGnJ5onmvZiRLCQXpDACnaTXYHIVJ+vZ0KTX + HlP0d1qE3+Vv267ti2fbvx0Px2YEDUkZEpKBxZORgceIaIMSHhFvGJLQQnZfQ2wkBB1T2x/Tnetkjrf9 + D5ZwcXkbhoLBYDhxni0kGx4Nj+G9GAZsJDNyYfyQwAh0il6DJwpPcniyXoOnxOCpei8JcZ+3bfFs+2B/ + wPZvx2MENXJy3JAyjpD8XiMjA44RkXMTktCHpFbO8LVECFgrB4y7tmNmf2O243FGuuEgnBdJPOEIoyyM + NLJZXhZ6tFok8+QyQhl5nqZ9PL2KZ+gZPLOKZ+nZ49n6ux7C79i2eLbt2/7Ytx0HpA3JyXFDSk/IkIzm + GY2IaUhoXpDzXo+AtfK/MeHAmOx0ApEuTjRhZPUezsJJI5t5uJBsjOZ4NSMbxmYezXszjNSTDGPGsI1c + RirIAYGeU8Vz9Ty1iufpGTy/ihfo2eOF+jsJ4WdtGzzbdm0/7NP2z7FwTCE5jZhGSPOSnowhEfH6SST0 + oagPQz0B64WfY+79HsnES+vlLHypRzjCSe/dTBxh9PaeLSQbnsCIZp7Mk8wTDEM3QkEQyPMvVbxIzy8W + XlLFS/UMXhbg5fq7HsLv2LZs2+wHsE/bP8fCMRlBIacRE1IaIfGU/D7vHb1XtLzRQlMjIYMW59LKGGkJ + GIaf5v3GlHyPVOKFJ92HIublPOGMdIQ0oYfzhPN5m3k3DKce2fBoGCTe... [truncated message content] |