├── LICENSE ├── README.md └── diag-doip-uds ├── Diag-Doip-Uds.sln └── Diag-Doip-Uds ├── Appl ├── Common │ └── Diagnostic_manager.cs ├── Dcm │ ├── Config_parser │ │ └── Config_parser_type.cs │ ├── Connection │ │ └── Uds_transport_protocol_manager.cs │ ├── Conversation │ │ ├── Conversation_manager.cs │ │ ├── Dm_conversation.cs │ │ ├── Dm_conversation_state_impl.cs │ │ └── Vd_conversation.cs │ ├── Dcm_client.cs │ └── Service │ │ ├── Dm_uds_message.cs │ │ └── Vd_message.cs ├── Diagnostic_client_impl.cs └── Include │ ├── Create_diagnostic_client.cs │ ├── Diagnostic_client_vehicle_info_message_type.cs │ ├── IDiagnostic_client.cs │ ├── IDiagnostic_client_conversation.cs │ └── IDiagnostic_client_uds_message_type.cs ├── Diag-Doip-Uds.csproj ├── Lib ├── Common │ └── Common_header.cs ├── Doip_client │ ├── Channel │ │ ├── Tcp_channel.cs │ │ ├── Tcp_channel_handler_impl.cs │ │ ├── Tcp_channel_state_impl.cs │ │ ├── Udp_channel.cs │ │ ├── Udp_channel_handler_impl.cs │ │ └── Udp_channel_state_impl.cs │ ├── Common │ │ ├── Common_doip_types.cs │ │ └── Doip_payload_type.cs │ ├── Connection │ │ └── Connection_manager.cs │ ├── Doip_transport_protocol_handler.cs │ ├── Handler │ │ ├── Tcp_transport_handler.cs │ │ └── Udp_transport_handler.cs │ └── Sockets │ │ ├── Tcp_socket_handler.cs │ │ └── Udp_socket_handler.cs ├── Uds_transport_layer_api │ └── Uds_transport │ │ ├── Connection.cs │ │ ├── Conversion_handler.cs │ │ ├── Protocol_handler.cs │ │ ├── Protocol_mgr.cs │ │ ├── Protocol_types.cs │ │ └── Uds_message.cs └── Utility_support │ ├── Socket │ ├── Tcp │ │ ├── Tcp_client.cs │ │ ├── Tcp_server.cs │ │ └── Tcp_types.cs │ └── Udp │ │ ├── Udp_client.cs │ │ └── Udp_types.cs │ └── Utility │ ├── State.cs │ ├── Sync_timer.cs │ └── Utils.cs ├── Program.cs ├── Resource └── diag_client_config.json ├── User_uds_message.cs ├── bin └── Debug │ └── net6.0 │ ├── Diag-Doip-Uds.deps.json │ ├── Diag-Doip-Uds.dll │ ├── Diag-Doip-Uds.exe │ ├── Diag-Doip-Uds.pdb │ ├── Diag-Doip-Uds.runtimeconfig.json │ ├── Newtonsoft.Json.dll │ └── diag_client_config.json └── obj ├── Debug └── net6.0 │ ├── Diag-Doip-Uds.AssemblyInfo.cs │ ├── Diag-Doip-Uds.AssemblyInfoInputs.cache │ ├── Diag-Doip-Uds.GeneratedMSBuildEditorConfig.editorconfig │ ├── Diag-Doip-Uds.GlobalUsings.g.cs │ ├── Diag-Doip-Uds.assets.cache │ ├── Diag-Doip-Uds.csproj.AssemblyReference.cache │ ├── Diag-Doip-Uds.csproj.BuildWithSkipAnalyzers │ ├── Diag-Doip-Uds.csproj.CopyComplete │ ├── Diag-Doip-Uds.csproj.CoreCompileInputs.cache │ ├── Diag-Doip-Uds.csproj.FileListAbsolute.txt │ ├── Diag-Doip-Uds.dll │ ├── Diag-Doip-Uds.genruntimeconfig.cache │ ├── Diag-Doip-Uds.pdb │ ├── apphost.exe │ ├── ref │ └── Diag-Doip-Uds.dll │ └── refint │ └── Diag-Doip-Uds.dll ├── Diag-Doip-Uds.csproj.nuget.dgspec.json ├── Diag-Doip-Uds.csproj.nuget.g.props ├── Diag-Doip-Uds.csproj.nuget.g.targets ├── project.assets.json └── project.nuget.cache /README.md: -------------------------------------------------------------------------------- 1 | # diag-doip-uds 2 | C# implementation of doip external test equipment 3 | 4 | # todo 5 | Route activation has not been fully tested yet, as I do not have a physical ecu on hand for testing, 6 | and if you find any problems in the code or find bugs, PR's are welcome. 7 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diag-Doip-Uds", "Diag-Doip-Uds\Diag-Doip-Uds.csproj", "{2FAAACDD-C985-4128-959D-79764363E5F9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2FAAACDD-C985-4128-959D-79764363E5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2FAAACDD-C985-4128-959D-79764363E5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2FAAACDD-C985-4128-959D-79764363E5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2FAAACDD-C985-4128-959D-79764363E5F9}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {00808D48-047D-43FE-B28A-87578DBAF6E4} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Common/Diagnostic_manager.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Include; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using static Diag_Doip_Uds.Lib.Common.Common_header; 9 | 10 | namespace Diag_Doip_Uds.Appl.Common 11 | { 12 | /* 13 | @ Class Name : DiagnosticManager 14 | @ Class Description : Parent class to create DCM and DEM class 15 | */ 16 | public abstract class DiagnosticManager : IDisposable 17 | { 18 | // flag to terminate the main thread 19 | private bool exit_requested_; 20 | // conditional variable to block the thread 21 | private AutoResetEvent auto_reset_event = new(false); 22 | // For locking critical section of code 23 | private Mutex mutex_ = new(); 24 | 25 | //ctor 26 | public DiagnosticManager() { exit_requested_ = false; } 27 | public void Dispose() 28 | { 29 | mutex_.WaitOne(); 30 | try 31 | { 32 | exit_requested_ = true; 33 | } 34 | finally 35 | { 36 | mutex_.ReleaseMutex(); 37 | } 38 | auto_reset_event.Set(); 39 | } 40 | 41 | // main function 42 | public virtual void Main() 43 | { 44 | // Initialize the module 45 | Initialize(); 46 | // Run the module 47 | Run(); 48 | // Entering infinite loop 49 | while (!exit_requested_) 50 | { 51 | // Thread exited 52 | //mutex_.WaitOne(); 53 | try 54 | { 55 | auto_reset_event.WaitOne(); 56 | } 57 | finally 58 | { 59 | //mutex_.ReleaseMutex(); 60 | } 61 | } 62 | // Shutdown Module 63 | Shutdown(); 64 | } 65 | 66 | // signal shutdown 67 | public virtual void SignalShutdown() 68 | { 69 | mutex_.WaitOne(); 70 | try 71 | { 72 | exit_requested_ = true; 73 | } 74 | finally 75 | { 76 | mutex_.ReleaseMutex(); 77 | } 78 | auto_reset_event.Set(); 79 | } 80 | 81 | // Initialize 82 | public abstract void Initialize(); 83 | 84 | // Run 85 | public abstract void Run(); 86 | 87 | // Shutdown 88 | public abstract void Shutdown(); 89 | 90 | // Function to get the diagnostic client conversation 91 | public abstract IDiagClientConversation 92 | GetDiagnosticClientConversation( string _conversation_name); 93 | 94 | // Send Vehicle Identification Request and get response 95 | public abstract Pair 96 | SendVehicleIdentificationRequest(VehicleAddrInfoRequest _vehicle_info_request); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Config_parser/Config_parser_type.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Appl.Dcm.Config_parser 9 | { 10 | // Doip network property type 11 | public class DoipNetworkType 12 | { 13 | [JsonProperty("TcpIpAddress")] 14 | // local tcp address 15 | public string Tcp_ip_address { get; set; } = string.Empty; 16 | }; 17 | 18 | public class ConversationPropertyType 19 | { 20 | [JsonProperty("p2ClientMax")] 21 | // store p2 client timeout 22 | public UInt16 P2_client_max { get; set; } 23 | [JsonProperty("p2StarClientMax")] 24 | // store p2 star client timeout 25 | public UInt16 P2_star_client_max { get; set; } 26 | [JsonProperty("RxBufferSize")] 27 | // store receive buffer size 28 | public UInt16 Rx_buffer_size { get; set; } 29 | [JsonProperty("SourceAddress")] 30 | // store source address of client 31 | public UInt16 Source_address { get; set; } 32 | 33 | [JsonProperty("TargetAddressType")] 34 | // store Target address type 35 | public string Target_address_type { get; set; } = string.Empty; 36 | [JsonProperty("Network")] 37 | // store the doip network item 38 | public DoipNetworkType Network { get; set; } = new(); 39 | [JsonProperty("ConversationName")] 40 | // store the client conversation name 41 | public string Conversation_name { get; set; } = string.Empty; 42 | } 43 | 44 | // Properties of a single conversation 45 | public class ConversationType 46 | { 47 | [JsonProperty("NumberOfConversation")] 48 | // number of conversation 49 | public byte Num_of_conversation { get; set; } 50 | [JsonProperty("ConversationProperty")] 51 | public List ConversationPropertys = new(); 52 | }; 53 | 54 | // Properties of diag client configuration 55 | public class DcmClientConfig 56 | { 57 | [JsonProperty("UdpIpAddress")] 58 | // local udp address 59 | public string Udp_ip_address { get; set; } = string.Empty; 60 | [JsonProperty("UdpBroadcastAddress")] 61 | // broadcast address 62 | public string Udp_broadcast_address { get; set; } = string.Empty; 63 | [JsonProperty("Conversation")] 64 | // store all conversations 65 | public ConversationType Conversation { get; set; } = new(); 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Connection/Uds_transport_protocol_manager.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client; 2 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Appl.Dcm.Connection 10 | { 11 | // UdsTransportProtocolHandler are flexible "plugins", which need an identification 12 | using UdsTransportProtocolHandlerID = Byte; 13 | /* 14 | @ Class Name : UdsTransportProtocolManager 15 | @ Class Description : This class must be instantiated by user for using the transport protocol functionalities. 16 | This will inherit uds transport protocol handler 17 | */ 18 | public sealed class UdsTransportProtocolManager : UdsTransportProtocolMgr 19 | { 20 | // store doip transport handler 21 | public UdsTransportProtocolHandler doip_transport_handler; 22 | 23 | // handler id count 24 | public UdsTransportProtocolHandlerID handler_id_count = 0; 25 | //ctor 26 | public UdsTransportProtocolManager() 27 | { 28 | doip_transport_handler = new DoipTransportProtocolHandler(handler_id_count, this); 29 | } 30 | 31 | // initialize all the transport protocol handler 32 | public override void Startup() 33 | { 34 | //Initialize all the handlers in box 35 | doip_transport_handler.Initialize(); 36 | } 37 | 38 | // start all the transport protocol handler 39 | public override void Run() 40 | { 41 | //Start all the handlers in box 42 | doip_transport_handler.Start(); 43 | } 44 | 45 | // terminate all the transport protocol handler 46 | public override void Shutdown() 47 | { 48 | //Stop all the handlers in box 49 | doip_transport_handler.Stop(); 50 | } 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Conversation/Conversation_manager.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Dcm.Config_parser; 2 | using Diag_Doip_Uds.Appl.Dcm.Connection; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport.Conversion_manager; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Diag_Doip_Uds.Appl.Dcm.Conversation 11 | { 12 | /* 13 | @ Class Name : ConversationManager 14 | @ Class Description : Class to manage all the conversion created from usr request 15 | */ 16 | public class ConversationManager 17 | { 18 | // store uds transport manager 19 | private UdsTransportProtocolManager uds_transport_mgr_; 20 | 21 | // store the conversion name with conversation configurations 22 | private Dictionary conversation_config_ = new(); 23 | 24 | // store the vehicle discovery with conversation configuration 25 | private Dictionary vd_conversation_config_ = new(); 26 | 27 | // ctor 28 | public ConversationManager(DcmClientConfig? _config, UdsTransportProtocolManager _uds_transport_mgr) 29 | { 30 | uds_transport_mgr_ = _uds_transport_mgr; 31 | // create the conversation config (vd & dm) out of passed config 32 | CreateConversationConfig(_config); 33 | } 34 | 35 | // startup 36 | public void Startup() 37 | { 38 | } 39 | 40 | // shutdown 41 | public void Shutdown() 42 | { 43 | } 44 | 45 | // Get the required conversion 46 | public DmConversation? GetDiagnosticClientConversation(string _conversation_name) 47 | { 48 | DmConversation? dm_conversation = null; 49 | if (conversation_config_.ContainsKey(_conversation_name)) 50 | { 51 | // create the conversation 52 | dm_conversation = new DmConversation(_conversation_name, conversation_config_[_conversation_name]); 53 | // Register the connection 54 | dm_conversation.RegisterConnection( 55 | uds_transport_mgr_.doip_transport_handler.FindOrCreateTcpConnection( 56 | dm_conversation.Dm_conversion_handler_, 57 | conversation_config_[_conversation_name].Tcp_address, 58 | conversation_config_[_conversation_name].Port_num 59 | ) 60 | ); 61 | } 62 | return dm_conversation; 63 | } 64 | 65 | // Get the required conversion 66 | public VdConversation GetDiagnosticClientVehicleDiscoveryConversation(string _conversation_name) 67 | { 68 | VdConversation? vd_conversation = null; 69 | if(vd_conversation_config_.ContainsKey(_conversation_name)) 70 | { 71 | // create the conversation 72 | vd_conversation = new VdConversation(_conversation_name, vd_conversation_config_[_conversation_name]); 73 | // Register the connection 74 | vd_conversation.RegisterConnection( 75 | uds_transport_mgr_.doip_transport_handler.FindOrCreateUdpConnection( 76 | vd_conversation.GetConversationHandler(), 77 | vd_conversation_config_[_conversation_name].Udp_address, 78 | vd_conversation_config_[_conversation_name].Port_num 79 | ) 80 | ); 81 | } 82 | return vd_conversation; 83 | } 84 | 85 | // function to create or find new conversion 86 | private void CreateConversationConfig(DcmClientConfig? _config) 87 | { 88 | if(_config == null ) 89 | { 90 | Console.WriteLine("CreateConversationConfig error : _config == null"); 91 | return; 92 | } 93 | 94 | // Create Vehicle discovery config 95 | { 96 | ConversionIdentifierType conversion_identifier = new(); 97 | conversion_identifier.Udp_address = _config.Udp_ip_address; 98 | conversion_identifier.Udp_broadcast_address = _config.Udp_broadcast_address; 99 | conversion_identifier.Port_num = 0; // random selection of port number 100 | vd_conversation_config_.Add("VehicleDiscovery", conversion_identifier); 101 | } 102 | 103 | // Create Conversation config 104 | { 105 | for (byte conv_count = 0; conv_count < _config.Conversation.Num_of_conversation; conv_count++) 106 | { 107 | if(_config.Conversation.ConversationPropertys[conv_count] != null) 108 | { 109 | ConversionIdentifierType conversion_identifier = new(); 110 | conversion_identifier.Rx_buffer_size = _config.Conversation.ConversationPropertys[conv_count].Rx_buffer_size; 111 | conversion_identifier.P2_client_max = _config.Conversation.ConversationPropertys[conv_count].P2_client_max; 112 | conversion_identifier.P2_star_client_max = _config.Conversation.ConversationPropertys[conv_count].P2_star_client_max; 113 | conversion_identifier.Source_address = _config.Conversation.ConversationPropertys[conv_count].Source_address; 114 | conversion_identifier.Tcp_address = _config.Conversation.ConversationPropertys[conv_count].Network.Tcp_ip_address; 115 | conversion_identifier.Port_num = 0; // random selection of port number 116 | conversation_config_.Add(_config.Conversation.ConversationPropertys[conv_count].Conversation_name, conversion_identifier); 117 | } 118 | } 119 | } 120 | } 121 | }; 122 | } 123 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Conversation/Dm_conversation_state_impl.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Dcm.Conversation; 2 | using Diag_Doip_Uds.Lib.Utility_support.Utility; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Appl.Dcm.Conversation 10 | { 11 | // Conversation States 12 | public enum ConversationState : byte 13 | { 14 | kIdle = 0x00, 15 | kDiagWaitForRes, 16 | kDiagStartP2StarTimer, 17 | kDiagRecvdPendingRes, 18 | kDiagRecvdFinalRes, 19 | kDiagSuccess, 20 | }; 21 | 22 | public class ConversationStateImpl 23 | { 24 | // conversation state 25 | private StateContext conversation_state_; 26 | // ctor 27 | public ConversationStateImpl() 28 | { 29 | conversation_state_ = new(); 30 | // create and add state 31 | // kIdle 32 | GetConversationStateContext().AddState(ConversationState.kIdle, 33 | new kIdle(ConversationState.kIdle)); 34 | // kDiagWaitForRes 35 | GetConversationStateContext().AddState(ConversationState.kDiagWaitForRes, 36 | new kDiagWaitForRes(ConversationState.kDiagWaitForRes)); 37 | // kDiagStartP2StarTimer 38 | GetConversationStateContext().AddState(ConversationState.kDiagStartP2StarTimer, 39 | new kDiagStartP2StarTimer(ConversationState.kDiagStartP2StarTimer)); 40 | // kDiagRecvdPendingRes 41 | GetConversationStateContext().AddState(ConversationState.kDiagRecvdPendingRes, 42 | new kDiagRecvdPendingRes(ConversationState.kDiagRecvdPendingRes)); 43 | // kDiagRecvdFinalRes 44 | GetConversationStateContext().AddState(ConversationState.kDiagRecvdFinalRes, 45 | new kDiagRecvdFinalRes(ConversationState.kDiagRecvdFinalRes)); 46 | // kDiagSuccess 47 | GetConversationStateContext().AddState(ConversationState.kDiagSuccess, 48 | new kDiagSuccess(ConversationState.kDiagSuccess)); 49 | // transit to idle state 50 | GetConversationStateContext().TransitionTo(ConversationState.kIdle); 51 | } 52 | 53 | // Function to get the Conversation State context 54 | public StateContext GetConversationStateContext() 55 | { 56 | return conversation_state_; 57 | } 58 | }; 59 | 60 | public sealed class kIdle : State 61 | { 62 | // ctor 63 | public kIdle(ConversationState _state) : base(_state) 64 | { 65 | } 66 | 67 | // start the state 68 | public override void Start() 69 | { 70 | } 71 | 72 | // Stop the state 73 | public override void Stop() 74 | { 75 | } 76 | 77 | // Handle invoked asynchronously 78 | public override void HandleMessage() 79 | { 80 | } 81 | }; 82 | 83 | public sealed class kDiagWaitForRes : State 84 | { 85 | // ctor 86 | public kDiagWaitForRes(ConversationState _state) : base(_state) 87 | { 88 | } 89 | 90 | // start the state 91 | public override void Start() 92 | { 93 | } 94 | 95 | // Stop the state 96 | public override void Stop() 97 | { 98 | } 99 | 100 | // Handle invoked asynchronously 101 | public override void HandleMessage() 102 | { 103 | } 104 | }; 105 | 106 | public sealed class kDiagStartP2StarTimer : State 107 | { 108 | // ctor 109 | public kDiagStartP2StarTimer(ConversationState _state) : base(_state) 110 | { 111 | } 112 | 113 | // start the state 114 | public override void Start() 115 | { 116 | } 117 | 118 | // Stop the state 119 | public override void Stop() 120 | { 121 | } 122 | 123 | // Handle invoked asynchronously 124 | public override void HandleMessage() 125 | { 126 | } 127 | }; 128 | 129 | public sealed class kDiagRecvdPendingRes : State 130 | { 131 | // ctor 132 | public kDiagRecvdPendingRes(ConversationState _state) : base(_state) 133 | { 134 | } 135 | 136 | // start the state 137 | public override void Start() 138 | { 139 | } 140 | 141 | // Stop the state 142 | public override void Stop() 143 | { 144 | } 145 | 146 | // Handle invoked asynchronously 147 | public override void HandleMessage() 148 | { 149 | } 150 | }; 151 | 152 | public sealed class kDiagRecvdFinalRes : State 153 | { 154 | // ctor 155 | public kDiagRecvdFinalRes(ConversationState _state) : base(_state) 156 | { 157 | } 158 | 159 | // start the state 160 | public override void Start() 161 | { 162 | } 163 | 164 | // Stop the state 165 | public override void Stop() 166 | { 167 | } 168 | 169 | // Handle invoked asynchronously 170 | public override void HandleMessage() 171 | { 172 | } 173 | }; 174 | 175 | public sealed class kDiagSuccess : State 176 | { 177 | // ctor 178 | public kDiagSuccess(ConversationState _state) : base(_state) 179 | { 180 | } 181 | 182 | // start the state 183 | public override void Start() 184 | { 185 | } 186 | 187 | // Stop the state 188 | public override void Stop() 189 | { 190 | } 191 | 192 | // Handle invoked asynchronously 193 | public override void HandleMessage() 194 | { 195 | } 196 | }; 197 | } 198 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Conversation/Vd_conversation.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Dcm.Service; 2 | using Diag_Doip_Uds.Appl.Include; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 4 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport.Conversion_manager; 5 | using Diag_Doip_Uds.Lib.Utility_support.Utility; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Drawing; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using static Diag_Doip_Uds.Lib.Common.Common_header; 13 | 14 | namespace Diag_Doip_Uds.Appl.Dcm.Conversation 15 | { 16 | using ProtocolKind = String; 17 | using Priority = Byte; 18 | using ChannelID = UInt32; 19 | using Address = UInt16; 20 | using PortNumber = UInt16; 21 | using MetaInfoMap = Dictionary; 22 | using IpAddress = String; 23 | using VehicleIdentificationResponseResult = Pair; 24 | using PreselectionMode = Byte; 25 | using PreselectionValue = List; 26 | using VehicleAddrInfoResponseStruct = VehicleAddrInfoResponse; 27 | using ConversionHandlerID = Byte; 28 | 29 | // Vehicle Info Message implementation class 30 | public sealed class VehicleInfoMessageImpl : IVehicleInfoMessage 31 | { 32 | public VehicleInfoMessageImpl( 33 | Dictionary _vehicle_info_collection) 34 | { 35 | vehicle_info_messages_ = new(); 36 | foreach (var item in _vehicle_info_collection) 37 | { 38 | Push(item.Value); 39 | } 40 | } 41 | 42 | public List GetVehicleList() { return vehicle_info_messages_; } 43 | 44 | // Function to push the vehicle address info received 45 | private void Push(VehicleAddrInfoResponse _vehicle_addr_info_response) 46 | { 47 | vehicle_info_messages_.Add(_vehicle_addr_info_response); 48 | } 49 | 50 | // store the vehicle info message list 51 | private List vehicle_info_messages_; 52 | }; 53 | 54 | /* 55 | @ Class Name : VdConversation 56 | @ Class Description : Class to query Diagnostic Server list 57 | */ 58 | public class VdConversation 59 | { 60 | // shared pointer to store the conversion handler 61 | private ConversionHandler vd_conversion_handler_; 62 | 63 | // conversation name 64 | private string conversation_name_; 65 | 66 | // Vehicle broadcast address 67 | private string? broadcast_address_; 68 | 69 | // Tp connection 70 | private Lib.Uds_transport_layer_api.Uds_transport.Connection? connection_ptr_; 71 | 72 | // container to store the vehicle information 73 | private Dictionary vehicle_info_collection_; 74 | 75 | // mutex to lock the vehicle info collection container 76 | private Mutex vehicle_info_container_mutex_; 77 | // ctor 78 | public VdConversation(string _conversion_name, ConversionIdentifierType _conversion_identifier) 79 | { 80 | vd_conversion_handler_ = new VdConversationHandler(_conversion_identifier.Handler_id, this); 81 | conversation_name_ = _conversion_name; 82 | broadcast_address_ = _conversion_identifier.Udp_broadcast_address; 83 | connection_ptr_ = null; 84 | vehicle_info_collection_ = new(); 85 | vehicle_info_container_mutex_ = new(); 86 | } 87 | 88 | // startup 89 | public void Startup() 90 | { 91 | if (connection_ptr_ == null) return; 92 | // initialize the connection 93 | connection_ptr_.Initialize(); 94 | // start the connection 95 | connection_ptr_.Start(); 96 | } 97 | 98 | // shutdown 99 | public void Shutdown() 100 | { 101 | if (connection_ptr_ == null) return; 102 | // shutdown connection 103 | connection_ptr_.Stop(); 104 | } 105 | 106 | // Register Connection 107 | public void RegisterConnection(Lib.Uds_transport_layer_api.Uds_transport.Connection _connection) 108 | { 109 | connection_ptr_ = _connection; 110 | } 111 | 112 | // Send Vehicle Identification Request and get response 113 | public VehicleIdentificationResponseResult 114 | SendVehicleIdentificationRequest(VehicleAddrInfoRequest _vehicle_info_request) 115 | { 116 | VehicleIdentificationResponseResult ret_val = new(VehicleResponseResult.kTransmitFailed, null); 117 | if (connection_ptr_ == null || broadcast_address_ == null) return ret_val; 118 | 119 | // Deserialize first , Todo: Add optional when deserialize fails 120 | Pair vehicle_info_request_deserialized_value = 121 | DeserializeVehicleInfoRequest(_vehicle_info_request); 122 | 123 | if (VerifyVehicleInfoRequest(vehicle_info_request_deserialized_value.First, 124 | (byte)vehicle_info_request_deserialized_value.Second.Count)) 125 | { 126 | if (connection_ptr_.Transmit(new VdMessage( 127 | vehicle_info_request_deserialized_value.First, vehicle_info_request_deserialized_value.Second, 128 | broadcast_address_)) != TransmissionResult.kTransmitFailed) 129 | { 130 | // Check if any response received 131 | if (vehicle_info_collection_.Count == 0) 132 | { 133 | // no response received 134 | ret_val.First = VehicleResponseResult.kNoResponseReceived; 135 | } 136 | else 137 | { 138 | ret_val.First = VehicleResponseResult.kStatusOk; 139 | ret_val.Second = new VehicleInfoMessageImpl(vehicle_info_collection_); 140 | // all the responses are copied, now clear the map 141 | vehicle_info_collection_.Clear(); 142 | } 143 | } 144 | } 145 | else 146 | { 147 | ret_val.First = VehicleResponseResult.kInvalidParameters; 148 | } 149 | return ret_val; 150 | } 151 | 152 | // Get the list of available Diagnostic Server 153 | public IVehicleInfoMessage? GetDiagnosticServerList() 154 | { 155 | return null; 156 | } 157 | 158 | // Indicate message Diagnostic message reception over TCP to user 159 | public Pair IndicateMessage(Address _source_addr, 160 | Address _target_addr, 161 | TargetAddressType _type, 162 | ChannelID _channel_id, 163 | int _size, 164 | Priority _priority, 165 | ProtocolKind _protocol_kind, 166 | List _payloadInfo) 167 | { 168 | Pair ret_val = new(IndicationResult.kIndicationNOk, null); 169 | if (_payloadInfo.Count != 0) 170 | { 171 | ret_val.First = IndicationResult.kIndicationOk; 172 | ret_val.Second = new VdMessage(); 173 | ret_val.Second.GetPayload().EnsureCapacity(_size); 174 | } 175 | return ret_val; 176 | } 177 | 178 | // Hands over a valid message to conversion 179 | public void HandleMessage(UdsMessage _message) 180 | { 181 | if (_message != null) 182 | { 183 | vehicle_info_container_mutex_.WaitOne(); 184 | try 185 | { 186 | Pair vehicle_info_request = 187 | DeserializeVehicleInfoResponse(_message); 188 | 189 | vehicle_info_collection_.Add(vehicle_info_request.First, vehicle_info_request.Second); 190 | } 191 | finally 192 | { 193 | vehicle_info_container_mutex_.ReleaseMutex(); 194 | } 195 | } 196 | } 197 | 198 | // Function to verify Vehicle Info requests 199 | private bool VerifyVehicleInfoRequest(PreselectionMode _preselection_mode, byte _preselection_value_length) 200 | { 201 | bool is_veh_info_valid = false; 202 | if ((_preselection_mode != 0U) && (_preselection_value_length != 0U)) 203 | { 204 | // 1U : DoIP Entities with given VIN 205 | if (_preselection_mode == 1U && (_preselection_value_length == 17U)) 206 | { 207 | is_veh_info_valid = true; 208 | } 209 | // 2U : DoIP Entities with given EID 210 | else if (_preselection_mode == 2U && (_preselection_value_length == 6U)) 211 | { 212 | is_veh_info_valid = true; 213 | } 214 | else 215 | { 216 | } 217 | } 218 | // 0U : No preselection 219 | else if (_preselection_mode == 0U && (_preselection_value_length == 0U)) 220 | { 221 | is_veh_info_valid = true; 222 | } 223 | else 224 | { 225 | } 226 | return is_veh_info_valid; 227 | } 228 | 229 | // Function to deserialize the received Vehicle Identification Response/ Announcement 230 | private static Pair 231 | DeserializeVehicleInfoResponse(UdsMessage _message) 232 | { 233 | byte start_index_vin = 0; 234 | byte total_vin_length = 17; 235 | byte start_index_eid = 19; 236 | byte start_index_gid = 25; 237 | byte total_eid_gid_length = 6; 238 | 239 | string vehicle_info_data_vin = Utils.ConvertToAsciiString(start_index_vin, total_vin_length, _message.GetPayload()); 240 | string vehicle_info_data_eid = Utils.ConvertToHexString(start_index_eid, total_eid_gid_length, _message.GetPayload()); 241 | string vehicle_info_data_gid = Utils.ConvertToHexString(start_index_gid, total_eid_gid_length, _message.GetPayload()); 242 | 243 | UInt16 logical_address = ((UInt16)(((_message.GetPayload()[17] & 0xFF) << 8) | (_message.GetPayload()[18] & 0xFF))); 244 | 245 | // Create the structure out of the extracted string 246 | VehicleAddrInfoResponseStruct vehicle_addr_info = new() 247 | { 248 | Ip_address = _message.GetHostIpAddress(), // remote ip address 249 | Logical_address = logical_address, // logical address 250 | VIN = vehicle_info_data_vin, // vin 251 | EID = vehicle_info_data_eid, // eid 252 | GID = vehicle_info_data_gid // gid 253 | }; 254 | 255 | return new(logical_address, vehicle_addr_info); 256 | } 257 | 258 | // Get Conversation Handlers 259 | public ConversionHandler GetConversationHandler() 260 | { 261 | return vd_conversion_handler_; 262 | } 263 | 264 | private static Pair 265 | DeserializeVehicleInfoRequest(VehicleAddrInfoRequest _vehicle_info_request) 266 | { 267 | 268 | Pair ret_val = new(_vehicle_info_request.Preselection_mode, new()); 269 | 270 | if (ret_val.First == 1U) 271 | { 272 | // 1U : DoIP Entities with given VIN 273 | Utils.SerializeVINFromString(_vehicle_info_request.Preselection_value, ret_val.Second, 274 | (byte)_vehicle_info_request.Preselection_value.Length, 1); 275 | } 276 | else if (ret_val.First == 2U) 277 | { 278 | // 2U : DoIP Entities with given EID 279 | _vehicle_info_request.Preselection_value = new(_vehicle_info_request.Preselection_value.Where(c => c != ':').ToArray()); 280 | 281 | Utils.SerializeEIDGIDFromString(_vehicle_info_request.Preselection_value, ret_val.Second, 282 | (byte)_vehicle_info_request.Preselection_value.Length, 2); 283 | } 284 | return ret_val; 285 | } 286 | }; 287 | 288 | /* 289 | @ Class Name : DmConversationHandler 290 | @ Class Description : Class to establish connection with Diagnostic Server 291 | */ 292 | public class VdConversationHandler : ConversionHandler 293 | { 294 | private VdConversation vd_conversation_; 295 | // ctor 296 | public VdConversationHandler(ConversionHandlerID _handler_id, VdConversation _vd_conversion) 297 | :base(_handler_id) 298 | { 299 | vd_conversation_ = _vd_conversion; 300 | } 301 | 302 | // Indicate message Diagnostic message reception over TCP to user 303 | public override Pair IndicateMessage(Address _source_addr, 304 | Address _target_addr, 305 | TargetAddressType _type, 306 | ChannelID _channel_id, 307 | int _size, 308 | Priority _priority, 309 | ProtocolKind _protocol_kind, 310 | List _payloadInfo) 311 | { 312 | return (vd_conversation_.IndicateMessage(_source_addr, _target_addr, _type, _channel_id, 313 | _size, _priority, _protocol_kind, _payloadInfo)); 314 | } 315 | 316 | // Hands over a valid message to conversion 317 | public override void HandleMessage(UdsMessage _message) 318 | { 319 | vd_conversation_.HandleMessage(_message); 320 | } 321 | }; 322 | } 323 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Dcm_client.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Common; 2 | using Diag_Doip_Uds.Appl.Dcm.Config_parser; 3 | using Diag_Doip_Uds.Appl.Dcm.Connection; 4 | using Diag_Doip_Uds.Appl.Dcm.Conversation; 5 | using Diag_Doip_Uds.Appl.Include; 6 | using Newtonsoft.Json; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using static Diag_Doip_Uds.Lib.Common.Common_header; 13 | 14 | namespace Diag_Doip_Uds.Appl.Dcm 15 | { 16 | /* 17 | @ Class Name : DCM Client 18 | @ Class Description : Class to create Diagnostic Manager Client functionality 19 | */ 20 | public sealed class DCMClient : DiagnosticManager 21 | { 22 | // uds transport protocol Manager 23 | private UdsTransportProtocolManager uds_transport_protocol_mgr; 24 | 25 | // conversation manager 26 | private ConversationManager conversation_mgr; 27 | 28 | // map to store conversation pointer along with conversation name 29 | private Dictionary diag_client_conversation_map; 30 | 31 | // store the diag client conversation for vehicle discovery 32 | private VdConversation diag_client_vehicle_discovery_conversation; 33 | 34 | //ctor 35 | public DCMClient(string _config_file) : base() 36 | { 37 | uds_transport_protocol_mgr = new UdsTransportProtocolManager(); 38 | conversation_mgr = new ConversationManager(GetDcmClientConfig(_config_file), uds_transport_protocol_mgr); 39 | diag_client_vehicle_discovery_conversation = 40 | conversation_mgr.GetDiagnosticClientVehicleDiscoveryConversation("VehicleDiscovery"); 41 | diag_client_conversation_map = new(); 42 | } 43 | 44 | // Initialize 45 | public override void Initialize() 46 | { 47 | // start Vehicle Discovery 48 | diag_client_vehicle_discovery_conversation?.Startup(); 49 | // start Conversation Manager 50 | conversation_mgr.Startup(); 51 | // start all the udsTransportProtocol Layer 52 | uds_transport_protocol_mgr.Startup(); 53 | } 54 | 55 | // Run 56 | public override void Run() 57 | { 58 | // run udsTransportProtocol layer 59 | uds_transport_protocol_mgr.Run(); 60 | } 61 | 62 | // Shutdown 63 | public override void Shutdown() 64 | { 65 | // shutdown Vehicle Discovery 66 | diag_client_vehicle_discovery_conversation?.Shutdown(); 67 | // shutdown Conversation Manager 68 | conversation_mgr.Shutdown(); 69 | // shutdown udsTransportProtocol layer 70 | uds_transport_protocol_mgr.Shutdown(); 71 | } 72 | 73 | // Function to get the diagnostic client conversation 74 | public override IDiagClientConversation 75 | GetDiagnosticClientConversation(string _conversation_name) 76 | { 77 | string diag_client_conversation_name = _conversation_name; 78 | IDiagClientConversation? ret_conversation = null; 79 | IDiagClientConversation? conversation = 80 | conversation_mgr.GetDiagnosticClientConversation(diag_client_conversation_name); 81 | if (conversation != null) 82 | { 83 | diag_client_conversation_map.Add( _conversation_name, conversation); 84 | ret_conversation = diag_client_conversation_map[diag_client_conversation_name]; 85 | } 86 | return ret_conversation; 87 | } 88 | 89 | // function to read from property tree to config structure 90 | private static DcmClientConfig? GetDcmClientConfig(string _config_file) 91 | { 92 | DcmClientConfig? config = null; 93 | if (!File.Exists(_config_file)) 94 | { 95 | return config; 96 | } 97 | 98 | try 99 | { 100 | string str = File.ReadAllText(_config_file); 101 | if (str.Length == 0) 102 | { 103 | return config; 104 | } 105 | else 106 | { 107 | config = JsonConvert.DeserializeObject(str, new JsonSerializerSettings 108 | { 109 | TypeNameHandling = TypeNameHandling.Auto 110 | }); 111 | } 112 | } 113 | catch (Exception ex) 114 | { 115 | Console.WriteLine(ex.Message.ToString()); 116 | } 117 | return config; 118 | } 119 | 120 | // Send Vehicle Identification Request and get response 121 | public override Pair 122 | SendVehicleIdentificationRequest(VehicleAddrInfoRequest _vehicle_info_request) 123 | { 124 | return diag_client_vehicle_discovery_conversation.SendVehicleIdentificationRequest(_vehicle_info_request); 125 | } 126 | }; 127 | } 128 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Service/Dm_uds_message.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Include; 2 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Diag_Doip_Uds.Appl.Dcm.Service 11 | { 12 | using Address = UInt16; 13 | using PortNumber = UInt16; 14 | using MetaInfoMap = Dictionary; 15 | // Ip address 16 | using IpAddress = String; 17 | public sealed class DmUdsMessage : UdsMessage 18 | { 19 | // ctor 20 | public DmUdsMessage(Address _sa, Address _ta, IpAddress _host_ip_address, List _payload) 21 | : base() 22 | { 23 | source_address_ = _sa; 24 | target_address_ = _ta; 25 | target_address_type_ = TargetAddressType.kPhysical; 26 | host_ip_address_ = _host_ip_address; 27 | uds_payload_ = _payload; 28 | } 29 | // SA 30 | private Address source_address_; 31 | 32 | // TA 33 | private Address target_address_; 34 | 35 | // TA type 36 | private TargetAddressType target_address_type_; 37 | 38 | // Host Ip Address 39 | private string host_ip_address_; 40 | 41 | // store only UDS payload to be sent 42 | private List uds_payload_; 43 | 44 | // add new metaInfo to this message. 45 | public override void AddMetaInfo(MetaInfoMap _meta_info) 46 | { 47 | // Todo [Add meta info information] 48 | } 49 | 50 | // Get the UDS message data starting with the SID (A_Data as per ISO) 51 | public override List GetPayload(){ return uds_payload_; } 52 | 53 | // Get the source address of the uds message. 54 | public override Address GetSa() { return source_address_; } 55 | 56 | // Get the target address of the uds message. 57 | public override Address GetTa() { return target_address_; } 58 | 59 | // Get the target address type (phys/func) of the uds message. 60 | public override TargetAddressType GetTaType() { return target_address_type_; } 61 | 62 | // Get Host Ip address 63 | public override IpAddress GetHostIpAddress() { return host_ip_address_; } 64 | 65 | // Get Host port number 66 | public override PortNumber GetHostPortNumber() { return 13400; } 67 | }; 68 | 69 | public sealed class DmUdsResponse : IUdsMessage 70 | { 71 | public DmUdsResponse(List _payload) 72 | { 73 | uds_payload_ = _payload; 74 | } 75 | // store only UDS payload to be sent 76 | private List uds_payload_; 77 | // Host Ip Address 78 | IpAddress host_ip_address_ = string.Empty; 79 | 80 | // Get the UDS message data starting with the SID (A_Data as per ISO) 81 | public List GetPayload() { return uds_payload_; } 82 | 83 | // Get Host Ip address 84 | public IpAddress GetHostIpAddress(){ return host_ip_address_; } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Dcm/Service/Vd_message.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Appl.Dcm.Service 10 | { 11 | using Address = UInt16; 12 | using PortNumber = UInt16; 13 | using MetaInfoMap = Dictionary; 14 | // Ip address 15 | using IpAddress = String; 16 | public sealed class VdMessage : UdsMessage 17 | { 18 | // ctor 19 | public VdMessage(byte _preselection_mode, List _preselection_value, 20 | string _host_ip_address) : base() 21 | { 22 | source_address_ = 0; 23 | target_address_ = 0; 24 | target_address_type = TargetAddressType.kPhysical; 25 | host_ip_address_ = _host_ip_address; 26 | vehicle_info_payload_ = SerializeVehicleInfoList(_preselection_mode, _preselection_value); 27 | } 28 | 29 | // default ctor 30 | public VdMessage() : base() 31 | { 32 | source_address_ = 0; 33 | target_address_ = 0; 34 | target_address_type = TargetAddressType.kPhysical; 35 | host_ip_address_ = string.Empty; 36 | vehicle_info_payload_ = new(); 37 | } 38 | 39 | private List SerializeVehicleInfoList(byte _preselection_mode, List _preselection_value) 40 | { 41 | byte VehicleIdentificationHandler = 0; 42 | List payload = new List { VehicleIdentificationHandler, _preselection_mode }; 43 | payload.AddRange(_preselection_value); 44 | return payload; 45 | } 46 | 47 | // SA 48 | private Address source_address_; 49 | 50 | // TA 51 | private Address target_address_; 52 | 53 | // TA type 54 | private TargetAddressType target_address_type; 55 | 56 | // Host Ip Address 57 | private IpAddress host_ip_address_; 58 | 59 | // store the vehicle info payload 60 | private List vehicle_info_payload_; 61 | 62 | // store the 63 | private MetaInfoMap meta_info_ = new(); 64 | 65 | // add new metaInfo to this message. 66 | public override void AddMetaInfo(MetaInfoMap _meta_info) 67 | { 68 | // update meta info data 69 | if (_meta_info != null) { 70 | meta_info_ = _meta_info; 71 | host_ip_address_ = meta_info_["kRemoteIpAddress"]; 72 | } 73 | } 74 | 75 | // Get the UDS message data starting with the SID (A_Data as per ISO) 76 | public override List GetPayload() { return vehicle_info_payload_; } 77 | 78 | // Get the source address of the uds message. 79 | public override Address GetSa() { return source_address_; } 80 | 81 | // Get the target address of the uds message. 82 | public override Address GetTa() { return target_address_; } 83 | 84 | // Get the target address type (phys/func) of the uds message. 85 | public override TargetAddressType GetTaType() { return target_address_type; } 86 | 87 | // Get Host Ip address 88 | public override IpAddress GetHostIpAddress() { return host_ip_address_; } 89 | // Get Host port number 90 | public override PortNumber GetHostPortNumber() { return 13400; } 91 | }; 92 | } 93 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Diagnostic_client_impl.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Common; 2 | using Diag_Doip_Uds.Appl.Dcm; 3 | using Diag_Doip_Uds.Appl.Include; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using static Diag_Doip_Uds.Lib.Common.Common_header; 10 | 11 | namespace Diag_Doip_Uds.Appl 12 | { 13 | public sealed class DiagClientImpl : IDiagClient 14 | { 15 | // dcm client instance 16 | private DiagnosticManager dcm_instance_ptr; 17 | 18 | // thread to hold dcm client instance 19 | private Thread? dcm_thread_; 20 | 21 | // ctor 22 | public DiagClientImpl(string _dm_client_config) 23 | { 24 | dcm_instance_ptr = new DCMClient(_dm_client_config); 25 | dcm_thread_ = null; 26 | } 27 | 28 | // Initialize 29 | public void Initialize() 30 | { 31 | dcm_thread_ = new Thread(() => 32 | { 33 | dcm_instance_ptr.Main(); 34 | }); 35 | dcm_thread_.Name = "DCMClient_Main"; 36 | dcm_thread_.Start(); 37 | } 38 | 39 | // De-Initialize 40 | public void DeInitialize() 41 | { 42 | dcm_instance_ptr.SignalShutdown(); 43 | if(dcm_thread_ != null) 44 | { 45 | dcm_thread_.Join(); 46 | } 47 | } 48 | 49 | // Get Required Conversation based on Conversation Name 50 | public IDiagClientConversation GetDiagnosticClientConversation(string _conversation_name) 51 | { 52 | return dcm_instance_ptr.GetDiagnosticClientConversation(_conversation_name); 53 | } 54 | 55 | // Send Vehicle Identification Request and get response 56 | public Pair 57 | SendVehicleIdentificationRequest(VehicleAddrInfoRequest _vehicle_info_request) 58 | { 59 | return dcm_instance_ptr.SendVehicleIdentificationRequest(_vehicle_info_request); 60 | } 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Include/Create_diagnostic_client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Appl.Include 8 | { 9 | public class DiagClientHelper 10 | { 11 | /** 12 | * @brief Function to get the instance of Diagnostic Client Object. 13 | * This instance to be further used for all the functionalities. 14 | * @param[in] diag_client_config_path 15 | * path to diag client config file 16 | * @return std::unique_ptr 17 | * Unique pointer to diag client object 18 | * @remarks Implemented requirements: 19 | * DiagClientLib-Library-Support, DiagClientLib-ComParam-Settings 20 | */ 21 | public static IDiagClient CreateDiagnosticClient(string _diag_client_config_path) 22 | { 23 | return new DiagClientImpl(_diag_client_config_path); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Include/Diagnostic_client_vehicle_info_message_type.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Appl.Include 8 | { 9 | /** 10 | * @brief Alias to collection of Vehicle info response 11 | */ 12 | using VehicleInfoListResponseType = List; 13 | /** 14 | * @brief Structure containing available Vehicle Address Information 15 | */ 16 | public class VehicleAddrInfoResponse 17 | { 18 | /** 19 | * @brief IP address of the vehicle 20 | */ 21 | public string Ip_address { get; set; } = string.Empty; 22 | 23 | /** 24 | * @brief Logical address of the vehicle 25 | */ 26 | public UInt16 Logical_address { get; set; } 27 | 28 | /** 29 | * @brief VIN of the vehicle 30 | */ 31 | public string VIN { get; set; } = string.Empty; 32 | 33 | /** 34 | * @brief Entity Identification of the vehicle 35 | */ 36 | public string EID { get; set; } = string.Empty; 37 | 38 | /** 39 | * @brief Group Identification of the vehicle 40 | */ 41 | public string GID { get; set; } = string.Empty; 42 | }; 43 | 44 | /** 45 | * @brief Struct containing Vehicle selection mode. 46 | */ 47 | public class VehicleAddrInfoRequest 48 | { 49 | /** 50 | * @brief Mode to be used during sending of Vehicle Identification request. 51 | * 0U : No preselection 52 | * 1U : DoIP Entities with given VIN 53 | * 2U : DoIP Entities with given EID 54 | */ 55 | public byte Preselection_mode { get; set; } = 0; 56 | 57 | /** 58 | * @brief Value to be used based on preselection mode. 59 | * VIN when preselection_mode = 1U 60 | * EID when preselection_mode = 2U 61 | * Empty when preselection_mode = 0U 62 | */ 63 | public string Preselection_value { get; set; } = string.Empty; 64 | }; 65 | 66 | /** 67 | * @brief Class provide storage of list of all available vehicle entity 68 | */ 69 | public interface IVehicleInfoMessage 70 | { 71 | /** 72 | * @brief Function to get the list of vehicle available in the network. 73 | * @return VehicleInfoListResponseType 74 | * Result returned 75 | */ 76 | public VehicleInfoListResponseType GetVehicleList(); 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Include/IDiagnostic_client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using static Diag_Doip_Uds.Lib.Common.Common_header; 7 | 8 | namespace Diag_Doip_Uds.Appl.Include 9 | { 10 | /** 11 | * @brief Definitions of Vehicle Identification response result 12 | */ 13 | public enum VehicleResponseResult : byte 14 | { 15 | kTransmitFailed = 0, /* Failure on Transmissions */ 16 | kInvalidParameters = 1, /* Invalid Parameter passed */ 17 | kNoResponseReceived = 2, /* No vehicle identification response received */ 18 | kStatusOk = 3 /* Vehicle identification response received success */ 19 | }; 20 | 21 | /** 22 | * @brief Class to manage Diagnostic Client 23 | */ 24 | public interface IDiagClient 25 | { 26 | /** 27 | * @brief Function to initialize the already created instance of DiagClient 28 | * @details Must be called once and before using any other functions of DiagClient 29 | * @remarks Implemented requirements: 30 | * DiagClientLib-Initialization 31 | */ 32 | public void Initialize(); 33 | 34 | /** 35 | * @brief Function to de-initialize the already initialized instance of DiagClient 36 | * @details Must be called during shutdown phase, no further processing of any 37 | * function will be allowed after this call 38 | * @remarks Implemented requirements: 39 | * DiagClientLib-DeInitialization 40 | */ 41 | public void DeInitialize(); 42 | 43 | /** 44 | * @brief Function to send vehicle identification request and get the Diagnostic Server list 45 | * @param[in] vehicle_info_request 46 | * Vehicle information sent along with request 47 | * @return std::pair 48 | * Pair consisting the result & response, contains valid response when result = kStatusOk 49 | * @remarks Implemented requirements: 50 | * DiagClientLib-VehicleDiscovery 51 | */ 52 | public Pair 53 | SendVehicleIdentificationRequest(VehicleAddrInfoRequest _vehicle_info_request); 54 | 55 | /** 56 | * @brief Function to get required diag client conversation object based on conversation name 57 | * @param[in] conversation_name 58 | * Name of conversation configured as json parameter "ConversationName" 59 | * @return DiagClientConversation& 60 | * Reference to diag client conversation 61 | * @remarks Implemented requirements: 62 | * DiagClientLib-MultipleTester-Connection, DiagClientLib-Conversation-Construction 63 | */ 64 | public IDiagClientConversation GetDiagnosticClientConversation(string _conversation_name); 65 | 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Include/IDiagnostic_client_conversation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Appl.Include 9 | { 10 | using static Diag_Doip_Uds.Lib.Common.Common_header; 11 | 12 | /** 13 | * @brief Type alias of ip address type 14 | */ 15 | using IpAddress = String; 16 | 17 | /** 18 | * @brief Definitions of Connection results 19 | */ 20 | public enum ConnectResult : byte 21 | { 22 | kConnectSuccess = 0, /* Successfully connected to Diagnostic Server */ 23 | kConnectFailed = 1, /* Connection failure to Diagnostic Server, check logs for more failure information */ 24 | kConnectTimeout = 2 /* No Connection response received from Diagnostic Server */ 25 | }; 26 | 27 | /** 28 | * @brief Definitions of Disconnection results 29 | */ 30 | public enum DisconnectResult : byte 31 | { 32 | kDisconnectSuccess = 0, /* Successfully disconnected from Diagnostic Server */ 33 | kDisconnectFailed = 1, /* Disconnection failure with Diagnostic Server, check logs for more information */ 34 | kAlreadyDisconnected = 2 /* Not connected to Diagnostic Server */ 35 | }; 36 | 37 | /** 38 | * @brief Definitions of Diagnostics Request Response results 39 | */ 40 | public enum DiagResult : byte 41 | { 42 | kDiagSuccess = 0, /* Diagnostic request message transmitted and response received successfully */ 43 | kDiagGenericFailure = 1, /* Generic Diagnostic Error, see logs for more information */ 44 | kDiagRequestSendFailed = 2, /* Diagnostic request message transmission failure */ 45 | kDiagAckTimeout = 3, /* No diagnostic acknowledgement response received within 2 seconds */ 46 | kDiagNegAckReceived = 4, /* Diagnostic negative acknowledgement received */ 47 | kDiagResponseTimeout = 5, /* No diagnostic response message received within P2/P2Star time */ 48 | kDiagInvalidParameter = 6, /* Passed parameter value is not valid */ 49 | kDiagBusyProcessing = 7 /* Conversation is already busy processing previous request */ 50 | }; 51 | 52 | 53 | /** 54 | * @brief Conversation class to establish connection with a Diagnostic Server 55 | * @details Conversation class only support DoIP communication protocol for connecting to remote ECU 56 | */ 57 | public interface IDiagClientConversation 58 | { 59 | /** 60 | * @brief Function to startup the Diagnostic Client Conversation 61 | * @details Must be called once and before using any other functions of DiagClientConversation 62 | * @remarks Implemented requirements: 63 | * DiagClientLib-Conversation-StartUp 64 | */ 65 | public void Startup(); 66 | 67 | /** 68 | * @brief Function to shutdown the Diagnostic Client Conversation 69 | * @details Must be called during shutdown phase, no further processing of any 70 | * function will be allowed after this call 71 | * @remarks Implemented requirements: 72 | * DiagClientLib-Conversation-Shutdown 73 | */ 74 | public void Shutdown(); 75 | 76 | /** 77 | * @brief Function to connect to Diagnostic Server. 78 | * @param[in] target_address 79 | * Logical address of the Remote server 80 | * @param[in] host_ip_addr 81 | * IP address of the Remote server 82 | * @return ConnectResult 83 | * Connection result returned 84 | * @remarks Implemented requirements: 85 | * DiagClientLib-Conversation-Connect 86 | */ 87 | public ConnectResult ConnectToDiagServer(UInt16 _target_address, IpAddress _host_ip_addr); 88 | 89 | /** 90 | * @brief Function to disconnect from Diagnostic Server 91 | * @return DisconnectResult 92 | * Disconnection result returned 93 | * @remarks Implemented requirements: 94 | * DiagClientLib-Conversation-Disconnect 95 | */ 96 | public DisconnectResult DisconnectFromDiagServer(); 97 | 98 | /** 99 | * @brief Function to send Diagnostic Request and get Diagnostic Response 100 | * @param[in] message 101 | * Diagnostic request message wrapped in a unique pointer 102 | * @return DiagResult 103 | * Result returned 104 | * @return uds_message::UdsResponseMessagePtr 105 | * Diagnostic Response message received, null_ptr in case of error 106 | * @remarks Implemented requirements: 107 | * DiagClientLib-Conversation-DiagRequestResponse 108 | */ 109 | public Pair SendDiagnosticRequest(IUdsMessage _message); 110 | }; 111 | } 112 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Appl/Include/IDiagnostic_client_uds_message_type.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Appl.Include 9 | { 10 | using IpAddress = String; 11 | /** 12 | * @brief Class represents an UDS message exchanged between User of diag-client-lib and implementation of 13 | * diag-client-lib on diagnostic request reception path or diagnostic response transmission path. 14 | * UdsMessage provides the storage for UDS requests/responses. 15 | */ 16 | public interface IUdsMessage 17 | { 18 | /** 19 | * @brief Get the UDS message data starting with the SID (A_Data as per ISO) 20 | * @return const ByteVector& 21 | * The entire payload (A_Data) 22 | */ 23 | public List GetPayload(); 24 | 25 | /** 26 | * @brief Get the remote ip address present 27 | * @return IpAddress 28 | * Ip address stored 29 | */ 30 | public IpAddress GetHostIpAddress(); 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Diag-Doip-Uds.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0 6 | Diag_Doip_Uds 7 | enable 8 | enable 9 | x64 10 | OnOutputUpdated 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Common/Common_header.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Common 8 | { 9 | public class Common_header 10 | { 11 | /* Magic numbers */ 12 | public const byte BYTE_POS_ZERO = 0x00; 13 | public const byte BYTE_POS_ONE = 0x01; 14 | public const byte BYTE_POS_TWO = 0x02; 15 | public const byte BYTE_POS_THREE = 0x03; 16 | public const byte BYTE_POS_FOUR = 0x04; 17 | public const byte BYTE_POS_FIVE = 0x05; 18 | public const byte BYTE_POS_SIX = 0x06; 19 | public const byte BYTE_POS_SEVEN = 0x07; 20 | 21 | public enum StdReturnType : byte 22 | { 23 | E_OK = 0x00, 24 | E_NOT_OK, 25 | E_BUSY 26 | } 27 | 28 | public class Pair 29 | { 30 | public F First { get; set; } 31 | public S Second { get; set; } 32 | 33 | public Pair(F _first, S _second) 34 | { 35 | this.First = _first; 36 | this.Second = _second; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Channel/Tcp_channel.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Common; 2 | using Diag_Doip_Uds.Lib.Doip_client.Handler; 3 | using Diag_Doip_Uds.Lib.Doip_client.Sockets; 4 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 5 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp; 6 | using SynchronizedTimer; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Diag_Doip_Uds.Lib.Doip_client.Channel 14 | { 15 | public delegate void Callback(); 16 | // socket state 17 | public enum tcpSocketState : byte { kSocketOffline = 0, kSocketOnline }; 18 | public class TcpChannel 19 | { 20 | // tcp socket handler 21 | private TcpSocketHandler tcp_socket_handler_; 22 | // tcp socket state 23 | private tcpSocketState tcp_socket_state_ = tcpSocketState.kSocketOffline; 24 | // tcp channel state 25 | private TcpChannelStateImpl tcp_channel_state_ = new(); 26 | // tcp channel handler 27 | private TcpChannelHandlerImpl tcp_channel_handler_; 28 | // sync timer 29 | private SyncTimer sync_timer_ = new(); 30 | 31 | //ctor 32 | public TcpChannel(string _localIpaddress, TcpTransportHandler _tcp_transport_handler) 33 | { 34 | tcp_socket_handler_ = new TcpSocketHandler(_localIpaddress, this); 35 | tcp_socket_state_ = tcpSocketState.kSocketOffline; 36 | tcp_channel_handler_ = new(tcp_socket_handler_, _tcp_transport_handler, this); 37 | } 38 | 39 | // Initialize 40 | public InitializationResult Initialize() 41 | { 42 | return (InitializationResult.kInitializeOk); 43 | } 44 | 45 | //Start 46 | public void Start() 47 | { 48 | tcp_socket_handler_.Start(); 49 | } 50 | 51 | // Stop 52 | public void Stop() 53 | { 54 | if (tcp_socket_state_ == tcpSocketState.kSocketOnline) 55 | { 56 | tcp_socket_handler_.Stop(); 57 | if (tcp_socket_handler_.DisconnectFromHost()) { tcp_socket_state_ = tcpSocketState.kSocketOffline; } 58 | } 59 | } 60 | 61 | // Check if already connected to host 62 | public bool IsConnectToHost() 63 | { 64 | return (tcp_socket_state_ == tcpSocketState.kSocketOnline); 65 | } 66 | 67 | // Function to connect to host 68 | public ConnectionResult ConnectToHost(UdsMessage _message) 69 | { 70 | ConnectionResult ret_val = ConnectionResult.kConnectionFailed; 71 | if (tcp_socket_state_ == tcpSocketState.kSocketOffline) 72 | { 73 | // sync connect to change the socket state 74 | if (tcp_socket_handler_.ConnectToHost(_message.GetHostIpAddress(), _message.GetHostPortNumber())) 75 | { 76 | // set socket state, tcp connection established 77 | tcp_socket_state_ = tcpSocketState.kSocketOnline; 78 | } 79 | else 80 | { // failure 81 | Console.WriteLine($"Doip Tcp socket connect failed for remote endpoints : " + 82 | $""); 83 | } 84 | } 85 | else 86 | { 87 | // socket already online 88 | Console.WriteLine($"Doip Tcp socket already connected"); 89 | } 90 | // If socket online, send routing activation req and get response 91 | if (tcp_socket_state_ == tcpSocketState.kSocketOnline) 92 | { 93 | // send routing activation request and get response 94 | ret_val = HandleRoutingActivationState(_message); 95 | } 96 | return ret_val; 97 | } 98 | 99 | // Function to disconnect from host 100 | public DisconnectionResult DisconnectFromHost() 101 | { 102 | DisconnectionResult ret_val = DisconnectionResult.kDisconnectionFailed; 103 | if (tcp_socket_state_ == tcpSocketState.kSocketOnline) 104 | { 105 | if (tcp_socket_handler_.DisconnectFromHost()) 106 | { 107 | tcp_socket_state_ = tcpSocketState.kSocketOffline; 108 | if (tcp_channel_state_.GetRoutingActivationStateContext().GetActiveState().GetState() == 109 | routingActivationState.kRoutingActivationSuccessful) 110 | { 111 | // reset previous routing activation 112 | tcp_channel_state_.GetRoutingActivationStateContext().TransitionTo(routingActivationState.kIdle); 113 | } 114 | ret_val = DisconnectionResult.kDisconnectionOk; 115 | } 116 | } 117 | else 118 | { 119 | Console.WriteLine($"Doip Tcp socket already in not connected state"); 120 | } 121 | return ret_val; 122 | } 123 | 124 | // Function to Hand over all the message received 125 | public void HandleMessage(TcpMessageType _tcp_rx_message) 126 | { 127 | tcp_channel_handler_.HandleMessage(_tcp_rx_message); 128 | } 129 | 130 | // Function to trigger transmission 131 | public TransmissionResult Transmit(UdsMessage _message) 132 | { 133 | TransmissionResult ret_val = TransmissionResult.kTransmitFailed; 134 | if (tcp_socket_state_ == tcpSocketState.kSocketOnline) 135 | { 136 | // routing activation should be active before sending diag request 137 | if (tcp_channel_state_.GetRoutingActivationStateContext().GetActiveState().GetState() == 138 | routingActivationState.kRoutingActivationSuccessful) 139 | { 140 | ret_val = HandleDiagnosticRequestState(_message); 141 | } 142 | else 143 | { 144 | Console.WriteLine($"Routing Activation required, please connect to server first"); 145 | } 146 | } 147 | else 148 | { 149 | Console.WriteLine($"Socket Offline, please connect to server first"); 150 | } 151 | return ret_val; 152 | } 153 | 154 | // Function to get the channel context 155 | public TcpChannelStateImpl GetChannelState() { return tcp_channel_state_; } 156 | 157 | // Function to wait for response 158 | public void WaitForResponse(Callback _timeout_func, Callback _cancel_func, int _msec) 159 | { 160 | if (sync_timer_.Start(_msec) == TimerState.kTimeout) 161 | { 162 | _timeout_func(); 163 | } 164 | else 165 | { 166 | _cancel_func(); 167 | } 168 | } 169 | 170 | // Function to cancel the synchronous wait 171 | public void WaitCancel() 172 | { 173 | sync_timer_.Stop(); 174 | } 175 | 176 | // Function to handle the routing states 177 | private ConnectionResult HandleRoutingActivationState(UdsMessage _message) 178 | { 179 | ConnectionResult result = ConnectionResult.kConnectionFailed; 180 | if (tcp_channel_state_.GetRoutingActivationStateContext().GetActiveState().GetState() == 181 | routingActivationState.kIdle) 182 | { 183 | if (tcp_channel_handler_.SendRoutingActivationRequest(_message) == 184 | TransmissionResult.kTransmitOk) 185 | { 186 | tcp_channel_state_.GetRoutingActivationStateContext().TransitionTo( 187 | routingActivationState.kWaitForRoutingActivationRes); 188 | WaitForResponse( 189 | () => { 190 | // todo : make sure result be assigned correctly 191 | ref ConnectionResult inner_result = ref result; 192 | inner_result = ConnectionResult.kConnectionTimeout; 193 | tcp_channel_state_.GetRoutingActivationStateContext().TransitionTo(routingActivationState.kIdle); 194 | Console.WriteLine($"RoutingActivation response timeout, no response received in : " + 195 | $"{Common_doip_types.kDoIPRoutingActivationTimeout} milliseconds"); 196 | }, 197 | () => { 198 | if (tcp_channel_state_.GetRoutingActivationStateContext().GetActiveState().GetState() == 199 | routingActivationState.kRoutingActivationSuccessful) 200 | { 201 | // success 202 | // todo : make sure result be assigned correctly 203 | ref ConnectionResult inner_result = ref result; 204 | inner_result = ConnectionResult.kConnectionOk; 205 | Console.WriteLine($"RoutingActivation successful with remote server"); 206 | } 207 | else 208 | { // failed 209 | tcp_channel_state_.GetRoutingActivationStateContext().TransitionTo( 210 | routingActivationState.kIdle); 211 | Console.WriteLine($"RoutingActivation failed with remote server"); 212 | } 213 | }, 214 | (int)Common_doip_types.kDoIPRoutingActivationTimeout); 215 | } 216 | else 217 | { 218 | // failed, do nothing 219 | tcp_channel_state_.GetRoutingActivationStateContext().TransitionTo(routingActivationState.kIdle); 220 | Console.WriteLine($"RoutingActivation Request send failed with remote server"); 221 | } 222 | } 223 | else 224 | { 225 | // channel not free 226 | Console.WriteLine($"RoutingActivation channel not free"); 227 | } 228 | return result; 229 | } 230 | 231 | // Function to handle the diagnostic request response state 232 | private TransmissionResult HandleDiagnosticRequestState(UdsMessage _message) 233 | { 234 | TransmissionResult result = TransmissionResult.kTransmitFailed; 235 | if (tcp_channel_state_.GetDiagnosticMessageStateContext().GetActiveState().GetState() == 236 | diagnosticState.kDiagIdle) 237 | { 238 | if (tcp_channel_handler_.SendDiagnosticRequest(_message) == 239 | TransmissionResult.kTransmitOk) 240 | { 241 | tcp_channel_state_.GetDiagnosticMessageStateContext().TransitionTo( 242 | diagnosticState.kWaitForDiagnosticAck); 243 | WaitForResponse( 244 | () => { 245 | ref TransmissionResult inner_result = ref result; 246 | inner_result = TransmissionResult.kNoTransmitAckReceived; 247 | tcp_channel_state_.GetDiagnosticMessageStateContext().TransitionTo( 248 | diagnosticState.kDiagIdle); 249 | Console.WriteLine($"Diagnostic Message Ack Request timed out, no response received" + 250 | $" in: {Common_doip_types.kDoIPDiagnosticAckTimeout} seconds"); 251 | }, 252 | () => { 253 | if (tcp_channel_state_.GetDiagnosticMessageStateContext().GetActiveState().GetState() == 254 | diagnosticState.kDiagnosticPositiveAckRecvd) 255 | { 256 | tcp_channel_state_.GetDiagnosticMessageStateContext().TransitionTo( 257 | diagnosticState.kWaitForDiagnosticResponse); 258 | // success 259 | ref TransmissionResult inner_result = ref result; 260 | inner_result = TransmissionResult.kTransmitOk; 261 | Console.WriteLine($"Diagnostic Message Positive Ack received"); 262 | } 263 | else 264 | { 265 | // failed with neg acknowledgement from server 266 | ref TransmissionResult inner_result = ref result; 267 | inner_result = TransmissionResult.kNegTransmitAckReceived; 268 | tcp_channel_state_.GetDiagnosticMessageStateContext().TransitionTo( 269 | diagnosticState.kDiagIdle); 270 | Console.WriteLine($"Diagnostic Message Transmission Failed Neg Ack Received"); 271 | } 272 | }, 273 | (int)Common_doip_types.kDoIPDiagnosticAckTimeout); 274 | } 275 | else 276 | { 277 | // failed, do nothing 278 | tcp_channel_state_.GetDiagnosticMessageStateContext().TransitionTo(diagnosticState.kDiagIdle); 279 | Console.WriteLine($"Diagnostic Request Message Transmission Failed"); 280 | } 281 | } 282 | else 283 | { 284 | // channel not in idle state 285 | result = TransmissionResult.kBusyProcessing; 286 | Console.WriteLine($"Diagnostic Message Transmission already in progress"); 287 | } 288 | return result; 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Channel/Tcp_channel_state_impl.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Utility_support.Utility; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Lib.Doip_client.Channel 10 | { 11 | // routing activation state 12 | public enum routingActivationState : byte 13 | { 14 | kIdle = 0, 15 | kWaitForRoutingActivationRes, 16 | kRoutingActivationSuccessful, 17 | kRoutingActivationFailed 18 | }; 19 | // Diagnostic state 20 | public enum diagnosticState : byte 21 | { 22 | kDiagIdle = 0, 23 | kSendDiagnosticReqFailed, 24 | kWaitForDiagnosticAck, 25 | kDiagnosticPositiveAckRecvd, 26 | kDiagnosticNegativeAckRecvd, 27 | kWaitForDiagnosticResponse, 28 | kDiagnosticFinalResRecvd 29 | }; 30 | 31 | public class TcpChannelStateImpl 32 | { 33 | // ctor 34 | public TcpChannelStateImpl() 35 | { 36 | routing_activation_state_context_ = new StateContext(); 37 | diagnostic_message_state_context_ = new StateContext(); 38 | 39 | // create and add state for routing activation 40 | // kIdle 41 | GetRoutingActivationStateContext().AddState( 42 | routingActivationState.kIdle, 43 | new kIdle(routingActivationState.kIdle)); 44 | // kWaitForRoutingActivationRes 45 | GetRoutingActivationStateContext().AddState( 46 | routingActivationState.kWaitForRoutingActivationRes, 47 | new kWaitForRoutingActivationRes(routingActivationState.kWaitForRoutingActivationRes)); 48 | // kRoutingActivationSuccessful 49 | GetRoutingActivationStateContext().AddState( 50 | routingActivationState.kRoutingActivationSuccessful, 51 | new kRoutingActivationSuccessful(routingActivationState.kRoutingActivationSuccessful)); 52 | // kRoutingActivationFailed 53 | GetRoutingActivationStateContext().AddState( 54 | routingActivationState.kRoutingActivationFailed, 55 | new kRoutingActivationFailed(routingActivationState.kRoutingActivationFailed)); 56 | // transit to idle state 57 | GetRoutingActivationStateContext().TransitionTo(routingActivationState.kIdle); 58 | 59 | // create and add state for Diagnostic State 60 | // kDiagIdle 61 | GetDiagnosticMessageStateContext().AddState( 62 | diagnosticState.kDiagIdle, 63 | new kDiagIdle(diagnosticState.kDiagIdle)); 64 | // kWaitForDiagnosticAck 65 | GetDiagnosticMessageStateContext().AddState( 66 | diagnosticState.kWaitForDiagnosticAck, 67 | new kWaitForDiagnosticAck(diagnosticState.kWaitForDiagnosticAck)); 68 | // kSendDiagnosticReqFailed 69 | GetDiagnosticMessageStateContext().AddState( 70 | diagnosticState.kSendDiagnosticReqFailed, 71 | new kSendDiagnosticReqFailed(diagnosticState.kSendDiagnosticReqFailed)); 72 | // kDiagnosticPositiveAckRecvd 73 | GetDiagnosticMessageStateContext().AddState( 74 | diagnosticState.kDiagnosticPositiveAckRecvd, 75 | new kDiagnosticPositiveAckRecvd(diagnosticState.kDiagnosticPositiveAckRecvd)); 76 | // kDiagnosticNegativeAckRecvd 77 | GetDiagnosticMessageStateContext().AddState( 78 | diagnosticState.kDiagnosticNegativeAckRecvd, 79 | new kDiagnosticNegativeAckRecvd(diagnosticState.kDiagnosticNegativeAckRecvd)); 80 | // kWaitForDiagnosticResponse 81 | GetDiagnosticMessageStateContext().AddState( 82 | diagnosticState.kWaitForDiagnosticResponse, 83 | new kWaitForDiagnosticResponse(diagnosticState.kWaitForDiagnosticResponse)); 84 | // transit to idle state 85 | GetDiagnosticMessageStateContext().TransitionTo(diagnosticState.kDiagIdle); 86 | } 87 | 88 | // Function to get the Routing Activation State context 89 | public StateContext GetRoutingActivationStateContext() 90 | { 91 | return routing_activation_state_context_; 92 | } 93 | 94 | // Function to get Diagnostic Message State context 95 | public StateContext GetDiagnosticMessageStateContext() 96 | { 97 | return diagnostic_message_state_context_; 98 | } 99 | 100 | // routing activation state 101 | private StateContext routing_activation_state_context_; 102 | // diagnostic state 103 | private StateContext diagnostic_message_state_context_; 104 | }; 105 | 106 | public sealed class kIdle : State 107 | { 108 | // ctor 109 | public kIdle(routingActivationState _state) : base(_state) 110 | { 111 | } 112 | 113 | // start the state 114 | public override void Start() 115 | { 116 | } 117 | 118 | // Stop the state 119 | public override void Stop() 120 | { 121 | } 122 | 123 | // Handle invoked asynchronously 124 | public override void HandleMessage() 125 | { 126 | } 127 | }; 128 | 129 | public sealed class kWaitForRoutingActivationRes : State 130 | { 131 | // ctor 132 | public kWaitForRoutingActivationRes(routingActivationState _state) : base(_state) 133 | { 134 | } 135 | 136 | // start the state 137 | public override void Start() 138 | { 139 | } 140 | 141 | // Stop the state 142 | public override void Stop() 143 | { 144 | } 145 | 146 | // Handle invoked asynchronously 147 | public override void HandleMessage() 148 | { 149 | } 150 | }; 151 | 152 | public sealed class kRoutingActivationSuccessful : State 153 | { 154 | // ctor 155 | public kRoutingActivationSuccessful(routingActivationState _state) : base(_state) 156 | { 157 | } 158 | 159 | // start the state 160 | public override void Start() 161 | { 162 | } 163 | 164 | // Stop the state 165 | public override void Stop() 166 | { 167 | } 168 | 169 | // Handle invoked asynchronously 170 | public override void HandleMessage() 171 | { 172 | } 173 | }; 174 | 175 | public sealed class kRoutingActivationFailed : State 176 | { 177 | // ctor 178 | public kRoutingActivationFailed(routingActivationState _state) : base(_state) 179 | { 180 | } 181 | 182 | // start the state 183 | public override void Start() 184 | { 185 | } 186 | 187 | // Stop the state 188 | public override void Stop() 189 | { 190 | } 191 | 192 | // Handle invoked asynchronously 193 | public override void HandleMessage() 194 | { 195 | } 196 | }; 197 | 198 | public sealed class kDiagIdle : State 199 | { 200 | // ctor 201 | public kDiagIdle(diagnosticState _state) : base(_state) 202 | { 203 | } 204 | 205 | // start the state 206 | public override void Start() 207 | { 208 | } 209 | 210 | // Stop the state 211 | public override void Stop() 212 | { 213 | } 214 | 215 | // Handle invoked asynchronously 216 | public override void HandleMessage() 217 | { 218 | } 219 | }; 220 | 221 | public sealed class kWaitForDiagnosticAck : State 222 | { 223 | // ctor 224 | public kWaitForDiagnosticAck(diagnosticState _state) : base(_state) 225 | { 226 | } 227 | 228 | // start the state 229 | public override void Start() 230 | { 231 | } 232 | 233 | // Stop the state 234 | public override void Stop() 235 | { 236 | } 237 | 238 | // Handle invoked asynchronously 239 | public override void HandleMessage() 240 | { 241 | } 242 | }; 243 | 244 | public sealed class kSendDiagnosticReqFailed : State 245 | { 246 | // ctor 247 | public kSendDiagnosticReqFailed(diagnosticState _state) : base(_state) 248 | { 249 | } 250 | 251 | // start the state 252 | public override void Start() 253 | { 254 | } 255 | 256 | // Stop the state 257 | public override void Stop() 258 | { 259 | } 260 | 261 | // Handle invoked asynchronously 262 | public override void HandleMessage() 263 | { 264 | } 265 | }; 266 | 267 | public sealed class kDiagnosticPositiveAckRecvd : State 268 | { 269 | // ctor 270 | public kDiagnosticPositiveAckRecvd(diagnosticState _state) : base(_state) 271 | { 272 | } 273 | 274 | // start the state 275 | public override void Start() 276 | { 277 | } 278 | 279 | // Stop the state 280 | public override void Stop() 281 | { 282 | } 283 | 284 | // Handle invoked asynchronously 285 | public override void HandleMessage() 286 | { 287 | } 288 | }; 289 | 290 | public sealed class kDiagnosticNegativeAckRecvd : State 291 | { 292 | // ctor 293 | public kDiagnosticNegativeAckRecvd(diagnosticState _state) : base(_state) 294 | { 295 | } 296 | 297 | // start the state 298 | public override void Start() 299 | { 300 | } 301 | 302 | // Stop the state 303 | public override void Stop() 304 | { 305 | } 306 | 307 | // Handle invoked asynchronously 308 | public override void HandleMessage() 309 | { 310 | } 311 | }; 312 | 313 | public sealed class kWaitForDiagnosticResponse : State 314 | { 315 | // ctor 316 | public kWaitForDiagnosticResponse(diagnosticState _state) : base(_state) 317 | { 318 | } 319 | 320 | // start the state 321 | public override void Start() 322 | { 323 | } 324 | 325 | // Stop the state 326 | public override void Stop() 327 | { 328 | } 329 | 330 | // Handle invoked asynchronously 331 | public override void HandleMessage() 332 | { 333 | } 334 | }; 335 | } 336 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Channel/Udp_channel.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Handler; 2 | using Diag_Doip_Uds.Lib.Doip_client.Sockets; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 4 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Udp; 5 | using SynchronizedTimer; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Diag_Doip_Uds.Lib.Doip_client.Channel 13 | { 14 | /* 15 | @ Class Name : UdpChannel 16 | @ Class Description : Class used to handle Doip Udp Channel 17 | */ 18 | public class UdpChannel 19 | { 20 | // udp transport handler ref 21 | private UdpTransportHandler udp_transport_handler_; 22 | // udp socket handler broadcast 23 | private UdpSocketHandler udp_socket_handler_bcast_; 24 | // udp socket handler unicast 25 | private UdpSocketHandler udp_socket_handler_ucast_; 26 | // udp channel state 27 | private UdpChannelStateImpl udp_channel_state_ = new(); 28 | // udp channel handler 29 | private UdpChannelHandlerImpl udp_channel_handler_; 30 | // Executor 31 | //private TaskExecutor task_executor_; //todo : 封装一个执行器 32 | // sync timer 33 | private SyncTimer sync_timer_ = new(); 34 | //ctor 35 | public UdpChannel(string _local_ip_address, UInt16 _port_num, UdpTransportHandler _udp_transport_handler) 36 | { 37 | udp_transport_handler_ = _udp_transport_handler; 38 | udp_socket_handler_bcast_ = new UdpSocketHandler( 39 | _local_ip_address, _port_num, PortType.kUdp_Broadcast, this); 40 | udp_socket_handler_ucast_ = new UdpSocketHandler( 41 | _local_ip_address, _port_num, PortType.kUdp_Unicast, this); 42 | udp_channel_handler_ = new(udp_socket_handler_bcast_, udp_socket_handler_ucast_, udp_transport_handler_, this); 43 | } 44 | 45 | // Initialize 46 | public InitializationResult Initialize() 47 | { 48 | InitializationResult ret_val = InitializationResult.kInitializeOk; 49 | return ret_val; 50 | } 51 | 52 | //Start 53 | public void Start() 54 | { 55 | udp_socket_handler_bcast_.Start(); 56 | udp_socket_handler_ucast_.Start(); 57 | } 58 | 59 | // Stop 60 | public void Stop() 61 | { 62 | udp_socket_handler_bcast_.Stop(); 63 | udp_socket_handler_ucast_.Stop(); 64 | } 65 | 66 | // function to handle read broadcast 67 | public void HandleMessageBroadcast(UdpMessageType _udp_rx_message) 68 | { 69 | udp_channel_handler_.HandleMessageBroadcast(_udp_rx_message); 70 | } 71 | 72 | // function to handle read unicast 73 | public void HandleMessageUnicast(UdpMessageType _udp_rx_message) 74 | { 75 | udp_channel_handler_.HandleMessage(_udp_rx_message); 76 | } 77 | 78 | // Function to trigger transmission of vehicle identification request 79 | public TransmissionResult Transmit(UdsMessage _message) 80 | { 81 | return udp_channel_handler_.Transmit(_message); 82 | } 83 | 84 | // Function to get the channel context 85 | public UdpChannelStateImpl GetChannelState() { return udp_channel_state_; } 86 | 87 | // Function to add job to executor 88 | public void SendVehicleInformationToUser() 89 | { 90 | } 91 | 92 | // Function to wait for response 93 | public void WaitForResponse(Callback _timeout_func, Callback _cancel_func, int _msec) 94 | { 95 | if (sync_timer_.Start(_msec) == TimerState.kTimeout) 96 | { 97 | _timeout_func(); 98 | } 99 | else 100 | { 101 | _cancel_func(); 102 | } 103 | } 104 | 105 | // Function to cancel the synchronous wait 106 | public void WaitCancel() 107 | { 108 | sync_timer_.Stop(); 109 | } 110 | }; 111 | } 112 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Channel/Udp_channel_state_impl.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Utility_support.Utility; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Lib.Doip_client.Channel 10 | { 11 | // Vehicle discovery state 12 | public enum VehicleDiscoveryState : byte { kVdIdle = 0, kWaitForVehicleAnnouncement, kVdDoIPCtrlTimeout }; 13 | // Vehicle Identification state 14 | public enum VehicleIdentificationState : byte 15 | { 16 | kViIdle = 0, 17 | kViSendVehicleIdentificationReq, 18 | kViWaitForVehicleIdentificationRes, 19 | kViDoIPCtrlTimeout 20 | }; 21 | 22 | public class UdpChannelStateImpl 23 | { 24 | // routing activation state 25 | private StateContext vehicle_discovery_state_context_; 26 | // diagnostic state 27 | private StateContext vehicle_identification_state_context_; 28 | // ctor 29 | public UdpChannelStateImpl() 30 | { 31 | vehicle_discovery_state_context_ = new StateContext(); 32 | vehicle_identification_state_context_ = new StateContext(); 33 | 34 | // create and add state for vehicle discovery 35 | // kVdIdle 36 | GetVehicleDiscoveryStateContext().AddState( 37 | VehicleDiscoveryState.kVdIdle, 38 | new kVdIdle(VehicleDiscoveryState.kVdIdle)); 39 | // kWaitForVehicleAnnouncement 40 | GetVehicleDiscoveryStateContext().AddState( 41 | VehicleDiscoveryState.kWaitForVehicleAnnouncement, 42 | new kWaitForVehicleAnnouncement(VehicleDiscoveryState.kWaitForVehicleAnnouncement)); 43 | // kVdDoIPCtrlTimeout 44 | GetVehicleDiscoveryStateContext().AddState( 45 | VehicleDiscoveryState.kVdDoIPCtrlTimeout, 46 | new kVdDoIPCtrlTimeout(VehicleDiscoveryState.kVdDoIPCtrlTimeout)); 47 | // Transit to idle 48 | GetVehicleDiscoveryStateContext().TransitionTo(VehicleDiscoveryState.kVdIdle); 49 | 50 | // create and add state for vehicle identification 51 | // kVdIdle 52 | GetVehicleIdentificationStateContext().AddState( 53 | VehicleIdentificationState.kViIdle, 54 | new kViIdle(VehicleIdentificationState.kViIdle)); 55 | // kViSendVehicleIdentificationReq 56 | GetVehicleIdentificationStateContext().AddState( 57 | VehicleIdentificationState.kViSendVehicleIdentificationReq, 58 | new kViSendVehicleIdentificationReq(VehicleIdentificationState.kViSendVehicleIdentificationReq)); 59 | // kViWaitForVehicleIdentificationRes 60 | GetVehicleIdentificationStateContext().AddState( 61 | VehicleIdentificationState.kViWaitForVehicleIdentificationRes, 62 | new kViWaitForVehicleIdentificationRes(VehicleIdentificationState.kViWaitForVehicleIdentificationRes)); 63 | // kViDoIPCtrlTimeout 64 | GetVehicleIdentificationStateContext().AddState( 65 | VehicleIdentificationState.kViDoIPCtrlTimeout, 66 | new kViDoIPCtrlTimeout(VehicleIdentificationState.kViDoIPCtrlTimeout)); 67 | // Transit to idle 68 | GetVehicleIdentificationStateContext().TransitionTo(VehicleIdentificationState.kViIdle); 69 | } 70 | 71 | // Function to get Vehicle Discovery State context 72 | public StateContext GetVehicleDiscoveryStateContext() 73 | { 74 | return vehicle_discovery_state_context_; 75 | } 76 | 77 | // Function to get Vehicle Identification State context 78 | public StateContext GetVehicleIdentificationStateContext() 79 | { 80 | return vehicle_identification_state_context_; 81 | } 82 | }; 83 | 84 | public sealed class kVdIdle : State 85 | { 86 | // ctor 87 | public kVdIdle(VehicleDiscoveryState _state) : base(_state) 88 | { 89 | } 90 | 91 | // start the state 92 | public override void Start() 93 | { 94 | } 95 | 96 | // Stop the state 97 | public override void Stop() 98 | { 99 | } 100 | 101 | // Handle invoked asynchronously 102 | public override void HandleMessage() 103 | { 104 | } 105 | }; 106 | 107 | public sealed class kWaitForVehicleAnnouncement : State 108 | { 109 | // ctor 110 | public kWaitForVehicleAnnouncement(VehicleDiscoveryState _state) : base(_state) 111 | { 112 | } 113 | 114 | // start the state 115 | public override void Start() 116 | { 117 | } 118 | 119 | // Stop the state 120 | public override void Stop() 121 | { 122 | } 123 | 124 | // Handle invoked asynchronously 125 | public override void HandleMessage() 126 | { 127 | } 128 | }; 129 | 130 | public sealed class kVdDoIPCtrlTimeout : State 131 | { 132 | // ctor 133 | public kVdDoIPCtrlTimeout(VehicleDiscoveryState _state) : base(_state) 134 | { 135 | } 136 | 137 | // start the state 138 | public override void Start() 139 | { 140 | } 141 | 142 | // Stop the state 143 | public override void Stop() 144 | { 145 | } 146 | 147 | // Handle invoked asynchronously 148 | public override void HandleMessage() 149 | { 150 | } 151 | }; 152 | 153 | public sealed class kViIdle : State 154 | { 155 | // ctor 156 | public kViIdle(VehicleIdentificationState _state) : base(_state) 157 | { 158 | } 159 | 160 | // start the state 161 | public override void Start() 162 | { 163 | } 164 | 165 | // Stop the state 166 | public override void Stop() 167 | { 168 | } 169 | 170 | // Handle invoked asynchronously 171 | public override void HandleMessage() 172 | { 173 | } 174 | }; 175 | 176 | public sealed class kViSendVehicleIdentificationReq : State 177 | { 178 | // ctor 179 | public kViSendVehicleIdentificationReq(VehicleIdentificationState _state) : base(_state) 180 | { 181 | } 182 | 183 | // start the state 184 | public override void Start() 185 | { 186 | } 187 | 188 | // Stop the state 189 | public override void Stop() 190 | { 191 | } 192 | 193 | // Handle invoked asynchronously 194 | public override void HandleMessage() 195 | { 196 | } 197 | }; 198 | 199 | public sealed class kViWaitForVehicleIdentificationRes : State 200 | { 201 | // ctor 202 | public kViWaitForVehicleIdentificationRes(VehicleIdentificationState _state) : base(_state) 203 | { 204 | } 205 | 206 | // start the state 207 | public override void Start() 208 | { 209 | } 210 | 211 | // Stop the state 212 | public override void Stop() 213 | { 214 | } 215 | 216 | // Handle invoked asynchronously 217 | public override void HandleMessage() 218 | { 219 | } 220 | }; 221 | 222 | public sealed class kViDoIPCtrlTimeout : State 223 | { 224 | // ctor 225 | public kViDoIPCtrlTimeout(VehicleIdentificationState _state) : base(_state) 226 | { 227 | } 228 | 229 | // start the state 230 | public override void Start() 231 | { 232 | } 233 | 234 | // Stop the state 235 | public override void Stop() 236 | { 237 | } 238 | 239 | // Handle invoked asynchronously 240 | public override void HandleMessage() 241 | { 242 | } 243 | }; 244 | } 245 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Common/Common_doip_types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Doip_client.Common 8 | { 9 | public class Common_doip_types 10 | { 11 | /* DoIP Port Number - Unsecured */ 12 | public const UInt16 kDoipPort = 13400; 13 | /* Udp Channel Length */ 14 | public const UInt32 kUdpChannelLength = 41U; 15 | /* Tcp Channel Length */ 16 | public const UInt32 kTcpChannelLength = 4096U; 17 | /* DoIP Header */ 18 | public const byte kDoipheadrSize = 0x8; 19 | public const byte kDoip_ProtocolVersion_2012 = 0x2; // ISO 13400-2012 20 | public const byte kDoip_ProtocolVersion_2019 = 0x3; // ISO 13400-2019 21 | public const byte kDoip_ProtocolVersion = kDoip_ProtocolVersion_2012; 22 | public const byte kDoip_ProtocolVersion_Def = 0xFF; 23 | public const UInt32 kDoip_Protocol_MaxPayload = 0xFFFFFFFF; // 4294967295 bytes 24 | /* Payload Types */ 25 | public const UInt16 kDoip_GenericHeadr_NackType = 0x0000; 26 | public const UInt16 kDoip_VehicleIdentification_ReqType = 0x0001; 27 | public const UInt16 kDoip_VehicleIdentificationEID_ReqType = 0x0002; 28 | public const UInt16 kDoip_VehicleIdentificationVIN_ReqType = 0x0003; 29 | public const UInt16 kDoip_VehicleAnnouncement_ResType = 0x0004; 30 | public const UInt16 kDoip_RoutingActivation_ReqType = 0x0005; 31 | public const UInt16 kDoip_RoutingActivation_ResType = 0x0006; 32 | public const UInt16 kDoip_AliveCheck_ReqType = 0x0007; 33 | public const UInt16 kDoip_AliveCheck_ResType = 0x0008; 34 | //constexpr UInt16 kDoipENTITY_STATUS_REQ_TYPE 0x4001 35 | //constexpr UInt16 kDoipENTITY_STATUS_RES_TYPE 0x4002 36 | //constexpr UInt16 kDoipDIAG_POWER_MODEINFO_REQ_TYPE 0x4003 37 | //constexpr UInt16 kDoipDIAG_POWER_MODEINFO_RES_TYPE 0x4004 38 | public const UInt16 kDoip_DiagMessage_Type = 0x8001; 39 | public const UInt16 kDoip_DiagMessagePosAck_Type = 0x8002; 40 | public const UInt16 kDoip_DiagMessageNegAck_Type = 0x8003; 41 | public const UInt16 kDoip_InvalidPayload_Type = 0xFFFF; 42 | /* Payload length excluding header */ 43 | public const byte kDoip_VehicleIdentification_ReqLen = 0; 44 | public const byte kDoip_VehicleIdentificationEID_ReqLen = 6; 45 | public const byte kDoip_VehicleIdentificationVIN_ReqLen = 17; 46 | public const byte kDoip_VehicleAnnouncement_ResMaxLen = 33; 47 | public const byte kDoip_GenericHeader_NackLen = 1; 48 | public const byte kDoip_RoutingActivation_ReqMinLen = 7; //without OEM specific use byte 49 | public const byte kDoip_RoutingActivation_ResMinLen = 9; //without OEM specific use byte 50 | public const byte kDoip_RoutingActivation_ReqMaxLen = 11; //with OEM specific use byte 51 | public const byte kDoip_RoutingActivation_ResMaxLen = 13; //with OEM specific use byte 52 | //constexpr byte kDoipALIVE_CHECK_RES_LEN 1 53 | public const byte kDoip_DiagMessage_ReqResMinLen = 4; // considering SA and TA 54 | public const byte kDoip_DiagMessageAck_ResMinLen = 5; // considering SA, TA, Ack code 55 | /* Generic DoIP Header NACK codes */ 56 | public const byte kDoip_GenericHeader_IncorrectPattern = 0x00; 57 | public const byte kDoip_GenericHeader_UnknownPayload = 0x01; 58 | public const byte kDoip_GenericHeader_MessageTooLarge = 0x02; 59 | public const byte kDoip_GenericHeader_OutOfMemory = 0x03; 60 | public const byte kDoip_GenericHeader_InvalidPayloadLen = 0x04; 61 | /* Routing Activation request activation types */ 62 | public const byte kDoip_RoutingActivation_ReqActType_Default = 0x00; 63 | public const byte kDoip_RoutingActivation_ReqActType_WWHOBD = 0x01; 64 | public const byte kDoip_RoutingActivation_ReqActType_CentralSec = 0xE0; 65 | /* Routing Activation response code values */ 66 | public const byte kDoip_RoutingActivation_ResCode_UnknownSA = 0x00; 67 | public const byte kDoip_RoutingActivation_ResCode_AllSocktActive = 0x01; 68 | public const byte kDoip_RoutingActivation_ResCode_DifferentSA = 0x02; 69 | public const byte kDoip_RoutingActivation_ResCode_ActiveSA = 0x03; 70 | public const byte kDoip_RoutingActivation_ResCode_AuthentnMissng = 0x04; 71 | public const byte kDoip_RoutingActivation_ResCode_ConfirmtnRejectd = 0x05; 72 | public const byte kDoip_RoutingActivation_ResCode_UnsupportdActType = 0x06; 73 | public const byte kDoip_RoutingActivation_ResCode_TLSRequired = 0x07; 74 | public const byte kDoip_RoutingActivation_ResCode_RoutingSuccessful = 0x10; 75 | public const byte kDoip_RoutingActivation_ResCode_ConfirmtnRequired = 0x11; 76 | /* Diagnostic Message positive acknowledgement code */ 77 | public const byte kDoip_DiagnosticMessage_PosAckCode_Confirm = 0x00; 78 | /* Diagnostic Message negative acknowledgement code */ 79 | public const byte kDoip_DiagnosticMessage_NegAckCode_InvalidSA = 0x02; 80 | public const byte kDoip_DiagnosticMessage_NegAckCode_UnknownTA = 0x03; 81 | public const byte kDoip_DiagnosticMessage_NegAckCode_MessageTooLarge = 0x04; 82 | public const byte kDoip_DiagnosticMessage_NegAckCode_OutOfMemory = 0x05; 83 | public const byte kDoip_DiagnosticMessage_NegAckCode_TargetUnreachable = 0x06; 84 | public const byte kDoip_DiagnosticMessage_NegAckCode_UnknownNetwork = 0x07; 85 | public const byte kDoip_DiagnosticMessage_NegAckCode_TPError = 0x08; 86 | 87 | /* Further action code values */ 88 | //constexpr byte kDoipNO_FURTHER_ACTION 0x00 89 | //constexpr byte kDoipFURTHER_ACTION_CENTRAL_SEC 0x10 90 | //constexpr byte kDoipFURTHER_VM_SPECIFIC_MIN 0x11 91 | //constexpr byte kDoipFURTHER_VM_SPECIFIC_MAX 0xFF 92 | /* VIN/GID Sync status Code values */ 93 | //constexpr byte kDoipVIN_GID_SYNC 0x00 94 | //constexpr byte kDoipVIN_GID_NOT_SYNC 0x10 95 | /* Vehicle identification parameter (invalidity pattern) */ 96 | public const byte kDoip_VIN_Invalid_FF = 0xFF; 97 | public const byte kDoip_VIN_Invalid_00 = 0x00; 98 | public const UInt16 kDoip_LogAddress_Invalid = 0xFFFF; 99 | public const byte kDoip_EID_Invalid_FF = 0xFF; 100 | public const byte kDoip_EID_Invalid_00 = 0x00; 101 | public const byte kDoip_GID_Invalid_FF = 0xFF; 102 | public const byte kDoip_GID_Invalid_00 = 0x00; 103 | /* DoIP timing and communication parameter (in millisecond) */ 104 | /* Description: This is used to configure the 105 | timeout value for a DoIP Routing Activation request */ 106 | public const UInt32 kDoIPRoutingActivationTimeout = 1000U; // 1 sec 107 | /* Description: This timeout specifies the maximum time that 108 | the test equipment waits for a confirmation ACK or NACK 109 | from the DoIP entity after the last byte of a DoIP Diagnostic 110 | request message has been sent 111 | */ 112 | public const UInt32 kDoIPDiagnosticAckTimeout = 2000U; // 2 sec 113 | /* Description: This timeout specifies the maximum time that the 114 | client waits for response to a previously sent UDP message. 115 | This includes max time to wait and collect multiple responses 116 | to previous broadcast(UDP only) 117 | * */ 118 | public const UInt32 kDoIPCtrl = 2000U; // 2 sec 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Common/Doip_payload_type.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Doip_client.Common 8 | { 9 | // ip address type 10 | using IpAddressType = String; 11 | public enum rx_socket_type : byte { kBroadcast, kUnicast }; 12 | public class DoipMessage 13 | { 14 | // rx type -> broadcast, unicast 15 | public rx_socket_type Rx_socket { get; set; } = rx_socket_type.kUnicast; 16 | // remote ip address; 17 | public IpAddressType Host_ip_address { get; set; } = string.Empty; 18 | // remote port number 19 | public UInt16 Host_port_number { get; set; } 20 | // doip protocol version 21 | public byte Protocol_version { get; set; } 22 | // doip protocol inverse version 23 | public byte Protocol_version_inv { get; set; } 24 | // doip payload type 25 | public UInt16 Payload_type { get; set; } 26 | // doip payload length 27 | public UInt32 Payload_length { get; set; } 28 | // doip payload 29 | public List Payload { get; set; } = new(); 30 | public DoipMessage() { } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Connection/Connection_manager.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Handler; 2 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 3 | using Microsoft.VisualBasic; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Diag_Doip_Uds.Lib.Doip_client.Doip_connection 12 | { 13 | using ChannelID = UInt32; 14 | // type for UDS source and target addresses 15 | using Address = UInt16; 16 | // This is the type of Priority 17 | using Priority = Byte; 18 | // This is the type of Protocol Kind 19 | using ProtocolKind = String; 20 | using static Diag_Doip_Uds.Lib.Common.Common_header; 21 | 22 | public class DoipTcpConnection : Connection 23 | { 24 | // Tcp Transport Handler 25 | private TcpTransportHandler tcp_transport_handler_; 26 | public DoipTcpConnection(ConversionHandler _conversation, string _tcp_ip_address, UInt16 _port_num) 27 | : base(1, _conversation) 28 | { 29 | tcp_transport_handler_ = new(_tcp_ip_address, _port_num, 1, this); 30 | } 31 | 32 | public override InitializationResult Initialize() 33 | { 34 | tcp_transport_handler_.Initialize(); 35 | return (InitializationResult.kInitializeOk); 36 | } 37 | 38 | public override void Start() { tcp_transport_handler_.Start(); } 39 | 40 | public override void Stop() { tcp_transport_handler_.Stop(); } 41 | 42 | public override bool IsConnectToHost() { return (tcp_transport_handler_.IsConnectToHost()); } 43 | 44 | public override ConnectionResult ConnectToHost(UdsMessage _message) 45 | { 46 | return (tcp_transport_handler_.ConnectToHost(_message)); 47 | } 48 | 49 | public override DisconnectionResult DisconnectFromHost() 50 | { 51 | return (tcp_transport_handler_.DisconnectFromHost()); 52 | } 53 | 54 | public override Pair IndicateMessage(Address _source_addr, 55 | Address _target_addr, 56 | TargetAddressType _type, 57 | ChannelID _channel_id, 58 | int _size, 59 | Priority _priority, 60 | ProtocolKind _protocol_kind, 61 | List _payloadInfo) 62 | { 63 | // Send Indication to conversion 64 | return (conversation_.IndicateMessage(_source_addr, _target_addr, _type, _channel_id, 65 | _size, _priority, _protocol_kind, _payloadInfo)); 66 | } 67 | 68 | public override TransmissionResult Transmit(UdsMessage _message) 69 | { 70 | ChannelID channel_id = 0; 71 | return (tcp_transport_handler_.Transmit(_message, channel_id)); 72 | } 73 | 74 | public override void HandleMessage(UdsMessage _message) 75 | { 76 | // send full message to conversion 77 | conversation_.HandleMessage(_message); 78 | } 79 | } 80 | 81 | public class DoipUdpConnection : Connection 82 | { 83 | // Udp Transport Handler 84 | private UdpTransportHandler udp_transport_handler_; 85 | 86 | // ctor 87 | public DoipUdpConnection(ConversionHandler _conversation, string _udp_ip_address, UInt16 _port_num) 88 | : base(1, _conversation) 89 | { 90 | udp_transport_handler_ = new(_udp_ip_address, _port_num, this); 91 | } 92 | 93 | // Initialize 94 | public override InitializationResult Initialize() 95 | { 96 | udp_transport_handler_.Initialize(); 97 | return InitializationResult.kInitializeOk; 98 | } 99 | 100 | // Start the connection 101 | public override void Start() { udp_transport_handler_.Start(); } 102 | 103 | // Stop the connection 104 | public override void Stop() { udp_transport_handler_.Stop(); } 105 | 106 | // Check if already connected to host 107 | public override bool IsConnectToHost() { return false; } 108 | 109 | // Connect to host using the ip address 110 | public override ConnectionResult ConnectToHost(UdsMessage _message) 111 | { 112 | return (ConnectionResult.kConnectionFailed); 113 | } 114 | 115 | // Disconnect from Host Server 116 | public override DisconnectionResult DisconnectFromHost() 117 | { 118 | return (DisconnectionResult.kDisconnectionFailed); 119 | } 120 | 121 | // Indicate message Diagnostic message reception over TCP to user 122 | public override Pair IndicateMessage(Address _source_addr, 123 | Address _target_addr, 124 | TargetAddressType _type, 125 | ChannelID _channel_id, 126 | int _size, 127 | Priority _priority, 128 | ProtocolKind _protocol_kind, 129 | List _payloadInfo) 130 | { 131 | // Send Indication to conversion 132 | return (conversation_.IndicateMessage(_source_addr, _target_addr, _type, _channel_id, 133 | _size, _priority, _protocol_kind, _payloadInfo)); 134 | } 135 | 136 | // Transmit tcp 137 | public override TransmissionResult Transmit(UdsMessage _message) 138 | { 139 | ChannelID channel_id = 0; 140 | return (udp_transport_handler_.Transmit(_message, channel_id)); 141 | } 142 | 143 | // Hands over a valid message to conversion 144 | public override void HandleMessage(UdsMessage _message) 145 | { 146 | // send full message to conversion 147 | conversation_.HandleMessage(_message); 148 | } 149 | } 150 | 151 | public class DoipConnectionManager 152 | { 153 | // ctor 154 | public DoipConnectionManager() { } 155 | 156 | // Function to create new connection to handle doip tcp request and response 157 | public DoipTcpConnection FindOrCreateTcpConnection(ConversionHandler _conversation, 158 | string _tcp_ip_address, 159 | UInt16 _port_num) 160 | { 161 | return (new DoipTcpConnection(_conversation, _tcp_ip_address, _port_num)); 162 | } 163 | 164 | // Function to create new connection to handle doip udp request and response 165 | public DoipUdpConnection FindOrCreateUdpConnection(ConversionHandler _conversation, 166 | string _udp_ip_address, 167 | UInt16 _port_num) 168 | { 169 | return (new DoipUdpConnection(_conversation, _udp_ip_address, _port_num)); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Doip_transport_protocol_handler.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Doip_connection; 2 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 3 | using Microsoft.VisualBasic; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Diag_Doip_Uds.Lib.Doip_client 11 | { 12 | // UdsTransportProtocolHandler are flexible "plugins", which need an identification 13 | using UdsTransportProtocolHandlerID = Byte; 14 | /* 15 | @ Class Name : DoipTransportProtocolHandler 16 | @ Class Description : This class must be instantiated by user for using the DoIP functionalities. 17 | This will inherit uds transport protocol handler 18 | */ 19 | public sealed class DoipTransportProtocolHandler : UdsTransportProtocolHandler 20 | { 21 | // store handle id 22 | private UdsTransportProtocolHandlerID handle_id_e; 23 | // store the transport protocol manager 24 | private UdsTransportProtocolMgr transport_protocol_mgr_; 25 | // Create Doip Connection Manager 26 | private DoipConnectionManager doip_connection_mgr_ptr; 27 | 28 | //ctor 29 | public DoipTransportProtocolHandler(UdsTransportProtocolHandlerID _handler_id, 30 | UdsTransportProtocolMgr _transport_protocol_mgr) : base(_handler_id, _transport_protocol_mgr) 31 | { 32 | handle_id_e = _handler_id; 33 | transport_protocol_mgr_ = _transport_protocol_mgr; 34 | doip_connection_mgr_ptr = new(); 35 | } 36 | 37 | // Return the UdsTransportProtocolHandlerID, which was given to the implementation during construction (ctor call). 38 | public override UdsTransportProtocolHandlerID GetHandlerID() 39 | { 40 | return handle_id_e; 41 | } 42 | 43 | // Initializes handler 44 | public override InitializationResult Initialize() 45 | { 46 | return InitializationResult.kInitializeOk; 47 | } 48 | 49 | // Start processing the implemented Uds Transport Protocol 50 | public override void Start() 51 | { 52 | } 53 | 54 | // Method to indicate that this UdsTransportProtocolHandler should terminate 55 | public override void Stop() 56 | { 57 | } 58 | 59 | // Get or Create Tcp connection 60 | public override Connection FindOrCreateTcpConnection(ConversionHandler _conversation, 61 | string _tcp_ip_address, 62 | UInt16 _port_num) 63 | { 64 | return doip_connection_mgr_ptr.FindOrCreateTcpConnection(_conversation, 65 | _tcp_ip_address, 66 | _port_num); 67 | } 68 | 69 | // Get or Create Udp connection 70 | public override Connection FindOrCreateUdpConnection(ConversionHandler _conversation, 71 | string _udp_ip_address, 72 | UInt16 _port_num) 73 | { 74 | return doip_connection_mgr_ptr.FindOrCreateUdpConnection(_conversation, 75 | _udp_ip_address, 76 | _port_num); 77 | } 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Handler/Tcp_transport_handler.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Doip_client.Doip_connection; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Diag_Doip_Uds.Lib.Doip_client.Handler 12 | { 13 | using ChannelID = UInt32; 14 | // type for UDS source and target addresses 15 | using Address = UInt16; 16 | // This is the type of Priority 17 | using Priority = Byte; 18 | // This is the type of Protocol Kind 19 | using ProtocolKind = String; 20 | using static Diag_Doip_Uds.Lib.Common.Common_header; 21 | 22 | public class TcpTransportHandler 23 | { 24 | // reference to doip connection 25 | private DoipTcpConnection doip_connection_; 26 | // Tcp channel responsible for transmitting and reception of TCP messages 27 | private TcpChannel tcp_channel_; 28 | 29 | // ctor 30 | public TcpTransportHandler(string _local_ip_address, UInt16 _port_num, byte _total_tcp_channel_req, 31 | DoipTcpConnection _doip_connection) 32 | { 33 | doip_connection_ = _doip_connection; 34 | tcp_channel_ = new TcpChannel(_local_ip_address, this); 35 | } 36 | 37 | // Initialize 38 | public InitializationResult Initialize() 39 | { 40 | return (tcp_channel_.Initialize()); 41 | } 42 | 43 | // Start 44 | public void Start() { tcp_channel_.Start(); } 45 | 46 | // Stop 47 | public void Stop() { tcp_channel_.Stop(); } 48 | 49 | // Check if already connected to host 50 | public bool IsConnectToHost() { return (tcp_channel_.IsConnectToHost()); } 51 | 52 | // Connect to remote Host 53 | public ConnectionResult ConnectToHost(UdsMessage _message) 54 | { 55 | return (tcp_channel_.ConnectToHost(_message)); 56 | } 57 | 58 | // Disconnect from remote Host 59 | public DisconnectionResult DisconnectFromHost() 60 | { 61 | return (tcp_channel_.DisconnectFromHost()); 62 | } 63 | 64 | // Transmit 65 | public TransmissionResult Transmit(UdsMessage _message,ChannelID _channel_id) 66 | { 67 | // find the corresponding channel 68 | // Trigger transmit 69 | return (tcp_channel_.Transmit(_message)); 70 | } 71 | 72 | // Indicate message Diagnostic message reception over TCP to user 73 | public Pair IndicateMessage(Address _source_addr, 74 | Address _target_addr, 75 | TargetAddressType _type, 76 | ChannelID _channel_id, 77 | int _size, 78 | Priority _priority, 79 | ProtocolKind _protocol_kind, 80 | List _payloadInfo) 81 | { 82 | return (doip_connection_.IndicateMessage(_source_addr, _target_addr, _type, _channel_id, 83 | _size, _priority, _protocol_kind, _payloadInfo)); 84 | } 85 | 86 | // Hands over a valid received Uds message (currently this is only a request type) from transport 87 | // layer to session layer 88 | public void HandleMessage(UdsMessage _message) 89 | { 90 | doip_connection_.HandleMessage(_message); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Handler/Udp_transport_handler.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Doip_client.Doip_connection; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Diag_Doip_Uds.Lib.Doip_client.Handler 12 | { 13 | using ChannelID = UInt32; 14 | // type for UDS source and target addresses 15 | using Address = UInt16; 16 | // This is the type of Priority 17 | using Priority = Byte; 18 | // This is the type of Protocol Kind 19 | using ProtocolKind = String; 20 | using static Diag_Doip_Uds.Lib.Common.Common_header; 21 | 22 | public class UdpTransportHandler 23 | { 24 | // reference to doip Connection 25 | private DoipUdpConnection doip_connection_; 26 | // Udp channel responsible for transmitting and reception of UDP messages 27 | private UdpChannel udp_channel_; 28 | 29 | // ctor 30 | public UdpTransportHandler(string _localIpaddress, UInt16 _portNum, DoipUdpConnection _doipConnection) 31 | { 32 | doip_connection_ = _doipConnection; 33 | udp_channel_ = new(_localIpaddress, _portNum, this); 34 | } 35 | 36 | // Initialize 37 | public InitializationResult Initialize() 38 | { 39 | return (udp_channel_.Initialize()); 40 | } 41 | 42 | // Start 43 | public void Start() 44 | { 45 | udp_channel_.Start(); 46 | } 47 | 48 | // Stop 49 | public void Stop() 50 | { 51 | udp_channel_.Stop(); 52 | } 53 | 54 | // Transmit 55 | public TransmissionResult Transmit(UdsMessage _message, ChannelID _channel_id) 56 | { 57 | return (udp_channel_.Transmit(_message)); 58 | } 59 | 60 | // Indicate message Diagnostic message reception over UDP to user 61 | public Pair IndicateMessage(Address _source_addr, 62 | Address _target_addr, 63 | TargetAddressType _type, 64 | ChannelID _channel_id, 65 | int _size, 66 | Priority _priority, 67 | ProtocolKind _protocol_kind, 68 | List _payloadInfo) 69 | { 70 | return (doip_connection_.IndicateMessage(_source_addr, _target_addr, _type, _channel_id, 71 | _size, _priority, _protocol_kind, _payloadInfo)); 72 | } 73 | 74 | // Hands over a valid received UDP message (currently this is only a request type) from transport 75 | // layer to session layer 76 | public void HandleMessage(UdsMessage _message) 77 | { 78 | doip_connection_.HandleMessage(_message); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Sockets/Tcp_socket_handler.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Channels; 8 | using System.Threading.Tasks; 9 | 10 | namespace Diag_Doip_Uds.Lib.Doip_client.Sockets 11 | { 12 | public class TcpSocketHandler 13 | { 14 | // local Ip address 15 | private string local_ip_address_ = string.Empty; 16 | // local port number 17 | private UInt16 local_port_num_; 18 | // tcp socket 19 | private CreateTcpClientSocket tcpSocket_; 20 | // store tcp channel reference 21 | private TcpChannel channel_; 22 | 23 | // ctor 24 | public TcpSocketHandler(string _localIpaddress, TcpChannel _channel) 25 | { 26 | local_ip_address_ = _localIpaddress; 27 | local_port_num_ = 0; 28 | channel_ = _channel; 29 | //create socket 30 | tcpSocket_ = new CreateTcpClientSocket(local_ip_address_, local_port_num_, 31 | (TcpMessageType _tcpMessage) => {channel_.HandleMessage(_tcpMessage); 32 | }); 33 | } 34 | 35 | // Start 36 | public void Start() 37 | { 38 | } 39 | 40 | // Stop 41 | public void Stop() 42 | { 43 | } 44 | 45 | // Connect to host 46 | public bool ConnectToHost(string _host_ip_address, UInt16 _host_port_num) 47 | { 48 | bool ret_val = false; 49 | if (tcpSocket_.Open()) { ret_val = tcpSocket_.ConnectToHost(_host_ip_address, _host_port_num); } 50 | return ret_val; 51 | } 52 | 53 | // Disconnect from host 54 | public bool DisconnectFromHost() 55 | { 56 | bool ret_val = false; 57 | if (tcpSocket_.DisconnectFromHost()) { ret_val = tcpSocket_.Destroy(); } 58 | return ret_val; 59 | } 60 | 61 | // Transmit function 62 | public bool Transmit(TcpMessageType _tcp_message) 63 | { 64 | return (tcpSocket_.Transmit(_tcp_message)); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Doip_client/Sockets/Udp_socket_handler.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Doip_client.Channel; 2 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp; 3 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Udp; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Channels; 9 | using System.Threading.Tasks; 10 | 11 | namespace Diag_Doip_Uds.Lib.Doip_client.Sockets 12 | { 13 | public class UdpSocketHandler 14 | { 15 | // local Ip address 16 | private string local_ip_address_ = string.Empty; 17 | // Host Ip address 18 | private string host_ip_address_ = string.Empty; 19 | // Host port number 20 | private UInt16 port_num_; 21 | // Port type 22 | private PortType port_type_; 23 | // udp socket 24 | private CreateUdpClientSocket udp_socket_; 25 | // store tcp channel reference 26 | private UdpChannel channel_; 27 | 28 | //ctor 29 | public UdpSocketHandler(string _local_ip_address, UInt16 _port_num, PortType _port_type, 30 | UdpChannel _channel) 31 | { 32 | local_ip_address_ = _local_ip_address; 33 | port_num_ = _port_num; 34 | port_type_ = _port_type; 35 | channel_ = _channel; 36 | // create sockets and start receiving 37 | if (_port_type == PortType.kUdp_Broadcast) 38 | { 39 | udp_socket_ = new CreateUdpClientSocket( 40 | local_ip_address_, port_num_, port_type_, 41 | (UdpMessageType _udp_rx_message) => { channel_.HandleMessageBroadcast(_udp_rx_message); }); 42 | } 43 | else 44 | { 45 | udp_socket_ = new CreateUdpClientSocket( 46 | local_ip_address_, port_num_, port_type_, 47 | (UdpMessageType _udp_rx_message) => { channel_.HandleMessageUnicast(_udp_rx_message); }); 48 | } 49 | } 50 | 51 | //start 52 | public void Start() { udp_socket_.Open(); } 53 | 54 | //stop 55 | public void Stop() { udp_socket_.Destroy(); } 56 | 57 | // function to trigger transmission 58 | public bool Transmit(UdpMessageType _udp_tx_message) 59 | { 60 | return (udp_socket_.Transmit(_udp_tx_message)); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Connection.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Channels; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 10 | { 11 | // type alias for connection id 12 | using ConnectionId = Byte; 13 | using Address = UInt16; 14 | // This is the type of Channel Id 15 | using ChannelID = UInt32; 16 | // This is the type of Priority 17 | using Priority = Byte; 18 | // This is the type of Protocol Kind 19 | using ProtocolKind = String; 20 | using static Diag_Doip_Uds.Lib.Common.Common_header; 21 | 22 | public abstract class Connection 23 | { 24 | // store the connection id 25 | private ConnectionId connection_id_; 26 | // Store the conversion 27 | protected ConversionHandler conversation_; 28 | 29 | // ctor 30 | public Connection(ConnectionId _connection_id, ConversionHandler _conversation) 31 | { 32 | conversation_ = _conversation; 33 | connection_id_ = _connection_id; 34 | } 35 | 36 | // Initialize 37 | public abstract InitializationResult Initialize(); 38 | 39 | // Start the connection 40 | public abstract void Start(); 41 | 42 | // Stop the connection 43 | public abstract void Stop(); 44 | 45 | // Check if already connected to host 46 | public abstract bool IsConnectToHost(); 47 | 48 | // Connect to Host Server 49 | public abstract ConnectionResult ConnectToHost(UdsMessage message); 50 | 51 | // Disconnect from Host Server 52 | public abstract DisconnectionResult DisconnectFromHost(); 53 | 54 | // Indicate message Diagnostic message reception over TCP to user 55 | public abstract Pair IndicateMessage( Address _source_addr, 56 | Address _target_addr, 57 | TargetAddressType _type, 58 | ChannelID _channel_id, 59 | int _size, 60 | Priority _priority, 61 | ProtocolKind _protocol_kind, 62 | List _payloadInfo); 63 | 64 | // Transmit tcp/udp data 65 | public abstract TransmissionResult Transmit(UdsMessage message); 66 | 67 | // Hands over a valid message to conversion 68 | public abstract void HandleMessage(UdsMessage message); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Conversion_handler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Channels; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 9 | { 10 | using ConversionHandlerID = Byte; 11 | using Address = UInt16; 12 | // This is the type of Channel Id 13 | using ChannelID = UInt32; 14 | // This is the type of Priority 15 | using Priority = Byte; 16 | // This is the type of Protocol Kind 17 | using ProtocolKind = String; 18 | using static Diag_Doip_Uds.Lib.Common.Common_header; 19 | 20 | public abstract class ConversionHandler 21 | { 22 | protected ConversionHandlerID handler_id_; 23 | 24 | // ctor 25 | public ConversionHandler(ConversionHandlerID _handler_id) { handler_id_ = _handler_id; } 26 | 27 | // Indicate message Diagnostic message reception over TCP/UDP to user 28 | public abstract Pair IndicateMessage( Address _source_addr, 29 | Address _target_addr, 30 | TargetAddressType _type, 31 | ChannelID _channel_id, 32 | int _size, 33 | Priority _priority, 34 | ProtocolKind _protocol_kind, 35 | List _payloadInfo); 36 | 37 | // Hands over a valid message to conversion 38 | public abstract void HandleMessage(UdsMessage message); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Protocol_handler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 9 | { 10 | using UdsTransportProtocolHandlerID = Byte; 11 | public enum InitializationResult : byte { kInitializeOk = 0, kInitializeFailed = 1 }; 12 | public abstract class UdsTransportProtocolHandler 13 | { 14 | protected UdsTransportProtocolHandlerID handler_id_; 15 | private UdsTransportProtocolMgr? transport_protocol_mgr_; 16 | 17 | //ctor 18 | public UdsTransportProtocolHandler(UdsTransportProtocolHandlerID _handler_id, 19 | UdsTransportProtocolMgr _transport_protocol_mgr) 20 | { 21 | handler_id_ = _handler_id; 22 | transport_protocol_mgr_ = _transport_protocol_mgr; 23 | } 24 | 25 | // Return the UdsTransportProtocolHandlerID 26 | public virtual UdsTransportProtocolHandlerID GetHandlerID() { return handler_id_; } 27 | 28 | // Initialize 29 | public abstract InitializationResult Initialize(); 30 | 31 | // Start processing the implemented Uds Transport Protocol 32 | public abstract void Start(); 33 | 34 | // Method to indicate that this UdsTransportProtocolHandler should terminate 35 | public abstract void Stop(); 36 | 37 | // Get or Create a Tcp Connection 38 | public abstract Connection FindOrCreateTcpConnection(ConversionHandler _conversion_handler, 39 | string _tcpIpaddress, 40 | UInt16 _portNum); 41 | 42 | // Get or Create an Udp Connection 43 | public abstract Connection FindOrCreateUdpConnection(ConversionHandler _conversion_handler, 44 | string _udpIpaddress, 45 | UInt16 _portNum); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Protocol_mgr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Channels; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 9 | { 10 | // This is the type of Channel Id 11 | using ChannelID = UInt32; 12 | // UdsTransportProtocolHandler are flexible "plugins", which need an identification 13 | using UdsTransportProtocolHandlerID = Byte; 14 | // Type of tuple to pack UdsTransportProtocolHandlerID and ChannelID together, to form a global 15 | // unique (among all used UdsTransportProtocolHandlers within DM) identifier of a UdsTransport 16 | // Protocol channel. 17 | //using GlobalChannelIdentifier = Tuple; 18 | // Result for Indication of message received 19 | public enum IndicationResult : byte 20 | { 21 | kIndicationOk = 0, 22 | kIndicationOccupied, 23 | kIndicationOverflow, 24 | kIndicationUnknownTargetAddress, 25 | kIndicationPending, 26 | kIndicationNOk 27 | }; 28 | // Result for transmission of message sent 29 | public enum TransmissionResult : byte 30 | { 31 | kTransmitOk = 0, 32 | kTransmitFailed, 33 | kNoTransmitAckReceived, 34 | kNegTransmitAckReceived, 35 | kBusyProcessing 36 | }; 37 | // Result for connection to remote endpoint 38 | public enum ConnectionResult : byte { kConnectionOk = 0, kConnectionFailed, kConnectionTimeout }; 39 | // Result for disconnection to remote endpoint 40 | public enum DisconnectionResult : byte { kDisconnectionOk = 0, kDisconnectionFailed }; 41 | public abstract class UdsTransportProtocolMgr 42 | { 43 | //ctor 44 | public UdsTransportProtocolMgr() { } 45 | 46 | // initialize all the transport protocol handler 47 | public abstract void Startup(); 48 | 49 | // start all the transport protocol handler 50 | public abstract void Run(); 51 | 52 | // terminate all the transport protocol handler 53 | public abstract void Shutdown(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Protocol_types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 8 | { 9 | namespace Conversion_manager 10 | { 11 | // Conversation identification needed by user 12 | using ConversionHandlerID = Byte; 13 | public class ConversionIdentifierType 14 | { 15 | // Reception buffer 16 | public UInt32 Rx_buffer_size { get; set; } 17 | // p2 client time 18 | public UInt16 P2_client_max { get; set; } 19 | // p2 star Client time 20 | public UInt16 P2_star_client_max { get; set; } 21 | // source address of client 22 | public UInt16 Source_address { get; set; } 23 | // self tcp address 24 | public string Tcp_address { get; set; } = string.Empty; 25 | // self udp address 26 | public string Udp_address { get; set; } = string.Empty; 27 | // Vehicle broadcast address 28 | public string? Udp_broadcast_address { get; set; } = string.Empty; 29 | // Port Number 30 | public UInt16 Port_num { get; set; } 31 | // conversion handler ID 32 | public ConversionHandlerID Handler_id { get; set; } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Uds_transport_layer_api/Uds_transport/Uds_message.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport 9 | { 10 | using Address = UInt16; 11 | using PortNumber = UInt16; 12 | using MetaInfoMap = Dictionary; 13 | using IpAddress = String; 14 | public enum TargetAddressType : byte 15 | { 16 | kPhysical = 0, 17 | kFunctional = 1, 18 | } 19 | public abstract class UdsMessage 20 | { 21 | public UdsMessage() { } 22 | 23 | // add new metaInfo to this message. 24 | public abstract void AddMetaInfo(MetaInfoMap _meta_info); 25 | 26 | // Get the UDS message data starting with the SID (A_Data as per ISO) 27 | public abstract List GetPayload(); 28 | 29 | // return the underlying buffer for write access 30 | //public abstract List GetPayload(); 31 | 32 | // Get the source address of the uds message. 33 | public abstract Address GetSa(); 34 | 35 | // Get the target address of the uds message. 36 | public abstract Address GetTa(); 37 | 38 | // Get the target address type (phys/func) of the uds message. 39 | public abstract TargetAddressType GetTaType(); 40 | 41 | // Get Host Ip address 42 | public abstract IpAddress GetHostIpAddress(); 43 | 44 | // Get Host port number 45 | public abstract PortNumber GetHostPortNumber(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Socket/Tcp/Tcp_client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Sockets; 5 | using System.Net; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Diag_Doip_Uds.Lib.Doip_client.Common; 9 | 10 | namespace Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp 11 | { 12 | public class CreateTcpClientSocket 13 | { 14 | // local Ip address 15 | private string local_ip_address_ = string.Empty; 16 | // local port number 17 | private UInt16 local_port_num_; 18 | // tcp socket 19 | private System.Net.Sockets.Socket? tcp_socket_; 20 | // flag to terminate the thread 21 | //private bool exit_request_; 22 | // flag th start the thread 23 | //private bool running_; 24 | // conditional variable to block the thread 25 | //private std::condition_variable cond_var_; 26 | // threading var 27 | private Thread? thread_ = null; 28 | // locking critical section 29 | //private Mutex mutex_; 30 | // Handler invoked during read operation 31 | private TcpHandlerRead tcp_handler_read_; 32 | //通过Interlocked.Exchange原子化读写,is_connected调整为int型,0表示false,1表示true 33 | private /*bool*/int is_connected; 34 | 35 | //ctor 36 | public CreateTcpClientSocket(string _local_ip_address, UInt16 _local_port_num, TcpHandlerRead _tcp_handler_read) 37 | { 38 | local_ip_address_ = _local_ip_address; 39 | local_port_num_ = _local_port_num; 40 | tcp_handler_read_ = _tcp_handler_read; 41 | tcp_socket_ = null; 42 | Interlocked.Exchange(ref is_connected, 0); 43 | } 44 | 45 | // Function to Open the socket 46 | public bool Open() 47 | { 48 | bool retVal = false; 49 | try 50 | { 51 | // 创建 TCP Socket 52 | tcp_socket_ = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 53 | 54 | // 设置 Socket 为非阻塞模式 55 | tcp_socket_.Blocking = false; 56 | 57 | // 设置 Socket 选项,允许地址重用 58 | tcp_socket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 59 | 60 | // 绑定到本地地址和随机端口 61 | IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(local_ip_address_), local_port_num_); 62 | tcp_socket_.Bind(localEndPoint); 63 | 64 | Console.WriteLine($"Tcp Socket opened and bound to <{localEndPoint.Address.ToString()}, {localEndPoint.Port}>"); 65 | retVal = true; 66 | } 67 | catch(Exception ex) 68 | { 69 | Console.WriteLine(ex.Message.ToString()); 70 | } 71 | return retVal; 72 | } 73 | 74 | // Function to Connect to host 75 | public bool ConnectToHost(string _host_ip_address, UInt16 _host_port_num) 76 | { 77 | bool ret_val = false; 78 | 79 | if (tcp_socket_ == null) return ret_val; 80 | try 81 | { 82 | IAsyncResult result = tcp_socket_.BeginConnect(IPAddress.Parse(_host_ip_address), _host_port_num, null, null); 83 | bool success = result.AsyncWaitHandle.WaitOne(2000); // 等待2秒 84 | if (success) 85 | { 86 | tcp_socket_.EndConnect(result); 87 | // 启动接收数据的线程 88 | Interlocked.Exchange(ref is_connected, 1); 89 | thread_ = new Thread(HandleMessage); 90 | thread_.Start(); 91 | ret_val = true; 92 | } 93 | else 94 | { 95 | Console.WriteLine($"Tcp Socket connect to <{_host_ip_address}, {_host_port_num}> failed"); 96 | } 97 | } 98 | catch (Exception) 99 | { 100 | Console.WriteLine($"Tcp Socket connect to <{_host_ip_address}, {_host_port_num}> failed"); 101 | } 102 | return ret_val; 103 | } 104 | 105 | // Function to Disconnect from host 106 | public bool DisconnectFromHost() 107 | { 108 | bool ret_val = false; 109 | 110 | if (tcp_socket_ != null) 111 | { 112 | tcp_socket_.Shutdown(SocketShutdown.Both); 113 | 114 | Interlocked.Exchange(ref is_connected, 0); 115 | thread_?.Join(); 116 | ret_val = true; 117 | } 118 | 119 | return ret_val; 120 | } 121 | 122 | // Function to trigger transmission 123 | public bool Transmit(TcpMessageType _tcpMessage) 124 | { 125 | bool ret_val = false; 126 | if (tcp_socket_ == null) return ret_val; 127 | try 128 | { 129 | var send_length = tcp_socket_.Send(_tcpMessage.TxBuffer_.ToArray()); 130 | if(send_length == _tcpMessage.TxBuffer_.Count) 131 | { 132 | var remote_endpoint = tcp_socket_.RemoteEndPoint as IPEndPoint; 133 | if(remote_endpoint != null) 134 | { 135 | Console.WriteLine($"Tcp message sent to {remote_endpoint.Address.ToString()}, {remote_endpoint.Port}>"); 136 | ret_val = true; 137 | } 138 | } 139 | } 140 | catch(Exception ex) 141 | { 142 | Console.WriteLine($"Tcp message sending failed with error : {ex.Message.ToString()}"); 143 | } 144 | return ret_val; 145 | } 146 | 147 | // Function to destroy the socket 148 | public bool Destroy() 149 | { 150 | if (tcp_socket_ != null) 151 | { 152 | tcp_socket_.Shutdown(SocketShutdown.Both); 153 | tcp_socket_.Close(); 154 | tcp_socket_ = null; 155 | 156 | Interlocked.Exchange(ref is_connected, 0); 157 | thread_?.Join(); 158 | } 159 | return true; 160 | } 161 | // function to handle read 162 | private void HandleMessage() 163 | { 164 | if (tcp_socket_ == null) return; 165 | byte[] receiveBuffer = new byte[1024]; 166 | 167 | while (is_connected == 1) 168 | { 169 | TcpMessageType tcp_rx_message = new(); 170 | try 171 | { 172 | if (tcp_socket_.Poll(50000, SelectMode.SelectRead)) 173 | { 174 | //todo : make sure bytesRead > Common_doip_types.kDoipheadrSize 175 | int bytesRead = tcp_socket_.Receive(receiveBuffer, Common_doip_types.kDoipheadrSize, 0); 176 | if (bytesRead == Common_doip_types.kDoipheadrSize) 177 | { 178 | tcp_rx_message.RxBuffer_.AddRange(receiveBuffer.Take(Common_doip_types.kDoipheadrSize)); 179 | UInt32 read_next_bytes = ((UInt32)((UInt32)((tcp_rx_message.RxBuffer_[4] << 24) & 0xFF000000) | 180 | (UInt32)((tcp_rx_message.RxBuffer_[5] << 16) & 0x00FF0000) | 181 | (UInt32)((tcp_rx_message.RxBuffer_[6] << 8) & 0x0000FF00) | 182 | (UInt32)((tcp_rx_message.RxBuffer_[7] & 0x000000FF)))); 183 | 184 | //continue reading payload 185 | Array.Resize(ref receiveBuffer, (int)read_next_bytes); 186 | Array.Clear(receiveBuffer, 0, receiveBuffer.Length); 187 | bytesRead = tcp_socket_.Receive(receiveBuffer, (int)read_next_bytes, 0); 188 | if (bytesRead == read_next_bytes) 189 | { 190 | tcp_rx_message.RxBuffer_.AddRange(receiveBuffer.Take((int)read_next_bytes)); 191 | 192 | // all message received, transfer to upper layer 193 | IPEndPoint? endpoint = tcp_socket_.RemoteEndPoint as IPEndPoint; 194 | if (endpoint == null) return; 195 | // fill the remote endpoints 196 | tcp_rx_message.Host_ip_address_ = endpoint.Address.ToString(); 197 | tcp_rx_message.Host_port_num_ = (ushort)endpoint.Port; 198 | 199 | Console.WriteLine($"Tcp Message received from <{endpoint.Address.ToString()}," + 200 | $"{endpoint.Port}>"); 201 | // send data to upper layer 202 | tcp_handler_read_(tcp_rx_message); 203 | } 204 | else 205 | { 206 | Console.WriteLine($"Do not read data with payload length"); 207 | } 208 | } 209 | else 210 | { 211 | Console.WriteLine($"Do not read data with length Common_doip_types.kDoipheadrSize"); 212 | } 213 | } 214 | } 215 | catch (Exception ex) 216 | { 217 | Console.WriteLine(ex.Message.ToString()); 218 | } 219 | //Thread.Sleep(50); 220 | } 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Socket/Tcp/Tcp_server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | using System.Net.Sockets; 8 | using static Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp.CreateTcpServerSocket; 9 | using System.Net.WebSockets; 10 | 11 | namespace Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp 12 | { 13 | // Tcp function template used for reception 14 | public delegate void TcpHandlerRead(TcpMessageType message); 15 | // Tcp Server connection class to create connection with client 16 | public class TcpServerConnection 17 | { 18 | // ctor 19 | public TcpServerConnection(TcpHandlerRead _tcp_handler_read) 20 | { 21 | tcp_handler_read_ = _tcp_handler_read; 22 | } 23 | 24 | // Get reference to underlying socket 25 | public System.Net.Sockets.Socket? GetSocket() { return tcp_socket_; } 26 | public void SetSocket(System.Net.Sockets.Socket _socket) { tcp_socket_ = _socket; } 27 | 28 | // function to transmit tcp message 29 | public bool Transmit(TcpMessageType _tcp_tx_message) 30 | { 31 | if(tcp_socket_ != null) 32 | { 33 | tcp_socket_.Send(_tcp_tx_message.TxBuffer_.ToArray()); 34 | return true; 35 | } 36 | else 37 | { 38 | return false; 39 | } 40 | } 41 | 42 | // function to handle read 43 | public bool ReceivedMessage() 44 | { 45 | bool connection_closed = false; 46 | TcpMessageType tcp_rx_message = new(); 47 | int read_next_bytes; 48 | 49 | try 50 | { 51 | if (tcp_socket_ != null) 52 | { 53 | // start blocking read to read Header first 54 | byte[] buffer = new byte[TcpMessageType.kDoipheadrSize]; 55 | if (tcp_socket_.Receive(buffer) == TcpMessageType.kDoipheadrSize) 56 | { 57 | tcp_rx_message.RxBuffer_.AddRange(buffer.ToList()); 58 | read_next_bytes = (int)((buffer[4] << 24) & 0xFF000000) | 59 | (int)((buffer[5] << 16) & 0x00FF0000) | 60 | (int)((buffer[6] << 8) & 0x0000FF00) | 61 | (int)((buffer[7] & 0x000000FF)); 62 | 63 | buffer = new byte[read_next_bytes]; 64 | if (tcp_socket_.Receive(buffer) == read_next_bytes) 65 | { 66 | tcp_rx_message.RxBuffer_.AddRange(buffer.ToList()); 67 | 68 | // all message received, transfer to upper layer 69 | IPEndPoint? endPoint = tcp_socket_.RemoteEndPoint as IPEndPoint; 70 | if (endPoint != null) 71 | { 72 | tcp_rx_message.Host_ip_address_ = endPoint.Address.ToString(); 73 | tcp_rx_message.Host_port_num_ = (ushort)endPoint.Port; 74 | 75 | // send data to upper layer 76 | tcp_handler_read_(tcp_rx_message); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | catch (Exception) 83 | { 84 | connection_closed = true; 85 | } 86 | return connection_closed; 87 | } 88 | 89 | // function to close the socket 90 | public bool Shutdown() 91 | { 92 | bool ret_val = false; 93 | 94 | if(tcp_socket_ != null) 95 | { 96 | tcp_socket_.Shutdown(SocketShutdown.Both); 97 | tcp_socket_.Close(); 98 | tcp_socket_ = null; 99 | } 100 | 101 | return ret_val; 102 | } 103 | 104 | // tcp socket 105 | private System.Net.Sockets.Socket? tcp_socket_ = null; 106 | 107 | // handler read 108 | private TcpHandlerRead tcp_handler_read_; 109 | } 110 | 111 | public class CreateTcpServerSocket 112 | { 113 | // local Ip address 114 | private string local_ip_address_ = string.Empty; 115 | // local port number 116 | private UInt16 local_port_num_; 117 | // server socket 118 | private System.Net.Sockets.Socket server_socket_; 119 | public CreateTcpServerSocket(string _local_ip_address, UInt16 _local_port_num) 120 | { 121 | local_ip_address_ = _local_ip_address; 122 | local_port_num_ = _local_port_num; 123 | 124 | server_socket_ = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 125 | IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, local_port_num_); 126 | server_socket_.Bind(endPoint); 127 | server_socket_.Listen(10);//设置监听最大值 128 | } 129 | 130 | // Blocking function get a tcp connection 131 | public TcpServerConnection GetTcpServerConnection(TcpHandlerRead _tcp_handler_read) 132 | { 133 | TcpServerConnection tcp_connection = new(_tcp_handler_read); 134 | //var client = tcp_connection.GetSocket(); 135 | var client = server_socket_.Accept(); 136 | tcp_connection.SetSocket(client); 137 | return tcp_connection; 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Socket/Tcp/Tcp_types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp 8 | { 9 | // buffer type 10 | using buffType = List; 11 | // ip address type 12 | using ipAddressType = String; 13 | public enum tcpSocketState : byte 14 | { 15 | // Socket state 16 | kIdle = 0x00, 17 | kSocketOnline, 18 | kSocketOffline, 19 | kSocketRxMessageReceived, 20 | kSocketTxMessageSend, 21 | kSocketTxMessageConf, 22 | kSocketError 23 | }; 24 | public enum tcpSocketError : byte 25 | { 26 | // state 27 | kNone = 0x00 28 | }; 29 | 30 | public class TcpMessageType 31 | { 32 | public TcpMessageType() { } 33 | public const byte kDoipheadrSize = 8; 34 | 35 | // socket state 36 | public tcpSocketState Tcp_socket_state_ { get; set; } = tcpSocketState.kIdle; 37 | 38 | // socket error 39 | public tcpSocketError Tcp_socket_error_ { get; set; } = tcpSocketError.kNone; 40 | 41 | // Receive buffer 42 | public buffType RxBuffer_ { get; set; } = new(); 43 | 44 | // Transmit buffer 45 | public buffType TxBuffer_ { get; set; } = new(); 46 | 47 | // host ipaddress 48 | public ipAddressType Host_ip_address_ { get; set; } = string.Empty; 49 | 50 | // host port num 51 | public UInt16 Host_port_num_ { get; set; } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Socket/Udp/Udp_client.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Lib.Utility_support.Socket.Tcp; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Sockets; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Diag_Doip_Uds.Lib.Utility_support.Socket.Udp 11 | { 12 | // Udp function template used for reception 13 | public delegate void UdpHandlerRead(UdpMessageType message); 14 | // Port Type 15 | public enum PortType : byte { kUdp_Broadcast = 0, kUdp_Unicast }; 16 | public class CreateUdpClientSocket 17 | { 18 | // local Ip address 19 | private string local_ip_address_ = string.Empty; 20 | // local port number 21 | private UInt16 local_port_num_; 22 | // udp socket 23 | private System.Net.Sockets.Socket? udp_socket_; 24 | //private UdpClient udpClient_; 25 | 26 | // flag to terminate the thread 27 | //通过Interlocked.Exchange原子化读写,exit_request_调整为int型,0表示false,1表示true 28 | private /*bool*/int exit_request_; 29 | // flag th start the thread 30 | //通过Interlocked.Exchange原子化读写,running_调整为int型,0表示false,1表示true 31 | private /*bool*/int running_; 32 | // conditional variable to block the thread 33 | //private std::condition_variable cond_var_; 34 | // threading var 35 | //private Thread thread_; 36 | // locking critical section 37 | //private Mutex mutex_; 38 | // end points 39 | private EndPoint remote_endpoint_; 40 | // port type - broadcast / unicast 41 | private PortType port_type_; 42 | // Handler invoked during read operation 43 | private UdpHandlerRead udp_handler_read_; 44 | // Rx buffer 45 | private byte[] rxbuffer_ = new byte[UdpMessageType.kDoipUdpResSize]; 46 | 47 | // ctor 48 | public CreateUdpClientSocket(string _local_ip_address, UInt16 _local_port_num, PortType port_type, 49 | UdpHandlerRead udp_handler_read) 50 | { 51 | local_ip_address_ = _local_ip_address; 52 | local_port_num_ = _local_port_num; 53 | Interlocked.Exchange(ref exit_request_, 0); 54 | Interlocked.Exchange(ref running_, 0); 55 | port_type_ = port_type; 56 | udp_handler_read_ = udp_handler_read; 57 | remote_endpoint_ = new IPEndPoint(IPAddress.Any, 0); 58 | udp_socket_ = null; 59 | //udp_socket_ = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 60 | } 61 | 62 | // Function to Open the socket 63 | public bool Open() 64 | { 65 | bool retVal = false; 66 | try 67 | { 68 | udp_socket_ = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 69 | // set broadcast option 70 | udp_socket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); 71 | // reuse address 72 | udp_socket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 73 | 74 | if (port_type_ == PortType.kUdp_Broadcast) 75 | { 76 | // Todo : change the hardcoded value of port number 13400 77 | udp_socket_.Bind(new IPEndPoint(IPAddress.Any, 13400)); 78 | } 79 | else 80 | { 81 | //bind to local address and random port 82 | udp_socket_.Bind(new IPEndPoint(IPAddress.Parse(local_ip_address_), local_port_num_)); 83 | } 84 | 85 | IPEndPoint? endpoint = udp_socket_.LocalEndPoint as IPEndPoint; 86 | 87 | if (endpoint == null) 88 | { 89 | Console.WriteLine("Udp Socket Bind failed"); 90 | return false; 91 | } 92 | 93 | Console.WriteLine($"Udp Socket Opened and bound to <{endpoint.Address.ToString()}, {endpoint.Port}>"); 94 | // Update the port number with new one 95 | local_port_num_ = (ushort)endpoint.Port; 96 | // start reading 97 | Interlocked.Exchange(ref exit_request_, 1); 98 | //cond_var_.notify_all(); 99 | retVal = true; 100 | // start async receive 101 | StartReceiving(); 102 | } 103 | catch(Exception ex) 104 | { 105 | Console.WriteLine(ex.Message.ToString()); 106 | } 107 | return retVal; 108 | } 109 | 110 | private void StartReceiving() 111 | { 112 | // 接收数据缓冲区 113 | byte[] receiveData = new byte[1024]; 114 | 115 | if (udp_socket_ == null) return; 116 | // 开始异步接收数据 117 | udp_socket_.BeginReceiveFrom(receiveData, 0, receiveData.Length, SocketFlags.None, ref remote_endpoint_, HandleMessage, receiveData); 118 | } 119 | 120 | // Transmit 121 | public bool Transmit(UdpMessageType _udp_message) 122 | { 123 | bool ret_val = false; 124 | if (udp_socket_ == null) return ret_val; 125 | try 126 | { 127 | // Transmit to remote endpoints 128 | int send_size = udp_socket_.SendTo(_udp_message.Tx_buffer_.ToArray(), 129 | new IPEndPoint(IPAddress.Parse(_udp_message.Host_ip_address_), _udp_message.Host_port_num_)); 130 | 131 | // Check for error 132 | if (send_size == _udp_message.Tx_buffer_.Count) 133 | { 134 | // successful 135 | IPEndPoint? endpoint = udp_socket_.LocalEndPoint as IPEndPoint; 136 | if (endpoint == null) 137 | { 138 | Console.WriteLine("LocalEndPoint null"); 139 | return ret_val; 140 | } 141 | Console.WriteLine($"Udp message sent : <{endpoint.Address.ToString()}, {endpoint.Port}> -> " + 142 | $"<{_udp_message.Host_ip_address_}, {_udp_message.Host_port_num_}>"); 143 | ret_val = true; 144 | // start async receive 145 | StartReceiving(); 146 | } 147 | } 148 | catch (Exception e) 149 | { 150 | Console.WriteLine($"Udp message sending to <{_udp_message.Host_ip_address_}> " + 151 | $"failed with error : {e.Message.ToString()}"); 152 | } 153 | 154 | return ret_val; 155 | } 156 | 157 | // Function to destroy the socket 158 | public bool Destroy() 159 | { 160 | if (udp_socket_ != null) 161 | { 162 | Interlocked.Exchange(ref running_, 0); 163 | udp_socket_.Shutdown(SocketShutdown.Both); 164 | udp_socket_.Close(); 165 | udp_socket_ = null; 166 | } 167 | return true; 168 | } 169 | // function invoked when datagram is received 170 | //private void HandleMessage(UdpErrorCodeType &error, std::size_t bytes_recvd) 171 | private void HandleMessage(IAsyncResult ar) 172 | { 173 | try 174 | { 175 | if (udp_socket_ == null || ar.AsyncState == null) return; 176 | 177 | // 结束异步接收,并获取接收到的数据长度 178 | int bytesReceived = udp_socket_.EndReceiveFrom(ar, ref remote_endpoint_); 179 | var remote_endpoint = (remote_endpoint_ as IPEndPoint); 180 | 181 | if (remote_endpoint == null) 182 | { 183 | Console.WriteLine("remote_endpoint == null"); 184 | return; 185 | } 186 | 187 | if (!local_ip_address_ .Equals(remote_endpoint.Address.ToString())) 188 | { 189 | UdpMessageType udp_rx_message = new UdpMessageType(); 190 | // Copy the data 191 | byte[] receiveData = (byte[])ar.AsyncState; 192 | //string receivedMessage = Encoding.ASCII.GetString(receiveData, 0, bytesReceived); 193 | udp_rx_message.Rx_buffer_.AddRange(receiveData); 194 | // fill the remote endpoints 195 | udp_rx_message.Host_ip_address_ = remote_endpoint.Address.ToString(); 196 | udp_rx_message.Host_port_num_ = (ushort)remote_endpoint.Port; 197 | 198 | // all message received, transfer to upper layer 199 | //IPEndPoint? remote_endpoint = remote_endpoint_ as IPEndPoint; 200 | //IPEndPoint? local_endpoint = udp_socket_.LocalEndPoint as IPEndPoint; 201 | 202 | Console.WriteLine($"Udp Message received: <{remote_endpoint.Address.ToString()},{remote_endpoint.Port}>" + 203 | $"-><{local_ip_address_},{local_port_num_}>"); 204 | 205 | // send data to upper layer 206 | udp_handler_read_(udp_rx_message); 207 | // start async receive 208 | StartReceiving(); 209 | } 210 | else 211 | { 212 | Console.WriteLine($"Udp Message received from <{remote_endpoint.Address.ToString()}, {remote_endpoint.Port}>" + 213 | $"ignored as received by self ip <{local_ip_address_}>"); 214 | } 215 | } 216 | catch (Exception ex) 217 | { 218 | Console.WriteLine("Error while receiving data: " + ex.Message); 219 | } 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Socket/Udp/Udp_types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Utility_support.Socket.Udp 8 | { 9 | // buffer type 10 | using buffType = List; 11 | // ip address type 12 | using ipAddressType = String; 13 | public class UdpMessageType 14 | { 15 | // ctor 16 | public UdpMessageType() { } 17 | public const byte kDoipUdpResSize = 40; 18 | // Receive buffer 19 | public buffType Rx_buffer_ { get; set; } = new(); 20 | // Transmit buffer 21 | public buffType Tx_buffer_ { get; set; } = new(); 22 | // host ipaddress 23 | public ipAddressType Host_ip_address_ = String.Empty; 24 | // host port num 25 | public UInt16 Host_port_num_ { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Utility/State.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Utility_support.Utility 8 | { 9 | public abstract class State 10 | { 11 | protected EnumState state_; 12 | public State(EnumState _state) 13 | { 14 | state_ = _state; 15 | } 16 | public abstract void Start(); 17 | public abstract void Stop(); 18 | public abstract void HandleMessage(); 19 | public EnumState GetState() { return state_; } 20 | } 21 | 22 | public class StateContext where EnumState : struct 23 | { 24 | // mutex to protect transition 25 | private static Mutex state_mutex_ = new(); 26 | // pointer to store the active state 27 | private State current_state_; 28 | // mapping of state to state ref 29 | private Dictionary> state_map_ = new(); 30 | public StateContext() 31 | { 32 | current_state_ = null; 33 | } 34 | 35 | // Add the needed state 36 | public void AddState(EnumState _state, State _state_ptr) 37 | { 38 | state_map_.Add(_state, _state_ptr); 39 | } 40 | 41 | // Get the current state 42 | public State GetActiveState() 43 | { 44 | state_mutex_.WaitOne(); 45 | try 46 | { 47 | return current_state_; 48 | } 49 | finally 50 | { 51 | state_mutex_.ReleaseMutex(); 52 | } 53 | } 54 | 55 | // Function to transition state to provided state 56 | public void TransitionTo(EnumState state) 57 | { 58 | // stop the current state 59 | Stop(); 60 | // Update to new state 61 | Update(state); 62 | // Start new state 63 | Start(); 64 | } 65 | 66 | // Get Context 67 | public StateContext GetContext() { return this; } 68 | 69 | // Start the current state 70 | private void Start() 71 | { 72 | if (current_state_ != null) { current_state_.Start(); } 73 | } 74 | 75 | // Stop the current state 76 | private void Stop() 77 | { 78 | if (current_state_ != null) { current_state_.Stop(); } 79 | } 80 | 81 | // Update to new state 82 | private void Update(EnumState state) 83 | { 84 | state_mutex_.WaitOne(); 85 | try 86 | { 87 | if (state_map_.ContainsKey(state)) 88 | { 89 | current_state_ = state_map_[state]; 90 | } 91 | else 92 | { 93 | // failure condition 94 | } 95 | } 96 | finally 97 | { 98 | state_mutex_.ReleaseMutex(); 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Utility/Sync_timer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace SynchronizedTimer 9 | { 10 | // timer state 11 | public enum TimerState : byte { kIdle = 0, kCancelRequested, kTimeout }; 12 | public class SyncTimer : IDisposable 13 | { 14 | private AutoResetEvent reset_event_ = new(false); 15 | private Timer? timer_ = null; 16 | private bool exit_request_; 17 | private bool start_running_; 18 | 19 | public SyncTimer() 20 | { 21 | exit_request_ = false; 22 | start_running_ = false; 23 | } 24 | 25 | public void Dispose() 26 | { 27 | try 28 | { 29 | exit_request_ = false; 30 | start_running_ = false; 31 | reset_event_.Set(); 32 | } 33 | finally 34 | { 35 | } 36 | } 37 | 38 | public TimerState Start(int _msec) 39 | { 40 | try 41 | { 42 | TimerState timer_state = TimerState.kIdle; 43 | start_running_ = true; 44 | long expiry_timepoint = DateTime.Now.Ticks + _msec * 10000; //100ns 45 | timer_ = new Timer(TimerCallback, null, TimeSpan.FromMilliseconds(_msec), Timeout.InfiniteTimeSpan); 46 | reset_event_.WaitOne(); 47 | timer_.Dispose(); 48 | if (!exit_request_) 49 | { 50 | long current_time = DateTime.Now.Ticks; //100ns 51 | // check for expiry 52 | if (current_time > expiry_timepoint) 53 | { 54 | // timeout 55 | timer_state = TimerState.kTimeout; 56 | } 57 | else 58 | { 59 | if (!start_running_) 60 | { 61 | timer_state = TimerState.kCancelRequested; 62 | } 63 | } 64 | } 65 | return timer_state; 66 | } 67 | finally 68 | { 69 | } 70 | } 71 | 72 | public void Stop() 73 | { 74 | try 75 | { 76 | start_running_ = false; 77 | reset_event_.Set(); 78 | } 79 | finally 80 | { 81 | } 82 | } 83 | 84 | private void TimerCallback(object? state) 85 | { 86 | reset_event_.Set(); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Lib/Utility_support/Utility/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Diag_Doip_Uds.Lib.Utility_support.Utility 8 | { 9 | public class Utils 10 | { 11 | public static string ConvertToHexString(byte _char_start, byte _char_count, List _input_buffer) 12 | { 13 | string hex_string = string.Empty; 14 | byte total_char_count = (byte)(_char_start + _char_count); 15 | 16 | for (byte char_start_count = _char_start; char_start_count < total_char_count; char_start_count++) 17 | { 18 | string vehicle_info_data_eid = string.Empty; 19 | int payload_byte = _input_buffer[char_start_count]; 20 | if ((payload_byte <= 15U)) 21 | { 22 | // "0" appended in case of value upto 15/0xF 23 | vehicle_info_data_eid += "0"; 24 | } 25 | vehicle_info_data_eid += (payload_byte.ToString("X") + ":"); 26 | hex_string += vehicle_info_data_eid; 27 | } 28 | // remove last ":" appended before 29 | return hex_string.Remove(hex_string.LastIndexOf(":"), 1); 30 | } 31 | 32 | public static string ConvertToAsciiString(byte _char_start, byte _char_count,List _input_buffer) 33 | { 34 | string ascii_string = string.Empty; 35 | byte total_char_count = (byte)(_char_start + _char_count); 36 | 37 | for (byte char_start_count = _char_start; char_start_count < total_char_count; char_start_count++) 38 | { 39 | string vehicle_info_data_vin = string.Empty; 40 | vehicle_info_data_vin += _input_buffer[char_start_count]; 41 | ascii_string += vehicle_info_data_vin; 42 | } 43 | return ascii_string; 44 | } 45 | 46 | public static void SerializeEIDGIDFromString(string _input_string, 47 | List _output_buffer, 48 | byte _total_size, 49 | byte _substring_range) 50 | { 51 | 52 | for (var char_count = 0U; char_count < _total_size; char_count += _substring_range) 53 | { 54 | string input_string_new = _input_string.Substring((int)char_count, _substring_range); 55 | int get_byte = Convert.ToInt32(input_string_new, 16); 56 | _output_buffer.Add((byte)get_byte); 57 | } 58 | } 59 | 60 | public static void SerializeVINFromString(string _input_string, 61 | List _output_buffer, 62 | byte _total_size, 63 | byte _substring_range) 64 | { 65 | 66 | for (var char_count = 0U; char_count < _total_size; char_count += _substring_range) 67 | { 68 | string input_string_new = _input_string.Substring((int)char_count, _substring_range); 69 | //int get_byte = Convert.ToInt32(input_string_new, 16); 70 | byte get_byte = (byte)input_string_new[0]; 71 | _output_buffer.Add((byte)get_byte); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Program.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Dcm.Service; 2 | using Diag_Doip_Uds.Appl.Include; 3 | using Diag_Doip_Uds.Lib.Uds_transport_layer_api.Uds_transport; 4 | using static Diag_Doip_Uds.Lib.Common.Common_header; 5 | 6 | namespace Diag_Doip_Uds 7 | { 8 | internal class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | #if true 13 | /* 14 | * Main Entry point of diag client example 15 | * Example to find available ECU in a network through vehicle discovery and connecting to it. 16 | */ 17 | 18 | // Create the Diagnostic client and pass the config for creating internal properties 19 | IDiagClient diag_client = DiagClientHelper.CreateDiagnosticClient("diag_client_config.json"); 20 | 21 | // Initialize the Diagnostic Client library 22 | diag_client.Initialize(); 23 | 24 | // Get conversation for tester one by providing the conversation name configured 25 | // in diag_client_config file passed while creating the diag client 26 | IDiagClientConversation diag_client_conversation = diag_client.GetDiagnosticClientConversation("DiagTesterOne"); 27 | 28 | // Start the conversation for tester one 29 | diag_client_conversation.Startup(); 30 | 31 | // Create a vehicle info request for finding ECU with matching VIN - ABCDEFGH123456789 32 | VehicleAddrInfoRequest vehicle_info_request = new(){ Preselection_mode = 1, Preselection_value = "ABCDEFGH123456789" }; 33 | // Send Vehicle Identification request and get the response with available ECU information 34 | Pair vehicle_response_result = 35 | diag_client.SendVehicleIdentificationRequest(vehicle_info_request); 36 | 37 | 38 | // Valid vehicle discovery response must be received before connecting to ECU 39 | if (vehicle_response_result.First == VehicleResponseResult.kStatusOk 40 | && (vehicle_response_result.Second != null)) 41 | { 42 | // Get the list of all vehicle available with matching VIN 43 | List vehicle_response_collection = 44 | vehicle_response_result.Second.GetVehicleList(); 45 | 46 | // Create an uds message using first vehicle available in the list of response collection 47 | string remote_ecu_ip_address = vehicle_response_collection[0].Ip_address; // Remote ECU ip address 48 | UInt16 remote_ecu_server_logical_address = vehicle_response_collection[0].Logical_address; // Remote ECU logical address 49 | 50 | IUdsMessage uds_message = new UdsMessageImpl(remote_ecu_ip_address, new(){ 0x10, 0x01}); 51 | 52 | // Connect Tester One to remote ECU 53 | ConnectResult connect_result = 54 | diag_client_conversation.ConnectToDiagServer(remote_ecu_server_logical_address, 55 | uds_message.GetHostIpAddress()); 56 | 57 | if (connect_result == ConnectResult.kConnectSuccess) 58 | { 59 | // Use Tester One to send the diagnostic message to remote ECU 60 | Pair diag_response = 61 | diag_client_conversation.SendDiagnosticRequest(uds_message); 62 | 63 | if (diag_response.First == DiagResult.kDiagSuccess) 64 | { 65 | Console.WriteLine($"diag_client_conversation Total size: : {diag_response.Second.GetPayload().Count}"); 66 | // Print the payload 67 | Console.WriteLine($"diag_client_conversation1 byte : {BytesToHexStr(diag_response.Second.GetPayload().ToArray())}"); 68 | } 69 | 70 | // Disconnect Tester One from ECU1 with remote ip address "172.16.25.128" 71 | diag_client_conversation.DisconnectFromDiagServer(); 72 | } 73 | 74 | } 75 | 76 | // shutdown the conversation 77 | diag_client_conversation.Shutdown(); 78 | 79 | // important to release all the resources by calling de-initialize 80 | diag_client.DeInitialize(); 81 | #else 82 | /* 83 | * Main Entry point of diag client example 84 | * Example to connect to multiple ECU by creating multiple diagnostic tester instance. 85 | */ 86 | 87 | // Create the Diagnostic client and pass the config for creating internal properties 88 | IDiagClient diag_client = DiagClientHelper.CreateDiagnosticClient("diag_client_config.json"); 89 | 90 | // Initialize the Diagnostic Client library 91 | diag_client.Initialize(); 92 | 93 | // Get conversation for tester one by providing the conversation name configured 94 | // in diag_client_config file passed while creating the diag client 95 | IDiagClientConversation diag_client_conversation1 = diag_client.GetDiagnosticClientConversation("DiagTesterOne"); 96 | 97 | // Start the conversation for tester one 98 | diag_client_conversation1.Startup(); 99 | 100 | // Get conversation for tester two by providing the conversation name configured 101 | // in diag_client_config file passed while creating the diag client 102 | IDiagClientConversation diag_client_conversation2 = diag_client.GetDiagnosticClientConversation("DiagTesterTwo"); 103 | 104 | // Start the conversation for tester two 105 | diag_client_conversation2.Startup(); 106 | 107 | // Create an uds payload 10 01 ( Default Session ) 108 | List payload_1 = new(){ 0x10, 0x01}; 109 | 110 | // Create an uds payload 3E 00( Tester Present ) 111 | List payload_2 = new(){ 0x3E, 0x00}; 112 | 113 | { 114 | // Create an uds message with payload for ECU1 with remote ip address 10.167.226.194 115 | IUdsMessage uds_message_1 = new UdsMessageImpl("10.167.226.194", payload_1); 116 | 117 | // Create an uds message with payload for ECU2 with remote ip address 10.167.218.217 118 | IUdsMessage uds_message_2 = new UdsMessageImpl("10.167.218.217", payload_2); 119 | 120 | // Connect Tester One to ECU1 with target address "0x1234" and remote ip address "10.167.226.194" 121 | diag_client_conversation1.ConnectToDiagServer(0x1234, uds_message_1.GetHostIpAddress()); 122 | 123 | // Connect Tester Two to ECU2 with target address "0x1235" and remote ip address "10.167.218.217" 124 | diag_client_conversation2.ConnectToDiagServer(0x1235, uds_message_2.GetHostIpAddress()); 125 | 126 | // Use Tester One to send the diagnostic message to ECU1 127 | Pair ret_val_1 = diag_client_conversation1.SendDiagnosticRequest(uds_message_1); 128 | 129 | if (ret_val_1.First == DiagResult.kDiagSuccess) 130 | { 131 | Console.WriteLine($"diag_client_conversation1 Total size : {ret_val_1.Second.GetPayload().Count}"); 132 | // Print the payload 133 | Console.WriteLine($"diag_client_conversation1 byte : {BytesToHexStr(ret_val_1.Second.GetPayload().ToArray())}"); 134 | } 135 | 136 | // Use Tester Two to send the diagnostic message to ECU2 137 | Pair ret_val_2 = diag_client_conversation2.SendDiagnosticRequest(uds_message_2); 138 | 139 | if (ret_val_2.First == DiagResult.kDiagSuccess) 140 | { 141 | Console.WriteLine($"diag_client_conversation2 Total size : {ret_val_2.Second.GetPayload().Count}"); 142 | // Print the payload 143 | Console.WriteLine($"diag_client_conversation2 byte : {BytesToHexStr(ret_val_2.Second.GetPayload().ToArray())}"); 144 | } 145 | 146 | // Disconnect Tester One from ECU1 with remote ip address "10.167.226.194" 147 | diag_client_conversation1.DisconnectFromDiagServer(); 148 | // Disconnect Tester Two from ECU2 with remote ip address "10.167.218.217" 149 | diag_client_conversation2.DisconnectFromDiagServer(); 150 | } 151 | 152 | // shutdown all the conversation 153 | diag_client_conversation1.Shutdown(); 154 | diag_client_conversation2.Shutdown(); 155 | 156 | // important to release all the resources by calling de-initialize 157 | diag_client.DeInitialize(); 158 | #endif 159 | } 160 | 161 | private static string BytesToHexStr(byte[] bytes) 162 | { 163 | string returnStr = ""; 164 | if (bytes != null) 165 | { 166 | for (int i = 0; i < bytes.Length; i++) 167 | { 168 | returnStr += bytes[i].ToString("X2"); 169 | } 170 | } 171 | return returnStr; 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/Resource/diag_client_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "UdpIpAddress": "10.167.218.36", 3 | "UdpBroadcastAddress": "255.255.255.255", 4 | "Conversation": { 5 | "NumberOfConversation": 2, 6 | "ConversationProperty": [ 7 | { 8 | "p2ClientMax": 1000, 9 | "p2StarClientMax": 5000, 10 | "RxBufferSize": 4095, 11 | "SourceAddress": 1, 12 | "TargetAddressType": "Physical", 13 | "Network": { 14 | "ProtocolKind": "DoIP", 15 | "TcpIpAddress": "10.167.218.36", 16 | "TLS": false 17 | }, 18 | "ConversationName": "DiagTesterOne" 19 | }, 20 | { 21 | "p2ClientMax": 2000, 22 | "p2StarClientMax": 5000, 23 | "RxBufferSize": 4095, 24 | "SourceAddress": 2, 25 | "TargetAddressType": "Functional", 26 | "Network": { 27 | "ProtocolKind": "DoIP", 28 | "TcpIpAddress": "10.167.218.36", 29 | "TLS": false 30 | }, 31 | "ConversationName": "DiagTesterTwo" 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/User_uds_message.cs: -------------------------------------------------------------------------------- 1 | using Diag_Doip_Uds.Appl.Include; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Diag_Doip_Uds 10 | { 11 | using IpAddress = String; 12 | public class UdsMessageImpl : IUdsMessage 13 | { 14 | // host ip address 15 | private IpAddress host_ip_address_; 16 | 17 | // store only UDS payload to be sent 18 | private List uds_payload_; 19 | // ctor 20 | public UdsMessageImpl(string _host_ip_address, List _payload) 21 | { 22 | host_ip_address_ = _host_ip_address; 23 | uds_payload_ = _payload; 24 | } 25 | public List GetPayload() 26 | { 27 | return uds_payload_; 28 | } 29 | public string GetHostIpAddress() 30 | { 31 | return host_ip_address_; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeTarget": { 3 | "name": ".NETCoreApp,Version=v6.0", 4 | "signature": "" 5 | }, 6 | "compilationOptions": {}, 7 | "targets": { 8 | ".NETCoreApp,Version=v6.0": { 9 | "Diag-Doip-Uds/1.0.0": { 10 | "dependencies": { 11 | "Newtonsoft.Json": "13.0.3" 12 | }, 13 | "runtime": { 14 | "Diag-Doip-Uds.dll": {} 15 | } 16 | }, 17 | "Newtonsoft.Json/13.0.3": { 18 | "runtime": { 19 | "lib/net6.0/Newtonsoft.Json.dll": { 20 | "assemblyVersion": "13.0.0.0", 21 | "fileVersion": "13.0.3.27908" 22 | } 23 | } 24 | } 25 | } 26 | }, 27 | "libraries": { 28 | "Diag-Doip-Uds/1.0.0": { 29 | "type": "project", 30 | "serviceable": false, 31 | "sha512": "" 32 | }, 33 | "Newtonsoft.Json/13.0.3": { 34 | "type": "package", 35 | "serviceable": true, 36 | "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", 37 | "path": "newtonsoft.json/13.0.3", 38 | "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.dll -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.exe -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.pdb -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Diag-Doip-Uds.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net6.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "6.0.0" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/bin/Debug/net6.0/diag_client_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "UdpIpAddress": "10.167.218.36", 3 | "UdpBroadcastAddress": "255.255.255.255", 4 | "Conversation": { 5 | "NumberOfConversation": 2, 6 | "ConversationProperty": [ 7 | { 8 | "p2ClientMax": 1000, 9 | "p2StarClientMax": 5000, 10 | "RxBufferSize": 4095, 11 | "SourceAddress": 1, 12 | "TargetAddressType": "Physical", 13 | "Network": { 14 | "ProtocolKind": "DoIP", 15 | "TcpIpAddress": "10.167.218.36", 16 | "TLS": false 17 | }, 18 | "ConversationName": "DiagTesterOne" 19 | }, 20 | { 21 | "p2ClientMax": 2000, 22 | "p2StarClientMax": 5000, 23 | "RxBufferSize": 4095, 24 | "SourceAddress": 2, 25 | "TargetAddressType": "Functional", 26 | "Network": { 27 | "ProtocolKind": "DoIP", 28 | "TcpIpAddress": "10.167.218.36", 29 | "TLS": false 30 | }, 31 | "ConversationName": "DiagTesterTwo" 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("Diag-Doip-Uds")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("Diag-Doip-Uds")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("Diag-Doip-Uds")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // 由 MSBuild WriteCodeFragment 类生成。 23 | 24 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 1c12d6c971501ea50b85fd6c800915d49dee06ec 2 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net6.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = Diag_Doip_Uds 11 | build_property.ProjectDir = E:\diag-doip-uds\Diag-Doip-Uds\ 12 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.GlobalUsings.g.cs: -------------------------------------------------------------------------------- 1 | // 2 | global using global::System; 3 | global using global::System.Collections.Generic; 4 | global using global::System.IO; 5 | global using global::System.Linq; 6 | global using global::System.Net.Http; 7 | global using global::System.Threading; 8 | global using global::System.Threading.Tasks; 9 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.assets.cache -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.BuildWithSkipAnalyzers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.BuildWithSkipAnalyzers -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.CopyComplete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.CopyComplete -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 5e99ab9b227048cec7ac6fe3155e46d2e3a8a9a2 2 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Diag-Doip-Uds.exe 2 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Diag-Doip-Uds.deps.json 3 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Diag-Doip-Uds.runtimeconfig.json 4 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Diag-Doip-Uds.dll 5 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Diag-Doip-Uds.pdb 6 | E:\diag-doip-uds\Diag-Doip-Uds\bin\Debug\net6.0\Newtonsoft.Json.dll 7 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.csproj.AssemblyReference.cache 8 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.GeneratedMSBuildEditorConfig.editorconfig 9 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.AssemblyInfoInputs.cache 10 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.AssemblyInfo.cs 11 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.csproj.CoreCompileInputs.cache 12 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.csproj.CopyComplete 13 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.dll 14 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\refint\Diag-Doip-Uds.dll 15 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.pdb 16 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\Diag-Doip-Uds.genruntimeconfig.cache 17 | E:\diag-doip-uds\Diag-Doip-Uds\obj\Debug\net6.0\ref\Diag-Doip-Uds.dll 18 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.dll -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | 47ff7384b8fc20dede0b918534626502327c8030 2 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/Diag-Doip-Uds.pdb -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/apphost.exe -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/ref/Diag-Doip-Uds.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/ref/Diag-Doip-Uds.dll -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/refint/Diag-Doip-Uds.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jimmy-drod/diag-doip-uds/29cf0795cbc6014f9d34467bfcca006f333aabfa/diag-doip-uds/Diag-Doip-Uds/obj/Debug/net6.0/refint/Diag-Doip-Uds.dll -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Diag-Doip-Uds.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj": {} 5 | }, 6 | "projects": { 7 | "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj", 11 | "projectName": "Diag-Doip-Uds", 12 | "projectPath": "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj", 13 | "packagesPath": "C:\\Users\\xingzp.fnst\\.nuget\\packages\\", 14 | "outputPath": "E:\\diag-doip-uds\\Diag-Doip-Uds\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "configFilePaths": [ 17 | "C:\\Users\\xingzp.fnst\\AppData\\Roaming\\NuGet\\NuGet.Config", 18 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 19 | ], 20 | "originalTargetFrameworks": [ 21 | "net6.0" 22 | ], 23 | "sources": { 24 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 25 | "https://api.nuget.org/v3/index.json": {} 26 | }, 27 | "frameworks": { 28 | "net6.0": { 29 | "targetAlias": "net6.0", 30 | "projectReferences": {} 31 | } 32 | }, 33 | "warningProperties": { 34 | "warnAsError": [ 35 | "NU1605" 36 | ] 37 | } 38 | }, 39 | "frameworks": { 40 | "net6.0": { 41 | "targetAlias": "net6.0", 42 | "dependencies": { 43 | "Newtonsoft.Json": { 44 | "target": "Package", 45 | "version": "[13.0.3, )" 46 | } 47 | }, 48 | "imports": [ 49 | "net461", 50 | "net462", 51 | "net47", 52 | "net471", 53 | "net472", 54 | "net48", 55 | "net481" 56 | ], 57 | "assetTargetFallback": true, 58 | "warn": true, 59 | "frameworkReferences": { 60 | "Microsoft.NETCore.App": { 61 | "privateAssets": "all" 62 | } 63 | }, 64 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.100\\RuntimeIdentifierGraph.json" 65 | } 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Diag-Doip-Uds.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\xingzp.fnst\.nuget\packages\ 9 | PackageReference 10 | 6.4.0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/Diag-Doip-Uds.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/project.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "targets": { 4 | "net6.0": { 5 | "Newtonsoft.Json/13.0.3": { 6 | "type": "package", 7 | "compile": { 8 | "lib/net6.0/Newtonsoft.Json.dll": { 9 | "related": ".xml" 10 | } 11 | }, 12 | "runtime": { 13 | "lib/net6.0/Newtonsoft.Json.dll": { 14 | "related": ".xml" 15 | } 16 | } 17 | } 18 | } 19 | }, 20 | "libraries": { 21 | "Newtonsoft.Json/13.0.3": { 22 | "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", 23 | "type": "package", 24 | "path": "newtonsoft.json/13.0.3", 25 | "files": [ 26 | ".nupkg.metadata", 27 | ".signature.p7s", 28 | "LICENSE.md", 29 | "README.md", 30 | "lib/net20/Newtonsoft.Json.dll", 31 | "lib/net20/Newtonsoft.Json.xml", 32 | "lib/net35/Newtonsoft.Json.dll", 33 | "lib/net35/Newtonsoft.Json.xml", 34 | "lib/net40/Newtonsoft.Json.dll", 35 | "lib/net40/Newtonsoft.Json.xml", 36 | "lib/net45/Newtonsoft.Json.dll", 37 | "lib/net45/Newtonsoft.Json.xml", 38 | "lib/net6.0/Newtonsoft.Json.dll", 39 | "lib/net6.0/Newtonsoft.Json.xml", 40 | "lib/netstandard1.0/Newtonsoft.Json.dll", 41 | "lib/netstandard1.0/Newtonsoft.Json.xml", 42 | "lib/netstandard1.3/Newtonsoft.Json.dll", 43 | "lib/netstandard1.3/Newtonsoft.Json.xml", 44 | "lib/netstandard2.0/Newtonsoft.Json.dll", 45 | "lib/netstandard2.0/Newtonsoft.Json.xml", 46 | "newtonsoft.json.13.0.3.nupkg.sha512", 47 | "newtonsoft.json.nuspec", 48 | "packageIcon.png" 49 | ] 50 | } 51 | }, 52 | "projectFileDependencyGroups": { 53 | "net6.0": [ 54 | "Newtonsoft.Json >= 13.0.3" 55 | ] 56 | }, 57 | "packageFolders": { 58 | "C:\\Users\\xingzp.fnst\\.nuget\\packages\\": {} 59 | }, 60 | "project": { 61 | "version": "1.0.0", 62 | "restore": { 63 | "projectUniqueName": "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj", 64 | "projectName": "Diag-Doip-Uds", 65 | "projectPath": "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj", 66 | "packagesPath": "C:\\Users\\xingzp.fnst\\.nuget\\packages\\", 67 | "outputPath": "E:\\diag-doip-uds\\Diag-Doip-Uds\\obj\\", 68 | "projectStyle": "PackageReference", 69 | "configFilePaths": [ 70 | "C:\\Users\\xingzp.fnst\\AppData\\Roaming\\NuGet\\NuGet.Config", 71 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 72 | ], 73 | "originalTargetFrameworks": [ 74 | "net6.0" 75 | ], 76 | "sources": { 77 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 78 | "https://api.nuget.org/v3/index.json": {} 79 | }, 80 | "frameworks": { 81 | "net6.0": { 82 | "targetAlias": "net6.0", 83 | "projectReferences": {} 84 | } 85 | }, 86 | "warningProperties": { 87 | "warnAsError": [ 88 | "NU1605" 89 | ] 90 | } 91 | }, 92 | "frameworks": { 93 | "net6.0": { 94 | "targetAlias": "net6.0", 95 | "dependencies": { 96 | "Newtonsoft.Json": { 97 | "target": "Package", 98 | "version": "[13.0.3, )" 99 | } 100 | }, 101 | "imports": [ 102 | "net461", 103 | "net462", 104 | "net47", 105 | "net471", 106 | "net472", 107 | "net48", 108 | "net481" 109 | ], 110 | "assetTargetFallback": true, 111 | "warn": true, 112 | "frameworkReferences": { 113 | "Microsoft.NETCore.App": { 114 | "privateAssets": "all" 115 | } 116 | }, 117 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.100\\RuntimeIdentifierGraph.json" 118 | } 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /diag-doip-uds/Diag-Doip-Uds/obj/project.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "dgSpecHash": "CUFoRuOllVmUWyxEgPeplkP3PLcvsqF3F0+9957h0BM4SIfMk/0vvVu9MiAV62LUkOI3tPSLT0pZqNGed1VQuw==", 4 | "success": true, 5 | "projectFilePath": "E:\\diag-doip-uds\\Diag-Doip-Uds\\Diag-Doip-Uds.csproj", 6 | "expectedPackageFiles": [ 7 | "C:\\Users\\xingzp.fnst\\.nuget\\packages\\newtonsoft.json\\13.0.3\\newtonsoft.json.13.0.3.nupkg.sha512" 8 | ], 9 | "logs": [] 10 | } --------------------------------------------------------------------------------