Diag-Client-Lib
doip_udp_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 
14 #include "common/logger.h"
15 #include "core/include/span.h"
16 
17 namespace doip_client {
18 namespace channel {
19 namespace udp_channel {
20 
24 constexpr std::uint8_t kDoip_GenericHeader_IncorrectPattern{0x00};
25 constexpr std::uint8_t kDoip_GenericHeader_UnknownPayload{0x01};
26 constexpr std::uint8_t kDoip_GenericHeader_MessageTooLarge{0x02};
27 constexpr std::uint8_t kDoip_GenericHeader_OutOfMemory{0x03};
28 constexpr std::uint8_t kDoip_GenericHeader_InvalidPayloadLen{0x04};
29 
31  sockets::UdpSocketHandler &udp_socket_handler_unicast,
32  DoipUdpChannel &channel)
33  : vehicle_discovery_handler_{udp_socket_handler_broadcast, channel},
34  vehicle_identification_handler_{udp_socket_handler_unicast, channel} {}
35 
37  uds_transport::UdsMessageConstPtr vehicle_identification_request) noexcept
41  // Get the udp handler type from payload
42  std::uint8_t const handler_type{vehicle_identification_request->GetPayload()[BYTE_POS_ZERO]};
43  // deserialize and send to proper handler
44  switch (handler_type) {
45  case 0U:
46  // 0U -> Vehicle Identification Req
47  ret_val =
48  vehicle_identification_handler_.HandleVehicleIdentificationRequest(std::move(vehicle_identification_request));
49  break;
50  case 1U:
51  // 1U -> Power Mode Req
52  break;
53  }
54  return ret_val;
55 }
56 
57 auto DoipUdpChannelHandler::HandleMessageUnicast(UdpMessagePtr udp_rx_message) noexcept -> void {
58  std::uint8_t nack_code{};
59  DoipMessage doip_rx_message{DoipMessage::MessageType::kUdp, udp_rx_message->GetHostIpAddress(),
60  udp_rx_message->GetHostPortNumber(),
61  core_type::Span<std::uint8_t>{udp_rx_message->GetRxBuffer()}};
62  // Process the Doip Generic header check
63  if (ProcessDoIPHeader(doip_rx_message, nack_code)) {
64  ProcessDoIPPayload(doip_rx_message);
65  } else {
66  // send NACK or ignore
67  (void) nack_code;
68  }
69 }
70 
71 auto DoipUdpChannelHandler::HandleMessageBroadcast(UdpMessagePtr udp_rx_message) noexcept -> void {
72  uint8_t nack_code;
73  DoipMessage doip_rx_message{DoipMessage::MessageType::kUdp, udp_rx_message->GetHostIpAddress(),
74  udp_rx_message->GetHostPortNumber(),
75  core_type::Span<std::uint8_t>{udp_rx_message->GetRxBuffer()}};
76  // Process the Doip Generic header check
77  if (ProcessDoIPHeader(doip_rx_message, nack_code)) {
78  vehicle_discovery_handler_.ProcessVehicleAnnouncementResponse(doip_rx_message);
79  } else {
80  // send NACK or ignore
81  (void) nack_code;
82  }
83 }
84 
85 auto DoipUdpChannelHandler::ProcessDoIPHeader(DoipMessage &doip_rx_message, std::uint8_t &nack_code) noexcept -> bool {
86  bool ret_val{false};
87  /* Check the header synchronisation pattern */
88  if (((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion) &&
89  (doip_rx_message.GetInverseProtocolVersion() == static_cast<std::uint8_t>(~kDoip_ProtocolVersion))) ||
90  ((doip_rx_message.GetProtocolVersion() == kDoip_ProtocolVersion_Def) &&
91  (doip_rx_message.GetInverseProtocolVersion() == static_cast<std::uint8_t>(~kDoip_ProtocolVersion_Def)))) {
92  /* Check the supported payload type */
93  if (doip_rx_message.GetPayloadType() == kDoip_VehicleAnnouncement_ResType) {
94  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00017] */
95  if (doip_rx_message.GetPayloadLength() <= kDoip_Protocol_MaxPayload) {
96  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00018] */
97  if (doip_rx_message.GetPayloadLength() <= kUdpChannelLength) {
98  /* Req-[AUTOSAR_SWS_DiagnosticOverIP][SWS_DoIP_00019] */
99  if (ProcessDoIPPayloadLength(doip_rx_message.GetPayloadLength(), doip_rx_message.GetPayloadType())) {
100  ret_val = true;
101  } else {
102  // Send NACK code 0x04, close the socket
104  // socket closure ??
105  }
106  } else {
107  // Send NACK code 0x03, discard message
109  }
110  } else {
111  // Send NACK code 0x02, discard message
113  }
114  } else { // Send NACK code 0x01, discard message
116  }
117  } else { // Send NACK code 0x00, close the socket
119  // socket closure
120  }
121  return ret_val;
122 }
123 
124 auto DoipUdpChannelHandler::ProcessDoIPPayloadLength(std::uint32_t payload_len, std::uint16_t payload_type) noexcept
125  -> bool {
126  bool ret_val{false};
127  switch (payload_type) {
129  if (payload_len <= kDoip_VehicleAnnouncement_ResMaxLen) ret_val = true;
130  break;
131  }
132  default:
133  // do nothing
134  break;
135  }
136  return ret_val;
137 }
138 
140  std::lock_guard<std::mutex> const lck(channel_handler_lock);
141  switch (doip_payload.GetPayloadType()) {
144  break;
145  }
146  default:
147  /* do nothing */
148  break;
149  }
150 }
151 
152 } // namespace udp_channel
153 } // namespace channel
154 } // namespace doip_client
Immutable class to store received doip message.
Definition: doip_message.h:21
std::uint16_t GetPayloadType() const
Get the payload type.
Definition: doip_message.h:94
RxSocketType
Definition of socket type from where the request was received.
Definition: doip_message.h:31
sockets::UdpSocketHandler::UdpMessagePtr UdpMessagePtr
Type alias for Tcp message pointer.
std::mutex channel_handler_lock
Mutex to protect critical section.
auto ProcessDoIPHeader(DoipMessage &doip_rx_message, std::uint8_t &nack_code) noexcept -> bool
Function to process doip header in received response.
auto SendVehicleIdentificationRequest(uds_transport::UdsMessageConstPtr vehicle_identification_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
Function to vehicle identification request to the connected network.
void ProcessDoIPPayload(DoipMessage &doip_payload, DoipMessage::RxSocketType socket_type=DoipMessage::RxSocketType::kUnicast)
Function to process the doip payload.
VehicleIdentificationHandler vehicle_identification_handler_
Handler to process vehicle identification req/res messages.
DoipUdpChannelHandler(sockets::UdpSocketHandler &udp_socket_handler_broadcast, sockets::UdpSocketHandler &udp_socket_handler_unicast, DoipUdpChannel &channel)
Constructs an instance of DoipUdpChannelHandler.
void HandleMessageUnicast(UdpMessagePtr udp_rx_message) noexcept
Function to process the received unicast udp message.
static auto ProcessDoIPPayloadLength(std::uint32_t payload_len, std::uint16_t payload_type) noexcept -> bool
Function to verify payload length of various payload type.
void HandleMessageBroadcast(UdpMessagePtr udp_rx_message) noexcept
Function to process the received broadcast udp message.
Class to manage a udp channel as per DoIP protocol.
void ProcessVehicleIdentificationResponse(DoipMessage &doip_payload) noexcept
Function to process received vehicle identification response.
Class used to create a udp socket for handling transmission and reception of udp message from driver.
constexpr uint8_t BYTE_POS_ZERO
Definition: common_header.h:31
constexpr std::uint8_t kDoip_GenericHeader_IncorrectPattern
Generic DoIP Header NACK codes.
constexpr std::uint8_t kDoip_GenericHeader_OutOfMemory
constexpr std::uint8_t kDoip_GenericHeader_InvalidPayloadLen
constexpr std::uint8_t kDoip_GenericHeader_MessageTooLarge
constexpr std::uint8_t kDoip_GenericHeader_UnknownPayload
constexpr std::uint8_t kDoip_ProtocolVersion_Def
constexpr std::uint32_t kDoip_Protocol_MaxPayload
constexpr std::uint32_t kUdpChannelLength
constexpr std::uint16_t kDoip_VehicleAnnouncement_ResType
constexpr std::uint8_t kDoip_ProtocolVersion
constexpr std::uint32_t kDoip_VehicleAnnouncement_ResMaxLen
std::unique_ptr< const UdsMessage > UdsMessageConstPtr
Definition: uds_message.h:69