PDA

View Full Version : Raw data I/O



IODR100
4th March 2016, 21:09
Hi
I have developed a connector with Qt that send instruction to equipement on my site.
This equipement located by it IP give an answer in three times
the instruction is 2 byte 0801
the response will be
- 4 bytes 08010d01.
- 32 bytes 00000..... (just zeros).
- 237 bytes 00000..0100000000000001010101010101000000000000000 000000. ( the first byte with 01 is the 16th one and the series of next 01
bytes are in position 101th.
but data that i recieved is:
- 4 bytes 08010d01.
- 32 bytes 0e1f134ffe..
- 237 bytes 000ffffffff0001deae8546796.......... (not expected data)

this is an extract of my code:


connect(socketts,SIGNAL(readyRead()),this,SLOT(rec ievedata()));
void M10::recievedata()

{
QDataStream in(socketts);
taillemessage=socketts->bytesAvailable();
ui->taillebuffer->append (tr("La taille de la socket est : ")+QString::number(taillemessage));
int row = ui->Notification->rowCount();
QByteArray bab,buffer;
bab.resize(taillemessage);
buffer.resize(500);
int sizebab = in.readRawData(bab.data(),bab.size());

{
buffer=bab.data();
buffer.resize(taillemessage);
if(buffer.size()>2)
{
ui->textBrowser_2->append(buffer.toHex());
QStringList fields1;
ui->Notification->setRowCount(row+1);
fields1 <<buffer.toHex()<<QString::number(buffer.size());
for(int i=0;i<fields1.count();++i)
ui->Notification->setItem(row,i,new QTableWidgetItem(fields1[i]));

taillemessage=0;
}
}
}

can you explain me why the data is not serialized correctly?

d_stranz
5th March 2016, 19:45
Your device has a different "endianess" from your PC for binary data? You also resize "bab" once and "buffer" twice, including after assigning bab.data() to it. Why?

IODR100
5th March 2016, 21:04
Thanks for reply
ths taillemessage is defined by socket.bytesavailable, i try to use buffers to stock data incoming.
can you give an element of response it seem working when i have one packet recieved but for other packets the data displayed is different to data that i have on wireshark.

IODR100
6th March 2016, 10:17
It seem s work with first packet but when other packets becomes i compare. Packets displayed and data packets on wireshark and they are completly different

anda_skoa
6th March 2016, 11:14
How do you store the data until you have reached the necessary amount for interpretation?

Or rather how do you plan on doing this, currently you seem to accumulate everything as text, which is likely not what you will end up using.

Cheers,
_

IODR100
6th March 2016, 14:21
I just recieve data becoming from the equipement who send me response..
but response displayed doesnt match the data on the network.
The data stored in bytearray is simply displayed on textbrowser just to make sure that i have recieved the data that i expected to ricieve.

anda_skoa
6th March 2016, 14:35
You wrote that "the first packet" works, but since TCP does not work with packets I assume you are referring to reponses.
What your code currently doesn't show how you separate responses, i.e. where you determine that one response has endded and the next one has started.

Cheers,
_

IODR100
6th March 2016, 15:30
i dont have specific endword in my response from the controller that i m asking
but if i send instruction 0x0801 automatically the controller will send the respnse in three times
4 bytes 0X08010d01
32 bytes 0000..... (Only zeros)
237 bytes 000000010000000010101010101....01010000000000000.. .....
i know exactly 01 positions but i dont know how can i get those two other packets because i only recieve the first packet authentic.
The others are something like random packets .
How can i get this issu resolved??

Added after 8 minutes:

More explanations
If i recieve the first 4bytes packet i display it on my textbroxser widget . its ok
The second other packets i display theire sizes and what are containing
the size is fine but what contains is alrady something like efffff0000001111ddffffff00000
and sometime when i refresh i get the right packets
However the packets transmitted dont contains delimiter of end sending or something like that.

anda_skoa
6th March 2016, 16:25
Well, if you know that the response has a defined size, then it doesn't need any delimiter.
You can then check the number of received bytes to determine when the next response starts.

My suggestion would be to assmble each response completely before attempting to display it.

Cheers,
_

IODR100
6th March 2016, 17:20
ok how can i do it , i still start on Qt programming can you give me draft of code that i can use for my example

Added after 37 minutes:

can you give me an example to follow
??

ChrisW67
6th March 2016, 20:41
At its simplest, assuming a packet does not take long to process:

// m10.h
class M10: public QObject
{
Q_OBJECT
public:
..
private slots:
void handleReadyRead();
private:
void handleCompletePacket(const QByteArray& packet);

enum { packetSize = 273 };

QTcpSocket m_socket;
QByteArray m_buffer;
}



void M10::handleReadyRead() {
m_buffer.append(m_socket.readAll());
while (m_buffer.size() >= packetSize) {
handleCompletePacket(m_buffer.mid(0, packetSize));
m_buffer = m_buffer.mid(packetSize);
}
}

void M10::handleCompletePacket(const QByteArray& packet) {
...
}


Other notes: You do not need QDataStream for this exercise, and it could get in your way.

IODR100
6th March 2016, 21:17
Chris thanks for reply
i will show you all my code and give me changes to do/


#include "m10.h"
#include "ui_m10.h"

M10::M10(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::M10)
{
taillemessage=0;
ui->setupUi(this);
ui->spinBox->setRange(0,99999);
ui->spinBox->setValue(24001);
ui->IP->setText("10.32.3.12");
socketts=new QTcpSocket(this);
QTimer *timer=new QTimer(this);
timer->start(4000);
connect(timer,SIGNAL(timeout()),this,SLOT(sendrequ est()));
connect(socketts,SIGNAL(connected()),this,SLOT(sen drequest()));
connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(connect tom10()));
connect(socketts,SIGNAL(error(QAbstractSocket::Soc ketError)),this,SLOT(erreurSocket(QAbstractSocket: :SocketError)));
connect(socketts,SIGNAL(readyRead()),this,SLOT(rec ievedata()));
// connect(socketts,SIGNAL(readyRead()),this,SLOT(on_ Configuration_clicked()));
ui->PWD->setEchoMode(QLineEdit::NoEcho);
ui->PWD->setText("klm123");
ui->Login->setText("Admin");
}

