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
00028 #include "bluetoothcommunicator.h"
00029 #include "btdiscoverer.h"
00030 #include "cobainserver.h"
00031 #include "serversession.h"
00032 #include "Log.h"
00033
00034 CBTDiscoverer::CBTDiscoverer(RMessage &aMessage, CServerSession &aSession)
00035 : CActive(CActive::EPriorityStandard),
00036 iMessage(aMessage),
00037 iSession(aSession),
00038 iCurrentDeviceIndex(-1)
00039 {
00040 }
00041
00042 CBTDiscoverer::~CBTDiscoverer()
00043 {
00044 iDeviceAddresses.ResetAndDestroy();
00045 delete iSdpPattern;
00046 delete iAgent;
00047 delete iAttrMatchList;
00048 }
00049
00050 CBTDiscoverer * CBTDiscoverer::NewL(RMessage &aMessage, CServerSession &aSession)
00051 {
00052 CBTDiscoverer *d = new (ELeave) CBTDiscoverer(aMessage, aSession);
00053 CleanupStack::PushL(d);
00054 d->ConstructL();
00055 CleanupStack::Pop();
00056
00057 return d;
00058 }
00059
00060 void CBTDiscoverer::ConstructL()
00061 {
00062
00063 delete iSdpPattern;
00064 iSdpPattern = NULL;
00065 iSdpPattern = CSdpSearchPattern::NewL();
00066
00067
00068 iAttrMatchList = CSdpAttrIdMatchList::NewL();
00069 iAttrMatchList->AddL(TAttrRange(KSdpAttrIdProtocolDescriptorList));
00070 TSdpAttributeID attr_id = KSdpAttrIdOffsetServiceName +
00071 KSdpAttrIdBasePrimaryLanguage;
00072 iAttrMatchList->AddL(TAttrRange(attr_id));
00073
00074
00075
00076 TUint service_id = iMessage.Int2();
00077 if( service_id != 0 ) {
00078
00079 iSdpPattern->AddL(service_id);
00080 Log::Print(_L("CBTDiscoverer::ConstructL() id: 0x%X"), service_id);
00081 } else {
00082
00083 iSdpPattern->AddL(KL2CAP);
00084 iSdpPattern->AddL(KRFCOMM);
00085 Log::Print(_L("CBTDiscoverer::ConstructL() looking up all"));
00086 }
00087 }
00088
00089 void CBTDiscoverer::DoCancel()
00090 {
00091
00092 iHr.Close();
00093
00094 delete iPeerList;
00095 iPeerList = NULL;
00096 }
00097
00098 void CBTDiscoverer::StartL(RSocketServ &aSocketServ)
00099 {
00100 Log::Print(_L("CBTDiscoverer::StartL()"));
00101
00102
00103 delete iPeerList;
00104 iPeerList = NULL;
00105 iPeerList = new (ELeave) TPeerDataList();
00106
00107 TProtocolDesc pInfo;
00108 User::LeaveIfError(aSocketServ.FindProtocol(_L("BTLinkManager"), pInfo));
00109
00110
00111 User::LeaveIfError(iHr.Open(aSocketServ, pInfo.iAddrFamily, pInfo.iProtocol));
00112
00113
00114 TInquirySockAddr addr;
00115 TNameEntry name;
00116 addr.SetIAC(KGIAC);
00117 addr.SetAction(KHostResName | KHostResInquiry);
00118
00119
00120 CActiveScheduler::Add(this);
00121
00122
00123 TRequestStatus status;
00124 iHr.GetByAddress(addr, iNameEntry, iStatus);
00125
00126
00127 SetActive();
00128 }
00129
00130 void CBTDiscoverer::DiscoverServices(TNameRecord &aNameRecord)
00131 {
00132 delete iAgent;
00133 iAgent = NULL;
00134
00135 Log::Print(_L("DiscoverServices(): %S"), &(aNameRecord.iName));
00136
00137
00138 TBTDevAddr btaddr = static_cast<TBTSockAddr>(aNameRecord.iAddr).BTAddr();
00139
00140 TRAPD(err, (iAgent = CSdpAgent::NewL(*this, btaddr)));
00141 if( err != KErrNone ) {
00142 User::Panic(KBTDiscovererPanic, KErrBtdiscovererAllocFailed);
00143 }
00144
00145 iAgent->SetRecordFilterL(*iSdpPattern);
00146 iAgent->NextRecordRequestL();
00147 }
00148
00149
00150 void CBTDiscoverer::FinishDiscovery()
00151 {
00152 Log::Print(_L("FinishDiscovery()"));
00153
00154 iCurrentDeviceIndex = -1;
00155
00156
00157 iSession.SetPeerList(iPeerList);
00158 iPeerList = NULL;
00159
00160
00161 TBuf8<sizeof(TInt)> buf;
00162 buf.Copy((const TUint8 *)(&iNumPeers), sizeof(TInt));
00163 iMessage.WriteL(iMessage.Ptr1(), buf);
00164
00165 iMessage.Complete(KErrNone);
00166
00167
00168 iDeviceAddresses.ResetAndDestroy();
00169 }
00170
00171 void CBTDiscoverer::DeviceDiscovered()
00172 {
00173 if( iStatus == KErrNone ) {
00174 TNameRecord record = iNameEntry();
00175
00176
00177
00178
00179 TNameRecord *new_record = NULL;
00180 TRAPD(err, (new_record = new (ELeave) TNameRecord()));
00181 if( err != KErrNone ) {
00182 User::Panic(KBTDiscovererPanic, KErrBtdiscovererAllocFailed);
00183 }
00184
00185
00186 Mem::Copy(new_record, &record, sizeof(TNameRecord));
00187
00188
00189 iDeviceAddresses.Append(new_record);
00190
00191
00192 iHr.Next(iNameEntry, iStatus);
00193 SetActive();
00194 } else {
00195 Log::Print(_L("** no more devices"));
00196
00197
00198 iHr.Close();
00199
00200
00201 if( iDeviceAddresses.Count() > 0 ) {
00202
00203 iCurrentDeviceIndex = 0;
00204 DiscoverServices(*iDeviceAddresses[iCurrentDeviceIndex]);
00205 } else {
00206
00207 FinishDiscovery();
00208 }
00209 }
00210 }
00211
00212 void CBTDiscoverer::RunL()
00213 {
00214
00215
00216 DeviceDiscovered();
00217 }
00218
00219 TInt CBTDiscoverer::RunError(TInt aError)
00220 {
00221
00222
00223 return aError;
00224 }
00225
00227
00229
00230 void CBTDiscoverer::AttributeRequestComplete(TSdpServRecordHandle ,
00231 TInt aError)
00232 {
00233
00234
00235 if( aError != KErrNone ) {
00236
00237
00238 } else {
00239
00240 TNameRecord *record = iDeviceAddresses[iCurrentDeviceIndex];
00241 TBTDevAddr btaddr = static_cast<TBTSockAddr>(record->iAddr).BTAddr();
00242 TPeerData *data = new (ELeave) TPeerData();
00243 data->iDeviceName = record->iName;
00244 data->iDeviceAddress = btaddr.Des();
00245 data->iServiceName = iServiceName;
00246 data->p.iBtProperties.iRfcommPort = iRfcommPort;
00247 data->p.iBtProperties.iL2capPort = iL2capPort;
00248 iPeerList->Append(data);
00249 iNumPeers++;
00250
00251 Log::Print(_L("added peer: L: %d, R: %d"), iL2capPort, iRfcommPort);
00252
00253
00254
00255 TRAPD(err, iAgent->NextRecordRequestL());
00256 if( err != KErrNone ) {
00257
00258
00259 }
00260 }
00261 }
00262
00263 void CBTDiscoverer::AttributeRequestResult(TSdpServRecordHandle ,
00264 TSdpAttributeID ,
00265 CSdpAttrValue* aAttrValue)
00266 {
00267
00268
00269
00270
00271 TRAPD(err, aAttrValue->AcceptVisitorL(*this));
00272 }
00273
00274
00275 void CBTDiscoverer::NextRecordRequestComplete(TInt aError,
00276 TSdpServRecordHandle aHandle,
00277 TInt aTotalRecordsCount)
00278 {
00279 TInt err;
00280 Log::Print(_L("NRRC(): error: %d, count: %d, handle: %d"),
00281 aError, aTotalRecordsCount, aHandle);
00282
00283 if( (aError == KErrNone) && (aTotalRecordsCount > 0) ) {
00284
00285 iRfcommPort = -1;
00286 iL2capPort = -1;
00287 iServiceName.Zero();
00288 iLastUuid32 = 0;
00289
00290
00291
00292
00293 TRAP(err, iAgent->AttributeRequestL(aHandle, *iAttrMatchList));
00294 } else {
00295
00296 iCurrentDeviceIndex++;
00297
00298 if( iCurrentDeviceIndex < iDeviceAddresses.Count() ) {
00299 DiscoverServices(*iDeviceAddresses[iCurrentDeviceIndex]);
00300 } else {
00301
00302 FinishDiscovery();
00303 }
00304 }
00305 }
00306
00308
00310
00311 void CBTDiscoverer::VisitAttributeValueL(CSdpAttrValue &aValue,
00312 TSdpElementType aType)
00313 {
00314 TBuf<64> bufw;
00315 TInt index;
00316
00317 if( aType != ETypeUint ) {
00318
00319 iLastUuid32 = 0;
00320 }
00321
00322 switch( aType ) {
00323 case ETypeUUID:
00324 ParseUuid(bufw, aValue.UUID(), iLastUuid32);
00325 Log::Print(_L("UUID: %S"), &bufw);
00326
00327 break;
00328 case ETypeUint:
00329 Log::Print(_L("Uint: %u"), aValue.Uint());
00330 if( iLastUuid32 == KRFCOMM ) {
00331 iRfcommPort = aValue.Uint();
00332 } else if( iLastUuid32 == KL2CAP ) {
00333 iL2capPort = aValue.Uint();
00334 }
00335 break;
00336 case ETypeDES:
00337
00338 break;
00339 case ETypeNil:
00340 Log::Print(_L("Nil"));
00341 break;
00342 case ETypeInt:
00343 Log::Print(_L("Int: %d"), aValue.Int());
00344 break;
00345 case ETypeString:
00346
00347 iServiceName.Copy(aValue.Des());
00348 bufw.Copy(aValue.Des());
00349
00350
00351 index = iServiceName.Locate(0x00);
00352 if( index != KErrNotFound ) {
00353 iServiceName.SetLength(index);
00354 }
00355
00356
00357
00358 Log::Print(_L("String: %S"), &bufw);
00359 break;
00360 case ETypeBoolean:
00361 Log::Print(_L("Boolean"));
00362 break;
00363 case ETypeDEA:
00364 Log::Print(_L("DEA"));
00365 break;
00366 case ETypeURL:
00367 Log::Print(_L("URL"));
00368 break;
00369 case ETypeEncoded:
00370 Log::Print(_L("Encoded"));
00371 break;
00372 default:
00373
00374 break;
00375 }
00376 }
00377
00378 void CBTDiscoverer::StartListL(CSdpAttrValueList& )
00379 {
00380
00381 }
00382
00383 void CBTDiscoverer::EndListL()
00384 {
00385
00386 }
00387
00388
00389 void CBTDiscoverer::ParseUuid(TDes &aBuf, const TUUID &aUuid, TUint32 &aUuid32)
00390 {
00391 TPtrC8 uuid(aUuid.ShortestForm());
00392 TInt len = uuid.Length();
00393
00394
00395
00396 switch( len ) {
00397 case 2:
00398 aUuid32 = (TUint)BigEndian::Get16(uuid.Ptr());
00399 aBuf.Format(_L("0x%X"), aUuid32);
00400 break;
00401 case 4:
00402 aUuid32 = BigEndian::Get32(uuid.Ptr());
00403 aBuf.Format(_L("0x%X"), aUuid32);
00404 break;
00405 case 16:
00406 aUuid32 = 0;
00407
00408 break;
00409 }
00410 }