Diffstat (limited to 'noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp | 354 |
1 files changed, 133 insertions, 221 deletions
diff --git a/noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp b/noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp index 24e4b7b..9d4ae97 100644 --- a/noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp +++ b/noncore/settings/networksettings2/bluetooth/bluetoothBNEPrun.cpp | |||
@@ -1,249 +1,161 @@ | |||
1 | #include <qfile.h> | 1 | #include <qfile.h> |
2 | #include <qfileinfo.h> | 2 | #include <qfileinfo.h> |
3 | #include <qtextstream.h> | 3 | #include <qtextstream.h> |
4 | #include <resources.h> | 4 | #include <resources.h> |
5 | #include "bluetoothBNEPrun.h" | 5 | #include "bluetoothBNEPrun.h" |
6 | 6 | ||
7 | QDict<QString> * BluetoothBNEPRun::PANConnections = 0; | 7 | BluetoothBNEPRun::BluetoothBNEPRun( ANetNodeInstance * NNI, |
8 | BluetoothBNEPData & D ) : | ||
9 | RuntimeInfo( NNI ), | ||
10 | Data( D), | ||
11 | Pat( "bnep[0-6]" ) { | ||
12 | OT = 0; | ||
13 | } | ||
8 | 14 | ||
9 | void BluetoothBNEPRun::detectState( NodeCollection * NC ) { | 15 | BluetoothBNEPRun::~BluetoothBNEPRun( void ) { |
10 | // unavailable : no card found | 16 | if( OT ) { |
11 | // available : card found and assigned to us or free | 17 | OTGateway::releaseOTGateway(); |
12 | // up : card found and assigned to us and up | 18 | } |
13 | QString S = QString( "/tmp/profile-%1.up" ).arg(NC->number()); | 19 | } |
14 | System & Sys = NSResources->system(); | ||
15 | InterfaceInfo * Run; | ||
16 | QFile F( S ); | ||
17 | |||
18 | Log(("Detecting for %s\n", NC->name().latin1() )); | ||
19 | |||
20 | if( F.open( IO_ReadOnly ) ) { | ||
21 | // could open file -> read interface and assign | ||
22 | QString X; | ||
23 | bool accepted = 0; | ||
24 | QTextStream TS(&F); | ||
25 | X = TS.readLine(); | ||
26 | Log(("%s exists : %s\n", S.latin1(), X.latin1() )); | ||
27 | // find interface | ||
28 | if( handlesInterface( X ) ) { | ||
29 | |||
30 | Log(("Handles interface %s, PANC %p\n", X.latin1(), PANConnections )); | ||
31 | if( PANConnections == 0 ) { | ||
32 | // load connections that are active | ||
33 | // format : bnep0 00:60:57:02:71:A2 PANU | ||
34 | FILE * OutputOfCmd = popen( "pand --show", "r" ) ; | ||
35 | |||
36 | PANConnections = new QDict<QString>; | ||
37 | |||
38 | if( OutputOfCmd ) { | ||
39 | char ch; | ||
40 | // could fork | ||
41 | // read all data | ||
42 | QString Line = ""; | ||
43 | while( 1 ) { | ||
44 | if( fread( &ch, 1, 1, OutputOfCmd ) < 1 ) { | ||
45 | // eof | ||
46 | break; | ||
47 | } | ||
48 | if( ch == '\n' || ch == '\r' ) { | ||
49 | if( ! Line.isEmpty() ) { | ||
50 | if( Line.startsWith( "bnep" ) ) { | ||
51 | QStringList SL = QStringList::split( " ", Line ); | ||
52 | Log(("Detected PAN %s %s\n", | ||
53 | SL[0].latin1(), SL[1].latin1() )); | ||
54 | PANConnections->insert( SL[0], new QString(SL[1])); | ||
55 | } | ||
56 | Line=""; | ||
57 | } | ||
58 | } else { | ||
59 | Line += ch; | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | 20 | ||
64 | pclose( OutputOfCmd ); | 21 | State_t BluetoothBNEPRun::detectState( void ) { |
65 | } | ||
66 | 22 | ||
67 | // check if this runtime allows connection to node | 23 | /* |
68 | if( ! Data.AllowAll ) { | ||
69 | // has addresses | ||
70 | for ( QStringList::Iterator it = Data.BDAddress.begin(); | ||
71 | ! accepted && it != Data.BDAddress.end(); | ||
72 | ++ it ) { | ||
73 | for( QDictIterator<QString> it2( *(PANConnections) ); | ||
74 | it2.current(); | ||
75 | ++ it2 ) { | ||
76 | if( X == it2.currentKey() && | ||
77 | (*it) == *(it2.current()) | ||
78 | ) { | ||
79 | // found | ||
80 | Log(("%s accepts connections to %s\n", | ||
81 | NC->name().latin1(), | ||
82 | it2.current()->latin1() )); | ||
83 | accepted = 1; | ||
84 | break; | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | } else { | ||
89 | Log(("%s accepts any connection\n", NC->name().latin1() )); | ||
90 | // accept any | ||
91 | accepted = 1; | ||
92 | } | ||
93 | 24 | ||
94 | if( accepted ) { | 25 | need to detect |
95 | // matches and is allowed for this node | 26 | |
96 | for( QDictIterator<InterfaceInfo> It(Sys.interfaces()); | 27 | 1. for any PAN connection that is found if that |
97 | It.current(); | 28 | PAN is connected. |
98 | ++It ) { | 29 | |
99 | Run = It.current(); | 30 | if it is connected it is not available (since we do |
100 | if( X == Run->Name ) { | 31 | not manage IP settings and we are called to detect |
101 | Log(("%s Assigned %p\n", NC->name().latin1(), Run )); | 32 | the state we knwo that we do not have an UP connection) |
102 | Run->assignNode( netNode() ); | 33 | |
103 | assignInterface( Run ); | 34 | 2. if it not connected and we allow any connection we |
104 | NC->setCurrentState( IsUp ); | 35 | are available or if that PAN connection is to a device |
105 | return; | 36 | with a correct address |
106 | } | 37 | |
107 | } | 38 | 3. if it is not connected and the address do not match or |
108 | } | 39 | we do not accept any address, we are Unavailable but |
109 | } | 40 | not DOWN. I.e a new connection could perhaps be created |
110 | } | 41 | |
111 | 42 | */ | |
112 | Log(("Assigned %p\n", assignedInterface() )); | 43 | |
113 | if( ( Run = assignedInterface() ) ) { | 44 | if( ! OT ) { |
114 | // we already have an interface assigned -> still present ? | 45 | OT = OTGateway::getOTGateway(); |
115 | if( ! Run->IsUp ) { | ||
116 | // usb is still free -> keep assignment | ||
117 | NC->setCurrentState( Available ); | ||
118 | return; | ||
119 | } // else interface is up but NOT us -> some other profile | ||
120 | } | 46 | } |
121 | 47 | ||
122 | // nothing (valid) assigned to us | 48 | if( ! OT->isEnabled() ) { |
123 | assignInterface( 0 ); | 49 | return Unavailable; |
124 | |||
125 | // find possible interface | ||
126 | for( QDictIterator<InterfaceInfo> It(Sys.interfaces()); | ||
127 | It.current(); | ||
128 | ++It ) { | ||
129 | Run = It.current(); | ||
130 | |||
131 | Log(("%s %d %d=%d %d\n", | ||
132 | Run->Name.latin1(), | ||
133 | handlesInterface( Run->Name ), | ||
134 | Run->CardType, ARPHRD_ETHER, | ||
135 | ! Run->IsUp )); | ||
136 | |||
137 | if( handlesInterface( Run->Name ) && | ||
138 | Run->CardType == ARPHRD_ETHER && | ||
139 | ! Run->IsUp | ||
140 | ) { | ||
141 | Log(("Released(OFF)\n" )); | ||
142 | // proper type, and Not UP -> free | ||
143 | NC->setCurrentState( Off ); | ||
144 | return; | ||
145 | } | ||
146 | } | 50 | } |
147 | // no free found | ||
148 | Log(("None available\n" )); | ||
149 | 51 | ||
150 | NC->setCurrentState( Unavailable ); | 52 | // if there is a PAN connection that is UP but not |
53 | // yet configured (no ifup) the we are available | ||
54 | return ( hasFreePANConnection() ) ? Available : Unknown; | ||
151 | } | 55 | } |
152 | 56 | ||
153 | bool BluetoothBNEPRun::setState( NodeCollection * NC, Action_t A, bool ) { | 57 | QString BluetoothBNEPRun::setMyState( NodeCollection * NC, Action_t A, bool ) { |
154 | 58 | ||
155 | // we only handle activate and deactivate | 59 | if( A == Activate ) { |
156 | switch( A ) { | 60 | if( hasFreePANConnection( 1 ) ) { |
157 | case Activate : | 61 | // we have now an assignedinterface |
158 | { | 62 | } else { |
159 | if( NC->currentState() != Off ) { | 63 | return QString("TODO : Start PAND"); |
160 | return 0; | 64 | } |
161 | } | 65 | |
162 | InterfaceInfo * N = getInterface(); | 66 | Log(( "Assigned interface" )); |
163 | if( ! N ) { | 67 | NC->setCurrentState( Available ); |
164 | // no interface available | 68 | |
165 | NC->setCurrentState( Unavailable ); | 69 | return QString(); |
166 | return 0; | ||
167 | } | ||
168 | // because we were OFF the interface | ||
169 | // we get back is NOT assigned | ||
170 | N->assignNode( netNode() ); | ||
171 | assignInterface( N ); | ||
172 | Log(("Assing %p\n", N )); | ||
173 | NC->setCurrentState( Available ); | ||
174 | return 1; | ||
175 | } | ||
176 | case Deactivate : | ||
177 | if( NC->currentState() == IsUp ) { | ||
178 | // bring down first | ||
179 | if( ! connection()->setState( Down ) ) | ||
180 | // could not ... | ||
181 | return 0; | ||
182 | } else if( NC->currentState() != Available ) { | ||
183 | return 1; | ||
184 | } | ||
185 | assignedInterface()->assignNode( 0 ); // release | ||
186 | assignInterface( 0 ); | ||
187 | NC->setCurrentState( Off ); | ||
188 | return 1; | ||
189 | default : | ||
190 | // FT | ||
191 | break; | ||
192 | } | 70 | } |
193 | return 0; | 71 | |
72 | if( A == Deactivate ) { | ||
73 | // nothing to do | ||
74 | NC->setCurrentState( Off ); | ||
75 | return QString(); | ||
76 | } | ||
77 | return QString(); | ||
194 | } | 78 | } |
195 | 79 | ||
196 | bool BluetoothBNEPRun::canSetState( State_t Curr , Action_t A ) { | 80 | bool BluetoothBNEPRun::handlesInterface( const QString & S ) { |
197 | // we only handle up down activate and deactivate | 81 | return Pat.match( S ) >= 0; |
198 | switch( A ) { | 82 | } |
199 | case Activate : | 83 | |
200 | { // at least available | 84 | bool BluetoothBNEPRun::handlesInterface( InterfaceInfo * I ) { |
201 | if( Curr == Available ) { | 85 | return handlesInterface( I->Name ); |
202 | return 1; | 86 | } |
203 | } | 87 | |
204 | // or we can make one available | 88 | bool BluetoothBNEPRun::hasFreePANConnection( bool Grab ) { |
205 | InterfaceInfo * N = getInterface(); | 89 | |
206 | if( ! N || N->assignedNode() != 0 ) { | 90 | if( ! OT ) { |
207 | // non available or assigned | 91 | OT = OTGateway::getOTGateway(); |
208 | return 0; | 92 | } |
93 | |||
94 | // load PAN connections | ||
95 | OTPANConnection * C; | ||
96 | InterfaceInfo * Run; | ||
97 | InterfaceInfo * Candidate = 0; // reuse this interface | ||
98 | PANConnectionVector Conns = OT->getPANConnections(); | ||
99 | System & Sys = NSResources->system(); | ||
100 | bool IsValid; | ||
101 | |||
102 | for( unsigned int i = 0; | ||
103 | i < Conns.count(); | ||
104 | i ++ ) { | ||
105 | C = Conns[i]; | ||
106 | |||
107 | if( Data.AllowAll ) { | ||
108 | // we allow all | ||
109 | IsValid = 1; | ||
110 | } else { | ||
111 | // is this PAN connection connecting to a Peer | ||
112 | // we allow ? | ||
113 | IsValid = 0; | ||
114 | for ( QStringList::Iterator it = Data.BDAddress.begin(); | ||
115 | it != Data.BDAddress.end(); | ||
116 | ++ it ) { | ||
117 | if( C->ConnectedTo == (*it) ) { | ||
118 | // this is a connection we could accept | ||
119 | IsValid = 1; | ||
120 | break; | ||
209 | } | 121 | } |
210 | return 1; | ||
211 | } | 122 | } |
212 | case Deactivate : | 123 | } |
213 | return ( Curr >= Available ); | 124 | |
214 | default : | 125 | if( ! IsValid ) { |
215 | // FT | 126 | Log(("%s to %s not acceptable\n", |
216 | break; | 127 | C->Device.latin1(), |
128 | C->ConnectedTo.latin1() )); | ||
129 | // don't bother checking this address | ||
130 | // it is not acceptable | ||
131 | continue; | ||
132 | } | ||
133 | |||
134 | // is this PAN connection available to us ? | ||
135 | Run = Sys.findInterface( C->Device ); | ||
136 | |||
137 | if( Run && Run->IsUp ) { | ||
138 | // this PAN connection is up | ||
139 | Log(("%s acceptable but unavailable\n", | ||
140 | C->Device.latin1() )); | ||
141 | // find others | ||
142 | continue; | ||
143 | } | ||
144 | |||
145 | // we at least have a possible interface | ||
146 | if( ! Candidate ) { | ||
147 | Candidate = Run; | ||
148 | } | ||
217 | } | 149 | } |
218 | return 0; | ||
219 | } | ||
220 | 150 | ||
221 | // get interface that is free or assigned to us | 151 | if( Candidate ) { |
222 | InterfaceInfo * BluetoothBNEPRun::getInterface( void ) { | 152 | if ( Grab ) { |
223 | 153 | netNode()->connection()->assignInterface( Candidate ); | |
224 | System & S = NSResources->system(); | ||
225 | InterfaceInfo * best = 0, * Run; | ||
226 | |||
227 | for( QDictIterator<InterfaceInfo> It(S.interfaces()); | ||
228 | It.current(); | ||
229 | ++It ) { | ||
230 | Run = It.current(); | ||
231 | if( handlesInterface( Run->Name ) && | ||
232 | Run->CardType == ARPHRD_ETHER | ||
233 | ) { | ||
234 | // this is a bluetooth card | ||
235 | if( Run->assignedNode() == netNode() ) { | ||
236 | // assigned to us | ||
237 | return Run; | ||
238 | } else if( Run->assignedNode() == 0 ) { | ||
239 | // free | ||
240 | best = Run; | ||
241 | } | ||
242 | } | 154 | } |
155 | return 1; | ||
243 | } | 156 | } |
244 | return best; // can be 0 | ||
245 | } | ||
246 | 157 | ||
247 | bool BluetoothBNEPRun::handlesInterface( const QString & S ) { | 158 | // no free PAN |
248 | return Pat.match( S ) >= 0; | 159 | return 0; |
249 | } | 160 | } |
161 | |||