void M10::authentification()
{
ui->test->clear();
ui->textBrowser->clear();
ui->textBrowser_2->clear();
QByteArray block;
block.fill(0,22);
//out.setByteOrder(QDataStream::LittleEndian);

if((ui->Login->text())!="Admin"&& ui->PWD->text()!="klm123")
{
ui->textBrowser->append("User not Authorized to login");
}
else
{
int i=1;
ui->textBrowser->append("Authorized");
QDataStream out(&block, QIODevice::WriteOnly);
out <<quint8(i)<<quint8(i)<<(ui->PWD->text()).toUtf8();
block.remove(2,4);
out.device()->seek(0);
socketts->write(block);
ui->Auth->setEnabled(true);
ui->Login->setFocus();
ui->PWD->setFocus();
sendrequest();


}
}
void M10::sendrequest()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint8(ping);
socketts->write(block);
}


void M10::connecttom10()
{

socketts->abort();
socketts->connectToHost(ui->IP->text(),ui->spinBox->value());
ui->textBrowser->append("Connected");
}




void M10::on_pushButton_clicked()
{
ui->textBrowser->append("Wait for connecting....");
}
void M10::erreurSocket(QAbstractSocket::SocketError erreur)
{

switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
{

case QAbstractSocket::HostNotFoundError:
ui->textBrowser->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>"));
break;
case QAbstractSocket::ConnectionRefusedError:
ui->textBrowser->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.</em>"));
break;
case QAbstractSocket::RemoteHostClosedError:
ui->textBrowser->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>"));
break;
default:
ui->textBrowser->append(tr("<em>ERREUR : ") + socketts->errorString() + tr("</em>"));
}
}

void M10::recievedata()

