/// /// Copyright (c) 2017 Sensus Metering Systems /// using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Timers; using log4net; using Config.Entities; namespace TBF.BenchControl.Network.Camera.CLP1611 { public class Camera : ComponentBase, Generic.IDevice { private static readonly ILog log = LogManager.GetLogger(typeof(Camera)); public override string ToString() { return string.Format("{0}, Name={1}, HWAddress={2}, IPAddress={3}, Serial={4}, Image={5}", this.GetType().Namespace.Substring(17), cameraCfg.Name, cameraCfg.HardwareAddress, ipAddress == null ? "not detected" : ipAddress.ToString(), string.IsNullOrEmpty(serial) ? "not detected" : serial, string.IsNullOrEmpty(image) ? "not detected" : image); } public bool Running { get { return running; } } bool running; const string ClpUserName = "tbf"; const string ClpPassword = "C1ern4V0d4"; const string ClpPrompt = "$ "; readonly CameraCfg cameraCfg; readonly GenericDevices.INetworkAdapter netAdapter; public IPAddress IPAddress { get { return ipAddress; } } IPAddress ipAddress; public string Hardware { get { return hardware; } } string hardware; public string Revision { get { return revision; } } string revision; public string Serial { get { return serial; } } string serial; public string Image { get { return image; } } string image; public Telnet.TelnetClient Telnet; private TerminalDlg terminalDlg; public Camera() {} public Camera(Generic.IComponentCfg cfg, IList components) : base(cfg) { cameraCfg = cfg as CameraCfg; netAdapter = TbfComponents.FindComponent(cfg.ParentName, components) as GenericDevices.INetworkAdapter; if (netAdapter == null) throw new ArgumentNullException("no network adapter"); Telnet = null; terminalDlg = null; running = false; log.Debug(this.ToString()); } public void Initialize() { if (cameraCfg.DebugLevel == DebugMode.Simulate) return; /// Detect a camera bool cameraDetected = DetectCamera(cameraCfg.HardwareAddress, true, out ipAddress, out hardware, out revision, out serial, out image); if (!cameraDetected) throw new Exception("No camera detected"); /// Open telnet clint and start the log-in process Telnet = new Telnet.TelnetClient(this, cameraCfg.Name, ClpUserName, ClpPassword, ClpPrompt); if (cameraCfg.DisplayTerminal) { terminalDlg = new TerminalDlg(cameraCfg.Name, Telnet); terminalDlg.Show(); } Telnet.Enqueue(new Telnet.Command(Network.Telnet.CmdAction.CONNECT, ipAddress.ToString(), 10, 30)); running = true; log.FatalFormat("Successfully initialized device {0}", ToString()); } public void StopDevice() { if (terminalDlg != null) { terminalDlg.CloseDlg(); terminalDlg = null; } if (Telnet != null) { Telnet.Dispose(); Telnet = null; } running = false; } public void RunDeviceBefore() {} public void RunDeviceAfter() {} public IOperation LiveStreamOp() { return new LiveStreamOp(this, Telnet, "clp/livestream.sh"); } public IOperation HRLiveStreamOp() { return new LiveStreamOp(this, Telnet, "clp/hrlivestream.sh"); } /// /// Detect the camera with specified hardware address (DIP switches) /// /// Hardware address (DIP switches) /// true = Broadcast 'SetDateTime' to all cameras /// Detected IP address /// Detected hardware /// Detected HW revision /// Detected serial number /// Detected OS image /// true when camera detected successfully bool DetectCamera(int hwAddress, bool setDateTime, out IPAddress ipAddress, out string hardware, out string revision, out string serial, out string image) { for (int trials = 1; trials <= 3; trials++) { UdpClient udpClient = new UdpClient(); if (setDateTime) { SetDateTime(udpClient, DateTime.Now); } /// /// Send a request for camera information /// DateTime detectionStart = DateTime.Now; CameraInfoRequest(udpClient, hwAddress); /// /// Receive a response or timeout /// IAsyncResult asyncRslt = udpClient.BeginReceive(null, null); if (asyncRslt.AsyncWaitHandle.WaitOne(500)) { /// Response received within time limit IPEndPoint cameraIPEndpoint = new IPEndPoint(IPAddress.Any, 1852); byte[] inputBuffer = udpClient.EndReceive(asyncRslt, ref cameraIPEndpoint); double duration_ms = (DateTime.Now - detectionStart).TotalMilliseconds; ipAddress = cameraIPEndpoint.Address; udpClient.Close(); string response = Encoding.ASCII.GetString(inputBuffer, 0, inputBuffer.Length); string[] strArr = response.Split(new char[] { ' ', '=' }); if (strArr.Length == 10 && strArr[0] == "Address" && strArr[2] == "Hardware" && strArr[4] == "Revision" && strArr[6] == "Serial" && strArr[8] == "Image") { hardware = strArr[3]; revision = strArr[5]; serial = strArr[7]; image = strArr[9]; } else if (strArr.Length == 8 && strArr[0] == "Address" && strArr[2] == "Hardware" && strArr[4] == "Revision" && strArr[6] == "Serial") { hardware = strArr[3]; revision = strArr[5]; serial = strArr[7]; image = string.Empty; } else { continue; } string msg = string.Format("Camera {0} detected in {1} ms: HWAddress={2} IPAddress={3} {4}", cameraCfg.Name, duration_ms, cameraCfg.HardwareAddress, ipAddress == null ? "not detected" : ipAddress.ToString(), response); log.Info(msg); Console.WriteLine(msg); return true; /// Camera detected } udpClient.Close(); } ipAddress = null; hardware = null; revision = null; serial = null; image = null; return false; /// No camera detected } void CameraInfoRequest(UdpClient udpClient, int hardwareAddress) { string strToSend = string.Format("getinfo {0}", hardwareAddress); byte[] dataToSend = Encoding.ASCII.GetBytes(strToSend); udpClient.Send(dataToSend, dataToSend.Length, new IPEndPoint(netAdapter.BroadcastAddress, 1852)); } void SetDateTime(UdpClient udpClient, DateTime dateTime) { string strToSend = string.Format("setdatetime {0:yyMMddHHmmss}", dateTime); byte[] dataToSend = Encoding.ASCII.GetBytes(strToSend); udpClient.Send(dataToSend, dataToSend.Length, new IPEndPoint(netAdapter.BroadcastAddress, 1852)); } } }