diff options
| author | Roy <roy.mail.net@gmail.com> | 2018-01-03 01:57:58 +0200 |
|---|---|---|
| committer | Roy <roy.mail.net@gmail.com> | 2018-01-03 01:57:58 +0200 |
| commit | 63b2a192ba12f8239668b6818db4ad02db68dbbc (patch) | |
| tree | c9c1de011b38fbff94ce87ac2771667b9a3e773d /Software/Visual_Studio | |
| parent | f917366c405a4308b4b60e30eb1bd0dcf880532c (diff) | |
| download | Tango-63b2a192ba12f8239668b6818db4ad02db68dbbc.tar.gz Tango-63b2a192ba12f8239668b6818db4ad02db68dbbc.zip | |
Implemented abstraction of message encoding/decoding by adding another layer of "Encoders" to Transporters.
Diffstat (limited to 'Software/Visual_Studio')
15 files changed, 193 insertions, 124 deletions
diff --git a/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs b/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs index b783ec261..aec9c0db0 100644 --- a/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs +++ b/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs @@ -12,7 +12,7 @@ using Tango.Transport.Transporters; namespace Tango.Integration.Services { - public class ExternalBridgeClient : ProtoTransporter, IExternalBridgeClient + public class ExternalBridgeClient : BasicTransporter, IExternalBridgeClient { private String _serialNumber; diff --git a/Software/Visual_Studio/Tango.PMR/ITangoMessage.cs b/Software/Visual_Studio/Tango.PMR/ITangoMessage.cs new file mode 100644 index 000000000..90b33a6bb --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/ITangoMessage.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Common; + +namespace Tango.PMR +{ + public interface ITangoMessage + { + /// <summary> + /// Gets the container that will encapsulate the actual PMR message. + /// </summary> + MessageContainer Container { get; } + + /// <summary> + /// Gets or sets the PMR message type. + /// </summary> + MessageType Type { get; set; } + + /// <summary> + /// Serializes the Tango message to byte array. + /// </summary> + /// <returns></returns> + byte[] ToBytes(); + + /// <summary> + /// Serializes the Tango message to byte array representing a serialized JSON object of this Tango message. + /// </summary> + /// <returns></returns> + byte[] ToJsonBytes(); + } +} diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj index 7226685ea..e3846da7a 100644 --- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj +++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj @@ -55,6 +55,7 @@ <Compile Include="Integration\ExternalClientLoginResponse.cs" /> <Compile Include="Integration\OverrideDataBaseRequest.cs" /> <Compile Include="Integration\OverrideDataBaseResponse.cs" /> + <Compile Include="ITangoMessage.cs" /> <Compile Include="MessageFactory.cs" /> <Compile Include="NativePMR.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> diff --git a/Software/Visual_Studio/Tango.PMR/TangoMessage.cs b/Software/Visual_Studio/Tango.PMR/TangoMessage.cs index 4819ac509..c99fc0dfb 100644 --- a/Software/Visual_Studio/Tango.PMR/TangoMessage.cs +++ b/Software/Visual_Studio/Tango.PMR/TangoMessage.cs @@ -13,10 +13,10 @@ namespace Tango.PMR /// Represents a wrapper class for PRM messages. /// </summary> /// <typeparam name="T"></typeparam> - public class TangoMessage<T> where T : IMessage<T> + public class TangoMessage<T> : ITangoMessage where T : IMessage<T> { /// <summary> - /// Gets the container. + /// Gets the container that will encapsulate the actual PMR message. /// </summary> public MessageContainer Container { get; } @@ -26,7 +26,7 @@ namespace Tango.PMR public T Message { get; set; } /// <summary> - /// Gets or sets the message type. + /// Gets or sets the PMR message type. /// </summary> public MessageType Type { get; set; } @@ -46,7 +46,7 @@ namespace Tango.PMR } /// <summary> - /// Generates a new <see cref="MessageContainer"/> containing the message of type <see cref="T"/> and returns a byte array. + /// Serializes the Tango message to byte array. /// </summary> /// <returns></returns> public byte[] ToBytes() @@ -61,7 +61,7 @@ namespace Tango.PMR } /// <summary> - /// Generates a new <see cref="MessageContainer"/> containing the message of type <see cref="T"/> and returns a byte array. + /// Serializes the Tango message to byte array representing a serialized JSON object of this Tango message. /// </summary> /// <returns></returns> public byte[] ToJsonBytes() diff --git a/Software/Visual_Studio/Tango.Transport/Encoders/ProtoEncoder.cs b/Software/Visual_Studio/Tango.Transport/Encoders/ProtoEncoder.cs new file mode 100644 index 000000000..689b331e6 --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/Encoders/ProtoEncoder.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.Transport.Encoders +{ + /// <summary> + /// Represents a protobuf <see cref="ITransportEncoder">Transport Encoder</see>. + /// </summary> + /// <seealso cref="Tango.Transport.ITransportEncoder" /> + public class ProtoEncoder : ITransportEncoder + { + /// <summary> + /// Decodes the specified data. + /// </summary> + /// <param name="data">The data.</param> + /// <returns></returns> + public ITangoMessage Decode(byte[] data) + { + return MessageFactory.ParseTangoMessageAgnostic(data) as ITangoMessage; + } + + /// <summary> + /// Decodes only the container part of the message. + /// </summary> + /// <param name="data">The data.</param> + /// <returns></returns> + public MessageContainer DecodeContainer(byte[] data) + { + return MessageFactory.ParseContainer(data); + } + + /// <summary> + /// Encodes the specified tango message. + /// </summary> + /// <param name="tangoMessage">The tango message.</param> + /// <returns></returns> + public byte[] Encode(ITangoMessage tangoMessage) + { + return tangoMessage.ToBytes(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs index 5ab48e503..413ea7559 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs @@ -15,6 +15,16 @@ namespace Tango.Transport public interface ITransportAdapter : ITransportComponent { /// <summary> + /// Gets the total bytes received. + /// </summary> + long TotalBytesReceived { get; } + + /// <summary> + /// Gets the total bytes sent. + /// </summary> + long TotalBytesSent { get; } + + /// <summary> /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> diff --git a/Software/Visual_Studio/Tango.Transport/ITransportEncoder.cs b/Software/Visual_Studio/Tango.Transport/ITransportEncoder.cs new file mode 100644 index 000000000..beae60d14 --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/ITransportEncoder.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.Transport +{ + /// <summary> + /// Represents a Transport message encoder capable of encoding or decoding <see cref="ITangoMessage">Tango Messages</see>. + /// </summary> + public interface ITransportEncoder + { + /// <summary> + /// Encodes the specified tango message. + /// </summary> + /// <param name="tangoMessage">The tango message.</param> + /// <returns></returns> + byte[] Encode(ITangoMessage tangoMessage); + + /// <summary> + /// Decodes the specified data. + /// </summary> + /// <param name="data">The data.</param> + /// <returns></returns> + ITangoMessage Decode(byte[] data); + + /// <summary> + /// Decodes only the container part of the message. + /// </summary> + /// <param name="data">The data.</param> + /// <returns></returns> + MessageContainer DecodeContainer(byte[] data); + } +} diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs index 9d6f13446..0c06e68f8 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs @@ -25,6 +25,11 @@ namespace Tango.Transport ITransportAdapter Adapter { get; set; } /// <summary> + /// Gets or sets the transport encoder used to encode and decode tango messages. + /// </summary> + ITransportEncoder Encoder { get; set; } + + /// <summary> /// Sends a request. /// </summary> /// <typeparam name="Request">The type of the request.</typeparam> diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index aa5b5ef67..88e2a3b75 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -66,9 +66,11 @@ <Link>GlobalVersionInfo.cs</Link> </Compile> <Compile Include="Adapters\UsbTransportAdapter.cs" /> + <Compile Include="Encoders\ProtoEncoder.cs" /> <Compile Include="ITransportComponent.cs" /> <Compile Include="ITransportAdapter.cs" /> <Compile Include="Adapters\TcpTransportAdapter.cs" /> + <Compile Include="ITransportEncoder.cs" /> <Compile Include="ITransportRouter.cs" /> <Compile Include="PendingResponse.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> @@ -81,8 +83,7 @@ <Compile Include="TransportAdapterMode.cs" /> <Compile Include="TransportComponentState.cs" /> <Compile Include="TransporterBase.cs" /> - <Compile Include="Transporters\JsonTransporter.cs" /> - <Compile Include="Transporters\ProtoTransporter.cs" /> + <Compile Include="Transporters\BasicTransporter.cs" /> <Compile Include="TransportMessage.cs" /> <Compile Include="TransportMessageBase.cs" /> <Compile Include="TransportMessageDirection.cs" /> diff --git a/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs index 100990d0e..b996c82b2 100644 --- a/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs @@ -31,6 +31,26 @@ namespace Tango.Transport #region Properties + private long _totalBytesReceived; + /// <summary> + /// Gets the total bytes received. + /// </summary> + public long TotalBytesReceived + { + get { return _totalBytesReceived; } + protected set { _totalBytesReceived = value; } + } + + private long _totalBytesSent; + /// <summary> + /// Gets the total bytes sent. + /// </summary> + public long TotalBytesSent + { + get { return _totalBytesSent; } + protected set { _totalBytesSent = value; } + } + /// <summary> /// Gets or sets the channel address. /// </summary> @@ -76,6 +96,7 @@ namespace Tango.Transport /// <param name="data">The data.</param> protected virtual void OnDataAvailable(byte[] data) { + TotalBytesReceived += data.Length; DataAvailable?.Invoke(this, data); } @@ -106,14 +127,20 @@ namespace Tango.Transport /// <returns></returns> protected virtual byte[] PostProcessBuffer(byte[] data) { + byte[] postData = data; + if (AdapterMode == TransportAdapterMode.NO_HEADER) { - return data; + return postData; } else { - return BitConverter.GetBytes(data.Length).Concat(data).ToArray(); + postData = BitConverter.GetBytes(data.Length).Concat(data).ToArray(); } + + TotalBytesSent += postData.Length; + + return postData; } #endregion diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs index 756738ee8..2e25d5bf1 100644 --- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs @@ -14,6 +14,7 @@ using Tango.PMR; using Tango.PMR.Common; using System.Reactive.Linq; using System.ServiceModel; +using Tango.Transport.Encoders; namespace Tango.Transport { @@ -57,6 +58,11 @@ namespace Tango.Transport set { _adapter = value; OnAdapterChanged(value); } } + /// <summary> + /// Gets or sets the transport encoder used to encode and decode tango messages. + /// </summary> + public ITransportEncoder Encoder { get; set; } + private TransportComponentState _state; /// <summary> /// Gets the component state. @@ -103,6 +109,7 @@ namespace Tango.Transport /// </summary> public bool FailsWithAdapter { get; set; } + #endregion #region Virtual Methods @@ -183,47 +190,6 @@ namespace Tango.Transport StateChanged?.Invoke(this, state); } - /// <summary> - /// Override in order to provide a method serializer for <see cref="TangoMessage{T}"/>. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="message">The message.</param> - /// <returns></returns> - protected virtual Func<byte[]> OnSerializeingMessage<Request>(TangoMessage<Request> message) where Request : IMessage<Request> - { - return message.ToBytes; - } - - /// <summary> - /// Override in order to provide a deserialized message container part of the message. - /// </summary> - /// <param name="data">The data.</param> - /// <returns></returns> - protected virtual MessageContainer OnParseContainer(byte[] data) - { - return MessageFactory.ParseContainer(data); - } - - /// <summary> - /// Override in order to provide a deserialized message from a container. - /// </summary> - /// <param name="container">The container.</param> - /// <returns></returns> - protected virtual IMessage OnParseMessage(MessageContainer container) - { - return MessageFactory.ParseMessageFromContainer(container); - } - - /// <summary> - /// Called when [parse tango message]. - /// </summary> - /// <param name="bytes">The bytes.</param> - /// <returns></returns> - protected virtual Object OnParseTangoMessage(byte[] bytes) - { - return MessageFactory.ParseTangoMessageAgnostic(bytes); - } - #endregion #region Constructors @@ -233,6 +199,7 @@ namespace Tango.Transport /// </summary> public TransporterBase() { + Encoder = new ProtoEncoder(); _pendingResponses = new Dictionary<string, PendingResponse>(); _sendingQueue = new ConcurrentQueue<TransportMessageBase>(); _pendingRequests = new List<TransportMessageBase>(); @@ -297,7 +264,7 @@ namespace Tango.Transport LogManager.Log("Expected response: " + typeof(Response).Name); TaskCompletionSource<TangoMessage<Response>> source = new TaskCompletionSource<TangoMessage<Response>>(); - TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), source); + TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, () => Encoder.Encode(request), source); _sendingQueue.Enqueue(message); Task.Delay(timeout != null ? timeout.Value : RequestTimeout).ContinueWith((x) => { @@ -329,7 +296,7 @@ namespace Tango.Transport request.Container.Continuous = true; request.Container.Completed = false; - TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), null) + TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, () => Encoder.Encode(request), null) { IsContinuous = true, ContinuesResponseSubject = subject, @@ -389,7 +356,7 @@ namespace Tango.Transport } TaskCompletionSource<object> source = new TaskCompletionSource<object>(); - TransportMessage<object> message = new TransportMessage<object>(token, response, TransportMessageDirection.Response, OnSerializeingMessage(response), source); + TransportMessage<object> message = new TransportMessage<object>(token, response, TransportMessageDirection.Response, () => Encoder.Encode(response), source); _sendingQueue.Enqueue(message); return source.Task; } @@ -492,7 +459,7 @@ namespace Tango.Transport LogManager.Log("Message received on adapter: " + Adapter.Address); LogManager.Log("Parsing message container..."); - MessageContainer container = OnParseContainer(data); + MessageContainer container = Encoder.DecodeContainer(data); LogManager.Log("Searching for pending request token: " + container.Token); TransportMessageBase request = _pendingRequests.SingleOrDefault(x => x.Token == container.Token); @@ -511,7 +478,7 @@ namespace Tango.Transport if (container.Error == ErrorCode.None) { LogManager.Log("Parsing inner response message and setting pending request task result..."); - request.SetResult(OnParseTangoMessage(data), true); + request.SetResult(Encoder.Decode(data), true); LogManager.Log("Message enquirer released..."); } else @@ -538,7 +505,7 @@ namespace Tango.Transport { LogManager.Log("Continuous sequence completed."); } - request.SetResult(OnParseTangoMessage(data), container.Completed); + request.SetResult(Encoder.Decode(data), container.Completed); } else { diff --git a/Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs b/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs index 7c82639d2..06c1f3921 100644 --- a/Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs @@ -21,23 +21,23 @@ namespace Tango.Transport.Transporters /// Represents an <see cref="ITransporter"/> which send and receive <see cref="TangoMessage{T}"/> messages using Protobuf binary data. /// </summary> /// <seealso cref="Tango.Transport.TransporterBase" /> - public class ProtoTransporter : TransporterBase + public class BasicTransporter : TransporterBase { #region Constructors /// <summary> - /// Initializes a new instance of the <see cref="ProtoTransporter"/> class. + /// Initializes a new instance of the <see cref="BasicTransporter"/> class. /// </summary> - public ProtoTransporter() : base() + public BasicTransporter() : base() { } /// <summary> - /// Initializes a new instance of the <see cref="ProtoTransporter"/> class. + /// Initializes a new instance of the <see cref="BasicTransporter"/> class. /// </summary> /// <param name="adapter">The transport adapter.</param> - public ProtoTransporter(ITransportAdapter adapter) : base(adapter) + public BasicTransporter(ITransportAdapter adapter) : base(adapter) { } diff --git a/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs b/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs deleted file mode 100644 index d490d4a61..000000000 --- a/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Google.Protobuf; -using Tango.PMR; -using Tango.PMR.Common; - -namespace Tango.Transport.Transporters -{ - /// <summary> - /// Represents an <see cref="ITransporter"/> which send and receive <see cref="TangoMessage{T}"/> messages using JSON formatted strings. - /// </summary> - /// <seealso cref="Tango.Transport.TransporterBase" /> - public class JsonTransporter : TransporterBase - { - #region Constructors - - /// <summary> - /// Initializes a new instance of the <see cref="JsonTransporter"/> class. - /// </summary> - public JsonTransporter() : base() - { - - } - - /// <summary> - /// Initializes a new instance of the <see cref="JsonTransporter"/> class. - /// </summary> - /// <param name="adapter">The transport adapter.</param> - public JsonTransporter(ITransportAdapter adapter) : base(adapter) - { - - } - - #endregion - - /// <summary> - /// Override in order to provide a method serializer for <see cref="TangoMessage{T}" />. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="message">The message.</param> - /// <returns></returns> - protected override Func<byte[]> OnSerializeingMessage<Request>(TangoMessage<Request> message) - { - return message.ToJsonBytes; - } - - /// <summary> - /// Override in order to provide a deserialized message container part of the message. - /// </summary> - /// <param name="data">The data.</param> - /// <returns></returns> - protected override MessageContainer OnParseContainer(byte[] data) - { - return MessageFactory.ParseContainerJson(data); - } - } -} diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs index ad5c449c8..0ffc89fdf 100644 --- a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs @@ -153,7 +153,7 @@ namespace Tango.MachineEM.UI.ViewModels LogManager.RegisterLogger(logger); - Emulator = new MachineEmulator(new ProtoTransporter()); + Emulator = new MachineEmulator(new BasicTransporter()); StartCommand = new RelayCommand(Start, (x) => !Emulator.IsStarted); StopCommand = new RelayCommand(Stop,(x) => Emulator.IsStarted); diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs index 306da384f..36c360c5a 100644 --- a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs +++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs @@ -21,7 +21,7 @@ namespace Tango.MobileEM.UI protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); - Emulator = new MobileEmulator(new ProtoTransporter(new UsbTransportAdapter("COM2"))); + Emulator = new MobileEmulator(new BasicTransporter(new UsbTransportAdapter("COM2"))); } } } |
