16 #include "common/logger.h"
22 namespace tcp_channel {
231 msg <<
"invalid source address.";
234 msg <<
"unknown target address.";
237 msg <<
"diagnostic message too large.";
240 msg <<
"server out of memory.";
243 msg <<
"target unreachable.";
246 msg <<
"unknown network.";
249 msg <<
"transport protocol error.";
252 msg <<
"unknown reason.";
287 state_context_.
AddState(DiagnosticMessageState::kIdle, std::make_unique<kIdle>(DiagnosticMessageState::kIdle));
290 DiagnosticMessageState::kSendDiagnosticReqFailed,
291 std::make_unique<kSendDiagnosticReqFailed>(DiagnosticMessageState::kSendDiagnosticReqFailed));
294 std::make_unique<kWaitForDiagnosticAck>(DiagnosticMessageState::kWaitForDiagnosticAck));
297 DiagnosticMessageState::kDiagnosticPositiveAckRecvd,
298 std::make_unique<kDiagnosticPositiveAckRecvd>(DiagnosticMessageState::kDiagnosticPositiveAckRecvd));
301 DiagnosticMessageState::kDiagnosticNegativeAckRecvd,
302 std::make_unique<kDiagnosticNegativeAckRecvd>(DiagnosticMessageState::kDiagnosticNegativeAckRecvd));
305 DiagnosticMessageState::kWaitForDiagnosticResponse,
306 std::make_unique<kWaitForDiagnosticResponse>(DiagnosticMessageState::kWaitForDiagnosticResponse));
391 if (handler_impl_->GetStateContext().GetActiveState().GetState() == DiagnosticMessageState::kWaitForDiagnosticAck) {
393 DiagAckType const diag_ack_type{doip_payload.GetPayload()[0u]};
396 final_state = DiagnosticMessageState::kDiagnosticPositiveAckRecvd;
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() <<
")";
407 __FILE__, __LINE__, __func__,
408 [&diag_ack_type](std::stringstream &msg) { msg <<
"Diagnostic request denied due to " << diag_ack_type; });
412 handler_impl_->GetStateContext().TransitionTo(final_state);
413 handler_impl_->GetSyncTimer().CancelWait();
420 if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
421 DiagnosticMessageState::kWaitForDiagnosticResponse) {
423 std::pair<uds_transport::UdsTransportProtocolMgr::IndicationResult, uds_transport::UdsMessagePtr> ret_val{
424 handler_impl_->GetDoipChannel().IndicateMessage(
425 doip_payload.GetServerAddress(), doip_payload.GetClientAddress(),
427 "DoIPTcp", doip_payload.GetPayload())};
433 (ret_val.second !=
nullptr)) {
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));
440 __FILE__, __LINE__, __func__,
441 [](std::stringstream &msg) { msg <<
"Diagnostic message response ignored due to unknown error"; });
443 handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
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());
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(
466 handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
468 __FILE__, __LINE__,
"", [](std::stringstream &msg) {
469 msg <<
"Diagnostic Message Ack Request timed out, no response received in: "
474 if (handler_impl_->GetStateContext().GetActiveState().GetState() ==
475 DiagnosticMessageState::kDiagnosticPositiveAckRecvd) {
476 handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kWaitForDiagnosticResponse);
480 __FILE__, __LINE__,
"",
481 [](std::stringstream &msg) { msg <<
"Diagnostic Message Positive Ack received"; });
485 handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
487 __FILE__, __LINE__,
"",
488 [](std::stringstream &msg) { msg <<
"Diagnostic Message Transmission Failed Neg Ack Received"; });
494 handler_impl_->GetStateContext().TransitionTo(DiagnosticMessageState::kIdle);
496 __FILE__, __LINE__,
"",
497 [](std::stringstream &msg) { msg <<
"Diagnostic Request Message Transmission Failed"; });
503 __FILE__, __LINE__,
"",
504 [](std::stringstream &msg) { msg <<
"Diagnostic Message Transmission already in progress"; });
514 constexpr std::uint8_t kSourceAddressSize{4u};
515 TcpMessagePtr doip_diag_req = std::make_unique<TcpMessage>();
518 diagnostic_request->GetPayload().size());
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));
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));
530 doip_diag_req->GetTxBuffer().insert(doip_diag_req->GetTxBuffer().begin() +
kDoipheadrSize + kSourceAddressSize,
531 diagnostic_request->GetPayload().begin(), diagnostic_request->GetPayload().end());
534 if (handler_impl_->GetSocketHandler().Transmit(std::move(doip_diag_req))) {
541 std::uint16_t payload_type, std::uint32_t payload_len) {
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));
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.
sockets::TcpSocketHandler::TcpMessagePtr TcpMessagePtr
Type alias for Tcp message pointer.
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.
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.
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 &
Class used to create a tcp socket for handling transmission and reception of tcp message from driver.
@ 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 kDoip_DiagnosticMessage_NegAckCode_OutOfMemory
constexpr std::uint8_t kDoip_DiagMessage_ReqResMinLen
Diagnostic Message request/response lengths.
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_UnknownNetwork
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_TPError
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_InvalidSA
Diagnostic Message negative acknowledgement code.
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_MessageTooLarge
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_TargetUnreachable
constexpr std::uint16_t kDoip_DiagMessageNegAck_Type
constexpr std::uint16_t kDoip_DiagMessage_Type
Diagnostic message type.
constexpr std::uint8_t kDoip_DiagnosticMessage_PosAckCode_Confirm
Diagnostic Message positive acknowledgement code.
constexpr std::uint8_t kDoip_DiagnosticMessage_NegAckCode_UnknownTA
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 kDoip_DiagMessageAck_ResMinLen
DiagnosticMessageState
Different diagnostic message state.
@ kDiagnosticFinalResRecvd
constexpr std::uint16_t kDoip_DiagMessagePosAck_Type
std::ostream & operator<<(std::ostream &msg, DiagAckType diag_ack_type)
Function to stream the diagnostic acknowledgement type.
void CreateDoipGenericHeader(std::vector< std::uint8_t > &doip_header_buffer, std::uint16_t payload_type, std::uint32_t payload_len)
Create the doip generic header.
constexpr std::uint8_t kDoipheadrSize
constexpr std::uint8_t kDoip_ProtocolVersion
std::unique_ptr< const UdsMessage > UdsMessageConstPtr
Type holding acknowledgement type.