|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // btgpsdiscovery implementation |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file btgpsdiscovery.cpp |
|
20 @internal technology |
|
21 */ |
|
22 |
|
23 #include "btgpsdiscovery.h" |
|
24 #include "btgpssimstubs.h" |
|
25 |
|
26 |
|
27 CBTGPSDiscovery::CBTGPSDiscovery (MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) |
|
28 { |
|
29 iBTSdpResultReceiver = aBTEngSdpResultReceiver; |
|
30 iChannel = 0; |
|
31 iValid = EFalse; |
|
32 } |
|
33 |
|
34 CBTGPSDiscovery* CBTGPSDiscovery::NewLC (MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) |
|
35 { |
|
36 CBTGPSDiscovery* self = new ( ELeave ) CBTGPSDiscovery(aBTEngSdpResultReceiver); |
|
37 CleanupStack::PushL (self); |
|
38 return self; |
|
39 } |
|
40 |
|
41 CBTGPSDiscovery* CBTGPSDiscovery::NewL(MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) |
|
42 { |
|
43 CBTGPSDiscovery* self = CBTGPSDiscovery::NewLC (aBTEngSdpResultReceiver); |
|
44 CleanupStack::Pop (self); |
|
45 return self; |
|
46 } |
|
47 |
|
48 CBTGPSDiscovery::~CBTGPSDiscovery () |
|
49 { |
|
50 delete iSdpAgent; |
|
51 #ifdef LBS_BTGPSPSY_SIM |
|
52 delete iSdpAgentSim; |
|
53 #endif |
|
54 } |
|
55 |
|
56 /** |
|
57 * Starts an SDP query. The remote SDP database is searched for the value |
|
58 * of the ProtocolDescriptorList attribute in a service record containing |
|
59 * the specified UUID, the equivalent of an SDP ServiceAttributeSearch |
|
60 * transaction with ProtocolDescriptorList as attribute. This can e.g. be |
|
61 * used to search the remote RFCOMM channel. When completed, the results |
|
62 * are passed back to the client through the callback interface method |
|
63 * MBTEngSdpResultReceiver::AttributeSearchComplete(). |
|
64 * @param aAddr Target Bluetooth device address for the SDP query. |
|
65 * @param aService The UUID to search for. |
|
66 * @return KErrNone if successful, otherwise the error code indicating the error situation. |
|
67 */ |
|
68 TInt CBTGPSDiscovery::RemoteProtocolChannelQueryL(const TBTDevAddr& aAddr, TInt aService) |
|
69 { |
|
70 if(iSdpAgent) |
|
71 { |
|
72 return KErrInUse; |
|
73 } |
|
74 |
|
75 #ifdef LBS_BTGPSPSY_SIM |
|
76 // See if the device is simulated, in which case use the simulated SdpAgent. |
|
77 // otherwise use the regular one. |
|
78 iSdpAgentSim = CSdpAgentSim::NewL(*this); |
|
79 if (iSdpAgentSim->GetChannelStart(aAddr, iChannel) != KErrNone) |
|
80 #endif |
|
81 { |
|
82 CSdpAgent* sdpAgent = CSdpAgent::NewL(*this, aAddr); |
|
83 CleanupStack::PushL(sdpAgent); |
|
84 |
|
85 // create the attribute ID list to match against |
|
86 CSdpSearchPattern* searchPattern = CSdpSearchPattern::NewL(); |
|
87 CleanupStack::PushL(searchPattern); |
|
88 |
|
89 // search for BNEP, as it's the common field in all PAN records |
|
90 searchPattern->AddL(aService); |
|
91 |
|
92 // Set Record Filter copies searchPattern |
|
93 sdpAgent->SetRecordFilterL(*searchPattern); |
|
94 CleanupStack::PopAndDestroy(searchPattern); |
|
95 |
|
96 sdpAgent->NextRecordRequestL(); |
|
97 |
|
98 // Now we have successfully issued the request we know that it will later be |
|
99 // completed, so we can keep sdpAgent and it will be deleted on request |
|
100 // completion. |
|
101 CleanupStack::Pop(sdpAgent); |
|
102 iSdpAgent = sdpAgent; |
|
103 } |
|
104 |
|
105 return KErrNone; |
|
106 } |
|
107 |
|
108 /** |
|
109 * This function to return the protocol channel number from the |
|
110 * result array of a ServiceAttributeSearch. This value can be used to |
|
111 * obtain e.g. the remote RFCOMM channel after a RemoteProtocolChannelQueryL |
|
112 * has completed. |
|
113 * @param aResultArray The array containing the SDP attribute. |
|
114 * @param aType On return, contains the channel number. |
|
115 * @return KerrNone if successful, KerrArgument if the SDP attribute is not |
|
116 * of type ProtocolDescriptorLis |
|
117 */ |
|
118 TInt CBTGPSDiscovery::ParseRfcommChannel(TInt& aType) |
|
119 { |
|
120 aType = iChannel; |
|
121 return KErrNone; |
|
122 } |
|
123 |
|
124 /** Called when an service record request (CSdpAgent::NextRecordRequestComplete()) |
|
125 operation completes. |
|
126 |
|
127 @param aError KErrNone if successful; |
|
128 KErrEof if there are no more SDP records left to be read; or an SDP error. |
|
129 @param aHandle Service record for which the query was made |
|
130 @param aTotalRecordsCount Total number of matching records |
|
131 @see CSdpAgent::NextRecordRequestL() */ |
|
132 void CBTGPSDiscovery::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/) |
|
133 { |
|
134 TInt err = aError; |
|
135 |
|
136 if(err == KErrNone) //more results available |
|
137 { |
|
138 iMatchesFound = ETrue; |
|
139 // Check the attributes of the returned record to see if it's a U, GN, or NAP record |
|
140 TRAP(err,iSdpAgent->AttributeRequestL(aHandle, KSdpAttrIdProtocolDescriptorList)); |
|
141 |
|
142 if(err == KErrNone) |
|
143 { |
|
144 return; |
|
145 } |
|
146 } |
|
147 |
|
148 //Request has completed or error has occured |
|
149 if(err != KErrEof) |
|
150 { |
|
151 // A 'real' error has occured, cancel the query |
|
152 if(iSdpAgent) |
|
153 { |
|
154 iSdpAgent->Cancel(); |
|
155 } |
|
156 iBTSdpResultReceiver->ServiceAttributeSearchComplete(err); |
|
157 } |
|
158 else |
|
159 { |
|
160 iBTSdpResultReceiver->ServiceAttributeSearchComplete(KErrEof); |
|
161 } |
|
162 } |
|
163 |
|
164 /** Called when an attribute request (CSdpAgent::AttributeRequestL()) wants to |
|
165 pass up a result. |
|
166 |
|
167 @param aHandle Service record for which the query was made |
|
168 @param aAttrID ID of the attribute obtained |
|
169 @param aAttrValue Attribute value obtained |
|
170 @see CSdpAgent::AttributeRequestL() */ |
|
171 void CBTGPSDiscovery::AttributeRequestResult(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue) |
|
172 { |
|
173 if((aAttrID == KSdpAttrIdProtocolDescriptorList) && (aAttrValue->Type()==ETypeDES)) |
|
174 { |
|
175 CSdpAttrValueDES* sdpProfileDesList = static_cast<CSdpAttrValueDES*>(aAttrValue); |
|
176 // cycle through the contents of the DES to find the remote role |
|
177 TRAPD(err, sdpProfileDesList->AcceptVisitorL(*this)); |
|
178 if(KErrNone == err) |
|
179 { |
|
180 // Delete the attribute value now that we've finished with it |
|
181 delete aAttrValue; |
|
182 // there shouldn't be another profile descriptor list, so we should now get AttributeRequestComplete() called |
|
183 } |
|
184 } |
|
185 } |
|
186 |
|
187 /** Called when an attribute request (CSdpAgent::AttributeRequestL()) wants to |
|
188 signal the completion of a attribute request. |
|
189 |
|
190 @param aHandle Service record for which the query was made |
|
191 @param aError an error |
|
192 @see CSdpAgent::AttributeRequestL() */ |
|
193 void CBTGPSDiscovery::AttributeRequestComplete(TSdpServRecordHandle /*aHandle*/, TInt /*aError*/) |
|
194 { |
|
195 // examine the next record returned |
|
196 TRAP_IGNORE(iSdpAgent->NextRecordRequestL()); |
|
197 } |
|
198 |
|
199 void CBTGPSDiscovery::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType) |
|
200 { |
|
201 if(iValid) |
|
202 { |
|
203 if(aType==ETypeUint) |
|
204 { |
|
205 iChannel = aValue.Uint(); |
|
206 iBTSdpResultReceiver->ServiceAttributeSearchComplete( KErrNone); |
|
207 } |
|
208 iValid = EFalse; |
|
209 } |
|
210 |
|
211 if(aType==ETypeUUID) |
|
212 { |
|
213 if(aValue.UUID() == KRFCommUUID) |
|
214 { |
|
215 iValid = ETrue; |
|
216 } |
|
217 } |
|
218 } |