Diag-Client-Lib
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
doip_client::channel::tcp_channel::DiagnosticMessageHandler Class Referencefinal

Class used as a handler to process routing activation messages. More...

#include <doip_diagnostic_message_handler.h>

Classes

class  DiagnosticMessageHandlerImpl
 Class implements routing activation handler. More...
 

Public Types

using TcpMessagePtr = sockets::TcpSocketHandler::MessagePtr
 Type alias for Tcp message pointer. More...
 
using TcpMessage = sockets::TcpSocketHandler::Message
 Type alias for Tcp message. More...
 

Public Member Functions

 DiagnosticMessageHandler (sockets::TcpSocketHandler &tcp_socket_handler, DoipTcpChannel &channel)
 Constructs an instance of DiagnosticMessageHandler. More...
 
 ~DiagnosticMessageHandler ()
 Destruct an instance of DiagnosticMessageHandler. More...
 
void Start ()
 Function to start the handler. More...
 
void Stop ()
 Function to stop the handler. More...
 
void Reset ()
 Function to reset the handler. More...
 
void ProcessDoIPDiagnosticAckMessageResponse (DoipMessage &doip_payload) noexcept
 Function to process received diagnostic acknowledgement from server. More...
 
void ProcessDoIPDiagnosticMessageResponse (DoipMessage &doip_payload) noexcept
 Function to process received diagnostic positive/negative response from server. More...
 
auto HandleDiagnosticRequest (uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
 Function to handle sending of diagnostic request. More...
 

Private Member Functions

auto SendDiagnosticRequest (uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
 Function to send diagnostic request. More...
 

Private Attributes

std::unique_ptr< DiagnosticMessageHandlerImplhandler_impl_
 Stores the Handler implementation. More...
 

Detailed Description

Class used as a handler to process routing activation messages.

Definition at line 29 of file doip_diagnostic_message_handler.h.

Member Typedef Documentation

◆ TcpMessage

Type alias for Tcp message.

Definition at line 39 of file doip_diagnostic_message_handler.h.

◆ TcpMessagePtr

Type alias for Tcp message pointer.

Definition at line 34 of file doip_diagnostic_message_handler.h.

Constructor & Destructor Documentation

◆ DiagnosticMessageHandler()

doip_client::channel::tcp_channel::DiagnosticMessageHandler::DiagnosticMessageHandler ( sockets::TcpSocketHandler tcp_socket_handler,
DoipTcpChannel channel 
)

Constructs an instance of DiagnosticMessageHandler.

Parameters
[in]tcp_socket_handlerThe reference to socket handler
[in]channelThe reference to doip channel

Definition at line 406 of file doip_diagnostic_message_handler.cpp.

408  : handler_impl_{std::make_unique<DiagnosticMessageHandlerImpl>(tcp_socket_handler, channel)} {}
std::unique_ptr< DiagnosticMessageHandlerImpl > handler_impl_
Stores the Handler implementation.

◆ ~DiagnosticMessageHandler()

doip_client::channel::tcp_channel::DiagnosticMessageHandler::~DiagnosticMessageHandler ( )
default

Destruct an instance of DiagnosticMessageHandler.

Member Function Documentation

◆ HandleDiagnosticRequest()

auto doip_client::channel::tcp_channel::DiagnosticMessageHandler::HandleDiagnosticRequest ( uds_transport::UdsMessageConstPtr  diagnostic_request) -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
noexcept

Function to handle sending of diagnostic request.

Parameters
[in]diagnostic_requestThe diagnostic request
Returns
The Transmission result

Definition at line 493 of file doip_diagnostic_message_handler.cpp.

495  {
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(
504  [this, &result]() {
505  result =
507  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
508  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogError(
509  FILE_NAME, __LINE__, "", [](std::stringstream &msg) {
510  msg << "Diagnostic Message Ack Request timed out, no "
511  "response received in: "
512  << kDoIPDiagnosticAckTimeout << " seconds";
513  });
514  },
515  [this, &result]() {
516  if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
517  DiagnosticMessageState::kDiagnosticPositiveAckRecvd) {
518  handler_impl_->GetStateContext().TransitionTo(
519  DiagnosticMessageState::kWaitForDiagnosticResponse);
520  // success
522  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
523  FILE_NAME, __LINE__, "", [](std::stringstream &msg) {
524  msg << "Diagnostic Message Positive Ack received";
525  });
526  } else {
527  // failed with neg acknowledgement from server
530  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
531  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
532  FILE_NAME, __LINE__, "", [](std::stringstream &msg) {
533  msg << "Diagnostic Message Transmission Failed Neg Ack "
534  "Received";
535  });
536  }
537  },
538  std::chrono::milliseconds{kDoIPDiagnosticAckTimeout});
539  } else {
540  // Failed, do nothing
541  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
542  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogError(
543  FILE_NAME, __LINE__, "",
544  [](std::stringstream &msg) { msg << "Diagnostic Request Message Transmission Failed"; });
545  }
546  } else {
547  // channel not in idle state
549  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
550  FILE_NAME, __LINE__, "", [](std::stringstream &msg) {
551  msg << "Diagnostic Message Transmission already in progress";
552  });
553  }
554  return result;
555 }
auto SendDiagnosticRequest(uds_transport::UdsMessageConstPtr diagnostic_request) noexcept -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
Function to send diagnostic request.
static auto GetDiagClientLogger() noexcept -> DoipClientLogger &
Definition: logger.h:20
#define FILE_NAME
Definition: file_path.h:14
constexpr std::uint32_t kDoIPDiagnosticAckTimeout
The timeout specifies the maximum time that the test equipment waits for a confirmation ACK or NACK f...

References FILE_NAME, doip_client::logger::DoipClientLogger::GetDiagClientLogger(), uds_transport::UdsTransportProtocolMgr::kBusyProcessing, doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoIPDiagnosticAckTimeout, uds_transport::UdsTransportProtocolMgr::kNegTransmitAckReceived, uds_transport::UdsTransportProtocolMgr::kNoTransmitAckReceived, uds_transport::UdsTransportProtocolMgr::kTransmitFailed, and uds_transport::UdsTransportProtocolMgr::kTransmitOk.

Here is the call graph for this function:

◆ ProcessDoIPDiagnosticAckMessageResponse()

auto doip_client::channel::tcp_channel::DiagnosticMessageHandler::ProcessDoIPDiagnosticAckMessageResponse ( DoipMessage doip_payload)
noexcept

Function to process received diagnostic acknowledgement from server.

Parameters
[in]doip_payloadThe doip message received

Definition at line 418 of file doip_diagnostic_message_handler.cpp.

419  {
420  DiagnosticMessageState final_state{DiagnosticMessageState::kDiagnosticNegativeAckRecvd};
421  if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
422  DiagnosticMessageState::kWaitForDiagnosticAck) {
423  // get the ack code
424  DiagAckType const diag_ack_type{doip_payload.GetPayload()[0u]};
425  if (doip_payload.GetPayloadType() == kDoipDiagMessagePosAck) {
426  if (diag_ack_type.ack_type_ == kDoipDiagnosticMessagePosAckCodeConfirm) {
427  final_state = DiagnosticMessageState::kDiagnosticPositiveAckRecvd;
428  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
429  FILE_NAME, __LINE__, __func__, [&doip_payload](std::stringstream &msg) {
430  msg << "Diagnostic message positively acknowledged from remote "
431  "server "
432  << " (0x" << std::hex << doip_payload.GetServerAddress() << ")";
433  });
434  } else {
435  // do nothing
436  }
437  } else if (doip_payload.GetPayloadType() == kDoipDiagMessageNegAck) {
438  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogWarn(
439  FILE_NAME, __LINE__, __func__, [&diag_ack_type](std::stringstream &msg) {
440  msg << "Diagnostic request denied due to " << diag_ack_type;
441  });
442  } else {
443  // do nothing
444  }
445  handler_impl_->GetStateContext().TransitionTo(final_state);
446  handler_impl_->GetSyncTimer().CancelWait();
447  } else {
448  /* ignore */
449  }
450 }
constexpr std::uint8_t kDoipDiagnosticMessagePosAckCodeConfirm
Diagnostic Message positive acknowledgement code.

References FILE_NAME, doip_client::logger::DoipClientLogger::GetDiagClientLogger(), doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoipDiagMessageNegAck, doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoipDiagMessagePosAck, and doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoipDiagnosticMessagePosAckCodeConfirm.

Here is the call graph for this function:

◆ ProcessDoIPDiagnosticMessageResponse()

auto doip_client::channel::tcp_channel::DiagnosticMessageHandler::ProcessDoIPDiagnosticMessageResponse ( DoipMessage doip_payload)
noexcept

Function to process received diagnostic positive/negative response from server.

Parameters
[in]doip_payloadThe doip message received

Definition at line 452 of file doip_diagnostic_message_handler.cpp.

453  {
454  if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
455  DiagnosticMessageState::kWaitForDiagnosticResponse) {
456  // Indicate upper layer about incoming data
459  ret_val{handler_impl_->GetDoipChannel().IndicateMessage(
460  doip_payload.GetServerAddress(), doip_payload.GetClientAddress(),
462  doip_payload.GetPayload().size(), 0u, "DoIPTcp", doip_payload.GetPayload())};
463  if (ret_val.first ==
465  // keep channel alive since pending request received, do not change channel state
466  } else {
467  // Check result and udsMessagePtr
468  if ((ret_val.first ==
470  (ret_val.second != nullptr)) {
471  // copy to application buffer
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));
475  } else {
476  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
477  FILE_NAME, __LINE__, __func__, [](std::stringstream &msg) {
478  msg << "Diagnostic message response ignored due to unknown error";
479  });
480  }
481  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
482  }
483  } else {
484  // ignore
485  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
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());
489  });
490  }
491 }
std::unique_ptr< UdsMessage > UdsMessagePtr
Definition: uds_message.h:71

References FILE_NAME, doip_client::logger::DoipClientLogger::GetDiagClientLogger(), uds_transport::UdsTransportProtocolMgr::kIndicationOk, uds_transport::UdsTransportProtocolMgr::kIndicationPending, and uds_transport::UdsMessage::kPhysical.

Here is the call graph for this function:

◆ Reset()

void doip_client::channel::tcp_channel::DiagnosticMessageHandler::Reset ( )

Function to reset the handler.

This will reset all the internal handler back to default state

Definition at line 416 of file doip_diagnostic_message_handler.cpp.

416 { handler_impl_->Reset(); }

References handler_impl_.

Referenced by doip_client::channel::tcp_channel::DoipTcpChannelHandler::Reset().

Here is the caller graph for this function:

◆ SendDiagnosticRequest()

auto doip_client::channel::tcp_channel::DiagnosticMessageHandler::SendDiagnosticRequest ( uds_transport::UdsMessageConstPtr  diagnostic_request) -> uds_transport::UdsTransportProtocolMgr::TransmissionResult
privatenoexcept

Function to send diagnostic request.

Parameters
[in]diagnostic_requestThe routing activation request
Returns
The Transmission result

Definition at line 557 of file doip_diagnostic_message_handler.cpp.

559  {
562  constexpr std::uint8_t kSourceAddressSize{4u};
563  // Create header
564  std::uint32_t const total_diagnostic_response_length{static_cast<uint32_t>(
565  kDoipDiagMessageReqResMinLen + diagnostic_request->GetPayload().size())};
566  TcpMessage::BufferType compose_diag_req{
567  CreateDoipGenericHeader(kDoipDiagMessage, total_diagnostic_response_length)};
568  compose_diag_req.reserve(kDoipheadrSize + total_diagnostic_response_length);
569 
570  // Add source address
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));
574  // Add target address
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));
578  // Copy data bytes
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))};
585  // Initiate transmission
586  if (handler_impl_->GetSocketHandler().Transmit(std::move(doip_diag_req))) {
588  }
589  return ret_val;
590 }
sockets::TcpSocketHandler::MessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
constexpr std::uint8_t kDoipDiagMessageReqResMinLen
Diagnostic Message request/response lengths.
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 kDoipheadrSize

References doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::CreateDoipGenericHeader(), doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoipDiagMessage, doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoipDiagMessageReqResMinLen, doip_client::kDoipheadrSize, uds_transport::UdsTransportProtocolMgr::kTransmitFailed, and uds_transport::UdsTransportProtocolMgr::kTransmitOk.

Here is the call graph for this function:

◆ Start()

void doip_client::channel::tcp_channel::DiagnosticMessageHandler::Start ( )

Function to start the handler.

Definition at line 412 of file doip_diagnostic_message_handler.cpp.

412 { handler_impl_->Start(); }

References handler_impl_.

Referenced by doip_client::channel::tcp_channel::DoipTcpChannelHandler::Start().

Here is the caller graph for this function:

◆ Stop()

void doip_client::channel::tcp_channel::DiagnosticMessageHandler::Stop ( )

Function to stop the handler.

This will reset all the internal handler back to default state

Definition at line 414 of file doip_diagnostic_message_handler.cpp.

414 { handler_impl_->Stop(); }

References handler_impl_.

Referenced by doip_client::channel::tcp_channel::DoipTcpChannelHandler::Stop().

Here is the caller graph for this function:

Member Data Documentation

◆ handler_impl_

std::unique_ptr<DiagnosticMessageHandlerImpl> doip_client::channel::tcp_channel::DiagnosticMessageHandler::handler_impl_
private

Stores the Handler implementation.

Definition at line 115 of file doip_diagnostic_message_handler.h.

Referenced by Reset(), Start(), and Stop().


The documentation for this class was generated from the following files: