problem in getting needed data from Zusi application

Hey folks, everyone speaking English may write in this category!
Antworten
Nachricht
Autor
thisismyuname
Beiträge: 2
Registriert: 03.03.2010 11:12:44

problem in getting needed data from Zusi application

#1 Beitrag von thisismyuname »

Hello,

I am currently developing a Client application to receive data from Zusi-3 (Fahrsimulator). I am Programming in C++ and Using Qt Framework for GUI. As per the documentation in order to receive data from Zusi,a client must do the following:

1.Send Hello request
2. Receive Ack from Zusi
3. Send Needed Data Request (Have problems in this step!!!)
4. Receive Ack from Zusi
and so on...

From my client application I sent HELLO Request to Zusi and received ACK (0) from Zusi.
Eventhough I sent Needed Data request command to Zusi it still displays an error "Needed_data Erwartet".

Following is the code. Please let me know where did I go wrong.


#include "clientdialog.h"
#include "ui_clientdialog.h"
#include <QDataStream>
#include <QByteArray>
#include <QDataStream>
#include <QString>
#include <QtDebug>
#include <QAbstractSocket>
#include <sstream>
ClientDialog::ClientDialog(QWidget *parent)
: QDialog(parent), ui(new Ui::ClientDialog)
{
ui->setupUi(this);
ui->hostNameEdit->setText("localhost");
ui->portNumberEdit->setText("1435");

// Connecting the Signals and Slots
// When START button is clicked, Connection to the Server is ESTABLISHED
connect(ui->startButton, SIGNAL(clicked()), this, SLOT(connectToServer()));

// When STOP button is clicked, Connection to the Server is STOPPED
connect(ui->stopButton, SIGNAL(clicked()), this, SLOT(stopConnectToServer()));

/* QTcpSocket class communicates it's current status by emitting SIGNALS.
In this client application, we listen to connected, disconnected and readyRead SIGNALS.
connected(): Emitted when a successful connectToHost call has been made and a connection
has been established. */

connect(&tcpSocket, SIGNAL(connected()), this, SLOT(statusConnected()));

//disconnected(): Emitted when the socket has been disconnected.
connect(&tcpSocket, SIGNAL(disconnected()), this, SLOT(connectionClosedByServer()));

connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(whileSend()));

/* readyRead(): Emitted when data is available for reading. It is emitted only when new
data is available, so if you don’t read the data, the signal is not re-emitted until even
more data is available. */
connect(&tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveAck()));

/*error(QAbstractSocket::SocketError): Emitted when an error has occurred. The argument
describes the cause of the error. */
connect(&tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
}

/*
connectToServer():
This slot is executed when the user clicks on the Start Button.
connectToHost() on the QTcpSocket object is called to connect to the Server.
Host Name and the Port number are taken from the User Input in Text Edit.
QTcpSocket object emits the connected() signal when the connection is up and running
or error(QAbstractSocket::SocketError) if the connection failed.
Next the User Interface is updated.
Finally, we set the nextBlockSize variable to 0. This variable stores the length of
the next block received from the server.
*/
void ClientDialog::connectToServer()
{
tcpSocket.connectToHost(ui->hostNameEdit->text(),ui->portNumberEdit- >text().toUInt());
ui->startButton->setEnabled(false);
ui->stopButton->setEnabled(true);
ui->currentStatusLabel->setText(tr("Connecting to Server..."));
nextBlockSize = 0;
statusCheck = 0;
}


void ClientDialog::statusConnected()
{
statusCheck = 1;
ui->currentStatusLabel->setText(("Connected to Server..."));

}

void ClientDialog::whileSend()
{
while(1)
{
ui->currentStatusLabel->setText(tr("Entered into while loop..."));
if (statusCheck ==1)
{
qDebug() <<"Value of statuscheck in while loop is";
qDebug() << statusCheck;
sendHelloRequest();
break;
}
}
}
/*
sendHelloRequest():
This SLOT is executed when the QTcpSocket object emits the connected() signal,
indicating that a connection has been established. The slot's task is to generate
a request to the server. The request is with the following format:
Length Contents Term
4 byte xx xx xx xx PACKET_LENGTH
2 byte 00 01 HELLO
1 byte 02 VERSION
1 byte 02 CLIENT_TYPE Note: 02 is for Fahrpult
Variable xx.. String to identify the program. First byte indicates
the length of the string.
At first the data is written to a QByteArray called block.After that,
I call write() on theQTcpSocket to send the block to the server.

*/
void ClientDialog::sendHelloRequest()
{
qDebug() << "First statement of sendHellorequest() function";
QByteArray block;

//The QDataStream class provides serialization of binary data to a QIODevice.
QDataStream out(&block, QIODevice::WriteOnly);

quint32 lengthOfPacket = 13;
qint16 hello = 0001;
qint8 version = 02;
qint8 clientType = 02;
qint8 lengthOfString = 8;
QString identifier = "Fahrpult";
out.setVersion(QDataStream::Qt_4_5);
QDataStream::BigEndian;
out << lengthOfPacket << hello << version << clientType << lengthOfString << identifier;

qDebug() << "Sending Hello Request";
tcpSocket.write(block);
ui->currentStatusLabel->setText(tr("Hello Request Sent..."));
qDebug() << "Hello Request Sent";
}

