summaryrefslogtreecommitdiff
authorkorovkin <korovkin>2006-07-06 16:28:08 (UTC)
committer korovkin <korovkin>2006-07-06 16:28:08 (UTC)
commit43cd66c08de4447998028179d20fd4817aaf16ca (patch) (side-by-side diff)
tree87888aadc3398c3c633e332cda46d92bb0522d6a
parentadcfc6f4afe184a9eb6fbf458616494dfe0dadda (diff)
downloadopie-43cd66c08de4447998028179d20fd4817aaf16ca.zip
opie-43cd66c08de4447998028179d20fd4817aaf16ca.tar.gz
opie-43cd66c08de4447998028179d20fd4817aaf16ca.tar.bz2
Added OBEX Push functionality for Bluetooth.
- Added ObexBase - asic class for IR and BT Obex - Added ObexServer - OBEX Push server.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/obex/.cvsignore2
-rw-r--r--core/obex/btobex.cpp60
-rw-r--r--core/obex/btobex.h40
-rw-r--r--core/obex/obex.cpp49
-rw-r--r--core/obex/obex.h40
-rw-r--r--core/obex/obex.pro16
-rw-r--r--core/obex/obexbase.cpp74
-rw-r--r--core/obex/obexbase.h99
-rw-r--r--core/obex/obexhandler.cpp44
-rw-r--r--core/obex/obexhandler.h9
-rw-r--r--core/obex/obexsend.cpp2
-rw-r--r--core/obex/obexserver.cpp514
-rw-r--r--core/obex/obexserver.h83
-rw-r--r--core/obex/receiver.cpp9
-rw-r--r--core/obex/receiver.h12
15 files changed, 985 insertions, 68 deletions
diff --git a/core/obex/.cvsignore b/core/obex/.cvsignore
index ed75078..90f9614 100644
--- a/core/obex/.cvsignore
+++ b/core/obex/.cvsignore
@@ -1,4 +1,6 @@
Makefile
moc_*
.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,262 +1,294 @@
+/*
+               =. 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
+ */
#include "btobex.h"
#include <manager.h>
#include <services.h>
/* OPIE */
#include <opie2/oprocess.h>
#include <opie2/odebug.h>
/* QT */
#include <qfileinfo.h>
#include <qstring.h>
#include <qmap.h>
#include <qmessagebox.h>
using namespace OpieObex;
using namespace Opie::Core;
/* TRANSLATOR OpieObex::Obex */
using namespace OpieTooth;
BtObex::BtObex( QObject *parent, const char* name )
- : QObject(parent, name )
+ : ObexBase(parent, name )
{
m_rec = 0;
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;
};
BtObex::~BtObex() {
delete btManager;
delete m_rec;
delete m_send;
}
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
connect(m_rec, SIGNAL(processExited(Opie::Core::OProcess*) ),
this, SLOT(slotExited(Opie::Core::OProcess*) ) );
connect(m_rec, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ),
this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) );
if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) {
emit done( false );
delete m_rec;
m_rec = 0;
}
}
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) {
if (m_send->isSending())
return;
else {
delete m_send;
m_send = 0;
}
}
if (m_rec != 0 ) {
if (m_rec->isRunning() ) {
emit error(-1 );
delete m_rec;
m_rec = 0;
}else{
emit error( -1 ); // we did not delete yet but it's not running slotExited is pending
return;
}
}
//Now we need to find out if the OBEX push is supported for this device
//And get the port number
if (!btManager) {
btManager = new Manager("hci0");
connect(btManager,
SIGNAL(foundServices(const QString&, Services::ValueList)),
this, SLOT(slotFoundServices(const QString&, Services::ValueList)));
}
btManager->searchServices(bdaddr);
}
/**
* This function reacts on the service discovery finish
*/
void BtObex::slotFoundServices(const QString&, Services::ValueList svcList)
{
QValueList<OpieTooth::Services>::Iterator it;
QMap<int, QString> classList; //The classes list
QMap<int, QString>::Iterator classIt; //Iterator in the class list
int portNum = -1; //The desired port number
odebug << "BtObex slotFoundServices" << oendl;
if (svcList.isEmpty()) {
QMessageBox::critical(NULL, tr("Object send"), tr("No services found"));
emit error(-1);
return;
}
for (it = svcList.begin(); it != svcList.end(); it++) {
classList = (*it).classIdList();
classIt = classList.begin();
if (classIt == classList.end())
continue;
////We really need symbolic names for service IDs
//Ok, we have found the object push service
if (classIt.key() == 4357) {
portNum = (*it).protocolDescriptorList().last().port();
break;
}
}
if (portNum == -1) {
QMessageBox::critical(NULL, tr("Object send"),
tr("No OBEX Push service"));
emit error(-1);
return;
}
m_port = portNum;
sendNow();
}
void BtObex::sendNow(){
QString m_dst = "";
int result; //function call result
if ( m_count >= 25 ) { // could not send
emit error(-1 );
emit sent(false);
return;
}
// OProcess inititialisation
m_send = new ObexPush();
// connect to slots Exited and and StdOut
connect(m_send, SIGNAL(sendComplete(int)),
this, SLOT(slotPushComplete(int)) );
connect(m_send, SIGNAL(sendError(int)),
this, SLOT(slotPushError(int)) );
connect(m_send, SIGNAL(status(QCString&)),
this, SLOT(slotPushStatus(QCString&) ) );
+ /*
+ * FIXME: this delay is made because some cell phones understands an error
+ * later.
+ */
::sleep(4);
// now start it
result = m_send->send(m_bdaddr, m_port, m_file, m_dst);
if (result > 0) //Sending process is actually running
return;
else if (result < 0) {
m_count = 25;
emit error(-1 );
delete m_send;
m_send=0;
}
// end
m_count++;
emit currentTry( m_count );
}
void BtObex::slotExited(OProcess* proc ){
odebug << proc->name() << " exited with result "
<< proc->exitStatus() << oendl;
if (proc == m_rec ) // receive process
received();
+
}
void BtObex::slotStdOut(OProcess* proc, char* buf, int len){
if ( proc == m_rec ) { // only receive
QByteArray ar( len );
memcpy( ar.data(), buf, len );
m_outp.append( ar );
+ QCString str(buf, len);
+ odebug << str << oendl;
}
}
void BtObex::slotPushComplete(int result) {
if (result == 0) {
delete m_send;
m_send=0;
emit sent(true);
} else { // it failed maybe the other side wasn't ready
// let's try it again
delete m_send;
m_send = 0;
sendNow();
}
}
void BtObex::slotPushError(int) {
emit error( -1 );
delete m_send;
m_send = 0;
}
void BtObex::slotPushStatus(QCString& str) {
odebug << str << oendl;
}
void BtObex::received() {
if (m_rec->normalExit() ) {
if ( m_rec->exitStatus() == 0 ) { // we got one
QString filename = parseOut();
+ odebug << "OBEX " << filename << " received" << oendl;
emit receivedFile( filename );
}
}else{
emit done(false);
};
delete m_rec;
m_rec = 0;
receive();
}
// This probably doesn't do anything useful for bt.
QString BtObex::parseOut(){
QString path;
QStringList list = QStringList::split("\n", m_outp);
QStringList::Iterator it;
for (it = list.begin(); it != list.end(); ++it ) {
odebug << (*it) << oendl;
if ( (*it).startsWith("Wrote" ) ) {
int pos = (*it).findRev('(' );
if ( pos > 0 ) {
path = (*it).remove( pos, (*it).length() - pos );
path = path.mid(6 );
path = path.stripWhiteSpace();
}
}
}
return path;
}
/**
* when sent is done slotError is called we will start receive again
*/
void BtObex::slotError() {
+ ObexBase::slotError();
if ( m_receive )
receive();
};
void BtObex::setReceiveEnabled( bool receive ) {
+ odebug << "BT OBEX setReceiveEnabled " << receive << oendl;
+ ObexBase::setReceiveEnabled(receive);
if ( !receive ) { //
m_receive = false;
shutDownReceive();
}
}
void BtObex::shutDownReceive() {
if (m_rec != 0 ) {
if (m_rec->isRunning() ) {
emit error(-1 );
delete m_rec;
m_rec = 0;
}
}
}
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,90 +1,118 @@
+/*
+               =. 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
+ */
#ifndef OpieBtObex_H
#define OpieBtObex_H
+#include "obexbase.h"
#include <qobject.h>
#include <services.h>
#include <manager.h>
#include <obexpush.h>
+#include "obexserver.h"
namespace Opie {namespace Core {class OProcess;}}
class QCopChannel;
using namespace OpieTooth;
namespace OpieObex {
// Maybe this should be derved from Obex.
- class BtObex : public QObject {
+ class BtObex : public ObexBase {
Q_OBJECT
public:
/**
* BtObex c'tor look
*/
BtObex( QObject *parent, const char* name);
/**
* d'tor
*/
~BtObex();
/** TODO mbhaynie -- Maybe opd would be a better way to receive.
* Starting listening to Bluetooth after enabled by the applet
* a signal gets emitted when received a file
*/
void receive();
void send( const QString&, const QString& );
void setReceiveEnabled( bool = false );
signals:
/**
* a signal
* @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);
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;
OpieTooth::Manager* btManager;
void shutDownReceive();
+ ObexServer* m_rec;
private slots:
// Push process slots
void slotPushStatus(QCString&);
void slotPushComplete(int);
void slotPushError(int);
// the process exited
void slotExited(Opie::Core::OProcess*) ;
void slotStdOut(Opie::Core::OProcess*, char*, int);
void slotError();
void slotFoundServices(const QString&, Services::ValueList);
private:
void sendNow();
QString parseOut();
void received();
};
};
#endif
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,187 +1,212 @@
+/*
+               =. 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
+ */
#include "obex.h"
/* OPIE */
#include <opie2/oprocess.h>
#include <opie2/odebug.h>
/* QT */
#include <qfileinfo.h>
using namespace OpieObex;
using namespace Opie::Core;
/* TRANSLATOR OpieObex::Obex */
Obex::Obex( QObject *parent, const char* name )
- : QObject(parent, name )
+ : ObexBase(parent, name )
{
m_rec = 0;
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() ) );
};
Obex::~Obex() {
delete m_rec;
delete m_send;
}
void Obex::receive() {
- m_receive = true;
- m_outp = QString::null;
+ ObexBase::receive();
m_rec = new OProcess();
*m_rec << "irobex_palm3";
// connect to the necessary slots
connect(m_rec, SIGNAL(processExited(Opie::Core::OProcess*) ),
this, SLOT(slotExited(Opie::Core::OProcess*) ) );
connect(m_rec, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ),
this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) );
if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) {
emit done( false );
delete m_rec;
m_rec = 0;
}
}
-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 ) {
if (m_rec->isRunning() ) {
emit error(-1 );
delete m_rec;
m_rec = 0;
}else{
emit error( -1 ); // we did not delete yet but it's not running slotExited is pending
return;
}
}
sendNow();
}
void Obex::sendNow(){
if ( m_count >= 25 ) { // could not send
emit error(-1 );
emit sent(false);
return;
}
// OProcess inititialisation
m_send = new OProcess();
m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) );
*m_send << "irobex_palm3";
*m_send << QFile::encodeName(QFileInfo(m_file).fileName());
// connect to slots Exited and and StdOut
connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ),
this, SLOT(slotExited(Opie::Core::OProcess*)) );
connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int )),
this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) );
// now start it
if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) {
m_count = 25;
emit error(-1 );
delete m_send;
m_send=0;
}
// end
m_count++;
emit currentTry( m_count );
}
void Obex::slotExited(OProcess* proc ){
if (proc == m_rec ) // receive process
received();
else if ( proc == m_send )
sendEnd();
}
void Obex::slotStdOut(OProcess* proc, char* buf, int len){
if ( proc == m_rec ) { // only receive
QByteArray ar( len );
memcpy( ar.data(), buf, len );
m_outp.append( ar );
}
}
void Obex::received() {
if (m_rec->normalExit() ) {
if ( m_rec->exitStatus() == 0 ) { // we got one
QString filename = parseOut();
emit receivedFile( filename );
}
}else{
emit done(false);
};
delete m_rec;
m_rec = 0;
receive();
}
void Obex::sendEnd() {
if (m_send->normalExit() ) {
if ( m_send->exitStatus() == 0 ) {
delete m_send;
m_send=0;
emit sent(true);
}else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready
// let's try it again
delete m_send;
m_send = 0;
sendNow();
}
}else {
emit error( -1 );
delete m_send;
m_send = 0;
}
}
QString Obex::parseOut( ){
QString path;
QStringList list = QStringList::split("\n", m_outp);
QStringList::Iterator it;
for (it = list.begin(); it != list.end(); ++it ) {
if ( (*it).startsWith("Wrote" ) ) {
int pos = (*it).findRev('(' );
if ( pos > 0 ) {
path = (*it).remove( pos, (*it).length() - pos );
path = path.mid(6 );
path = path.stripWhiteSpace();
}
}
}
return path;
}
/**
* when sent is done slotError is called we will start receive again
*/
void Obex::slotError() {
+ ObexBase::slotError();
if ( m_receive )
receive();
};
void Obex::setReceiveEnabled( bool receive ) {
+ ObexBase::setReceiveEnabled(receive);
if ( !receive ) { //
m_receive = false;
shutDownReceive();
}
}
void Obex::shutDownReceive() {
if (m_rec != 0 ) {
if (m_rec->isRunning() ) {
emit error(-1 );
delete m_rec;
m_rec = 0;
}
}
}
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,84 +1,114 @@
+/*
+               =. 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
+ */
#ifndef OpieObex_H
#define OpieObex_H
+#include "obexbase.h"
#include <qobject.h>
namespace Opie {namespace Core {class OProcess;}}
class QCopChannel;
namespace OpieObex {
- class Obex : public QObject {
+ class Obex : public ObexBase {
Q_OBJECT
public:
/**
* Obex c'tor look
*/
Obex( QObject *parent, const char* name);
/**
* d'tor
*/
~Obex();
/**
* Starting listening to irda after enabled by the applet
* a signal gets emitted when received a file
*/
- 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:
/**
* a signal
* @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);
private:
uint m_count;
QString m_file;
QString m_outp;
Opie::Core::OProcess *m_send;
Opie::Core::OProcess *m_rec;
bool m_receive : 1;
void shutDownReceive();
private slots:
/**
* send over palm obex
*/
//void send(const QString&);
// the process exited
void slotExited(Opie::Core::OProcess* proc) ;
void slotStdOut(Opie::Core::OProcess*, char*, int);
- void slotError();
+ virtual void slotError();
private:
void sendNow();
QString parseOut();
void received();
void sendEnd();
};
};
#endif
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
@@ -1,14 +1,20 @@
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
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
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
@@ -1,67 +1,79 @@
#include <qpe/qcopenvelope_qws.h>
#include <qpe/qpeapplication.h>
#include "obexsend.h"
#include "receiver.h"
#include "obexhandler.h"
using namespace OpieObex;
/* TRANSLATOR OpieObex::ObexHandler */
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");
connect(chan, SIGNAL(received(const QCString&,const QByteArray&) ),
this, SLOT(irdaMessage(const QCString&,const QByteArray&) ) );
}
ObexHandler::~ObexHandler() {
delete m_sender;
- delete m_receiver;
+ delete m_receiver[REC_IRDA];
+ delete m_receiver[REC_BLUETOOTH];
}
void ObexHandler::doSend(const QString& str, const QString& desc) {
delete m_sender;
m_sender = new SendWidget;
m_sender->raise();
QPEApplication::showWidget( m_sender );
connect(m_sender, SIGNAL(done() ),
this, SLOT(slotSent() ) );
m_sender->send( str, 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);
}
}
void ObexHandler::slotSent() {
QString file = m_sender->file();
delete m_sender;
m_sender = 0;
QCopEnvelope e ("QPE/Obex", "done(QString)" );
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;
}
void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) {
QDataStream stream( data, IO_ReadOnly );
if ( msg == "send(QString,QString,QString)" ) {
QString name, desc;
stream >> desc;
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);
}else if (msg == "receive(int)") {
int rec;
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
@@ -1,39 +1,40 @@
#ifndef OPIE_OBEX_HANDLER_H
#define OPIE_OBEX_HANDLER_H
#include <qobject.h>
#include <qstring.h>
+#include "receiver.h"
namespace OpieObex {
/*
* The handler is responsible for handling receiving
* and sending
* It will connect to the IrDa QCOP channel and then
* wait for activation...
*/
class SendWidget;
class Receiver;
class ObexHandler : public QObject {
Q_OBJECT
public:
ObexHandler();
~ObexHandler();
private slots:
void doSend(const QString&,const QString& );
- void doReceive(bool b);
+ void doReceive(RecType type, bool b);
void slotSent();
private slots: // QCOP message
void irdaMessage( const QCString&, const QByteArray& );
private:
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)
};
}
#endif
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
@@ -1,252 +1,252 @@
// 7-Jul-2005 mbh@sdgsystems.com: replace hand coded form with one
// generated via QT2 Designer. The new form supports
// selection of target devices, as opposed to sending to
// all.
#include "obex.h"
#include "btobex.h"
#include "obexsend.h"
using namespace OpieObex;
/* OPIE */
#include <opie2/odebug.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/resource.h>
using namespace Opie::Core;
/* QT */
#include <qlabel.h>
#include <qpushbutton.h>
#include <qpixmap.h>
#include <qlistview.h>
#include <unistd.h>
/* TRANSLATOR OpieObex::SendWidget */
SendWidget::SendWidget( QWidget* parent, const char* name )
: obexSendBase( parent, name ) {
initUI();
}
SendWidget::~SendWidget() {
}
void SendWidget::initUI() {
m_obex = new Obex(this, "obex");
connect(m_obex, SIGNAL(error(int) ),
this, SLOT(slotIrError(int) ) );
connect(m_obex, SIGNAL(sent(bool) ),
this, SLOT(slotIrSent(bool) ) );
connect(m_obex, SIGNAL(currentTry(unsigned int) ),
this, SLOT(slotIrTry(unsigned int) ) );
QCopChannel* chan = new QCopChannel("QPE/IrDaAppletBack", this );
connect(chan, SIGNAL(received(const QCString&,const QByteArray&) ),
this, SLOT(dispatchIrda(const QCString&,const QByteArray&) ) );
m_btobex = new BtObex(this, "btobex");
connect(m_btobex, SIGNAL(error(int) ),
this, SLOT(slotBtError(int) ) );
connect(m_btobex, SIGNAL(sent(bool) ),
this, SLOT(slotBtSent(bool) ) );
connect(m_btobex, SIGNAL(currentTry(unsigned int) ),
this, SLOT(slotBtTry(unsigned int) ) );
chan = new QCopChannel("QPE/BluetoothBack", this );
connect(chan, SIGNAL(received(const QCString&,const QByteArray&) ),
this, SLOT(dispatchBt(const QCString&,const QByteArray&) ) );
}
/*
* in send we'll first set everything up
* and then wait for a list of devices.
*/
void SendWidget::send( const QString& file, const QString& desc ) {
m_file = file;
m_irDa.clear();
m_start = 0;
fileToSend->setText(desc.isEmpty() ? file : desc );
scan_for_receivers();
}
int SendWidget::addReceiver(const char *r, const char *icon)
{
QListViewItem * item = new QListViewItem( receiverList, 0 );
item->setText( 0, r);
item->setPixmap( 1, Resource::loadPixmap( icon ) );
int id=receivers.count();
receivers[id]=item;
return id;
}
bool SendWidget::receiverSelected(int id)
{
return (bool)(receivers[id]->pixmap(2) != NULL);
}
void SendWidget::setReceiverStatus( int id, const QString& status ) {
if ( !receivers.contains(id) ) return;
receivers[id]->setText(3, status );
}
void SendWidget::slotIrDaDevices( const QStringList& list) {
for (QStringList::ConstIterator it = list.begin();
it != list.end(); ++it ) {
int id = addReceiver(*it, "obex/irda.png");
m_irDa.insert( id, (*it) );
}
irdaStatus->setText( tr("ready."));
m_irDaIt = m_irDa.begin();
}
void SendWidget::slotBTDevices( const QMap<QString, QString>& str ) {
for(QMap<QString, QString>::ConstIterator it = str.begin();
it != str.end(); ++it ) {
int id = addReceiver(it.key(), "obex/bt.png");
m_bt.insert( id, Pair( it.key(), it.data() ) );
}
btStatus->setText(tr("ready."));
m_btIt = m_bt.begin();
}
void SendWidget::slotSelectedDevice( int, int ) {
/* if ( name == m_irDeSearch ) {
for (QMap<int, QString>::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it )
m_devBox->removeDevice( it.key() );
QCopEnvelope e2("QPE/IrDaApplet", "listDevices()");
}*/
}
void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) {
if ( str == "devices(QStringList)" ) {
QDataStream stream( ar, IO_ReadOnly );
QStringList list;
stream >> list;
slotIrDaDevices( list );
}
}
void SendWidget::slotIrError( int ) {
irdaStatus->setText(tr("error :("));
}
void SendWidget::slotIrSent( bool b) {
QString text = b ? tr("Sent") : tr("Failure");
setReceiverStatus( m_irDaIt.key(), text );
++m_irDaIt;
slotStartIrda();
}
void SendWidget::slotIrTry(unsigned int trI) {
setReceiverStatus(m_irDaIt.key(), tr("Try %1").arg( QString::number( trI ) ));
}
void SendWidget::slotStartIrda() {
if ( !m_irDa.count() )
return;
if ( m_irDaIt == m_irDa.end() || !receiverSelected(m_irDaIt.key())) {
irdaStatus->setText(tr("complete."));
return;
}
setReceiverStatus( m_irDaIt.key(), tr("Start sending") );
- m_obex->send( m_file );
+ m_obex->send( m_file, tr("noaddress") );
}
void SendWidget::dispatchBt( const QCString& str, const QByteArray& ar ) {
if ( str == "devices(QStringMap)" ) {
QDataStream stream( ar, IO_ReadOnly );
QMap<QString, QString> btmap;
stream >> btmap;
slotBTDevices( btmap );
}
}
void SendWidget::slotBtError( int ) {
btStatus->setText(tr("error :("));
}
void SendWidget::slotBtSent( bool b) {
QString text = b ? tr("Sent") : tr("Failure");
setReceiverStatus( m_btIt.key(), text );
++m_btIt;
slotStartBt();
}
void SendWidget::slotBtTry(unsigned int trI) {
setReceiverStatus( m_btIt.key(), tr("Try %1").arg( QString::number( trI ) ) );
}
void SendWidget::slotStartBt() {
// skip past unselected receivers
while((m_btIt != m_bt.end()) && !receiverSelected(m_btIt.key()))
++m_btIt;
if (m_btIt == m_bt.end() ) {
btStatus->setText(tr("complete."));
return;
}
setReceiverStatus( m_btIt.key(), tr("Start sending") );
m_btobex->send( m_file, m_btIt.data().second() );
}
void SendWidget::send_to_receivers() {
slotStartIrda();
slotStartBt();
}
void SendWidget::scan_for_receivers()
{
receiverList->clear();
receivers.clear();
sendButton->setDisabled( true );
if ( !QCopChannel::isRegistered("QPE/IrDaApplet") )
{
irdaStatus->setText(tr("not enabled."));
}
else
{
QCopEnvelope e1("QPE/IrDaApplet", "enableIrda()");
irdaStatus->setText(tr("searching..."));
sendButton->setEnabled( true );
QCopEnvelope e2("QPE/IrDaApplet", "listDevices()");
}
if ( !QCopChannel::isRegistered("QPE/Bluetooth") )
{
btStatus->setText(tr("not enabled."));
}
else
{
QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()");
btStatus->setText(tr("searching..."));
sendButton->setEnabled( true );
QCopEnvelope e3("QPE/Bluetooth", "listDevices()");
}
}
void SendWidget::toggle_receiver(QListViewItem* item)
{
// toggle the state of an individual receiver.
if(item->pixmap(2))
item->setPixmap(2,QPixmap());
else
item->setPixmap(2,Resource::loadPixmap("obex/check.png"));
}
void SendWidget::closeEvent( QCloseEvent* evt) {
delete m_obex;
m_obex = NULL;
delete m_btobex;
m_btobex = NULL;
obexSendBase::closeEvent(evt);
{
QCopEnvelope e("QPE/IrDaApplet", "disableIrda()");
}
{
QCopEnvelope e("QPE/Bluetooth", "disableBluetooth()");
}
}
void SendWidget::userDone() {
close();
}
QString SendWidget::file()const {
return m_file;
}
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,198 +1,203 @@
#include "obex.h"
+#include "btobex.h"
+#include "obexbase.h"
#include "receiver.h"
using namespace OpieObex;
/* OPIE */
#include <opie2/odebug.h>
#include <qpe/applnk.h>
#include <qpe/qpeapplication.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/filemanager.h>
using namespace Opie::Core;
/* QT */
#include <qfileinfo.h>
#include <qlabel.h>
#include <qtextview.h>
#include <qpushbutton.h>
/* STD */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdlib.h> // int system
#include <unistd.h>
#include <fcntl.h>
/* TRANSLATOR OpieObex::Receiver */
-Receiver::Receiver() {
- m_obex = new Obex(this, "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&) ),
this, SLOT(slotReceived(const QString&) ) );
m_obex->receive();
}
Receiver::~Receiver() {
m_obex->setReceiveEnabled( false );
delete m_obex;
}
void Receiver::slotReceived( const QString& _file ) {
QString file = _file;
int check = checkFile(file);
if ( check == AddressBook )
handleAddr( file );
else if ( check == Datebook )
handleDateTodo( file );
else
handleOther( file );
}
void Receiver::handleAddr( const QString& str ) {
QCopEnvelope e("QPE/Application/addressbook", "setDocument(QString)" );
e << str;
}
/* we can not say for sure if it's a VEevent ot VTodo */
void Receiver::handleDateTodo( const QString& str ) {
QCopEnvelope e0("QPE/Application/todolist", "setDocument(QString)");
e0 << str;
QCopEnvelope e1("QPE/Application/datebook", "setDocument(QString)" );
e1 << str;
}
/*
* Handle other asks if it should accept the
* beamed object and creates a DocLnk
*/
void Receiver::handleOther( const QString& other ) {
OtherHandler* hand = new OtherHandler();
hand->handle( other );
}
void Receiver::tidyUp( QString& _file, const QString& ending) {
/* libversit fails on BASE64 encoding we try to sed it away */
QString file = _file;
char foo[24]; // big enough
(void)::strcpy(foo, "/tmp/opie-XXXXXX");
int fd = ::mkstemp(foo);
if ( fd == -1 )
return;
(void)::strncat( foo, QFile::encodeName(ending), 4 );
_file = QString::fromLocal8Bit( foo );
QString cmd = QString("sed -e \"s/^\\(X-MICROSOFT-BODYINK\\)\\;/\\1:/;\" < %2 > %2 ").arg( Global::shellQuote(file)).arg( Global::shellQuote(_file) );
(void)::system( QFile::encodeName(cmd) );
cmd = QString("rm %1").arg( Global::shellQuote(file) );
(void)::system( QFile::encodeName(cmd) );
}
int Receiver::checkFile( QString& file ) {
int ret;
QString ending;
if (file.right(4) == ".vcs" ) {
ret = Datebook;
ending = QString::fromLatin1(".vcs");
}else if ( file.right(4) == ".vcf") {
ret = AddressBook;
ending = QString::fromLatin1(".vcf");
}else
ret = Other;
if (ending.isEmpty() )
return ret;
/**
* currently the parser is broken in regard of BASE64 encoding
* and M$ likes to send that. So we will executed a small
* tidy up system sed script
* At this point we can also remove umlaute from the filename
*/
tidyUp( file, ending );
return ret;
}
/* TRANSLATOR OpieObex::OtherHandler */
OtherHandler::OtherHandler()
: QVBox()
{
QHBox* box = new QHBox(this);
QLabel* lbl = new QLabel(box);
lbl->setText(tr("<qt><b>Received:</b></qt>"));
m_na = new QLabel(box);
QFrame* frame = new QFrame(this);
frame->setFrameShape( QFrame::HLine );
frame->setFrameShadow( QFrame::Sunken );
m_view = new QTextView(this);
box = new QHBox(this);
QPushButton *but = new QPushButton(box);
but->setText(tr("Accept") );
connect(but, SIGNAL(clicked() ),
this, SLOT(accept()) );
but = new QPushButton(box);
but->setText(tr("Deny") );
connect(but, SIGNAL(clicked() ),
this, SLOT(deny() ) );
raise();
showMaximized();
}
OtherHandler::~OtherHandler() {
}
void OtherHandler::handle( const QString& file ) {
m_file = file;
m_na->setText(file);
DocLnk lnk(file);
QString str = tr("<p>You received a file of type %1 (<img src=\"%2\"> )What do you want to do?").arg(lnk.type() ).arg(lnk.icon() );
m_view->setText( str );
}
/*
* hehe evil evil mmap ahead :)
* we quickly copy the file and then we'll create a DocLnk for it
*/
void OtherHandler::accept() {
QString na = targetName( m_file );
copy(m_file, na );
DocLnk lnk(na);
lnk.writeLink();
QFile::remove(m_file);
delete this;
}
void OtherHandler::deny() {
QFile::remove( m_file );
delete this;
}
QString OtherHandler::targetName( const QString& file ) {
QFileInfo info( file );
/* $HOME needs to be set!!!! */
Global::createDocDir();
QString newFile = QPEApplication::documentDir()+ "/"+ info.baseName();
QString newFileBase = newFile;
int trie = 0;
while (QFile::exists(newFile + "."+info.extension() ) ) {
newFile = newFileBase + "_"+QString::number(trie) ;
trie++;
}
newFile += "." + info.extension();
return newFile;
}
/* fast cpy */
void OtherHandler::copy(const QString& src, const QString& file) {
FileManager *fm;
if(!fm->copyFile(src,file)) {
owarn << "Copy failed" << oendl;
}
}
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
@@ -1,58 +1,64 @@
#ifndef OPIE_OBEX_RECEIVER_H
#define OPIE_OBEX_RECEIVER_H
#include <qobject.h>
#include <qvbox.h>
#include <qstring.h>
+//Receiver type
+typedef enum _RecType {
+ REC_IRDA = 0,
+ REC_BLUETOOTH = 1
+} RecType;
+
class QLabel;
class QTextView;
namespace OpieObex {
- class Obex;
+ class ObexBase;
class OtherHandler;
class Receiver : public QObject {
Q_OBJECT
public:
enum { Datebook , AddressBook, Other };
- Receiver();
+ Receiver(RecType type);
~Receiver();
private:
void handleAddr(const QString& );
void handleDateTodo(const QString& );
void handleOther(const QString& );
/* will alter the file name */
int checkFile( QString& file );
bool testDateTodo(const QString& file);
bool testAddressbook(const QString& file);
/* called by checkFile */
void tidyUp( QString& file, const QString& ending );
private slots:
void slotReceived( const QString& );
private:
- Obex* m_obex;
+ ObexBase* m_obex; //IR obex
};
class OtherHandler : public QVBox {
Q_OBJECT
public:
OtherHandler();
~OtherHandler();
void handle( const QString& file );
private slots:
void accept();
void deny();
private:
QString targetName( const QString& file );
void copy( const QString& src, const QString& dest );
QLabel* m_na;
QTextView* m_view;
QString m_file;
};
}
#endif