?? client.cpp
字號:
/*
qpegps is a program for displaying a map centered at the current longitude/
latitude as read from a gps receiver.
Copyright (C) 2002 Ralf Haselmeier <Ralf.Haselmeier@gmx.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include "client.h"
#include "qpegps.h"
#include "settings.h"
#include <qmessagebox.h>
#include <qapplication.h>
#include <qpe/qpedebug.h>
int Client::resumeEvent = -1;
int Client::resumeFlag = 0;
int Client::gpsdCounter = 1;
//Client::Client( GpsData *gData )
Client::Client(Qpegps * appl)
: application(appl), status(Stopped)
{
gpsData.connected = false;
gpsData.online = false;
// gpsData->gpsData.timestamp.setDate(QDate(0,0,0));
// gpsData->gpsData.timestamp.setDate(QDate(0,0,0));
gpsData.status = GpsData::NoFix;
// startGpsd();
// setup socket for communication with gpsd
gpsSocket = new QSocket(this);
connect(gpsSocket, SIGNAL(connected()), SLOT(socketConnected()));
connect(gpsSocket, SIGNAL(connectionClosed()), SLOT(socketClosed()));
connect(gpsSocket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
connect(gpsSocket, SIGNAL(error(int)), SLOT(socketError(int)));
timer = new QTimer(this);
connect( timer, SIGNAL(timeout()),
SLOT(gpsTimeout()) ); // redraw map every 500 msec indep. of gpsData
timer->start(100, false); // check for changes every 100 msec
// activate resume events
qcopChannel = new QCopChannel( "QPE/System", this );
connect( qcopChannel, SIGNAL(received(const QCString&, const QByteArray&)),
this, SLOT(qcopResume(const QCString&, const QByteArray&)) );
signal(SIGCONT, &signalResume);
// startConnection();
}
Client::~Client()
{
closeConnection();
system(gpsOptions.stopScript.join("\n"));
qDebug("stop script called\n");
}
void Client::closeConnection()
{
if (gpsData.connected) {
gpsSocket->close();
if ( gpsSocket->state() == QSocket::Closing ) {
connect( gpsSocket, SIGNAL(delayedCloseFinished()),
SLOT(socketClosed()) );
} else {
socketClosed();
}
}
}
void Client::restartGpsd()
{
closeConnection();
system(gpsOptions.stopScript.join("\n"));
qDebug("stop script called\n");
startGpsd();
startConnection();
}
void Client::startConnection()
{
if (status == Starting || status == StartingConnect
|| status == WaitingConnection) {
// we are waiting for gpsd to start, postpone the connection
gpsData.statusStr = tr("Waiting the connection to gpsd...");
status = StartingConnect;
return;
}
if (gpsData.connected) {
return;
}
gpsSocket->connectToHost(gpsOptions.host, gpsOptions.port);
gpsData.statusStr = tr("Waiting the connection to gpsd...");
status = StartingConnect;
gpsdCounter = 1;
}
void Client::queryGpsd()
{
// write to gpsd
QString str("w+xi\n");
gpsSocket->writeBlock(str, str.length());
}
void Client::socketConnected()
{
// connection established
gpsData.connected = true;
gpsData.online = false;
gpsData.statusStr = tr("Connecting to gpsd...");
status = Connecting;
emit updated(STA);
// first query to get name and status and set watcher mode
queryGpsd();
gpsdCounter = 1;
}
void Client::socketClosed()
{
gpsData.connected = false;
gpsData.online = false;
gpsData.statusStr = tr("gpsd connection closed");
status = Stopped;
emit updated(STA);
}
void Client::socketError(int e)
{
QString strError;
switch ( e ) {
case QSocket::ErrConnectionRefused:
strError = tr("Connection to gpsd refused");
break;
case QSocket::ErrHostNotFound:
strError = tr("gpsd host address/port not found");
break;
case QSocket::ErrSocketRead:
// NOTE: if gpsd is killed, this error is received
strError = tr("could not read data from gpsd");
break;
default:
strError = tr("Error number %1 occured").arg(e);
break;
}
qDebug("No gpsd running or network error: %s", (const char *) strError);
// no matter the error, disconnect from the server
closeConnection();
}
void Client::socketReadyRead()
{
// make sure an entire line is available
if( !gpsSocket->canReadLine() ) {
gpsSocket->waitForMore(25); // wait 25 msec
}
// read and process all available lines
while ( gpsSocket->canReadLine() ) {
QString dataStr(gpsSocket->readLine());
// qDebug("Received data: %s", (const char *) dataStr);
parseGps(dataStr);
}
}
void Client::startGpsd()
{
system(gpsOptions.startScript.join("\n"));
qDebug("start script called\n");
gpsdCounter = 1;
gpsData.statusStr = tr("Starting gpsd...");
status = Starting;
}
void Client::gpsTimeout()
{
static bool dialogActive = false;
if (resumeFlag == resumeEvent) {
resumeFlag = 0;
closeConnection();
system(gpsOptions.resumeScript.join("\n"));
startConnection();
}
switch( status) {
case Starting:
// gpsd starting: wait 3 seconds and go to stopped
if (gpsdCounter == 30) {
gpsData.statusStr = "";
status = Stopped;
}
case StartingConnect:
// gpsd starting and waiting to connect: wait 3 seconds and connect
if (gpsdCounter == 30) {
gpsData.statusStr = "";
status = Stopped;
startConnection();
}
break;
case WaitingConnection:
// waiting the socket connection to gpsd: wait 1 seconds and retry
if (gpsdCounter == 10) {
closeConnection();
startConnection();
}
break;
case Connecting:
// waiting for the first message from gpsd
if (gpsdCounter == 0) {
gpsData.statusStr = ""; // hide label, if everything is OK
status = Running;
} else if (gpsdCounter == 50) { // 5 seconds without data
// switch to GPS setup page (makes sense right now)
application->showPage(reinterpret_cast<QWidget *>(application->viewGpsStatus));
if (!dialogActive) { // do not display dialog if there's already one
dialogActive = true;
QMessageBox mb( "QpeGps",
tr("Cannot connect to GPS!\n\n"
"Abort: Exit QpeGps now.\n"
"Retry: Start gpsd with default settings.\n"
"Ignore: Change setup on GPS page."),
QMessageBox::Critical,
QMessageBox::Abort,
QMessageBox::Retry | QMessageBox::Default,
QMessageBox::Ignore);
// run modal
mb.exec();
mb.hide();
switch(mb.result()) {
case QMessageBox::Abort:
closeConnection();
QApplication::exit(1);
break;
case QMessageBox::Retry:
// OK, we never had a working gpsd connection, restart gpsd
restartGpsd();
break;
default:
// user asked to ignore this - alright, let him deal with this
gpsData.statusStr = "";
status = Stopped;
break;
}
dialogActive = false;
}
return;
}
case Running:
// waiting for gpsd data
if (gpsdCounter == 0/* || gpsdCounter % 10*/) {
// update();
// emit newData();
} else if ( gpsdCounter == 50 ) { // 5 seconds without data
if (gpsData.connected) {
// try to manual request gpsd
queryGpsd();
gpsdCounter = -1; // next iteration will update
}
}
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -