19 #include <QModelIndex> |
19 #include <QModelIndex> |
20 #include <btsettingmodel.h> |
20 #include <btsettingmodel.h> |
21 #include <btdevicemodel.h> |
21 #include <btdevicemodel.h> |
22 #include <btdelegatefactory.h> |
22 #include <btdelegatefactory.h> |
23 #include <hbnotificationdialog.h> |
23 #include <hbnotificationdialog.h> |
|
24 #include "btqtconstants.h" |
|
25 #include "btuiutil.h" |
|
26 #include <bluetoothuitrace.h> |
|
27 #include <btengconnman.h> |
24 |
28 |
25 BtDelegateDevSecurity::BtDelegateDevSecurity( |
29 BtDelegateDevSecurity::BtDelegateDevSecurity( |
26 BtSettingModel* settingModel, |
30 BtSettingModel* settingModel, |
27 BtDeviceModel* deviceModel, |
31 BtDeviceModel* deviceModel, |
28 QObject *parent) : |
32 QObject *parent) : |
29 BtAbstractDelegate(settingModel, deviceModel, parent), mBtEngDevMan(0), mBtengConnMan(0), mDisconnectDelegate(0) |
33 BtAbstractDelegate(settingModel, deviceModel, parent), mBtEngDevMan(0), |
30 { |
34 mDisconnectDelegate(0), mBtEngAddr(0), mRegDevArray(0), mOperation(0), |
31 |
35 mDevice(0),mNewDev(0), mActiveHandling(false),mAddingBlockedDev(false) |
|
36 { |
|
37 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
|
38 mRegDevArray = new CBTDeviceArray(1); |
|
39 BTUI_ASSERT_X( mRegDevArray, "BtDelegateDevSecurity::BtDelegateDevSecurity()", |
|
40 "can't allocate regdevarray"); |
|
41 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
32 } |
42 } |
33 |
43 |
34 BtDelegateDevSecurity::~BtDelegateDevSecurity() |
44 BtDelegateDevSecurity::~BtDelegateDevSecurity() |
35 { |
45 { |
|
46 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
36 delete mBtEngDevMan; |
47 delete mBtEngDevMan; |
37 delete mBtengConnMan; |
|
38 delete mDisconnectDelegate; |
48 delete mDisconnectDelegate; |
39 } |
49 delete mRegDevArray; |
40 |
50 delete mNewDev; |
41 |
51 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
|
52 } |
|
53 |
|
54 |
|
55 /*! |
|
56 Returns the supported editor types. |
|
57 \return the sum of supported editor types |
|
58 */ |
|
59 int BtDelegateDevSecurity::supportedEditorTypes() const |
|
60 { |
|
61 return BtDelegate::UnpairDevice |
|
62 | BtDelegate::BlockDevice |
|
63 | BtDelegate::UnblockDevice |
|
64 | BtDelegate::TrustDevice |
|
65 | BtDelegate::UntrustDevice; |
|
66 } |
|
67 |
|
68 /*! |
|
69 * performs operations on remote device: unpair, authorize/unauthorize, block/unblock |
|
70 * params of type QList<QVariant>: |
|
71 * 1) remote device address (QString) |
|
72 * 2) DeviceSecurityService operation |
|
73 */ |
42 void BtDelegateDevSecurity::exec( const QVariant ¶ms ) |
74 void BtDelegateDevSecurity::exec( const QVariant ¶ms ) |
43 { |
75 { |
|
76 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
|
77 // check if in use already |
|
78 if ( mActiveHandling ) { |
|
79 emit delegateCompleted(KErrInUse, this); |
|
80 BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrInUse ); |
|
81 return; |
|
82 } |
|
83 mActiveHandling = true; |
|
84 |
|
85 // check parameters |
|
86 QList<QVariant> paramList = params.value< QList<QVariant> >(); |
|
87 if (paramList.count() != 2) { |
|
88 // wrong parameters |
|
89 emitCommandComplete( KErrArgument ); |
|
90 BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrArgument ); |
|
91 return; |
|
92 } |
|
93 |
|
94 int error = 0; |
|
95 TRAP( error, { |
|
96 if( !mBtEngDevMan) { |
|
97 mBtEngDevMan = CBTEngDevMan::NewL( this ); |
|
98 } |
|
99 }); |
|
100 if (error) { |
|
101 emitCommandComplete( KErrNoMemory ); |
|
102 BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrNoMemory ); |
|
103 return; |
|
104 } |
|
105 |
|
106 mStrBtAddr = paramList.at(0).value<QString>(); // device to operate on |
|
107 mOperation = paramList.at(1).toInt(); // operation |
|
108 |
|
109 addrReadbleStringToSymbian( mStrBtAddr, mBtEngAddr ); |
|
110 BtTraceBtAddr1( TRACE_DEBUG, DUMMY_DEVLIST, "device addr=", mBtEngAddr ); |
|
111 |
|
112 |
|
113 // get device from registry since it is needed for all operations |
|
114 mSearchPattern.FindAddress( mBtEngAddr ); |
|
115 mRegDevArray->ResetAndDestroy(); |
|
116 mBtEngDevMan->GetDevices(mSearchPattern, mRegDevArray); // callback is HandleGetDevicesComplete() |
|
117 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
|
118 } |
|
119 |
|
120 |
|
121 void BtDelegateDevSecurity::unpair() |
|
122 { |
|
123 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
44 int error = KErrNone; |
124 int error = KErrNone; |
45 QModelIndex index = params.value<QModelIndex>(); |
125 |
46 |
126 // unpair first since malicious device might try to connect/pair again |
47 QString strBtAddr = getDeviceModel()->data(index, |
127 // immediately after disconnecting |
48 BtDeviceModel::ReadableBdaddrRole).toString(); |
128 mDevice->SetPaired(EFalse); |
49 |
129 mDevice->DeleteLinkKey(); |
50 mdeviceName = getDeviceModel()->data(index,BtDeviceModel::NameAliasRole).toString(); |
130 |
51 |
131 // untrust the device also |
52 TBTDevAddr symaddr; |
132 TBTDeviceSecurity security = mDevice->GlobalSecurity(); |
53 TBuf<KBTDevAddrSize * 2> buffer(strBtAddr.utf16()); |
133 security.SetNoAuthorise( EFalse ); |
54 symaddr.SetReadable( buffer ); |
134 mDevice->SetGlobalSecurity( security ); |
55 |
135 |
56 // Disconnect if paired device was connected |
136 error = mBtEngDevMan->ModifyDevice( *mDevice ); // see callback for possible disconnect |
57 if ( ! mBtengConnMan ){ |
|
58 TRAP( error, mBtengConnMan = CBTEngConnMan::NewL(this) ); |
|
59 } |
|
60 TBTEngConnectionStatus connstatus; |
|
61 if ( !error && mBtengConnMan->IsConnected(symaddr, connstatus ) == KErrNone) { |
|
62 if ( connstatus == EBTEngConnected) { |
|
63 if (! mDisconnectDelegate){ |
|
64 mDisconnectDelegate = BtDelegateFactory::newDelegate( |
|
65 BtDelegate::Disconnect, getSettingModel(), getDeviceModel()); |
|
66 connect( mDisconnectDelegate, SIGNAL(commandCompleted(int)), this, SLOT(disconnectDelegateCompleted(int)) ); |
|
67 |
|
68 } |
|
69 QList<QVariant>list; |
|
70 QVariant paramFirst; |
|
71 paramFirst.setValue(index); |
|
72 QVariant paramSecond; |
|
73 DisconnectOption discoOpt = ServiceLevel; |
|
74 paramSecond.setValue((int)discoOpt); |
|
75 list.append(paramFirst); |
|
76 list.append(paramSecond); |
|
77 QVariant paramsList; |
|
78 paramsList.setValue(list); |
|
79 mDisconnectDelegate->exec(paramsList); |
|
80 } |
|
81 } |
|
82 |
|
83 // Set device as unpaired |
|
84 CBTDevice *symBtDevice = 0; |
|
85 TRAP( error, { |
|
86 symBtDevice = CBTDevice::NewL( symaddr ); |
|
87 if( !mBtEngDevMan) { |
|
88 mBtEngDevMan = CBTEngDevMan::NewL( this ); |
|
89 } |
|
90 }); |
|
91 |
|
92 if ( !error ) { |
|
93 symBtDevice->SetPaired(EFalse); |
|
94 // deleting link key for executing unpair is safe as no |
|
95 // link key shall exist if the device has been unpaired. |
|
96 symBtDevice->DeleteLinkKey(); |
|
97 error = mBtEngDevMan->ModifyDevice( *symBtDevice ); |
|
98 } |
|
99 delete symBtDevice; |
|
100 |
137 |
101 if ( error ) { |
138 if ( error ) { |
102 emitCommandComplete(error); |
139 emitCommandComplete(error); |
103 } |
140 } |
|
141 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
|
142 } |
|
143 |
|
144 void BtDelegateDevSecurity::authorizeOrBlock() |
|
145 { |
|
146 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
|
147 BOstraceExt1( TRACE_NORMAL, DUMMY_DEVLIST, "operation (Unpair|Block|Unblock|Authorize|Unauthorize)=%d", |
|
148 mOperation); |
|
149 int error = KErrNone; |
|
150 |
|
151 TBTDeviceSecurity security = mDevice->GlobalSecurity(); |
|
152 switch ( mOperation ) { |
|
153 case BtAuthorize: |
|
154 security.SetNoAuthorise( ETrue ); // set trust status to true |
|
155 security.SetBanned( EFalse ); |
|
156 break; |
|
157 case BtUnauthorize: |
|
158 security.SetNoAuthorise( EFalse ); |
|
159 break; |
|
160 case BtUnblock: |
|
161 security.SetBanned( EFalse ); |
|
162 break; |
|
163 case BtBlock: |
|
164 security.SetBanned( ETrue ); |
|
165 security.SetNoAuthorise( EFalse ); // set trust status to false |
|
166 break; |
|
167 } |
|
168 |
|
169 mDevice->SetGlobalSecurity( security ); |
|
170 if ( (mOperation == BtBlock) || (mOperation == BtUnblock) ) { |
|
171 // deleting link key for executing unblock is safe as no |
|
172 // link key shall exist if the device has been blocked. |
|
173 mDevice->DeleteLinkKey(); |
|
174 if ( mOperation == BtBlock ) { |
|
175 mDevice->SetPaired(EFalse); |
|
176 } |
|
177 } |
|
178 error = mBtEngDevMan->ModifyDevice( *mDevice ); |
|
179 |
|
180 if ( error ) { |
|
181 emitCommandComplete(error); |
|
182 } |
|
183 BOstraceFunctionExitExt( DUMMY_DEVLIST, this, error ); |
104 } |
184 } |
105 |
185 |
106 void BtDelegateDevSecurity::cancel() |
186 void BtDelegateDevSecurity::cancel() |
107 { |
187 { |
108 |
188 BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); |
|
189 if ( mActiveHandling ) { |
|
190 mAddingBlockedDev = false; |
|
191 emitCommandComplete(KErrNone); |
|
192 } |
|
193 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
109 } |
194 } |
110 |
195 |
111 void BtDelegateDevSecurity::disconnectDelegateCompleted( int err ) |
196 void BtDelegateDevSecurity::disconnectDelegateCompleted( int err ) |
112 { |
197 { |
113 Q_UNUSED(err); |
198 BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err ); |
114 } |
199 if (mDisconnectDelegate) { |
115 |
200 delete mDisconnectDelegate; |
116 void BtDelegateDevSecurity::HandleDevManComplete( TInt aErr ) |
201 mDisconnectDelegate = 0; |
117 { |
202 } |
118 emitCommandComplete(aErr); |
203 emitCommandComplete(err); |
119 } |
204 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
120 |
205 } |
121 void BtDelegateDevSecurity::HandleGetDevicesComplete( TInt aErr, CBTDeviceArray* aDeviceArray ) |
206 |
122 { |
207 void BtDelegateDevSecurity::HandleDevManComplete( TInt err ) |
123 Q_UNUSED(aErr); |
208 { |
124 Q_UNUSED(aDeviceArray); |
209 BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err ); |
|
210 |
|
211 if ( !mActiveHandling ) { |
|
212 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
|
213 return; |
|
214 } |
|
215 if ( !err ) { |
|
216 if ( mAddingBlockedDev ) { |
|
217 // blocked a device which was not in the registry originally |
|
218 mAddingBlockedDev = false; |
|
219 delete mNewDev; |
|
220 mNewDev = 0; |
|
221 } |
|
222 else if ( mOperation == BtBlock || mOperation == BtUnpair) { |
|
223 // disconnect after blocking/unpairing if device is connected; |
|
224 // disconnect done after block/unpair, instead of before, to prevent a malicious device |
|
225 // from reconnecting/"re-pairing" |
|
226 CBTEngConnMan *connMan(0); |
|
227 TRAP( err, connMan = CBTEngConnMan::NewL() ); |
|
228 TBTEngConnectionStatus connstatus(EBTEngNotConnected); |
|
229 if (!err) { |
|
230 err = connMan->IsConnected(mBtEngAddr, connstatus ); |
|
231 delete connMan; |
|
232 } |
|
233 if ( !err && connstatus == EBTEngConnected ) { |
|
234 if (! mDisconnectDelegate){ |
|
235 mDisconnectDelegate = BtDelegateFactory::newDelegate( |
|
236 BtDelegate::DisconnectService, settingModel(), deviceModel()); |
|
237 connect( mDisconnectDelegate, SIGNAL(delegateCompleted(int,BtAbstractDelegate*)), this, |
|
238 SLOT(disconnectDelegateCompleted(int)) ); |
|
239 } |
|
240 QList<QVariant>list; |
|
241 list.append(QVariant(ServiceLevel)); |
|
242 list.append(QVariant(mStrBtAddr)); |
|
243 mDisconnectDelegate->exec(QVariant(list)); // see callback for continuation |
|
244 return; |
|
245 } |
|
246 } |
|
247 } |
|
248 emitCommandComplete(err); |
|
249 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
|
250 } |
|
251 |
|
252 void BtDelegateDevSecurity::HandleGetDevicesComplete( TInt err, CBTDeviceArray* aDeviceArray ) |
|
253 { |
|
254 BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err ); |
|
255 |
|
256 if ( mActiveHandling ) { |
|
257 if ( !err && aDeviceArray->Count() ) { |
|
258 mDevice = aDeviceArray->At( 0 ); |
|
259 switch ( mOperation ) { |
|
260 case BtUnpair: |
|
261 unpair(); |
|
262 break; |
|
263 case BtAuthorize: |
|
264 case BtUnauthorize: |
|
265 case BtUnblock: |
|
266 case BtBlock: |
|
267 authorizeOrBlock(); |
|
268 break; |
|
269 default: |
|
270 // wrong parameter |
|
271 emitCommandComplete( KErrArgument ); |
|
272 } |
|
273 } |
|
274 else if ( err == KErrNotFound && mOperation == BtBlock) { // device not in registry, need to add it |
|
275 mAddingBlockedDev = true; |
|
276 TRAP( err, { |
|
277 mNewDev = CBTDevice::NewL( mBtEngAddr ); |
|
278 }); |
|
279 if ( !err ) { |
|
280 // get needed info about device from model, e.g. name, cod |
|
281 QString btStringAddr; |
|
282 addrSymbianToReadbleString(btStringAddr, mBtEngAddr); |
|
283 QModelIndex start = deviceModel()->index(0,0); |
|
284 QModelIndexList indexList = deviceModel()->match(start, |
|
285 BtDeviceModel::ReadableBdaddrRole, btStringAddr); |
|
286 // ToDo: can we be sure that device will always be found in the model? |
|
287 QModelIndex index = indexList.at(0); |
|
288 QString devName = deviceModel()->data(index,BtDeviceModel::NameAliasRole).toString(); |
|
289 BtTraceQString1( TRACE_DEBUG, DUMMY_DEVLIST, "device name=", devName); |
|
290 TBuf<KMaxBCBluetoothNameLen> buf( devName.utf16() ); |
|
291 TRAP( err, mNewDev->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( buf ) )); |
|
292 if( !err ) { |
|
293 int cod = (index.data(BtDeviceModel::CoDRole)).toInt(); |
|
294 mNewDev->SetDeviceClass(cod); |
|
295 TBTDeviceSecurity security = mNewDev->GlobalSecurity(); |
|
296 security.SetBanned( ETrue ); |
|
297 security.SetNoAuthorise( EFalse ); // set trust status to false |
|
298 mNewDev->SetGlobalSecurity( security ); |
|
299 mNewDev->DeleteLinkKey(); |
|
300 mNewDev->SetPaired(EFalse); |
|
301 err = mBtEngDevMan->AddDevice( *mNewDev ); // see callback HandleDevManComplete() |
|
302 } |
|
303 } |
|
304 } |
|
305 if (err) { |
|
306 mAddingBlockedDev = false; |
|
307 emitCommandComplete( err ); |
|
308 } |
|
309 } |
|
310 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
125 } |
311 } |
126 |
312 |
127 void BtDelegateDevSecurity::emitCommandComplete(int error) |
313 void BtDelegateDevSecurity::emitCommandComplete(int error) |
128 { |
314 { |
|
315 BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, error ); |
129 // no dialogs here since stack provides "unpaired to %1" dialog |
316 // no dialogs here since stack provides "unpaired to %1" dialog |
130 // and failures are not reported |
317 // and failures are not reported |
131 |
318 mActiveHandling = false; |
132 emit commandCompleted(error); |
319 mAddingBlockedDev = false; |
133 } |
320 if ( mNewDev ) { |
134 |
321 delete mNewDev; |
135 void BtDelegateDevSecurity::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, |
322 mNewDev = 0; |
136 RBTDevAddrArray* aConflicts ) |
323 } |
137 { |
324 emit delegateCompleted(error, this); |
138 Q_UNUSED(aAddr); |
325 BOstraceFunctionExit1( DUMMY_DEVLIST, this ); |
139 Q_UNUSED(aErr); |
326 } |
140 Q_UNUSED(aConflicts); |
327 |
141 } |
328 |
142 |
329 |
143 void BtDelegateDevSecurity::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr ) |
330 |
144 { |
|
145 Q_UNUSED(aAddr); |
|
146 Q_UNUSED(aErr); |
|
147 } |
|
148 |
|
149 |
|
150 |
|
151 |
|