-rw-r--r-- | examples/opiebluez/oblueztest/main.cpp | 17 | ||||
-rw-r--r-- | libopie2/opiebluez/obluetooth.cpp | 137 | ||||
-rw-r--r-- | libopie2/opiebluez/obluetooth.h | 20 |
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 | |||
@@ -1,23 +1,34 @@ | |||
1 | #include <opie2/odebug.h> | 1 | #include <opie2/odebug.h> |
2 | #include <opie2/obluetooth.h> | 2 | #include <opie2/obluetooth.h> |
3 | 3 | ||
4 | using namespace Opie::Core; | 4 | using namespace Opie::Core; |
5 | using namespace Opie::Bluez; | 5 | using namespace Opie::Bluez; |
6 | 6 | ||
7 | int main( int argc, char** argv ) | 7 | int main( int argc, char** argv ) |
8 | { | 8 | { |
9 | OBluetooth* sys = OBluetooth::instance(); | 9 | OBluetooth* sys = OBluetooth::instance(); |
10 | |||
11 | OBluetooth::InterfaceIterator it = sys->iterator(); | 10 | OBluetooth::InterfaceIterator it = sys->iterator(); |
12 | 11 | ||
13 | while( it.current() ) | 12 | while( it.current() ) |
14 | { | 13 | { |
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; |
20 | } | 31 | } |
21 | return 0; | 32 | return 0; |
22 | } | 33 | } |
23 | 34 | ||
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 | |||
@@ -1,251 +1,374 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> | 3 | Copyright (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; version 2 of the license. | 11 | - . .-<_> .<> Foundation; version 2 of the license. |
12 | ._= =} : | 12 | ._= =} : |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "obluetooth.h" | 30 | #include "obluetooth.h" |
31 | 31 | ||
32 | /* OPIE */ | 32 | /* OPIE */ |
33 | #include <opie2/odebug.h> | 33 | #include <opie2/odebug.h> |
34 | using namespace Opie::Core; | 34 | using namespace Opie::Core; |
35 | 35 | ||
36 | /* STD */ | 36 | /* STD */ |
37 | #include <bluetooth/bluetooth.h> | 37 | #include <bluetooth/bluetooth.h> |
38 | #include <bluetooth/hci.h> | 38 | #include <bluetooth/hci.h> |
39 | #include <bluetooth/hci_lib.h> | 39 | #include <bluetooth/hci_lib.h> |
40 | #include <assert.h> | 40 | #include <assert.h> |
41 | #include <errno.h> | 41 | #include <errno.h> |
42 | #include <stdlib.h> | 42 | #include <stdlib.h> |
43 | #include <string.h> | 43 | #include <string.h> |
44 | #include <unistd.h> | 44 | #include <unistd.h> |
45 | #include <sys/ioctl.h> | 45 | #include <sys/ioctl.h> |
46 | #include <sys/types.h> | 46 | #include <sys/types.h> |
47 | #include <sys/socket.h> | 47 | #include <sys/socket.h> |
48 | 48 | ||
49 | namespace Opie { | 49 | namespace Opie { |
50 | namespace Bluez { | 50 | namespace Bluez { |
51 | 51 | ||
52 | /*====================================================================================== | 52 | /*====================================================================================== |
53 | * OBluetooth | 53 | * OBluetooth |
54 | *======================================================================================*/ | 54 | *======================================================================================*/ |
55 | 55 | ||
56 | OBluetooth* OBluetooth::_instance = 0; | 56 | OBluetooth* OBluetooth::_instance = 0; |
57 | 57 | ||
58 | OBluetooth::OBluetooth() | 58 | OBluetooth::OBluetooth() |
59 | { | 59 | { |
60 | synchronize(); | 60 | synchronize(); |
61 | } | 61 | } |
62 | 62 | ||
63 | OBluetooth* OBluetooth::instance() | 63 | OBluetooth* OBluetooth::instance() |
64 | { | 64 | { |
65 | if ( !_instance ) _instance = new OBluetooth(); | 65 | if ( !_instance ) _instance = new OBluetooth(); |
66 | return _instance; | 66 | return _instance; |
67 | } | 67 | } |
68 | 68 | ||
69 | OBluetooth::InterfaceIterator OBluetooth::iterator() const | 69 | OBluetooth::InterfaceIterator OBluetooth::iterator() const |
70 | { | 70 | { |
71 | return OBluetooth::InterfaceIterator( _interfaces ); | 71 | return OBluetooth::InterfaceIterator( _interfaces ); |
72 | } | 72 | } |
73 | 73 | ||
74 | int OBluetooth::count() const | 74 | int OBluetooth::count() const |
75 | { | 75 | { |
76 | return _interfaces.count(); | 76 | return _interfaces.count(); |
77 | } | 77 | } |
78 | 78 | ||
79 | OBluetoothInterface* OBluetooth::interface( const QString& iface ) const | 79 | OBluetoothInterface* OBluetooth::interface( const QString& iface ) const |
80 | { | 80 | { |
81 | return _interfaces[iface]; | 81 | return _interfaces[iface]; |
82 | } | 82 | } |
83 | 83 | ||
84 | void OBluetooth::synchronize() | 84 | void OBluetooth::synchronize() |
85 | { | 85 | { |
86 | odebug << "OBluetooth::synchronize() - gathering available HCI devices" << oendl; | 86 | odebug << "OBluetooth::synchronize() - gathering available HCI devices" << oendl; |
87 | _interfaces.clear(); | 87 | _interfaces.clear(); |
88 | 88 | ||
89 | _fd = ::socket( AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI ); | 89 | _fd = ::socket( AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI ); |
90 | if ( _fd == -1 ) | 90 | if ( _fd == -1 ) |
91 | { | 91 | { |
92 | owarn << "OBluetooth::synchronize() - can't open HCI control socket (" << strerror( errno ) << ")" << oendl; | 92 | owarn << "OBluetooth::synchronize() - can't open HCI control socket (" << strerror( errno ) << ")" << oendl; |
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
96 | struct hci_dev_list_req *dl; | 96 | struct hci_dev_list_req *dl; |
97 | struct hci_dev_req *dr; | 97 | struct hci_dev_req *dr; |
98 | struct hci_dev_info di; | 98 | struct hci_dev_info di; |
99 | 99 | ||
100 | if (!(dl = (struct hci_dev_list_req*)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) | 100 | if (!(dl = (struct hci_dev_list_req*)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) |
101 | { | 101 | { |
102 | ofatal << "OBluetooth::synchronize() - can't allocate memory for HCI request" << oendl; | 102 | ofatal << "OBluetooth::synchronize() - can't allocate memory for HCI request" << oendl; |
103 | return; | 103 | return; |
104 | } | 104 | } |
105 | 105 | ||
106 | dl->dev_num = HCI_MAX_DEV; | 106 | dl->dev_num = HCI_MAX_DEV; |
107 | dr = dl->dev_req; | 107 | dr = dl->dev_req; |
108 | 108 | ||
109 | if (::ioctl( _fd, HCIGETDEVLIST, (void *) dl) == -1) | 109 | if (::ioctl( _fd, HCIGETDEVLIST, (void *) dl) == -1) |
110 | { | 110 | { |
111 | owarn << "OBluetooth::synchronize() - can't complete HCIGETDEVLIST (" << strerror( errno ) << ")" << oendl; | 111 | owarn << "OBluetooth::synchronize() - can't complete HCIGETDEVLIST (" << strerror( errno ) << ")" << oendl; |
112 | return; | 112 | return; |
113 | } | 113 | } |
114 | 114 | ||
115 | for ( int i = 0; i < dl->dev_num; ++i ) | 115 | for ( int i = 0; i < dl->dev_num; ++i ) |
116 | { | 116 | { |
117 | di.dev_id = ( dr + i )->dev_id; | 117 | di.dev_id = ( dr + i )->dev_id; |
118 | if ( ::ioctl( _fd, HCIGETDEVINFO, (void *) &di ) == -1 ) | 118 | if ( ::ioctl( _fd, HCIGETDEVINFO, (void *) &di ) == -1 ) |
119 | { | 119 | { |
120 | owarn << "OBluetooth::synchronize() - can't issue HCIGETDEVINFO on device " << i << " (" << strerror( errno ) << ") - skipping that device. " << oendl; | 120 | owarn << "OBluetooth::synchronize() - can't issue HCIGETDEVINFO on device " << i << " (" << strerror( errno ) << ") - skipping that device. " << oendl; |
121 | continue; | 121 | continue; |
122 | } | 122 | } |
123 | odebug << "OBluetooth::synchronize() - found device #" << di.dev_id << oendl; | 123 | odebug << "OBluetooth::synchronize() - found device #" << di.dev_id << oendl; |
124 | _interfaces.insert( di.name, new OBluetoothInterface( this, di.name, (void*) &di, _fd ) ); | 124 | _interfaces.insert( di.name, new OBluetoothInterface( this, di.name, (void*) &di, _fd ) ); |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | /*====================================================================================== | 128 | /*====================================================================================== |
129 | * OBluetoothInterface | 129 | * OBluetoothInterface |
130 | *======================================================================================*/ | 130 | *======================================================================================*/ |
131 | 131 | ||
132 | class OBluetoothInterface::Private | 132 | class OBluetoothInterface::Private |
133 | { | 133 | { |
134 | public: | 134 | public: |
135 | Private( struct hci_dev_info* di, int fd ) | 135 | Private( struct hci_dev_info* di, int fd ) |
136 | { | 136 | { |
137 | ::memcpy( &devinfo, di, sizeof(struct hci_dev_info) ); | 137 | ::memcpy( &devinfo, di, sizeof(struct hci_dev_info) ); |
138 | ctlfd = fd; | 138 | ctlfd = fd; |
139 | } | 139 | } |
140 | void reloadInfo() | 140 | void reloadInfo() |
141 | { | 141 | { |
142 | int result = ::ioctl( ctlfd, HCIGETDEVINFO, (void *) &devinfo ); | 142 | int result = ::ioctl( ctlfd, HCIGETDEVINFO, (void *) &devinfo ); |
143 | if ( result == -1 ) | 143 | if ( result == -1 ) |
144 | { | 144 | { |
145 | owarn << "OBluetoothInterface::Private - can't reload device info (" << strerror( errno ) << ")" << oendl; | 145 | owarn << "OBluetoothInterface::Private - can't reload device info (" << strerror( errno ) << ")" << oendl; |
146 | } | 146 | } |
147 | } | 147 | } |
148 | struct hci_dev_info devinfo; | 148 | struct hci_dev_info devinfo; |
149 | int ctlfd; | 149 | int ctlfd; |
150 | }; | 150 | }; |
151 | 151 | ||
152 | OBluetoothInterface::OBluetoothInterface( QObject* parent, const char* name, void* devinfo, int ctlfd ) | 152 | OBluetoothInterface::OBluetoothInterface( QObject* parent, const char* name, void* devinfo, int ctlfd ) |
153 | :QObject( parent, name ) | 153 | :QObject( parent, name ) |
154 | { | 154 | { |
155 | d = new OBluetoothInterface::Private( (struct hci_dev_info*) devinfo, ctlfd ); | 155 | d = new OBluetoothInterface::Private( (struct hci_dev_info*) devinfo, ctlfd ); |
156 | } | 156 | } |
157 | 157 | ||
158 | OBluetoothInterface::~OBluetoothInterface() | 158 | OBluetoothInterface::~OBluetoothInterface() |
159 | { | 159 | { |
160 | } | 160 | } |
161 | 161 | ||
162 | QString OBluetoothInterface::macAddress() const | 162 | QString OBluetoothInterface::macAddress() const |
163 | { | 163 | { |
164 | return QString().sprintf( "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", | 164 | return QString().sprintf( "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", |
165 | d->devinfo.bdaddr.b[5], | 165 | d->devinfo.bdaddr.b[5], |
166 | d->devinfo.bdaddr.b[4], | 166 | d->devinfo.bdaddr.b[4], |
167 | d->devinfo.bdaddr.b[3], | 167 | d->devinfo.bdaddr.b[3], |
168 | d->devinfo.bdaddr.b[2], | 168 | d->devinfo.bdaddr.b[2], |
169 | d->devinfo.bdaddr.b[1], | 169 | d->devinfo.bdaddr.b[1], |
170 | d->devinfo.bdaddr.b[0] ); | 170 | d->devinfo.bdaddr.b[0] ); |
171 | } | 171 | } |
172 | 172 | ||
173 | bool OBluetoothInterface::setUp( bool b ) | 173 | bool OBluetoothInterface::setUp( bool b ) |
174 | { | 174 | { |
175 | int cmd = b ? HCIDEVUP : HCIDEVDOWN; | 175 | int cmd = b ? HCIDEVUP : HCIDEVDOWN; |
176 | int result = ::ioctl( d->ctlfd, cmd, d->devinfo.dev_id ); | 176 | int result = ::ioctl( d->ctlfd, cmd, d->devinfo.dev_id ); |
177 | if ( result == -1 && errno != EALREADY ) | 177 | if ( result == -1 && errno != EALREADY ) |
178 | { | 178 | { |
179 | owarn << "OBluetoothInterface::setUp( " << b << " ) - couldn't change interface state (" << strerror( errno ) << ")" << oendl; | 179 | owarn << "OBluetoothInterface::setUp( " << b << " ) - couldn't change interface state (" << strerror( errno ) << ")" << oendl; |
180 | return false; | 180 | return false; |
181 | } | 181 | } |
182 | else | 182 | else |
183 | { | 183 | { |
184 | d->reloadInfo(); | 184 | d->reloadInfo(); |
185 | return true; | 185 | return true; |
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | bool OBluetoothInterface::isUp() const | 189 | bool OBluetoothInterface::isUp() const |
190 | { | 190 | { |
191 | return hci_test_bit( HCI_UP, &d->devinfo.flags ); | 191 | return hci_test_bit( HCI_UP, &d->devinfo.flags ); |
192 | } | 192 | } |
193 | 193 | ||
194 | OBluetoothInterface::DeviceIterator OBluetoothInterface::neighbourhood() | 194 | OBluetoothInterface::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 | ||
234 | OBluetoothDevice::OBluetoothDevice( QObject* parent, const char* name ) | 237 | class 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 | |||
247 | OBluetoothDevice::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 | ||
240 | OBluetoothDevice::~OBluetoothDevice() | 254 | OBluetoothDevice::~OBluetoothDevice() |
241 | { | 255 | { |
242 | odebug << "OBluetoothDevice::~OBluetoothDevice()" << oendl; | 256 | odebug << "OBluetoothDevice::~OBluetoothDevice()" << oendl; |
243 | } | 257 | } |
244 | 258 | ||
245 | QString OBluetoothDevice::macAddress() const | 259 | 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 | |||
270 | QString 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 | ||
360 | QString 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 | |||
@@ -1,187 +1,199 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> | 3 | Copyright (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; version 2 of the License. | 11 | - . .-<_> .<> Foundation; version 2 of the License. |
12 | ._= =} : | 12 | ._= =} : |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #ifndef OBLUETOOTH_H | 30 | #ifndef OBLUETOOTH_H |
31 | #define OBLUETOOTH_H | 31 | #define OBLUETOOTH_H |
32 | 32 | ||
33 | #include <qobject.h> | 33 | #include <qobject.h> |
34 | #include <qdict.h> | 34 | #include <qdict.h> |
35 | 35 | ||
36 | namespace Opie { | 36 | namespace Opie { |
37 | namespace Bluez { | 37 | namespace Bluez { |
38 | 38 | ||
39 | class OBluetoothInterface; | 39 | class OBluetoothInterface; |
40 | class OBluetoothDevice; | 40 | class OBluetoothDevice; |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * @brief A container class for all bluetooth interfaces | 43 | * @brief A container class for all bluetooth interfaces |
44 | * | 44 | * |
45 | * This class provides access to all available bluetooth interfaces of your computer. | 45 | * This class provides access to all available bluetooth interfaces of your computer. |
46 | * | 46 | * |
47 | * @author Michael 'Mickey' Lauer <mickey@vanille.de> | 47 | * @author Michael 'Mickey' Lauer <mickey@vanille.de> |
48 | */ | 48 | */ |
49 | class OBluetooth : public QObject | 49 | class OBluetooth : public QObject |
50 | { | 50 | { |
51 | Q_OBJECT | 51 | Q_OBJECT |
52 | 52 | ||
53 | public: | 53 | public: |
54 | typedef QDict<OBluetoothInterface> InterfaceMap; | 54 | typedef QDict<OBluetoothInterface> InterfaceMap; |
55 | typedef QDictIterator<OBluetoothInterface> InterfaceIterator; | 55 | typedef QDictIterator<OBluetoothInterface> InterfaceIterator; |
56 | 56 | ||
57 | public: | 57 | public: |
58 | /** | 58 | /** |
59 | * @returns the number of available interfaces | 59 | * @returns the number of available interfaces |
60 | */ | 60 | */ |
61 | int count() const; | 61 | int count() const; |
62 | /** | 62 | /** |
63 | * @returns a pointer to the (one and only) @ref OBluetooth instance. | 63 | * @returns a pointer to the (one and only) @ref OBluetooth instance. |
64 | */ | 64 | */ |
65 | static OBluetooth* instance(); | 65 | static OBluetooth* instance(); |
66 | /** | 66 | /** |
67 | * @returns an iterator usable for iterating through all network interfaces. | 67 | * @returns an iterator usable for iterating through all network interfaces. |
68 | */ | 68 | */ |
69 | InterfaceIterator iterator() const; | 69 | InterfaceIterator iterator() const; |
70 | /** | 70 | /** |
71 | * @returns true, if the @a interface is present. | 71 | * @returns true, if the @a interface is present. |
72 | */ | 72 | */ |
73 | bool isPresent( const char* interface ) const; | 73 | bool isPresent( const char* interface ) const; |
74 | /** | 74 | /** |
75 | * @returns true, if the @a interface supports the wireless extension protocol. | 75 | * @returns true, if the @a interface supports the wireless extension protocol. |
76 | */ | 76 | */ |
77 | bool isWirelessInterface( const char* interface ) const; | 77 | bool isWirelessInterface( const char* interface ) const; |
78 | /** | 78 | /** |
79 | * @returns a pointer to the @ref OBluetoothInterface object for the specified @a interface or 0, if not found. | 79 | * @returns a pointer to the @ref OBluetoothInterface object for the specified @a interface or 0, if not found. |
80 | * @see OBluetoothInterface | 80 | * @see OBluetoothInterface |
81 | */ | 81 | */ |
82 | OBluetoothInterface* interface( const QString& interface ) const; | 82 | OBluetoothInterface* interface( const QString& interface ) const; |
83 | /** | 83 | /** |
84 | * @internal Rebuild the internal interface database | 84 | * @internal Rebuild the internal interface database |
85 | * @note Sometimes it might be useful to call this from client code, | 85 | * @note Sometimes it might be useful to call this from client code, |
86 | * e.g. after issuing a cardctl insert | 86 | * e.g. after issuing a cardctl insert |
87 | */ | 87 | */ |
88 | void synchronize(); | 88 | void synchronize(); |
89 | 89 | ||
90 | protected: | 90 | protected: |
91 | OBluetooth(); | 91 | OBluetooth(); |
92 | 92 | ||
93 | private: | 93 | private: |
94 | static OBluetooth* _instance; | 94 | static OBluetooth* _instance; |
95 | InterfaceMap _interfaces; | 95 | InterfaceMap _interfaces; |
96 | class OBluetoothPrivate; | 96 | class OBluetoothPrivate; |
97 | OBluetoothPrivate *d; | 97 | OBluetoothPrivate *d; |
98 | int _fd; | 98 | int _fd; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | /*====================================================================================== | 101 | /*====================================================================================== |
102 | * OBluetoothInterface | 102 | * OBluetoothInterface |
103 | *======================================================================================*/ | 103 | *======================================================================================*/ |
104 | 104 | ||
105 | /** | 105 | /** |
106 | * @brief An bluetooth interface wrapper. | 106 | * @brief An bluetooth interface wrapper. |
107 | * | 107 | * |
108 | * This class provides a wrapper for a bluetooth HCI device. All the cumbersome details of | 108 | * This class provides a wrapper for a bluetooth HCI device. All the cumbersome details of |
109 | * Linux ioctls are hidden under a convenient high-level interface. | 109 | * Linux ioctls are hidden under a convenient high-level interface. |
110 | * @warning Most of the setting methods contained in this class require the appropriate | 110 | * @warning Most of the setting methods contained in this class require the appropriate |
111 | * process permissions to work. | 111 | * process permissions to work. |
112 | * | 112 | * |
113 | * @author Michael 'Mickey' Lauer <mickey@vanille.de> | 113 | * @author Michael 'Mickey' Lauer <mickey@vanille.de> |
114 | */ | 114 | */ |
115 | class OBluetoothInterface : public QObject | 115 | class OBluetoothInterface : public QObject |
116 | { | 116 | { |
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 | */ |
165 | class OBluetoothDevice : public QObject | 165 | class 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 | ||