author | wimpie <wimpie> | 2005-01-04 01:42:25 (UTC) |
---|---|---|
committer | wimpie <wimpie> | 2005-01-04 01:42:25 (UTC) |
commit | 2487b0a05f502e7410715460f390cc80e7e76fd9 (patch) (unidiff) | |
tree | 430dce90a1bdff8eb85cbf1004db094ab6653ab9 | |
parent | e2094d408c9102f8866aafbe725a65f25fdef063 (diff) | |
download | opie-2487b0a05f502e7410715460f390cc80e7e76fd9.zip opie-2487b0a05f502e7410715460f390cc80e7e76fd9.tar.gz opie-2487b0a05f502e7410715460f390cc80e7e76fd9.tar.bz2 |
*** empty log message ***
23 files changed, 4075 insertions, 0 deletions
diff --git a/noncore/settings/networksettings2/etc_ppp/ip-up b/noncore/settings/networksettings2/etc_ppp/ip-up new file mode 100755 index 0000000..ec964d0 --- a/dev/null +++ b/noncore/settings/networksettings2/etc_ppp/ip-up | |||
@@ -0,0 +1,71 @@ | |||
1 | #!/bin/sh | ||
2 | exec 2> /tmp/IPL | ||
3 | set -x | ||
4 | # | ||
5 | # This script is run by the pppd after the link is established. | ||
6 | # This script is run by the pppd _after_ the link is brought down. | ||
7 | # | ||
8 | # variable DIR determines if it is run after establish (up) or | ||
9 | # after down (down) | ||
10 | # | ||
11 | # It uses run-parts to run scripts in /etc/ppp/ip-$DIR.d | ||
12 | # | ||
13 | # This script is called with the following arguments: | ||
14 | # Arg Name Example | ||
15 | # $1 Interface name ppp0 | ||
16 | # $2 The tty ttyS1 | ||
17 | # $3 The link speed 38400 | ||
18 | # $4 Local IP number 12.34.56.78 | ||
19 | # $5 Peer IP number 12.34.56.99 | ||
20 | # $6 Optional ``ipparam'' value foo | ||
21 | |||
22 | # The environment is cleared before executing this script | ||
23 | # so the path must be reset | ||
24 | PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin | ||
25 | export PATH | ||
26 | |||
27 | case $0 in | ||
28 | *ip-up*) | ||
29 | DIR=up | ||
30 | ;; | ||
31 | *ip-down*) | ||
32 | DIR=down | ||
33 | ;; | ||
34 | esac | ||
35 | |||
36 | # These variables are for the use of the scripts run by run-parts | ||
37 | PPP_IFACE="$1" | ||
38 | PPP_TTY="$2" | ||
39 | PPP_SPEED="$3" | ||
40 | PPP_LOCAL="$4" | ||
41 | PPP_REMOTE="$5" | ||
42 | PPP_IPPARAM="$6" | ||
43 | export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM | ||
44 | |||
45 | # as an additional convenience, $PPP_TTYNAME is set to the tty name, | ||
46 | # stripped of /dev/ (if present) for easier matching. | ||
47 | PPP_TTYNAME=`/usr/bin/basename "$2"` | ||
48 | export PPP_TTYNAME | ||
49 | |||
50 | # If /var/log/ppp-ipupdown.log exists use it for logging. | ||
51 | if [ -e /var/log/ppp-ipupdown.log ]; then | ||
52 | exec > /var/log/ppp-ipupdown.log 2>&1 | ||
53 | fi | ||
54 | |||
55 | # This script can be used to override the .d files supplied by other packages. | ||
56 | if [ -x /etc/ppp/ip-${DIR}.local ]; then | ||
57 | exec /etc/ppp/ip-${DIR}.local | ||
58 | fi | ||
59 | |||
60 | run-parts -a "$1" -a "$2" -a "$3" -a "$4" -a "$5" -a "$6" \ | ||
61 | /etc/ppp/ip-${DIR}.d | ||
62 | |||
63 | if [ "$DIR" = "up" ] | ||
64 | then | ||
65 | # if pon was called with the "quick" argument, stop pppd | ||
66 | if [ -e /var/run/ppp-quick ]; then | ||
67 | rm /var/run/ppp-quick | ||
68 | wait | ||
69 | kill $PPPD_PID | ||
70 | fi | ||
71 | fi | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDevice.cpp b/noncore/settings/networksettings2/opietooth2/OTDevice.cpp new file mode 100644 index 0000000..62f17a0 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDevice.cpp | |||
@@ -0,0 +1,256 @@ | |||
1 | #include <qdir.h> | ||
2 | #include <qfileinfo.h> | ||
3 | |||
4 | #include <bluezlib.h> | ||
5 | |||
6 | /* OPIE */ | ||
7 | #include <opie2/odevice.h> | ||
8 | #include <opie2/oprocess.h> | ||
9 | #include <opie2/odebug.h> | ||
10 | |||
11 | #include <OTDevice.h> | ||
12 | |||
13 | using namespace Opie::Core; | ||
14 | using namespace Opietooth2; | ||
15 | using Opie::Core::OProcess; | ||
16 | |||
17 | OTDevice::OTDevice( OTGateway * _OT ) : QObject(0, "device") { | ||
18 | |||
19 | // initialize | ||
20 | OT = _OT; | ||
21 | |||
22 | // detect bluetooth type | ||
23 | QString a, b; // fake | ||
24 | unsigned long c; // fake | ||
25 | detectDeviceType( a, b, c ); | ||
26 | |||
27 | if( needsAttach() ) { | ||
28 | // requires HCIATTACH | ||
29 | // pid of hciattach | ||
30 | m_hciattachPid = getPidOfHCIAttach(); | ||
31 | |||
32 | m_hciattach = 0; | ||
33 | |||
34 | if( m_hciattachPid == 0 ) { | ||
35 | // no pid -> not attached | ||
36 | m_deviceNr = -1; | ||
37 | } else { | ||
38 | // system enabled | ||
39 | // currently no way to figure out which attach produce which | ||
40 | // hci | ||
41 | m_deviceNr = 0; | ||
42 | } | ||
43 | } else { | ||
44 | m_deviceNr = 0; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | OTDevice::~OTDevice(){ | ||
49 | if( needsAttach() && m_hciattach ) { | ||
50 | // does not auto stop bluetooth | ||
51 | m_hciattach->detach(); | ||
52 | delete m_hciattach; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | bool OTDevice::attach(){ | ||
57 | |||
58 | if( needsAttach() && m_hciattachPid == 0 ) { | ||
59 | QString Dev, Mode; | ||
60 | unsigned long Spd; | ||
61 | |||
62 | detectDeviceType( Dev, Mode, Spd ); | ||
63 | |||
64 | // not yet started | ||
65 | m_hciattach = new OProcess(); | ||
66 | *m_hciattach << "hciattach"; | ||
67 | *m_hciattach << "-p"; // so that it prints its pid | ||
68 | *m_hciattach << Dev | ||
69 | << Mode | ||
70 | << QString().setNum(Spd); | ||
71 | |||
72 | connect( m_hciattach, | ||
73 | SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ), | ||
74 | this, SLOT | ||
75 | (slotStdOut(Opie::Core::OProcess*,char*,int) ) ); | ||
76 | |||
77 | connect( m_hciattach, | ||
78 | SIGNAL(receivedStderr(Opie::Core::OProcess*, char*, int ) ), | ||
79 | this, SLOT | ||
80 | (slotStdErr(Opie::Core::OProcess*,char*,int) ) ); | ||
81 | |||
82 | // we need to start this in 'dontcare' mode because | ||
83 | // if qpe exists we want the hci to keep running | ||
84 | if( ! m_hciattach->start( OProcess::DontCare, | ||
85 | OProcess::AllOutput | ||
86 | ) ){ | ||
87 | emit error( tr( "Could not start hciattach" ) ); | ||
88 | delete m_hciattach; | ||
89 | m_hciattach = 0; | ||
90 | return FALSE; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return TRUE; | ||
95 | } | ||
96 | |||
97 | bool OTDevice::detach(){ | ||
98 | |||
99 | if( needsAttach() && m_hciattachPid ) { | ||
100 | if( m_hciattach ) { | ||
101 | delete m_hciattach; | ||
102 | m_hciattach = 0; | ||
103 | } | ||
104 | |||
105 | if( kill( m_hciattachPid, 9) < 0 ) { | ||
106 | owarn << "could not stop " << errno << oendl; | ||
107 | emit error( tr( "Could not stop process" ) ); | ||
108 | return FALSE; | ||
109 | } | ||
110 | m_hciattachPid = 0; | ||
111 | emit isEnabled( m_deviceNr, 0 ); | ||
112 | m_deviceNr = -1; | ||
113 | } | ||
114 | |||
115 | return TRUE; | ||
116 | } | ||
117 | |||
118 | bool OTDevice::isAttached()const{ | ||
119 | return ! needsAttach() || m_hciattachPid != 0; | ||
120 | } | ||
121 | |||
122 | bool OTDevice::checkAttach(){ | ||
123 | if( ! needsAttach() ) { | ||
124 | m_deviceNr = 0; | ||
125 | emit isEnabled( 0, 1 ); | ||
126 | return TRUE; | ||
127 | } | ||
128 | |||
129 | if( m_hciattachPid ) { | ||
130 | QString S; | ||
131 | S.setNum( m_hciattachPid ); | ||
132 | QDir D( "/proc" ); | ||
133 | if( !D.exists( S ) ) { | ||
134 | // down | ||
135 | m_hciattachPid = 0; | ||
136 | emit isEnabled( m_deviceNr, 0 ); | ||
137 | m_deviceNr = -1; | ||
138 | } | ||
139 | } else { | ||
140 | // check | ||
141 | m_hciattachPid = getPidOfHCIAttach(); | ||
142 | if ( m_hciattachPid ) { | ||
143 | m_deviceNr = 0; | ||
144 | emit isEnabled( m_deviceNr, 1 ); | ||
145 | } | ||
146 | } | ||
147 | return m_hciattachPid != 0; | ||
148 | } | ||
149 | |||
150 | void OTDevice::slotStdOut(OProcess* proc, char* , int ) { | ||
151 | if( proc == m_hciattach ) { | ||
152 | m_hciattach->detach(); | ||
153 | |||
154 | // system enabled | ||
155 | // currently no way to figure out which attach produce which | ||
156 | // hci | ||
157 | if( m_deviceNr == -1 ) { | ||
158 | m_deviceNr = 0; | ||
159 | emit isEnabled( m_deviceNr, 1 ); | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | void OTDevice::slotStdErr(OProcess* proc, char* chars, int len) { | ||
165 | |||
166 | if(proc == m_hciattach && len >= 1 ){ | ||
167 | // collect output | ||
168 | QCString string( chars, len+1 ); // \0 == +1 | ||
169 | QString m_output; | ||
170 | m_output.append( string.data() ); | ||
171 | owarn << m_output << oendl; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | pid_t OTDevice::getPidOfHCIAttach( void ) { | ||
176 | |||
177 | if( needsAttach() ) { | ||
178 | // not yet attached -> perhaps now ? | ||
179 | // load /proc dir and check if command name contains hciattach | ||
180 | QRegExp R("[0-9]+"); | ||
181 | QDir ProcDir( "/proc" ); | ||
182 | QFileInfo FI; | ||
183 | QStringList EL = ProcDir.entryList( QDir::Dirs ); | ||
184 | |||
185 | // print it out | ||
186 | for ( QStringList::Iterator it = EL.begin(); | ||
187 | it != EL.end(); | ||
188 | ++it ) { | ||
189 | if( R.match( (*it) ) >= 0 ) { | ||
190 | // is pid | ||
191 | |||
192 | // get command being executed | ||
193 | FI.setFile( ProcDir.path()+"/"+ (*it) + "/exe" ); | ||
194 | |||
195 | // get the link | ||
196 | if( FI.readLink().right( 9 ) == "hciattach" ) { | ||
197 | // this is hci attach process | ||
198 | |||
199 | return (*it).toULong(); | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | void OTDevice::detectDeviceType( QString & Device, | ||
210 | QString & Mode, | ||
211 | unsigned long & Speed ) { | ||
212 | |||
213 | // detect device type and determine parms | ||
214 | owarn << "Detecting device" << oendl; | ||
215 | switch ( ODevice::inst()->model() ) { | ||
216 | case Model_iPAQ_H39xx: | ||
217 | Device = "/dev/tts/1"; | ||
218 | Mode = "bcsp"; | ||
219 | Speed = 921600; | ||
220 | NeedsAttach = 1; | ||
221 | break; | ||
222 | |||
223 | case Model_iPAQ_H5xxx: | ||
224 | Device = "/dev/tts/1"; | ||
225 | Mode = "any"; | ||
226 | Speed = 921600; | ||
227 | NeedsAttach = 1; | ||
228 | break; | ||
229 | |||
230 | case Model_GenuineIntel : | ||
231 | Device = ""; | ||
232 | Mode = ""; | ||
233 | Speed = 0; | ||
234 | NeedsAttach = 0; | ||
235 | break; | ||
236 | |||
237 | default: | ||
238 | Device = "/dev/ttySB0"; | ||
239 | Mode = "bcsp"; | ||
240 | Speed = 230400; | ||
241 | NeedsAttach = 1; | ||
242 | break; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | QString OTDevice::getRFCommDevicePattern( void ) { | ||
247 | |||
248 | QDir D( "/dev/bluetooth/rfcomm" ); | ||
249 | if( D.exists() ) { | ||
250 | // devfs | ||
251 | return QString( "/dev/bluetooth/rfcomm/%1" ); | ||
252 | } | ||
253 | |||
254 | // regular 'dev' directory | ||
255 | return QString( "/dev/rfcomm%1" ); | ||
256 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDevice.h b/noncore/settings/networksettings2/opietooth2/OTDevice.h new file mode 100644 index 0000000..c2abb09 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDevice.h | |||
@@ -0,0 +1,116 @@ | |||
1 | #ifndef OTDEVICE_H | ||
2 | #define OTDEVICE_H | ||
3 | |||
4 | #include <qobject.h> | ||
5 | #include <qstring.h> | ||
6 | |||
7 | #include <bluezlib.h> | ||
8 | |||
9 | #include <OTGateway.h> | ||
10 | |||
11 | // define if you want to use the process hciattach for detection | ||
12 | // #define USEHCIPROC | ||
13 | |||
14 | class QTimerEvent; | ||
15 | |||
16 | namespace Opie { | ||
17 | namespace Core { | ||
18 | class OProcess; | ||
19 | } | ||
20 | } | ||
21 | |||
22 | namespace Opietooth2 { | ||
23 | |||
24 | /** | ||
25 | * Device takes care of attaching serial | ||
26 | * devices to the blueZ stack. | ||
27 | * After attaching it hciconfig ups it | ||
28 | */ | ||
29 | class OTDevice : public QObject { | ||
30 | |||
31 | Q_OBJECT | ||
32 | |||
33 | public: | ||
34 | |||
35 | /** | ||
36 | * Brings up the device. | ||
37 | * will detech which device is needed | ||
38 | * Usage example: new Device(/dev/ttySB0, csr) | ||
39 | * | ||
40 | */ | ||
41 | OTDevice( OTGateway * _OT ); | ||
42 | |||
43 | /** | ||
44 | * unloads the device | ||
45 | */ | ||
46 | ~OTDevice(); | ||
47 | |||
48 | inline OTGateway * gateway() const | ||
49 | { return OT; } | ||
50 | |||
51 | inline bool needsAttach( void ) const | ||
52 | { return NeedsAttach; } | ||
53 | |||
54 | inline int deviceNr() const | ||
55 | { return m_deviceNr; } | ||
56 | |||
57 | /** | ||
58 | * attach the device | ||
59 | * @return bool which is TRUE if command started sucessfully | ||
60 | */ | ||
61 | bool attach(); | ||
62 | |||
63 | /** | ||
64 | * detach the device | ||
65 | * @return bool which is TRUE if command started sucessfully | ||
66 | */ | ||
67 | bool detach(); | ||
68 | |||
69 | /** | ||
70 | * Is the device loaded? | ||
71 | * @return bool, if the device is loaded | ||
72 | */ | ||
73 | bool isAttached()const; | ||
74 | |||
75 | // check current state of attachment | ||
76 | bool checkAttach(); | ||
77 | |||
78 | // returns pattern that points to the proper | ||
79 | // RFCOMM device file. Put %1 where device nr should be put | ||
80 | // e.g. : /dev/bluetooth/rfcomm/%1 or /def/rfcomm%1 | ||
81 | QString getRFCommDevicePattern(); | ||
82 | |||
83 | signals: | ||
84 | |||
85 | /** | ||
86 | * Signals if the attach/detach of the device produced | ||
87 | * errors | ||
88 | * @param Mesg contains an error message | ||
89 | */ | ||
90 | void error( const QString & mesg ); | ||
91 | void isEnabled( int devnr, bool ); | ||
92 | |||
93 | private slots: | ||
94 | |||
95 | void slotStdOut(Opie::Core::OProcess*, char*, int ); | ||
96 | void slotStdErr(Opie::Core::OProcess*, char*, int ); | ||
97 | |||
98 | private: | ||
99 | |||
100 | void detectDeviceType( QString & Device, | ||
101 | QString & Mode, | ||
102 | unsigned long & Speed ); | ||
103 | pid_t getPidOfHCIAttach( void ); | ||
104 | |||
105 | Opie::Core::OProcess* m_hciattach; // ptr to hciattach proces | ||
106 | |||
107 | int m_deviceNr; // x as in hci(x) | ||
108 | pid_t m_hciattachPid; // pid of hciattach program | ||
109 | |||
110 | // backpointer | ||
111 | OTGateway * OT; | ||
112 | bool NeedsAttach; | ||
113 | }; | ||
114 | }; | ||
115 | |||
116 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.cpp b/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.cpp new file mode 100644 index 0000000..7fbfaf4 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.cpp | |||
@@ -0,0 +1,110 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@schaettgen.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | #include <string.h> | ||
13 | #include <bluezlib.h> | ||
14 | #include <opie2/odebug.h> | ||
15 | |||
16 | #include <OTDeviceAddress.h> | ||
17 | |||
18 | using namespace Opietooth2; | ||
19 | |||
20 | //const bdaddr_t OTDeviceAddress::bdaddr_any = {{0,0,0,0,0,0}}; | ||
21 | //const bdaddr_t OTDeviceAddress::bdaddr_local = {{0, 0, 0, 0xff, 0xff, 0xff}}; | ||
22 | |||
23 | const OTDeviceAddress OTDeviceAddress::invalid = | ||
24 | OTDeviceAddress(); | ||
25 | const OTDeviceAddress OTDeviceAddress::any = | ||
26 | OTDeviceAddress("00:00:00:00:00:00"); | ||
27 | const OTDeviceAddress OTDeviceAddress::local = | ||
28 | OTDeviceAddress("00:00:00:FF:FF:FF"); | ||
29 | |||
30 | OTDeviceAddress::OTDeviceAddress() { | ||
31 | |||
32 | IsValid = false; | ||
33 | memset( &BDaddr, 0, sizeof( BDaddr ) ); | ||
34 | } | ||
35 | |||
36 | OTDeviceAddress::OTDeviceAddress( const bdaddr_t& bdaddr, | ||
37 | bool networkbyteorder) { | ||
38 | setBDAddr( bdaddr, networkbyteorder ); | ||
39 | } | ||
40 | |||
41 | OTDeviceAddress::OTDeviceAddress(const QString& s) { | ||
42 | |||
43 | bdaddr_t a; | ||
44 | int ret = str2ba(s.latin1(), &a); | ||
45 | if (ret==0) { | ||
46 | IsValid = true; | ||
47 | bacpy( &BDaddr, &a ); | ||
48 | } else { | ||
49 | IsValid = false; | ||
50 | bacpy( &BDaddr, &(OTDeviceAddress::invalid.getBDAddr()) ) ; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | QString OTDeviceAddress::toString() const { | ||
55 | char addrbuf[20]; | ||
56 | ba2str(&BDaddr, addrbuf); | ||
57 | return QString(addrbuf); | ||
58 | |||
59 | } | ||
60 | |||
61 | void OTDeviceAddress::setBDAddr( const bdaddr_t& bdaddr, | ||
62 | bool networkbyteorder) { | ||
63 | if (networkbyteorder) { | ||
64 | baswap(&BDaddr, &bdaddr); | ||
65 | } else { | ||
66 | bacpy( &BDaddr, &bdaddr ); | ||
67 | } | ||
68 | IsValid = true; | ||
69 | } | ||
70 | |||
71 | bdaddr_t OTDeviceAddress::getBDAddrInNetworkByteOrder(void) const { | ||
72 | bdaddr_t ret; | ||
73 | baswap(&ret, &BDaddr); | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | bool OTDeviceAddress::operator==(const OTDeviceAddress& b) const { | ||
78 | if ( ! IsValid && ! b.IsValid ) | ||
79 | return true; | ||
80 | return memcmp( &BDaddr, &(b.BDaddr), sizeof( b.BDaddr ) ) == 0; | ||
81 | } | ||
82 | |||
83 | bool OTDeviceAddress::operator<(const OTDeviceAddress& b) const { | ||
84 | if ( ! IsValid && ! b.IsValid ) | ||
85 | return false; | ||
86 | else if ( ! IsValid && b.IsValid ) | ||
87 | return false; | ||
88 | else if ( IsValid && ! b.IsValid ) | ||
89 | return true; | ||
90 | |||
91 | if (BDaddr.b[5] != b.BDaddr.b[5]) | ||
92 | return (BDaddr.b[5] < b.BDaddr.b[5]); | ||
93 | |||
94 | if (BDaddr.b[4] != b.BDaddr.b[4]) | ||
95 | return (BDaddr.b[4] < b.BDaddr.b[4]); | ||
96 | |||
97 | if (BDaddr.b[3] != b.BDaddr.b[3]) | ||
98 | return (BDaddr.b[3] < b.BDaddr.b[3]); | ||
99 | |||
100 | if (BDaddr.b[2] != b.BDaddr.b[2]) | ||
101 | return (BDaddr.b[2] < b.BDaddr.b[2]); | ||
102 | |||
103 | if (BDaddr.b[1] != b.BDaddr.b[1]) | ||
104 | return (BDaddr.b[1] < b.BDaddr.b[1]); | ||
105 | |||
106 | if (BDaddr.b[0] != b.BDaddr.b[0]) | ||
107 | return (BDaddr.b[0] < b.BDaddr.b[0]); | ||
108 | |||
109 | return false; | ||
110 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.h b/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.h new file mode 100644 index 0000000..8395f37 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDeviceAddress.h | |||
@@ -0,0 +1,108 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@0xF.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | #ifndef OTDEVICEADDRESS_H | ||
13 | #define OTDEVICEADDRESS_H | ||
14 | |||
15 | #include <qstring.h> | ||
16 | #include <bluezlib.h> | ||
17 | |||
18 | namespace Opietooth2 { | ||
19 | |||
20 | /** Represents a Bluetooth device address. | ||
21 | * This class allows easy conversion of Bluetooth addresses | ||
22 | * from and to strings. It also works with the bdaddr_t type | ||
23 | * used by BlueZ. | ||
24 | * The class offers a comparsion and less-than operator, so | ||
25 | * that it can be used a key in an STL map or similar. | ||
26 | * The string conversion functions of BlueZ are used internally, | ||
27 | * so the string format is the same than for BlueZ's ba2str(). | ||
28 | */ | ||
29 | class OTDeviceAddress { | ||
30 | |||
31 | public: | ||
32 | |||
33 | /** Default constructor. | ||
34 | The resulting address is equal to DeviceAddress::invalid. | ||
35 | */ | ||
36 | OTDeviceAddress(); | ||
37 | |||
38 | /** Initialize the object with a BlueZ bdaddr_t. | ||
39 | @param bdaddr address | ||
40 | @param networkbyteorder if true, bdaddr is assumed to be in | ||
41 | network byte order and converted to host byte order first. | ||
42 | */ | ||
43 | explicit OTDeviceAddress( const bdaddr_t& bdaddr, | ||
44 | bool networkbyteorder = false | ||
45 | ); | ||
46 | |||
47 | /** Initializes the object with an address given as a string. | ||
48 | The string must be in a format which is understood by the | ||
49 | BlueZ str2ba function, like 00:61:58:4C:E6:AD. Case doesn't matter. | ||
50 | @param s address string | ||
51 | */ | ||
52 | explicit OTDeviceAddress(const QString& s); | ||
53 | |||
54 | /** convert the address to a string. | ||
55 | @return address string | ||
56 | */ | ||
57 | QString toString() const; | ||
58 | |||
59 | /** Converts the DeviceAddress into a BlueZ bdaddr_t. | ||
60 | @param networkbyteorder if true, the address is returned | ||
61 | in network byte order. | ||
62 | @return the address as bdaddr_t | ||
63 | */ | ||
64 | inline const bdaddr_t & getBDAddr( void ) const | ||
65 | { return BDaddr; } | ||
66 | bdaddr_t getBDAddrInNetworkByteOrder() const; | ||
67 | void setBDAddr( const bdaddr_t& bdaddr, | ||
68 | bool networkbyteorder = false | ||
69 | ); | ||
70 | |||
71 | /** Less-than-operator. | ||
72 | Mainly there to use DeviceAddress inside STL containers, | ||
73 | like STL sets or as a key in a STL map. | ||
74 | @param b the DeviceAddress to compare to (right hand side) | ||
75 | @return true if this < b, false otherwise. | ||
76 | */ | ||
77 | bool operator<(const OTDeviceAddress& b) const; | ||
78 | |||
79 | /** Equality operator. | ||
80 | Tests two device addresses for equality. | ||
81 | @param b the DeviceAddress to compare to (right hand side) | ||
82 | @return true if this and b have the same address or | ||
83 | if both are invalid, false otherwise | ||
84 | */ | ||
85 | bool operator==(const OTDeviceAddress& b) const; | ||
86 | |||
87 | inline bool operator!=(const OTDeviceAddress& b) const | ||
88 | { return ! ( *this == b ); } | ||
89 | |||
90 | /** The address 00:00:00:FF:FF:FF */ | ||
91 | static const OTDeviceAddress local; | ||
92 | |||
93 | /** The address 00:00:00:00:00:00 */ | ||
94 | static const OTDeviceAddress any; | ||
95 | |||
96 | /** An address tagged as invalid */ | ||
97 | static const OTDeviceAddress invalid; | ||
98 | |||
99 | protected: | ||
100 | |||
101 | bdaddr_t BDaddr; | ||
102 | bool IsValid; | ||
103 | |||
104 | }; | ||
105 | |||
106 | } | ||
107 | |||
108 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDriver.cpp b/noncore/settings/networksettings2/opietooth2/OTDriver.cpp new file mode 100644 index 0000000..8bd7919 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDriver.cpp | |||
@@ -0,0 +1,744 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2003 by Mattia Merzi * | ||
3 | * ottobit@ferrara.linux.it * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | ***************************************************************************/ | ||
10 | |||
11 | #include <opie2/odebug.h> | ||
12 | #include <qtimer.h> | ||
13 | |||
14 | #include <sys/poll.h> | ||
15 | #include <bluezlib.h> | ||
16 | |||
17 | #include <OTGateway.h> | ||
18 | #include <OTDriver.h> | ||
19 | #include <OTHCISocket.h> | ||
20 | |||
21 | using namespace Opietooth2; | ||
22 | |||
23 | static struct { | ||
24 | const char *str; | ||
25 | unsigned short rev; | ||
26 | } csr_map[] = { | ||
27 | { "HCI 11.2 (bc01b)", 114 }, | ||
28 | { "HCI 11.3 (bc01b)", 115 }, | ||
29 | { "HCI 12.1 (bc01b)", 119 }, | ||
30 | { "HCI 12.3 (bc01b)", 134 }, | ||
31 | { "HCI 12.7 (bc01b)", 188 }, | ||
32 | { "HCI 12.8 (bc01b)", 218 }, | ||
33 | { "HCI 12.9 (bc01b)", 283 }, | ||
34 | { "HCI 13.10 (bc01b)", 309 }, | ||
35 | { "HCI 13.11 (bc01b)", 351 }, | ||
36 | { "HCI 16.4 (bc01b)", 523 }, | ||
37 | { "HCI 14.3 (bc02x)", 272 }, | ||
38 | { "HCI 14.6 (bc02x)", 336 }, | ||
39 | { "HCI 14.7 (bc02x)", 373 }, | ||
40 | { "HCI 14.8 (bc02x)", 487 }, | ||
41 | { "HCI 15.3 (bc02x)", 443 }, | ||
42 | { "HCI 16.4 (bc02x)", 525 }, | ||
43 | { NULL, 0} | ||
44 | }; | ||
45 | |||
46 | static char *services[] = { "Positioning", | ||
47 | "Networking", | ||
48 | "Rendering", | ||
49 | "Capturing", | ||
50 | "Object Transfer", | ||
51 | "Audio", | ||
52 | "Telephony", | ||
53 | "Information" }; | ||
54 | |||
55 | static char *major_devices[] = { "Miscellaneous", | ||
56 | "Computer", | ||
57 | "Phone", | ||
58 | "LAN Access", | ||
59 | "Audio/Video", | ||
60 | "Peripheral", | ||
61 | "Imaging", | ||
62 | "Uncategorized" }; | ||
63 | |||
64 | |||
65 | typedef struct { | ||
66 | short Minor; | ||
67 | const char * Description; | ||
68 | } ClassMap_t; | ||
69 | |||
70 | static ClassMap_t MapMiscClass[] = { | ||
71 | { -1, "" } | ||
72 | }; | ||
73 | |||
74 | static ClassMap_t MapUnclassifiedClass[] = { | ||
75 | { -1, "" } | ||
76 | }; | ||
77 | |||
78 | static ClassMap_t MapComputerClass[] = { | ||
79 | { 0, "Uncategorized" } , | ||
80 | { 1, "Desktop workstation" } , | ||
81 | { 2, "Server" } , | ||
82 | { 3, "Laptop" } , | ||
83 | { 4, "Handheld" } , | ||
84 | { 5, "Palm" } , | ||
85 | { 6, "Wearable" }, | ||
86 | { -1, 0 } | ||
87 | }; | ||
88 | |||
89 | static ClassMap_t MapPhoneClass[] = { | ||
90 | { 0, "Uncategorized" }, | ||
91 | { 1, "Cellular" }, | ||
92 | { 2, "Cordless" }, | ||
93 | { 3, "Smart phone" }, | ||
94 | { 4, "Wired modem or voice gateway" }, | ||
95 | { 5, "Common ISDN Access" }, | ||
96 | { 6, "Sim Card Reader" }, | ||
97 | { -1, 0 } | ||
98 | }; | ||
99 | |||
100 | static ClassMap_t MapAVClass[] = { | ||
101 | { 0, "Uncategorized" }, | ||
102 | { 1, "Device conforms to the Headset profile" }, | ||
103 | { 2, "Hands-free" }, | ||
104 | { 3, 0 }, | ||
105 | { 4, "Microphone" }, | ||
106 | { 5, "Loudspeaker" }, | ||
107 | { 6, "Headphones" }, | ||
108 | { 7, "Portable Audio" }, | ||
109 | { 8, "Car Audio" }, | ||
110 | { 9, "Set-top box" }, | ||
111 | { 10, "HiFi Audio Device" }, | ||
112 | { 11, "VCR" }, | ||
113 | { 12, "Video Camera" }, | ||
114 | { 13, "Camcorder" }, | ||
115 | { 14, "Video Monitor" }, | ||
116 | { 15, "Video Display and Loudspeaker" }, | ||
117 | { 16, "Video Conferencing" }, | ||
118 | { 17, 0 }, | ||
119 | { 18, "Gaming/Toy" }, | ||
120 | { -1, 0 } | ||
121 | }; | ||
122 | |||
123 | static ClassMap_t MapPeripheralClass[] = { | ||
124 | { 16, "Keyboard" }, | ||
125 | { 32, "Pointing device" }, | ||
126 | { 48, "Combo keyboard/pointing device" }, | ||
127 | { -1, 0 } | ||
128 | }; | ||
129 | |||
130 | typedef struct { | ||
131 | int Major; | ||
132 | ClassMap_t * Map; | ||
133 | } MainClassMap_t; | ||
134 | |||
135 | static MainClassMap_t MainClasses[] = { | ||
136 | { 0, MapMiscClass }, | ||
137 | { 1, MapComputerClass }, | ||
138 | { 2, MapPhoneClass }, | ||
139 | { 3, 0 }, // special case | ||
140 | { 4, MapAVClass }, | ||
141 | { 5, MapPeripheralClass }, | ||
142 | { 6, 0 }, // special case | ||
143 | { 63, MapUnclassifiedClass }, | ||
144 | { -1, 0 } | ||
145 | }; | ||
146 | |||
147 | OTDriver::OTDriver( OTGateway * _OT, struct hci_dev_info* di) : QObject( _OT ), Address() { | ||
148 | OT = _OT; | ||
149 | IsUp = 0; | ||
150 | Socket = 0; | ||
151 | |||
152 | init(di); | ||
153 | owarn << "Driver " << devname() << oendl; | ||
154 | |||
155 | AutoClose = new QTimer( this ); | ||
156 | connect( AutoClose, | ||
157 | SIGNAL( timeout() ), | ||
158 | this, | ||
159 | SLOT( SLOT_CloseFd() ) | ||
160 | ); | ||
161 | } | ||
162 | |||
163 | OTDriver::~OTDriver() { | ||
164 | closeSocket(); | ||
165 | SLOT_CloseFd(); | ||
166 | } | ||
167 | |||
168 | void OTDriver::SLOT_CloseFd( void ){ | ||
169 | if ( isOpen() ) { | ||
170 | AutoClose->stop(); | ||
171 | ::close( fd() ); | ||
172 | setfd( -1 ); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | void OTDriver::init(struct hci_dev_info* di) { | ||
177 | |||
178 | Dev = di->name; | ||
179 | |||
180 | setDevId(di->dev_id); | ||
181 | setType(di->type); | ||
182 | setFlags(di->flags); | ||
183 | Address.setBDAddr( di->bdaddr ); | ||
184 | setFeatures(di->features); | ||
185 | setfd( -1 ); // not open | ||
186 | |||
187 | Manufacturer = ""; | ||
188 | } | ||
189 | |||
190 | // internal reinitialize | ||
191 | void OTDriver::reinit() { | ||
192 | bool Old; | ||
193 | Old = IsUp; | ||
194 | |||
195 | if( currentState() < 0 ) | ||
196 | return; | ||
197 | |||
198 | if( Old != IsUp ) { | ||
199 | // state changes | ||
200 | emit stateChange( this, IsUp ); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | // requested by application | ||
205 | int OTDriver::currentState() { | ||
206 | struct hci_dev_info di; | ||
207 | |||
208 | // uint16_t tmp_dev_id = device_info.dev_id; | ||
209 | // bzero(&device_info,sizeof(struct hci_dev_info)); | ||
210 | // device_info.dev_id = tmp_dev_id; | ||
211 | |||
212 | memset( &di, 0, sizeof( di ) ); | ||
213 | di.dev_id = Dev_id; | ||
214 | if( ioctl( OT->getSocket(), HCIGETDEVINFO, (void*)&di) < 0 ) { | ||
215 | SLOT_CloseFd(); | ||
216 | return -1; | ||
217 | } else { | ||
218 | // load new info | ||
219 | init(&di); | ||
220 | } | ||
221 | |||
222 | return IsUp; | ||
223 | } | ||
224 | |||
225 | bool OTDriver::open() { | ||
226 | |||
227 | // (re)start single shot close | ||
228 | AutoClose->start( 30000, TRUE ); | ||
229 | |||
230 | if( isOpen() ) | ||
231 | // is open | ||
232 | return 1; | ||
233 | |||
234 | setfd(hci_open_dev(devId())); | ||
235 | |||
236 | if (fd() < 0) { | ||
237 | emit error( tr( "Can't open device %1. %2 : %3" ). | ||
238 | arg( devname() ). | ||
239 | arg( errno ). | ||
240 | arg( strerror(errno) ) | ||
241 | ); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | return 1; | ||
246 | } | ||
247 | |||
248 | QString OTDriver::name() { | ||
249 | char name[1000]; | ||
250 | |||
251 | if( ! open() ) { | ||
252 | return tr("Cannot open"); | ||
253 | } | ||
254 | |||
255 | if (hci_read_local_name( fd(), sizeof(name), name, 1000) < 0) { | ||
256 | if (errno != ETIMEDOUT) { | ||
257 | emit error( tr("Can't read local name on %1. %2 : %3. Default to %4" ). | ||
258 | arg( devname() ). | ||
259 | arg( errno ). | ||
260 | arg( strerror(errno) ). | ||
261 | arg( devname() ) | ||
262 | ); | ||
263 | } // ETIMEDOUT error is quite normal, device is down ... I think ! :) | ||
264 | strcpy(name,devname().latin1()); | ||
265 | } | ||
266 | return QString(name); | ||
267 | } | ||
268 | |||
269 | void OTDriver::setFlags(unsigned long flags) { | ||
270 | |||
271 | // kdDebug() << "Setting OTDriver Values ..." << endl; | ||
272 | IsUp = BTVALUE(hci_test_bit(HCI_UP, &flags)); | ||
273 | |||
274 | if (isUp()) { | ||
275 | setIScan(BTVALUE(hci_test_bit(HCI_ISCAN, &flags))); | ||
276 | setPScan(BTVALUE(hci_test_bit(HCI_PSCAN, &flags))); | ||
277 | setAuthentication(BTVALUE(hci_test_bit(HCI_AUTH, &flags))); | ||
278 | setEncryption(BTVALUE(hci_test_bit(HCI_ENCRYPT, &flags))); | ||
279 | } else { | ||
280 | setIScan(BT_UNKNOWN); | ||
281 | setPScan(BT_UNKNOWN); | ||
282 | setAuthentication(BT_UNKNOWN); | ||
283 | setEncryption(BT_UNKNOWN); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | QString OTDriver::revision() { | ||
288 | |||
289 | struct hci_version ver; | ||
290 | |||
291 | if( ! open() ) { | ||
292 | return tr("Cannot open"); | ||
293 | } | ||
294 | |||
295 | if (hci_read_local_version(fd(), &ver, 1000) < 0) { | ||
296 | emit error( tr( "Can't read revision info on %1. %2 : %3" ). | ||
297 | arg( devname() ). | ||
298 | arg( errno ). | ||
299 | arg( strerror(errno) ) ); | ||
300 | return QString(); | ||
301 | } | ||
302 | |||
303 | setManufacturer(ver.manufacturer); | ||
304 | |||
305 | switch (ver.manufacturer) { | ||
306 | case 0: | ||
307 | return getRevEricsson(); | ||
308 | break; | ||
309 | case 10: | ||
310 | return getRevCsr(ver.hci_rev); | ||
311 | break; | ||
312 | default: | ||
313 | return tr( "Unsupported manufacturer" ); | ||
314 | break; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | QString OTDriver::getRevEricsson() { | ||
319 | |||
320 | char revision[102]; | ||
321 | struct hci_request rq; | ||
322 | |||
323 | if( ! open() ) { | ||
324 | return QString( "Cannot open" ); | ||
325 | } | ||
326 | |||
327 | memset(&rq, 0, sizeof(rq)); | ||
328 | rq.ogf = 0x3f; | ||
329 | rq.ocf = 0x000f; | ||
330 | rq.cparam = NULL; | ||
331 | rq.clen = 0; | ||
332 | rq.rparam = &revision; | ||
333 | rq.rlen = sizeof(revision); | ||
334 | |||
335 | if (hci_send_req(fd(), &rq, 1000) < 0) { | ||
336 | emit error( tr( "Can't read revision info on %1. %2 : %3" ). | ||
337 | arg( devname() ). | ||
338 | arg( errno ). | ||
339 | arg( strerror(errno) ) ); | ||
340 | return QString(); | ||
341 | } | ||
342 | |||
343 | return QString( revision+1 ); | ||
344 | } | ||
345 | |||
346 | QString OTDriver::getRevCsr( unsigned short rev) { | ||
347 | |||
348 | int i; | ||
349 | |||
350 | for (i = 0; csr_map[i].str; i++) | ||
351 | if (csr_map[i].rev == rev) { | ||
352 | return QString( csr_map[i].str ); | ||
353 | } | ||
354 | |||
355 | return tr( "Unknown firmware" ); | ||
356 | } | ||
357 | |||
358 | int OTDriver::reset() { | ||
359 | |||
360 | if( ! open() ) { | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | if( ioctl(fd(), HCIDEVRESET, devId()) < 0 ) { | ||
365 | if( errno != EALREADY ) { | ||
366 | emit error( tr( "Reset failed for %1. %2 : %3" ). | ||
367 | arg( devname() ). | ||
368 | arg( errno ). | ||
369 | arg( strerror(errno) ) ); | ||
370 | if (errno == EACCES) { | ||
371 | return EACCES; | ||
372 | } | ||
373 | } | ||
374 | } | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | void OTDriver::setUp( bool M ) { | ||
379 | if( M && ! isUp() ) { | ||
380 | bringUp(); | ||
381 | } else if( ! M && isUp() ) { | ||
382 | bringDown(); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | void OTDriver::bringUp() { | ||
387 | |||
388 | owarn << "bringUp : " << Dev << oendl; | ||
389 | |||
390 | if( ! open() ) { | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | if (! isUp()) { | ||
395 | if( ioctl(fd(), HCIDEVUP, devId()) < 0 ) { | ||
396 | if( errno != EALREADY ) { | ||
397 | emit error( tr( "Cannot bring interface %1 up. %2 : %3" ). | ||
398 | arg( devname() ). | ||
399 | arg( errno ). | ||
400 | arg( strerror(errno) ) ); | ||
401 | } | ||
402 | return; | ||
403 | } | ||
404 | // have to wait a bit for the 'up' to become active | ||
405 | QTimer::singleShot( 3000, this, SLOT( reinit() ) ); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | void OTDriver::bringDown() { | ||
410 | |||
411 | owarn << "bringDown : " << Dev << oendl; | ||
412 | |||
413 | if( ! open() ) { | ||
414 | return; | ||
415 | } | ||
416 | |||
417 | if ( isUp() ) { | ||
418 | if( ioctl(fd(), HCIDEVDOWN, devId()) < 0 ) { | ||
419 | if( errno != EALREADY ) { | ||
420 | emit error( tr( "Cannot bring interface %1 down. %2 : %3" ). | ||
421 | arg( devname() ). | ||
422 | arg( errno ). | ||
423 | arg( strerror(errno) ) ); | ||
424 | } | ||
425 | return; | ||
426 | } | ||
427 | reinit(); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | void OTDriver::setScanMode(bool iscan, bool pscan) { | ||
432 | |||
433 | struct hci_dev_req dr; | ||
434 | |||
435 | if( ! open() ) { | ||
436 | return; | ||
437 | } | ||
438 | |||
439 | dr.dev_id = devId(); | ||
440 | dr.dev_opt = SCAN_DISABLED; | ||
441 | |||
442 | if( iscan&&(!pscan) ) | ||
443 | dr.dev_opt = SCAN_INQUIRY; | ||
444 | else if( pscan&&(!iscan) ) | ||
445 | dr.dev_opt = SCAN_PAGE; | ||
446 | else if( pscan&&iscan ) | ||
447 | dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; | ||
448 | |||
449 | if( ioctl(fd(), HCISETSCAN, (unsigned long)&dr) < 0 ) { | ||
450 | if( errno != EALREADY ) { | ||
451 | emit error( tr( "Can't set scan mode on %1. %2 : %3" ). | ||
452 | arg( devname() ). | ||
453 | arg( errno ). | ||
454 | arg( strerror(errno) ) ); | ||
455 | } | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | reinit(); | ||
460 | } | ||
461 | |||
462 | void OTDriver::changeDevName(const char* name) { | ||
463 | |||
464 | if( ! open() ) { | ||
465 | return; | ||
466 | } | ||
467 | |||
468 | if (hci_write_local_name(fd(), name, 1000) < 0) { | ||
469 | emit error( tr( "Can't change local name on %1. %2 : %3" ). | ||
470 | arg( devname() ). | ||
471 | arg( errno ). | ||
472 | arg( strerror(errno) ) ); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | void OTDriver::changeAuthentication(bool _auth) { | ||
477 | struct hci_dev_req dr; | ||
478 | |||
479 | if( ! open() ) { | ||
480 | return; | ||
481 | } | ||
482 | |||
483 | dr.dev_id = devId(); | ||
484 | dr.dev_opt = _auth?AUTH_ENABLED:AUTH_DISABLED; | ||
485 | |||
486 | if (ioctl(fd(),HCISETAUTH,(unsigned long)&dr) < 0) { | ||
487 | if( errno != EALREADY ) { | ||
488 | emit error( tr( "Can't change authentication on %1. %2 : %3" ). | ||
489 | arg( devname() ). | ||
490 | arg( errno ). | ||
491 | arg( strerror(errno) ) ); | ||
492 | } | ||
493 | return; | ||
494 | } | ||
495 | reinit(); | ||
496 | } | ||
497 | |||
498 | void OTDriver::changeEncryption(bool _encrypt) { | ||
499 | struct hci_dev_req dr; | ||
500 | |||
501 | if( ! open() ) { | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | dr.dev_id = devId(); | ||
506 | dr.dev_opt = _encrypt?ENCRYPT_P2P:ENCRYPT_DISABLED; | ||
507 | |||
508 | if (ioctl(fd(),HCISETENCRYPT,(unsigned long)&dr) < 0) { | ||
509 | if( errno != EALREADY ) { | ||
510 | emit error( tr( "Can't change encryption on %1. %2 : %3" ). | ||
511 | arg( devname() ). | ||
512 | arg( errno ). | ||
513 | arg( strerror(errno) ) ); | ||
514 | } | ||
515 | return; | ||
516 | } | ||
517 | |||
518 | reinit(); | ||
519 | } | ||
520 | |||
521 | void OTDriver::changeClass ( unsigned char service, | ||
522 | unsigned char major, | ||
523 | unsigned char minor ) { | ||
524 | unsigned long cod = 0; | ||
525 | cod = (service << 16) | | ||
526 | (major << 8) | | ||
527 | (minor ) ; | ||
528 | |||
529 | if( ! open() ) { | ||
530 | return; | ||
531 | } | ||
532 | |||
533 | if ( hci_write_class_of_dev(fd(),cod,1000) < 0 ) { | ||
534 | emit error( tr( "Can't change class informations for %1. %2 : %3" ). | ||
535 | arg( devname() ). | ||
536 | arg( errno ). | ||
537 | arg( strerror(errno) ) ); | ||
538 | return; | ||
539 | } | ||
540 | } | ||
541 | |||
542 | void OTDriver::getClass( QString & service, | ||
543 | QString & device ) { | ||
544 | unsigned char cls[3]; | ||
545 | |||
546 | if( ! open() ) { | ||
547 | return; | ||
548 | } | ||
549 | |||
550 | if ( hci_read_class_of_dev(fd(),cls,1000) < 0 ) { | ||
551 | emit error( tr( "Can't read class information for %1. %2 : %3" ). | ||
552 | arg( devname() ). | ||
553 | arg( errno ). | ||
554 | arg( strerror(errno) ) ); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | if( cls[2] ) { | ||
559 | int first = 1; | ||
560 | for ( unsigned int s = 0; s < sizeof(*services); s++) { | ||
561 | if (cls[2] & (1 << s)) { | ||
562 | if( !first ) | ||
563 | service += ", "; | ||
564 | service += services[s]; | ||
565 | first = 0; | ||
566 | } | ||
567 | } | ||
568 | } else { | ||
569 | service = "unspecified"; | ||
570 | } | ||
571 | |||
572 | MainClassMap_t * MCM = MainClasses; | ||
573 | int major = cls[1] & 0x1f; | ||
574 | int minor = cls[0] >> 2; | ||
575 | |||
576 | if( (unsigned)(cls[1] & 0x1f) > sizeof(*major_devices)) { | ||
577 | device = tr("Invalid Device Class"); | ||
578 | return; | ||
579 | } | ||
580 | |||
581 | device = major_devices[cls[1] & 0x1f]; | ||
582 | |||
583 | while( MCM->Major != -1 ) { | ||
584 | if( major == MCM->Major ) { | ||
585 | // this class | ||
586 | ClassMap_t * CM = MCM->Map; | ||
587 | if( MCM->Map ) { | ||
588 | while( CM->Minor != -1 ) { | ||
589 | if( minor == CM->Minor ) { | ||
590 | break; | ||
591 | } | ||
592 | CM ++; | ||
593 | } | ||
594 | device = CM->Description; | ||
595 | } else { | ||
596 | // special case | ||
597 | if( major == 3 ) { | ||
598 | /* lan access */ | ||
599 | if( minor == 0 ) { | ||
600 | device = "Uncategorized"; | ||
601 | } else { | ||
602 | switch( minor / 8 ) { | ||
603 | case 0: | ||
604 | device = "Fully available"; | ||
605 | break; | ||
606 | case 1: | ||
607 | device = "1-17% utilized"; | ||
608 | break; | ||
609 | case 2: | ||
610 | device = "17-33% utilized"; | ||
611 | break; | ||
612 | case 3: | ||
613 | device = "33-50% utilized"; | ||
614 | break; | ||
615 | case 4: | ||
616 | device = "50-67% utilized"; | ||
617 | break; | ||
618 | case 5: | ||
619 | device = "67-83% utilized"; | ||
620 | break; | ||
621 | case 6: | ||
622 | device = "83-99% utilized"; | ||
623 | break; | ||
624 | case 7: | ||
625 | device = "No service available"; | ||
626 | break; | ||
627 | } | ||
628 | } | ||
629 | } else if( major == 6 ) { /* imaging */ | ||
630 | if (minor & 4) | ||
631 | device = "Display"; | ||
632 | if (minor & 8) | ||
633 | device = "Camera"; | ||
634 | if (minor & 16) | ||
635 | device = "Scanner"; | ||
636 | if (minor & 32) | ||
637 | device = "Printer"; | ||
638 | } | ||
639 | } | ||
640 | break; | ||
641 | } | ||
642 | MCM ++; | ||
643 | } | ||
644 | |||
645 | if( MCM->Major == -1 ) { | ||
646 | device = "Unknown (reserved) minor device class"; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | QString OTDriver::strType() { | ||
651 | return QString( hci_dtypetostr(Type) ); | ||
652 | } | ||
653 | |||
654 | void OTDriver::setFeatures( unsigned char * _f) { | ||
655 | Features = lmp_featurestostr(_f, NULL, 255); | ||
656 | } | ||
657 | |||
658 | void OTDriver::setManufacturer(int compid) { | ||
659 | Manufacturer = bt_compidtostr(compid); | ||
660 | } | ||
661 | |||
662 | OTHCISocket * OTDriver::openSocket( void ) { | ||
663 | if( ! Socket ) { | ||
664 | owarn << "Open HCI socket to " << devname() << oendl; | ||
665 | Socket = new OTHCISocket( this ); | ||
666 | } | ||
667 | return Socket; | ||
668 | } | ||
669 | |||
670 | void OTDriver::closeSocket( void ) { | ||
671 | if( Socket ) { | ||
672 | owarn << "Close HCI socket to " << devname() << oendl; | ||
673 | delete Socket; | ||
674 | Socket = 0; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | QString OTDriver::getPeerName( const OTDeviceAddress & PAddr ) { | ||
679 | QString S; | ||
680 | char name[100 ]; | ||
681 | |||
682 | if( ! open() ) { | ||
683 | return QString("N/A"); | ||
684 | } | ||
685 | |||
686 | if( hci_read_remote_name( fd(), | ||
687 | &(PAddr.getBDAddr()), | ||
688 | sizeof(name), | ||
689 | name, | ||
690 | 100000 ) < 0 ) { | ||
691 | return QString( "N/A" ); | ||
692 | } | ||
693 | |||
694 | return QString( name ); | ||
695 | } | ||
696 | |||
697 | long OTDriver::getLinkQuality( const OTDeviceAddress & Addr ) { | ||
698 | struct hci_conn_info_req *cr; | ||
699 | struct hci_request rq; | ||
700 | read_rssi_rp rp; | ||
701 | uint16_t handle; | ||
702 | |||
703 | if( ! open() ) { | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | cr = (struct hci_conn_info_req *)malloc( | ||
708 | sizeof(*cr) + sizeof(struct hci_conn_info)); | ||
709 | if (!cr) | ||
710 | return 0; | ||
711 | |||
712 | bacpy( &(cr->bdaddr), &(Addr.getBDAddr()) ); | ||
713 | cr->type = ACL_LINK; | ||
714 | |||
715 | if (ioctl( fd(), HCIGETCONNINFO, (unsigned long) cr) < 0) { | ||
716 | owarn << "Get connection info failed" << oendl; | ||
717 | free(cr); | ||
718 | return 0; | ||
719 | } | ||
720 | |||
721 | handle = htobs(cr->conn_info->handle); | ||
722 | |||
723 | free(cr); | ||
724 | |||
725 | memset(&rq, 0, sizeof(rq)); | ||
726 | rq.ogf = OGF_STATUS_PARAM; | ||
727 | rq.ocf = OCF_READ_RSSI; | ||
728 | rq.cparam = &handle; | ||
729 | rq.clen = 2; | ||
730 | rq.rparam = &rp; | ||
731 | rq.rlen = GET_LINK_QUALITY_RP_SIZE; | ||
732 | |||
733 | if (hci_send_req( fd(), &rq, 100) < 0) { | ||
734 | owarn << "Get connection info failed" << oendl; | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | if( rp.status ) { | ||
739 | owarn << QString().sprintf("HCI get_link_quality cmd failed (0x%2.2X)", rp.status) << oendl; | ||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | return rp.rssi+50; | ||
744 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDriver.h b/noncore/settings/networksettings2/opietooth2/OTDriver.h new file mode 100644 index 0000000..b54ffdf --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDriver.h | |||
@@ -0,0 +1,232 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2003 by Mattia Merzi * | ||
3 | * ottobit@ferrara.linux.it * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | ***************************************************************************/ | ||
10 | |||
11 | #ifndef OTDRIVER_H | ||
12 | #define OTDRIVER_H | ||
13 | |||
14 | /* | ||
15 | * This class handles the connection with the BlueZ libraries, implements | ||
16 | * most of the bluetooth-related functions and owns the KBTDevice class | ||
17 | * that is a single local bluetooth device representation. | ||
18 | * It is used as a Singleton pattern thru the getDefaultConnector() method. | ||
19 | * | ||
20 | */ | ||
21 | #include <qobject.h> | ||
22 | #include <opie2/odebug.h> | ||
23 | #include <bluezlib.h> | ||
24 | |||
25 | #include <OTDeviceAddress.h> | ||
26 | |||
27 | namespace Opietooth2 { | ||
28 | |||
29 | class OTGateway; | ||
30 | class OTHCISocket; | ||
31 | class OTDeviceAddress; | ||
32 | class OTPeer; | ||
33 | |||
34 | /* | ||
35 | * This is the representation of a | ||
36 | * Bluetooth device for the local | ||
37 | * machine. | ||
38 | */ | ||
39 | class OTDriver : public QObject { | ||
40 | |||
41 | Q_OBJECT | ||
42 | |||
43 | public: | ||
44 | |||
45 | OTDriver( OTGateway * Ot, struct hci_dev_info* di); | ||
46 | ~OTDriver(); | ||
47 | |||
48 | inline OTGateway * gateway() const | ||
49 | { return OT; } | ||
50 | |||
51 | /* | ||
52 | * Initializes the device using the passed hci_dev_info | ||
53 | * struct, contining the basic information in order to | ||
54 | * talk with the pyisical device. | ||
55 | */ | ||
56 | void init(struct hci_dev_info* di); | ||
57 | |||
58 | /* | ||
59 | * Open the device and obtains a file descriptor to id | ||
60 | * return if open | ||
61 | */ | ||
62 | bool open(); | ||
63 | |||
64 | OTHCISocket * openSocket(); | ||
65 | |||
66 | void closeSocket(); | ||
67 | |||
68 | /* | ||
69 | * Return true if the device is opened. | ||
70 | */ | ||
71 | int isOpen() | ||
72 | { return Fd != -1; }; | ||
73 | |||
74 | /* | ||
75 | * Calls the ioctl(HCIDEVRESET) in order to | ||
76 | * reset the device. | ||
77 | */ | ||
78 | int reset(); | ||
79 | |||
80 | // set Up if true and not yet up | ||
81 | void setUp( bool Mode ); | ||
82 | |||
83 | /* | ||
84 | * Turn the device up and the reinitializes the device. | ||
85 | * If the device is already up, nothing is done. | ||
86 | */ | ||
87 | void bringUp(); | ||
88 | |||
89 | /* | ||
90 | * Turn the device down and the reinitializes the device. | ||
91 | * If the device is already down, nothing is done. | ||
92 | */ | ||
93 | void bringDown(); | ||
94 | |||
95 | // is the device UP now | ||
96 | bool isUp() const | ||
97 | { return IsUp; } | ||
98 | |||
99 | // get current state | ||
100 | // return 1 if UP, 0 if DOWN, -1 if ERROR | ||
101 | int currentState(); | ||
102 | |||
103 | /* | ||
104 | * Returns the name of the device. If the device is | ||
105 | * down, the device id is returned. | ||
106 | */ | ||
107 | QString name(); | ||
108 | |||
109 | int devId() const | ||
110 | { return Dev_id; }; | ||
111 | |||
112 | /* | ||
113 | * Returns the string representation of the device id, | ||
114 | * with the same format of the hciconfig tool. | ||
115 | */ | ||
116 | QString devname() | ||
117 | { return Dev; }; | ||
118 | |||
119 | /* | ||
120 | * Returns the file descriptor for the local | ||
121 | * connection to this device | ||
122 | */ | ||
123 | int fd() const | ||
124 | { return Fd; }; | ||
125 | void setfd(int _fd) | ||
126 | { Fd = _fd; }; | ||
127 | |||
128 | void setType(int _type) | ||
129 | { Type = _type; }; | ||
130 | int type() const | ||
131 | { return Type; }; | ||
132 | QString strType(); | ||
133 | |||
134 | int iscan() const | ||
135 | { return Iscan; } | ||
136 | void setIScan(int _iscan) | ||
137 | { Iscan = _iscan; } | ||
138 | |||
139 | int pscan() const | ||
140 | { return Pscan; } | ||
141 | void setPScan(int _pscan) | ||
142 | { Pscan = _pscan; } | ||
143 | |||
144 | int authentication() const | ||
145 | { return Auth; } | ||
146 | void setAuthentication(int _auth) | ||
147 | { Auth = _auth; } | ||
148 | |||
149 | int encryption() const | ||
150 | { return Encrypt; } | ||
151 | void setEncryption(int _encrypt) | ||
152 | { Encrypt = _encrypt; } | ||
153 | |||
154 | void setDevId(int _dev_id) | ||
155 | { Dev_id = _dev_id; }; | ||
156 | void setDev(char* _dev) | ||
157 | { Dev = _dev; }; | ||
158 | |||
159 | void setFlags( unsigned long flags); | ||
160 | |||
161 | const OTDeviceAddress & address() | ||
162 | { return Address; } | ||
163 | |||
164 | void setFeatures( unsigned char * _f); | ||
165 | QString features() | ||
166 | { return Features; } | ||
167 | |||
168 | void setManufacturer(int compid); | ||
169 | QString manufacturer() | ||
170 | { return Manufacturer; } | ||
171 | |||
172 | QString revision(); | ||
173 | |||
174 | void setScanMode(bool iscan, bool pscan); | ||
175 | void setClass(unsigned long cls); | ||
176 | |||
177 | void changeDevName(const char* name); | ||
178 | void changeEncryption(bool _encryption); | ||
179 | void changeAuthentication(bool _auth); | ||
180 | |||
181 | void getClass( QString & service, | ||
182 | QString & device ); | ||
183 | void changeClass( unsigned char service, | ||
184 | unsigned char major, | ||
185 | unsigned char minor); | ||
186 | |||
187 | QString getPeerName( const OTDeviceAddress & PAddr ); | ||
188 | |||
189 | // address must be connected to this driver | ||
190 | long getLinkQuality( const OTDeviceAddress & Address ); | ||
191 | |||
192 | signals : | ||
193 | |||
194 | void error( const QString & ); | ||
195 | void stateChange( OTDriver * , bool ); | ||
196 | void driverDisappeared( OTDriver * ); | ||
197 | |||
198 | private slots : | ||
199 | |||
200 | /* | ||
201 | * Reinitializes the device, obtaining a fresh | ||
202 | * hci_dev_info structure. | ||
203 | */ | ||
204 | void reinit(); | ||
205 | void SLOT_CloseFd(); | ||
206 | |||
207 | private: | ||
208 | |||
209 | QString getRevEricsson(); | ||
210 | QString getRevCsr(unsigned short rev); | ||
211 | |||
212 | QString Name; | ||
213 | QString Dev; | ||
214 | QString Revision; | ||
215 | QString Manufacturer; | ||
216 | OTDeviceAddress Address; | ||
217 | QString Features; | ||
218 | QTimer * AutoClose; | ||
219 | |||
220 | int Dev_id,Fd,Type; | ||
221 | bool IsUp; | ||
222 | int Iscan,Pscan,Auth,Encrypt; | ||
223 | |||
224 | // socket bound to this device | ||
225 | OTHCISocket * Socket; | ||
226 | |||
227 | // backpointer to opietooth system | ||
228 | OTGateway * OT; | ||
229 | }; | ||
230 | |||
231 | } | ||
232 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDriverList.cpp b/noncore/settings/networksettings2/opietooth2/OTDriverList.cpp new file mode 100644 index 0000000..f703834 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDriverList.cpp | |||
@@ -0,0 +1,86 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2003 by Mattia Merzi * | ||
3 | * ottobit@ferrara.linux.it * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | ***************************************************************************/ | ||
10 | |||
11 | #include <malloc.h> | ||
12 | #include <bluezlib.h> | ||
13 | |||
14 | #include <opie2/odebug.h> | ||
15 | |||
16 | #include <OTDriverList.h> | ||
17 | #include <OTGateway.h> | ||
18 | #include <OTDriver.h> | ||
19 | |||
20 | using namespace Opietooth2; | ||
21 | |||
22 | OTDriverList::OTDriverList( OTGateway * _OT ) : QVector<OTDriver>() { | ||
23 | |||
24 | OT = _OT; | ||
25 | setAutoDelete( true ); | ||
26 | } | ||
27 | |||
28 | OTDriverList::~OTDriverList() { | ||
29 | } | ||
30 | |||
31 | void OTDriverList::update() { | ||
32 | |||
33 | struct hci_dev_list_req *dl; | ||
34 | struct hci_dev_req *dr; | ||
35 | struct hci_dev_info di; | ||
36 | int cur; | ||
37 | |||
38 | dl = 0; | ||
39 | cur = 0; | ||
40 | do { | ||
41 | cur += 5; | ||
42 | |||
43 | dl = (struct hci_dev_list_req*) | ||
44 | ::realloc( dl, sizeof( struct hci_dev_list_req ) + | ||
45 | ( cur * sizeof(struct hci_dev_req) ) | ||
46 | ); | ||
47 | |||
48 | if( dl == 0 ) { | ||
49 | // memory problem | ||
50 | exit(1); | ||
51 | } | ||
52 | |||
53 | dl->dev_num = cur; | ||
54 | |||
55 | if( ioctl( OT->getSocket(), HCIGETDEVLIST, (void*)dl) ) { | ||
56 | owarn << "WARNING : cannot read device list. " | ||
57 | << errno | ||
58 | << strerror( errno ) << oendl; | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | // if num == cur perhaps we did not get all devices yet | ||
63 | } while( dl->dev_num == cur ); | ||
64 | |||
65 | if( dl->dev_num != count() ) { | ||
66 | // new or missing devices | ||
67 | clear(); | ||
68 | |||
69 | dr = dl->dev_req; | ||
70 | resize( dl->dev_num ); | ||
71 | |||
72 | for( cur=0; cur < dl->dev_num; cur ++) { | ||
73 | memset( &di, 0, sizeof( di ) ); | ||
74 | di.dev_id = (dr+cur)->dev_id; | ||
75 | |||
76 | // get device info | ||
77 | if( ioctl( OT->getSocket(), HCIGETDEVINFO, (void*)&di) != 0 ) | ||
78 | continue; // uh ? | ||
79 | insert( cur, new OTDriver( OT, &di ) ); | ||
80 | } | ||
81 | |||
82 | owarn << "Found " << count() << " devices" << oendl; | ||
83 | |||
84 | ::free( dl ); | ||
85 | } | ||
86 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTDriverList.h b/noncore/settings/networksettings2/opietooth2/OTDriverList.h new file mode 100644 index 0000000..c98ffa0 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTDriverList.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2003 by Mattia Merzi * | ||
3 | * ottobit@ferrara.linux.it * | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | ***************************************************************************/ | ||
10 | |||
11 | #ifndef OTDRIVERLIST_H | ||
12 | #define OTDRIVERLIST_H | ||
13 | |||
14 | #include <qvector.h> | ||
15 | |||
16 | namespace Opietooth2 { | ||
17 | |||
18 | class OTDriver; | ||
19 | class OTGateway; | ||
20 | |||
21 | class OTDriverList : public QVector<OTDriver> { | ||
22 | |||
23 | public: | ||
24 | |||
25 | OTDriverList( OTGateway * _OT ); | ||
26 | ~OTDriverList(); | ||
27 | |||
28 | inline OTGateway * gateway() const | ||
29 | { return OT; } | ||
30 | |||
31 | void update(); | ||
32 | |||
33 | private: | ||
34 | |||
35 | // backpointer | ||
36 | OTGateway * OT; | ||
37 | }; | ||
38 | |||
39 | } | ||
40 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTGateway.cpp b/noncore/settings/networksettings2/opietooth2/OTGateway.cpp new file mode 100644 index 0000000..2d13ce9 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTGateway.cpp | |||
@@ -0,0 +1,773 @@ | |||
1 | #include <qmessagebox.h> | ||
2 | #include <qfile.h> | ||
3 | #include <qdir.h> | ||
4 | #include <qtextstream.h> | ||
5 | #include <qpixmap.h> | ||
6 | #include <qvector.h> | ||
7 | #include <qpe/resource.h> | ||
8 | |||
9 | #include <opie2/odebug.h> | ||
10 | |||
11 | #include <bluezlib.h> | ||
12 | |||
13 | #include <OTDevice.h> | ||
14 | #include <OTDriver.h> | ||
15 | #include <OTInquiry.h> | ||
16 | #include <OTDriverList.h> | ||
17 | #include <OTDeviceAddress.h> | ||
18 | #include <OTGateway.h> | ||
19 | |||
20 | using namespace Opietooth2; | ||
21 | |||
22 | // single instance | ||
23 | OTGateway * OTGateway::SingleGateway = 0; | ||
24 | int OTGateway::UseCount = 0; | ||
25 | |||
26 | OTGateway * OTGateway::getOTGateway( void ) { | ||
27 | if(SingleGateway == 0 ) { | ||
28 | SingleGateway = new OTGateway(); | ||
29 | } | ||
30 | |||
31 | UseCount ++; | ||
32 | return SingleGateway; | ||
33 | } | ||
34 | |||
35 | void OTGateway::releaseOTGateway( void ) { | ||
36 | UseCount --; | ||
37 | if( UseCount == 0 ) { | ||
38 | delete SingleGateway; | ||
39 | SingleGateway = 0; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | // open bluetooth system | ||
44 | OTGateway::OTGateway( void ) : QObject( 0, "OTGateway" ), | ||
45 | AllDrivers( this ), | ||
46 | AllPeers() { | ||
47 | |||
48 | ErrorConnectCount = 0; | ||
49 | TheOTDevice = 0; | ||
50 | Scanning = 0; | ||
51 | AllPeersModified = 0; | ||
52 | AllPeers.setAutoDelete( TRUE ); | ||
53 | |||
54 | if ( ( HciCtl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { | ||
55 | SLOT_ShowError( tr( "error opening hci socket" ) ); | ||
56 | return; | ||
57 | } | ||
58 | |||
59 | // load all known devices | ||
60 | updateDrivers(); | ||
61 | |||
62 | // load all peers we have ever seen | ||
63 | loadKnownPeers(); | ||
64 | |||
65 | // iterate over drivers and find active connections | ||
66 | // adding/updating peers | ||
67 | loadActiveConnections(); | ||
68 | |||
69 | // check every 4 seconds the state of BT | ||
70 | timerEvent(0); | ||
71 | RefreshTimer = -1; | ||
72 | setRefreshTimer( 4000 ); | ||
73 | |||
74 | // load known link keys | ||
75 | readLinkKeys(); | ||
76 | } | ||
77 | |||
78 | // close bluetooth system | ||
79 | OTGateway::~OTGateway( void ) { | ||
80 | |||
81 | if( AllPeersModified ) { | ||
82 | saveKnownPeers(); | ||
83 | } | ||
84 | |||
85 | if( Scanning ) | ||
86 | delete Scanning; | ||
87 | |||
88 | if( TheOTDevice ) | ||
89 | delete TheOTDevice; | ||
90 | |||
91 | if( HciCtl >= 0 ) { | ||
92 | ::close( HciCtl ); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void OTGateway::setRefreshTimer( int T ) { | ||
97 | if( RefreshTimer != -1 ) { | ||
98 | killTimer( RefreshTimer ); | ||
99 | } | ||
100 | |||
101 | if( T == 0 ) | ||
102 | T = 4000; | ||
103 | RefreshTimer = startTimer( T ); | ||
104 | } | ||
105 | |||
106 | OTDevice * OTGateway::getOTDevice( ) { | ||
107 | if( TheOTDevice == 0 ) { | ||
108 | // load bluetooth device and check state | ||
109 | TheOTDevice = new OTDevice( this ); | ||
110 | connect( TheOTDevice, | ||
111 | SIGNAL( isEnabled( int, bool ) ), | ||
112 | this, | ||
113 | SLOT( SLOT_Enabled( int, bool ) ) ); | ||
114 | |||
115 | connect( TheOTDevice, | ||
116 | SIGNAL( error( const QString & ) ), | ||
117 | this, | ||
118 | SLOT( SLOT_ShowError( const QString & ) ) ); | ||
119 | } | ||
120 | |||
121 | return TheOTDevice; | ||
122 | } | ||
123 | |||
124 | // start bluetooth (if stopped) | ||
125 | // return TRUE if started | ||
126 | void OTGateway::SLOT_SetEnabled( bool Mode ) { | ||
127 | if( Mode ) { | ||
128 | SLOT_Enable(); | ||
129 | return; | ||
130 | } | ||
131 | SLOT_Disable(); | ||
132 | } | ||
133 | |||
134 | void OTGateway::SLOT_Enable() { | ||
135 | getOTDevice()->attach(); | ||
136 | } | ||
137 | |||
138 | void OTGateway::SLOT_Disable() { | ||
139 | getOTDevice()->detach(); | ||
140 | } | ||
141 | |||
142 | bool OTGateway::needsEnabling() { | ||
143 | return getOTDevice()->needsAttach(); | ||
144 | } | ||
145 | |||
146 | bool OTGateway::isEnabled() { | ||
147 | if( getOTDevice()->deviceNr() >= 0 && | ||
148 | driver( getOTDevice()->deviceNr() )->isUp() ) | ||
149 | return TRUE; | ||
150 | |||
151 | // else check system | ||
152 | return getOTDevice()->isAttached(); | ||
153 | } | ||
154 | |||
155 | void OTGateway::SLOT_ShowError( const QString & S ) { | ||
156 | |||
157 | owarn << S << oendl; | ||
158 | |||
159 | if( ErrorConnectCount > 0 ) { | ||
160 | // pass error | ||
161 | emit error( QString( "<p>" ) + S + "</p>" ); | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | QMessageBox::warning( 0, | ||
166 | tr("OTGateway error"), | ||
167 | S ); | ||
168 | } | ||
169 | |||
170 | void OTGateway::connectNotify( const char * S ) { | ||
171 | if( strcmp( S, "error(const QString&)" ) == 0 ) { | ||
172 | ErrorConnectCount ++; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | void OTGateway::disconnectNotify( const char * S ) { | ||
177 | if( strcmp( S, "error(const QString&)" ) == 0 ) { | ||
178 | ErrorConnectCount --; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | void OTGateway::timerEvent( QTimerEvent * ) { | ||
183 | |||
184 | OTDriver * D; | ||
185 | unsigned int oldc = AllDrivers.count(); | ||
186 | bool old; | ||
187 | |||
188 | AllDrivers.update(); | ||
189 | |||
190 | if( oldc != AllDrivers.count() ) { | ||
191 | updateDrivers(); | ||
192 | } else { | ||
193 | for( unsigned int i = 0; | ||
194 | i < AllDrivers.count(); | ||
195 | i ++ ) { | ||
196 | D = AllDrivers[i]; | ||
197 | old = D->isUp(); | ||
198 | if( D->currentState() >= 0 ) { | ||
199 | if( old != D->isUp() ) { | ||
200 | emit stateChange( D, D->isUp() ); | ||
201 | } | ||
202 | } else { | ||
203 | // if one driver is unable to provide info | ||
204 | // we refresh all devices | ||
205 | updateDrivers(); | ||
206 | return; | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | void OTGateway::SLOT_Enabled( int id, bool Up ) { | ||
213 | owarn << "device " << id << " state " << Up << oendl; | ||
214 | if( Up ) { | ||
215 | // device is up -> detect it | ||
216 | updateDrivers(); | ||
217 | if( (unsigned)id >= AllDrivers.count() ) { | ||
218 | // to make sure that the driver really IS detected | ||
219 | AllDrivers[id]->bringUp(); | ||
220 | } | ||
221 | } // if DOWN device already down | ||
222 | emit deviceEnabled( Up ); | ||
223 | } | ||
224 | |||
225 | void OTGateway::updateDrivers( void ) { | ||
226 | OTDriver * D; | ||
227 | |||
228 | AllDrivers.update(); | ||
229 | |||
230 | owarn << "updated drivers. now " << AllDrivers.count() << oendl; | ||
231 | |||
232 | // connect signals for each driver | ||
233 | for( unsigned int i = 0; | ||
234 | i < AllDrivers.count(); | ||
235 | i ++ ) { | ||
236 | D = AllDrivers[i]; | ||
237 | |||
238 | connect( D, | ||
239 | SIGNAL( error( const QString & ) ), | ||
240 | this, | ||
241 | SLOT( SLOT_ShowError( const QString & ) ) | ||
242 | ); | ||
243 | |||
244 | connect( D, | ||
245 | SIGNAL( stateChange( OTDriver *, bool ) ), | ||
246 | this, | ||
247 | SIGNAL( stateChange( OTDriver *, bool ) ) | ||
248 | ); | ||
249 | |||
250 | connect( D, | ||
251 | SIGNAL( driverDisappeared( OTDriver * ) ), | ||
252 | this, | ||
253 | SLOT( SLOT_DriverDisappeared( OTDriver * ) ) | ||
254 | ); | ||
255 | } | ||
256 | |||
257 | // verify main device too | ||
258 | if( TheOTDevice ) | ||
259 | TheOTDevice->checkAttach(); | ||
260 | |||
261 | // set to default scanning hardware | ||
262 | setScanWith( 0 ); | ||
263 | |||
264 | emit driverListChanged(); | ||
265 | } | ||
266 | |||
267 | void OTGateway::SLOT_DriverDisappeared( OTDriver * D ) { | ||
268 | owarn << "Driver " << D->devname() << " when offline" << oendl; | ||
269 | updateDrivers(); | ||
270 | } | ||
271 | |||
272 | void OTGateway::scanNeighbourhood( OTDriver * D ) { | ||
273 | |||
274 | if( Scanning ) { | ||
275 | stopScanOfNeighbourhood(); | ||
276 | } | ||
277 | |||
278 | if( D ) { | ||
279 | setScanWith( D ); | ||
280 | } | ||
281 | |||
282 | Scanning = new OTInquiry( scanWith() ); | ||
283 | |||
284 | connect( Scanning, | ||
285 | SIGNAL( peerFound( OTPeer *, bool )), | ||
286 | this, | ||
287 | SLOT( SLOT_PeerDetected( OTPeer *, bool ) ) | ||
288 | ); | ||
289 | connect( Scanning, | ||
290 | SIGNAL( finished()), | ||
291 | this, | ||
292 | SLOT( SLOT_FinishedDetecting() ) | ||
293 | ); | ||
294 | |||
295 | // start scanning | ||
296 | Scanning->inquire( 30.0 ); | ||
297 | } | ||
298 | |||
299 | OTPeer* OTGateway::findPeer( const OTDeviceAddress & Addr ) { | ||
300 | for( unsigned int i = 0 ; i < AllPeers.count(); i ++ ) { | ||
301 | if( AllPeers[i]->address() == Addr ) { | ||
302 | return AllPeers[i]; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | OTDriver* OTGateway::findDriver( const OTDeviceAddress & Addr ) { | ||
309 | for( unsigned int i = 0 ; i < AllDrivers.count(); i ++ ) { | ||
310 | if( AllDrivers[i]->address() == Addr ) { | ||
311 | return AllDrivers[i]; | ||
312 | } | ||
313 | } | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | void OTGateway::SLOT_PeerDetected( OTPeer * P, bool IsNew ) { | ||
318 | |||
319 | if( IsNew ) { | ||
320 | // new peer | ||
321 | owarn << "New peer " << P->name() << oendl; | ||
322 | addPeer( P ); | ||
323 | } | ||
324 | |||
325 | emit detectedPeer( P, IsNew ); | ||
326 | } | ||
327 | |||
328 | void OTGateway::addPeer( OTPeer * P ) { | ||
329 | AllPeers.resize( AllPeers.size()+1); | ||
330 | AllPeers.insert( AllPeers.size()-1, P ); | ||
331 | AllPeersModified = 1; | ||
332 | } | ||
333 | |||
334 | void OTGateway::removePeer( OTPeer * P ) { | ||
335 | int i = AllPeers.find( P ); | ||
336 | if( i ) { | ||
337 | AllPeers.remove( i ); | ||
338 | AllPeersModified = 1; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | void OTGateway::stopScanOfNeighbourhood( void ) { | ||
343 | if( Scanning ) { | ||
344 | delete Scanning; | ||
345 | Scanning = 0; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | void OTGateway::SLOT_FinishedDetecting() { | ||
350 | stopScanOfNeighbourhood(); | ||
351 | emit finishedDetecting(); | ||
352 | } | ||
353 | |||
354 | const char * OTGateway::deviceTypeToName( int cls ) { | ||
355 | switch ( (cls & 0x001F00) >> 8) { | ||
356 | case 0x00: | ||
357 | return "misc"; | ||
358 | case 0x01: | ||
359 | return "computer"; | ||
360 | case 0x02: | ||
361 | return "phone"; | ||
362 | case 0x03: | ||
363 | return "lan"; | ||
364 | case 0x04: | ||
365 | return "av"; | ||
366 | case 0x05: | ||
367 | return "peripheral"; | ||
368 | case 0x06: | ||
369 | return "imaging"; | ||
370 | case 0x07: | ||
371 | default : | ||
372 | break; | ||
373 | } | ||
374 | return "unknown"; | ||
375 | } | ||
376 | |||
377 | PANConnectionVector OTGateway::getPANConnections( void ) { | ||
378 | PANConnectionVector V; | ||
379 | |||
380 | struct bnep_connlist_req req; | ||
381 | struct bnep_conninfo ci[48]; | ||
382 | |||
383 | V.setAutoDelete(TRUE); | ||
384 | |||
385 | int ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); | ||
386 | if (ctl < 0) { | ||
387 | owarn << "Failed to open control socket" << oendl; | ||
388 | return V; | ||
389 | } | ||
390 | |||
391 | req.cnum = 48; | ||
392 | req.ci = ci; | ||
393 | if (ioctl(ctl, BNEPGETCONNLIST, &req)) { | ||
394 | owarn << "Failed to get connection list" << oendl; | ||
395 | ::close( ctl ); | ||
396 | return V; | ||
397 | } | ||
398 | |||
399 | for ( unsigned i=0; i < req.cnum; i++) { | ||
400 | V.resize( V.size() + 1 ); | ||
401 | if( ci[i].role == BNEP_SVC_PANU ) { | ||
402 | // we are the client | ||
403 | V.insert( V.size()-1, new OTPANConnection( | ||
404 | ci[i].device, | ||
405 | batostr((bdaddr_t *) ci[i].dst) | ||
406 | ) ); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | ::close( ctl ); | ||
411 | return V; | ||
412 | } | ||
413 | |||
414 | struct link_key { | ||
415 | bdaddr_t sba; | ||
416 | bdaddr_t dba; | ||
417 | uint8_t key[16]; | ||
418 | uint8_t type; | ||
419 | time_t time; | ||
420 | }; | ||
421 | |||
422 | void OTGateway::readLinkKeys( void ) { | ||
423 | |||
424 | struct link_key k; | ||
425 | int rv; | ||
426 | |||
427 | AllKeys.truncate(0); | ||
428 | |||
429 | QFile F( "/etc/bluetooth/link_key" ); | ||
430 | |||
431 | if( ! F.open( IO_ReadOnly ) ) { | ||
432 | emit error( tr("Cannot open link_key file") ); | ||
433 | return; | ||
434 | } | ||
435 | |||
436 | while( 1 ) { | ||
437 | rv = F.readBlock( (char *)&k, sizeof( k ) ); | ||
438 | if( rv == 0 ) | ||
439 | // EOF | ||
440 | break; | ||
441 | |||
442 | if( rv < 0 ) { | ||
443 | emit error( tr("Read error in link key file") ); | ||
444 | } | ||
445 | |||
446 | AllKeys.resize( AllKeys.size()+1 ); | ||
447 | AllKeys[ AllKeys.size()-1 ].From.setBDAddr( k.sba ); | ||
448 | AllKeys[ AllKeys.size()-1 ].To.setBDAddr( k.dba ); | ||
449 | } | ||
450 | } | ||
451 | |||
452 | bool OTGateway::removeLinkKey( unsigned int Index ) { | ||
453 | OTLinkKey & LK = AllKeys[Index]; | ||
454 | |||
455 | struct link_key k; | ||
456 | int rv; | ||
457 | |||
458 | QFile F( "/etc/bluetooth/link_key" ); | ||
459 | QFile OutF( "/etc/bluetooth/newlink_key" ); | ||
460 | |||
461 | if( ! F.open( IO_ReadOnly ) ) { | ||
462 | emit error( tr("Cannot open link_key file") ); | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | if( ! OutF.open( IO_WriteOnly | IO_Truncate ) ) { | ||
467 | emit error( tr("Cannot open temporary link_key file") ); | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | while( 1 ) { | ||
472 | rv = F.readBlock( (char *)&k, sizeof( k ) ); | ||
473 | if( rv == 0 ) | ||
474 | // EOF | ||
475 | break; | ||
476 | |||
477 | if( rv < 0 ) { | ||
478 | emit error( tr("Read error in link key file") ); | ||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | if( LK.from() != OTDeviceAddress( k.sba ) || | ||
483 | LK.to() != OTDeviceAddress( k.dba ) ) { | ||
484 | // copy | ||
485 | OutF.writeBlock( (char *)&k, sizeof( k ) ); | ||
486 | } // else remove this key | ||
487 | } | ||
488 | |||
489 | // rename files | ||
490 | QDir D( "/etc/bluetooth" ); | ||
491 | |||
492 | D.remove( "link_key" ); | ||
493 | D.rename( "newlink_key", "link_key" ); | ||
494 | |||
495 | // restart hcid | ||
496 | system( "/etc/init.d/hcid stop" ); | ||
497 | system( "/etc/init.d/hcid start" ); | ||
498 | |||
499 | // remove from table | ||
500 | if( Index < (AllKeys.size()-1) ) { | ||
501 | // collapse array | ||
502 | AllKeys[Index] = AllKeys[AllKeys.size()-1]; | ||
503 | } | ||
504 | |||
505 | // remove last element | ||
506 | AllKeys.resize( AllKeys.size()-1 ); | ||
507 | |||
508 | return 1; | ||
509 | } | ||
510 | |||
511 | #define MAXCONNECTIONS 10 | ||
512 | void OTGateway::loadActiveConnections( void ) { | ||
513 | |||
514 | struct hci_conn_list_req *cl; | ||
515 | struct hci_conn_info *ci; | ||
516 | OTDeviceAddress Addr; | ||
517 | OTPeer * P; | ||
518 | |||
519 | if (!(cl = (struct hci_conn_list_req *)malloc( | ||
520 | MAXCONNECTIONS * sizeof(*ci) + sizeof(*cl)))) { | ||
521 | emit error( tr("Can't allocate memory") ); | ||
522 | return; | ||
523 | } | ||
524 | memset( cl, 0, MAXCONNECTIONS * sizeof(*ci) + sizeof(*cl) ); | ||
525 | |||
526 | for( unsigned int i = 0; | ||
527 | i < AllDrivers.count(); | ||
528 | i ++ ) { | ||
529 | |||
530 | if( ! AllDrivers[i]->isUp() ) { | ||
531 | continue; | ||
532 | } | ||
533 | |||
534 | // driver is up -> check connections | ||
535 | cl->dev_id = AllDrivers[i]->devId(); | ||
536 | cl->conn_num = MAXCONNECTIONS; | ||
537 | ci = cl->conn_info; | ||
538 | |||
539 | if (ioctl( getSocket(), HCIGETCONNLIST, (void *) cl)) { | ||
540 | emit error( tr("Can't get connection list") ); | ||
541 | break; | ||
542 | } | ||
543 | |||
544 | for ( int k = 0; k < cl->conn_num; k++, ci++) { | ||
545 | |||
546 | if( ci->state != BT_CONNECTED ) { | ||
547 | // not yet connected | ||
548 | continue; | ||
549 | } | ||
550 | |||
551 | Addr.setBDAddr( ci->bdaddr ); | ||
552 | P = findPeer( Addr ); | ||
553 | if( ! P ) { | ||
554 | // peer not yet known -> add | ||
555 | P = new OTPeer( this ); | ||
556 | addPeer( P ); | ||
557 | P->setAddress( Addr ); | ||
558 | // infoQueue.push_back(info); | ||
559 | P->setName( AllDrivers[i]->getPeerName( Addr ) ); | ||
560 | } | ||
561 | P->setState( OTPeer::Peer_Up ); | ||
562 | P->setConnectedTo( AllDrivers[i] ); | ||
563 | } | ||
564 | } | ||
565 | |||
566 | free( cl ); | ||
567 | } | ||
568 | |||
569 | void OTGateway::loadKnownPeers( void ) { | ||
570 | QDir SaveDir = QDir::home(); | ||
571 | |||
572 | if( ! SaveDir.exists( "Settings" ) ) { | ||
573 | return; | ||
574 | } | ||
575 | SaveDir.cd( "Settings" ); | ||
576 | |||
577 | if( ! SaveDir.exists( "opietooth" ) ) { | ||
578 | return; | ||
579 | } | ||
580 | SaveDir.cd( "opietooth" ); | ||
581 | |||
582 | QFile F( SaveDir.path() + "/SeenDevices.conf" ); | ||
583 | |||
584 | if( F.open( IO_ReadOnly ) ) { | ||
585 | QTextStream TS(&F); | ||
586 | long count; | ||
587 | |||
588 | count = TS.readLine().toLong(); | ||
589 | |||
590 | while( count > 0 ) { | ||
591 | addPeer( new OTPeer( TS, this ) ); | ||
592 | count --; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | AllPeersModified = 0; | ||
597 | } | ||
598 | |||
599 | void OTGateway::saveKnownPeers( void ) { | ||
600 | QDir SaveDir = QDir::home(); | ||
601 | |||
602 | if( ! SaveDir.exists( "Settings" ) ) { | ||
603 | SaveDir.mkdir( "Settings" ); | ||
604 | } | ||
605 | SaveDir.cd( "Settings" ); | ||
606 | |||
607 | if( ! SaveDir.exists( "opietooth" ) ) { | ||
608 | SaveDir.mkdir( "opietooth" ); | ||
609 | } | ||
610 | SaveDir.cd( "opietooth" ); | ||
611 | |||
612 | QFile F( SaveDir.path() + "/SeenDevices.conf" ); | ||
613 | |||
614 | if( F.open( IO_WriteOnly | IO_Truncate ) ) { | ||
615 | QTextStream TS(&F); | ||
616 | QString S; | ||
617 | |||
618 | TS << AllPeers.count() << endl; | ||
619 | |||
620 | for( unsigned int i = 0; | ||
621 | i < AllPeers.count(); | ||
622 | i ++ ) { | ||
623 | AllPeers[i]->save( TS ); | ||
624 | } | ||
625 | AllPeersModified = 0; | ||
626 | } | ||
627 | AllPeersModified = 0; | ||
628 | } | ||
629 | |||
630 | int OTGateway::connectedToRFCommChannel( const OTDeviceAddress & Addr, | ||
631 | int channel ) { | ||
632 | |||
633 | int s; | ||
634 | |||
635 | if( (s = ::socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0 ) { | ||
636 | emit error( tr("Can't open RFCOMM control socket") ); | ||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | // get all rfcomm devices | ||
641 | { struct rfcomm_dev_list_req *dl; | ||
642 | struct rfcomm_dev_info *di, *dr; | ||
643 | int i; | ||
644 | |||
645 | dl = (struct rfcomm_dev_list_req *)alloca( | ||
646 | sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); | ||
647 | memset( dl, 0, sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di) ); | ||
648 | dl->dev_num = RFCOMM_MAX_DEV; | ||
649 | di = dl->dev_info; | ||
650 | |||
651 | if( ::ioctl(s, RFCOMMGETDEVLIST, (void *) dl) < 0) { | ||
652 | emit error( tr("Can't get device list") ); | ||
653 | ::close( s ); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | dr = di; | ||
658 | for (i = 0; i < dl->dev_num; i++, dr++) { | ||
659 | // connected to Peer | ||
660 | if( Addr == OTDeviceAddress( dr->dst ) && | ||
661 | channel == dr->channel && | ||
662 | ( dr->state != 0 ) | ||
663 | ) { | ||
664 | // return device ID | ||
665 | return dr->id; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | |||
670 | // no device | ||
671 | return -1; | ||
672 | } | ||
673 | |||
674 | static int byID( struct rfcomm_dev_info * d1, | ||
675 | struct rfcomm_dev_info * d2 ) { | ||
676 | return d1->id - d2->id; | ||
677 | } | ||
678 | |||
679 | int OTGateway::getFreeRFCommDevice( void ) { | ||
680 | |||
681 | int s; | ||
682 | |||
683 | if( (s = ::socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0 ) { | ||
684 | emit error( tr("Can't open RFCOMM control socket") ); | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | // get all rfcomm devices | ||
689 | { struct rfcomm_dev_list_req *dl; | ||
690 | struct rfcomm_dev_info *di, *dr; | ||
691 | int i; | ||
692 | |||
693 | dl = (struct rfcomm_dev_list_req *)alloca( | ||
694 | sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); | ||
695 | |||
696 | dl->dev_num = RFCOMM_MAX_DEV; | ||
697 | di = dl->dev_info; | ||
698 | |||
699 | if( ::ioctl(s, RFCOMMGETDEVLIST, (void *) dl) < 0) { | ||
700 | emit error( tr("Can't get device list") ); | ||
701 | ::close( s ); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | // s | ||
706 | if( dl->dev_num ) { | ||
707 | qsort( di, sizeof(struct rfcomm_dev_info), | ||
708 | dl->dev_num, (int(*)(const void*,const void*))byID ); | ||
709 | int id = 0; | ||
710 | |||
711 | dr = di; | ||
712 | // find lowest free device number | ||
713 | for (i = 0; i < dl->dev_num; i++, dr++) { | ||
714 | if( id != dr->id ) { | ||
715 | return id; | ||
716 | } | ||
717 | id ++; | ||
718 | } | ||
719 | return id; | ||
720 | } else { | ||
721 | return 0; | ||
722 | } | ||
723 | } | ||
724 | } | ||
725 | |||
726 | int OTGateway::releaseRFCommDevice( int devnr ) { | ||
727 | |||
728 | int s; | ||
729 | |||
730 | if( (s = ::socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0 ) { | ||
731 | emit error( tr("Can't open RFCOMM control socket") ); | ||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | // get all rfcomm devices | ||
736 | { struct rfcomm_dev_list_req *dl; | ||
737 | struct rfcomm_dev_info *di, *dr; | ||
738 | int i; | ||
739 | |||
740 | dl = (struct rfcomm_dev_list_req *)alloca( | ||
741 | sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); | ||
742 | memset( dl, 0, sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di) ); | ||
743 | dl->dev_num = RFCOMM_MAX_DEV; | ||
744 | di = dl->dev_info; | ||
745 | |||
746 | if( ::ioctl(s, RFCOMMGETDEVLIST, (void *) dl) < 0) { | ||
747 | emit error( tr("Can't get device list") ); | ||
748 | ::close( s ); | ||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | dr = di; | ||
753 | for (i = 0; i < dl->dev_num; i++, dr++) { | ||
754 | if( dr->id == devnr ) { | ||
755 | // still in connection list | ||
756 | struct rfcomm_dev_req req; | ||
757 | int err; | ||
758 | |||
759 | memset(&req, 0, sizeof(req)); | ||
760 | req.dev_id = devnr; | ||
761 | |||
762 | if ((err = ioctl(s, RFCOMMRELEASEDEV, &req)) < 0 ) { | ||
763 | return err; | ||
764 | } | ||
765 | return 0; | ||
766 | } | ||
767 | } | ||
768 | } | ||
769 | |||
770 | // no device -> nothing to release eiterh | ||
771 | return 0; | ||
772 | } | ||
773 | |||
diff --git a/noncore/settings/networksettings2/opietooth2/OTGateway.h b/noncore/settings/networksettings2/opietooth2/OTGateway.h new file mode 100644 index 0000000..a47cefb --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTGateway.h | |||
@@ -0,0 +1,200 @@ | |||
1 | #ifndef OTGATEWAY_H | ||
2 | #define OTGATEWAY_H | ||
3 | |||
4 | #include <qobject.h> | ||
5 | #include <qvector.h> | ||
6 | #include <qmap.h> | ||
7 | |||
8 | #include <OTDriverList.h> | ||
9 | #include <OTInquiry.h> | ||
10 | |||
11 | class QPixmap; | ||
12 | |||
13 | namespace Opietooth2 { | ||
14 | |||
15 | class OTDriverList; | ||
16 | class OTDriver; | ||
17 | class OTDevice; | ||
18 | class OTPeer; | ||
19 | class OTInquiry; | ||
20 | class OTPANConnection; | ||
21 | class OTLinkKey; | ||
22 | |||
23 | typedef QVector<OTPeer> PeerVector; | ||
24 | typedef QVector<OTPANConnection> PANConnectionVector; | ||
25 | typedef QArray<OTLinkKey> LinkKeyArray; | ||
26 | |||
27 | class OTLinkKey { | ||
28 | |||
29 | public : | ||
30 | |||
31 | OTLinkKey( const OTDeviceAddress & F, | ||
32 | const OTDeviceAddress & T ) { | ||
33 | From = F; | ||
34 | To = T; | ||
35 | } | ||
36 | |||
37 | const OTDeviceAddress & to() | ||
38 | { return To; } | ||
39 | const OTDeviceAddress & from() | ||
40 | { return From; } | ||
41 | |||
42 | OTDeviceAddress From; | ||
43 | OTDeviceAddress To; | ||
44 | }; | ||
45 | |||
46 | class OTPANConnection { | ||
47 | |||
48 | public : | ||
49 | |||
50 | OTPANConnection( const QString & Dev, const QString & CT ) { | ||
51 | Device = Dev; | ||
52 | ConnectedTo = CT; | ||
53 | } | ||
54 | |||
55 | QString Device; | ||
56 | QString ConnectedTo; | ||
57 | }; | ||
58 | |||
59 | |||
60 | class OTGateway : public QObject { | ||
61 | |||
62 | Q_OBJECT | ||
63 | |||
64 | public : | ||
65 | |||
66 | // single instance | ||
67 | static OTGateway * getOTGateway( void ); | ||
68 | static void releaseOTGateway( void ); | ||
69 | // convert device type as class to name for that class | ||
70 | static const char * deviceTypeToName( int Cls ); | ||
71 | |||
72 | // open bluetooth system | ||
73 | OTGateway( void ); | ||
74 | // close bluetooth system | ||
75 | ~OTGateway( void ); | ||
76 | |||
77 | // get access to system device | ||
78 | OTDevice * getOTDevice(); | ||
79 | |||
80 | // return true if this device needs enabling of bluetooth | ||
81 | bool needsEnabling(); | ||
82 | // return true if system is running | ||
83 | bool isEnabled(); | ||
84 | void setRefreshTimer( int MilleSecs ); | ||
85 | // return socket to HCI raw layer | ||
86 | inline int getSocket() | ||
87 | { return HciCtl; } | ||
88 | |||
89 | OTDriverList & getDriverList() | ||
90 | { return AllDrivers; } | ||
91 | OTDriver * driver( int nr ) | ||
92 | { return AllDrivers[nr]; } | ||
93 | void updateDrivers(); | ||
94 | |||
95 | PANConnectionVector getPANConnections(); | ||
96 | |||
97 | // scan neighbourhood using device | ||
98 | void scanNeighbourhood( OTDriver * D = 0 ); | ||
99 | void stopScanOfNeighbourhood(void ); | ||
100 | void setScanWith( OTDriver * D = 0 ) | ||
101 | { ScanWith = (D) ? D : | ||
102 | (AllDrivers.count() ) ? AllDrivers[0] : 0; } | ||
103 | OTDriver * scanWith( void ) | ||
104 | { return ScanWith; } | ||
105 | |||
106 | // get list of all detected peers | ||
107 | inline const PeerVector & peers( void ) | ||
108 | { return AllPeers; } | ||
109 | // ping peer to see if it is up | ||
110 | bool isPeerUp( const OTDeviceAddress & PAddr, | ||
111 | int timeoutInSec = 1, | ||
112 | int timeoutInUSec = 0, | ||
113 | int retry = 1 ); | ||
114 | OTPeer * findPeer( const OTDeviceAddress & Addr ); | ||
115 | void removePeer( OTPeer * P ); | ||
116 | void addPeer( OTPeer * P ); | ||
117 | |||
118 | OTDriver * findDriver( const OTDeviceAddress & Addr ); | ||
119 | |||
120 | inline const LinkKeyArray & getLinkKeys() const | ||
121 | { return AllKeys; } | ||
122 | bool removeLinkKey( unsigned int index ); | ||
123 | |||
124 | // return device number if we are connected over any device | ||
125 | // to the channel | ||
126 | // else returns -1 | ||
127 | int connectedToRFCommChannel( const OTDeviceAddress & Addr, int channel ); | ||
128 | int getFreeRFCommDevice( void ); | ||
129 | // return 0 if properly released | ||
130 | int releaseRFCommDevice( int DevNr ); | ||
131 | |||
132 | public slots : | ||
133 | |||
134 | // start bluetooth system | ||
135 | void SLOT_SetEnabled( bool ); | ||
136 | void SLOT_Enable(); | ||
137 | void SLOT_Disable(); | ||
138 | |||
139 | // show error | ||
140 | void SLOT_ShowError( const QString & ); | ||
141 | |||
142 | void SLOT_Enabled( int, bool ); | ||
143 | void SLOT_DriverDisappeared( OTDriver * ); | ||
144 | void SLOT_PeerDetected( OTPeer *, bool ); | ||
145 | void SLOT_FinishedDetecting(); | ||
146 | |||
147 | signals : | ||
148 | |||
149 | // any error | ||
150 | void error( const QString & ); | ||
151 | |||
152 | // signal state of bluetooth driver | ||
153 | void stateChange( OTDriver * D, bool State ); | ||
154 | |||
155 | // sent when list of drivers changees | ||
156 | void driverListChanged(); | ||
157 | |||
158 | // sent when bluetooth on device is enabled | ||
159 | void deviceEnabled( bool ); | ||
160 | |||
161 | // sent when a (new if bool = TRUE) peer is detected | ||
162 | void detectedPeer( OTPeer *, bool ); | ||
163 | |||
164 | // end of detection process | ||
165 | void finishedDetecting(); | ||
166 | |||
167 | protected : | ||
168 | |||
169 | void connectNotify( const char * Signal ); | ||
170 | void disconnectNotify( const char * Signal ); | ||
171 | |||
172 | void timerEvent( QTimerEvent * ); | ||
173 | |||
174 | private : | ||
175 | |||
176 | void loadActiveConnections( void ); | ||
177 | void loadKnownPeers( void ); | ||
178 | void saveKnownPeers( void ); | ||
179 | bool isConnectedTo( int devid, | ||
180 | const OTDeviceAddress & Address ); | ||
181 | |||
182 | void readLinkKeys(); | ||
183 | |||
184 | static OTGateway * SingleGateway; | ||
185 | static int UseCount; | ||
186 | |||
187 | OTDriver * ScanWith; | ||
188 | OTDriverList AllDrivers; | ||
189 | OTDevice * TheOTDevice; | ||
190 | int HciCtl; | ||
191 | int ErrorConnectCount; | ||
192 | int RefreshTimer; | ||
193 | OTInquiry * Scanning; | ||
194 | bool AllPeersModified; | ||
195 | PeerVector AllPeers; | ||
196 | LinkKeyArray AllKeys; | ||
197 | }; | ||
198 | }; | ||
199 | |||
200 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTHCISocket.cpp b/noncore/settings/networksettings2/opietooth2/OTHCISocket.cpp new file mode 100644 index 0000000..471c3bf --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTHCISocket.cpp | |||
@@ -0,0 +1,274 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@schaettgen.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | #include <qbuffer.h> | ||
13 | #include <qtimer.h> | ||
14 | #include <qdatastream.h> | ||
15 | #include <opie2/odebug.h> | ||
16 | |||
17 | #include <bluezlib.h> | ||
18 | |||
19 | // #include "deviceaddress.h" | ||
20 | #include <OTHCISocket.h> | ||
21 | #include <OTDriver.h> | ||
22 | |||
23 | using namespace Opietooth2; | ||
24 | |||
25 | OTHCISocket::OTHCISocket( OTDriver * D ) : | ||
26 | QObject( D, D->devname() ) { | ||
27 | BStatusSet = false; | ||
28 | Driver = D; | ||
29 | HCIReadNotifier = 0; | ||
30 | } | ||
31 | |||
32 | OTHCISocket::~OTHCISocket() { | ||
33 | close(); | ||
34 | } | ||
35 | |||
36 | void OTHCISocket::close() { | ||
37 | owarn << "OTHCISocket::close()" << oendl; | ||
38 | if( HCIReadNotifier ) { | ||
39 | delete HCIReadNotifier; | ||
40 | } | ||
41 | |||
42 | if( HCISocket.isValid() ) { | ||
43 | HCISocket.close(); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | bool OTHCISocket::open() { | ||
48 | |||
49 | owarn << "OTHCISocket::open()" << oendl; | ||
50 | int s; | ||
51 | |||
52 | s = ::socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); | ||
53 | |||
54 | if (s < 0) { | ||
55 | emit error( tr( "Error creating socket on %1 : %2 %3"). | ||
56 | arg( Driver->devname() ). | ||
57 | arg( errno ). | ||
58 | arg( strerror(errno) ) | ||
59 | ); | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | /* Bind socket to the HCI device */ | ||
64 | struct sockaddr_hci sa; | ||
65 | sa.hci_family = AF_BLUETOOTH; | ||
66 | sa.hci_dev = Driver->devId(); | ||
67 | if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { | ||
68 | ::close(s); | ||
69 | emit error( tr( "Error binding to socket to %1 : %2 %3"). | ||
70 | arg( Driver->devname() ). | ||
71 | arg( errno ). | ||
72 | arg( strerror(errno) ) | ||
73 | ); | ||
74 | return false; | ||
75 | } | ||
76 | |||
77 | struct hci_filter flt; | ||
78 | hci_filter_clear(&flt); | ||
79 | hci_filter_set_ptype(HCI_EVENT_PKT, &flt); | ||
80 | hci_filter_all_events(&flt); | ||
81 | if( setsockopt(s, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0 ) { | ||
82 | ::close(s); | ||
83 | emit error( tr( "HCI filter setup failed on %1 : %2 %3"). | ||
84 | arg( Driver->devname() ). | ||
85 | arg( errno ). | ||
86 | arg( strerror(errno) ) | ||
87 | ); | ||
88 | return false; | ||
89 | } | ||
90 | |||
91 | if( HCIReadNotifier ) { | ||
92 | delete HCIReadNotifier; | ||
93 | } | ||
94 | |||
95 | HCISocket.setSocket(s, QSocketDevice::Datagram); | ||
96 | HCIReadNotifier = new QSocketNotifier( | ||
97 | s, QSocketNotifier::Read, this); | ||
98 | |||
99 | connect( HCIReadNotifier, | ||
100 | SIGNAL(activated(int)), | ||
101 | this, | ||
102 | SLOT(slotSocketActivated()) | ||
103 | ); | ||
104 | |||
105 | //connect(hciSocket, SIGNAL(error(int)), | ||
106 | // this, SLOT(slotSocketError(int))); | ||
107 | //connect(hciSocket, SIGNAL(connectionClosed()), | ||
108 | // this, SLOT(slotConnectionClosed())); | ||
109 | //hciSocket->setSocket(s); | ||
110 | |||
111 | return true; | ||
112 | } | ||
113 | |||
114 | void OTHCISocket::slotSocketError(int e) { | ||
115 | close(); | ||
116 | emit error( tr( "HCI socket error 0x%1 on %1 : %2 %3"). | ||
117 | arg(e,2,16). | ||
118 | arg( Driver->devname() ). | ||
119 | arg( errno ). | ||
120 | arg( strerror(errno) ) | ||
121 | ); | ||
122 | } | ||
123 | |||
124 | void OTHCISocket::slotSocketActivated() { | ||
125 | |||
126 | QSocketDevice::Error err = HCISocket.error(); | ||
127 | |||
128 | if( (err == QSocketDevice::NoError ) && | ||
129 | ( HCISocket.isValid() ) ) { | ||
130 | //kdDebug() << "HCI socket ready read." << endl; | ||
131 | |||
132 | unsigned char buf[512]; | ||
133 | int psize = HCISocket.readBlock((char*)buf, 512); | ||
134 | |||
135 | if (psize <= 0) { | ||
136 | slotSocketError(HCISocket.error()); | ||
137 | HCISocket.close(); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | //unsigned char packetType = buf[0]; | ||
142 | unsigned char eventCode = buf[1]; | ||
143 | unsigned char len = buf[2]; | ||
144 | |||
145 | if (psize-3 == len) { | ||
146 | |||
147 | QByteArray databuf; | ||
148 | databuf.duplicate((char*)(buf+3), len); | ||
149 | emit event(eventCode, databuf); | ||
150 | if (eventCode == EVT_CMD_STATUS) { | ||
151 | updateStatus( databuf ); | ||
152 | } | ||
153 | } else { | ||
154 | owarn << "Error reading hci packet: packetSize(" | ||
155 | << psize | ||
156 | << ")-3 != dataSize(" | ||
157 | << len | ||
158 | << ")" | ||
159 | << oendl; | ||
160 | } | ||
161 | } else if (err == QSocketDevice::NoError) { | ||
162 | slotConnectionClosed(); | ||
163 | } else { | ||
164 | HCISocket.close(); | ||
165 | slotSocketError(err); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | void OTHCISocket::updateStatus(const QByteArray& data) { | ||
170 | |||
171 | QDataStream stream(data, IO_ReadOnly); | ||
172 | stream.setByteOrder(QDataStream::LittleEndian); | ||
173 | Q_UINT8 status, dummy; | ||
174 | Q_UINT16 opcode; | ||
175 | |||
176 | BStatusSet = true; | ||
177 | |||
178 | stream >> status >> dummy >> opcode; | ||
179 | //kdDebug() << "updatestatus opcode=" << uint32_t(opcode) << endl; | ||
180 | LastStatus = status; | ||
181 | LastStatusOgf = cmd_opcode_ogf(opcode); | ||
182 | LastStatusOcf = cmd_opcode_ocf(opcode); | ||
183 | } | ||
184 | |||
185 | void OTHCISocket::slotConnectionClosed() { | ||
186 | owarn << "HCI connection closed." << oendl; | ||
187 | emit connectionClosed(); | ||
188 | } | ||
189 | |||
190 | void OTHCISocket::readEvent() { | ||
191 | |||
192 | if (HCIReadNotifier) { | ||
193 | slotSocketActivated(); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | bool OTHCISocket::sendCommand( unsigned char ogf, | ||
198 | unsigned short ocf, | ||
199 | QByteArray buf | ||
200 | ) { | ||
201 | QBuffer packet; | ||
202 | QDataStream stream(&packet); | ||
203 | |||
204 | stream.setByteOrder(QDataStream::LittleEndian); | ||
205 | packet.open(IO_WriteOnly); | ||
206 | |||
207 | if (buf.size() > 255) return false; | ||
208 | |||
209 | //kdDebug() << "sendCommand. ogf=" << ogf << " ocf=" << ocf << endl; | ||
210 | Q_UINT16 opcode = cmd_opcode_pack(ogf, ocf); | ||
211 | Q_UINT8 pType = HCI_COMMAND_PKT; | ||
212 | Q_UINT8 buflen = buf.size(); | ||
213 | |||
214 | stream << pType << opcode << buflen; | ||
215 | stream.writeRawBytes(buf.data(), buflen); | ||
216 | packet.close(); | ||
217 | HCISocket.writeBlock((const char*)packet.buffer(), | ||
218 | packet.buffer().size()); | ||
219 | return true; | ||
220 | } | ||
221 | |||
222 | bool OTHCISocket::readStatus( unsigned char ogf, | ||
223 | unsigned short ocf, | ||
224 | int *status, | ||
225 | int timeout_ms) { | ||
226 | QTimer timer; | ||
227 | |||
228 | timer.start(timeout_ms, true); | ||
229 | BStatusSet = false; | ||
230 | |||
231 | while (timer.isActive() && HCISocket.isValid()) { | ||
232 | |||
233 | owarn << "OTHCISocket::readStatus()" << oendl; | ||
234 | bool timeout = false; | ||
235 | |||
236 | if( HCISocket.bytesAvailable() == 0) { | ||
237 | int rv = HCISocket.waitForMore(timeout_ms); | ||
238 | timeout = (rv == 0); | ||
239 | } | ||
240 | |||
241 | if (!timeout) { | ||
242 | slotSocketActivated(); | ||
243 | } | ||
244 | |||
245 | if( BStatusSet == true && | ||
246 | ogf == LastStatusOgf && | ||
247 | ocf == LastStatusOcf) { | ||
248 | *status = LastStatus; | ||
249 | owarn << "OTHCISocket::readStatus(ogf=" | ||
250 | << ogf | ||
251 | << ",ocf=" | ||
252 | << ocf | ||
253 | << ",timeout=" | ||
254 | << LastStatus | ||
255 | << ")" | ||
256 | << oendl; | ||
257 | return true; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | owarn << "OTHCISocket::readStatus(ogf=" | ||
262 | << ogf | ||
263 | << ",ocf=" | ||
264 | << ocf | ||
265 | << ",timeout=" | ||
266 | << LastStatus | ||
267 | << ") : timeout " | ||
268 | << oendl; | ||
269 | return false; | ||
270 | } | ||
271 | |||
272 | int OTHCISocket::socket() { | ||
273 | return HCISocket.socket(); | ||
274 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTHCISocket.h b/noncore/settings/networksettings2/opietooth2/OTHCISocket.h new file mode 100644 index 0000000..d508078 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTHCISocket.h | |||
@@ -0,0 +1,116 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@schaettgen.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | #ifndef OTHCISOCKET_H | ||
13 | #define OTHCISOCKET_H | ||
14 | |||
15 | #include <qobject.h> | ||
16 | #include <qsocketnotifier.h> | ||
17 | #include <qsocketdevice.h> | ||
18 | #include <qguardedptr.h> | ||
19 | |||
20 | class QSocket; | ||
21 | |||
22 | namespace Opietooth2 { | ||
23 | |||
24 | /** Bluetooth HCI Socket class. | ||
25 | * This class provides socket level access to the Bluez HCI layer. | ||
26 | * It is set up to filter out all but HCI event packets, since more | ||
27 | * is only allowed for privileged users. | ||
28 | * @todo writeHciEvent() function | ||
29 | * @todo error handling | ||
30 | */ | ||
31 | |||
32 | class OTDriver; | ||
33 | |||
34 | class OTHCISocket : public QObject { | ||
35 | |||
36 | Q_OBJECT | ||
37 | |||
38 | public: | ||
39 | |||
40 | OTHCISocket( OTDriver * ConnectTo ); | ||
41 | virtual ~OTHCISocket(); | ||
42 | |||
43 | /** Opens a HCI socket for the given | ||
44 | @return true if sucessfully opened, false otherwise | ||
45 | */ | ||
46 | virtual bool open(); | ||
47 | |||
48 | /** Closes the HCI socket. */ | ||
49 | virtual void close(); | ||
50 | |||
51 | bool sendCommand( unsigned char ogf, | ||
52 | unsigned short ocf, | ||
53 | QByteArray buf | ||
54 | ); | ||
55 | bool readStatus( unsigned char ogf, | ||
56 | unsigned short ocf, | ||
57 | int *status, | ||
58 | int timeout_ms = 1000); | ||
59 | |||
60 | /** Reads whole HCI packet. | ||
61 | @param packetType [out] The packet type. Should always be ... | ||
62 | @param eventCode [out] The event code. | ||
63 | @param buflen [in/out] The maximum size of the buffer / the number of | ||
64 | bytes written into the buffer. | ||
65 | @param paramBuf pointer to a buffer for the HCI event packet | ||
66 | @return true if successful | ||
67 | */ | ||
68 | /*bool readEvent(unsigned char &packetType, | ||
69 | unsigned char &eventCode, unsigned char &buflen, | ||
70 | char* paramBuf);*/ | ||
71 | |||
72 | enum Error { ErrSocket = 1 }; | ||
73 | |||
74 | /** Forces reading the next event packet. */ | ||
75 | void readEvent( void ); | ||
76 | |||
77 | /** Returns the internal socket */ | ||
78 | int socket( void ); | ||
79 | |||
80 | inline QSocketDevice & socketDevice() | ||
81 | { return HCISocket; } | ||
82 | |||
83 | inline OTDriver * driver() const | ||
84 | { return Driver; } | ||
85 | |||
86 | signals: | ||
87 | |||
88 | void event( unsigned char eventCode, QByteArray buf); | ||
89 | void error( QString message ); | ||
90 | void connectionClosed( ); | ||
91 | |||
92 | private: | ||
93 | |||
94 | void updateStatus( const QByteArray& data ); | ||
95 | |||
96 | //QSocketDevice hciSocket; | ||
97 | QGuardedPtr<QSocketNotifier> HCIReadNotifier; | ||
98 | QSocketDevice HCISocket; | ||
99 | OTDriver * Driver ; | ||
100 | |||
101 | bool BStatusSet; | ||
102 | unsigned short LastStatusOcf; | ||
103 | unsigned char LastStatusOgf; | ||
104 | int LastStatus; | ||
105 | |||
106 | private slots: | ||
107 | |||
108 | void slotSocketActivated(); | ||
109 | void slotSocketError(int); | ||
110 | void slotConnectionClosed(); | ||
111 | |||
112 | }; | ||
113 | |||
114 | }; | ||
115 | |||
116 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTIcons.cpp b/noncore/settings/networksettings2/opietooth2/OTIcons.cpp new file mode 100644 index 0000000..8b58b75 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTIcons.cpp | |||
@@ -0,0 +1,120 @@ | |||
1 | #include <OTIcons.h> | ||
2 | |||
3 | #include <opie2/odebug.h> | ||
4 | #include <qpe/resource.h> | ||
5 | |||
6 | using namespace Opietooth2; | ||
7 | |||
8 | OTIcons::OTIcons() : deviceIcons(), serviceIcons() { | ||
9 | |||
10 | // still need to find out real ids | ||
11 | deviceIcons.insert( "unknown", "unknown_16" ); | ||
12 | deviceIcons.insert( "misc", "misc_16" ); | ||
13 | deviceIcons.insert( "computer", "computer_16" ); | ||
14 | deviceIcons.insert( "phone", "phone_16" ); | ||
15 | deviceIcons.insert( "lan", "network_16" ); | ||
16 | deviceIcons.insert( "audiovideo", "audio_16" ); | ||
17 | deviceIcons.insert( "peripheral", "print_16" ); | ||
18 | deviceIcons.insert( "imaging", "other_16" ); | ||
19 | |||
20 | serviceIcons.insert( 0x1101 , "serial_16" ); //SerialPort | ||
21 | serviceIcons.insert( 0x1102 , "network_16" ); //LANAccessUsingPPP | ||
22 | serviceIcons.insert( 0x1103 , "network_16"); //DialupNetworking | ||
23 | serviceIcons.insert( 0x1104 , "sync_16" ); //IrMCSync | ||
24 | serviceIcons.insert( 0x1105 , "obex_16" ); //OBEXObjectPush | ||
25 | serviceIcons.insert( 0x1106 , "obex_16" ); //OBEXFileTransfer | ||
26 | serviceIcons.insert( 0x1107 , "sync_16" ); //IrMCSyncCommand | ||
27 | serviceIcons.insert( 0x1108 , "phone_16"); // Headset | ||
28 | serviceIcons.insert( 0x1109 , "phone_16"); // CordlessTelephony | ||
29 | serviceIcons.insert( 0x110A , "audio_16"); // AudioSource | ||
30 | serviceIcons.insert( 0x110B , "audio_16"); // AudioSink | ||
31 | //serviceIcons.insert( 0x110C , "remotecontrol_16" ); // remote control target --- | ||
32 | //serviceIcons.insert( 0x110D , "audio_16" ); // advanced audio distribution --- | ||
33 | //serviceIcons.insert( 0x110E , "remotecontrol_16" ); // remote control --- | ||
34 | //serviceIcons.insert( 0x110F , "video_16" ); // video conferencing --- | ||
35 | //serviceIcons.insert( 0x1110 , "audio_16" ); // intercom --- | ||
36 | serviceIcons.insert( 0x1111 , "fax_16" ); //Fax | ||
37 | serviceIcons.insert( 0x1112 , "audio_16"); //HeadsetAudioGateway | ||
38 | //serviceIcons.insert( 0x1113 , "wap_16" ); // WAP --- | ||
39 | //serviceIcons.insert( 0x1114 , "wap_16" ); // WAP client --- | ||
40 | serviceIcons.insert( 0x1115 , "network_16"); // Network Access Point (PANU) | ||
41 | serviceIcons.insert( 0x1116 , "network_16"); // Network Access Point (NAP) | ||
42 | serviceIcons.insert( 0x1117 , "network_16"); // Network Access Point (GN) | ||
43 | serviceIcons.insert( 0x1118 , "print_16" ); // direct printing | ||
44 | serviceIcons.insert( 0x1119 , "print_16" ); // reference printing | ||
45 | //serviceIcons.insert( 0x111A , "image_16" ); // imaging --- | ||
46 | //serviceIcons.insert( 0x111B , "image_16" ); // imaging responder --- | ||
47 | //serviceIcons.insert( 0x111C , "image_16" ); // imaging automatic archive --- | ||
48 | //serviceIcons.insert( 0x111D , "image_16" ); // imaging referenced objects --- | ||
49 | //serviceIcons.insert( 0x111E , "handsfree_16" ); // handsfree --- | ||
50 | //serviceIcons.insert( 0x111F , "handsfree_16" ); // handsfree audio gateway --- | ||
51 | serviceIcons.insert( 0x1120 , "print_16" ); // direct printing referenced object service | ||
52 | //serviceIcons.insert( 0x1121 , "handsfree_16" ); // reflected UI --- | ||
53 | serviceIcons.insert( 0x1122 , "print_16" ); // basic printing | ||
54 | serviceIcons.insert( 0x1123 , "print_16" ); // printing status | ||
55 | //serviceIcons.insert( 0x1124 , "handsfree_16" ); // human interface device service --- | ||
56 | //serviceIcons.insert( 0x1125 , "handsfree_16" ); // hardcopy cable replacement --- | ||
57 | serviceIcons.insert( 0x1126 , "print_16" ); // HCR print | ||
58 | serviceIcons.insert( 0x1127 , "print_16" ); // HCR scan | ||
59 | serviceIcons.insert( 0x1128 , "phone_16" ); // Common_ISDN_Access | ||
60 | //serviceIcons.insert( 0x1129 , "audio_16" ); // video conferencing GW --- | ||
61 | //serviceIcons.insert( 0x112C , "audio_16" ); // audio video --- | ||
62 | //serviceIcons.insert( 0x112D , "phone_16" ); // SIM access --- | ||
63 | serviceIcons.insert( 0x1201 , "network_16" ); //GenericNetworking | ||
64 | serviceIcons.insert( 0x1202 , "folder_16" ); //GenericFileTransfer | ||
65 | serviceIcons.insert( 0x1203 , "audio_16" ); //GenericAudio | ||
66 | serviceIcons.insert( 0x1204 , "phone_16" ); //GenericTelephony | ||
67 | //serviceIcons.insert( 0x1303 , "video_16" ); // video source --- | ||
68 | //serviceIcons.insert( 0x1304 , "video_16" ); // video sink --- | ||
69 | |||
70 | Modems.resize( 3 ); | ||
71 | Modems[0].setUUID32( 0x1101 ); // SerialPort | ||
72 | Modems[1].setUUID32( 0x1102 ); // Lan access using PPP | ||
73 | Modems[2].setUUID32( 0x1103 ); // DialupNetworking | ||
74 | |||
75 | Networks.resize( 3 ); | ||
76 | Networks[0].setUUID32( 0x1115 ); // PANU | ||
77 | Networks[1].setUUID32( 0x1116 ); // NAP | ||
78 | Networks[2].setUUID32( 0x1117 ); // GN | ||
79 | } | ||
80 | |||
81 | OTIcons::~OTIcons() { | ||
82 | } | ||
83 | |||
84 | QPixmap OTIcons::deviceIcon( const QString & deviceClass ) { | ||
85 | |||
86 | QString iconName; | ||
87 | |||
88 | QMap<QString, QString>::Iterator it; | ||
89 | |||
90 | it = deviceIcons.find( deviceClass ); | ||
91 | iconName = it.data(); | ||
92 | |||
93 | if ( iconName.isEmpty() ) { | ||
94 | iconName = "unknown_16"; | ||
95 | } | ||
96 | return loadPixmap( iconName, 1 ); | ||
97 | } | ||
98 | |||
99 | QPixmap OTIcons::serviceIcon( int serviceClass, bool & found ) { | ||
100 | |||
101 | QString iconName; | ||
102 | |||
103 | QMap<int, QString>::Iterator it; | ||
104 | |||
105 | it = serviceIcons.find( serviceClass ); | ||
106 | iconName = it.data(); | ||
107 | |||
108 | if ( iconName.isEmpty() ) { | ||
109 | iconName = "unknown_16"; | ||
110 | found = 0 ; | ||
111 | } else | ||
112 | found = 1 ; | ||
113 | return loadPixmap( iconName, 1 ); | ||
114 | } | ||
115 | |||
116 | QPixmap OTIcons::loadPixmap( const QString & name, bool Sub ) { | ||
117 | return( Resource::loadPixmap( "opietooth/" + | ||
118 | QString( (Sub) ? "icons/" : "" ) + | ||
119 | name ) ); | ||
120 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTIcons.h b/noncore/settings/networksettings2/opietooth2/OTIcons.h new file mode 100644 index 0000000..ee10831 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTIcons.h | |||
@@ -0,0 +1,54 @@ | |||
1 | #ifndef OTICONLOADER_H | ||
2 | #define OTICONLOADER_H | ||
3 | |||
4 | #include <OTUUID.h> | ||
5 | #include <qpixmap.h> | ||
6 | #include <qmap.h> | ||
7 | |||
8 | namespace Opietooth2 { | ||
9 | |||
10 | class OTIcons { | ||
11 | |||
12 | public: | ||
13 | |||
14 | OTIcons(); | ||
15 | ~OTIcons(); | ||
16 | |||
17 | /** | ||
18 | * Returns an icon depending on device class | ||
19 | * @param deviceClass the device class name | ||
20 | * @return the pixmap | ||
21 | */ | ||
22 | QPixmap deviceIcon( const QString & ); | ||
23 | |||
24 | /** | ||
25 | * Returns an icon depending on service id | ||
26 | * @param serviceClass the service id | ||
27 | * @return the pixmap | ||
28 | * @return true if found | ||
29 | */ | ||
30 | QPixmap serviceIcon( int, bool & ); | ||
31 | |||
32 | // returns all UUID that represent channels with modem function | ||
33 | const UUIDVector & modems() | ||
34 | { return Modems; } | ||
35 | |||
36 | // returns all UUID that represent channels with network | ||
37 | const UUIDVector & network() | ||
38 | { return Networks; } | ||
39 | |||
40 | // set Sub to find icons in .../Icons dir | ||
41 | QPixmap loadPixmap( const QString &, bool Sub = 0 ); | ||
42 | |||
43 | private: | ||
44 | |||
45 | // first ist id, second is icon name | ||
46 | QMap<QString,QString> deviceIcons; | ||
47 | QMap<int,QString> serviceIcons; | ||
48 | UUIDVector Modems; | ||
49 | UUIDVector Networks; | ||
50 | |||
51 | }; | ||
52 | } | ||
53 | |||
54 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTInquiry.cpp b/noncore/settings/networksettings2/opietooth2/OTInquiry.cpp new file mode 100644 index 0000000..8e94bbc --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTInquiry.cpp | |||
@@ -0,0 +1,219 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@schaettgen.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | |||
13 | #include <qcstring.h> | ||
14 | #include <qsocket.h> | ||
15 | #include <qdatetime.h> | ||
16 | #include <qtimer.h> | ||
17 | #include <qthread.h> | ||
18 | #include <qapplication.h> | ||
19 | |||
20 | #include <bluezlib.h> | ||
21 | |||
22 | #include <OTGateway.h> | ||
23 | #include <OTDriver.h> | ||
24 | #include <OTPeer.h> | ||
25 | #include <OTHCISocket.h> | ||
26 | #include <OTInquiry.h> | ||
27 | |||
28 | #include <opie2/odebug.h> | ||
29 | |||
30 | using namespace Opietooth2; | ||
31 | |||
32 | #define max(a,b) (((a)>(b)) ? (a) : (b)) | ||
33 | #define min(a,b) (((a)>(b)) ? (b) : (a)) | ||
34 | |||
35 | OTInquiry::OTInquiry( OTDriver * Drv ) : QObject( Drv ) { | ||
36 | |||
37 | reset(); | ||
38 | |||
39 | InquiryTimeoutTimer = new QTimer(this); | ||
40 | |||
41 | connect( InquiryTimeoutTimer, | ||
42 | SIGNAL(timeout()), | ||
43 | this, | ||
44 | SLOT(slotInquiryTimeout())); | ||
45 | |||
46 | Driver = Drv; | ||
47 | Socket = Drv->openSocket(); | ||
48 | Socket->open(); | ||
49 | |||
50 | connect( Socket, | ||
51 | SIGNAL( event(unsigned char, QByteArray)), | ||
52 | this, | ||
53 | SLOT(slotHCIEvent(unsigned char, QByteArray))); | ||
54 | } | ||
55 | |||
56 | OTInquiry::~OTInquiry() { | ||
57 | stopInquiring(); | ||
58 | } | ||
59 | |||
60 | void OTInquiry::stopInquiring( void ) { | ||
61 | if( Socket ) { | ||
62 | owarn << "Stop inquiry" << oendl; | ||
63 | Driver->closeSocket(); | ||
64 | Socket = 0; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | bool OTInquiry::inquire( double timeout, int numResponses, int lap) { | ||
69 | |||
70 | QByteArray cmdBuf(5); | ||
71 | |||
72 | cmdBuf[0] = lap & 0xFF; | ||
73 | cmdBuf[1] = (lap >> 8) & 0xFF; | ||
74 | cmdBuf[2] = (lap >> 16) & 0xFF; | ||
75 | cmdBuf[3] = max(0x01, min(0x30, int(timeout/1.28))); | ||
76 | cmdBuf[4] = (unsigned char)numResponses; | ||
77 | |||
78 | owarn << "Send HCI inquiry command. wait for " << cmdBuf[3] << oendl; | ||
79 | |||
80 | Socket->sendCommand(0x01, 0x0001, cmdBuf); | ||
81 | |||
82 | int status; | ||
83 | |||
84 | if( Socket->readStatus(0x01, 0x0001, &status)) { | ||
85 | if (status == 0) { | ||
86 | SuccessfullyStarted = true; | ||
87 | InquiryTimeoutTimer->start( int(1000*(timeout+1.0)), true); | ||
88 | return true; | ||
89 | } | ||
90 | else { | ||
91 | QString S =QString().sprintf( "%x", status ); | ||
92 | owarn << "OTInquiry::inquiry() failed: 0x" << S << oendl; | ||
93 | emit finished(); | ||
94 | return false; | ||
95 | } | ||
96 | } else { | ||
97 | owarn << "OTInquiry::inquiry(): Timeout." << oendl; | ||
98 | return false; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | bool OTInquiry::isInquiring() { | ||
103 | return InquiryTimeoutTimer->isActive(); | ||
104 | } | ||
105 | |||
106 | bool OTInquiry::isFinished() { | ||
107 | return SuccessfullyStarted && SuccessfullyEnded; | ||
108 | } | ||
109 | |||
110 | void OTInquiry::reset() { | ||
111 | |||
112 | SuccessfullyStarted = false; | ||
113 | SuccessfullyEnded = false; | ||
114 | //addrCache.clear(); | ||
115 | //infoQueue.clear(); | ||
116 | } | ||
117 | |||
118 | |||
119 | void OTInquiry::onPeerFound( OTPeer * Peer, bool IsNew ) { | ||
120 | emit peerFound( Peer, IsNew ); | ||
121 | } | ||
122 | |||
123 | void OTInquiry::slotInquiryTimeout() { | ||
124 | emit error( tr( "Timeout while waiting for end of inquiry.") ); | ||
125 | } | ||
126 | |||
127 | void OTInquiry::slotHCIEvent(unsigned char eventCode, QByteArray buf) { | ||
128 | |||
129 | owarn << "OTInquiry: hci packet received: eventCode=" | ||
130 | << (unsigned int)eventCode | ||
131 | << " packetLength=" | ||
132 | << (unsigned int)buf.size() | ||
133 | << oendl; | ||
134 | |||
135 | unsigned char *data = (unsigned char*)buf.data(); | ||
136 | switch (eventCode) { | ||
137 | case EVT_INQUIRY_COMPLETE: | ||
138 | { unsigned char status = data[0]; | ||
139 | owarn << "EVT_INQUIRY_COMPLETE status=" << status << oendl; | ||
140 | InquiryTimeoutTimer->stop(); | ||
141 | if (status == 0) { | ||
142 | if( SuccessfullyStarted == true) { | ||
143 | owarn << "OTInquiry ended successfully" << oendl; | ||
144 | SuccessfullyEnded = true; | ||
145 | } | ||
146 | emit finished(); | ||
147 | } | ||
148 | else { | ||
149 | emit error( tr( "OTInquiry completed with error (code %1)" ). | ||
150 | arg(status)); | ||
151 | } | ||
152 | } | ||
153 | break; | ||
154 | case EVT_INQUIRY_RESULT: | ||
155 | { int numResults = data[0]; | ||
156 | OTPeer * P = 0; | ||
157 | bool IsNew; | ||
158 | OTDeviceAddress Addr; | ||
159 | QString N; | ||
160 | |||
161 | inquiry_info *results = (inquiry_info*)(data+1); | ||
162 | |||
163 | for (int n=0; n<numResults; n++) { | ||
164 | Addr.setBDAddr( results[n].bdaddr ); | ||
165 | |||
166 | owarn << "INQUIRY_RESULT: " | ||
167 | << Addr.toString() | ||
168 | << oendl; | ||
169 | |||
170 | P = Driver->gateway()->findPeer( Addr ); | ||
171 | |||
172 | if( P ) { | ||
173 | // peer known | ||
174 | if( P->state() != OTPeer::Peer_Up ) { | ||
175 | P->setState( OTPeer::Peer_Up ); | ||
176 | } | ||
177 | IsNew = 0; | ||
178 | } else { | ||
179 | IsNew = 1; | ||
180 | // push the address to the address queue | ||
181 | // where it can be consumed by nextNeighbour() | ||
182 | P = new OTPeer( Driver->gateway() ); | ||
183 | P->setState( OTPeer::Peer_Up ); // we just detected it | ||
184 | P->setAddress( Addr ); | ||
185 | //if( addrCache.find(info.addr) == addrCache.end()) { | ||
186 | // addrCache.insert(info.addr); | ||
187 | |||
188 | P->setDeviceClass( (results[n].dev_class[0] << 16) | | ||
189 | (results[n].dev_class[1] << 8) | | ||
190 | (results[n].dev_class[2] << 0) ); | ||
191 | // infoQueue.push_back(info); | ||
192 | P->setName( Driver->getPeerName( Addr ) ); | ||
193 | } | ||
194 | |||
195 | // call the handler. Emits a signal if not overwritten | ||
196 | onPeerFound( P, IsNew ); | ||
197 | |||
198 | // } | ||
199 | } | ||
200 | } | ||
201 | break; | ||
202 | case EVT_CMD_STATUS : | ||
203 | { int status = data[0]; | ||
204 | int numHciCmdPkts = data[1]; | ||
205 | int cmdOpcode = *((uint16_t*)(data+2)); | ||
206 | owarn << "EVT_CMD_STATUS status=" | ||
207 | << status | ||
208 | << " numPkts=" | ||
209 | << numHciCmdPkts | ||
210 | << " cmdOpcode=" | ||
211 | << cmdOpcode | ||
212 | << oendl; | ||
213 | if (cmdOpcode == OCF_INQUIRY) { | ||
214 | |||
215 | } | ||
216 | } | ||
217 | break; | ||
218 | } | ||
219 | } | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTInquiry.h b/noncore/settings/networksettings2/opietooth2/OTInquiry.h new file mode 100644 index 0000000..f7bdeec --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTInquiry.h | |||
@@ -0,0 +1,178 @@ | |||
1 | //-*-c++-*- | ||
2 | /*************************************************************************** | ||
3 | * Copyright (C) 2003 by Fred Schaettgen * | ||
4 | * kdebluetooth@schaettgen.de * | ||
5 | * * | ||
6 | * This program is free software; you can redistribute it and/or modify * | ||
7 | * it under the terms of the GNU General Public License as published by * | ||
8 | * the Free Software Foundation; either version 2 of the License, or * | ||
9 | * (at your option) any later version. * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | #ifndef OTINQUIRY_H | ||
13 | #define OTINQUIRY_H | ||
14 | |||
15 | #include <qstring.h> | ||
16 | #include <qobject.h> | ||
17 | |||
18 | #include <qguardedptr.h> | ||
19 | #include <qtimer.h> | ||
20 | |||
21 | #include <OTPeer.h> | ||
22 | |||
23 | // #include <set> | ||
24 | // #include <deque> | ||
25 | |||
26 | namespace Opietooth2 { | ||
27 | |||
28 | class QSocket; | ||
29 | class QDateTime; | ||
30 | |||
31 | class OTDriver; | ||
32 | class OTHCISocket; | ||
33 | |||
34 | /** Scans for nearby bluetooth devices. | ||
35 | * This class provides an asynchronous interface to the | ||
36 | * inquriy HCI command. To scan for other devices, connect | ||
37 | * to the signals neighbourFound() and finished() and call | ||
38 | * inquiry(). Inquiry results are signalled as soon as they arrive, | ||
39 | * so the information can be displayed before the whole inquiry | ||
40 | * process is finished. | ||
41 | * Still no connections should be set up before | ||
42 | * the finished() signal was sent (hmm, is this always true..?) | ||
43 | */ | ||
44 | |||
45 | class OTInquiry : public QObject { | ||
46 | |||
47 | Q_OBJECT | ||
48 | |||
49 | public: | ||
50 | |||
51 | /** Constructor. | ||
52 | @param owner The owning parent object | ||
53 | */ | ||
54 | OTInquiry( OTDriver* Drv ); | ||
55 | |||
56 | /** Destructor. */ | ||
57 | virtual ~OTInquiry(); | ||
58 | |||
59 | // General/Unlimited Inquiry Access Code | ||
60 | static const int GIAC = 0x9E8B33; | ||
61 | |||
62 | // Limited Dedicated Inquiry Access Code | ||
63 | static const int LIAC = 0x9E8B00; | ||
64 | |||
65 | /** Starts the inquiry. | ||
66 | if you start inquiry several times without calling clear(), | ||
67 | you will receive each result only once. | ||
68 | @param timeout duration of the inquiry in seconds. | ||
69 | It will be rounded to the next multiple of 1.28 sec, | ||
70 | with a maximum of 61.44 sec. | ||
71 | @param lap | ||
72 | */ | ||
73 | bool inquire( double timeout = 8.0, | ||
74 | int numResponses = 0, | ||
75 | int lap = GIAC); | ||
76 | |||
77 | void stopInquiring( ); | ||
78 | |||
79 | /** Enters periodic inquiry mode. | ||
80 | An inquiry will be started at a random time in the intervall | ||
81 | between minduration and maxduration. | ||
82 | @param minduration minimum time between two inquiries. Rounded to | ||
83 | a multiple of 1.28, (3.84 <= d <= 83884.8) | ||
84 | @param maxduration maximum time between two inquiries. Rounded to | ||
85 | a multiple of 1.28, (3.84 <= d <= 83884.8) | ||
86 | @param timeout duration of the inquiry in seconds. | ||
87 | It will be rounded to the next multiple of 1.28 sec, | ||
88 | with a maximum of 61.44 sec. | ||
89 | @param numResponses Number of responses after which the inquiry | ||
90 | will be stopped. 0 means no limit. | ||
91 | @param lap | ||
92 | */ | ||
93 | /* | ||
94 | void inquirePeriodically( double minduration, | ||
95 | double maxduration, | ||
96 | double timeout = 8.0, | ||
97 | int numResponses = 0, | ||
98 | int lap = LIAC | ||
99 | ); | ||
100 | */ | ||
101 | /** checks if there the inquiry is running currently | ||
102 | @return true if there is an inquiry running | ||
103 | which was started by this object. | ||
104 | @todo possibility to check for "foreign" inquiries. Deal with | ||
105 | the fact that we can receive foreign inquiry results. | ||
106 | */ | ||
107 | bool isInquiring(); | ||
108 | |||
109 | /** This function returns true after after an inquiry was | ||
110 | started, results were received and the inquiry ended successfully. | ||
111 | This can be the case without calling inquiry() at all, because | ||
112 | results of inquiries started by other programs are also processed. | ||
113 | */ | ||
114 | bool isFinished(); | ||
115 | |||
116 | /** Resets the list of received results and sets | ||
117 | isInquiryComplete() to false. | ||
118 | */ | ||
119 | void reset(); | ||
120 | |||
121 | inline OTDriver * driver() const | ||
122 | { return Driver; } | ||
123 | |||
124 | protected: | ||
125 | |||
126 | /** Called when a new neighbour was found. The default | ||
127 | implementation emits the neighbourFound signal. | ||
128 | @param bdaddr the address found. | ||
129 | */ | ||
130 | virtual void onPeerFound( OTPeer * Peer, bool ); | ||
131 | |||
132 | enum ErrorCode { | ||
133 | InquiryFinishedTimeout = 0x0100 | ||
134 | }; | ||
135 | |||
136 | signals : | ||
137 | |||
138 | void peerFound( OTPeer *, bool ); | ||
139 | |||
140 | /** Emitted after an inquiry has finished successfully. | ||
141 | If the inquiry was canceled, no finished signals is emitted. | ||
142 | This signal can be emitted without having called inquiry, since | ||
143 | other processes may have started an inquiry. | ||
144 | */ | ||
145 | void finished(); | ||
146 | |||
147 | /** Emitted instead of finished if an error occured after | ||
148 | calling inquiry() or periodicInquiryMode() | ||
149 | @param code error code. | ||
150 | @param message Error message | ||
151 | */ | ||
152 | void error( QString message ); | ||
153 | |||
154 | private: | ||
155 | |||
156 | // std::set<DeviceAddress> addrCache; | ||
157 | // double currentTimeout; | ||
158 | // QByteArray* buf; | ||
159 | // QSocket* hciSocket; | ||
160 | QGuardedPtr<OTHCISocket> Socket; | ||
161 | OTDriver * Driver; | ||
162 | |||
163 | //QDateTime *startTime; | ||
164 | QTimer *InquiryTimeoutTimer; | ||
165 | |||
166 | // std::deque<InquiryInfo> infoQueue; | ||
167 | bool SuccessfullyStarted; | ||
168 | bool SuccessfullyEnded; | ||
169 | |||
170 | private slots: | ||
171 | |||
172 | void slotInquiryTimeout(); | ||
173 | void slotHCIEvent(unsigned char eventCode, QByteArray buf); | ||
174 | |||
175 | }; | ||
176 | |||
177 | } | ||
178 | #endif | ||
diff --git a/noncore/settings/networksettings2/opietooth2/OTMainGUI.ui b/noncore/settings/networksettings2/opietooth2/OTMainGUI.ui new file mode 100644 index 0000000..5584cd9 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTMainGUI.ui | |||
@@ -0,0 +1,378 @@ | |||
1 | <!DOCTYPE UI><UI> | ||
2 | <class>OTMainGUI</class> | ||
3 | <widget> | ||
4 | <class>QWidget</class> | ||
5 | <property stdset="1"> | ||
6 | <name>name</name> | ||
7 | <cstring>OTMainGUI</cstring> | ||
8 | </property> | ||
9 | <property stdset="1"> | ||
10 | <name>geometry</name> | ||
11 | <rect> | ||
12 | <x>0</x> | ||
13 | <y>0</y> | ||
14 | <width>240</width> | ||
15 | <height>385</height> | ||
16 | </rect> | ||
17 | </property> | ||
18 | <property stdset="1"> | ||
19 | <name>caption</name> | ||
20 | <string>Bluetooth Manager</string> | ||
21 | </property> | ||
22 | <grid> | ||
23 | <property stdset="1"> | ||
24 | <name>margin</name> | ||
25 | <number>11</number> | ||
26 | </property> | ||
27 | <property stdset="1"> | ||
28 | <name>spacing</name> | ||
29 | <number>6</number> | ||
30 | </property> | ||
31 | <widget row="7" column="0" rowspan="1" colspan="5" > | ||
32 | <class>QLayoutWidget</class> | ||
33 | <property stdset="1"> | ||
34 | <name>name</name> | ||
35 | <cstring>Layout4</cstring> | ||
36 | </property> | ||
37 | <hbox> | ||
38 | <property stdset="1"> | ||
39 | <name>margin</name> | ||
40 | <number>0</number> | ||
41 | </property> | ||
42 | <property stdset="1"> | ||
43 | <name>spacing</name> | ||
44 | <number>6</number> | ||
45 | </property> | ||
46 | <spacer> | ||
47 | <property> | ||
48 | <name>name</name> | ||
49 | <cstring>Spacer4_2</cstring> | ||
50 | </property> | ||
51 | <property stdset="1"> | ||
52 | <name>orientation</name> | ||
53 | <enum>Horizontal</enum> | ||
54 | </property> | ||
55 | <property stdset="1"> | ||
56 | <name>sizeType</name> | ||
57 | <enum>Expanding</enum> | ||
58 | </property> | ||
59 | <property> | ||
60 | <name>sizeHint</name> | ||
61 | <size> | ||
62 | <width>20</width> | ||
63 | <height>20</height> | ||
64 | </size> | ||
65 | </property> | ||
66 | </spacer> | ||
67 | <widget> | ||
68 | <class>QCheckBox</class> | ||
69 | <property stdset="1"> | ||
70 | <name>name</name> | ||
71 | <cstring>MustBeEnabled_CB</cstring> | ||
72 | </property> | ||
73 | <property stdset="1"> | ||
74 | <name>text</name> | ||
75 | <string>Bluetooth Enabled</string> | ||
76 | </property> | ||
77 | </widget> | ||
78 | </hbox> | ||
79 | </widget> | ||
80 | <widget row="3" column="2" > | ||
81 | <class>QLabel</class> | ||
82 | <property stdset="1"> | ||
83 | <name>name</name> | ||
84 | <cstring>TextLabel5</cstring> | ||
85 | </property> | ||
86 | <property stdset="1"> | ||
87 | <name>sizePolicy</name> | ||
88 | <sizepolicy> | ||
89 | <hsizetype>0</hsizetype> | ||
90 | <vsizetype>1</vsizetype> | ||
91 | </sizepolicy> | ||
92 | </property> | ||
93 | <property stdset="1"> | ||
94 | <name>text</name> | ||
95 | <string>Use device :</string> | ||
96 | </property> | ||
97 | </widget> | ||
98 | <spacer row="4" column="0" > | ||
99 | <property> | ||
100 | <name>name</name> | ||
101 | <cstring>Spacer7</cstring> | ||
102 | </property> | ||
103 | <property stdset="1"> | ||
104 | <name>orientation</name> | ||
105 | <enum>Horizontal</enum> | ||
106 | </property> | ||
107 | <property stdset="1"> | ||
108 | <name>sizeType</name> | ||
109 | <enum>Fixed</enum> | ||
110 | </property> | ||
111 | <property> | ||
112 | <name>sizeHint</name> | ||
113 | <size> | ||
114 | <width>20</width> | ||
115 | <height>20</height> | ||
116 | </size> | ||
117 | </property> | ||
118 | </spacer> | ||
119 | <spacer row="1" column="0" > | ||
120 | <property> | ||
121 | <name>name</name> | ||
122 | <cstring>Spacer7_2</cstring> | ||
123 | </property> | ||
124 | <property stdset="1"> | ||
125 | <name>orientation</name> | ||
126 | <enum>Horizontal</enum> | ||
127 | </property> | ||
128 | <property stdset="1"> | ||
129 | <name>sizeType</name> | ||
130 | <enum>Fixed</enum> | ||
131 | </property> | ||
132 | <property> | ||
133 | <name>sizeHint</name> | ||
134 | <size> | ||
135 | <width>20</width> | ||
136 | <height>20</height> | ||
137 | </size> | ||
138 | </property> | ||
139 | </spacer> | ||
140 | <spacer row="6" column="0" > | ||
141 | <property> | ||
142 | <name>name</name> | ||
143 | <cstring>Spacer7_3</cstring> | ||
144 | </property> | ||
145 | <property stdset="1"> | ||
146 | <name>orientation</name> | ||
147 | <enum>Horizontal</enum> | ||
148 | </property> | ||
149 | <property stdset="1"> | ||
150 | <name>sizeType</name> | ||
151 | <enum>Fixed</enum> | ||
152 | </property> | ||
153 | <property> | ||
154 | <name>sizeHint</name> | ||
155 | <size> | ||
156 | <width>20</width> | ||
157 | <height>20</height> | ||
158 | </size> | ||
159 | </property> | ||
160 | </spacer> | ||
161 | <widget row="1" column="1" rowspan="1" colspan="4" > | ||
162 | <class>QLabel</class> | ||
163 | <property stdset="1"> | ||
164 | <name>name</name> | ||
165 | <cstring>TextLabel1</cstring> | ||
166 | </property> | ||
167 | <property stdset="1"> | ||
168 | <name>sizePolicy</name> | ||
169 | <sizepolicy> | ||
170 | <hsizetype>7</hsizetype> | ||
171 | <vsizetype>1</vsizetype> | ||
172 | </sizepolicy> | ||
173 | </property> | ||
174 | <property stdset="1"> | ||
175 | <name>text</name> | ||
176 | <string>Select to manage your local Bluetooth hardware</string> | ||
177 | </property> | ||
178 | <property stdset="1"> | ||
179 | <name>alignment</name> | ||
180 | <set>WordBreak|AlignVCenter|AlignLeft</set> | ||
181 | </property> | ||
182 | <property> | ||
183 | <name>wordwrap</name> | ||
184 | </property> | ||
185 | </widget> | ||
186 | <widget row="4" column="1" rowspan="1" colspan="4" > | ||
187 | <class>QLabel</class> | ||
188 | <property stdset="1"> | ||
189 | <name>name</name> | ||
190 | <cstring>TextLabel1_2</cstring> | ||
191 | </property> | ||
192 | <property stdset="1"> | ||
193 | <name>sizePolicy</name> | ||
194 | <sizepolicy> | ||
195 | <hsizetype>7</hsizetype> | ||
196 | <vsizetype>1</vsizetype> | ||
197 | </sizepolicy> | ||
198 | </property> | ||
199 | <property stdset="1"> | ||
200 | <name>text</name> | ||
201 | <string>Select to scan the bluetooth network for reachable devices using the selected local device</string> | ||
202 | </property> | ||
203 | <property stdset="1"> | ||
204 | <name>alignment</name> | ||
205 | <set>WordBreak|AlignVCenter|AlignLeft</set> | ||
206 | </property> | ||
207 | <property> | ||
208 | <name>wordwrap</name> | ||
209 | </property> | ||
210 | </widget> | ||
211 | <spacer row="3" column="0" rowspan="1" colspan="2" > | ||
212 | <property> | ||
213 | <name>name</name> | ||
214 | <cstring>Spacer4</cstring> | ||
215 | </property> | ||
216 | <property stdset="1"> | ||
217 | <name>orientation</name> | ||
218 | <enum>Horizontal</enum> | ||
219 | </property> | ||
220 | <property stdset="1"> | ||
221 | <name>sizeType</name> | ||
222 | <enum>Expanding</enum> | ||
223 | </property> | ||
224 | <property> | ||
225 | <name>sizeHint</name> | ||
226 | <size> | ||
227 | <width>20</width> | ||
228 | <height>20</height> | ||
229 | </size> | ||
230 | </property> | ||
231 | </spacer> | ||
232 | <widget row="3" column="3" rowspan="1" colspan="2" > | ||
233 | <class>QComboBox</class> | ||
234 | <property stdset="1"> | ||
235 | <name>name</name> | ||
236 | <cstring>DeviceList_CB</cstring> | ||
237 | </property> | ||
238 | <property stdset="1"> | ||
239 | <name>sizePolicy</name> | ||
240 | <sizepolicy> | ||
241 | <hsizetype>7</hsizetype> | ||
242 | <vsizetype>0</vsizetype> | ||
243 | </sizepolicy> | ||
244 | </property> | ||
245 | </widget> | ||
246 | <widget row="6" column="1" rowspan="1" colspan="4" > | ||
247 | <class>QLabel</class> | ||
248 | <property stdset="1"> | ||
249 | <name>name</name> | ||
250 | <cstring>TextLabel1_2_2</cstring> | ||
251 | </property> | ||
252 | <property stdset="1"> | ||
253 | <name>sizePolicy</name> | ||
254 | <sizepolicy> | ||
255 | <hsizetype>7</hsizetype> | ||
256 | <vsizetype>1</vsizetype> | ||
257 | </sizepolicy> | ||
258 | </property> | ||
259 | <property stdset="1"> | ||
260 | <name>text</name> | ||
261 | <string>Select to manage all pairings known on the local device to any remote device regardless if it is currently reachable or not</string> | ||
262 | </property> | ||
263 | <property stdset="1"> | ||
264 | <name>alignment</name> | ||
265 | <set>WordBreak|AlignVCenter|AlignLeft</set> | ||
266 | </property> | ||
267 | <property> | ||
268 | <name>wordwrap</name> | ||
269 | </property> | ||
270 | </widget> | ||
271 | <spacer row="2" column="4" > | ||
272 | <property> | ||
273 | <name>name</name> | ||
274 | <cstring>Spacer5_2</cstring> | ||
275 | </property> | ||
276 | <property stdset="1"> | ||
277 | <name>orientation</name> | ||
278 | <enum>Horizontal</enum> | ||
279 | </property> | ||
280 | <property stdset="1"> | ||
281 | <name>sizeType</name> | ||
282 | <enum>Expanding</enum> | ||
283 | </property> | ||
284 | <property> | ||
285 | <name>sizeHint</name> | ||
286 | <size> | ||
287 | <width>20</width> | ||
288 | <height>20</height> | ||
289 | </size> | ||
290 | </property> | ||
291 | </spacer> | ||
292 | <widget row="2" column="0" rowspan="1" colspan="4" > | ||
293 | <class>QPushButton</class> | ||
294 | <property stdset="1"> | ||
295 | <name>name</name> | ||
296 | <cstring>Scan_But</cstring> | ||
297 | </property> | ||
298 | <property stdset="1"> | ||
299 | <name>text</name> | ||
300 | <string>Scan Neighbourhood</string> | ||
301 | </property> | ||
302 | </widget> | ||
303 | <widget row="5" column="0" rowspan="1" colspan="4" > | ||
304 | <class>QPushButton</class> | ||
305 | <property stdset="1"> | ||
306 | <name>name</name> | ||
307 | <cstring>Pairing_But</cstring> | ||
308 | </property> | ||
309 | <property stdset="1"> | ||
310 | <name>text</name> | ||
311 | <string>Manage Pairing</string> | ||
312 | </property> | ||
313 | </widget> | ||
314 | <widget row="0" column="0" rowspan="1" colspan="4" > | ||
315 | <class>QPushButton</class> | ||
316 | <property stdset="1"> | ||
317 | <name>name</name> | ||
318 | <cstring>ManageLocalHW_But</cstring> | ||
319 | </property> | ||
320 | <property stdset="1"> | ||
321 | <name>text</name> | ||
322 | <string>Local Bluetooth hardware</string> | ||
323 | </property> | ||
324 | </widget> | ||
325 | <spacer row="0" column="4" > | ||
326 | <property> | ||
327 | <name>name</name> | ||
328 | <cstring>Spacer5_2_2</cstring> | ||
329 | </property> | ||
330 | <property stdset="1"> | ||
331 | <name>orientation</name> | ||
332 | <enum>Horizontal</enum> | ||
333 | </property> | ||
334 | <property stdset="1"> | ||
335 | <name>sizeType</name> | ||
336 | <enum>Expanding</enum> | ||
337 | </property> | ||
338 | <property> | ||
339 | <name>sizeHint</name> | ||
340 | <size> | ||
341 | <width>20</width> | ||
342 | <height>20</height> | ||
343 | </size> | ||
344 | </property> | ||
345 | </spacer> | ||
346 | </grid> | ||
347 | </widget> | ||
348 | <connections> | ||
349 | <connection> | ||
350 | <sender>ManageLocalHW_But</sender> | ||
351 | <signal>clicked()</signal> | ||
352 | <receiver>OTMainGUI</receiver> | ||
353 | <slot>SLOT_Manage()</slot> | ||
354 | </connection> | ||
355 | <connection> | ||
356 | <sender>Scan_But</sender> | ||
357 | <signal>clicked()</signal> | ||
358 | <receiver>OTMainGUI</receiver> | ||
359 | <slot>SLOT_Scan()</slot> | ||
360 | </connection> | ||
361 | <connection> | ||
362 | <sender>MustBeEnabled_CB</sender> | ||
363 | <signal>toggled(bool)</signal> | ||
364 | <receiver>OTMainGUI</receiver> | ||
365 | <slot>SLOT_EnableBluetooth(bool)</slot> | ||
366 | </connection> | ||
367 | <connection> | ||
368 | <sender>Pairing_But</sender> | ||
369 | <signal>clicked()</signal> | ||
370 | <receiver>OTMainGUI</receiver> | ||
371 | <slot>SLOT_Pairing()</slot> | ||
372 | </connection> | ||
373 | <slot access="public">SLOT_EnableBluetooth(bool)</slot> | ||
374 | <slot access="public">SLOT_Manage()</slot> | ||
375 | <slot access="public">SLOT_Scan()</slot> | ||
376 | <slot access="public">SLOT_Pairing()</slot> | ||
377 | </connections> | ||
378 | </UI> | ||
diff --git a/pics/networksettings2/Devices/ppp-large.png b/pics/networksettings2/Devices/ppp-large.png index ca41693..cfb9129 100644 --- a/pics/networksettings2/Devices/ppp-large.png +++ b/pics/networksettings2/Devices/ppp-large.png | |||
Binary files differ | |||
diff --git a/pics/networksettings2/Devices/ppp.png b/pics/networksettings2/Devices/ppp.png index 4271e18..9de4c89 100644 --- a/pics/networksettings2/Devices/ppp.png +++ b/pics/networksettings2/Devices/ppp.png | |||
Binary files differ | |||
diff --git a/pics/networksettings2/check.png b/pics/networksettings2/check.png index 4ed65a9..c52af91 100644 --- a/pics/networksettings2/check.png +++ b/pics/networksettings2/check.png | |||
Binary files differ | |||
diff --git a/pics/opietooth/connected.png b/pics/opietooth/connected.png index 4ba4084..9465e0e 100644 --- a/pics/opietooth/connected.png +++ b/pics/opietooth/connected.png | |||
Binary files differ | |||
diff --git a/pics/opietooth/notconnected.png b/pics/opietooth/notconnected.png index c964fa3..0b752fc 100644 --- a/pics/opietooth/notconnected.png +++ b/pics/opietooth/notconnected.png | |||
Binary files differ | |||