-rw-r--r-- | core/obex/.cvsignore | 2 | ||||
-rw-r--r-- | core/obex/btobex.cpp | 60 | ||||
-rw-r--r-- | core/obex/btobex.h | 40 | ||||
-rw-r--r-- | core/obex/obex.cpp | 49 | ||||
-rw-r--r-- | core/obex/obex.h | 40 | ||||
-rw-r--r-- | core/obex/obex.pro | 16 | ||||
-rw-r--r-- | core/obex/obexbase.cpp | 74 | ||||
-rw-r--r-- | core/obex/obexbase.h | 99 | ||||
-rw-r--r-- | core/obex/obexhandler.cpp | 44 | ||||
-rw-r--r-- | core/obex/obexhandler.h | 9 | ||||
-rw-r--r-- | core/obex/obexsend.cpp | 2 | ||||
-rw-r--r-- | core/obex/obexserver.cpp | 514 | ||||
-rw-r--r-- | core/obex/obexserver.h | 83 | ||||
-rw-r--r-- | core/obex/receiver.cpp | 7 | ||||
-rw-r--r-- | core/obex/receiver.h | 12 |
15 files changed, 984 insertions, 67 deletions
diff --git a/core/obex/.cvsignore b/core/obex/.cvsignore index ed75078..90f9614 100644 --- a/core/obex/.cvsignore +++ b/core/obex/.cvsignore @@ -4 +4,3 @@ moc_* .obj +obexsendbase.h +obexsendbase.cpp diff --git a/core/obex/btobex.cpp b/core/obex/btobex.cpp index a5bfe5f..212a084 100644 --- a/core/obex/btobex.cpp +++ b/core/obex/btobex.cpp @@ -1 +1,31 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The Bluetooth OBEX manipulating class implementation + */ @@ -22,3 +52,3 @@ using namespace OpieTooth; BtObex::BtObex( QObject *parent, const char* name ) - : QObject(parent, name ) + : ObexBase(parent, name ) { @@ -26,8 +56,2 @@ BtObex::BtObex( QObject *parent, const char* name ) m_send=0; - m_count = 0; - m_receive = false; - connect( this, SIGNAL(error(int) ), // for recovering to receive - SLOT(slotError() ) ); - connect( this, SIGNAL(sent(bool) ), - SLOT(slotError() ) ); btManager = NULL; @@ -42,8 +66,7 @@ BtObex::~BtObex() { void BtObex::receive() { - m_receive = true; - m_outp = QString::null; - m_rec = new OProcess(); + ObexBase::receive(); + m_rec = new ObexServer(); + odebug << "BT OBEX do receive" << oendl; // TODO mbhaynie: No idea if this actually works -- maybe opd is better. - *m_rec << "obexftpd" << "-b"; // connect to the necessary slots @@ -63,6 +86,4 @@ void BtObex::receive() { void BtObex::send( const QString& fileName, const QString& bdaddr) { + ObexBase::send(fileName, bdaddr); // if currently receiving stop it send receive - m_count = 0; - m_file = fileName; - m_bdaddr = bdaddr; if (m_send != 0) { @@ -152,2 +173,6 @@ void BtObex::sendNow(){ + /* + * FIXME: this delay is made because some cell phones understands an error + * later. + */ ::sleep(4); @@ -173,2 +198,3 @@ void BtObex::slotExited(OProcess* proc ){ received(); + } @@ -179,2 +205,4 @@ void BtObex::slotStdOut(OProcess* proc, char* buf, int len){ m_outp.append( ar ); + QCString str(buf, len); + odebug << str << oendl; } @@ -209,2 +237,3 @@ void BtObex::received() { QString filename = parseOut(); + odebug << "OBEX " << filename << " received" << oendl; emit receivedFile( filename ); @@ -242,2 +271,3 @@ QString BtObex::parseOut(){ void BtObex::slotError() { + ObexBase::slotError(); if ( m_receive ) @@ -246,2 +276,4 @@ void BtObex::slotError() { void BtObex::setReceiveEnabled( bool receive ) { + odebug << "BT OBEX setReceiveEnabled " << receive << oendl; + ObexBase::setReceiveEnabled(receive); if ( !receive ) { // diff --git a/core/obex/btobex.h b/core/obex/btobex.h index 9c1ab70..7e91c06 100644 --- a/core/obex/btobex.h +++ b/core/obex/btobex.h @@ -1 +1,31 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The Bluetooth OBEX manipulating class declaration + */ @@ -5,2 +35,3 @@ +#include "obexbase.h" #include <qobject.h> @@ -9,2 +40,3 @@ #include <obexpush.h> +#include "obexserver.h" @@ -15,3 +47,3 @@ namespace OpieObex { // Maybe this should be derved from Obex. - class BtObex : public QObject { + class BtObex : public ObexBase { Q_OBJECT @@ -57,9 +89,4 @@ namespace OpieObex { private: - uint m_count; - QString m_file; - QString m_outp; - QString m_bdaddr; int m_port; ObexPush* m_send; - Opie::Core::OProcess *m_rec; bool m_receive : 1; @@ -67,2 +94,3 @@ namespace OpieObex { void shutDownReceive(); + ObexServer* m_rec; diff --git a/core/obex/obex.cpp b/core/obex/obex.cpp index 36634ec..95c561a 100644 --- a/core/obex/obex.cpp +++ b/core/obex/obex.cpp @@ -1 +1,31 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The Infrared OBEX handling class implementation + */ @@ -18,3 +48,3 @@ using namespace Opie::Core; Obex::Obex( QObject *parent, const char* name ) - : QObject(parent, name ) + : ObexBase(parent, name ) { @@ -22,8 +52,2 @@ Obex::Obex( QObject *parent, const char* name ) m_send=0; - m_count = 0; - m_receive = false; - connect( this, SIGNAL(error(int) ), // for recovering to receive - SLOT(slotError() ) ); - connect( this, SIGNAL(sent(bool) ), - SLOT(slotError() ) ); }; @@ -34,4 +58,3 @@ Obex::~Obex() { void Obex::receive() { - m_receive = true; - m_outp = QString::null; + ObexBase::receive(); m_rec = new OProcess(); @@ -52,5 +75,5 @@ void Obex::receive() { -void Obex::send( const QString& fileName) { // if currently receiving stop it send receive - m_count = 0; - m_file = fileName; +// if currently receiving stop it send receive +void Obex::send(const QString& fileName, const QString& addr) { + ObexBase::send(fileName, addr); if (m_rec != 0 ) { @@ -167,2 +190,3 @@ QString Obex::parseOut( ){ void Obex::slotError() { + ObexBase::slotError(); if ( m_receive ) @@ -171,2 +195,3 @@ void Obex::slotError() { void Obex::setReceiveEnabled( bool receive ) { + ObexBase::setReceiveEnabled(receive); if ( !receive ) { // diff --git a/core/obex/obex.h b/core/obex/obex.h index 5993976..36ff29a 100644 --- a/core/obex/obex.h +++ b/core/obex/obex.h @@ -1,2 +1,31 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* + * The Infrared OBEX handling class declaration + */ @@ -5,2 +34,3 @@ +#include "obexbase.h" #include <qobject.h> @@ -10,3 +40,3 @@ class QCopChannel; namespace OpieObex { - class Obex : public QObject { + class Obex : public ObexBase { Q_OBJECT @@ -26,5 +56,5 @@ namespace OpieObex { */ - void receive(); - void send( const QString& ); - void setReceiveEnabled( bool = false ); + virtual void receive(); + virtual void send(const QString& filename, const QString& addr); + virtual void setReceiveEnabled( bool = false ); signals: @@ -71,3 +101,3 @@ private slots: void slotStdOut(Opie::Core::OProcess*, char*, int); - void slotError(); + virtual void slotError(); diff --git a/core/obex/obex.pro b/core/obex/obex.pro index 33cb957..1fc6958 100644 --- a/core/obex/obex.pro +++ b/core/obex/obex.pro @@ -2,4 +2,4 @@ TEMPLATE = lib CONFIG += qt warn_on -HEADERS = obex.h btobex.h obexhandler.h obexsend.h receiver.h obeximpl.h -SOURCES = obex.cpp btobex.cpp obexsend.cpp obexhandler.cpp receiver.cpp obeximpl.cpp +HEADERS = obex.h btobex.h obexhandler.h obexsend.h receiver.h obeximpl.h obexbase.h obexserver.h +SOURCES = obex.cpp btobex.cpp obexsend.cpp obexhandler.cpp receiver.cpp obeximpl.cpp obexbase.cpp obexserver.cpp TARGET = opieobex @@ -7,6 +7,6 @@ DESTDIR = $(OPIEDIR)/plugins/obex INTERFACES = obexsendbase.ui -INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher $(OPIEDIR)/noncore/net/opietooth/lib +INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher DEPENDPATH += -LIBS += -lopietooth1 -lqpe -lopiecore2 -VERSION = 0.0.3 +LIBS += -lqpe -lopiecore2 +VERSION = 0.0.4 @@ -14 +14,7 @@ include( $(OPIEDIR)/include.pro ) target.path = $$prefix/plugins/applets + +#FIXME: These parameters are used if bluetooth is used +INCLUDEPATH += $(OPIEDIR)/noncore/net/opietooth/lib +LIBS += -lopietooth1 -lbluetooth -lopenobex +DEFINES += BLUETOOTH + diff --git a/core/obex/obexbase.cpp b/core/obex/obexbase.cpp new file mode 100644 index 0000000..8eda04e --- a/dev/null +++ b/core/obex/obexbase.cpp @@ -0,0 +1,74 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The basic class for OBEX manipulating classes implementation + */ + +#include "obexbase.h" + +/* OPIE */ +#include <opie2/oprocess.h> +#include <opie2/odebug.h> + +using namespace OpieObex; + +using namespace Opie::Core; + +ObexBase::ObexBase(QObject *parent, const char* name) + : QObject(parent, name) +{ + m_count = 0; + m_receive = false; + connect( this, SIGNAL(error(int) ), // for recovering to receive + SLOT(slotError() ) ); + connect( this, SIGNAL(sent(bool) ), + SLOT(slotError() ) ); +} + +ObexBase::~ObexBase() { +} + +void ObexBase::receive() { + m_receive = true; + m_outp = QString::null; +} + +void ObexBase::send( const QString& fileName, const QString& bdaddr) { + // if currently receiving stop it send receive + m_count = 0; + m_file = fileName; + m_bdaddr = bdaddr; +} + +void ObexBase::setReceiveEnabled(bool) { +} + +void ObexBase::slotError() { +} + +//eof diff --git a/core/obex/obexbase.h b/core/obex/obexbase.h new file mode 100644 index 0000000..f65d922 --- a/dev/null +++ b/core/obex/obexbase.h @@ -0,0 +1,99 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The basic class for OBEX manipulating classes declaration + */ +#ifndef ObexBase_H +#define ObexBase_H + +#include <qobject.h> + +namespace Opie {namespace Core {class OProcess;}} +class QCopChannel; +namespace OpieObex { + class ObexBase : public QObject { + Q_OBJECT + public: + /** + * ObexBase constructor look + */ + ObexBase(QObject *parent, const char* name); + /** + * d'tor + */ + virtual ~ObexBase(); + /** + * Starting listening to an interface after enabled by the applet + * a signal gets emitted when received a file + */ + virtual void receive(); + /** + * Send the file + * @param the name of the file + * @param the address of the device + */ + virtual void send(const QString&, const QString&); + /** + * Stop receiving + * @param if true - does nothing if false - stops receiving + */ + virtual void setReceiveEnabled(bool = false); + signals: + /** + * Notify the upper level that we have received the file + * @param path The path to the received file + */ + void receivedFile(const QString& path); + /** + * error signal if the program couldn't be started or the + * the connection timed out + */ + void error(int); + /** + * The current try to receive data + */ + void currentTry(unsigned int); + /** + * signal sent The file got beamed to the remote location + */ + void sent(bool); + void done(bool); + protected: + uint m_count; + QString m_file; + QString m_outp; + QString m_bdaddr; + bool m_receive : 1; + protected slots: + virtual void slotError(); + }; +}; + +#endif +//eof + diff --git a/core/obex/obexhandler.cpp b/core/obex/obexhandler.cpp index 28f9b5b..5d98ded 100644 --- a/core/obex/obexhandler.cpp +++ b/core/obex/obexhandler.cpp @@ -13,5 +13,8 @@ using namespace OpieObex; ObexHandler::ObexHandler() { - m_wasRec = false; + m_wasRec[REC_IRDA] = false; + m_receiver[REC_IRDA] = 0l; + m_wasRec[REC_BLUETOOTH] = false; + m_receiver[REC_BLUETOOTH] = 0l; m_sender = 0l; - m_receiver = 0l; + m_type = REC_IRDA; //FIXME: Just to init to something QCopChannel* chan = new QCopChannel("QPE/Obex"); @@ -22,3 +25,4 @@ ObexHandler::~ObexHandler() { delete m_sender; - delete m_receiver; + delete m_receiver[REC_IRDA]; + delete m_receiver[REC_BLUETOOTH]; } @@ -33,10 +37,10 @@ void ObexHandler::doSend(const QString& str, const QString& desc) { } -void ObexHandler::doReceive(bool b) { - if (m_receiver && b ) return; // we should enable receiver and it is on - else if (!m_receiver && !b ) return; // we should disbale receiver and it is off - else if (m_receiver && !b ) { - delete m_receiver; - m_receiver=0; - }else if (!m_receiver && b ) { - m_receiver= new Receiver; +void ObexHandler::doReceive(RecType type, bool b) { + if (m_receiver[type] && b ) return; // we should enable receiver and it is on + else if (!m_receiver[type] && !b ) return; // we should disbale receiver and it is off + else if (m_receiver[type] && !b ) { + delete m_receiver[type]; + m_receiver[type] = 0; + }else if (!m_receiver[type] && b ) { + m_receiver[type] = new Receiver(type); } @@ -49,4 +53,6 @@ void ObexHandler::slotSent() { e << file; - doReceive(m_wasRec ); - m_wasRec = false; + doReceive(REC_IRDA, m_wasRec[REC_IRDA]); + doReceive(REC_BLUETOOTH, m_wasRec[REC_BLUETOOTH]); + m_wasRec[REC_IRDA] = false; + m_wasRec[REC_BLUETOOTH] = false; } @@ -58,4 +64,6 @@ void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) { stream >> name; - m_wasRec = (m_receiver != 0 ); - doReceive( false ); + m_wasRec[REC_IRDA] = (m_receiver[REC_IRDA] != 0 ); + m_wasRec[REC_BLUETOOTH] = (m_receiver[REC_BLUETOOTH] != 0 ); + doReceive(REC_IRDA, false); + doReceive(REC_BLUETOOTH, false); doSend(name, desc); @@ -64,3 +72,7 @@ void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) { stream >> rec; - doReceive(rec); + doReceive(REC_IRDA, rec); + }else if (msg == "btreceive(int)") { + int rec; + stream >> rec; + doReceive(REC_BLUETOOTH, rec); } diff --git a/core/obex/obexhandler.h b/core/obex/obexhandler.h index 230c4f0..de2232e 100644 --- a/core/obex/obexhandler.h +++ b/core/obex/obexhandler.h @@ -5,2 +5,3 @@ #include <qstring.h> +#include "receiver.h" @@ -23,3 +24,3 @@ namespace OpieObex { void doSend(const QString&,const QString& ); - void doReceive(bool b); + void doReceive(RecType type, bool b); void slotSent(); @@ -31,5 +32,5 @@ namespace OpieObex { SendWidget* m_sender; - Receiver* m_receiver; - bool m_wasRec : 1; - + Receiver* m_receiver[2]; //For IRDA and Bluetooth + bool m_wasRec[2]; + RecType m_type; //receiver type (IRDA or Bluetooth) }; diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp index 8432d16..9a30a0a 100644 --- a/core/obex/obexsend.cpp +++ b/core/obex/obexsend.cpp @@ -150,3 +150,3 @@ void SendWidget::slotStartIrda() { setReceiverStatus( m_irDaIt.key(), tr("Start sending") ); - m_obex->send( m_file ); + m_obex->send( m_file, tr("noaddress") ); } diff --git a/core/obex/obexserver.cpp b/core/obex/obexserver.cpp new file mode 100644 index 0000000..95196de --- a/dev/null +++ b/core/obex/obexserver.cpp @@ -0,0 +1,514 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The OBEX server class implementation + * Based on OBEX server from GPE (thanks, guys) + */ + +#include "obexserver.h" +#include <unistd.h> +#include <opie2/odebug.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <qapplication.h> +#include <opie2/oprocctrl.h> +#include <qstring.h> +#include <qfile.h> + +using namespace Opie::Core; +using namespace Opie::Core::Internal; +using namespace OpieObex; + +ObexServer::ObexServer() : + OProcess(tr("ObexServer"), 0, "ObexServer") +{ + m_obex = NULL; +} + +ObexServer::~ObexServer() +{ + stop(); +} + +/** + * Function handles the file received + * @param name the file name + * @param data the file data + * @param data_len the data length + * @return 0 on success -1 on error + */ +static int file_received(uint8_t* name, const uint8_t* data, size_t data_len) +{ + QString path("/tmp/"); + path += (char*)name; + QFile out(path); + int err = 0; + + if (!out.open(IO_Raw | IO_ReadWrite | IO_Truncate)) { + printf("File %s open error %d\n", (const char*)path, errno); + err = -1; + goto out; + } + if (out.writeBlock((const char*)data, data_len) < 0) { + printf("File %s write error %d\n", (const char*)path, errno); + err = -1; + goto out; + } +out: + out.close(); + if (err == 0) { + printf("Wrote %s (%d bytes)\n", (const char*)path, data_len); + fflush(stdout); + } + return err; +} + +/** + * Function handles the situation when the PUT request has been done + * @param handle OBEX connection handle + * @param object OBEX object itself + */ +static int put_done(obex_t* handle, obex_object_t* object) +{ + obex_headerdata_t hv; //Received file header + uint8_t hi; //Type of the request + uint32_t hlen; //File (file name) length + int err = 0; + + const uint8_t *body = NULL; + int body_len = 0; + uint8_t* name = NULL; + + while (OBEX_ObjectGetNextHeader (handle, object, &hi, &hv, &hlen)) { + switch(hi) { + case OBEX_HDR_BODY: + body = hv.bs; + body_len = hlen; + break; + + case OBEX_HDR_NAME: + name = new uint8_t[(hlen / 2) + 1]; + OBEX_UnicodeToChar(name, hv.bs, hlen); + break; + + default: + break; + } + } + + if (body) + err = file_received(name, body, body_len); + + if (name) + delete[] name; + return err; +} + +/** + * Function handles OBEX request + * @param handle OBEX connection handle + * @param object OBEX object itself + * @param mode + * @param event event code + * @param cmd OBEX command itself + */ +static void handle_request (obex_t* handle, obex_object_t* object, + int event, int cmd) +{ + (void)event; + switch(cmd) { + case OBEX_CMD_SETPATH: + OBEX_ObjectSetRsp (object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + break; + case OBEX_CMD_PUT: + if (put_done (handle, object) < 0) + OBEX_ObjectSetRsp (object, OBEX_RSP_INTERNAL_SERVER_ERROR, + OBEX_RSP_INTERNAL_SERVER_ERROR); + else + OBEX_ObjectSetRsp (object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + break; + case OBEX_CMD_CONNECT: + OBEX_ObjectSetRsp (object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); + break; + case OBEX_CMD_DISCONNECT: + OBEX_ObjectSetRsp (object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); + break; + default: + printf("Denied %02x request\n", cmd); + fflush(stdout); + OBEX_ObjectSetRsp (object, OBEX_RSP_NOT_IMPLEMENTED, + OBEX_RSP_NOT_IMPLEMENTED); + break; + } +} + + +/** + * Function handles OBEX event when a client is connected to the server + * @param handle OBEX connection handle + * @param object OBEX object itself + * @param mode + * @param event event code + * @param obex_cmd OBEX command itself + * @param obex_rsp OBEX responce + */ +static void obex_conn_event (obex_t *handle, obex_object_t *object, + int mode, int event, int obex_cmd, int obex_rsp) +{ + (void)mode; + (void)obex_rsp; + + switch(event) { + case OBEX_EV_REQHINT: + switch(obex_cmd) { + case OBEX_CMD_PUT: + case OBEX_CMD_CONNECT: + case OBEX_CMD_DISCONNECT: + OBEX_ObjectSetRsp (object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + break; + default: + OBEX_ObjectSetRsp (object, OBEX_RSP_NOT_IMPLEMENTED, + OBEX_RSP_NOT_IMPLEMENTED); + break; + } + break; + + case OBEX_EV_REQ: + /* Comes when a server-request has been received. */ + handle_request (handle, object, event, obex_cmd); + break; + + case OBEX_EV_LINKERR: + break; + } +} + +/** + * Function handles OBEX event + * @param handle OBEX connection handle + * @param object OBEX object itself + * @param mode + * @param event event code + * @param obex_cmd OBEX command itself + * @param obex_rsp OBEX responce + */ +static void obex_event (obex_t* handle, obex_object_t* object, int mode, + int event, int obex_cmd, int obex_rsp) +{ + + obex_t *obex; //OBEX connection handle + + switch (event) { + case OBEX_EV_ACCEPTHINT: + obex = OBEX_ServerAccept (handle, obex_conn_event, NULL); + break; + + default: + obex_conn_event(handle, object, mode, event, obex_cmd, obex_rsp); + } +} + +/** + * Function registers OBEX push service on a specified channel + * Based on The same function from GPE. + * @param session SDP session + * @param chan channel to listen + * @name name to show + */ +sdp_session_t* ObexServer::addOpushSvc(uint8_t chan, const char* name) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + sdp_data_t *channel; + uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + //uint8_t formats[] = { 0xff }; + void *dtds[sizeof(formats)], *values[sizeof(formats)]; + unsigned int i; + uint8_t dtd = SDP_UINT8; + sdp_data_t *sflist; + int err = 0; + sdp_session_t* lsession = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID); + svclass_id = sdp_list_append(0, &opush_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &chan); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + for (i = 0; i < sizeof(formats); i++) + { + dtds[i] = &dtd; + values[i] = &formats[i]; + } + sflist = sdp_seq_alloc(dtds, values, sizeof(formats)); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist); + + sdp_set_info_attr(&record, name, 0, 0); + + // connect to the local SDP server, register the service record, and + // disconnect + lsession = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + if (lsession == NULL) + goto errout; + err = sdp_record_register(lsession, &record, 0); + if (err) { + sdp_close(lsession); + lsession = NULL; + } +errout: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + + return lsession; +} + +int ObexServer::initObex(void) +{ + int channel = 10; //Channel on which we do listen + if (m_obex) + return 0; + m_obex = ::OBEX_Init(OBEX_TRANS_BLUETOOTH, obex_event, 0); + if (!m_obex) { + printf("OBEX initialization error %d\n", errno); + return -1; + } + ::BtOBEX_ServerRegister(m_obex, NULL, channel); + m_session = addOpushSvc(channel, "OBEX push service"); + if (!m_session) { + printf("OBEX registration error %d\n", errno); + ::OBEX_Cleanup(m_obex); + m_obex = NULL; + return -1; + } + return 0; +} + +bool ObexServer::start(RunMode runmode, Communication comm) +{ + if ( runs ) + { + return false; // cannot start a process that is already running + // or if no executable has been assigned + } + run_mode = runmode; + status = 0; + + if ( !setupCommunication( comm ) ) + qWarning( "Could not setup Communication!" ); + + // We do this in the parent because if we do it in the child process + // gdb gets confused when the application runs from gdb. + uid_t uid = getuid(); + gid_t gid = getgid(); +#ifdef HAVE_INITGROUPS + + struct passwd *pw = getpwuid( uid ); +#endif + + int fd[ 2 ]; + if ( 0 > pipe( fd ) ) + { + fd[ 0 ] = fd[ 1 ] = 0; // Pipe failed.. continue + } + + runs = true; + + QApplication::flushX(); + + // WABA: Note that we use fork() and not vfork() because + // vfork() has unclear semantics and is not standardized. + pid_ = fork(); + + if ( 0 == pid_ ) + { + if ( fd[ 0 ] ) + close( fd[ 0 ] ); + if ( !runPrivileged() ) + { + setgid( gid ); +#if defined( HAVE_INITGROUPS) + + if ( pw ) + initgroups( pw->pw_name, pw->pw_gid ); +#endif + + setuid( uid ); + } + // The child process + if ( !commSetupDoneC() ) + qWarning( "Could not finish comm setup in child!" ); + + setupEnvironment(); + + // Matthias + if ( run_mode == DontCare ) + setpgid( 0, 0 ); + // restore default SIGPIPE handler (Harri) + struct sigaction act; + sigemptyset( &( act.sa_mask ) ); + sigaddset( &( act.sa_mask ), SIGPIPE ); + act.sa_handler = SIG_DFL; + act.sa_flags = 0; + sigaction( SIGPIPE, &act, 0L ); + + // We set the close on exec flag. + // Closing of fd[1] indicates that the execvp succeeded! + if ( fd[ 1 ] ) + fcntl( fd[ 1 ], F_SETFD, FD_CLOEXEC ); + + if (initObex() == 0) { + do { + int result; //Connection result + if ( fd[ 1 ] ) { + ::close(fd[1]); + fd[1] = 0; + } + if ((result = OBEX_HandleInput(m_obex, 60)) < 0) { + if (errno != ECONNRESET) { + printf("OBEX_HandleInput error %d\n", errno); + fflush(stdout); + _exit(-1); + } + else + _exit(0); + } + } while(1); + } + char resultByte = 1; + if ( fd[ 1 ] ) + write( fd[ 1 ], &resultByte, 1 ); + _exit( -1 ); + } + else if ( -1 == pid_ ) + { + // forking failed + + runs = false; + return false; + } + else + { + if ( fd[ 1 ] ) + close( fd[ 1 ] ); + // the parent continues here + + // Discard any data for stdin that might still be there + input_data = 0; + + // Check whether client could be started. + if ( fd[ 0 ] ) + for ( ;; ) + { + char resultByte; + int n = ::read( fd[ 0 ], &resultByte, 1 ); + if ( n == 1 ) + { + // Error + runs = false; + close( fd[ 0 ] ); + pid_ = 0; + return false; + } + if ( n == -1 ) + { + if ( ( errno == ECHILD ) || ( errno == EINTR ) ) + continue; // Ignore + } + break; // success + } + if ( fd[ 0 ] ) + close( fd[ 0 ] ); + + if ( !commSetupDoneP() ) // finish communication socket setup for the parent + qWarning( "Could not finish comm setup in parent!" ); + + if ( run_mode == Block ) + { + commClose(); + + // The SIGCHLD handler of the process controller will catch + // the exit and set the status + while ( runs ) + { + OProcessController::theOProcessController-> + slotDoHousekeeping( 0 ); + } + runs = FALSE; + emit processExited( this ); + } + } + return true; +} + +/* + * Stop forwarding process + */ +int ObexServer::stop() +{ + kill(SIGTERM); + return 0; +} + +//eof diff --git a/core/obex/obexserver.h b/core/obex/obexserver.h new file mode 100644 index 0000000..8567105 --- a/dev/null +++ b/core/obex/obexserver.h @@ -0,0 +1,83 @@ +/* + =. This file is part of the OPIE Project + .=l. Copyright (c) 2002 Maximilian Reiss <max.reiss@gmx.de> + .>+-= + _;:, .> :=|. This library is free software; you can +.> <, > . <= redistribute it and/or modify it under +:=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; version 2 of the License. + ._= =} : + .%+i> _;_. + .i_,=:_. -<s. This library 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 +..}^=.= = ; Library General Public License for more +++= -. . .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-= this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +/* + * The OBEX server class declaration + * Based on OBEX server from GPE (thanks, guys) + */ +#ifndef ObexServer_H +#define ObexServer_H + +#include <qobject.h> +#include <opie2/oprocess.h> + +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> + +#include <openobex/obex.h> + +namespace Opie { + namespace Core { + class OProcess; + namespace Internal { + class OProcessController; + } + } +}; + +namespace Opie {namespace Core {class OProcess;}} +namespace OpieObex { + class ObexServer : public Opie::Core::OProcess { + Q_OBJECT + public: + /** + * ObexServer constructor + */ + ObexServer(); + /** + * + */ + ~ObexServer(); + //Function starts the server process + virtual bool start( RunMode runmode = NotifyOnExit, + Communication comm = NoCommunication ); + //Stop the server process + int stop(); + protected: //variables + obex_t* m_obex; //Obex server handler + sdp_session_t* m_session; //SDP session handler; + protected: //functions + //Funtion initializes obex server return 0 on success and -1 on error + int initObex(void); + //Function registers an OBEX push service + sdp_session_t* addOpushSvc(uint8_t chan, const char* name); + signals: + protected slots: + }; +}; + +#endif diff --git a/core/obex/receiver.cpp b/core/obex/receiver.cpp index 7d9a42a..e153152 100644 --- a/core/obex/receiver.cpp +++ b/core/obex/receiver.cpp @@ -1,2 +1,4 @@ #include "obex.h" +#include "btobex.h" +#include "obexbase.h" #include "receiver.h" @@ -28,4 +30,7 @@ using namespace Opie::Core; -Receiver::Receiver() { +Receiver::Receiver(RecType type) { + if (type == REC_IRDA) m_obex = new Obex(this, "Receiver"); + else + m_obex = new BtObex(this, "Receiver"); connect(m_obex, SIGNAL(receivedFile(const QString&) ), diff --git a/core/obex/receiver.h b/core/obex/receiver.h index e1d54df..a10ea13 100644 --- a/core/obex/receiver.h +++ b/core/obex/receiver.h @@ -7,2 +7,8 @@ +//Receiver type +typedef enum _RecType { + REC_IRDA = 0, + REC_BLUETOOTH = 1 +} RecType; + class QLabel; @@ -10,3 +16,3 @@ class QTextView; namespace OpieObex { - class Obex; + class ObexBase; class OtherHandler; @@ -16,3 +22,3 @@ namespace OpieObex { enum { Datebook , AddressBook, Other }; - Receiver(); + Receiver(RecType type); ~Receiver(); @@ -34,3 +40,3 @@ namespace OpieObex { private: - Obex* m_obex; + ObexBase* m_obex; //IR obex }; |