00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <es_sock.h>
00026 #include <bt_sock.h>
00027 #include <btmanclient.h>
00028
00029 #include "bluetoothcommunicator.h"
00030 #include "cobainserver.h"
00031 #include "serversession.h"
00032 #include "btdiscoverer.h"
00033 #include "concreteconnection.h"
00034 #include "Log.h"
00035
00036 CBTCommunicator::CBTCommunicator(CServerSession *aSession)
00037 : iIsListening(EFalse),
00038 iListeningConnection(NULL),
00039 iListeningSocketType(-1)
00040 {
00041 iServerSession = aSession;
00042 }
00043
00044 CBTCommunicator::~CBTCommunicator()
00045 {
00046 delete iDiscoverer;
00047
00048 if( iIsListening ) {
00049 StopListeningL();
00050
00051
00052 iSdpDB.Close();
00053 iSdpSession.Close();
00054 }
00055
00056
00057 Log::Print(_L("closing socket server.."));
00058 iSocketServ.Close();
00059 }
00060
00061 void CBTCommunicator::ConstructL()
00062 {
00063
00064 iSocketServ.Connect();
00065 }
00066
00067 CBTCommunicator * CBTCommunicator::NewL(CServerSession *aSession)
00068 {
00069 CBTCommunicator *c = new CBTCommunicator(aSession);
00070 CleanupStack::PushL(c);
00071 c->ConstructL();
00072 CleanupStack::Pop();
00073
00074 return c;
00075 }
00076
00077 void CBTCommunicator::DiscoverPeersL(const RMessage &aMessage,
00078 CServerSession &aSession)
00079 {
00080 #ifdef __WINS__
00081
00082
00084
00085
00086 TUint8 btaddr[] = { 0x00, 0x04, 0x61, 0x80, 0x2f, 0xfd };
00087 TBuf8<6> addrbuf;
00088 addrbuf.Copy(btaddr, 6);
00089
00090 TPeerDataList *peers = new (ELeave) TPeerDataList();
00091 TPeerData *data = new TPeerData;
00092 data->iDeviceName = _L("device1");
00093 data->iDeviceAddress = addrbuf;
00094 data->iServiceName = _L("dummy service 1");
00095 data->p.iBtProperties.iL2capPort = 1;
00096 peers->Append(data);
00097 data = new TPeerData;
00098 data->iDeviceName = _L("device2");
00099 data->iDeviceAddress = addrbuf;
00100 data->iServiceName = _L("dummy service 2");
00101 data->p.iBtProperties.iRfcommPort = 3;
00102 peers->Append(data);
00103 TInt size = 2;
00104
00105
00106 aSession.SetPeerList(peers);
00107 TBuf8<sizeof(TInt)> buf;
00108 buf.Copy((const TUint8 *)(&size), sizeof(TInt));
00109 aMessage.WriteL(aMessage.Ptr1(), buf);
00110 aMessage.Complete(KErrNone);
00111 #else
00112
00113
00115
00116 if( iDiscoverer != NULL ) {
00117 delete iDiscoverer;
00118 iDiscoverer = NULL;
00119 }
00120
00121
00122 iDiscoverer = CBTDiscoverer::NewL(aMessage, aSession);
00123 iDiscoverer->StartL(iSocketServ);
00124
00125 #endif
00126 }
00127
00128
00129 RSocket* CBTCommunicator::ConnectL(TPeerData *aPeerData)
00130 {
00131
00132
00133 RSocket *socket = new (ELeave) RSocket();
00134 CleanupStack::PushL(socket);
00135
00136
00137 TBool use_rfcomm = ETrue;
00138 TInt port = aPeerData->p.iBtProperties.iRfcommPort;
00139
00140 if( aPeerData->p.iBtProperties.iL2capPort > 0 ) {
00141 use_rfcomm = EFalse;
00142 port = aPeerData->p.iBtProperties.iL2capPort;
00143 }
00144
00145
00146 __ASSERT_ALWAYS(port > 0, User::Leave(KErrArgument));
00147
00148 if( use_rfcomm ) {
00149
00150 Log::Print(_L("Opening RFCOMM socket"));
00151 User::LeaveIfError(socket->Open(iSocketServ,
00152 KBTAddrFamily,
00153 KSockStream,
00154 KRFCOMM));
00155 } else {
00156
00157 Log::Print(_L("Opening L2CAP socket"));
00158 User::LeaveIfError(socket->Open(iSocketServ,
00159 KBTAddrFamily,
00160 KSockSeqPacket,
00161 KL2CAP));
00162 }
00163
00164
00165 TBTDevAddr devaddr(aPeerData->iDeviceAddress);
00166 TBTSockAddr address;
00167 address.SetBTAddr(devaddr);
00168 address.SetPort(port);
00169
00170
00171 TRequestStatus status;
00172 socket->Connect(address, status);
00173 User::WaitForRequest(status);
00174
00175
00176 User::LeaveIfError(status.Int());
00177
00178 CleanupStack::Pop();
00179
00180 Log::Print(_L("CBTCommunicator::ConnectL() exiting.."));
00181
00182 return socket;
00183 }
00184
00185
00186 void CBTCommunicator::StopListeningL()
00187 {
00188 if( !iIsListening ) {
00189 return;
00190 }
00191
00192
00193 delete iListeningConnection;
00194 iListeningConnection = NULL;
00195
00196
00197 TRAPD(err, iSdpDB.DeleteRecordL(iRecord));
00198 if( err != KErrNone ) {
00199 Log::Print(_L("StopListeningL(): err %d"), err);
00200 }
00201
00202 iRecord = 0;
00203
00204 iIsListening = EFalse;
00205 iListeningSocketType = -1;
00206 }
00207
00208 void CBTCommunicator::StartAdvertisingL(TInt aPort,
00209 const TInt aServiceClassID,
00210 const TInt aApplicationID,
00211 const TDesC8 &aServiceName,
00212 const TDesC8 &aServiceDesc)
00213 {
00214 Log::Print(_L("StartAdvertisingL()"));
00215
00216
00217 User::LeaveIfError(iSdpSession.Connect());
00218 User::LeaveIfError(iSdpDB.Open(iSdpSession));
00219
00220
00221
00222 CSdpAttrValueDES* protocol_descriptor = CSdpAttrValueDES::NewDESL(NULL);
00223 CleanupStack::PushL(protocol_descriptor);
00224
00225 TBuf8<1> channel;
00226 channel.Append((TChar)aPort);
00227
00228 if( iListeningSocketType == KRFCOMM ) {
00229 protocol_descriptor
00230 ->StartListL()
00231 ->BuildDESL()
00232 ->StartListL()
00233 ->BuildUUIDL(aServiceClassID)
00234 ->BuildUUIDL(KL2CAP)
00235 ->BuildUUIDL(KRFCOMM)
00236 ->BuildUintL(channel)
00237 ->EndListL()
00238 ->EndListL();
00239 } else {
00240 protocol_descriptor
00241 ->StartListL()
00242 ->BuildDESL()
00243 ->StartListL()
00244 ->BuildUUIDL(aServiceClassID)
00245 ->BuildUUIDL(KL2CAP)
00246 ->BuildUintL(channel)
00247 ->BuildUUIDL(KRFCOMM)
00248 ->EndListL()
00249 ->EndListL();
00250 }
00251
00252 iSdpDB.CreateServiceRecordL(*protocol_descriptor, iRecord);
00253 iSdpDB.UpdateAttributeL(iRecord,
00254 KSdpAttrIdProtocolDescriptorList,
00255 *protocol_descriptor);
00256
00257 CleanupStack::PopAndDestroy();
00258
00259
00260 iSdpDB.UpdateAttributeL(iRecord,
00261 KSdpAttrIdServiceID,
00262 aApplicationID);
00263
00264
00265 CSdpAttrValueString *service_name =
00266 CSdpAttrValueString::NewStringL(aServiceName);
00267 CleanupStack::PushL(service_name);
00268 iSdpDB.UpdateAttributeL(iRecord,
00269 KSdpAttrIdBasePrimaryLanguage +
00270 KSdpAttrIdOffsetServiceName,
00271 *service_name);
00272 CleanupStack::PopAndDestroy();
00273
00274
00275 CSdpAttrValueString *service_desc =
00276 CSdpAttrValueString::NewStringL(aServiceDesc);
00277 CleanupStack::PushL(service_desc);
00278 iSdpDB.UpdateAttributeL(iRecord,
00279 KSdpAttrIdBasePrimaryLanguage +
00280 KSdpAttrIdOffsetServiceDescription,
00281 *service_desc);
00282 CleanupStack::PopAndDestroy();
00283 }
00284
00285 void CBTCommunicator::SetAvailabilityL(TBool aIsAvailable)
00286 {
00287 TUint state = aIsAvailable ? 0xff : 0x00;
00288
00289
00290 iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceAvailability, state);
00291
00292
00293 iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceRecordState, iRecordVersion++);
00294 }
00295
00296
00297
00298 TInt CBTCommunicator::OpenListeningSocketL()
00299 {
00300 Log::Print(_L("OpenListeningSocketL()"));
00301
00302
00303 iListeningSocket.Close();
00304
00305
00306 delete iListeningConnection;
00307 iListeningConnection = NULL;
00308
00309 TInt port;
00310
00311 if( iListeningSocketType == KRFCOMM ) {
00312
00313 Log::Print(_L("Opening RFCOMM socket"));
00314 User::LeaveIfError(iListeningSocket.Open(iSocketServ,
00315 KBTAddrFamily,
00316 KSockStream,
00317 KRFCOMM));
00318
00319
00320 User::LeaveIfError(
00321 iListeningSocket.GetOpt(KRFCOMMGetAvailableServerChannel,
00322 KSolBtRFCOMM, port)
00323 );
00324
00325 iListeningSocket.SetLocalPort(port);
00326 } else {
00327
00328 Log::Print(_L("Opening L2CAP socket"));
00329 User::LeaveIfError(iListeningSocket.Open(iSocketServ,
00330 KBTAddrFamily,
00331 KSockSeqPacket,
00332 KL2CAP));
00333
00334
00335
00336 TBool is_ok = EFalse;
00337 port = 5;
00338
00339 while( !is_ok ) {
00340
00341 TInt ret = iListeningSocket.SetLocalPort(port);
00342 if( ret == KErrNone ) {
00343
00344 break;
00345 } else if( ret == KErrInUse ) {
00346
00347 port += 2;
00348 } else {
00349
00350
00351 User::Leave(ret);
00352 }
00353 }
00354 }
00355
00356 Log::Print(_L("using port %d"), port);
00357
00358 Log::Print(_L("calling Listen()"));
00359 User::LeaveIfError(iListeningSocket.Listen(KListeningQueueSize));
00360
00361 Log::Print(_L("creating con entity"));
00362
00363
00364 iListeningConnection = CConcreteConnection::NewListeningL(&iListeningSocket,
00365 &iSocketServ,
00366 *iServerSession);
00367
00368 return port;
00369 }
00370
00371 void CBTCommunicator::SetChannelSecurityL(TInt aChannel)
00372 {
00373 RBTMan sec_manager;
00374 RBTSecuritySettings sec_session;
00375
00376
00377 User::LeaveIfError(sec_manager.Connect());
00378 CleanupClosePushL(sec_manager);
00379 User::LeaveIfError(sec_session.Open(sec_manager));
00380 CleanupClosePushL(sec_session);
00381
00382
00383 TBTServiceSecurity sec_settings(KCobainServerUid3, KSolBtRFCOMM, aChannel);
00384
00385 if( iListeningSocketType == KL2CAP ) {
00386 sec_settings.SetProtocolID(KSolBtL2CAP);
00387 }
00388
00389 sec_settings.SetAuthentication(EFalse);
00390 sec_settings.SetEncryption(EFalse);
00391 sec_settings.SetAuthorisation(EFalse);
00392
00393
00394 TRequestStatus status;
00395 sec_session.RegisterService(sec_settings, status);
00396 User::WaitForRequest(status);
00397 User::LeaveIfError(status.Int());
00398
00399
00400 CleanupStack::PopAndDestroy();
00401 CleanupStack::PopAndDestroy();
00402 }
00403
00404
00405 CConcreteConnection* CBTCommunicator::StartListeningL(const TInt aServiceClassID,
00406 const TInt aApplicationID,
00407 const TDesC8 &aServiceName,
00408 const TDesC8 &aServiceDesc,
00409 TInt aListeningSocketType)
00410 {
00411 __ASSERT_ALWAYS(iListeningConnection == NULL,
00412 User::Panic(KBTCommPanic, KErrBTCommAlreadyListening));
00413
00414 Log::Print(_L("StartListeningL()"));
00415
00416
00417 iListeningSocketType = aListeningSocketType;
00418
00419
00420 TInt port = -1;
00421
00422 TRAPD(err, (port = OpenListeningSocketL()));
00423 if( err != KErrNone ) {
00424
00425 User::Panic(KBTCommPanic, KerrBTCommFailedToCreateListeningSocket);
00426 }
00427
00428
00429 SetChannelSecurityL(port);
00430
00431
00432 StartAdvertisingL(port,
00433 aServiceClassID,
00434 aApplicationID,
00435 aServiceName,
00436 aServiceDesc);
00437
00438
00439 SetAvailabilityL(ETrue);
00440
00441 iIsListening = ETrue;
00442
00443 return iListeningConnection;
00444 }
00445
00446 TInt CBTCommunicator::ResolveMTU(RSocket& aSocket)
00447 {
00448 TInt mtu = 0;
00449 TInt rc = KErrNone;
00450
00451
00452 rc = aSocket.GetOpt(KL2CAPGetOutboundMTU,
00453 KSolBtL2CAP, mtu);
00454 if (rc != KErrNone) {
00455
00456
00457 mtu = 48;
00458 }
00459 return mtu;
00460 }
00461
00462