⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qirserver.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS and its licensors.** All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.** See below for additional copyright and license information**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qirserver.h"#include <qtopia/mimetype.h>#include <qtopia/qcopenvelope_qws.h>#include <qtopia/private/task.h>#include <qsocketnotifier.h>#include <qfile.h>#include <qtimer.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#define QTOPIA_DEBUG_OBEXextern "C" { #include "openobex/obex.h"}class QObexBase :public QObject{    Q_OBJECT;public:    QObexBase( QObject *parent = 0, const char *name = 0 );    ~QObexBase();signals:    void error();    void statusMsg(const QString &);    void aboutToDelete();public slots:    void abort();protected slots:    void deleteMeLater();    void processInput();    protected:    virtual void doPending() = 0;    void connectSocket();    obex_t *self;    bool finished;    bool aborted;private slots:    void deleteThis();};QObexBase::QObexBase( QObject *parent , const char *name )    :QObject( parent, name ){    finished = FALSE;    aborted = FALSE;}QObexBase::~QObexBase(){    OBEX_Cleanup( self );}void QObexBase::connectSocket(){    QSocketNotifier *sn = new QSocketNotifier( OBEX_GetFD( self ),					       QSocketNotifier::Read,					       this );    connect( sn, SIGNAL(activated(int)), this, SLOT(processInput()) );}void QObexBase::deleteMeLater(){    QTimer::singleShot( 0, this, SLOT(deleteThis()) );}void QObexBase::deleteThis(){    emit aboutToDelete();    delete this;}void QObexBase::abort(){    aborted = TRUE;    finished = TRUE;}void QObexBase::processInput(){    if ( !aborted )	OBEX_HandleInput( self, 0 );    if ( aborted )	deleteMeLater();    if ( finished )	doPending();}static void qobex_sender_callback(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp);class QObexSender : public QObexBase{    Q_OBJECT;public:    QObexSender( QObject *parent = 0, const char *name = 0 );    ~QObexSender();    void beam( const QString& filename, const QString& mimetype );signals:    void done();    void progress(int);private slots:    void tryConnecting(); private:    friend void qobex_sender_callback(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp);    enum State { Init, Connecting, Streaming,   		 Disconnecting, Error };    void process( obex_object_t *object ) {	if( object && OBEX_Request(self, object) < 0) {	    /* Error */	    qWarning( "could not request" );	    state = Error;	    finished = TRUE;        } else {	  finished = FALSE;	}    }    void feedStream( obex_object_t *);    void updateProgress( obex_object_t *);    void doPending();    void putFile( const QString&, const QString& );    QString file_to_send;    QString mime_to_send;    QFile *file_being_sent;    State state;    int connectCount;};class QObexReceiver;static void qobex_server_callback(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp);class QObexServer : public QObexBase{  friend void qobex_server_callback(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rs);  Q_OBJECT;public:  QObexServer( QObject *parent = 0, const char *name = 0 );  ~QObexServer();protected:    void doPending();private slots:    void slotReceiving(bool);	    void sessionEnded();    void finishedReceive();signals:    void receiving(bool);private:    QTimer *m_timer;    QObexReceiver *m_receiver;    bool m_receiving;    void spawnReceiver( obex_t *handle );    enum State { Init, Connecting, Receiving,   		 Disconnecting, Finished, Error, Aborted };    State state;};static void qobex_receiver_callback(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp);class QObexReceiver : public QObexBase{    Q_OBJECT;public:    QObexReceiver( obex_t *handle, QObject *parent = 0, const char *name = 0 );    ~QObexReceiver();    //a link error finish is a successful finish of a beamed file    //but terminates with a LINKERR message. some phones do this    //and create an obex session for each file they want to send   //sending a link error after each     bool linkErrFinish() const { return m_linkErrFinish; }protected:    void doPending();signals:    void receiving(bool);    void receiving( int size, const QString & name, const QString & mime );    void progress( int size );    void fileComplete();    //void received( const QString & name, const QString & mime );    //there is no easy way to emit this signal inbetween sends without    //screwing devices like the S45 which are tempremental over timing    //don't need it anywayprivate:    friend void qobex_receiver_callback(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp);    enum State { Init, Connecting, Receiving,   		 Disconnecting, Finished, Error, Aborted };    void readData( obex_object_t *);    void updateProgress( obex_object_t *);    void getHeaders( obex_object_t *object );    State state;    QString filename;    QString mimetype;    int reclen;    bool m_linkErrFinish;    QFile outfile;};/*  QObexSender functions */void QObexSender::feedStream( obex_object_t *object ){    static char buf[4096];    ASSERT( state == Streaming &&  file_being_sent );    obex_headerdata_t hd;    int len = file_being_sent->readBlock( buf, 4096 );    if ( len > 0 ) {	hd.bs = (uchar*)buf;	OBEX_ObjectAddHeader(self, object, OBEX_HDR_BODY,			     hd, len, OBEX_FL_STREAM_DATA);    } else {	/* EOF */	hd.bs = 0;	OBEX_ObjectAddHeader(self, object, OBEX_HDR_BODY,			     hd, 0, OBEX_FL_STREAM_DATAEND);	file_being_sent->close();	delete file_being_sent;	file_being_sent = 0;    } }void QObexSender::updateProgress( obex_object_t * /* obj */){    emit progress( file_being_sent->at() );}static bool hasTasks( const QString &filename ){    QValueList<Task> tasks = Task::readVCalendar( filename );    return tasks.count();}void QObexSender::putFile( const QString &filename, const QString& mimetype ){    obex_headerdata_t hd;            obex_object_t *object = OBEX_ObjectNew(self, OBEX_CMD_PUT);    if (object == NULL) {	/* Error */	qWarning( "null object" );	state = Error;	finished = TRUE;	return;    }    file_being_sent = new QFile( filename );    if ( file_being_sent->open(IO_ReadOnly) ) {	int body_size = file_being_sent->size();        	/* Add length header */	hd.bq4 = body_size;	OBEX_ObjectAddHeader(self, object,			     OBEX_HDR_LENGTH, hd, 4, 0);        	/* Add type header */	hd.bs = (uchar*)mimetype.latin1();	OBEX_ObjectAddHeader(self, object,			     OBEX_HDR_TYPE, hd, mimetype.length()+1, 0);        	/* Add PalmOS-style application id header */	// ####### if more PalmOS applications have this problem,	// ####### a more general solution is required.	if ( mimetype == "text/x-vCalendar" ) {	    if ( hasTasks( filename ) )		hd.bq4 = 0x746F646F; // "todo"	    else		hd.bq4 = 0x64617465; // "date"	    OBEX_ObjectAddHeader(self, object, 0xcf, hd, 4, 0);	}        	/* Add unicode name header*/		QString uc = filename + QChar( 0x0 );	uc = uc.mid( uc.findRev("/")+1 );	int name_size = uc.length() * 2;	hd.bs = (uchar*) uc.unicode();	OBEX_ObjectAddHeader(self, object,			     OBEX_HDR_NAME, hd, name_size, 0);	state = Streaming;	hd.bs = 0;	OBEX_ObjectAddHeader(self, object, OBEX_HDR_BODY,			     hd, 0, OBEX_FL_STREAM_START);	process( object );    }}static bool transmitDone = FALSE;void QObexSender::doPending(){#ifdef QTOPIA_DEBUG_OBEX    qDebug( "QObexSender::doPending %d", state );#endif    if ( state == Connecting ) {#ifdef QTOPIA_DEBUG_OBEX	qDebug( "state Connecting" );#endif	// finished connecting; time to send	putFile( file_to_send, mime_to_send );	file_to_send = QString::null;    } else if ( state == Streaming ) {#ifdef QTOPIA_DEBUG_OBEX	qDebug( "state Streaming" );#endif	//finished streaming	obex_object_t *object = OBEX_ObjectNew(self, OBEX_CMD_DISCONNECT);	process( object );	state = Disconnecting;    } else if ( state == Disconnecting ) {#ifdef QTOPIA_DEBUG_OBEX	qDebug( "state Disconnecting" );#endif	OBEX_TransportDisconnect(self);	state = Init;	emit done();	deleteMeLater();    }}static void qobex_sender_callback(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp){    QObexSender *sender = (QObexSender*)OBEX_GetUserData( handle );#ifdef QTOPIA_DEBUG_OBEX    qDebug( "qobex_sender_callback %p, %p, %p, %d, event %x, cmd %x, rsp %x",       sender, handle, obj, mode, event, obex_cmd, obex_rsp );#else    Q_UNUSED(mode);    Q_UNUSED(obex_rsp);#endif    switch (event) {    case OBEX_EV_REQDONE:#ifdef QTOPIA_DEBUG_OBEX	qDebug("OBEX_EV_REQDONE");#endif	sender->finished = TRUE;	if ( obex_cmd == OBEX_CMD_DISCONNECT ) {	    transmitDone = TRUE;	}	// else if OBEX_CMD_CONNECT, we could give feedback	break;    case OBEX_EV_LINKERR:#ifdef QTOPIA_DEBUG_OBEX	qDebug("OBEX_EV_LINKRER");#endif	// sometime we get a link error after we believed the connection was done.  Ignore this	// as emitting an error after done does not make sense	if ( !transmitDone ) {	    emit sender->error();	    sender->abort();	    sender->state = QObexSender::Error;	} else {	    sender->abort();#ifdef QTOPIA_DEBUG_OBEX	    qDebug("QIrServer:: got link error after done signal, no external signals sent");#endif	}		break;    case OBEX_EV_PROGRESS:#ifdef QTOPIA_DEBUG_OBEX	qDebug("OBEX_EV_PROGRESS");#endif	// report progress?	sender->updateProgress( obj );	break;	    case OBEX_EV_STREAMEMPTY:#ifdef QTOPIA_DEBUG_OBEX	qDebug("OBEX_EV_STREAMEMPTY");#endif	// when streaming: add more	sender->feedStream( obj );	break;	    default:#ifdef QTOPIA_DEBUG_OBEX	qDebug("qobex_sender_callback:: did not recongnize event signal %d", event);#endif	break;    }}QObexSender::QObexSender( QObject *parent, const char *name )  :QObexBase( parent, name ){  self = OBEX_Init( OBEX_TRANS_IRDA, qobex_sender_callback, OBEX_FL_KEEPSERVER );  finished = FALSE;  state = QObexSender::Init;  OBEX_SetUserData( self, this );}QObexSender::~QObexSender(){}void QObexSender::beam( const QString& filename, const QString& mimetype ){    file_to_send = filename;    mime_to_send = mimetype;    transmitDone = FALSE;    connectCount = 0;    tryConnecting();}void QObexSender::tryConnecting(){    connectCount++;    if ( aborted ) { deleteMeLater();	return;    }	    int retc = IrOBEX_TransportConnect(self, "OBEX");    if ( retc < 0 ) {	const int normalTry = 5;	const int maxTry = 20;	if ( connectCount > maxTry ) {	    abort();	    emit error();	    deleteMeLater();	} else {	    QString str;	    if ( connectCount <= normalTry )		str = tr("Searching...");	    else		str = tr("Beam failed (%1/%2). Retrying...","eg. 1/3").arg(connectCount).arg(maxTry);	    emit statusMsg( str );	    // Semi-random retry time to avoid re-collision	    QTimer::singleShot(200 + rand()%400, this, SLOT(tryConnecting()) );	}	return;    }#ifdef QTOPIA_DEBUG_OBEX    qDebug("QObexSender::tryConnecting() - Success");#endif    QString str = tr("Sending...");    emit statusMsg( str );    connectSocket();    obex_object_t *object;    // connecting    object = OBEX_ObjectNew(self, OBEX_CMD_CONNECT);    state = QObexSender::Connecting;    process( object );}//-----------------------------------------------------------------------/*  QObexServer /  functions*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -