Diag-Client-Lib
Classes | Public Types | Public Member Functions | Private Member Functions | Static 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::TcpMessagePtr
 Type alias for Tcp message pointer. More...
 
using TcpMessage = sockets::TcpSocketHandler::TcpMessage
 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...
 

Static Private Member Functions

static void CreateDoipGenericHeader (std::vector< std::uint8_t > &doip_header, std::uint16_t payload_type, std::uint32_t payload_len)
 Function to create doip generic header. 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 377 of file doip_diagnostic_message_handler.cpp.

379  : 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

◆ CreateDoipGenericHeader()

void doip_client::channel::tcp_channel::DiagnosticMessageHandler::CreateDoipGenericHeader ( std::vector< std::uint8_t > &  doip_header,
std::uint16_t  payload_type,
std::uint32_t  payload_len 
)
staticprivate

Function to create doip generic header.

Parameters
[in,out]doip_headerThe doip header
[in]payload_typeThe type of payload
[in]payload_lenThe length of payload

Definition at line 540 of file doip_diagnostic_message_handler.cpp.

541  {
542  doip_header_buffer.emplace_back(kDoip_ProtocolVersion);
543  doip_header_buffer.emplace_back(~(static_cast<std::uint8_t>(kDoip_ProtocolVersion)));
544  doip_header_buffer.emplace_back(static_cast<std::uint8_t>((payload_type & 0xFF00) >> 8));
545  doip_header_buffer.emplace_back(static_cast<std::uint8_t>(payload_type & 0x00FF));
546  doip_header_buffer.emplace_back(static_cast<std::uint8_t>((payload_len & 0xFF000000) >> 24));
547  doip_header_buffer.emplace_back(static_cast<std::uint8_t>((payload_len & 0x00FF0000) >> 16));
548  doip_header_buffer.emplace_back(static_cast<std::uint8_t>((payload_len & 0x0000FF00) >> 8));
549  doip_header_buffer.emplace_back(static_cast<std::uint8_t>(payload_len & 0x000000FF));
550 }
constexpr std::uint8_t kDoip_ProtocolVersion

References doip_client::kDoip_ProtocolVersion.

◆ 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 455 of file doip_diagnostic_message_handler.cpp.

456  {
459  if (handler_impl_->GetStateContext().GetActiveState().GetState() == DiagnosticMessageState::kIdle) {
460  if (SendDiagnosticRequest(std::move(diagnostic_request)) ==
462  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kWaitForDiagnosticAck);
463  handler_impl_->GetSyncTimer().WaitForTimeout(
464  [this, &result]() {
466  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
467  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogError(
468  __FILE__, __LINE__, "", [](std::stringstream &msg) {
469  msg << "Diagnostic Message Ack Request timed out, no response received in: "
470  << kDoIPDiagnosticAckTimeout << "seconds";
471  });
472  },
473  [this, &result]() {
474  if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
475  DiagnosticMessageState::kDiagnosticPositiveAckRecvd) {
476  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kWaitForDiagnosticResponse);
477  // success
479  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
480  __FILE__, __LINE__, "",
481  [](std::stringstream &msg) { msg << "Diagnostic Message Positive Ack received"; });
482  } else {
483  // failed with neg acknowledgement from server
485  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
486  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
487  __FILE__, __LINE__, "",
488  [](std::stringstream &msg) { msg << "Diagnostic Message Transmission Failed Neg Ack Received"; });
489  }
490  },
491  std::chrono::milliseconds{kDoIPDiagnosticAckTimeout});
492  } else {
493  // Failed, do nothing
494  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
495  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogError(
496  __FILE__, __LINE__, "",
497  [](std::stringstream &msg) { msg << "Diagnostic Request Message Transmission Failed"; });
498  }
499  } else {
500  // channel not in idle state
502  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
503  __FILE__, __LINE__, "",
504  [](std::stringstream &msg) { msg << "Diagnostic Message Transmission already in progress"; });
505  }
506  return result;
507 }
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
constexpr std::uint32_t kDoIPDiagnosticAckTimeout
The timeout specifies the maximum time that the test equipment waits for a confirmation ACK or NACK f...

References 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 389 of file doip_diagnostic_message_handler.cpp.

389  {
390  DiagnosticMessageState final_state{DiagnosticMessageState::kDiagnosticNegativeAckRecvd};
391  if (handler_impl_->GetStateContext().GetActiveState().GetState() == DiagnosticMessageState::kWaitForDiagnosticAck) {
392  // get the ack code
393  DiagAckType const diag_ack_type{doip_payload.GetPayload()[0u]};
394  if (doip_payload.GetPayloadType() == kDoip_DiagMessagePosAck_Type) {
395  if (diag_ack_type.ack_type_ == kDoip_DiagnosticMessage_PosAckCode_Confirm) {
396  final_state = DiagnosticMessageState::kDiagnosticPositiveAckRecvd;
397  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogInfo(
398  __FILE__, __LINE__, __func__, [&doip_payload](std::stringstream &msg) {
399  msg << "Diagnostic message positively acknowledged from remote server "
400  << " (0x" << std::hex << doip_payload.GetServerAddress() << ")";
401  });
402  } else {
403  // do nothing
404  }
405  } else if (doip_payload.GetPayloadType() == kDoip_DiagMessageNegAck_Type) {
406  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogWarn(
407  __FILE__, __LINE__, __func__,
408  [&diag_ack_type](std::stringstream &msg) { msg << "Diagnostic request denied due to " << diag_ack_type; });
409  } else {
410  // do nothing
411  }
412  handler_impl_->GetStateContext().TransitionTo(final_state);
413  handler_impl_->GetSyncTimer().CancelWait();
414  } else {
415  /* ignore */
416  }
417 }
constexpr std::uint8_t kDoip_DiagnosticMessage_PosAckCode_Confirm
Diagnostic Message positive acknowledgement code.

References doip_client::logger::DoipClientLogger::GetDiagClientLogger(), doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoip_DiagMessageNegAck_Type, doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoip_DiagMessagePosAck_Type, and doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoip_DiagnosticMessage_PosAckCode_Confirm.

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 419 of file doip_diagnostic_message_handler.cpp.

419  {
420  if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
421  DiagnosticMessageState::kWaitForDiagnosticResponse) {
422  // Indicate upper layer about incoming data
423  std::pair<uds_transport::UdsTransportProtocolMgr::IndicationResult, uds_transport::UdsMessagePtr> ret_val{
424  handler_impl_->GetDoipChannel().IndicateMessage(
425  doip_payload.GetServerAddress(), doip_payload.GetClientAddress(),
426  uds_transport::UdsMessage::TargetAddressType::kPhysical, 0U, doip_payload.GetPayload().size(), 0u,
427  "DoIPTcp", doip_payload.GetPayload())};
429  // keep channel alive since pending request received, do not change channel state
430  } else {
431  // Check result and udsMessagePtr
433  (ret_val.second != nullptr)) {
434  // copy to application buffer
435  (void) std::copy(doip_payload.GetPayload().begin(), doip_payload.GetPayload().end(),
436  ret_val.second->GetPayload().begin());
437  handler_impl_->GetDoipChannel().HandleMessage(std::move(ret_val.second));
438  } else {
439  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
440  __FILE__, __LINE__, __func__,
441  [](std::stringstream &msg) { msg << "Diagnostic message response ignored due to unknown error"; });
442  }
443  handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
444  }
445  } else {
446  // ignore
447  logger::DoipClientLogger::GetDiagClientLogger().GetLogger().LogVerbose(
448  __FILE__, __LINE__, __func__, [this](std::stringstream &msg) {
449  msg << "Diagnostic message response ignored due to channel in state: "
450  << static_cast<int>(handler_impl_->GetStateContext().GetActiveState().GetState());
451  });
452  }
453 }

References 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 387 of file doip_diagnostic_message_handler.cpp.

387 { 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 509 of file doip_diagnostic_message_handler.cpp.

510  {
513  constexpr std::uint8_t kDoipheadrSize{8u};
514  constexpr std::uint8_t kSourceAddressSize{4u};
515  TcpMessagePtr doip_diag_req = std::make_unique<TcpMessage>();
516  // reserve bytes in vector
517  doip_diag_req->GetTxBuffer().reserve(kDoipheadrSize + kDoip_DiagMessage_ReqResMinLen +
518  diagnostic_request->GetPayload().size());
519  // create header
521  doip_diag_req->GetTxBuffer(), kDoip_DiagMessage_Type,
522  kDoip_DiagMessage_ReqResMinLen + static_cast<std::uint32_t>(diagnostic_request->GetPayload().size()));
523  // Add source address
524  doip_diag_req->GetTxBuffer().emplace_back(static_cast<std::uint8_t>((diagnostic_request->GetSa() & 0xFF00) >> 8u));
525  doip_diag_req->GetTxBuffer().emplace_back(static_cast<std::uint8_t>(diagnostic_request->GetSa() & 0x00FF));
526  // Add target address
527  doip_diag_req->GetTxBuffer().emplace_back(static_cast<std::uint8_t>((diagnostic_request->GetSa() & 0xFF00) >> 8u));
528  doip_diag_req->GetTxBuffer().emplace_back(static_cast<std::uint8_t>(diagnostic_request->GetSa() & 0x00FF));
529  // Copy data bytes
530  doip_diag_req->GetTxBuffer().insert(doip_diag_req->GetTxBuffer().begin() + kDoipheadrSize + kSourceAddressSize,
531  diagnostic_request->GetPayload().begin(), diagnostic_request->GetPayload().end());
532 
533  // Initiate transmission
534  if (handler_impl_->GetSocketHandler().Transmit(std::move(doip_diag_req))) {
536  }
537  return ret_val;
538 }
sockets::TcpSocketHandler::TcpMessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
static void CreateDoipGenericHeader(std::vector< std::uint8_t > &doip_header, std::uint16_t payload_type, std::uint32_t payload_len)
Function to create doip generic header.
constexpr std::uint8_t kDoip_DiagMessage_ReqResMinLen
Diagnostic Message request/response lengths.
constexpr std::uint8_t kDoipheadrSize

References doip_client::channel::udp_channel::anonymous_namespace{doip_vehicle_identification_handler.cpp}::CreateDoipGenericHeader(), doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoip_DiagMessage_ReqResMinLen, doip_client::channel::tcp_channel::anonymous_namespace{doip_diagnostic_message_handler.cpp}::kDoip_DiagMessage_Type, 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 383 of file doip_diagnostic_message_handler.cpp.

383 { 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 385 of file doip_diagnostic_message_handler.cpp.

385 { 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 127 of file doip_diagnostic_message_handler.h.

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


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