Skip to Content
CTech Digital
  • Home
  • Odoo services
  • AI services
  • Contact us
  • 0
  • Nederlands (BE) English (UK) Français
CTech Digital
  • 0
    • Home
    • Odoo services
    • AI services
    • Contact us
  • Nederlands (BE) English (UK) Français

13/6/25

Handshake adding
  • All Blogs
  • Daily blog
  • 13/6/25
  • 13 June 2025 by
    CTech Metrology, Luc Wens

    Diagnostics on send and receive

    We have set handlers for send and receive to show messages on console screens.

    OnDiagnosticFunction PrintSendDiagnostics = [](std::unique_ptr<CTCPGram> &TCPGram, bool send, int port) -> void

    This feedback is set in CCommunicationObject::Open.

    It will show in darkblue messages send, in lightblue the return.


    Handshake for proxies

    Handshake was implemented for the XML style of sending messages, not yet for the JSON style.

    First (failed) attempt

    A first try was to set a handshake lamba in CProxyDevice::Connect :

    void CProxyDevice::Connect()
    {
       ........
        auto handShake = [this](SOCKET, size_t) { this->HandShake(); };
        m_CommunicationObject.SetOnConnectFunction(handShake);

       .........
        m_CommunicationObject.Open(TCP_CLIENT, m_TCP_Port);
    }

    This blocked. The reason is that Handshake contains a request itself, and the the lambda passed to SetOnConnectFunction will be copied and handled inside the communication thread CommunicationThread. Since it will send the handshake inside that thread, and then waits for the reply. But the communication thread cannot generate that reply because it is blocked.

    So a better approach is in CProxyDevice::Connect to send a request that returns immediately with a future to a message, and we wait on that future. This waiting will then happen in the main thread and the communication thread is no longer blocked.

    Second attempt with future

    Future mechanisme is not there yet, so we need to add this.

    The current function is CProxyDevice::SendTrackRequest

    bool CProxyDevice::SendTrackRequest(CTrack::Message &messageIn, CTrack::Message &messageOut, int timeoutSecs)
    {
        auto messageResponder = m_CommunicationObject.GetMessageResponder();
        if (messageResponder)
        {
            CProxyDevice::StartProxy();
            CProxyDevice::Connect();
            std::future<CTrack::Message> future;
            messageResponder->SendTrackRequest(messageIn, future);

            if (future.wait_for(std::chrono::seconds(timeoutSecs)) == std::future_status::timeout)
            {
                messageResponder->CancelRequest(messageIn);
                PrintError("Timeout waiting for handshake response on port {}", m_TCP_Port);
                return false;
            }
            messageOut = std::move(future.get());
            return true;
        }
        return false;
    }

    And for the Handshake we have

    bool CProxyDevice::HandShake()
    {
    .....
        CTrack::Message message;
        message.SetID(TAG_HANDSHAKE);
        message.SetParams({{ATTRIB_CHALLENGE, challengeBase64}});
        CTrack::Message response;
        if (!SendTrackRequest(message, response))
        {
            PrintError("Handshake failed on port {}", m_TCP_Port);
            return false;
        }
        ChallengeReturnBase64                         = response.GetParams()

    .....
    }

    So we need a new variant of this function where we send a request and return immediately with the future that holds the answer of the proxy.

    We cannot do this by setting an onConnect hook, because then we are already inside the communication thread. Instead it has to be in CProxyDevice::Connect.

    Remember that the purpose of the handshake is to make sure that the started proxy is actually the one made by CTech, and not an imposter that tries to hook up expensive equipment with a cheap license.


    Still a problem when reconnecting

    Steps:

    • In the engine click h to start hardware detect => works fine : handshake is done first, then the hardwaredetect is send
    • click again h => still works fine
    • Close the template proxy manually
    • click h => the handshake request is send before the TCP connection is established

    The first time the message is only send after a connection was established (1).

    The second time (2), the connection is wrongly denoted as established, so the request is send when the connection is not establish yet, and the request never reaches the new proxy.

    Turns out the problem was in CProxyDevice::Connect:

     m_CommunicationObject.WaitConnection(TIMEOUTSECS);

    Problems:

    • WaitConnection expects a timeout in milliseconds, we give something in seconds
    • The time-out will make WaitConnection return false, this is not checked

    Fixes were made and committed to 690b893904ff1bda387e134fad77c4b2c8d086c5 

    Test then done with both Vicon and Template and that works ok.

    Other points to look at:

    • Viewer is not showing numbers anymore
    • Logging : add commands and replies, or messages in general via the PrintSendDiagnostics functions
    • In logs we sometimes get the same info two times via source and sourceDetails
    • Add to settings the log level or individual on/off choices
    • start stop does restart the proxy
    in Daily blog
    # CTrack
    12/6/25
    Copyright © CTech
    Nederlands (BE) | English (UK) | Français
    Powered by Odoo - The #1 Open Source eCommerce