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 {
00040 iServerSession = aSession;
00041 }
00042
00043 CBTCommunicator::~CBTCommunicator()
00044 {
00045 delete iDiscoverer;
00046
00047 if( iIsListening ) {
00048 StopListeningL();
00049
00050
00051 iSdpDB.Close();
00052 iSdpSession.Close();
00053 }
00054
00055
00056 Log::Print(_L("closing socket server.."));
00057 iSocketServ.Close();
00058 }
00059
00060 void CBTCommunicator::ConstructL()
00061 {
00062
00063 iSocketServ.Connect();
00064 }
00065
00066 CBTCommunicator * CBTCommunicator::NewL(CServerSession *aSession)
00067 {
00068 CBTCommunicator *c = new CBTCommunicator(aSession);
00069 CleanupStack::PushL(c);
00070 c->ConstructL();
00071 CleanupStack::Pop();
00072
00073 return c;
00074 }
00075
00076 void CBTCommunicator::DiscoverPeersL(const RMessage &aMessage,
00077 CServerSession &aSession)
00078 {
00079 #ifdef __WINS__
00080
00081
00083
00084
00085 TUint8 btaddr[] = { 0x00, 0x04, 0x61, 0x80, 0x2f, 0xfd };
00086 TBuf8<6> addrbuf;
00087 addrbuf.Copy(btaddr, 6);
00088 TUint8 sid[] = { 0x01, 0x02, 0x03, 0x04 };
00089
00090 TPeerDataList *peers = new (ELeave) TPeerDataList();
00091 TPeerData *data = new TPeerData;
00092 data->iDeviceName = _L("device1");
00093 data->iDeviceAddress = addrbuf;
00094 data->iServiceID.Copy(sid, 4);
00095 data->iPort = 1;
00096 peers->Append(data);
00097 data = new TPeerData;
00098 data->iDeviceName = _L("device2");
00099 data->iDeviceAddress = addrbuf;
00100 data->iServiceID.Copy(sid, 4);
00101 data->iPort = 2;
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
00138
00139
00140
00141
00142
00143 User::LeaveIfError(socket->Open(iSocketServ,
00144 KBTAddrFamily,
00145 KSockSeqPacket,
00146 KL2CAP));
00147
00148
00149
00150
00151 TBTDevAddr devaddr(aPeerData->iDeviceAddress);
00152 TBTSockAddr address;
00153 address.SetBTAddr(devaddr);
00154 address.SetPort(aPeerData->iPort);
00155
00156
00157
00158
00159 TRequestStatus status;
00160 socket->Connect(address, status);
00161 User::WaitForRequest(status);
00162
00163 User::LeaveIfError(status.Int());
00164
00165 CleanupStack::Pop();
00166
00167
00168
00169 return socket;
00170 }
00171
00172
00173 void CBTCommunicator::StopListeningL()
00174 {
00175 if( !iIsListening ) {
00176 return;
00177 }
00178
00179
00180 delete iListeningConnection;
00181 iListeningConnection = NULL;
00182
00183
00184 TRAPD(err, iSdpDB.DeleteRecordL(iRecord));
00185 if( err != KErrNone ) {
00186 Log::Print(_L("StopListeningL(): err %d"), err);
00187 }
00188
00189 iRecord = 0;
00190
00191 iIsListening = EFalse;
00192 }
00193
00194 void CBTCommunicator::StartAdvertisingL(TInt aPort,
00195 const TInt aServiceClassID,
00196 const TInt aApplicationID,
00197 const TDesC8 &aServiceName,
00198 const TDesC8 &aServiceDesc)
00199 {
00200
00201
00202
00203 User::LeaveIfError(iSdpSession.Connect());
00204 User::LeaveIfError(iSdpDB.Open(iSdpSession));
00205
00206
00207 iSdpDB.CreateServiceRecordL(aServiceClassID, iRecord);
00208
00209
00210
00211 CSdpAttrValueDES* protocolDescriptorList = CSdpAttrValueDES::NewDESL(NULL);
00212 CleanupStack::PushL(protocolDescriptorList);
00213
00214 TBuf8<1> channel;
00215 channel.Append((TChar)aPort);
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 protocolDescriptorList
00232 ->StartListL()
00233 ->BuildDESL()
00234 ->StartListL()
00235 ->BuildUUIDL(KL2CAP)
00236 ->BuildUintL(channel)
00237 ->EndListL()
00238 ->EndListL();
00239
00240 iSdpDB.UpdateAttributeL(iRecord,
00241 KSdpAttrIdProtocolDescriptorList,
00242 *protocolDescriptorList);
00243
00244 CleanupStack::PopAndDestroy();
00245
00246
00247 iSdpDB.UpdateAttributeL(iRecord,
00248 KSdpAttrIdServiceID,
00249 aApplicationID);
00250
00251
00252 CSdpAttrValueString *service_name =
00253 CSdpAttrValueString::NewStringL(aServiceName);
00254 CleanupStack::PushL(service_name);
00255 iSdpDB.UpdateAttributeL(iRecord,
00256 KSdpAttrIdBasePrimaryLanguage +
00257 KSdpAttrIdOffsetServiceName,
00258 *service_name);
00259 CleanupStack::PopAndDestroy();
00260
00261
00262 CSdpAttrValueString *service_desc =
00263 CSdpAttrValueString::NewStringL(aServiceDesc);
00264 CleanupStack::PushL(service_desc);
00265 iSdpDB.UpdateAttributeL(iRecord,
00266 KSdpAttrIdBasePrimaryLanguage +
00267 KSdpAttrIdOffsetServiceDescription,
00268 *service_desc);
00269 CleanupStack::PopAndDestroy();
00270 }
00271
00272
00273 void CBTCommunicator::SetAvailabilityL(TBool aIsAvailable)
00274 {
00275 TUint state = aIsAvailable ? 0xff : 0x00;
00276
00277
00278 iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceAvailability, state);
00279
00280
00281 iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceRecordState, iRecordVersion++);
00282 }
00283
00284
00285
00286 TInt CBTCommunicator::OpenListeningSocketL()
00287 {
00288 Log::Print(_L("OpenListeningSocketL()"));
00289
00290
00291
00292
00293 iListeningSocket.Close();
00294
00295
00296
00297
00298 delete iListeningConnection;
00299 iListeningConnection = NULL;
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 User::LeaveIfError(iListeningSocket.Open(iSocketServ,
00311 KBTAddrFamily,
00312 KSockSeqPacket,
00313 KL2CAP));
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 TInt port = 1;
00328
00329
00330
00331
00332
00333
00334
00335
00336 TBool is_ok = EFalse;
00337
00338 while( !is_ok ) {
00339
00340 TInt ret = iListeningSocket.SetLocalPort(port);
00341 if( ret == KErrNone ) {
00342
00343 break;
00344 } else if( ret == KErrInUse ) {
00345
00346 port += 2;
00347 } else {
00348
00349
00350 User::Leave(ret);
00351 }
00352 }
00353
00354
00355
00356
00357
00358 User::LeaveIfError(iListeningSocket.Listen(KListeningQueueSize));
00359
00360
00361
00362
00363 iListeningConnection = CConcreteConnection::NewListeningL(&iListeningSocket,
00364 &iSocketServ,
00365 *iServerSession);
00366
00367 return port;
00368 }
00369
00370 void CBTCommunicator::SetChannelSecurityL(TInt aChannel)
00371 {
00372 RBTMan sec_manager;
00373 RBTSecuritySettings sec_session;
00374
00375
00376
00377
00378 User::LeaveIfError(sec_manager.Connect());
00379 CleanupClosePushL(sec_manager);
00380 User::LeaveIfError(sec_session.Open(sec_manager));
00381 CleanupClosePushL(sec_session);
00382
00383
00384
00385 TBTServiceSecurity sec_settings(KCobainServerUid3, KSolBtL2CAP, 0);
00386 sec_settings.SetAuthentication(EFalse);
00387 sec_settings.SetEncryption(EFalse);
00388 sec_settings.SetAuthorisation(EFalse);
00389
00390
00391 sec_settings.SetChannelID(aChannel);
00392 TRequestStatus status;
00393 sec_session.RegisterService(sec_settings, status);
00394 User::WaitForRequest(status);
00395 User::LeaveIfError(status.Int());
00396
00397
00398 CleanupStack::PopAndDestroy();
00399 CleanupStack::PopAndDestroy();
00400 }
00401
00402
00403 CConcreteConnection* CBTCommunicator::StartListeningL(const TInt aServiceClassID,
00404 const TInt aApplicationID,
00405 const TDesC8 &aServiceName,
00406 const TDesC8 &aServiceDesc)
00407 {
00408 __ASSERT_ALWAYS(iListeningConnection == NULL,
00409 User::Panic(KBTCommPanic, KErrBTCommAlreadyListening));
00410
00411
00412
00413
00414 TInt port = -1;
00415
00416 TRAPD(err, (port = OpenListeningSocketL()));
00417 if( err != KErrNone ) {
00418
00419 User::Panic(KBTCommPanic, KerrBTCommFailedToCreateListeningSocket);
00420 }
00421
00422
00423 SetChannelSecurityL(port);
00424
00425
00426 StartAdvertisingL(port,
00427 aServiceClassID,
00428 aApplicationID,
00429 aServiceName,
00430 aServiceDesc);
00431
00432
00433 SetAvailabilityL(ETrue);
00434
00435 iIsListening = ETrue;
00436
00437 return iListeningConnection;
00438 }
00439
00440
00441
00442