Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

converting a received UDP datagram to a class object



  • I have designed udp socket based communication between a micro controller and a host.
    With host, application is developed using Qt.
    And with micro controller it is C++.

    From micro controller, the UDP datagram transmitted is as a class object with "sendto()" API.

    The issue experienced is with the Qt application on the host, readDatagram() receives the datagram. But I am not finding an appropriate approach to convert the received datagram to the class object format.
    As the readDatagram(), receives the datagram as (char*).

    Please guide, how could the received datagram processed as class objects to read values of the class data members.



  • @lohithgm
    The fact that server/client are written in different languages is neither here nor there.

    Datagrams are all transmitted as a sequence of chars/bytes, regardless of source.

    The sender uses "serialization" of some kind to send the data message. It's your job to write corresponding "deserialization" code to reconstruct an appropriate object in the native language from whatever is received. You need to look at the source code of the sending application to see what the data format is, to know how to write the receiver end. You might be able to share .h file code for this to save you copying out the information.



  • @JonB

    thanks Jon for deserialization information.
    Please find the header file and also the corresponding datagram sender and receiver code snippet

    // header file, class declaration
    
    class batteryFrame{
        un_int_16 bat_voltage;
        un_int_16 bat_dis_cur;
        un_int_16 bat_temp;
    
    public:
        un_int_16 getBat_voltage() const;
        void setBat_voltage(const un_int_16 &value);
        un_int_16 getBat_dis_cur() const;
        void setBat_dis_cur(const un_int_16 &value);
        un_int_16 getBat_temp() const;
        void setBat_temp(const un_int_16 &value);
        batteryFrame();
        batteryFrame(const batteryFrame& src_obj);
        ~batteryFrame();
    };
    
    class MsgFrame{
        FrameType frame_id;
        batteryFrame payload;
        un_int_8 frame_length;
    
    public:
        FrameType getFrame_id() const;
        void setFrame_id(const FrameType &value);
        void setMsgFrame(batteryFrame value);
        void setFrame_length(const un_int_8 &value);
        MsgFrame();
        MsgFrame(const MsgFrame& src_obj);
        MsgFrame(FrameType id, batteryFrame msgdata, un_int_8 fr_len);
        ~MsgFrame();
    };
    

    // c++ code on safety controller
    // datagram sender
    
    int main()
    {
     // socket creation, binding code not shared
    
        batteryFrame batMsgFr;  // Battery  mesage frame
    // assign value to data members    
    batMsgFr.setBat_voltage(10);  
        batMsgFr.setBat_dis_cur(20);
        batMsgFr.setBat_temp(30);
    
    // composing a message frame 
        MsgFrame msgfr;
        msgfr.setFrame_id(Battery);
        msgfr.setMsgFrame(batMsgFr);  
        msgfr.setFrame_length(msg_len);
    
        sendto(NUC_fd, &msgfr,sizeof(msgfr), 0,(struct sockaddr*)&mpc_addr, len);
        close(NUC_fd);
        return 0;
    }
    

    // Qt application code on Host
    // receiver code
    
    // tried with few approaches, but not able to get the data values
    
    void Widget::readPendingDatagrams()
    {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
    
            batteryFrame batMsgFr;
            udpSocket->readDatagram((char*)&batMsgFr, sizeof(batMsgFr), &sender, &senderPort);
    
            //datastreams, assigning values to class data members
            QDataStream in(&datagram, QIODevice::ReadOnly);
            in >> batMsgFr.bat_voltage >> batMsgFr.bat_dis_cur >> batMsgFr.bat_temp >> batMsgFr.bat_emp_time >> batMsgFr.bat_full_time >> batMsgFr.bat_soc >> batMsgFr.bat_soh;
            qDebug() << " Data Arrived for bat_voltage : " << batMsgFr.bat_voltage;
            qDebug() << " Data Arrived for bat_dis_cur : " << batMsgFr.bat_dis_cur;
            qDebug() << " Data Arrived for bat_temp : " << batMsgFr.bat_temp;
    
    }
    


  • @lohithgm said in converting a received UDP datagram to a class object:

    // socket creation, binding code not shared

    This is a vital part to understand what's going on. Sockets are not part of the standard at the moment (they are planned for C++20) so we need to know what you are using here
    My guess is that sendto it is serialising using reinterpret_cast<char*>. In that case we need to know what FrameType is



  • @lohithgm

    Able to deserialize the received UDP datagram and display the value also, the issue was with the improper class object at the sender and receiver.
    At the sender, "MsgFrame" object is transmitted.
    But with the receiver, "batteryFrame" object is used.

    On using the same objects at both sender and receiver, class data member values were displayed appropriately.


Log in to reply