2017-02-27 02:02:19 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Plane.Communication
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// (通过DTU服务端的Udp透传管道)与飞机进行通信的连接器。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class UdpThroughDtuServiceConnection : ExceptionThrownEventSource, IConnection
|
|
|
|
|
{
|
|
|
|
|
#region Fields
|
|
|
|
|
private byte[] _currentByteArray;
|
|
|
|
|
private int _currentIndex;
|
|
|
|
|
#if LOG_PACKETS
|
|
|
|
|
private System.Text.StringBuilder _log = new System.Text.StringBuilder();
|
|
|
|
|
#endif
|
|
|
|
|
private ConcurrentQueue<byte[]> _inputQueue = new ConcurrentQueue<byte[]>();
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 表示向DTU服务端飞控透传通道握手的协议头
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected string FLAG_DTU_HANDSHAKE_HEAD = "*#$";
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 表示向DTU服务端的Udp飞控透传管道建立申请的结果状态
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected enum DTUHandShakeResult
|
|
|
|
|
{
|
|
|
|
|
Unknown = 0,
|
|
|
|
|
Successful = 1,
|
|
|
|
|
NotExisted,
|
|
|
|
|
Occupied,
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Properties
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 希望连接到哪台飞机
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string CopterIDToBind { get; set; }
|
|
|
|
|
|
|
|
|
|
public bool IsOpen { get; private set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取即将或正在与服务端连接的服务端IP
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string DtuServiceIP { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取即将或正在与服务端连接的服务端端口
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int DtuServicePort { get; set; }
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
public virtual async Task<int> ReadAsync(byte[] buffer, int offset, int size)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var indexLessThan = offset + size;
|
|
|
|
|
for (int i = offset; i < indexLessThan; i++, _currentIndex++)
|
|
|
|
|
{
|
|
|
|
|
while (_currentByteArray == null || _currentIndex >= _currentByteArray.Length)
|
|
|
|
|
{
|
|
|
|
|
while (_inputQueue.Count <= 0)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
await Task.Delay(5).ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
while (!_inputQueue.TryDequeue(out _currentByteArray))
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
await Task.Delay(5).ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
_currentIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
buffer[i] = _currentByteArray[_currentIndex];
|
|
|
|
|
}
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
RaiseExceptionThrown(ex);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-31 01:09:32 +08:00
|
|
|
|
public int BytesToRead()
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-27 02:02:19 +08:00
|
|
|
|
|
|
|
|
|
public virtual async Task WriteAsync(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
if (IsOpen)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (offset == 0)
|
|
|
|
|
{
|
|
|
|
|
await SendAsync(buffer, count);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var data = new byte[count];
|
|
|
|
|
for (int i = 0, j = offset; i < count; i++, j++)
|
|
|
|
|
{
|
|
|
|
|
data[i] = buffer[j];
|
|
|
|
|
}
|
|
|
|
|
await SendAsync(data, count);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
RaiseExceptionThrown(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void EnqueueDatagram(byte[] datagram)
|
|
|
|
|
{
|
|
|
|
|
if (datagram != null && IsOpen)
|
|
|
|
|
{
|
|
|
|
|
#if LOG_PACKETS
|
|
|
|
|
_log.AppendLine("------------");
|
|
|
|
|
for (int i = 0; i < datagram.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
_log.Append(datagram[i]).Append(" ");
|
|
|
|
|
}
|
|
|
|
|
_log.AppendLine();
|
|
|
|
|
#endif
|
|
|
|
|
_inputQueue.Enqueue(datagram);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构建用于发向DTU服务端的握手包
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual byte[] ConstructHandShakeDatagramToDTUService()
|
|
|
|
|
{
|
|
|
|
|
var str = string.Format("{0}{1}", FLAG_DTU_HANDSHAKE_HEAD, CopterIDToBind??string.Empty);
|
|
|
|
|
return Encoding.ASCII.GetBytes(str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 分析由DTU服务端返回的我握手包
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buffer"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual DTUHandShakeResult AnalyzeHandShakeDatagramFromDTUService(byte[] buffer)
|
|
|
|
|
{
|
|
|
|
|
var strResult = Encoding.ASCII.GetString(buffer);//返回的格式为“*#$xxxx|0”
|
|
|
|
|
if (strResult.StartsWith(FLAG_DTU_HANDSHAKE_HEAD))
|
|
|
|
|
{
|
|
|
|
|
var strList = strResult.Substring(FLAG_DTU_HANDSHAKE_HEAD.Length).Split('|');
|
|
|
|
|
var copterID = strList[0];
|
|
|
|
|
int iValue;
|
|
|
|
|
int.TryParse(strList[1], out iValue);
|
|
|
|
|
return (DTUHandShakeResult)iValue;
|
|
|
|
|
}
|
|
|
|
|
return DTUHandShakeResult.Unknown;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|