245 lines
6.7 KiB
C#
245 lines
6.7 KiB
C#
///
|
|
/// 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<Generic.IComponent> 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");
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Detect the camera with specified hardware address (DIP switches)
|
|
/// </summary>
|
|
/// <param name="hwAddress">Hardware address (DIP switches)</param>
|
|
/// <param name="setDateTime">true = Broadcast 'SetDateTime' to all cameras</param>
|
|
/// <param name="ipAddress">Detected IP address</param>
|
|
/// <param name="hardware">Detected hardware</param>
|
|
/// <param name="revision">Detected HW revision</param>
|
|
/// <param name="serial">Detected serial number</param>
|
|
/// <param name="image">Detected OS image</param>
|
|
/// <returns>true when camera detected successfully</returns>
|
|
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));
|
|
}
|
|
}
|
|
}
|