Plane.Sdk3/PlaneGcsSdk_Shared/Communication/UdpThroughDtuServiceConnection.cs
pxzleo 2ae769b5d4 加入RTK支持
地面站发送接收到的基站数据到飞机,数据不做任何修改直接打包发送到每架飞机
2017-07-31 01:09:32 +08:00

175 lines
5.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
public int BytesToRead()
{
return 0;
}
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;
}
}
}