16 #include "common/logger.h" 
   22 namespace tcp_channel {
 
  234       msg << 
"invalid source address.";
 
  237       msg << 
"unknown target address.";
 
  240       msg << 
"diagnostic message too large.";
 
  243       msg << 
"server out of memory.";
 
  246       msg << 
"target unreachable.";
 
  249       msg << 
"unknown network.";
 
  252       msg << 
"transport protocol error.";
 
  255       msg << 
"unknown reason.";
 
  269     -> std::vector<std::uint8_t> {
 
  270   std::vector<std::uint8_t> output_buffer{};
 
  273   output_buffer.emplace_back(
static_cast<std::uint8_t
>((payload_type & 0xFF00) >> 8));
 
  274   output_buffer.emplace_back(
static_cast<std::uint8_t
>(payload_type & 0x00FF));
 
  275   output_buffer.emplace_back(
static_cast<std::uint8_t
>((payload_len & 0xFF000000) >> 24));
 
  276   output_buffer.emplace_back(
static_cast<std::uint8_t
>((payload_len & 0x00FF0000) >> 16));
 
  277   output_buffer.emplace_back(
static_cast<std::uint8_t
>((payload_len & 0x0000FF00) >> 8));
 
  278   output_buffer.emplace_back(
static_cast<std::uint8_t
>(payload_len & 0x000000FF));
 
  279   return output_buffer;
 
  315                             std::make_unique<kIdle>(DiagnosticMessageState::kIdle));
 
  318                             std::make_unique<kSendDiagnosticReqFailed>(
 
  319                                 DiagnosticMessageState::kSendDiagnosticReqFailed));
 
  322         DiagnosticMessageState::kWaitForDiagnosticAck,
 
  323         std::make_unique<kWaitForDiagnosticAck>(DiagnosticMessageState::kWaitForDiagnosticAck));
 
  326                             std::make_unique<kDiagnosticPositiveAckRecvd>(
 
  327                                 DiagnosticMessageState::kDiagnosticPositiveAckRecvd));
 
  330                             std::make_unique<kDiagnosticNegativeAckRecvd>(
 
  331                                 DiagnosticMessageState::kDiagnosticNegativeAckRecvd));
 
  334                             std::make_unique<kWaitForDiagnosticResponse>(
 
  335                                 DiagnosticMessageState::kWaitForDiagnosticResponse));
 
  421   if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
 
  422       DiagnosticMessageState::kWaitForDiagnosticAck) {
 
  424     DiagAckType 
const diag_ack_type{doip_payload.GetPayload()[0u]};
 
  427         final_state = DiagnosticMessageState::kDiagnosticPositiveAckRecvd;
 
  429             FILE_NAME, __LINE__, __func__, [&doip_payload](std::stringstream &msg) {
 
  430               msg << 
"Diagnostic message positively acknowledged from remote " 
  432                   << 
" (0x" << std::hex << doip_payload.GetServerAddress() << 
")";
 
  439           FILE_NAME, __LINE__, __func__, [&diag_ack_type](std::stringstream &msg) {
 
  440             msg << 
"Diagnostic request denied due to " << diag_ack_type;
 
  445     handler_impl_->GetStateContext().TransitionTo(final_state);
 
  446     handler_impl_->GetSyncTimer().CancelWait();
 
  454   if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
 
  455       DiagnosticMessageState::kWaitForDiagnosticResponse) {
 
  459         ret_val{handler_impl_->GetDoipChannel().IndicateMessage(
 
  460             doip_payload.GetServerAddress(), doip_payload.GetClientAddress(),
 
  462             doip_payload.GetPayload().size(), 0u, 
"DoIPTcp", doip_payload.GetPayload())};
 
  468       if ((ret_val.first ==
 
  470           (ret_val.second != 
nullptr)) {
 
  472         (void) std::copy(doip_payload.GetPayload().begin(), doip_payload.GetPayload().end(),
 
  473                          ret_val.second->GetPayload().begin());
 
  474         handler_impl_->GetDoipChannel().HandleMessage(std::move(ret_val.second));
 
  477             FILE_NAME, __LINE__, __func__, [](std::stringstream &msg) {
 
  478               msg << 
"Diagnostic message response ignored due to unknown error";
 
  481       handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
 
  486         FILE_NAME, __LINE__, __func__, [
this](std::stringstream &msg) {
 
  487           msg << 
"Diagnostic message response ignored due to channel in state: " 
  488               << 
static_cast<int>(handler_impl_->GetStateContext().GetActiveState().GetState());
 
  498   if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
 
  499       DiagnosticMessageState::kIdle) {
 
  500     if (SendDiagnosticRequest(std::move(diagnostic_request)) ==
 
  502       handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kWaitForDiagnosticAck);
 
  503       handler_impl_->GetSyncTimer().WaitForTimeout(
 
  507             handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
 
  509                 FILE_NAME, __LINE__, 
"", [](std::stringstream &msg) {
 
  510                   msg << 
"Diagnostic Message Ack Request timed out, no " 
  511                          "response received in: " 
  516             if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
 
  517                 DiagnosticMessageState::kDiagnosticPositiveAckRecvd) {
 
  518               handler_impl_->GetStateContext().TransitionTo(
 
  519                   DiagnosticMessageState::kWaitForDiagnosticResponse);
 
  523                   FILE_NAME, __LINE__, 
"", [](std::stringstream &msg) {
 
  524                     msg << 
"Diagnostic Message Positive Ack received";
 
  530               handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
 
  532                   FILE_NAME, __LINE__, 
"", [](std::stringstream &msg) {
 
  533                     msg << 
"Diagnostic Message Transmission Failed Neg Ack " 
  541       handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
 
  544           [](std::stringstream &msg) { msg << 
"Diagnostic Request Message Transmission Failed"; });
 
  550         FILE_NAME, __LINE__, 
"", [](std::stringstream &msg) {
 
  551           msg << 
"Diagnostic Message Transmission already in progress";
 
  562   constexpr std::uint8_t kSourceAddressSize{4u};
 
  564   std::uint32_t 
const total_diagnostic_response_length{
static_cast<uint32_t
>(
 
  566   TcpMessage::BufferType compose_diag_req{
 
  568   compose_diag_req.reserve(
kDoipheadrSize + total_diagnostic_response_length);
 
  571   compose_diag_req.emplace_back(
 
  572       static_cast<std::uint8_t
>((diagnostic_request->GetSa() & 0xFF00) >> 8u));
 
  573   compose_diag_req.emplace_back(
static_cast<std::uint8_t
>(diagnostic_request->GetSa() & 0x00FF));
 
  575   compose_diag_req.emplace_back(
 
  576       static_cast<std::uint8_t
>((diagnostic_request->GetTa() & 0xFF00) >> 8u));
 
  577   compose_diag_req.emplace_back(
static_cast<std::uint8_t
>(diagnostic_request->GetTa() & 0x00FF));
 
  579   compose_diag_req.insert(compose_diag_req.begin() + 
kDoipheadrSize + kSourceAddressSize,
 
  580                           diagnostic_request->GetPayload().begin(),
 
  581                           diagnostic_request->GetPayload().end());
 
  582   TcpMessagePtr doip_diag_req{std::make_unique<TcpMessage>(diagnostic_request->GetHostIpAddress(),
 
  583                                                            diagnostic_request->GetHostPortNumber(),
 
  584                                                            std::move(compose_diag_req))};
 
  586   if (handler_impl_->GetSocketHandler().Transmit(std::move(doip_diag_req))) {
 
Immutable class to store received doip message.
 
Class implements routing activation handler.
 
void Stop()
Function to stop the handler.
 
DoipTcpChannel & channel_
The reference to doip channel.
 
SyncTimer sync_timer_
Store the synchronous timer.
 
auto GetSyncTimer() noexcept -> SyncTimer &
Function to get the sync timer.
 
DiagnosticMessageHandlerImpl(sockets::TcpSocketHandler &tcp_socket_handler, DoipTcpChannel &channel)
Constructs an instance of DiagnosticMessageHandlerImpl.
 
DiagnosticMessageStateContext state_context_
Stores the diagnostic message states.
 
auto GetDoipChannel() noexcept -> DoipTcpChannel &
Function to get the doip channel.
 
void Reset()
Function to reset the handler.
 
sockets::TcpSocketHandler & tcp_socket_handler_
The reference to socket handler.
 
void Start()
Function to start the handler.
 
auto GetSocketHandler() noexcept -> sockets::TcpSocketHandler &
Function to get the socket handler.
 
auto GetStateContext() noexcept -> DiagnosticMessageStateContext &
Function to get the Diagnostic Message State context.
 
void Stop()
Function to stop the handler.
 
~DiagnosticMessageHandler()
Destruct an instance of DiagnosticMessageHandler.
 
auto HandleDiagnosticRequest(uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
Function to handle sending of diagnostic request.
 
void Start()
Function to start the handler.
 
DiagnosticMessageHandler(sockets::TcpSocketHandler &tcp_socket_handler, DoipTcpChannel &channel)
Constructs an instance of DiagnosticMessageHandler.
 
void Reset()
Function to reset the handler.
 
void ProcessDoIPDiagnosticAckMessageResponse(DoipMessage &doip_payload) noexcept
Function to process received diagnostic acknowledgement from server.
 
auto SendDiagnosticRequest(uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
Function to send diagnostic request.
 
sockets::TcpSocketHandler::MessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
 
std::unique_ptr< DiagnosticMessageHandlerImpl > handler_impl_
Stores the Handler implementation.
 
void ProcessDoIPDiagnosticMessageResponse(DoipMessage &doip_payload) noexcept
Function to process received diagnostic positive/negative response from server.
 
Class to manage a tcp channel as per DoIP protocol.
 
Class implements wait for diagnostic message positive/negative response.
 
void Start() override
Function to start the current state.
 
kWaitForDiagnosticResponse(DiagnosticMessageState state)
Constructs an instance of kWaitForDiagnosticResponse.
 
void Stop() override
Function to stop the current state.
 
Class implements reception of diagnostic negative acknowledgement response.
 
void Start() override
Function to start the current state.
 
void Stop() override
Function to stop the current state.
 
kDiagnosticNegativeAckRecvd(DiagnosticMessageState state)
Constructs an instance of kDiagnosticNegativeAckRecvd.
 
Class implements idle state.
 
kIdle(DiagnosticMessageState state)
Constructs an instance of kIdle.
 
void Stop() override
Function to stop the current state.
 
void Start() override
Function to start the current state.
 
Class implements reception of diagnostic positive acknowledgement response.
 
void Stop() override
Function to stop the current state.
 
kDiagnosticPositiveAckRecvd(DiagnosticMessageState state)
Constructs an instance of kDiagnosticPositiveAckRecvd.
 
void Start() override
Function to start the current state.
 
Class implements sending of diagnostic request failed.
 
void Stop() override
Function to stop the current state.
 
kSendDiagnosticReqFailed(DiagnosticMessageState state)
Constructs an instance of kSendDiagnosticReqFailed.
 
void Start() override
Function to start the current state.
 
Class implements wait for diagnostic acknowledgement response.
 
void Stop() override
Function to stop the current state.
 
void Start() override
Function to start the current state.
 
kWaitForDiagnosticAck(DiagnosticMessageState state)
Constructs an instance of kWaitForDiagnosticAck.
 
static auto GetDiagClientLogger() noexcept -> DoipClientLogger &
 
Handler class to manage different socket of various client (Udp / Tcp)
 
@ kNegTransmitAckReceived
 
void TransitionTo(EnumState state)
 
void AddState(EnumState state, std::unique_ptr< State< EnumState >> state_ptr)
 
void CancelWait()
Function to cancel the synchronous wait.
 
auto IsTimerActive()
Function to query if timer is running.
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeOutOfMemory
 
constexpr std::uint16_t kDoipDiagMessageNegAck
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeTargetUnreachable
 
constexpr std::uint8_t kDoipDiagnosticMessagePosAckCodeConfirm
Diagnostic Message positive acknowledgement code.
 
constexpr std::uint8_t kDoipDiagMessageReqResMinLen
Diagnostic Message request/response lengths.
 
std::ostream & operator<<(std::ostream &msg, DiagAckType diag_ack_type)
Function to stream the diagnostic acknowledgement type.
 
constexpr std::uint16_t kDoipDiagMessagePosAck
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeUnknownNetwork
 
auto CreateDoipGenericHeader(std::uint16_t payload_type, std::uint32_t payload_len) noexcept -> std::vector< std::uint8_t >
Function to create doip generic header.
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeMessageTooLarge
 
constexpr std::uint16_t kDoipDiagMessage
Diagnostic message type.
 
constexpr std::uint8_t kDoipDiagMessageAckResMinLen
 
constexpr std::uint32_t kDoIPDiagnosticAckTimeout
The timeout specifies the maximum time that the test equipment waits for a confirmation ACK or NACK f...
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeTpError
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeInvalidSa
Diagnostic Message negative acknowledgement code.
 
constexpr std::uint8_t kDoipDiagnosticMessageNegAckCodeUnknownTa
 
DiagnosticMessageState
Different diagnostic message state.
 
@ kDiagnosticFinalResRecvd
 
SocketHandler< boost_support::client::tcp::TcpClient > TcpSocketHandler
Type alias of Tcp socket handler.
 
constexpr std::uint8_t kDoipheadrSize
 
constexpr std::uint8_t kDoip_ProtocolVersion
 
std::unique_ptr< const UdsMessage > UdsMessageConstPtr
 
std::unique_ptr< UdsMessage > UdsMessagePtr
 
Type holding acknowledgement type.
 
State
Definitions of different connection state.