summaryrefslogtreecommitdiff
path: root/core/obex
authorzecke <zecke>2003-02-16 15:49:02 (UTC)
committer zecke <zecke>2003-02-16 15:49:02 (UTC)
commit30a098530260176ac20d75ba6cb7abfb3d998c13 (patch) (side-by-side diff)
treeee5c08ca67fa00574414153921ab2de654c60421 /core/obex
parent7fab90d46144843d32e476ada8d0a5f40f50aa60 (diff)
downloadopie-30a098530260176ac20d75ba6cb7abfb3d998c13.zip
opie-30a098530260176ac20d75ba6cb7abfb3d998c13.tar.gz
opie-30a098530260176ac20d75ba6cb7abfb3d998c13.tar.bz2
disable snd in IrDaApplet it hangs on my machine..
Remove the hacky OBEX Implementation Add a more cleaned up more appealing (not yet working) version which will even be able to do OBEX over Bluetooth in the future -It handles receive better let's you choose what to do with custom files and created a DocLnk -Send lets you beam to multiple devices this needs the IrDa Applet to be present
Diffstat (limited to 'core/obex') (more/less context) (ignore whitespace changes)
-rw-r--r--core/obex/config.in4
-rw-r--r--core/obex/obex.cc195
-rw-r--r--core/obex/obex.h84
-rw-r--r--core/obex/obexhandler.cpp65
-rw-r--r--core/obex/obexhandler.h39
-rw-r--r--core/obex/obeximpl.cpp28
-rw-r--r--core/obex/obeximpl.h22
-rw-r--r--core/obex/obexsend.cpp251
-rw-r--r--core/obex/obexsend.h99
-rw-r--r--core/obex/receiver.cpp166
-rw-r--r--core/obex/receiver.h55
11 files changed, 1008 insertions, 0 deletions
diff --git a/core/obex/config.in b/core/obex/config.in
new file mode 100644
index 0000000..4d1f43d
--- a/dev/null
+++ b/core/obex/config.in
@@ -0,0 +1,4 @@
+ config OBEX
+ boolean "Obex library (library needed for beaming in Opie)"
+ default "y"
+ depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE
diff --git a/core/obex/obex.cc b/core/obex/obex.cc
new file mode 100644
index 0000000..83d1faf
--- a/dev/null
+++ b/core/obex/obex.cc
@@ -0,0 +1,195 @@
+
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <opie/oprocess.h>
+#include "obex.h"
+
+using namespace OpieObex;
+
+Obex::Obex( QObject *parent, const char* name )
+ : QObject(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() ),
+ SLOT(slotError() ) );
+};
+Obex::~Obex() {
+ delete m_rec;
+ delete m_send;
+}
+void Obex::receive() {
+ m_receive = true;
+ m_outp = QString::null;
+ qWarning("Receive" );
+ m_rec = new OProcess();
+ *m_rec << "irobex_palm3";
+ // connect to the necessary slots
+ connect(m_rec, SIGNAL(processExited(OProcess*) ),
+ this, SLOT(slotExited(OProcess*) ) );
+
+ connect(m_rec, SIGNAL(receivedStdout(OProcess*, char*, int ) ),
+ this, SLOT(slotStdOut(OProcess*, char*, int) ) );
+
+ if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) {
+ qWarning("could not start :(");
+ emit done( false );
+ delete m_rec;
+ m_rec = 0;
+ }
+// emit currentTry(m_count );
+
+}
+void Obex::send( const QString& fileName) { // if currently receiving stop it send receive
+ m_count = 0;
+ m_file = fileName;
+ qWarning("send");
+ if (m_rec != 0 ) {
+ qWarning("running");
+ if (m_rec->isRunning() ) {
+ emit error(-1 );
+ qWarning("is running");
+ delete m_rec;
+ m_rec = 0;
+
+ }else{
+ qWarning("is not running");
+ emit error( -1 ); // we did not delete yet but it's not running slotExited is pending
+ return;
+ }
+ }
+ sendNow();
+}
+void Obex::sendNow(){
+ qWarning("sendNow");
+ if ( m_count >= 25 ) { // could not send
+ emit error(-1 );
+ emit sent(false);
+ return;
+ }
+ // OProcess inititialisation
+ m_send = new OProcess();
+ *m_send << "irobex_palm3";
+ *m_send << m_file;
+
+ // connect to slots Exited and and StdOut
+ connect(m_send, SIGNAL(processExited(OProcess*) ),
+ this, SLOT(slotExited(OProcess*)) );
+ connect(m_send, SIGNAL(receivedStdout(OProcess*, char*, int )),
+ this, SLOT(slotStdOut(OProcess*, char*, int) ) );
+
+ // now start it
+ if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) {
+ qWarning("could not send" );
+ 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
+ QCString cstring( buf, len );
+ m_outp.append( cstring.data() );
+ }
+}
+
+void Obex::received() {
+ if (m_rec->normalExit() ) {
+ if ( m_rec->exitStatus() == 0 ) { // we got one
+ QString filename = parseOut();
+ qWarning("ACHTUNG");
+ 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;
+ qWarning("done" );
+ 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;
+ qWarning("try sending again" );
+ 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 ) {
+ qWarning( "%d %s", pos, (*it).mid(6 ).latin1() ) ;
+ qWarning("%d %d", (*it).length(), (*it).length()-pos );
+
+ path = (*it).remove( pos, (*it).length() - pos );
+ qWarning("%s", path.latin1() );
+ path = path.mid(6 );
+ path = path.stripWhiteSpace();
+ qWarning("path %s", path.latin1() );
+ }
+ }
+ }
+ return path;
+}
+/**
+ * when sent is done slotError is called we will start receive again
+ */
+void Obex::slotError() {
+ qWarning("slotError");
+ if ( m_receive )
+ receive();
+};
+void Obex::setReceiveEnabled( bool receive ) {
+ if ( !receive ) { //
+ m_receive = false;
+ shutDownReceive();
+ }
+}
+
+void Obex::shutDownReceive() {
+ if (m_rec != 0 ) {
+ qWarning("running");
+ if (m_rec->isRunning() ) {
+ emit error(-1 );
+ qWarning("is running");
+ delete m_rec;
+ m_rec = 0;
+ }
+ }
+
+}
diff --git a/core/obex/obex.h b/core/obex/obex.h
new file mode 100644
index 0000000..60f5d28
--- a/dev/null
+++ b/core/obex/obex.h
@@ -0,0 +1,84 @@
+
+
+#ifndef OpieObex_H
+#define OpieObex_H
+
+#include <qobject.h>
+
+class OProcess;
+class QCopChannel;
+namespace OpieObex {
+ class Obex : public QObject {
+ 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 recieved a file
+ */
+ void receive();
+ void send( const QString& );
+ void setReceiveEnabled( bool = false );
+ signals:
+
+ /**
+ * a signal
+ * @param path The path to the recieved 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;
+ OProcess *m_send;
+ OProcess *m_rec;
+ bool m_receive : 1;
+ void shutDownReceive();
+
+private slots:
+
+ /**
+ * send over palm obex
+ */
+
+ //void send(const QString&);
+
+ // the process exited
+ void slotExited(OProcess* proc) ;
+ void slotStdOut(OProcess*, char*, int);
+ void slotError();
+
+ private:
+ void sendNow();
+ QString parseOut();
+ void received();
+ void sendEnd();
+
+ };
+};
+
+
+#endif
diff --git a/core/obex/obexhandler.cpp b/core/obex/obexhandler.cpp
new file mode 100644
index 0000000..f71a233
--- a/dev/null
+++ b/core/obex/obexhandler.cpp
@@ -0,0 +1,65 @@
+#include <qcopchannel_qws.h>
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include "obexsend.h"
+#include "receiver.h"
+#include "obexhandler.h"
+
+using namespace OpieObex;
+
+ObexHandler::ObexHandler() {
+ m_wasRec = false;
+ m_sender = 0l;
+ m_receiver = 0l;
+ 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;
+}
+void ObexHandler::doSend(const QString& str, const QString& desc) {
+ delete m_sender;
+ m_sender = new SendWidget;
+ m_sender->raise();
+ m_sender->showMaximized();
+ 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::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;
+}
+void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) {
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "send(QString,QString,QString)" ) {
+ QString name, desc;
+ stream >> name;
+ stream >> desc;
+ m_wasRec = (m_receiver != 0 );
+ doReceive( false );
+ doSend(name, desc);
+ }else if (msg == "receive(int)") {
+ int rec;
+ stream >> rec;
+ doReceive(rec);
+ }
+}
diff --git a/core/obex/obexhandler.h b/core/obex/obexhandler.h
new file mode 100644
index 0000000..230c4f0
--- a/dev/null
+++ b/core/obex/obexhandler.h
@@ -0,0 +1,39 @@
+#ifndef OPIE_OBEX_HANDLER_H
+#define OPIE_OBEX_HANDLER_H
+
+#include <qobject.h>
+#include <qstring.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 slotSent();
+
+ private slots: // QCOP message
+ void irdaMessage( const QCString&, const QByteArray& );
+
+ private:
+ SendWidget* m_sender;
+ Receiver* m_receiver;
+ bool m_wasRec : 1;
+
+ };
+}
+
+
+#endif
diff --git a/core/obex/obeximpl.cpp b/core/obex/obeximpl.cpp
new file mode 100644
index 0000000..12a078f
--- a/dev/null
+++ b/core/obex/obeximpl.cpp
@@ -0,0 +1,28 @@
+#include "obexhandler.h"
+#include "obeximpl.h"
+
+using namespace OpieObex;
+
+ObexImpl::ObexImpl() {
+ m_handler = new ObexHandler;
+}
+ObexImpl::~ObexImpl() {
+ delete m_handler;
+}
+QRESULT ObexImpl::queryInterface( const QUuid& uuid, QUnknownInterface **iface ) {
+ *iface = 0;
+ if ( uuid == IID_QUnknown ) {
+ *iface = this;
+ }else if ( uuid == IID_ObexInterface )
+ *iface = this;
+
+ if (*iface)
+ (*iface)->addRef();
+
+ return QS_OK;
+}
+
+
+Q_EXPORT_INTERFACE() {
+ Q_CREATE_INSTANCE( ObexImpl )
+}
diff --git a/core/obex/obeximpl.h b/core/obex/obeximpl.h
new file mode 100644
index 0000000..604eb8f
--- a/dev/null
+++ b/core/obex/obeximpl.h
@@ -0,0 +1,22 @@
+#ifndef OPIE_OBEX_IMPL_QUERY_H
+#define OPIE_OBEX_IMPL_QUERY_H
+
+#include <obexinterface.h>
+
+namespace OpieObex {
+ class ObexHandler;
+ class ObexImpl : public ObexInterface {
+ public:
+ ObexImpl();
+ virtual ~ObexImpl();
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+ private:
+ ulong ref;
+ ObexHandler *m_handler;
+
+ };
+};
+
+#endif
diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp
new file mode 100644
index 0000000..a2e4c16
--- a/dev/null
+++ b/core/obex/obexsend.cpp
@@ -0,0 +1,251 @@
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qtimer.h>
+
+#include <qcopchannel_qws.h>
+
+#include <qpe/resource.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include "obex.h"
+#include "obexsend.h"
+
+using namespace OpieObex;
+
+
+SendWidget::SendWidget( QWidget* parent, const char* name )
+ : QWidget( 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(dispatchBt(const QCString&, const QByteArray& ) ) );
+
+ chan = new QCopChannel("QPE/BluetoothBack", this );
+ connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ),
+ this, SLOT(dispatchIrda(const QCString&, const QByteArray& ) ) );
+
+ QVBoxLayout* lay = new QVBoxLayout(this);
+
+ QHBox* nameBox = new QHBox(this);
+ QLabel* name = new QLabel(nameBox);
+ name->setText( tr("<qt><h1>Sending:</h1></qt>") );
+ name->setAlignment( AlignLeft | AlignTop );
+ m_lblFile = new QLabel(nameBox);
+ lay->addWidget(nameBox, 0);
+
+ QFrame* frame = new QFrame(this);
+ frame->setFrameShape( QFrame::HLine );
+ frame->setFrameShadow( QFrame::Sunken );
+ lay->addWidget(frame, 10);
+
+ QLabel* devices = new QLabel(this);
+ devices->setText("<qt><b>Devices:</b></qt>");
+ devices->setAlignment( AlignLeft | AlignTop );
+ lay->addWidget( devices,10 );
+
+ m_devBox = new DeviceBox(this);
+ lay->addWidget( m_devBox, 50 );
+ connect(m_devBox, SIGNAL(selectedDevice(const QString&, int ) ),
+ this, SLOT(slotSelectedDevice(const QString&, int) ) );
+
+ QPushButton *but = new QPushButton(this);
+ but->setText(tr("Done") );
+ connect(but, SIGNAL(clicked() ),
+ this, SLOT(slotDone() ) );
+
+ lay->addWidget( but );
+ m_lay = lay;
+
+ // QT does not like if you add items to an layout which already exits....
+ // and was layouted invalidate() does not help too
+ // so we use RichText....
+}
+
+/*
+ * 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;
+ m_lblFile->setText(desc.isEmpty() ? file : desc );
+
+ if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) {
+ m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error );
+ m_start++;
+ }else
+ m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search );
+
+ if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) {
+ m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error );
+ m_start++;
+ }else
+ m_devBox->addDevice( tr("Searching for bluetooth Devices."), DeviceBox::Search );
+
+ if (m_start != 2 ) {
+ QCopEnvelope e0("QPE/IrDaApplet", "enableIrda()");
+ QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()");
+ QCopEnvelope e2("QPE/IrDaApplet", "listDevices()");
+ QCopEnvelope e3("QPE/Bluetooth", "listDevices()");
+ }
+ QTimer::singleShot(5000, this, SLOT(testIt() ) );
+}
+void SendWidget::slotIrDaDevices( const QStringList& list) {
+ m_irDa = list;
+ m_start = 0;
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") );
+ m_devBox->removeDevice( tr("Search for IrDa Devices.") );
+
+ slotStartIrda();
+}
+void SendWidget::slotBTDevices( const QMap<QString, QString>& str ) {
+ m_bt = str;
+ for(QMap<QString, QString>::ConstIterator it = str.begin(); it != str.end(); ++it ) {
+ m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") );
+ }
+ m_devBox->removeDevice( tr("Searching for bluetooth Devices.") );
+}
+void SendWidget::slotSelectedDevice( const QString& name, int dev ) {
+ qWarning("Start beam? %s %d", name.latin1(), dev );
+ if ( name == tr("Search again for IrDa.") ) {
+ for (QStringList::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it )
+ m_devBox->removeDevice( (*it) );
+ QCopEnvelope e2("QPE/IrDaApplet", "listDevices()");
+ }
+}
+void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) {
+ qWarning("dispatch irda %s", str.data() );
+ if ( str == "listDevices(QStringList)" ) {
+ QDataStream stream( ar, IO_ReadOnly );
+ QStringList list;
+ stream >> list;
+ slotIrDaDevices( list );
+ }
+}
+void SendWidget::dispatchBt( const QCString& str, const QByteArray& ar ) {
+
+}
+void SendWidget::slotIrError( int ) {
+
+}
+void SendWidget::slotIrSent( bool b) {
+ QString text = b ? tr("Sent") : tr("Failure");
+ m_devBox->setStatus( m_irDa[m_start], text );
+ m_start++;
+ slotStartIrda();
+}
+void SendWidget::slotIrTry(unsigned int trI) {
+ m_devBox->setStatus( m_irDa[m_start], tr("Try %1").arg( QString::number( trI ) ) );
+}
+void SendWidget::slotStartIrda() {
+ if (m_start >= m_irDa.count() ) {
+ m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search );
+ return;
+ }
+ m_devBox->setStatus( m_irDa[m_start], tr("Start sending") );
+ m_obex->send( m_file );
+}
+void SendWidget::slotDone() {
+ QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()");
+ QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()");
+ emit done();
+}
+QString SendWidget::file()const {
+ return m_file;
+}
+DeviceBox::DeviceBox( QWidget* parent )
+ : QTextBrowser( parent ) {
+
+}
+DeviceBox::~DeviceBox() {
+
+}
+void DeviceBox::addDevice( const QString& name, int dev, const QString& status ) {
+ QString tex;
+ DeviceItem item( name, status, dev );
+ m_dev.insert( name, item );
+ tex = item.toString();
+ m_devices.prepend(tex);
+ setText( text()+ "<br>"+tex );
+}
+void DeviceBox::removeDevice( const QString& name ) {
+ if (!m_dev.contains(name) ) return;
+ m_devices.remove( m_dev[name].toString() );
+
+ m_dev.remove(name);
+ setText( m_devices.join("<br>") );
+
+}
+void DeviceBox::setStatus( const QString& name, const QString& status ) {
+ if ( !m_dev.contains(name) ) return;
+ DeviceItem dev = m_dev[name];
+ QString ole = dev.toString();
+ dev.setStatus( status );
+ int index = m_devices.findIndex( ole );
+ m_devices[index] = dev.toString();
+ setText( m_devices.join("<br>") );
+}
+void DeviceBox::setSource( const QString& str ) {
+ qWarning("SetSource:%s", str.latin1() );
+ emit selectedDevice( str, m_dev[str].device() );
+}
+
+
+DeviceItem::DeviceItem( const QString& name,
+ const QString& status, int dev)
+{
+ m_name = name;
+ m_status = status;
+ m_dev = dev;
+}
+QString DeviceItem::name()const {
+ return m_name;
+}
+QString DeviceItem::status()const {
+ return m_status;
+}
+int DeviceItem::device()const {
+ return m_dev;
+}
+QString DeviceItem::pixmap()const{
+ QString str;
+ switch(m_dev) {
+ case DeviceBox::IrDa:
+ str ="obex/irda";
+ break;
+ case DeviceBox::BT:
+ str ="obex/bt";
+ break;
+ case DeviceBox::Search:
+ str = "obex/search";
+ break;
+ case DeviceBox::Error:
+ str = "editdelete";
+ break;
+ };
+ return str;
+}
+DeviceItem::~DeviceItem() {
+}
+void DeviceItem::setStatus(const QString& status ) {
+ m_status = status;
+}
+QString DeviceItem::toString()const {
+ return "<p><a href=\""+m_name +"\" ><img src=\""+pixmap()+"\" >"+m_name+" "+m_status+" </a></p>" ;
+}
diff --git a/core/obex/obexsend.h b/core/obex/obexsend.h
new file mode 100644
index 0000000..fd819bc
--- a/dev/null
+++ b/core/obex/obexsend.h
@@ -0,0 +1,99 @@
+#ifndef OPIE_OBEX_SEND_WIDGET_H
+#define OPIE_OBEX_SEND_WIDGET_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qwidget.h>
+#include <qvbox.h>
+#include <qmap.h>
+#include <qtextbrowser.h>
+
+class QLabel;
+class QVBoxLayout;
+/**
+ * This is the new sending widget for Obex
+ * It will attemp to smart and be able to send
+ * it to multiple devices.
+ * It'll support BT + IrDa
+ */
+namespace OpieObex {
+ class DeviceBox;
+ class Obex;
+ class SendWidget : public QWidget{
+ Q_OBJECT
+ public:
+ SendWidget( QWidget* parent = 0, const char* name = 0);
+ ~SendWidget();
+
+ QString file()const;
+
+ public slots:
+ void send( const QString& file, const QString& desc );
+
+ signals:
+ void done();
+
+ private slots: // QCOP slots
+ /* IrDa Names*/
+ void slotIrDaDevices( const QStringList& );
+ /* Bt Names + BD-Addr */
+ void slotBTDevices( const QMap<QString, QString>& );
+ void slotSelectedDevice( const QString& name, int dev );
+ void dispatchIrda( const QCString& str, const QByteArray& ar );
+ void dispatchBt( const QCString& str, const QByteArray& ar );
+
+ void slotIrError( int );
+ void slotIrSent(bool);
+ void slotIrTry(unsigned int );
+ void slotStartIrda();
+ void slotDone();
+ private:
+ void initUI();
+ QLabel* m_lblFile;
+ DeviceBox* m_devBox;
+ QVBoxLayout* m_lay;
+ int m_start;
+ QStringList m_irDa;
+ QMap<QString, QString> m_bt;
+ QString m_file;
+ Obex* m_obex;
+ };
+ class DeviceItem {
+ public:
+ DeviceItem( const QString& name = QString::null,
+ const QString& status = QString::null, int dev = 3);
+ ~DeviceItem();
+ void setStatus( const QString& text );
+
+ QString name()const;
+ QString status()const;
+ QString pixmap()const;
+ int device()const;
+ QString toString()const;
+ private:
+ QString m_name;
+ QString m_status;
+ int m_dev;
+ };
+ class DeviceBox : public QTextBrowser {
+ Q_OBJECT
+ public:
+ enum Device { IrDa, BT, Search, Error };
+ DeviceBox( QWidget* parent );
+ ~DeviceBox();
+
+ void setSource( const QString& str );
+ void addDevice( const QString& name, int dev,
+ const QString& status = QString::null );
+ void removeDevice( const QString& name );
+ void setStatus( const QString& name, const QString& );
+ signals:
+ void selectedDevice( const QString& name, int dev );
+ private:
+ QMap<QString, DeviceItem> m_dev;
+ QStringList m_devices;
+
+ };
+}
+
+#endif
diff --git a/core/obex/receiver.cpp b/core/obex/receiver.cpp
new file mode 100644
index 0000000..50ee6cb
--- a/dev/null
+++ b/core/obex/receiver.cpp
@@ -0,0 +1,166 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qtextview.h>
+#include <qpushbutton.h>
+
+#include <qpe/applnk.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include "obex.h"
+#include "receiver.h"
+
+using namespace OpieObex;
+
+Receiver::Receiver() {
+ m_obex = new Obex(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 ) {
+ 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 );
+}
+int Receiver::checkFile( const QString& file ) {
+ int ret;
+ if (file.right(4) == ".vcs" ) {
+ ret = Datebook;
+ }else if ( file.right(4) == ".vcf") {
+ ret = AddressBook;
+ }else
+ ret = Other;
+
+ return ret;
+}
+
+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 );
+ 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) {
+ int src_fd = ::open( QFile::encodeName( src ), O_RDONLY );
+ int to_fd = ::open( QFile::encodeName( file), O_RDWR| O_CREAT| O_TRUNC,
+ S_IRUSR, S_IWUSR, S_IRGRP, S_IRGRP );
+
+ struct stat stater;
+ ::fstat(src_fd, &stater );
+ ::lseek(to_fd, stater.st_size-1, SEEK_SET );
+
+ void *src_addr, *dest_addr;
+ src_addr = ::mmap(0, stater.st_size, PROT_READ,
+ MAP_FILE | MAP_SHARED, src_fd, 0 );
+ dest_addr= ::mmap(0, stater.st_size, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_PRIVATE, to_fd, 0 );
+
+ ::memcpy(src_addr , dest_addr, stater.st_size );
+ ::munmap(src_addr , stater.st_size );
+ ::munmap(dest_addr, stater.st_size );
+
+ // done
+}
diff --git a/core/obex/receiver.h b/core/obex/receiver.h
new file mode 100644
index 0000000..5b20146
--- a/dev/null
+++ b/core/obex/receiver.h
@@ -0,0 +1,55 @@
+#ifndef OPIE_OBEX_RECEIVER_H
+#define OPIE_OBEX_RECEIVER_H
+
+#include <qobject.h>
+#include <qvbox.h>
+#include <qstring.h>
+
+class QLabel;
+class QTextView;
+namespace OpieObex {
+ class Obex;
+ class OtherHandler;
+ class Receiver : public QObject {
+ Q_OBJECT
+ public:
+ enum { Datebook , AddressBook, Other };
+ Receiver();
+ ~Receiver();
+
+ private:
+ void handleAddr(const QString& );
+ void handleDateTodo(const QString& );
+ void handleOther(const QString& );
+ int checkFile( const QString& file );
+ bool testDateTodo(const QString& file);
+ bool testAddressbook(const QString& file);
+
+ private slots:
+ void slotReceived( const QString& );
+
+ private:
+ Obex* m_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