|
1 /* |
|
2 * Copyright (c) 2005-2006 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: Implementation of Query state. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <AccPolGenericIdDefinitions.h> //device type definitions |
|
21 #include "basrvaccstatequery.h" |
|
22 #include "basrvaccstateconnect.h" |
|
23 #include "basrvaccstatedisconnect.h" |
|
24 #include "basrvaccstateattach.h" |
|
25 #include "basrvaccstateattached.h" |
|
26 #include "debug.h" |
|
27 |
|
28 // ================= MEMBER FUNCTIONS ======================= |
|
29 |
|
30 CBasrvAccStateQuery* CBasrvAccStateQuery::NewL(CBasrvAcc& aParent, TBool aConnectingRequest) |
|
31 { |
|
32 CBasrvAccStateQuery* self=new(ELeave) CBasrvAccStateQuery(aParent, aConnectingRequest); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(); |
|
35 CleanupStack::Pop(self); |
|
36 return self; |
|
37 } |
|
38 |
|
39 CBasrvAccStateQuery::~CBasrvAccStateQuery() |
|
40 { |
|
41 delete iQuery; |
|
42 TRACE_FUNC |
|
43 } |
|
44 |
|
45 void CBasrvAccStateQuery::EnterL() |
|
46 { |
|
47 StatePrint(_L("Query")); |
|
48 // (NOT iConnecting) -> Headset connects to phone, SDP failure is tolerated. |
|
49 iQuery->QueryAccInfoL(AccInfo().iAddr, !iConnecting); |
|
50 Parent().RequestActiveMode(); |
|
51 Parent().PreventLowPowerMode(); |
|
52 } |
|
53 |
|
54 CBasrvAccState* CBasrvAccStateQuery::ErrorOnEntry(TInt aReason) |
|
55 { |
|
56 TRACE_FUNC |
|
57 if (iConnecting) |
|
58 { |
|
59 TRAP_IGNORE(Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, aReason, 0)); |
|
60 } |
|
61 return NULL; |
|
62 } |
|
63 |
|
64 TBTEngConnectionStatus CBasrvAccStateQuery::ConnectionStatus() const |
|
65 { |
|
66 return EBTEngConnecting; |
|
67 } |
|
68 |
|
69 void CBasrvAccStateQuery::CancelConnect() |
|
70 { |
|
71 TRACE_FUNC |
|
72 if (iConnecting) |
|
73 { |
|
74 delete iQuery; |
|
75 iQuery = NULL; |
|
76 TRAP_IGNORE(Parent().ChangeStateL(NULL)); |
|
77 } |
|
78 } |
|
79 |
|
80 void CBasrvAccStateQuery::DisconnectL() |
|
81 { |
|
82 TRACE_FUNC |
|
83 delete iQuery; |
|
84 iQuery = NULL; |
|
85 if (AccInfo().iConnProfiles) |
|
86 { |
|
87 Parent().ChangeStateL(CBasrvAccStateDisconnect::NewL(Parent())); |
|
88 } |
|
89 else |
|
90 { |
|
91 Parent().ChangeStateL(NULL); |
|
92 } |
|
93 } |
|
94 |
|
95 void CBasrvAccStateQuery::AccessoryDisconnectedL(TProfiles aProfile) |
|
96 { |
|
97 TRACE_FUNC |
|
98 ProfileDisconnected(aProfile); |
|
99 AccClosedAudio(aProfile); |
|
100 StatePrint(_L("Query")); |
|
101 if (!AccInfo().iConnProfiles && !iConnecting) |
|
102 { |
|
103 delete iQuery; |
|
104 iQuery = NULL; |
|
105 Parent().ChangeStateL(NULL); |
|
106 } |
|
107 } |
|
108 |
|
109 void CBasrvAccStateQuery::GetAccInfoCompletedL(TInt aErr, const TAccInfo* aAcc, const TBTDeviceClass* aCod) |
|
110 { |
|
111 TRACE_FUNC |
|
112 CBasrvAccState* next = NULL; |
|
113 if ( ( aErr || !aAcc || !(aAcc->iSuppProfiles & EAnyAudioProfiles) ) && |
|
114 ( iConnecting || !(AccInfo().iConnProfiles ) )) |
|
115 { |
|
116 TInt err = (aErr) ? aErr : KErrNotSupported; |
|
117 Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, err, 0); |
|
118 Parent().ChangeStateL(next); |
|
119 return; |
|
120 } |
|
121 |
|
122 if (aAcc) |
|
123 { |
|
124 TInt exist_conns = AccInfo().iConnProfiles; |
|
125 TInt exist_audios = AccInfo().iAudioOpenedProfiles; |
|
126 AccInfo() = *aAcc; |
|
127 AccInfo().iAudioOpenedProfiles = exist_audios; |
|
128 AccInfo().iConnProfiles = exist_conns; |
|
129 AccInfo().iSuppProfiles |= exist_conns; |
|
130 } |
|
131 |
|
132 // Take HFP supported feature from BTMAC if it is not available |
|
133 if ( ( AccInfo().iConnProfiles & EHFP ) && |
|
134 AccInfo().iSupportedFeatures[TAccInfo::EHFPIndex] == 0 ) |
|
135 { |
|
136 CBTAccPlugin* plugin = Parent().AccMan().PluginMan().Plugin(EHFP);; |
|
137 AccInfo().SetSupportedFeature((TUint16)plugin->GetRemoteSupportedFeature(), TAccInfo::EHFPIndex); |
|
138 } |
|
139 |
|
140 // if e.g. A2DP is supported by headset but BTSAC is not in ROM, filter it. |
|
141 Parent().AccMan().FilterProfileSupport(AccInfo()); |
|
142 |
|
143 RArray<TBTDevAddr> conflicts; |
|
144 CleanupClosePushL(conflicts); |
|
145 ResolveConflicts(conflicts); |
|
146 if (conflicts.Count()) |
|
147 { |
|
148 if (iConnecting) |
|
149 { |
|
150 Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, KErrAlreadyExists, 0, &conflicts); |
|
151 } |
|
152 if (AccInfo().iConnProfiles) |
|
153 { |
|
154 next = CBasrvAccStateDisconnect::NewL(Parent()); |
|
155 } |
|
156 } |
|
157 else |
|
158 { |
|
159 // Guess if this is a carkit or headset using the CoD info |
|
160 if (aCod && (aCod->MajorServiceClass() & EMajorServiceAudioService) && |
|
161 (aCod->MajorDeviceClass() & EMajorDeviceAudioDevice )) |
|
162 { |
|
163 if (aCod->MinorDeviceClass() == EMinorDeviceAVHandsfree || |
|
164 aCod->MinorDeviceClass() == EMinorDeviceAVCarAudio) |
|
165 { |
|
166 AccInfo().SetDeviceType(KDTCarKit); |
|
167 TRACE_INFO((_L("Device is a carkit."))); |
|
168 } |
|
169 else |
|
170 { |
|
171 AccInfo().SetDeviceType(KDTHeadset); |
|
172 TRACE_INFO((_L("Device is a headset."))); |
|
173 } |
|
174 } |
|
175 else |
|
176 { |
|
177 AccInfo().SetDeviceType(KDTHeadset); |
|
178 TRACE_INFO((_L("Device is a headset."))); |
|
179 } |
|
180 |
|
181 if (iConnecting) |
|
182 { |
|
183 next = CBasrvAccStateConnect::NewL(Parent()); |
|
184 } |
|
185 else if (AccInfo().iConnProfiles) |
|
186 { |
|
187 next = CBasrvAccStateAttach::NewL(Parent(), iConnecting); |
|
188 } |
|
189 } |
|
190 CleanupStack::PopAndDestroy(&conflicts); |
|
191 Parent().ChangeStateL(next); |
|
192 } |
|
193 |
|
194 CBasrvAccStateQuery::CBasrvAccStateQuery(CBasrvAcc& aParent, TBool aConnectingRequest) |
|
195 : CBasrvAccState(aParent, NULL), iConnecting(aConnectingRequest) |
|
196 { |
|
197 } |
|
198 |
|
199 void CBasrvAccStateQuery::ConstructL() |
|
200 { |
|
201 iQuery = CBasrvSdpQuery::NewL(*this); |
|
202 } |
|
203 |
|
204 void CBasrvAccStateQuery::ResolveConflicts(RArray<TBTDevAddr>& aConflicts) |
|
205 { |
|
206 RPointerArray<const TAccInfo> infos; |
|
207 TInt err = Parent().AccMan().AccInfos(infos); |
|
208 |
|
209 if (err == KErrNone) |
|
210 { |
|
211 TInt supportedByThis = AccInfo().iSuppProfiles; |
|
212 |
|
213 // HFP and HSP are mutual exclusive, i.e. can only have one connected at a time. |
|
214 if (supportedByThis & EAnyMonoAudioProfiles) |
|
215 { |
|
216 supportedByThis |= EAnyMonoAudioProfiles; |
|
217 } |
|
218 |
|
219 for (TInt i = 0; i < infos.Count(); i++) |
|
220 { |
|
221 if ((infos[i]->iAddr != AccInfo().iAddr) && |
|
222 (infos[i]->iSuppProfiles & supportedByThis)) |
|
223 { |
|
224 aConflicts.Append(infos[i]->iAddr); |
|
225 } |
|
226 } |
|
227 |
|
228 infos.Close(); |
|
229 } |
|
230 } |