From d5b6868cb4f99d2c3dc3587115cd37c09e4610eb Mon Sep 17 00:00:00 2001
From: mickeyl <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/obex')

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 <manager.h>
+#include <services.h>
 
 /* OPIE */
 #include <opie2/oprocess.h>
@@ -7,13 +9,15 @@
 
 /* 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 )
@@ -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<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(){
     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 <bdaddr> [channel]
-    // 9 for phones.
-    // Palm T3 accepts pictures on 1
-    *m_send << "obextool" << "push";
+    // ussp-push --timeo 30 <btaddr:port> 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 <qobject.h>
+#include <services.h>
+#include <manager.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 {
@@ -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 <qpushbutton.h>
 #include <qpixmap.h>
 #include <qlistview.h>
-#include <qtimer.h>
 
+#include <unistd.h>
 /* 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