summaryrefslogtreecommitdiff
path: root/libopie2
authormickeyl <mickeyl>2005-07-15 19:50:35 (UTC)
committer mickeyl <mickeyl>2005-07-15 19:50:35 (UTC)
commit637271751ea243456c9c00319e59675f47dcc022 (patch) (unidiff)
treeb17c488a688da6aa004991206d1b2b0aae2f40c7 /libopie2
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 (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiebluez/obluetooth.cpp137
-rw-r--r--libopie2/opiebluez/obluetooth.h20
2 files changed, 146 insertions, 11 deletions
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
@@ -192,60 +192,183 @@ bool OBluetoothInterface::isUp() const
192} 192}
193 193
194OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood() 194OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood()
195{ 195{
196 _devices.clear(); 196 _devices.clear();
197 struct hci_inquiry_req* ir; 197 struct hci_inquiry_req* ir;
198 int nrsp = 255; 198 int nrsp = 255;
199 199
200 char* mybuffer = static_cast<char*>( malloc( sizeof( *ir ) + ( sizeof( inquiry_info ) * (nrsp) ) ) ); 200 char* mybuffer = static_cast<char*>( malloc( sizeof( *ir ) + ( sizeof( inquiry_info ) * (nrsp) ) ) );
201 assert( mybuffer ); 201 assert( mybuffer );
202 202
203 ir = (struct hci_inquiry_req*) mybuffer; 203 ir = (struct hci_inquiry_req*) mybuffer;
204 memset( ir, 0, sizeof( *ir ) + ( sizeof( inquiry_info ) * (nrsp) ) ); 204 memset( ir, 0, sizeof( *ir ) + ( sizeof( inquiry_info ) * (nrsp) ) );
205 205
206 ir->dev_id = d->devinfo.dev_id; 206 ir->dev_id = d->devinfo.dev_id;
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;
212 ir->lap[2] = 0x9e; 212 ir->lap[2] = 0x9e;
213 213
214 int result = ::ioctl( d->ctlfd, HCIINQUIRY, mybuffer ); 214 int result = ::ioctl( d->ctlfd, HCIINQUIRY, mybuffer );
215 if ( result == -1 ) 215 if ( result == -1 )
216 { 216 {
217 owarn << "OBluetoothInterface::neighbourhood() - can't issue HCIINQUIRY (" << strerror( errno ) << ")" << oendl; 217 owarn << "OBluetoothInterface::neighbourhood() - can't issue HCIINQUIRY (" << strerror( errno ) << ")" << oendl;
218 return DeviceIterator( _devices ); 218 return DeviceIterator( _devices );
219 } 219 }
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 }
225 229
226 return DeviceIterator( _devices ); 230 return DeviceIterator( _devices );
227} 231}
228 232
229
230/*====================================================================================== 233/*======================================================================================
231 * OBluetoothDevice 234 * OBluetoothDevice
232 *======================================================================================*/ 235 *======================================================================================*/
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 )
236{ 249{
237 odebug << "OBluetoothDevice::OBluetoothDevice() - '" << name << "'" << oendl; 250 odebug << "OBluetoothDevice::OBluetoothDevice() - '" << name << "'" << oendl;
251 d = new OBluetoothDevice::Private( (inquiry_info*) inqinfo );
238} 252}
239 253
240OBluetoothDevice::~OBluetoothDevice() 254OBluetoothDevice::~OBluetoothDevice()
241{ 255{
242 odebug << "OBluetoothDevice::~OBluetoothDevice()" << oendl; 256 odebug << "OBluetoothDevice::~OBluetoothDevice()" << oendl;
243} 257}
244 258
245QString OBluetoothDevice::macAddress() const 259QString 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}
251} 374}
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
@@ -117,71 +117,83 @@ class OBluetoothInterface : public QObject
117 Q_OBJECT 117 Q_OBJECT
118 public: 118 public:
119 typedef QDict<OBluetoothDevice> DeviceMap; 119 typedef QDict<OBluetoothDevice> DeviceMap;
120 typedef QDictIterator<OBluetoothDevice> DeviceIterator; 120 typedef QDictIterator<OBluetoothDevice> DeviceIterator;
121 121
122 public: 122 public:
123 /** 123 /**
124 * Constructor. Normally you don't create @ref OBluetoothInterface objects yourself, 124 * Constructor. Normally you don't create @ref OBluetoothInterface objects yourself,
125 * but access them via @ref OBluetooth::interface(). 125 * but access them via @ref OBluetooth::interface().
126 */ 126 */
127 OBluetoothInterface( QObject* parent, const char* name, void* devinfo, int ctlfd ); 127 OBluetoothInterface( QObject* parent, const char* name, void* devinfo, int ctlfd );
128 /** 128 /**
129 * Destructor. 129 * Destructor.
130 */ 130 */
131 virtual ~OBluetoothInterface(); 131 virtual ~OBluetoothInterface();
132 /** 132 /**
133 * @return the MAC address of the interfaces 133 * @return the MAC address of the interface.
134 */ 134 */
135 QString macAddress() const; 135 QString macAddress() const;
136 /** 136 /**
137 * Setting an interface to up enables it to receive packets. 137 * Setting an interface to up enables it to receive packets.
138 */ 138 */
139 bool setUp( bool ); 139 bool setUp( bool );
140 /** 140 /**
141 * @returns true if the interface is up. 141 * @returns true if the interface is up.
142 */ 142 */
143 bool isUp() const; 143 bool isUp() const;
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 */
147 DeviceIterator neighbourhood(); 147 DeviceIterator neighbourhood();
148 148
149 private: 149 private:
150 DeviceMap _devices; 150 DeviceMap _devices;
151 class Private; 151 class Private;
152 Private *d; 152 Private *d;
153}; 153};
154 154
155/*====================================================================================== 155/*======================================================================================
156 * OBluetoothDevice 156 * OBluetoothDevice
157 *======================================================================================*/ 157 *======================================================================================*/
158 158
159/** 159/**
160 * @brief An bluetooth (remote) device abstraction. 160 * @brief An bluetooth (remote) device abstraction.
161 * 161 *
162 * This class resembles a (remote) bluetooth device. 162 * This class resembles a (remote) bluetooth device.
163 * @author Michael 'Mickey' Lauer <mickey@vanille.de> 163 * @author Michael 'Mickey' Lauer <mickey@vanille.de>
164 */ 164 */
165class OBluetoothDevice : public QObject 165class OBluetoothDevice : public QObject
166{ 166{
167 Q_OBJECT 167 Q_OBJECT
168 168
169 public: 169 public:
170 /** 170 /**
171 * Constructor. 171 * Constructor.
172 */ 172 */
173 OBluetoothDevice( QObject* parent, const char* name ); 173 OBluetoothDevice( QObject* parent, const char* name, void* inqinfo );
174 /** 174 /**
175 * Destructor. 175 * Destructor.
176 */ 176 */
177 virtual ~OBluetoothDevice(); 177 virtual ~OBluetoothDevice();
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};
183 195
184} 196}
185} 197}
186#endif 198#endif
187 199