author | mickeyl <mickeyl> | 2006-05-02 08:57:25 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2006-05-02 08:57:25 (UTC) |
commit | d5b6868cb4f99d2c3dc3587115cd37c09e4610eb (patch) (unidiff) | |
tree | 1397f12f885c849419e511ad203d19696c4ae07e /core | |
parent | 1295db77f2ab7e9125183e4240de0b92f72940e4 (diff) | |
download | opie-d5b6868cb4f99d2c3dc3587115cd37c09e4610eb.zip opie-d5b6868cb4f99d2c3dc3587115cd37c09e4610eb.tar.gz opie-d5b6868cb4f99d2c3dc3587115cd37c09e4610eb.tar.bz2 |
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.
-rw-r--r-- | core/obex/btobex.cpp | 85 | ||||
-rw-r--r-- | core/obex/btobex.h | 8 | ||||
-rw-r--r-- | core/obex/obex.pro | 4 | ||||
-rw-r--r-- | core/obex/obexsend.cpp | 26 |
4 files changed, 94 insertions, 29 deletions
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,20 +1,24 @@ | |||
1 | 1 | ||
2 | #include "btobex.h" | 2 | #include "btobex.h" |
3 | #include <manager.h> | ||
4 | #include <services.h> | ||
3 | 5 | ||
4 | /* OPIE */ | 6 | /* OPIE */ |
5 | #include <opie2/oprocess.h> | 7 | #include <opie2/oprocess.h> |
6 | #include <opie2/odebug.h> | 8 | #include <opie2/odebug.h> |
7 | 9 | ||
8 | /* QT */ | 10 | /* QT */ |
9 | #include <qfileinfo.h> | 11 | #include <qfileinfo.h> |
10 | 12 | #include <qstring.h> | |
11 | 13 | #include <qmap.h> | |
14 | #include <qmessagebox.h> | ||
12 | 15 | ||
13 | using namespace OpieObex; | 16 | using namespace OpieObex; |
14 | 17 | ||
15 | using namespace Opie::Core; | 18 | using namespace Opie::Core; |
16 | /* TRANSLATOR OpieObex::Obex */ | 19 | /* TRANSLATOR OpieObex::Obex */ |
20 | using namespace OpieTooth; | ||
17 | 21 | ||
18 | BtObex::BtObex( QObject *parent, const char* name ) | 22 | BtObex::BtObex( QObject *parent, const char* name ) |
19 | : QObject(parent, name ) | 23 | : QObject(parent, name ) |
20 | { | 24 | { |
@@ -25,13 +29,18 @@ BtObex::BtObex( QObject *parent, const char* name ) | |||
25 | connect( this, SIGNAL(error(int) ), // for recovering to receive | 29 | connect( this, SIGNAL(error(int) ), // for recovering to receive |
26 | SLOT(slotError() ) ); | 30 | SLOT(slotError() ) ); |
27 | connect( this, SIGNAL(sent(bool) ), | 31 | connect( this, SIGNAL(sent(bool) ), |
28 | SLOT(slotError() ) ); | 32 | SLOT(slotError() ) ); |
33 | btManager = NULL; | ||
29 | }; | 34 | }; |
35 | |||
30 | BtObex::~BtObex() { | 36 | BtObex::~BtObex() { |
37 | if (btManager) | ||
38 | delete btManager; | ||
31 | delete m_rec; | 39 | delete m_rec; |
32 | delete m_send; | 40 | delete m_send; |
33 | } | 41 | } |
42 | |||
34 | void BtObex::receive() { | 43 | void BtObex::receive() { |
35 | m_receive = true; | 44 | m_receive = true; |
36 | m_outp = QString::null; | 45 | m_outp = QString::null; |
37 | m_rec = new OProcess(); | 46 | m_rec = new OProcess(); |
@@ -67,35 +76,80 @@ void BtObex::send( const QString& fileName, const QString& bdaddr) { | |||
67 | emit error( -1 ); // we did not delete yet but it's not running slotExited is pending | 76 | emit error( -1 ); // we did not delete yet but it's not running slotExited is pending |
68 | return; | 77 | return; |
69 | } | 78 | } |
70 | } | 79 | } |
80 | //Now we need to find out if the OBEX push is supported for this device | ||
81 | //And get the port number | ||
82 | if (!btManager) { | ||
83 | btManager = new Manager("hci0"); | ||
84 | connect(btManager, | ||
85 | SIGNAL(foundServices(const QString&, Services::ValueList)), | ||
86 | this, SLOT(slotFoundServices(const QString&, Services::ValueList))); | ||
87 | } | ||
88 | btManager->searchServices(bdaddr); | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * This function reacts on the service discovery finish | ||
93 | */ | ||
94 | void BtObex::slotFoundServices(const QString&, Services::ValueList svcList) | ||
95 | { | ||
96 | QValueList<OpieTooth::Services>::Iterator it; | ||
97 | QMap<int, QString> classList; //The classes list | ||
98 | QMap<int, QString>::Iterator classIt; //Iterator in the class list | ||
99 | int portNum = -1; //The desired port number | ||
100 | odebug << "BtObex slotFoundServices" << oendl; | ||
101 | if (svcList.isEmpty()) { | ||
102 | QMessageBox::critical(NULL, tr("Object send"), tr("No services found")); | ||
103 | emit error(-1); | ||
104 | return; | ||
105 | } | ||
106 | for (it = svcList.begin(); it != svcList.end(); it++) { | ||
107 | classList = (*it).classIdList(); | ||
108 | classIt = classList.begin(); | ||
109 | if (classIt == classList.end()) | ||
110 | continue; | ||
111 | ////We really need symbolic names for service IDs | ||
112 | //Ok, we have found the object push service | ||
113 | if (classIt.key() == 4357) { | ||
114 | portNum = (*it).protocolDescriptorList().last().port(); | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | if (portNum == -1) { | ||
119 | QMessageBox::critical(NULL, tr("Object send"), | ||
120 | tr("No OBEX Push service")); | ||
121 | emit error(-1); | ||
122 | return; | ||
123 | } | ||
124 | m_port = portNum; | ||
71 | sendNow(); | 125 | sendNow(); |
72 | } | 126 | } |
127 | |||
73 | void BtObex::sendNow(){ | 128 | void BtObex::sendNow(){ |
74 | if ( m_count >= 25 ) { // could not send | 129 | if ( m_count >= 25 ) { // could not send |
75 | emit error(-1 ); | 130 | emit error(-1 ); |
76 | emit sent(false); | 131 | emit sent(false); |
77 | return; | 132 | return; |
78 | } | 133 | } |
79 | // OProcess inititialisation | 134 | // OProcess inititialisation |
80 | m_send = new OProcess(); | 135 | m_send = new OProcess(0, "ussp-push"); |
81 | m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) ); | 136 | m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) ); |
82 | 137 | ||
83 | // obextool push file <bdaddr> [channel] | 138 | // ussp-push --timeo 30 <btaddr:port> file file |
84 | // 9 for phones. | 139 | *m_send << "ussp-push" << "--timeo 30"; |
85 | // Palm T3 accepts pictures on 1 | 140 | *m_send << m_bdaddr + "@" + QString::number(m_port); |
86 | *m_send << "obextool" << "push"; | ||
87 | *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); | 141 | *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); |
88 | *m_send << m_bdaddr << "9"; | 142 | *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); |
89 | 143 | m_send->setUseShell(true); | |
144 | |||
90 | // connect to slots Exited and and StdOut | 145 | // connect to slots Exited and and StdOut |
91 | connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ), | 146 | connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ), |
92 | this, SLOT(slotExited(Opie::Core::OProcess*)) ); | 147 | this, SLOT(slotExited(Opie::Core::OProcess*)) ); |
93 | connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int )), | 148 | connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int)), |
94 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); | 149 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); |
95 | |||
96 | // now start it | 150 | // now start it |
97 | if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { | 151 | if (!m_send->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { |
98 | m_count = 25; | 152 | m_count = 25; |
99 | emit error(-1 ); | 153 | emit error(-1 ); |
100 | delete m_send; | 154 | delete m_send; |
101 | m_send=0; | 155 | m_send=0; |
@@ -105,8 +159,10 @@ void BtObex::sendNow(){ | |||
105 | emit currentTry( m_count ); | 159 | emit currentTry( m_count ); |
106 | } | 160 | } |
107 | 161 | ||
108 | void BtObex::slotExited(OProcess* proc ){ | 162 | void BtObex::slotExited(OProcess* proc ){ |
163 | odebug << proc->name() << " exited with result " | ||
164 | << proc->exitStatus() << oendl; | ||
109 | if (proc == m_rec ) // receive process | 165 | if (proc == m_rec ) // receive process |
110 | received(); | 166 | received(); |
111 | else if ( proc == m_send ) | 167 | else if ( proc == m_send ) |
112 | sendEnd(); | 168 | sendEnd(); |
@@ -139,9 +195,9 @@ void BtObex::sendEnd() { | |||
139 | if ( m_send->exitStatus() == 0 ) { | 195 | if ( m_send->exitStatus() == 0 ) { |
140 | delete m_send; | 196 | delete m_send; |
141 | m_send=0; | 197 | m_send=0; |
142 | emit sent(true); | 198 | emit sent(true); |
143 | }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready | 199 | }else if (m_send->exitStatus() != 0 ) { // it failed maybe the other side wasn't ready |
144 | // let's try it again | 200 | // let's try it again |
145 | delete m_send; | 201 | delete m_send; |
146 | m_send = 0; | 202 | m_send = 0; |
147 | sendNow(); | 203 | sendNow(); |
@@ -153,13 +209,14 @@ void BtObex::sendEnd() { | |||
153 | } | 209 | } |
154 | } | 210 | } |
155 | 211 | ||
156 | // This probably doesn't do anything useful for bt. | 212 | // This probably doesn't do anything useful for bt. |
157 | QString BtObex::parseOut( ){ | 213 | QString BtObex::parseOut(){ |
158 | QString path; | 214 | QString path; |
159 | QStringList list = QStringList::split("\n", m_outp); | 215 | QStringList list = QStringList::split("\n", m_outp); |
160 | QStringList::Iterator it; | 216 | QStringList::Iterator it; |
161 | for (it = list.begin(); it != list.end(); ++it ) { | 217 | for (it = list.begin(); it != list.end(); ++it ) { |
218 | odebug << (*it) << oendl; | ||
162 | if ( (*it).startsWith("Wrote" ) ) { | 219 | if ( (*it).startsWith("Wrote" ) ) { |
163 | int pos = (*it).findRev('(' ); | 220 | int pos = (*it).findRev('(' ); |
164 | if ( pos > 0 ) { | 221 | if ( pos > 0 ) { |
165 | 222 | ||
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 | |||
@@ -3,11 +3,14 @@ | |||
3 | #ifndef OpieBtObex_H | 3 | #ifndef OpieBtObex_H |
4 | #define OpieBtObex_H | 4 | #define OpieBtObex_H |
5 | 5 | ||
6 | #include <qobject.h> | 6 | #include <qobject.h> |
7 | #include <services.h> | ||
8 | #include <manager.h> | ||
7 | 9 | ||
8 | namespace Opie {namespace Core {class OProcess;}} | 10 | namespace Opie {namespace Core {class OProcess;}} |
9 | class QCopChannel; | 11 | class QCopChannel; |
12 | using namespace OpieTooth; | ||
10 | namespace OpieObex { | 13 | namespace OpieObex { |
11 | // Maybe this should be derved from Obex. | 14 | // Maybe this should be derved from Obex. |
12 | class BtObex : public QObject { | 15 | class BtObex : public QObject { |
13 | Q_OBJECT | 16 | Q_OBJECT |
@@ -54,19 +57,22 @@ namespace OpieObex { | |||
54 | uint m_count; | 57 | uint m_count; |
55 | QString m_file; | 58 | QString m_file; |
56 | QString m_outp; | 59 | QString m_outp; |
57 | QString m_bdaddr; | 60 | QString m_bdaddr; |
61 | int m_port; | ||
58 | Opie::Core::OProcess *m_send; | 62 | Opie::Core::OProcess *m_send; |
59 | Opie::Core::OProcess *m_rec; | 63 | Opie::Core::OProcess *m_rec; |
60 | bool m_receive : 1; | 64 | bool m_receive : 1; |
65 | OpieTooth::Manager* btManager; | ||
61 | void shutDownReceive(); | 66 | void shutDownReceive(); |
62 | 67 | ||
63 | private slots: | 68 | private slots: |
64 | 69 | ||
65 | // the process exited | 70 | // the process exited |
66 | void slotExited(Opie::Core::OProcess* proc) ; | 71 | void slotExited(Opie::Core::OProcess*) ; |
67 | void slotStdOut(Opie::Core::OProcess*, char*, int); | 72 | void slotStdOut(Opie::Core::OProcess*, char*, int); |
68 | void slotError(); | 73 | void slotError(); |
74 | void slotFoundServices(const QString&, Services::ValueList); | ||
69 | 75 | ||
70 | private: | 76 | private: |
71 | void sendNow(); | 77 | void sendNow(); |
72 | QString parseOut(); | 78 | QString parseOut(); |
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 | |||
@@ -4,11 +4,11 @@ HEADERS = obex.h btobex.h obexhandler.h obexsend.h receiver.h obeximpl.h | |||
4 | SOURCES= obex.cpp btobex.cpp obexsend.cpp obexhandler.cpp receiver.cpp obeximpl.cpp | 4 | SOURCES= obex.cpp btobex.cpp obexsend.cpp obexhandler.cpp receiver.cpp obeximpl.cpp |
5 | TARGET = opieobex | 5 | TARGET = opieobex |
6 | DESTDIR = $(OPIEDIR)/plugins/obex | 6 | DESTDIR = $(OPIEDIR)/plugins/obex |
7 | INTERFACES = obexsendbase.ui | 7 | INTERFACES = obexsendbase.ui |
8 | INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher | 8 | INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher $(OPIEDIR)/noncore/net/opietooth/lib |
9 | DEPENDPATH += | 9 | DEPENDPATH += |
10 | LIBS += -lqpe -lopiecore2 | 10 | LIBS += -lopietooth1 -lqpe -lopiecore2 |
11 | VERSION = 0.0.3 | 11 | VERSION = 0.0.3 |
12 | 12 | ||
13 | include( $(OPIEDIR)/include.pro ) | 13 | include( $(OPIEDIR)/include.pro ) |
14 | target.path = $$prefix/plugins/applets | 14 | target.path = $$prefix/plugins/applets |
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 | |||
@@ -19,10 +19,10 @@ using namespace Opie::Core; | |||
19 | #include <qlabel.h> | 19 | #include <qlabel.h> |
20 | #include <qpushbutton.h> | 20 | #include <qpushbutton.h> |
21 | #include <qpixmap.h> | 21 | #include <qpixmap.h> |
22 | #include <qlistview.h> | 22 | #include <qlistview.h> |
23 | #include <qtimer.h> | ||
24 | 23 | ||
24 | #include <unistd.h> | ||
25 | /* TRANSLATOR OpieObex::SendWidget */ | 25 | /* TRANSLATOR OpieObex::SendWidget */ |
26 | 26 | ||
27 | SendWidget::SendWidget( QWidget* parent, const char* name ) | 27 | SendWidget::SendWidget( QWidget* parent, const char* name ) |
28 | : obexSendBase( parent, name ) { | 28 | : obexSendBase( parent, name ) { |
@@ -82,9 +82,9 @@ int SendWidget::addReceiver(const char *r, const char *icon) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | bool SendWidget::receiverSelected(int id) | 84 | bool SendWidget::receiverSelected(int id) |
85 | { | 85 | { |
86 | return receivers[id]->pixmap(2); | 86 | return (bool)(receivers[id]->pixmap(2) != NULL); |
87 | } | 87 | } |
88 | 88 | ||
89 | void SendWidget::setReceiverStatus( int id, const QString& status ) { | 89 | void SendWidget::setReceiverStatus( int id, const QString& status ) { |
90 | if ( !receivers.contains(id) ) return; | 90 | if ( !receivers.contains(id) ) return; |
@@ -140,9 +140,9 @@ void SendWidget::slotIrTry(unsigned int trI) { | |||
140 | } | 140 | } |
141 | void SendWidget::slotStartIrda() { | 141 | void SendWidget::slotStartIrda() { |
142 | if ( !m_irDa.count() ) return; | 142 | if ( !m_irDa.count() ) return; |
143 | if ( m_irDaIt == m_irDa.end() ) { | 143 | if ( m_irDaIt == m_irDa.end() ) { |
144 | irdaStatus->setText(tr("complete.")); | 144 | irdaStatus->setText(tr("complete.")); |
145 | return; | 145 | return; |
146 | } | 146 | } |
147 | setReceiverStatus( m_irDaIt.key(), tr("Start sending") ); | 147 | setReceiverStatus( m_irDaIt.key(), tr("Start sending") ); |
148 | m_obex->send( m_file ); | 148 | m_obex->send( m_file ); |
@@ -172,9 +172,9 @@ void SendWidget::slotStartBt() { | |||
172 | // skip past unselected receivers | 172 | // skip past unselected receivers |
173 | while((m_btIt != m_bt.end()) && !receiverSelected(m_btIt.key())) | 173 | while((m_btIt != m_bt.end()) && !receiverSelected(m_btIt.key())) |
174 | ++m_btIt; | 174 | ++m_btIt; |
175 | if (m_btIt == m_bt.end() ) { | 175 | if (m_btIt == m_bt.end() ) { |
176 | btStatus->setText(tr("complete.")); | 176 | btStatus->setText(tr("complete.")); |
177 | return; | 177 | return; |
178 | } | 178 | } |
179 | setReceiverStatus( m_btIt.key(), tr("Start sending") ); | 179 | setReceiverStatus( m_btIt.key(), tr("Start sending") ); |
180 | m_btobex->send( m_file, m_btIt.data().second() ); | 180 | m_btobex->send( m_file, m_btIt.data().second() ); |
@@ -186,9 +186,10 @@ void SendWidget::send_to_receivers() { | |||
186 | } | 186 | } |
187 | 187 | ||
188 | void SendWidget::scan_for_receivers() | 188 | void SendWidget::scan_for_receivers() |
189 | { | 189 | { |
190 | //FIXME: Clean ListBox prior to (re)scan | 190 | receiverList->clear(); |
191 | receivers.clear(); | ||
191 | sendButton->setDisabled( true ); | 192 | sendButton->setDisabled( true ); |
192 | 193 | ||
193 | if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) | 194 | if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) |
194 | { | 195 | { |
@@ -218,22 +219,23 @@ void SendWidget::scan_for_receivers() | |||
218 | void SendWidget::toggle_receiver(QListViewItem* item) | 219 | void SendWidget::toggle_receiver(QListViewItem* item) |
219 | { | 220 | { |
220 | // toggle the state of an individual receiver. | 221 | // toggle the state of an individual receiver. |
221 | if(item->pixmap(2)) | 222 | if(item->pixmap(2)) |
222 | item->setPixmap(2,QPixmap()); | 223 | item->setPixmap(2,QPixmap()); |
223 | else | 224 | else |
224 | item->setPixmap(2,Resource::loadPixmap("backup/check.png")); | 225 | item->setPixmap(2,Resource::loadPixmap("backup/check.png")); |
225 | } | 226 | } |
226 | 227 | ||
227 | 228 | ||
228 | void SendWidget::closeEvent( QCloseEvent* e) { | 229 | void SendWidget::closeEvent( QCloseEvent* e) { |
229 | e->accept(); // make sure | 230 | obexSendBase::closeEvent(e); |
230 | QTimer::singleShot(0, this, SLOT(userDone() ) ); | ||
231 | } | ||
232 | void SendWidget::userDone() { | ||
233 | QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); | 231 | QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); |
234 | QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); | 232 | QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); |
235 | emit done(); | ||
236 | } | 233 | } |
234 | |||
235 | void SendWidget::userDone() { | ||
236 | close(); | ||
237 | } | ||
238 | |||
237 | QString SendWidget::file()const { | 239 | QString SendWidget::file()const { |
238 | return m_file; | 240 | return m_file; |
239 | } | 241 | } |