{
QDataStream in(socketts);


taillemessage=socketts->bytesAvailable();



ui->taillebuffer->append (tr("La taille de la socket est : ")+QString::number(taillemessage));
//in.setByteOrder(QDataStream::LittleEndian);

int row = ui->Notification->rowCount();
QByteArray bab,buffer;
buffer.resize(taillemessage);
buffer=socketts->readAll();
ui->textBrowser_2->append(buffer.toHex());
//QStringList fields1;
//ui->Notification->setRowCount(row+1);

// fields1 <<buffer.toHex()<<QString::number(buffer.size());
//for(int i=0;i<fields1.count();++i)
// ui->Notification->setItem(row,i,new QTableWidgetItem(fields1[i]));

taillemessage=0;

}
}


//




M10::~M10()
{
delete ui;
}

void M10::on_Auth_clicked()
{
authentification();
}



void M10::on_Contentnode_clicked()
{

ui->textBrowser_2->clear();
ui->Notification->setRowCount(0);
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.device()->seek(0);
out << quint8(codecnt)<< quint8(node);
socketts->write(block);

}


void M10::on_Configuration_clicked()
{
ui->textBrowser_2->clear();
ui->Notification->setRowCount(0);
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint8(codegrp)<< quint8(node)<<quint8(0);
socketts->write(block);
// QDataStream in (socketts);
// int row = ui->Notification_2->rowCount();
//quint8 ping;
//in >>ping;
// ui->Notification_2->setRowCount(row+1);
//QStringList fields1;
//fields1 << QString::number(ping,16).toUpper();
//for(int i=0;i<fields1.count();++i)
// ui->Notification_2->setItem(row,i,new QTableWidgetItem(fields1[i]));


}



namespace Ui {
class M10;
}

class M10 : public QMainWindow
{
Q_OBJECT

public:
explicit M10(QWidget *parent = 0);

int ping=43;
int codecnt=8;
int codegrp=7;
int node=1;
int grp=6;
QByteArray ch;
~M10();

private slots:
void on_pushButton_clicked();

void authentification();
void connecttom10();
void erreurSocket(QAbstractSocket::SocketError erreur);
void sendrequest();
void recievedata();
void on_Auth_clicked();


void on_Contentnode_clicked();

void on_Configuration_clicked();

private:
Ui::M10 *ui;
QTcpSocket *socketts;
QTimer *timer;
quint8 taillemessage;
};

What does this void function contain??


void M10::handleCompletePacket(const QByteArray& packet) {
...
}

anda_skoa
7th March 2016, 09:36
What does this void function contain??


void M10::handleCompletePacket(const QByteArray& packet) {
...
}

This is the function that handles one complete response.
Here you could add the data to the text browser.

Cheers,
_

IODR100
7th March 2016, 10:17
i m beginner on Qt can you give me more explanations

anda_skoa
7th March 2016, 12:48
i m beginner on Qt can you give me more explanations
Handling your responses is application specific, not Qt specific.

Cheers,
_

IODR100
7th March 2016, 14:26
dont understood your answer

anda_skoa
7th March 2016, 15:19
dont understood your answer
We don't know what you want to do with the response data.
This is your application, your use case, you need to have an idea what to do with the data that is sent by the device, no?

Cheers,
_

IODR100
7th March 2016, 21:20
Ok thanks for answer but i resolve the problem it was just miss undesrtanding.
However , i want to read the 2 final bytes in little endian order and to convert to Uint16;

like if i have 2bytes 0D01 in little endian Uint16 the result will be 269;
i did this line of code but i dont have a good results

if(buffer.size()==164)
{
QDataStream in(buffer);

in.setByteOrder(QDataStream::LittleEndian);
buffer=buffer.right(2);
ui->textBrowser_2->append(buffer.toHex());
ui->textBrowser_2->append(QString::number(buffer.toUInt()));

thanks for help

Added after 1 32 minutes:

i have data recieved 269 bytes 00000000000000000010000000000000000....01010101010 1010303030300000000000000
i want to include in tablewidget Sensor names and states (2 columns)
In the byte array i have 20 of "0x01" 1byte at index from 109 to 128 i want to put a first column Sensor names (Sensor 01 to Sensor 020) and second column
status Normal if 01 , Status Maintenance if O3 , Status Alarm if 02 etc...
can i have Help..