summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-07-15 19:50:35 (UTC)
committer mickeyl <mickeyl>2005-07-15 19:50:35 (UTC)
commit637271751ea243456c9c00319e59675f47dcc022 (patch) (unidiff)
treeb17c488a688da6aa004991206d1b2b0aae2f40c7
parent72224480ec012cf8d68608aea5a1b035f4d16895 (diff)
downloadopie-637271751ea243456c9c00319e59675f47dcc022.zip
opie-637271751ea243456c9c00319e59675f47dcc022.tar.gz
opie-637271751ea243456c9c00319e59675f47dcc022.tar.bz2
opiebluez: add scanning.
Ok, guys, everything until now was easy. It gets very ugly to go from here - even to just get the name of a remote device, you have to setup some filters on the bluez socket, fill in some random flags to generate a PDU that calls 'get name' and then afterwards poll until the result comes in. Nasty :/ The BlueZ kernel interface seems to be very badly (if at all) documented. All people are assuming that you use libbluetooth to talk to that stack. However since libbluetooth is GPL, we can't do that :/ Guess, we are stuck here until someone finds time and/or motivation to look into that and create some easy-to-understand examples for how to talk directly to the BlueZ kernel interface.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--examples/opiebluez/oblueztest/main.cpp17
-rw-r--r--libopie2/opiebluez/obluetooth.cpp137
-rw-r--r--libopie2/opiebluez/obluetooth.h20
3 files changed, 160 insertions, 14 deletions
diff --git a/examples/opiebluez/oblueztest/main.cpp b/examples/opiebluez/oblueztest/main.cpp
index 361dbd8..6c2ca75 100644
--- a/examples/opiebluez/oblueztest/main.cpp
+++ b/examples/opiebluez/oblueztest/main.cpp
@@ -9,3 +9,2 @@ int main( int argc, char** argv )
9 OBluetooth* sys = OBluetooth::instance(); 9 OBluetooth* sys = OBluetooth::instance();
10
11 OBluetooth::InterfaceIterator it = sys->iterator(); 10 OBluetooth::InterfaceIterator it = sys->iterator();
@@ -15,5 +14,17 @@ int main( int argc, char** argv )
15 odebug << "APP: Bluetooth host controller interface '" << it.current()->name() << "' has MAC '" << it.current()->macAddress() << "'" << oendl; 14 odebug << "APP: Bluetooth host controller interface '" << it.current()->name() << "' has MAC '" << it.current()->macAddress() << "'" << oendl;
16 odebug << "APP: Interface is " << ( it.current()->isUp() ? "UP" : "DOWN" ) << ". Trying to toggle state..." << oendl;
17 it.current()->setUp( !it.current()->isUp() );
18 odebug << "APP: Interface is " << ( it.current()->isUp() ? "UP" : "DOWN" ) << "." << oendl; 15 odebug << "APP: Interface is " << ( it.current()->isUp() ? "UP" : "DOWN" ) << "." << oendl;
16 //odebug << "APP: Trying to toggle state..." << oendl;
17 //it.current()->setUp( !it.current()->isUp() );
18 //odebug << "APP: Interface is " << ( it.current()->isUp() ? "UP" : "DOWN" ) << "." << oendl;
19
20 odebug << "APP: scanning..." << oendl;
21
22 OBluetoothInterface::DeviceIterator devit = it.current()->neighbourhood();
23 while( devit.current() )
24 {
25 odebug << "APP: Neighbourhood '" << devit.current()->name() << "' has MAC '" << devit.current()->macAddress() << "'" << oendl;
26 odebug << "APP: Neighbourhood '" << devit.current()->name() << "' has class '" << devit.current()->deviceClass() << "'" << oendl;
27 ++devit;
28 }
29
19 ++it; 30 ++it;
diff --git a/libopie2/opiebluez/obluetooth.cpp b/libopie2/opiebluez/obluetooth.cpp
index e0ba0ec..80f4bfc 100644
--- a/libopie2/opiebluez/obluetooth.cpp
+++ b/libopie2/opiebluez/obluetooth.cpp
@@ -207,5 +207,5 @@ OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood()
207 ir->num_rsp = nrsp; 207 ir->num_rsp = nrsp;
208 ir->length = 8; 208 ir->length = 8; // 10 seconds
209 ir->flags = 0; 209 ir->flags = 0;
210 ir->lap[0] = 0x33; 210 ir->lap[0] = 0x33; // GIAC
211 ir->lap[1] = 0x8b; 211 ir->lap[1] = 0x8b;
@@ -220,5 +220,9 @@ OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood()
220 220
221 for( int i = 0; i < ir->num_rsp; ++i ) 221 inquiry_info* ii = (inquiry_info*)( ir+1 );
222
223 for ( int i = 0; i < ir->num_rsp; ++i )
222 { 224 {
223 odebug << "found a device" << oendl; 225 OBluetoothDevice* dev = new OBluetoothDevice( this, 0, ii );
226 _devices.insert( dev->macAddress(), dev );
227 ++ii;
224 } 228 }
@@ -228,3 +232,2 @@ OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood()
228 232
229
230/*====================================================================================== 233/*======================================================================================
@@ -233,3 +236,13 @@ OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood()
233 236
234OBluetoothDevice::OBluetoothDevice( QObject* parent, const char* name ) 237class OBluetoothDevice::Private
238{
239 public:
240 Private( inquiry_info* ii )
241 {
242 ::memcpy( &inqinfo, ii, sizeof(inquiry_info) );
243 }
244 inquiry_info inqinfo;
245};
246
247OBluetoothDevice::OBluetoothDevice( QObject* parent, const char* name, void* inqinfo )
235 :QObject( parent, name ) 248 :QObject( parent, name )
@@ -237,2 +250,3 @@ OBluetoothDevice::OBluetoothDevice( QObject* parent, const char* name )
237 odebug << "OBluetoothDevice::OBluetoothDevice() - '" << name << "'" << oendl; 250 odebug << "OBluetoothDevice::OBluetoothDevice() - '" << name << "'" << oendl;
251 d = new OBluetoothDevice::Private( (inquiry_info*) inqinfo );
238} 252}
@@ -246,5 +260,114 @@ QString OBluetoothDevice::macAddress() const
246{ 260{
247 return "N/A"; 261 return QString().sprintf( "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
262 d->inqinfo.bdaddr.b[5],
263 d->inqinfo.bdaddr.b[4],
264 d->inqinfo.bdaddr.b[3],
265 d->inqinfo.bdaddr.b[2],
266 d->inqinfo.bdaddr.b[1],
267 d->inqinfo.bdaddr.b[0] );
268}
269
270QString OBluetoothDevice::deviceClass() const
271{
272 int maj = d->inqinfo.dev_class[1] & 0x1f;
273 int min = d->inqinfo.dev_class[0] >> 2;
274
275 QString major = QString( "Unknown(%1)" ).arg( maj );
276 QString minor = QString( "Unknown(%1)" ).arg( min );
277
278 switch ( maj )
279 {
280 case 0: major = "Miscellaneous";
281 break;
282
283 case 1: major = "Computer";
284 switch ( min )
285 {
286 case 0: minor = "Uncategorized";
287 case 1: minor = "Desktop workstation";
288 case 2: minor = "Server";
289 case 3: minor = "Laptop";
290 case 4: minor = "Handheld";
291 case 5: minor = "Palm";
292 case 6: minor = "Wearable";
293 }
294 break;
295
296 case 2: major = "Phone";
297 switch ( min )
298 {
299 case 0: minor = "Uncategorized"; break;
300 case 1: minor = "Cellular"; break;
301 case 2: minor = "Cordless"; break;
302 case 3: minor = "Smart phone"; break;
303 case 4: minor = "Wired modem or voice gateway"; break;
304 case 5: minor = "Common ISDN Access"; break;
305 case 6: minor = "Sim Card Reader"; break;
306 }
307 break;
308
309 case 3: major = "LAN Access";
310 break;
311
312 case 4: major = "Audio/Video";
313 switch ( min )
314 {
315 case 0: minor = "Uncategorized"; break;
316 case 1: minor = "Device conforms to the Headset profile"; break;
317 case 2: minor = "Hands-free"; break;
318 case 3: minor = "Reserved(3)"; break;
319 case 4: minor = "Microphone"; break;
320 case 5: minor = "Loudspeaker"; break;
321 case 6: minor = "Headphones"; break;
322 case 7: minor = "Portable Audio"; break;
323 case 8: minor = "Car Audio"; break;
324 case 9: minor = "Set-top box"; break;
325 case 10: minor = "HiFi Audio Device"; break;
326 case 11: minor = "VCR"; break;
327 case 12: minor = "Video Camera"; break;
328 case 13: minor = "Camcorder"; break;
329 case 14: minor = "Video Monitor"; break;
330 case 15: minor = "Video Display and Loudspeaker"; break;
331 case 16: minor = "Video Conferencing"; break;
332 case 17: minor = "Reserved(17)"; break;
333 case 18: minor = "Gaming/Toy"; break;
334 }
335 break;
336
337 case 5: major = "Peripheral";
338 switch ( min )
339 {
340 case 16: minor = "Keyboard"; break;
341 case 32: minor = "Pointing Device"; break;
342 case 48: minor = "Keyboard and Pointing Device"; break;
343 }
344 break;
345
346 case 6: major = "Imaging";
347 if (min & 4) minor = "Display";
348 else if (min & 8) minor = "Camera";
349 else if (min & 16) minor = "Scanner";
350 else if (min & 32) minor = "Printer";
351 break;
352
353 case 63: major = "Uncategorized";
354 break;
355 }
356
357 return QString( "%1:%2" ).arg( major ).arg( minor );
248} 358}
249 359
360QString OBluetoothDevice::getName()
361{
362 /* FIXME: Uahhh, this gets ugly.
363 The BlueZ kernel interface seems to be very badly (if at all) documented.
364 All people are assuming that you use libbluetooth to talk to that stack.
365 However since libbluetooth is GPL, we can't do that :/
366 Guess, we are stuck here until someone finds time and/or motivation to look
367 into that and create some easy-to-understand examples for how to talk
368 directly to the BlueZ kernel interface.
369 */
370};
371
372
250} 373}
diff --git a/libopie2/opiebluez/obluetooth.h b/libopie2/opiebluez/obluetooth.h
index ee4a90d..fa3d2c1 100644
--- a/libopie2/opiebluez/obluetooth.h
+++ b/libopie2/opiebluez/obluetooth.h
@@ -132,3 +132,3 @@ class OBluetoothInterface : public QObject
132 /** 132 /**
133 * @return the MAC address of the interfaces 133 * @return the MAC address of the interface.
134 */ 134 */
@@ -144,3 +144,3 @@ class OBluetoothInterface : public QObject
144 /** 144 /**
145 * @returns an iterator usable for iterating through the devices in range 145 * @returns an iterator usable for iterating through the devices in range.
146 */ 146 */
@@ -172,3 +172,3 @@ class OBluetoothDevice : public QObject
172 */ 172 */
173 OBluetoothDevice( QObject* parent, const char* name ); 173 OBluetoothDevice( QObject* parent, const char* name, void* inqinfo );
174 /** 174 /**
@@ -178,5 +178,17 @@ class OBluetoothDevice : public QObject
178 /** 178 /**
179 * @returns the MAC address of the device's interface 179 * @returns the MAC address of the device's interface.
180 */ 180 */
181 QString macAddress() const; 181 QString macAddress() const;
182 /**
183 * @returns the class of device.
184 */
185 QString deviceClass() const;
186 /**
187 * @returns the device name.
188 */
189 QString getName();
190
191 private:
192 class Private;
193 Private *d;
182}; 194};