Diag-Client-Lib
doip_tcp_channel_handler.cpp
Go to the documentation of this file.
1 /* Diagnostic Client library
2  * Copyright (C) 2024 Avijit Dey
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
10 
11 #include <utility>
12 
15 #include "common/logger.h"
16 #include "core/include/span.h"
17 
18 namespace doip_client {
19 namespace channel {
20 namespace tcp_channel {
21 namespace {
22 
26 constexpr std::uint16_t kDoip_RoutingActivation_ResType{0x0006};
27 
31 constexpr std::uint16_t kDoip_DiagMessage_Type{0x8001};
32 constexpr std::uint16_t kDoip_DiagMessagePosAck_Type{0x8002};
33 constexpr std::uint16_t kDoip_DiagMessageNegAck_Type{0x8003};
34 
38 constexpr std::uint16_t kDoip_AliveCheck_ReqType{0x0007};
39 constexpr std::uint16_t kDoip_AliveCheck_ResType{0x0008};
40 
44 constexpr std::uint8_t kDoip_GenericHeader_IncorrectPattern{0x00};
45 constexpr std::uint8_t kDoip_GenericHeader_UnknownPayload{0x01};
46 constexpr std::uint8_t kDoip_GenericHeader_MessageTooLarge{0x02};
47 constexpr std::uint8_t kDoip_GenericHeader_OutOfMemory{0x03};
48 constexpr std::uint8_t kDoip_GenericHeader_InvalidPayloadLen{0x04};
49 
53 constexpr std::uint8_t kDoip_DiagMessage_ReqResMinLen = 4U; // considering SA and TA
54 constexpr std::uint8_t kDoip_DiagMessageAck_ResMinLen = 5U; // considering SA, TA, Ack code
55 
59 constexpr std::uint32_t kDoip_RoutingActivation_ReqMinLen{7u}; //without OEM specific use byte
60 constexpr std::uint32_t kDoip_RoutingActivation_ResMinLen{9u}; //without OEM specific use byte
61 constexpr std::uint32_t kDoip_RoutingActivation_ReqMaxLen{11u}; //with OEM specific use byte
62 constexpr std::uint32_t kDoip_RoutingActivation_ResMaxLen{13u}; //with OEM specific use byte
63 
64 } // namespace
65 
67  : routing_activation_handler_{tcp_socket_handler},
68  diagnostic_message_handler_{tcp_socket_handler, channel} {}
69 
73 }
74 
78 }
79 
83 }
84 
86  uds_transport::UdsMessageConstPtr routing_activation_request) noexcept
88  return routing_activation_handler_.HandleRoutingActivationRequest(std::move(routing_activation_request));
89 }
90 
93  return diagnostic_message_handler_.HandleDiagnosticRequest(std::move(diagnostic_request));
94 }
95 
96 auto DoipTcpChannelHandler::HandleMessage(TcpMessagePtr tcp_rx_message) noexcept -> void {
97  std::uint8_t nack_code{};
98  DoipMessage doip_rx_message{DoipMessage::MessageType::kTcp, tcp_rx_message->GetHostIpAddress(),
99  tcp_rx_message->GetHostPortNumber(),
100  core_type::Span<std::uint8_t>{tcp_rx_message->GetRxBuffer()}};
101  // Process the Doip Generic header check
102  if (ProcessDoIPHeader(doip_rx_message, nack_code)) {
103  ProcessDoIPPayload(doip_rx_message);
104  } else {
105  // send NACK or ignore
106  (void) nack_code;
107  }
108 }
109 
112 }
113 
114 auto DoipTcpChannelHandler::ProcessDoIPHeader(DoipMessage &doip_rx_message, std::uint8_t &nack_code) noexcept -> bool {
115  bool ret_val = false;
116  /* Check the header synchronisation pattern */
117  if (((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion) &&
118  (doip_rx_message.GetInverseProtocolVersion() == static_cast<std::uint8_t>(~kDoip_ProtocolVersion))) ||
119  ((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion_Def) &&
120  (doip_rx_message.GetInverseProtocolVersion() == static_cast<std::uint8_t>(~kDoip_ProtocolVersion_Def)))) {
121  /* Check the supported payload type */
122  if ((doip_rx_message.GetPayloadType() == kDoip_RoutingActivation_ResType) ||
123  (doip_rx_message.GetPayloadType() == kDoip_DiagMessagePosAck_Type) ||
124  (doip_rx_message.GetPayloadType() == kDoip_DiagMessageNegAck_Type) ||
125  (doip_rx_message.GetPayloadType() == kDoip_DiagMessage_Type) ||
126  (doip_rx_message.GetPayloadType() == kDoip_AliveCheck_ReqType)) {
127  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00017] */
128  if (doip_rx_message.GetPayloadLength() <= kDoip_Protocol_MaxPayload) {
129  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00018] */
130  if (doip_rx_message.GetPayloadLength() <= kTcpChannelLength) {
131  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00019] */
132  if (ProcessDoIPPayloadLength(doip_rx_message.GetPayloadLength(), doip_rx_message.GetPayloadType())) {
133  ret_val = true;
134  } else {
135  // Send NACK code 0x04, close the socket
137  // socket closure ??
138  }
139  } else {
140  // Send NACK code 0x03, discard message
142  }
143  } else {
144  // Send NACK code 0x02, discard message
146  }
147  } else { // Send NACK code 0x01, discard message
149  }
150  } else { // Send NACK code 0x00, close the socket
152  // socket closure
153  }
154  return ret_val;
155 }
156 
157 auto DoipTcpChannelHandler::ProcessDoIPPayloadLength(std::uint32_t payload_length, std::uint16_t payload_type) noexcept
158  -> bool {
159  bool ret_val{false};
160  switch (payload_type) {
162  if (payload_length <= kDoip_RoutingActivation_ResMaxLen) ret_val = true;
163  break;
164  }
167  if (payload_length >= kDoip_DiagMessageAck_ResMinLen) ret_val = true;
168  break;
169  }
170  case kDoip_DiagMessage_Type: {
171  // Atleast 1 byte of data must be present
172  if (payload_length >= (kDoip_DiagMessage_ReqResMinLen + 1u)) ret_val = true;
173  break;
174  }
176  if (payload_length <= kDoip_RoutingActivation_ResMaxLen) ret_val = true;
177  break;
178  }
179  default:
180  // do nothing
181  break;
182  }
183  return ret_val;
184 }
185 
187  std::lock_guard<std::mutex> const lck(channel_handler_lock);
188  switch (doip_payload.GetPayloadType()) {
190  // Process RoutingActivation response
191  routing_activation_handler_.ProcessDoIPRoutingActivationResponse(doip_payload);
192  break;
194  // Process Diagnostic Message Response
195  diagnostic_message_handler_.ProcessDoIPDiagnosticMessageResponse(doip_payload);
196  break;
199  // Process positive or negative diag ack message
200  diagnostic_message_handler_.ProcessDoIPDiagnosticAckMessageResponse(doip_payload);
201  break;
202  default:
203  /* do nothing */
204  break;
205  }
206 }
207 } // namespace tcp_channel
208 } // namespace channel
209 } // namespace doip_client
Immutable class to store received doip message.
Definition: doip_message.h:21
auto ProcessDoIPPayloadLength(std::uint32_t payload_len, std::uint16_t payload_type) noexcept -> bool
Function to verify payload length of various payload type.
auto IsRoutingActivated() noexcept -> bool
Check if routing activation is active for this handler.
RoutingActivationHandler routing_activation_handler_
Handler to process routing activation req/ resp.
DiagnosticMessageHandler diagnostic_message_handler_
Handler to process diagnostic message req/ resp.
DoipTcpChannelHandler(sockets::TcpSocketHandler &tcp_socket_handler, DoipTcpChannel &channel)
Constructs an instance of DoipTcpChannelHandler.
sockets::TcpSocketHandler::TcpMessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
auto SendDiagnosticRequest(uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
Function to send diagnostic request.
void ProcessDoIPPayload(DoipMessage &doip_payload) noexcept
Function to process the doip payload.
auto SendRoutingActivationRequest(uds_transport::UdsMessageConstPtr routing_activation_request) noexcept -> uds_transport::UdsTransportProtocolMgr::ConnectionResult
Function to send routing activation request.
auto ProcessDoIPHeader(DoipMessage &doip_rx_message, std::uint8_t &nack_code) noexcept -> bool
Function to process doip header in received response.
void HandleMessage(TcpMessagePtr tcp_rx_message) noexcept
Function to process the received message.
Class to manage a tcp channel as per DoIP protocol.
auto IsRoutingActivated() noexcept -> bool
Check if routing activation is active for this handler.
Class used to create a tcp socket for handling transmission and reception of tcp message from driver.
constexpr std::uint16_t kDoip_RoutingActivation_ResType
Routing Activation response Type.
constexpr std::uint8_t kDoip_DiagMessage_ReqResMinLen
Diagnostic Message request/response lengths.
constexpr std::uint8_t kDoip_GenericHeader_IncorrectPattern
Generic DoIP Header NACK codes.
constexpr std::uint32_t kDoip_RoutingActivation_ReqMinLen
Routing Activation request lengths.
constexpr std::uint8_t kDoip_ProtocolVersion_Def
constexpr std::uint32_t kDoip_Protocol_MaxPayload
constexpr std::uint8_t kDoip_ProtocolVersion
constexpr std::uint32_t kTcpChannelLength
std::unique_ptr< const UdsMessage > UdsMessageConstPtr
Definition: uds_message.h:69