/*
receiveAck():
This SLOT is connected to the QTcpSocket's readyRead() SIGNAL, which is emitted whenever
the QTcpSocket has received new data from the Server. The Server sends the needed
data. The forever() loop is necessary because I don't necessarily get one block of data from
the server at a time. I might have received an entire block, or just a part of a block, or
one and a half blocks, or even all of the blocks at once.
*/
void ClientDialog::receiveAck()
{
ui->currentStatusLabel->setText(tr("Receiving Ack from Zusi..."));
QDataStream in(&tcpSocket);
in.setVersion(QDataStream::Qt_4_5);
QDataStream::LittleEndian;
forever
{
if (tcpSocket.bytesAvailable()>=7)
{
quint32 recvLength;
in >> recvLength;
qDebug() <<"Received length's value is" << recvLength;
if (recvLength == 3)
{
quint16 ackHello;
in >> ackHello;
if (ackHello == 2)
{
quint8 ack;
in >> ack;
if (ack == 0)
{
qDebug() <<"Ack received from Zusi";
sendNeededData();
break;

}
}
}
}
}
}

/*
Needed Data command must be of the following format
Length Contents Term
4 byte xx xx xx xx PACKET_LENGTH
2 byte 00 03 NEEDED_DATA
2 byte xx xx COMMAND (00 0A – Führerstandanzeigen)
2 byte 00 01 ID for speed
*/
void ClientDialog::sendNeededData()
{
qDebug() << "First statement of sendNeededData() function";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
quint32 lengthOfPacket = 6;
qint16 neededData = 0x0003;
// for Führerstands ID's
qint16 command = 0x000A;
qint16 dataId = 0x0001;

out.setVersion(QDataStream::Qt_4_5);
QDataStream::BigEndian;
out << lengthOfPacket << neededData << command << dataId;
qDebug() << "Sending NeededDataRequest...";
tcpSocket.write(block);
ui->currentStatusLabel->setText(tr("NeededDataRequest has been sent..."));
qDebug() << "NeededDataRequest has been sent...";

}

<Bernd>
Beiträge: 152
Registriert: 21.01.2008 10:01:35
Aktuelle Projekte: Warten auf ...
Wohnort: Windeck/Sieg- RE9 Bhf Schladern

Re: problem in getting needed data from Zusi application

#2 Beitrag von <Bernd> »

hello thisismyuname,

while I am no C programer reading your code brings me to the very end
of your source: you probably forgot to terminate your needed-data-request
by sending the sequence "00 03 00 00". this is to signal the tcp-server
that there is no further needed data request from your client program.

hope that helps
Bernd
Zuletzt geändert von <Bernd> am 04.03.2010 11:51:21, insgesamt 1-mal geändert.
Grüsse von Bernd

thisismyuname
Beiträge: 2
Registriert: 03.03.2010 11:12:44

Re: problem in getting needed data from Zusi application

#3 Beitrag von thisismyuname »

Hallo,

Thank you very much for your reply. I implemented your suggestion and checked but still I received the same error

Benutzeravatar
Roland Ziegler
Beiträge: 5508
Registriert: 04.11.2001 22:09:26
Wohnort: 32U 0294406 5629020
Kontaktdaten:

Re: problem in getting needed data from Zusi application

#4 Beitrag von Roland Ziegler »

Did you check this sample implementation: http://forum.zusi.de/viewtopic.php?p=184105#p184105 ?
It's from a C perspective and does not feature any OO design at all but the basics are the same even in a procedural approach.
Zuletzt geändert von Roland Ziegler am 04.03.2010 15:09:11, insgesamt 1-mal geändert.

Bernhard
Beiträge: 22
Registriert: 11.09.2009 15:44:19

Re: problem in getting needed data from Zusi application

#5 Beitrag von Bernhard »

thisismyuname hat geschrieben:QDataStream::BigEndian;
out << lengthOfPacket << hello << version << clientType << lengthOfString << identifier;
Make sure to encode lengthOfPacket as little endian. Also requested IDs are encoded as one byte each so you're actually requesting two IDs now which should not make a difference though.

Antworten