From: <an...@us...> - 2007-07-06 05:03:28
|
Revision: 675 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=675&view=rev Author: and-81 Date: 2007-07-05 22:03:26 -0700 (Thu, 05 Jul 2007) Log Message: ----------- Modified Paths: -------------- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs trunk/plugins/IR Server Suite/IR Server Suite.sln Added Paths: ----------- trunk/plugins/IR Server Suite/Applications/IR Blast/ trunk/plugins/IR Server Suite/Applications/IR Blast/IR Blast.csproj trunk/plugins/IR Server Suite/Applications/IR Blast/Program.cs trunk/plugins/IR Server Suite/Applications/IR Blast/Properties/ trunk/plugins/IR Server Suite/Applications/IR Blast/Properties/AssemblyInfo.cs Added: trunk/plugins/IR Server Suite/Applications/IR Blast/IR Blast.csproj =================================================================== --- trunk/plugins/IR Server Suite/Applications/IR Blast/IR Blast.csproj (rev 0) +++ trunk/plugins/IR Server Suite/Applications/IR Blast/IR Blast.csproj 2007-07-06 05:03:26 UTC (rev 675) @@ -0,0 +1,76 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>IRBlast</RootNamespace> + <AssemblyName>IRBlast</AssemblyName> + <ApplicationIcon> + </ApplicationIcon> + <StartupObject>IRBlast.Program</StartupObject> + <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>false</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants> + </DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\Common\irssUtils\IrssUtils.csproj"> + <Project>{CA15769C-232E-4CA7-94FD-206A06CA3ABB}</Project> + <Name>IrssUtils</Name> + </ProjectReference> + <ProjectReference Include="..\..\IPC\AppModule.InterProcessComm\AppModule.InterProcessComm.csproj"> + <Project>{E98F1F7E-40B6-44C8-AC66-EC867B141FA1}</Project> + <Name>AppModule.InterProcessComm</Name> + </ProjectReference> + <ProjectReference Include="..\..\IPC\AppModule.NamedPipes\AppModule.NamedPipes.csproj"> + <Project>{077B53BB-404A-4B2F-BA17-AAE98C5E9C66}</Project> + <Name>AppModule.NamedPipes</Name> + </ProjectReference> + <ProjectReference Include="..\..\IPC\Named Pipes\Named Pipes.csproj"> + <Project>{F4EA6055-7133-4F18-8971-E19ADEB482C1}</Project> + <Name>Named Pipes</Name> + </ProjectReference> + </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>copy "*.*" "\MediaPortal Development\Plugin Releases\IR Server Suite\$(ProjectName)\"</PostBuildEvent> + </PropertyGroup> +</Project> \ No newline at end of file Added: trunk/plugins/IR Server Suite/Applications/IR Blast/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/IR Blast/Program.cs (rev 0) +++ trunk/plugins/IR Server Suite/Applications/IR Blast/Program.cs 2007-07-06 05:03:26 UTC (rev 675) @@ -0,0 +1,538 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.IO; +using System.Text; +using System.Threading; +using System.Xml; + +using NamedPipes; +using IrssUtils; + +namespace IRBlast +{ + + static class Program + { + + #region Variables + + static bool _registered = false; + static bool _keepAlive = true; + static int _echoID = -1; + static Thread _keepAliveThread; + + static string _serverHost = null; + static string _localPipeName; + + static string _blastPort = "None"; + static string _blastSpeed = "None"; + + static bool _treatAsChannelNumber = false; + + #endregion Variables + + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main(string[] args) + { + IrssLog.LogLevel = IrssLog.Level.Debug; + IrssLog.Open(Common.FolderIrssLogs + "IR Blast.log"); + + IrssLog.Debug("Platform is {0}", (IntPtr.Size == 4 ? "32-bit" : "64-bit")); + + ShowHeader(); + + try + { + + if (args.Length > 0) // Command Line Start ... + { + List<String> irCommands = new List<string>(); + + for (int index = 0; index < args.Length; index++) + { + switch (args[index].ToLowerInvariant()) + { + case "-host": + _serverHost = args[++index]; + continue; + + case "-port": + _blastPort = args[++index]; + continue; + + case "-speed": + _blastSpeed = args[++index]; + continue; + + case "-channel": + _treatAsChannelNumber = true; + continue; + + default: + irCommands.Add(args[index]); + continue; + } + } + + if (String.IsNullOrEmpty(_serverHost) || irCommands.Count == 0) + { + Console.WriteLine("Malformed command line parameters ..."); + Console.WriteLine(); + + ShowHelp(); + } + else if (StartComms()) + { + Thread.Sleep(250); + + // Wait for registered ... Give up after 10 seconds ... + int attempt = 0; + while (!_registered) + { + if (++attempt >= 10) + break; + else + Thread.Sleep(1000); + } + + if (_registered) + { + string fileName; + foreach (String command in irCommands) + { + if (_treatAsChannelNumber) + { + Info("Processing channel: {0}", command); + foreach (char digit in command) + { + if (digit == '~') + { + Thread.Sleep(500); + } + else + { + fileName = Common.FolderIRCommands + digit + Common.FileExtensionIR; + BlastIR(fileName, _blastPort, _blastSpeed); + } + } + } + else if (command.StartsWith("~")) + { + Thread.Sleep(command.Length * 500); + } + else + { + fileName = Common.FolderIRCommands + command; + BlastIR(fileName, _blastPort, _blastSpeed); + } + } + + Thread.Sleep(500); + } + else + { + Warn("Failed to register with server host \"{0}\", blasting not sent", _serverHost); + } + + } + } + else // Give help ... + { + ShowHelp(); + } + } + catch (Exception ex) + { + Error(ex); + } + + StopComms(); + + IrssLog.Close(); + } + + static void ShowHeader() + { + Console.WriteLine(""); + Console.WriteLine("IR Blast"); + Console.WriteLine("-----------------------------------------------------------------------------"); + Console.WriteLine("Command line IR blaster for IR Server Suite."); + Console.WriteLine("By and-81."); + Console.WriteLine(""); + Console.WriteLine(""); + } + + static void ShowHelp() + { + IrssLog.Debug("Show Help"); + + Console.WriteLine("IRBlast.exe -host <server> -port [port] -speed [speed] [-channel] <commands>"); + Console.WriteLine(""); + Console.WriteLine("Use -host to specify the computer that is hosting the IR Server."); + Console.WriteLine("Use -port to blast to a particular blaster port (Optional)."); + Console.WriteLine("Use -speed to set the blaster speed (Optional)."); + Console.WriteLine("Use -channel to tell IR Blast to break apart the following IR Command and"); + Console.WriteLine(" use each digit for a separate IR blast (Optional)."); + Console.WriteLine("Use a tilde ~ between commands to insert half second pauses."); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine("Examples:"); + Console.WriteLine(""); + Console.WriteLine("IRBlast -host HTPC TV_Power.IR"); + Console.WriteLine(""); + Console.WriteLine("This would blast the TV_Power.IR command on the HTPC computer to the default"); + Console.WriteLine("blaster port at the default blaster speed."); + Console.WriteLine(""); + Console.WriteLine("IRBlast -host MEDIAPC -port Port_2 \"Turn on surround.IR\""); + Console.WriteLine(""); + Console.WriteLine("This would blast the \"Turn on surround.IR\" command on the MEDIAPC computer"); + Console.WriteLine("to blaster port 2 at the default blaster speed."); + Console.WriteLine(""); + Console.WriteLine("IRBlast -host HTPC -channel 302"); + Console.WriteLine(""); + Console.WriteLine("This would blast the 3.IR, 0.IR, and 2.IR commands on the HTPC computer to"); + Console.WriteLine("the default blaster port at the default blaster speed."); + Console.WriteLine(""); + Console.WriteLine(""); + } + + static bool StartComms() + { + try + { + if (OpenLocalPipe()) + { + _keepAliveThread = new Thread(new ThreadStart(KeepAliveThread)); + _keepAliveThread.Start(); + return true; + } + } + catch (Exception ex) + { + Error(ex); + } + + return false; + } + static void StopComms() + { + _keepAlive = false; + + try + { + if (_keepAliveThread != null && _keepAliveThread.IsAlive) + _keepAliveThread.Abort(); + } + catch { } + + try + { + if (_registered) + { + _registered = false; + + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Unregister", null); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + } + } + catch { } + + try + { + if (PipeAccess.ServerRunning) + PipeAccess.StopServer(); + } + catch { } + } + + static bool OpenLocalPipe() + { + try + { + int pipeNumber = 1; + bool retry = false; + + do + { + string localPipeTest = String.Format(Common.LocalPipeFormat, pipeNumber); + + if (PipeAccess.PipeExists(String.Format("\\\\.\\pipe\\{0}", localPipeTest))) + { + if (++pipeNumber <= Common.MaximumLocalClientCount) + retry = true; + else + throw new Exception(String.Format("Maximum local client limit ({0}) reached", Common.MaximumLocalClientCount)); + } + else + { + if (!PipeAccess.StartServer(localPipeTest, new PipeMessageHandler(ReceivedMessage))) + throw new Exception(String.Format("Failed to start local pipe server \"{0}\"", localPipeTest)); + + _localPipeName = localPipeTest; + retry = false; + } + } + while (retry); + + return true; + } + catch (Exception ex) + { + Error(ex); + return false; + } + } + + static bool ConnectToServer() + { + try + { + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Register", null); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + return true; + } + catch (AppModule.NamedPipes.NamedPipeIOException) + { + return false; + } + catch (Exception ex) + { + Error(ex); + return false; + } + } + + static void KeepAliveThread() + { + Random random = new Random((int)DateTime.Now.Ticks); + bool reconnect; + int attempt; + + _registered = false; + _keepAlive = true; + while (_keepAlive) + { + reconnect = true; + + #region Connect to server + + Info("Connecting ({0}) ...", _serverHost); + attempt = 0; + while (_keepAlive && reconnect) + { + if (ConnectToServer()) + { + reconnect = false; + } + else + { + int wait; + + if (attempt <= 50) + attempt++; + + if (attempt > 50) + wait = 30; // 30 seconds + else if (attempt > 20) + wait = 10; // 10 seconds + else if (attempt > 10) + wait = 5; // 5 seconds + else + wait = 1; // 1 second + + for (int sleeps = 0; sleeps < wait && _keepAlive; sleeps++) + Thread.Sleep(1000); + } + } + + #endregion Connect to server + + #region Wait for registered + + // Give up after 10 seconds ... + attempt = 0; + while (_keepAlive && !_registered && !reconnect) + { + if (++attempt >= 10) + reconnect = true; + else + Thread.Sleep(1000); + } + + #endregion Wait for registered + + #region Ping the server repeatedly + + while (_keepAlive && _registered && !reconnect) + { + int pingID = random.Next(); + long pingTime = DateTime.Now.Ticks; + + try + { + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Ping", BitConverter.GetBytes(pingID)); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + } + catch + { + // Failed to ping ... reconnect ... + Warn("Failed to ping, attempting to reconnect ..."); + _registered = false; + reconnect = true; + break; + } + + // Wait 10 seconds for a ping echo ... + bool receivedEcho = false; + while (_keepAlive && _registered && !reconnect && + !receivedEcho && DateTime.Now.Ticks - pingTime < 10 * 1000 * 10000) + { + if (_echoID == pingID) + { + receivedEcho = true; + } + else + { + Thread.Sleep(1000); + } + } + + if (receivedEcho) // Received ping echo ... + { + // Wait 60 seconds before re-pinging ... + for (int sleeps = 0; sleeps < 60 && _keepAlive && _registered; sleeps++) + Thread.Sleep(1000); + } + else // Didn't receive ping echo ... + { + Warn("No echo to ping, attempting to reconnect ..."); + + // Break out of pinging cycle ... + _registered = false; + reconnect = true; + } + } + + #endregion Ping the server repeatedly + + } + + } + + static void ReceivedMessage(string message) + { + PipeMessage received = PipeMessage.FromString(message); + + IrssLog.Debug("Received Message \"{0}\"", received.Name); + + try + { + switch (received.Name) + { + case "Remote Button": + break; + + case "Blast Success": + Info("Blast Success"); + break; + + case "Blast Failure": + Warn("Blast Failed!"); + break; + + case "Register Success": + { + Info("Registered to IR Server"); + _registered = true; + //_transceiverInfo = TransceiverInfo.FromBytes(received.Data); + break; + } + + case "Register Failure": + { + Warn("IR Server refused to register"); + _registered = false; + break; + } + + case "Server Shutdown": + { + Warn("IR Server Shutdown - Blasting disabled until IR Server returns"); + _registered = false; + break; + } + + case "Echo": + { + _echoID = BitConverter.ToInt32(received.Data, 0); + break; + } + + case "Error": + { + Warn(Encoding.ASCII.GetString(received.Data)); + break; + } + + default: + { + Warn("Unknown message received from server: " + received.Name); + break; + } + } + } + catch (Exception ex) + { + Error(ex); + } + } + + static void BlastIR(string fileName, string port, string speed) + { + FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); + + byte[] outData = new byte[8 + port.Length + speed.Length + file.Length]; + + BitConverter.GetBytes(port.Length).CopyTo(outData, 0); + Encoding.ASCII.GetBytes(port).CopyTo(outData, 4); + BitConverter.GetBytes(speed.Length).CopyTo(outData, 4 + port.Length); + Encoding.ASCII.GetBytes(speed).CopyTo(outData, 8 + port.Length); + + file.Read(outData, 8 + port.Length + speed.Length, (int)file.Length); + file.Close(); + + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Blast", outData); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + } + + #region Log Commands + + static void Info(string format, params object[] args) + { + string message = String.Format(format, args); + Console.WriteLine(message); + IrssLog.Info(message); + } + static void Warn(string format, params object[] args) + { + string message = String.Format(format, args); + Console.WriteLine(message); + IrssLog.Warn(message); + } + static void Error(Exception ex) + { + Console.WriteLine(ex.Message); + IrssLog.Error(ex.ToString()); + } + + #endregion Log Commands + + } + +} Added: trunk/plugins/IR Server Suite/Applications/IR Blast/Properties/AssemblyInfo.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/IR Blast/Properties/AssemblyInfo.cs (rev 0) +++ trunk/plugins/IR Server Suite/Applications/IR Blast/Properties/AssemblyInfo.cs 2007-07-06 05:03:26 UTC (rev 675) @@ -0,0 +1,39 @@ +using System; +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("IR Blast")] +[assembly: AssemblyDescription("Command line application for blasting IR commands to IR Server")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("and-81")] +[assembly: AssemblyProduct("IRBlast")] +[assembly: AssemblyCopyright("Aaron Dinnage")] +[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)] + +// +// 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.3.2")] +[assembly: AssemblyFileVersion("1.0.3.2")] + +[assembly: CLSCompliant(true)] \ No newline at end of file Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-07-05 19:08:21 UTC (rev 674) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-07-06 05:03:26 UTC (rev 675) @@ -112,7 +112,7 @@ } catch (Exception ex) { - IrssLog.Error("Error processing command line parameters: {0}", ex.Message); + IrssLog.Error("Error processing command line parameters: {0}", ex.ToString()); } if (virtualButtons.Count != 0 && StartComms()) @@ -150,8 +150,6 @@ { IrssLog.Warn("Failed to register with server host \"{0}\", custom message(s) not sent", Program.ServerHost); } - - StopComms(); } } @@ -166,15 +164,13 @@ } if (StartComms()) - { Application.Run(new MainForm()); - StopComms(); - } - SaveSettings(); } + StopComms(); + IrssLog.Close(); } @@ -401,13 +397,6 @@ #endregion Wait for registered - #region Registered ... - - if (_keepAlive && _registered && !reconnect) - IrssLog.Info("Connected ({0})", _serverHost); - - #endregion Registered ... - #region Ping the server repeatedly while (_keepAlive && _registered && !reconnect) @@ -496,7 +485,7 @@ case "Server Shutdown": { - IrssLog.Warn("IR Server Shutdown - Tray Launcher disabled until IR Server returns"); + IrssLog.Warn("IR Server Shutdown - Virtual Remote disabled until IR Server returns"); _registered = false; break; } Modified: trunk/plugins/IR Server Suite/IR Server Suite.sln =================================================================== --- trunk/plugins/IR Server Suite/IR Server Suite.sln 2007-07-05 19:08:21 UTC (rev 674) +++ trunk/plugins/IR Server Suite/IR Server Suite.sln 2007-07-06 05:03:26 UTC (rev 675) @@ -67,6 +67,8 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Custom HID Receiver", "IR Server Plugins\Custom HID Receiver\Custom HID Receiver.csproj", "{0F6576B4-C88E-4E79-B7E9-9480498C5A32}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IR Blast", "Applications\IR Blast\IR Blast.csproj", "{C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -185,6 +187,10 @@ {0F6576B4-C88E-4E79-B7E9-9480498C5A32}.Debug|Any CPU.Build.0 = Debug|Any CPU {0F6576B4-C88E-4E79-B7E9-9480498C5A32}.Release|Any CPU.ActiveCfg = Release|Any CPU {0F6576B4-C88E-4E79-B7E9-9480498C5A32}.Release|Any CPU.Build.0 = Release|Any CPU + {C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -196,6 +202,7 @@ {A8B8B9C6-9E88-486B-AE9C-F2D945ED05A6} = {0C209E91-5AD5-4662-AD0E-976A940D4806} {46C08F6B-F3C8-461B-9B6F-3BFD4AAAFD63} = {0C209E91-5AD5-4662-AD0E-976A940D4806} {D871AB9A-71B3-4D63-8320-084BAD75064E} = {0C209E91-5AD5-4662-AD0E-976A940D4806} + {C6B0CF12-01D3-439A-9FB4-DEFD5B32F6FB} = {0C209E91-5AD5-4662-AD0E-976A940D4806} {A4023992-CCD6-461E-8E14-219A496734C5} = {0D1620EE-01B9-43B5-9FAA-E983BD9EBDBD} {7C686499-7517-4338-8837-7E8617549D9A} = {0D1620EE-01B9-43B5-9FAA-E983BD9EBDBD} {470D3C31-8D08-45D5-8C67-AEDEAD834402} = {0D1620EE-01B9-43B5-9FAA-E983BD9EBDBD} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |