192 lines
6.6 KiB
C#
192 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Inspectron.HawkEye.UDPB;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Inspectron.HawkEye.Protocol
|
|
{
|
|
public class ImageClientTCP : IDisposable
|
|
{
|
|
private static readonly object connectionLock = new object();
|
|
private readonly IPEndPoint _endpoint;
|
|
private readonly IPAddress _adapter;
|
|
|
|
private TcpListener _imageSocket;
|
|
private TcpClient _commandSocket;
|
|
private bool _isConnected = true;
|
|
|
|
public ImageClientTCP(IPEndPoint endpoint,IPAddress adapter)
|
|
{
|
|
_endpoint = endpoint;
|
|
_adapter = adapter;
|
|
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_isConnected = false;
|
|
_commandSocket.Dispose();
|
|
}
|
|
byte[] _commandBuffer = new byte[1500];
|
|
private TcpClient _lastClient;
|
|
public bool SupportsCalibration { get; set; }
|
|
public void Connect()
|
|
{
|
|
lock (connectionLock)
|
|
{
|
|
_commandSocket=new TcpClient(new IPEndPoint(_adapter, 0));
|
|
Console.WriteLine($"Bind on {_adapter?.ToString()}");
|
|
|
|
_commandSocket.Connect(_endpoint);
|
|
var port = UDPBSocket.FindFreePort(_adapter);
|
|
Console.WriteLine("Connected");
|
|
|
|
_imageSocket = new TcpListener(_adapter, port);
|
|
_imageSocket.Start();
|
|
|
|
Console.WriteLine("TCP started");
|
|
|
|
var bytesPort = BitConverter.GetBytes(port);
|
|
_commandSocket.Client.SendData(new[]
|
|
{(byte) ECommand.Connect, bytesPort[0], bytesPort[1], bytesPort[2], bytesPort[3]});
|
|
|
|
var receivedLen = _commandSocket.Client.Receive(_commandBuffer);
|
|
Console.WriteLine("received answer length:"+receivedLen);
|
|
var b = new byte[receivedLen - 1];
|
|
Array.Copy(_commandBuffer, 1, b, 0, b.Length);
|
|
var settingsString = Encoding.UTF8.GetString(b);
|
|
SettingsReceived(JsonConvert.DeserializeObject<CameraSettings>(settingsString));
|
|
if (SupportsCalibration)
|
|
{
|
|
|
|
_commandSocket.Client.SendData(new[] {(byte) ECommand.GetCalibration});
|
|
receivedLen = _commandSocket.Client.Receive(_commandBuffer);
|
|
if (_commandBuffer[0] == (byte) ECommand.OK)
|
|
{
|
|
Console.WriteLine($"calibration received {receivedLen} bytes");
|
|
var c = new byte[receivedLen - 1];
|
|
Array.Copy(_commandBuffer, 1, c, 0, c.Length);
|
|
var calibrationString = Encoding.UTF8.GetString(c);
|
|
CalibrationReceived(JsonConvert.DeserializeObject<List<Dictionary<double,double>>>(calibrationString));
|
|
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("no calibration received");
|
|
}
|
|
}
|
|
|
|
|
|
var th = new Thread(ReceiveLoop);
|
|
th.Start();
|
|
}
|
|
}
|
|
|
|
public event Action<byte[]> ImageReceived = delegate { };
|
|
public event Action<CameraSettings> SettingsReceived = delegate { };
|
|
public event Action<List<Dictionary<double,double>>> CalibrationReceived = delegate { };
|
|
|
|
|
|
public void Trigger()
|
|
{
|
|
_commandSocket.Client.SendData(new[] {(byte) ECommand.Trigger});
|
|
}
|
|
|
|
public void ApplySettings(CameraSettings cameraSettings)
|
|
{
|
|
var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(cameraSettings));
|
|
var databytes = new byte[1000];
|
|
databytes[0] = (byte) ECommand.Settings;
|
|
Array.Copy(data, 0, databytes, 1, data.Length);
|
|
|
|
_commandSocket.Client.SendData(databytes);
|
|
byte[] ok = new byte[1];
|
|
_commandSocket.Client.Receive(ok);
|
|
}
|
|
|
|
public void StartContinuous()
|
|
{
|
|
_commandSocket.Client.SendData(new[] {(byte) ECommand.StartContinuous});
|
|
}
|
|
|
|
public void StopContinuous()
|
|
{
|
|
_commandSocket.Client.SendData(new[] {(byte) ECommand.StopContinuous});
|
|
}
|
|
|
|
public void SaveSettingsOnCamera()
|
|
{
|
|
_commandSocket.Client.SendData(new[] {(byte) ECommand.SaveSettings});
|
|
}
|
|
|
|
private byte[] _imageBuffer = new byte[10*1024*1024];
|
|
private void ReceiveLoop()
|
|
{
|
|
while (_isConnected)
|
|
{
|
|
_lastClient = _imageSocket.AcceptTcpClient();
|
|
while (true)
|
|
{
|
|
int received=0;
|
|
|
|
try
|
|
{
|
|
_lastClient.Client.Receive(_imageBuffer, 0, 1,
|
|
SocketFlags.None);
|
|
Process(_imageBuffer);
|
|
}
|
|
catch
|
|
{
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
public void SaveCalibration(List<Dictionary<double,double>> calibration)
|
|
{
|
|
var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(calibration));
|
|
var databytes = new byte[1500];
|
|
databytes[0] = (byte)ECommand.SaveCalibration;
|
|
Array.Copy(data, 0, databytes, 1, data.Length);
|
|
|
|
_commandSocket.Client.SendData(databytes);
|
|
byte[] ok = new byte[1];
|
|
_commandSocket.Client.Receive(ok);
|
|
}
|
|
|
|
private void Process(byte[] data)
|
|
{
|
|
switch ((EData) data[0])
|
|
{
|
|
case EData.Image:
|
|
_lastClient.Client.Receive(_imageBuffer, 1, 4,
|
|
SocketFlags.None);
|
|
var imageSize = BitConverter.ToInt32(_imageBuffer,1);
|
|
var received = 0;
|
|
do
|
|
{
|
|
received += _lastClient.Client.Receive(_imageBuffer, 5+ received, imageSize- received,
|
|
SocketFlags.None);
|
|
} while (received < imageSize);
|
|
|
|
var b = new byte[imageSize];
|
|
Array.Copy(data, 5, b, 0, b.Length);
|
|
ImageReceived(b);
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
} |