|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "logger.h" |
|
20 #include "functionserver.h" |
|
21 #include "bluetoothfunctionserver.h" |
|
22 #include "bluetoothremotedevice.h" |
|
23 #include "fs_methodcall.h" |
|
24 #include "bluetoothclientconnection.h" |
|
25 #include "btrfcommserverconnection.h" |
|
26 #include "bluetoothpusheventlistener.h" |
|
27 #include "javasymbianoslayer.h" |
|
28 |
|
29 using namespace std; |
|
30 using namespace java::util; |
|
31 |
|
32 namespace java |
|
33 { |
|
34 namespace bluetooth |
|
35 { |
|
36 |
|
37 const TInt KSizeOfListenQueue = 7; |
|
38 #define SERVICE_AVAILABLE 0xFF |
|
39 #define SERVICE_NOTAVAILABLE 0x00 |
|
40 _LIT(KRfComm, "RFCOMM"); |
|
41 |
|
42 OS_EXPORT RFCOMMServerConnection::RFCOMMServerConnection( |
|
43 java::bluetooth::BluetoothFunctionServer* server): |
|
44 mAcceptMonitor(NULL), |
|
45 mAsyncAccept(false), |
|
46 mBtUrlParams(NULL), |
|
47 mBtClientConn(NULL), |
|
48 mServer(server), |
|
49 mIsConnected(EFalse), |
|
50 mServRec(NULL), |
|
51 mState(ENone) |
|
52 { |
|
53 JELOG2(EJavaBluetooth); |
|
54 } |
|
55 |
|
56 OS_EXPORT RFCOMMServerConnection::~RFCOMMServerConnection() |
|
57 { |
|
58 JELOG2(EJavaBluetooth); |
|
59 CloseServer(); |
|
60 delete mAcceptMonitor; |
|
61 } |
|
62 |
|
63 OS_EXPORT int RFCOMMServerConnection::openServer(bool authorize, |
|
64 bool authenticate, bool encrypt) |
|
65 { |
|
66 JELOG2(EJavaBluetooth); |
|
67 return ServerOpen(authorize, authenticate, encrypt); |
|
68 } |
|
69 |
|
70 OS_EXPORT int RFCOMMServerConnection::ServerOpen(TBool authorize, |
|
71 TBool authenticate, TBool encrypt) |
|
72 { |
|
73 JELOG2(EJavaBluetooth); |
|
74 int result = 0; |
|
75 TRAP(result, CallMethodL(this, &RFCOMMServerConnection::ServerOpenL, |
|
76 authorize, authenticate, encrypt, mServer)); |
|
77 return result; |
|
78 } |
|
79 |
|
80 OS_EXPORT ServiceRecord *RFCOMMServerConnection::getServiceRecordHandle() |
|
81 { |
|
82 return mServRec; |
|
83 } |
|
84 |
|
85 void RFCOMMServerConnection::ServerOpenL(TBool authorize, TBool authenticate, |
|
86 TBool encrypt) |
|
87 { |
|
88 JELOG2(EJavaBluetooth); |
|
89 |
|
90 if (mState != ENone) |
|
91 { |
|
92 User::Leave(KErrInUse); |
|
93 } |
|
94 |
|
95 User::LeaveIfError(mSocketServ.Connect()); |
|
96 User::LeaveIfError(mSocketServ.ShareAuto()); |
|
97 |
|
98 TRAPD(err, |
|
99 { |
|
100 // Set this active object to connecting state |
|
101 mState = EConnecting; |
|
102 |
|
103 // Set a Bluetooth socket address |
|
104 BindL(authorize, authenticate, encrypt); |
|
105 |
|
106 // Set a socket to listen for incoming connections |
|
107 ListenL(); |
|
108 } |
|
109 ); |
|
110 |
|
111 if (KErrNone != err) |
|
112 { |
|
113 ELOG(EJavaBluetooth, |
|
114 "- RFCOMMServerConnection::ServerOpenL: Exception caught "); |
|
115 mState = ENone; |
|
116 mSocketServ.Close(); |
|
117 User::LeaveIfError(err); |
|
118 } |
|
119 |
|
120 } |
|
121 |
|
122 void RFCOMMServerConnection::BindL(TBool authorize, TBool authenticate, |
|
123 TBool encrypt) |
|
124 { |
|
125 JELOG2(EJavaBluetooth); |
|
126 // Load protocol, RFCOMM |
|
127 TProtocolDesc protocolDesc; |
|
128 User::LeaveIfError(mSocketServ.FindProtocol(KRfComm(), protocolDesc)); |
|
129 |
|
130 LOG(EJavaBluetooth, EInfo, |
|
131 " RFCOMMServerConnection::Bind: Opening A Listener Socket "); |
|
132 |
|
133 // Open a socket |
|
134 mListenSock = CBluetoothSocket::NewL(*this, mSocketServ, |
|
135 protocolDesc.iSockType, KRFCOMM); |
|
136 |
|
137 mListenSock->SetNotifier(*this); |
|
138 |
|
139 TInt Channel = 0; |
|
140 // Get listening channel |
|
141 User::LeaveIfError(mListenSock->GetOpt(KRFCOMMGetAvailableServerChannel, |
|
142 KSolBtRFCOMM, Channel)); |
|
143 |
|
144 // Set security |
|
145 TBTServiceSecurity secSettings; |
|
146 |
|
147 secSettings.SetAuthentication(authenticate); |
|
148 secSettings.SetAuthorisation(authorize); |
|
149 secSettings.SetEncryption(encrypt); |
|
150 |
|
151 LOG(EJavaBluetooth, EInfo, |
|
152 " RFCOMMServerConnection::Accept: setting The Security Settings "); |
|
153 // Attach the security settings. |
|
154 mBtSockAddr.SetSecurity(secSettings); |
|
155 |
|
156 LOG1(EJavaBluetooth, EInfo, |
|
157 " RFCOMMServerConnection::Bind: setting port to: %d", Channel); |
|
158 // Setting Rfcom Port |
|
159 mBtSockAddr.SetPort(Channel); |
|
160 |
|
161 LOG(EJavaBluetooth, EInfo, |
|
162 " RFCOMMServerConnection::Bind: Binding Bluetooth Socket "); |
|
163 // Bind bluetooth socket |
|
164 User::LeaveIfError(mListenSock->Bind(mBtSockAddr)); |
|
165 } |
|
166 |
|
167 OS_EXPORT int RFCOMMServerConnection::GetRfListeningChannel() |
|
168 { |
|
169 JELOG2(EJavaBluetooth); |
|
170 int result = 0; |
|
171 TRAPD(err, CallMethodL(result, this, |
|
172 &RFCOMMServerConnection::GetRfListeningChannelFs, mServer)); |
|
173 |
|
174 if (err != KErrNone) |
|
175 { |
|
176 return err; |
|
177 } |
|
178 |
|
179 return result; |
|
180 } |
|
181 |
|
182 int RFCOMMServerConnection::GetRfListeningChannelFs() |
|
183 { |
|
184 JELOG2(EJavaBluetooth); |
|
185 TInt channel = 0; |
|
186 if (mState != EConnecting) |
|
187 { |
|
188 return -1; |
|
189 } |
|
190 |
|
191 channel = mListenSock->LocalPort(); |
|
192 LOG1(EJavaBluetooth, EInfo, |
|
193 " RFCOMMServerConnection::GetRfListeningChannelFs: %d", channel); |
|
194 return channel; |
|
195 |
|
196 } |
|
197 |
|
198 void RFCOMMServerConnection::ListenL() |
|
199 { |
|
200 JELOG2(EJavaBluetooth); |
|
201 // Listen on port |
|
202 User::LeaveIfError(mListenSock->Listen(KSizeOfListenQueue)); |
|
203 } |
|
204 |
|
205 OS_EXPORT int RFCOMMServerConnection::asyncAccept( |
|
206 java::bluetooth::BluetoothPushEventListener* aEventListener, |
|
207 BtUrlParams *aBtUrlParams) |
|
208 { |
|
209 JELOG2(EJavaBluetooth); |
|
210 //Store event listener and notify it when client is accepted. |
|
211 //Make a call to accept and do not wait. |
|
212 mAsyncAccept = true; |
|
213 mPushEventListener = aEventListener; |
|
214 mBtUrlParams = aBtUrlParams; |
|
215 int result = 0; |
|
216 TRAPD(err, CallMethodL(result, this, &RFCOMMServerConnection::AcceptL, |
|
217 mServer)); |
|
218 return err; |
|
219 } |
|
220 |
|
221 OS_EXPORT long RFCOMMServerConnection::Accept() |
|
222 { |
|
223 JELOG2(EJavaBluetooth); |
|
224 long result = 0; |
|
225 mBtClientConn = NULL; |
|
226 |
|
227 TRAPD(err, CallMethodL(result, this, &RFCOMMServerConnection::AcceptL, |
|
228 mServer)); |
|
229 |
|
230 if (err != KErrNone) |
|
231 { |
|
232 return err; |
|
233 } |
|
234 |
|
235 mAcceptMonitor->wait(); |
|
236 |
|
237 if (mAcceptStatus != KErrNone) |
|
238 { |
|
239 return mAcceptStatus; |
|
240 } |
|
241 |
|
242 mAcceptedSocket = NULL; |
|
243 |
|
244 return reinterpret_cast<long>(mBtClientConn); |
|
245 } |
|
246 |
|
247 long RFCOMMServerConnection::AcceptL() |
|
248 { |
|
249 JELOG2(EJavaBluetooth); |
|
250 |
|
251 // Open blank socket and pass it to accept to be assigned a proper |
|
252 // socket upon completion of Accept() |
|
253 mAcceptedSocket = CBluetoothSocket::NewL(*this, mSocketServ); |
|
254 LOG(EJavaBluetooth, EInfo, |
|
255 " RFCOMMServerConnection::Accept: Set To Accept Incoming Connections "); |
|
256 |
|
257 if (NULL == mAcceptMonitor) |
|
258 { |
|
259 mAcceptMonitor = java::util::Monitor::createMonitor(); |
|
260 } |
|
261 |
|
262 mAcceptStatus = 0; |
|
263 |
|
264 // Enabling the advertising flag |
|
265 if (NULL != mServRec) |
|
266 { |
|
267 mServRec -> setAdvertiseFs(ETrue); |
|
268 } |
|
269 int err = mListenSock->Accept((*mAcceptedSocket)); |
|
270 LOG1(EJavaBluetooth,EInfo, |
|
271 " RFCOMMServerConnection::Accept: accept return: %d", err); |
|
272 |
|
273 return err; |
|
274 } |
|
275 |
|
276 OS_EXPORT int RFCOMMServerConnection::initializeServiceRecord( |
|
277 TInt aChannel, TUUID &aServiceUUID, TDesC8 &aServiceName, bool aIsGOEP) |
|
278 { |
|
279 JELOG2(EJavaBluetooth); |
|
280 int result = 0; |
|
281 |
|
282 if (NULL == mServRec) |
|
283 { |
|
284 TRAP(result, CallMethodL(mServRec, this, |
|
285 &RFCOMMServerConnection::createServiceRecordL, mServer)); |
|
286 |
|
287 if (KErrNone == result) |
|
288 { |
|
289 TInt protocol = (true == aIsGOEP)?PROTOCOL_GOEP : PROTOCOL_RFCOMM; |
|
290 |
|
291 TRAP(result, mServRec->initializeRecordL(protocol, |
|
292 aChannel, aServiceUUID, aServiceName)); |
|
293 } |
|
294 } |
|
295 return result; |
|
296 } |
|
297 |
|
298 OS_EXPORT int RFCOMMServerConnection::initializeServiceRecord( |
|
299 int aChannel, wstring aServiceUUID, wstring aServiceName, bool aIsGOEP) |
|
300 { |
|
301 JELOG2(EJavaBluetooth); |
|
302 int result = 0; |
|
303 |
|
304 if (NULL == mServRec) |
|
305 { |
|
306 TRAP(result, CallMethodL(mServRec, this, |
|
307 &RFCOMMServerConnection::createServiceRecordL, mServer)); |
|
308 |
|
309 if (KErrNone == result) |
|
310 { |
|
311 TInt protocol = (true == aIsGOEP)?PROTOCOL_GOEP : PROTOCOL_RFCOMM; |
|
312 |
|
313 result = mServRec->initializeRecord(protocol, |
|
314 aChannel, aServiceUUID, aServiceName); |
|
315 } |
|
316 } |
|
317 return result; |
|
318 } |
|
319 |
|
320 OS_EXPORT int RFCOMMServerConnection::restorePersistentRecord() |
|
321 { |
|
322 JELOG2(EJavaBluetooth); |
|
323 int result = 0; |
|
324 if (NULL != mServRec) |
|
325 { |
|
326 result = mServRec->restorePersistentRecord(); |
|
327 } |
|
328 return result; |
|
329 } |
|
330 |
|
331 ServiceRecord *RFCOMMServerConnection::createServiceRecordL() |
|
332 { |
|
333 return ServiceRecord::NewL(mServer); |
|
334 } |
|
335 |
|
336 int RFCOMMServerConnection::CloseServer() |
|
337 { |
|
338 JELOG2(EJavaBluetooth); |
|
339 int result = 0; |
|
340 mIsConnected = EFalse; |
|
341 mAsyncAccept = false; |
|
342 CallMethod(this, &RFCOMMServerConnection::Close, mServer); |
|
343 return result; |
|
344 } |
|
345 |
|
346 void RFCOMMServerConnection::Close() |
|
347 { |
|
348 JELOG2(EJavaBluetooth); |
|
349 |
|
350 // Deleting service record. |
|
351 ServiceRecord::cleanup(mServRec); |
|
352 |
|
353 if (mState != ENone) |
|
354 { |
|
355 mListenSock->CancelAll(); |
|
356 mListenSock->Shutdown(RSocket::EImmediate); |
|
357 delete mListenSock; //Destructor closes the socket |
|
358 mListenSock = NULL; |
|
359 mState = ENone; |
|
360 mAcceptStatus = KErrCancel; |
|
361 if (mAcceptMonitor) |
|
362 mAcceptMonitor->notify(); |
|
363 } |
|
364 } |
|
365 |
|
366 void RFCOMMServerConnection::DoCancel() |
|
367 { |
|
368 JELOG2(EJavaBluetooth); |
|
369 } |
|
370 |
|
371 bool RFCOMMServerConnection::isConnectionAllowed(TBTSockAddr aBtAddr) |
|
372 { |
|
373 JELOG2(EJavaBluetooth); |
|
374 if (NULL == mBtUrlParams) |
|
375 { |
|
376 return true; |
|
377 } |
|
378 |
|
379 bool authorize = false; |
|
380 bool authenticate = false; |
|
381 |
|
382 HBufC* devAddr = HBufC::New(aBtAddr.Length()); |
|
383 TPtr ptr = devAddr->Des(); |
|
384 TBTDevAddr btDeviceAddress = aBtAddr.BTAddr(); |
|
385 btDeviceAddress.GetReadable((TDes&)ptr); |
|
386 if (true == mBtUrlParams->isBlockedSender(*devAddr)) |
|
387 { |
|
388 delete devAddr; |
|
389 return false; |
|
390 } |
|
391 if (true == mBtUrlParams->isAllowedSender(*devAddr, authorize, authenticate)) |
|
392 { |
|
393 LOG(EJavaBluetooth, EInfo, |
|
394 " RFCOMMServerConnection::isConnectionAllowed AllowedSender"); |
|
395 bool flag = true; |
|
396 TInt64 longBtAddr = 0; |
|
397 TLex16 toParse(*devAddr); |
|
398 toParse.Val(longBtAddr, EHex); |
|
399 LOG1(EJavaBluetooth, EInfo, |
|
400 " RFCOMMServerConnection::isConnectionAllowed Long BTRemote address %llx",longBtAddr); |
|
401 if (true == authorize) |
|
402 { |
|
403 flag = BluetoothRemoteDevice::getSecurityProperty( |
|
404 REMOTE_AUTHORIZED, longBtAddr); |
|
405 } |
|
406 if (true == flag && true == authenticate) |
|
407 { |
|
408 flag = BluetoothRemoteDevice::getSecurityProperty( |
|
409 REMOTE_AUTHENTICATED, longBtAddr); |
|
410 } |
|
411 delete devAddr; |
|
412 return flag; |
|
413 } |
|
414 delete devAddr; |
|
415 LOG(EJavaBluetooth, EInfo, "- RFCOMMServerConnection::isConnectionAllowed"); |
|
416 return false; |
|
417 } |
|
418 |
|
419 void RFCOMMServerConnection::avoidFilter() |
|
420 { |
|
421 JELOG2(EJavaBluetooth); |
|
422 mAvoidFilter = true; |
|
423 } |
|
424 //------------------------------------------------------------------------------ |
|
425 // Methods from MBluetoothSocketNotifier to handle Bluetooth Events |
|
426 //------------------------------------------------------------------------------ |
|
427 |
|
428 //Notification of an accept complete event |
|
429 void RFCOMMServerConnection::HandleAcceptCompleteL(TInt err) |
|
430 { |
|
431 TBTSockAddr btRemoteAddr; |
|
432 |
|
433 mAcceptStatus = err; |
|
434 |
|
435 LOG1(EJavaBluetooth, EInfo, "+ RFCOMMServerConnection::HandleAcceptCompleteL Err:%d", err); |
|
436 |
|
437 if (KErrNone == err) |
|
438 { |
|
439 mAcceptedSocket->RemoteName(btRemoteAddr); |
|
440 if (mAsyncAccept && (!mAvoidFilter) && (false == isConnectionAllowed(btRemoteAddr))) |
|
441 { |
|
442 mAcceptedSocket->CancelAll(); |
|
443 mAcceptedSocket->Shutdown(RSocket::EImmediate); |
|
444 delete mAcceptedSocket; |
|
445 mAcceptedSocket = NULL; |
|
446 ELOG(EJavaBluetooth, |
|
447 "RFCOMMServerConnection::HandleAcceptCompleteL Connection Rejected"); |
|
448 AcceptL(); |
|
449 return; |
|
450 } |
|
451 TBuf<20> addr; |
|
452 TInt64 longBtAddr = 0; |
|
453 TBTDevAddr btDeviceAddress = btRemoteAddr.BTAddr(); |
|
454 btDeviceAddress.GetReadable(addr); |
|
455 TLex16 toParse(addr); |
|
456 toParse.Val(longBtAddr, EHex); |
|
457 LOG1(EJavaBluetooth, EInfo, "RFCOMMServerConnection::HandleAcceptCompleteL: Address: %ld", longBtAddr); |
|
458 mBtClientConn = new BluetoothClientConnection(mAcceptedSocket, mServer); |
|
459 mBtClientConn->initialize(PROTOCOL_RFCOMM, longBtAddr, 0, 0); |
|
460 if (mAsyncAccept) |
|
461 { |
|
462 mPushEventListener->handleConnectionRequest(mBtClientConn, err); |
|
463 } |
|
464 else |
|
465 { |
|
466 mAcceptMonitor->notify(); |
|
467 } |
|
468 } |
|
469 else |
|
470 { |
|
471 if (mAsyncAccept) |
|
472 { |
|
473 // If Pushframework cancels the listening then return otherwise |
|
474 // continue listening. |
|
475 if (KErrCancel == err) |
|
476 { |
|
477 mPushEventListener->handleConnectionRequest(NULL, err); |
|
478 } |
|
479 else |
|
480 { |
|
481 ELOG(EJavaBluetooth, |
|
482 " RFCOMMServerConnection::HandleAcceptCompleteL: Error while accept. Listening again."); |
|
483 AcceptL(); |
|
484 } |
|
485 return; |
|
486 } |
|
487 else |
|
488 { |
|
489 mAcceptMonitor->notify(); |
|
490 } |
|
491 } |
|
492 |
|
493 // If connection is accepted, then it should |
|
494 // disable the advertising flag |
|
495 if (NULL != mServRec) |
|
496 { |
|
497 mServRec -> setAdvertiseFs(EFalse); |
|
498 } |
|
499 |
|
500 LOG(EJavaBluetooth, EInfo, "- RFCOMMServerConnection::HandleAcceptCompleteL"); |
|
501 } |
|
502 |
|
503 // Notification of a baseband event |
|
504 void RFCOMMServerConnection::HandleActivateBasebandEventNotifierCompleteL( |
|
505 TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/) |
|
506 { |
|
507 LOG1(EJavaBluetooth,EInfo, |
|
508 "+ RFCOMMServerConnection::HandleActivateBasebandEventNotifierCompleteL %s", |
|
509 "WARNING: Nothing to handle in this event !!"); |
|
510 } |
|
511 |
|
512 //Notification of a connection complete event |
|
513 void RFCOMMServerConnection::HandleConnectCompleteL(TInt /*aErr*/) |
|
514 { |
|
515 LOG1(EJavaBluetooth,EInfo, |
|
516 "+ RFCOMMServerConnection::HandleConnectCompleteL %s", |
|
517 "WARNING: Nothing to handle in this event !!"); |
|
518 } |
|
519 |
|
520 //Notification of a ioctl complete event |
|
521 void RFCOMMServerConnection::HandleIoctlCompleteL(TInt /*aErr*/) |
|
522 { |
|
523 LOG1(EJavaBluetooth,EInfo, |
|
524 "+ RFCOMMServerConnection::HandleIoctlCompleteL %s", |
|
525 "WARNING: Nothing to handle in this event !!"); |
|
526 } |
|
527 |
|
528 //Notification of a receive complete event |
|
529 void RFCOMMServerConnection::HandleReceiveCompleteL(TInt /*aErr*/) |
|
530 { |
|
531 LOG1(EJavaBluetooth,EInfo, |
|
532 "+ RFCOMMServerConnection::HandleReceiveCompleteL %s", |
|
533 "WARNING: Nothing to handle in this event !!"); |
|
534 } |
|
535 |
|
536 //Notification of a send complete event |
|
537 void RFCOMMServerConnection::HandleSendCompleteL(TInt /*aErr*/) |
|
538 { |
|
539 LOG1(EJavaBluetooth,EInfo, |
|
540 "+ RFCOMMServerConnection::HandleSendCompleteL %s", |
|
541 "WARNING: Nothing to handle in this event !!"); |
|
542 } |
|
543 |
|
544 //Notification of a shutdown complete event |
|
545 void RFCOMMServerConnection::HandleShutdownCompleteL(TInt /*aErr*/) |
|
546 { |
|
547 LOG1(EJavaBluetooth,EInfo, |
|
548 "+ RFCOMMServerConnection::HandleShutdownCompleteL %s", |
|
549 "WARNING: Nothing to handle in this event !!"); |
|
550 } |
|
551 |
|
552 } //end namespace bluetooth |
|
553 } //end namespace java |