From d5b6868cb4f99d2c3dc3587115cd37c09e4610eb Mon Sep 17 00:00:00 2001 From: mickeyl Date: Tue, 02 May 2006 08:57:25 +0000 Subject: bluetooth patches courtesy Dmitriy Korovkin (thanks!): * When sending data to a device, do service discovery in order to get port number. * Switched to ussp-push for sending. * Clear receivers list on rescan. * Changed the way of window closing in order to shut down IRDA and bluetooth correctly. --- (limited to 'core') diff --git a/core/obex/btobex.cpp b/core/obex/btobex.cpp index a2866f6..bb5c06d 100644 --- a/core/obex/btobex.cpp +++ b/core/obex/btobex.cpp @@ -1,5 +1,7 @@ #include "btobex.h" +#include +#include /* OPIE */ #include @@ -7,13 +9,15 @@ /* QT */ #include - - +#include +#include +#include using namespace OpieObex; using namespace Opie::Core; /* TRANSLATOR OpieObex::Obex */ +using namespace OpieTooth; BtObex::BtObex( QObject *parent, const char* name ) : QObject(parent, name ) @@ -26,11 +30,16 @@ BtObex::BtObex( QObject *parent, const char* name ) SLOT(slotError() ) ); connect( this, SIGNAL(sent(bool) ), SLOT(slotError() ) ); + btManager = NULL; }; + BtObex::~BtObex() { + if (btManager) + delete btManager; delete m_rec; delete m_send; } + void BtObex::receive() { m_receive = true; m_outp = QString::null; @@ -68,8 +77,54 @@ void BtObex::send( const QString& fileName, const QString& bdaddr) { 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::Iterator it; + QMap classList; //The classes list + QMap::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(){ if ( m_count >= 25 ) { // could not send emit error(-1 ); @@ -77,24 +132,23 @@ void BtObex::sendNow(){ return; } // OProcess inititialisation - m_send = new OProcess(); + m_send = new OProcess(0, "ussp-push"); m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) ); - // obextool push file [channel] - // 9 for phones. - // Palm T3 accepts pictures on 1 - *m_send << "obextool" << "push"; + // ussp-push --timeo 30 file file + *m_send << "ussp-push" << "--timeo 30"; + *m_send << m_bdaddr + "@" + QString::number(m_port); *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); - *m_send << m_bdaddr << "9"; - + *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); + m_send->setUseShell(true); + // 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 )), + 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*/ ) ) { + if (!m_send->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { m_count = 25; emit error(-1 ); delete m_send; @@ -106,6 +160,8 @@ void BtObex::sendNow(){ } void BtObex::slotExited(OProcess* proc ){ + odebug << proc->name() << " exited with result " + << proc->exitStatus() << oendl; if (proc == m_rec ) // receive process received(); else if ( proc == m_send ) @@ -140,7 +196,7 @@ void BtObex::sendEnd() { delete m_send; m_send=0; emit sent(true); - }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready + }else if (m_send->exitStatus() != 0 ) { // it failed maybe the other side wasn't ready // let's try it again delete m_send; m_send = 0; @@ -154,11 +210,12 @@ void BtObex::sendEnd() { } // This probably doesn't do anything useful for bt. -QString BtObex::parseOut( ){ +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 ) { diff --git a/core/obex/btobex.h b/core/obex/btobex.h index 5ab591c..099f04a 100644 --- a/core/obex/btobex.h +++ b/core/obex/btobex.h @@ -4,9 +4,12 @@ #define OpieBtObex_H #include +#include +#include namespace Opie {namespace Core {class OProcess;}} class QCopChannel; +using namespace OpieTooth; namespace OpieObex { // Maybe this should be derved from Obex. class BtObex : public QObject { @@ -55,17 +58,20 @@ namespace OpieObex { QString m_file; QString m_outp; QString m_bdaddr; + int m_port; Opie::Core::OProcess *m_send; Opie::Core::OProcess *m_rec; bool m_receive : 1; + OpieTooth::Manager* btManager; void shutDownReceive(); private slots: // the process exited - void slotExited(Opie::Core::OProcess* proc) ; + void slotExited(Opie::Core::OProcess*) ; void slotStdOut(Opie::Core::OProcess*, char*, int); void slotError(); + void slotFoundServices(const QString&, Services::ValueList); private: void sendNow(); diff --git a/core/obex/obex.pro b/core/obex/obex.pro index d6b527c..33cb957 100644 --- a/core/obex/obex.pro +++ b/core/obex/obex.pro @@ -5,9 +5,9 @@ SOURCES = obex.cpp btobex.cpp obexsend.cpp obexhandler.cpp receiver.cpp obexim TARGET = opieobex DESTDIR = $(OPIEDIR)/plugins/obex INTERFACES = obexsendbase.ui -INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher +INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher $(OPIEDIR)/noncore/net/opietooth/lib DEPENDPATH += -LIBS += -lqpe -lopiecore2 +LIBS += -lopietooth1 -lqpe -lopiecore2 VERSION = 0.0.3 include( $(OPIEDIR)/include.pro ) diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp index 9cd9972..dbbb7b3 100644 --- a/core/obex/obexsend.cpp +++ b/core/obex/obexsend.cpp @@ -20,8 +20,8 @@ using namespace Opie::Core; #include #include #include -#include +#include /* TRANSLATOR OpieObex::SendWidget */ SendWidget::SendWidget( QWidget* parent, const char* name ) @@ -83,7 +83,7 @@ int SendWidget::addReceiver(const char *r, const char *icon) bool SendWidget::receiverSelected(int id) { - return receivers[id]->pixmap(2); + return (bool)(receivers[id]->pixmap(2) != NULL); } void SendWidget::setReceiverStatus( int id, const QString& status ) { @@ -141,7 +141,7 @@ void SendWidget::slotIrTry(unsigned int trI) { void SendWidget::slotStartIrda() { if ( !m_irDa.count() ) return; if ( m_irDaIt == m_irDa.end() ) { - irdaStatus->setText(tr("complete.")); + irdaStatus->setText(tr("complete.")); return; } setReceiverStatus( m_irDaIt.key(), tr("Start sending") ); @@ -173,7 +173,7 @@ void SendWidget::slotStartBt() { while((m_btIt != m_bt.end()) && !receiverSelected(m_btIt.key())) ++m_btIt; if (m_btIt == m_bt.end() ) { - btStatus->setText(tr("complete.")); + btStatus->setText(tr("complete.")); return; } setReceiverStatus( m_btIt.key(), tr("Start sending") ); @@ -187,7 +187,8 @@ void SendWidget::send_to_receivers() { void SendWidget::scan_for_receivers() { - //FIXME: Clean ListBox prior to (re)scan + receiverList->clear(); + receivers.clear(); sendButton->setDisabled( true ); if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) @@ -219,21 +220,22 @@ void SendWidget::toggle_receiver(QListViewItem* item) { // toggle the state of an individual receiver. if(item->pixmap(2)) - item->setPixmap(2,QPixmap()); + item->setPixmap(2,QPixmap()); else - item->setPixmap(2,Resource::loadPixmap("backup/check.png")); + item->setPixmap(2,Resource::loadPixmap("backup/check.png")); } void SendWidget::closeEvent( QCloseEvent* e) { - e->accept(); // make sure - QTimer::singleShot(0, this, SLOT(userDone() ) ); -} -void SendWidget::userDone() { + obexSendBase::closeEvent(e); QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); - emit done(); } + +void SendWidget::userDone() { + close(); +} + QString SendWidget::file()const { return m_file; } -- cgit v0.9.0.2