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 kDoipDiagMessage{0x8001};
32 constexpr std::uint16_t kDoipDiagMessagePosAck{0x8002};
33 constexpr std::uint16_t kDoipDiagMessageNegAck{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 kDoipDiagMessageReqResMinLen = 4U; // considering SA and TA
54 constexpr std::uint8_t kDoipDiagMessageAckResMinLen = 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_ReqMaxLen{11u}; //with OEM specific use byte
61 constexpr std::uint32_t kDoipRoutingActivationResMinLen{9u}; // without OEM specific use byte
62 constexpr std::uint32_t kDoipRoutingActivationResMaxLen{13u}; //with OEM specific use byte
63 
64 } // namespace
65 
67  DoipTcpChannel &channel)
68  : routing_activation_handler_{tcp_socket_handler},
69  diagnostic_message_handler_{tcp_socket_handler, channel} {}
70 
74 }
75 
79 }
80 
84 }
85 
87  uds_transport::UdsMessageConstPtr routing_activation_request) noexcept
89  return routing_activation_handler_.HandleRoutingActivationRequest(
90  std::move(routing_activation_request));
91 }
92 
94  uds_transport::UdsMessageConstPtr diagnostic_request) noexcept
96  return diagnostic_message_handler_.HandleDiagnosticRequest(std::move(diagnostic_request));
97 }
98 
99 auto DoipTcpChannelHandler::HandleMessage(TcpMessagePtr tcp_rx_message) noexcept -> void {
100  std::uint8_t nack_code{};
101  DoipMessage doip_rx_message{DoipMessage::MessageType::kTcp, tcp_rx_message->GetHostIpAddress(),
102  tcp_rx_message->GetHostPortNumber(), tcp_rx_message->GetPayload()};
103  // Process the Doip Generic header check
104  if (ProcessDoIPHeader(doip_rx_message, nack_code)) {
105  ProcessDoIPPayload(doip_rx_message);
106  } else {
107  // send NACK or ignore
108  (void) nack_code;
109  }
110 }
111 
114 }
115 
117  std::uint8_t &nack_code) noexcept -> bool {
118  bool ret_val = false;
119  /* Check the header synchronisation pattern */
120  if (((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion) &&
121  (doip_rx_message.GetInverseProtocolVersion() ==
122  static_cast<std::uint8_t>(~kDoip_ProtocolVersion))) ||
123  ((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion_Def) &&
124  (doip_rx_message.GetInverseProtocolVersion() ==
125  static_cast<std::uint8_t>(~kDoip_ProtocolVersion_Def)))) {
126  /* Check the supported payload type */
127  if ((doip_rx_message.GetPayloadType() == kDoip_RoutingActivation_ResType) ||
128  (doip_rx_message.GetPayloadType() == kDoipDiagMessagePosAck) ||
129  (doip_rx_message.GetPayloadType() == kDoipDiagMessageNegAck) ||
130  (doip_rx_message.GetPayloadType() == kDoipDiagMessage) ||
131  (doip_rx_message.GetPayloadType() == kDoip_AliveCheck_ReqType)) {
132  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00017] */
133  if (doip_rx_message.GetPayloadLength() <= kDoip_Protocol_MaxPayload) {
134  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00018] */
135  if (doip_rx_message.GetPayloadLength() <= kTcpChannelLength) {
136  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00019] */
137  if (ProcessDoIPPayloadLength(doip_rx_message.GetPayloadLength(),
138  doip_rx_message.GetPayloadType())) {
139  ret_val = true;
140  } else {
141  // Send NACK code 0x04, close the socket
143  // socket closure ??
144  }
145  } else {
146  // Send NACK code 0x03, discard message
148  }
149  } else {
150  // Send NACK code 0x02, discard message
152  }
153  } else { // Send NACK code 0x01, discard message
155  }
156  } else { // Send NACK code 0x00, close the socket
158  // socket closure
159  }
160  return ret_val;
161 }
162 
163 auto DoipTcpChannelHandler::ProcessDoIPPayloadLength(std::uint32_t payload_length,
164  std::uint16_t payload_type) noexcept -> bool {
165  bool ret_val{false};
166  switch (payload_type) {
168  if (payload_length <= kDoipRoutingActivationResMaxLen) ret_val = true;
169  break;
170  }
172  case kDoipDiagMessageNegAck: {
173  if (payload_length >= kDoipDiagMessageAckResMinLen) ret_val = true;
174  break;
175  }
176  case kDoipDiagMessage: {
177  // Atleast 1 byte of data must be present
178  if (payload_length >= (kDoipDiagMessageReqResMinLen + 1u)) ret_val = true;
179  break;
180  }
182  if (payload_length <= kDoipRoutingActivationResMaxLen) ret_val = true;
183  break;
184  }
185  default:
186  // do nothing
187  break;
188  }
189  return ret_val;
190 }
191 
193  std::lock_guard<std::mutex> const lck(channel_handler_lock);
194  switch (doip_payload.GetPayloadType()) {
196  // Process RoutingActivation response
197  routing_activation_handler_.ProcessDoIPRoutingActivationResponse(doip_payload);
198  break;
199  case kDoipDiagMessage:
200  // Process Diagnostic Message Response
201  diagnostic_message_handler_.ProcessDoIPDiagnosticMessageResponse(doip_payload);
202  break;
205  // Process positive or negative diag ack message
206  diagnostic_message_handler_.ProcessDoIPDiagnosticAckMessageResponse(doip_payload);
207  break;
208  default:
209  /* do nothing */
210  break;
211  }
212 }
213 } // namespace tcp_channel
214 } // namespace channel
215 } // 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.
sockets::TcpSocketHandler::MessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
DoipTcpChannelHandler(sockets::TcpSocketHandler &tcp_socket_handler, DoipTcpChannel &channel)
Constructs an instance of DoipTcpChannelHandler.
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.
Handler class to manage different socket of various client (Udp / Tcp)
constexpr std::uint16_t kDoip_RoutingActivation_ResType
Routing Activation response Type.
constexpr std::uint8_t kDoipDiagMessageReqResMinLen
Diagnostic Message request/response lengths.
constexpr std::uint8_t kDoip_GenericHeader_IncorrectPattern
Generic DoIP Header NACK codes.
constexpr std::uint32_t kDoipRoutingActivationResMinLen
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