|
1 // Copyright (c) 2007-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 // SIP Connection Provider States/Transitions |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 |
|
24 #include "sipcprstates.h" |
|
25 #include <comms-infras/ss_subconnprov.h> |
|
26 #include <elements/nm_messages_base.h> |
|
27 #include <comms-infras/ss_nodemessages_dataclient.h> |
|
28 #include <comms-infras/ss_nodemessages_factory.h> |
|
29 |
|
30 using namespace SipCpr; |
|
31 using namespace SipCprStates; |
|
32 using namespace ESock; |
|
33 using namespace NetStateMachine; |
|
34 |
|
35 |
|
36 namespace SipCprStates |
|
37 { |
|
38 |
|
39 //======================================================================================================================= |
|
40 // |
|
41 // BinderRequest Activity |
|
42 // |
|
43 //========================================================================================================================== |
|
44 DEFINE_SMELEMENT(TIntializeWaitForIncmgParams, NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
45 void TIntializeWaitForIncmgParams::DoL() |
|
46 { |
|
47 TCFServiceProvider::TCommsBinderRequest* binderReq = Messages::message_cast<TCFServiceProvider::TCommsBinderRequest>(&iContext.iMessage); |
|
48 if (binderReq) |
|
49 { |
|
50 TSubConnOpen::TSubConnType subconType = (TSubConnOpen::TSubConnType)binderReq->iValue; |
|
51 iContext.Node().iSubconType = subconType; |
|
52 if (subconType == RSubConnection::EWaitIncoming) |
|
53 { |
|
54 iContext.Node().iConnStatus = SipCpr::EConnIncoming ; |
|
55 } |
|
56 else |
|
57 { |
|
58 iContext.Node().iConnStatus = SipCpr::EConnOutgoing ; |
|
59 } |
|
60 } |
|
61 } |
|
62 |
|
63 |
|
64 //===================================================== |
|
65 // |
|
66 // Provision Activity |
|
67 // |
|
68 //============================================================= |
|
69 DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
70 void TStoreProvision::DoL() |
|
71 { |
|
72 __CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("AStoreProvision::DoL()"))); |
|
73 PRStates::TStoreProvision storeProvision(iContext); |
|
74 storeProvision.DoL(); |
|
75 |
|
76 //Retrieve profileId, appUid and ptr to TransitionEngineMgr; |
|
77 |
|
78 const TSipMcprProvisionInfo* ext = static_cast<const TSipMcprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipMcprProvisionInfo::EUid, TSipMcprProvisionInfo::ETypeId))); |
|
79 if (ext) |
|
80 { |
|
81 iContext.Node().iProfileId = ext->iProfileId; |
|
82 iContext.Node().iAppUid = ext->iAppUid; |
|
83 iContext.Node().iTransitionEngineMgr = ext->iTransitionEngineMgr; |
|
84 // Create the transition engine here so that it can be sent in |
|
85 // send provision to SCPR |
|
86 |
|
87 CTransitionEngineMgr* mgr = iContext.Node().iTransitionEngineMgr; |
|
88 TUint32 profileId = iContext.Node().iProfileId; |
|
89 TUid appUid = iContext.Node().GetAppUid(); |
|
90 CSIPTransitionEngine* transitionEngine = NULL; |
|
91 TInt err; |
|
92 TRAP(err, transitionEngine = mgr->FindOrCreateL(appUid, profileId)); |
|
93 if(KErrNone != err) |
|
94 { |
|
95 __CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Error [%d] while executing CTransitionEngineMgr::FindOrCreate"))); |
|
96 User::Leave(err); |
|
97 } |
|
98 else |
|
99 { |
|
100 __CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Transition Engine has created"))); |
|
101 iContext.Node().iTransitionEngine = transitionEngine; |
|
102 if (profileId == KSIPDefaultProfileId) |
|
103 { |
|
104 profileId = mgr->DefaultProfileId(); |
|
105 } |
|
106 } |
|
107 } |
|
108 } |
|
109 |
|
110 DEFINE_SMELEMENT(TSendProvision, NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
111 void SipCprStates::TSendProvision::DoL() |
|
112 { |
|
113 //Adds the extension to Access Config which will beretrieved in |
|
114 // non-default SCPR and ignored in default SCPR. |
|
115 iContext.Node().SetConfigL(); |
|
116 |
|
117 PRStates::TSendProvision cprSendProvision(iContext); |
|
118 cprSendProvision.DoL(); |
|
119 } |
|
120 |
|
121 //============================================================================ |
|
122 // |
|
123 // Start Activity |
|
124 // |
|
125 //=========================================================================== |
|
126 DEFINE_SMELEMENT(TRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
127 DEFINE_SMELEMENT(TAwaitingRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext) |
|
128 DEFINE_SMELEMENT(TAwaitingIncomingConnection,NetStateMachine::MState, SipCprStates::TContext) |
|
129 DEFINE_SMELEMENT(TSetPostedToScpr,NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
130 |
|
131 void TSetPostedToScpr::DoL() |
|
132 { |
|
133 // Get the SCPR node ID and wait for the IncomingConneciton message from him |
|
134 Messages::RNodeInterface* client = iContext.iNode.FindClient(Messages::message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId); |
|
135 if (client) |
|
136 { |
|
137 iContext.iNodeActivity->SetPostedTo(client->RecipientId()); |
|
138 } |
|
139 } |
|
140 |
|
141 void TRegisterCpr::DoL() |
|
142 { |
|
143 //check if profile ID has been set by passed by MCPR |
|
144 //if no profile Id was paseed as part of conn preferences |
|
145 //profile id is set to KSIPDefaultProfileId (which is a filler because 0 wont work) |
|
146 if (iContext.Node().iProfileId == KSIPDefaultProfileId) |
|
147 { |
|
148 iContext.Node().iProfileId = iContext.Node().iTransitionEngineMgr->DefaultProfileId(); |
|
149 } |
|
150 // Call the SIP High-level API for the Registration |
|
151 if (iContext.Node().iTransitionEngine == NULL) |
|
152 { |
|
153 iContext.iNodeActivity->SetError(KErrNotFound); |
|
154 |
|
155 const Messages::TNodeId& self = iContext.Node().Id(); |
|
156 // Post RegistrationComplete msg with error set |
|
157 Messages::RClientInterface::OpenPostMessageClose(self,self,TSipCprMessages::TRegistrationComplete(KErrNotFound).CRef()); |
|
158 } |
|
159 else |
|
160 { |
|
161 iContext.Node().iTransitionEngine->RegisterL(&(iContext.Node())); |
|
162 iContext.Node().iStage = SipCpr::EStarting; |
|
163 } |
|
164 //Expect Response |
|
165 iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId(); |
|
166 iContext.iNodeActivity->SetPostedTo(iContext.Node().Id()); |
|
167 } |
|
168 |
|
169 TBool TAwaitingIncomingConnection::Accept() |
|
170 { |
|
171 if(iContext.iMessage.IsMessage<TSipCprMessages::TIncomingConnection>()) |
|
172 { |
|
173 // reset it to the initial value so that so that it is taken care in next time |
|
174 // around. That i.e after Rconn.Waitforincoming() if subcon open is called |
|
175 // on Rcon like subcon.open(Rcon) then it run into problems. |
|
176 iContext.Node().iConnStatus = SipCpr::EConnOutgoing ; |
|
177 return ETrue; |
|
178 } |
|
179 return EFalse; |
|
180 } |
|
181 |
|
182 TBool TAwaitingRegistrationComplete::Accept() |
|
183 { |
|
184 if(iContext.iMessage.IsMessage<TSipCprMessages::TRegistrationComplete>()) |
|
185 { |
|
186 TSipCprMessages::TRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TRegistrationComplete>(&iContext.iMessage); |
|
187 if (msg->iValue == KErrNone) |
|
188 { |
|
189 iContext.Node().iStage = SipCpr::EActive; |
|
190 } |
|
191 else |
|
192 { |
|
193 //Set the error for activity and will be raised |
|
194 TInt error = msg->iValue; |
|
195 iContext.iNodeActivity->SetError(error); |
|
196 } |
|
197 |
|
198 return ETrue; |
|
199 } |
|
200 return EFalse; |
|
201 } |
|
202 |
|
203 DEFINE_SMELEMENT(TNoTagOrRegistered,NetStateMachine::MStateFork, SipCprStates::TContext) |
|
204 TInt TNoTagOrRegistered::TransitionTag() |
|
205 { |
|
206 if(iContext.Node().iStage == SipCpr::EActive) |
|
207 { |
|
208 return SipCprStates::KRegistered; |
|
209 } |
|
210 return MeshMachine::KNoTag; |
|
211 } |
|
212 |
|
213 //=============================================================================== |
|
214 // |
|
215 // Stop Activity |
|
216 // |
|
217 //=============================================================================== |
|
218 |
|
219 DEFINE_SMELEMENT(TDeRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
220 DEFINE_SMELEMENT(TAwaitingDeRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext) |
|
221 |
|
222 void TDeRegisterCpr::DoL() |
|
223 { |
|
224 // Call the SIP high level API for de-registraiton |
|
225 iContext.Node().iTransitionEngine->Deregister(&(iContext.Node())); |
|
226 if(iContext.Node().iStage <= SipCpr::EStopping) |
|
227 { |
|
228 //We haven't recieved a DeRegister Request yet |
|
229 iContext.Node().iStage = SipCpr::EStopping; |
|
230 } |
|
231 |
|
232 //Expect Response |
|
233 iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId(); |
|
234 iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId()); |
|
235 } |
|
236 |
|
237 |
|
238 TBool TAwaitingDeRegistrationComplete::Accept() |
|
239 { |
|
240 //catch only messages generated by the SIPCPR |
|
241 ASSERT(iContext.iSender == iContext.Node().Id()); |
|
242 if(iContext.iMessage.IsMessage<TSipCprMessages::TDeRegistrationComplete>()) |
|
243 { |
|
244 TSipCprMessages::TDeRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TDeRegistrationComplete>(&iContext.iMessage); |
|
245 if (msg->iValue == KErrNone) |
|
246 { |
|
247 iContext.Node().iStage = SipCpr::EStopped; |
|
248 } |
|
249 else |
|
250 { |
|
251 //Set the error for activity so that it can be forwarded to applicaiton |
|
252 TInt error = msg->iValue; |
|
253 iContext.iNodeActivity->SetError(error); |
|
254 } |
|
255 return ETrue; |
|
256 } |
|
257 return EFalse; |
|
258 } |
|
259 |
|
260 /* |
|
261 DEFINE_SMELEMENT(TSendStopped,NetStateMachine::MStateTransition, SipCprStates::TContext) |
|
262 void TSendStopped::DoL() |
|
263 { |
|
264 |
|
265 TInt stopCode = iContext.Node().iStashedStoppedCode; |
|
266 //the section below is reproduced intoto from the CoreStates::TSendStopped :-) |
|
267 TCFMessage::TStopped msg(iContext.iNode(), iContext.iCFMessageSig.ActivityId(), stopCode); |
|
268 if (iContext.iNodeActivity) |
|
269 { |
|
270 iContext.iNodeActivity->PostToOriginators(msg); |
|
271 } |
|
272 else |
|
273 { |
|
274 //This transition can also be used from a single tripple activity |
|
275 ASSERT(iContext.iCFMessageSig.iPeer); //Always a peer message |
|
276 iContext.iCFMessageSig.iPeer->PostMessage(msg); |
|
277 } |
|
278 if (iContext.Node().CountActivities(ECFActivityStart) == 0) |
|
279 { |
|
280 TCFMessage::TGoneDown goneDown(iContext.iNode(), ECFActivityNull, stopCode); |
|
281 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(RNodeInterface::ECtrl); |
|
282 for (TInt i = 0; iter[i]; i++) |
|
283 { |
|
284 //Send TGoneDown to every Ctrl client except the originator (who would be recieving TStopped) |
|
285 if ((iContext.iNodeActivity && iContext.iNodeActivity->FindOriginator(*iter[i]) != KErrNone) || |
|
286 (iContext.iNodeActivity == NULL && iter[i] != iContext.iCFMessageSig.iPeer)) |
|
287 { |
|
288 iter[i]->PostMessage(goneDown); |
|
289 } |
|
290 } |
|
291 } |
|
292 if (iContext.iNodeActivity) |
|
293 { |
|
294 iContext.iNodeActivity->SetError(KErrNone); |
|
295 } |
|
296 } |
|
297 */ |
|
298 |
|
299 /** |
|
300 Comms-binder activity will use this function. |
|
301 It returns KWaitForIncoming if the connection type is WaitForIncoming |
|
302 otherwise returns KUseExisting |
|
303 */ |
|
304 DEFINE_SMELEMENT(TWaitForIncomingOrUseExisting,NetStateMachine::MStateFork, SipCprStates::TContext) |
|
305 TInt TWaitForIncomingOrUseExisting::TransitionTag() |
|
306 { |
|
307 if(iContext.Node().iConnStatus == SipCpr::EConnIncoming) |
|
308 { |
|
309 return CoreNetStates::KWaitForIncoming; |
|
310 } |
|
311 else |
|
312 { |
|
313 return CoreStates::KUseExisting; |
|
314 } |
|
315 } |
|
316 |
|
317 DEFINE_SMELEMENT(TNoTagOrDeRegister,NetStateMachine::MStateFork, SipCprStates::TContext) |
|
318 TInt TNoTagOrDeRegister::TransitionTag() |
|
319 { |
|
320 MeshMachine::CNodeActivityBase* activity = iContext.iNodeActivity; |
|
321 Messages::TSignatureBase& message = iContext.iMessage; |
|
322 TInt code = KErrCancel; |
|
323 if (activity && activity->Error() != KErrNone) |
|
324 { |
|
325 code = activity->Error(); |
|
326 } |
|
327 |
|
328 if (message.IsTypeOf(Messages::TSigNumber::TypeId())) |
|
329 { |
|
330 code = static_cast<const Messages::TSigNumber&>(message).iValue; |
|
331 } |
|
332 else if (message.IsTypeOf(Messages::TSigNumberNumber::TypeId())) |
|
333 { |
|
334 code = static_cast<const Messages::TSigNumberNumber&>(message).iValue1; |
|
335 } |
|
336 |
|
337 //stash the stop code to be used after we get DeRegistrationComplete |
|
338 iContext.Node().iStashedStoppedCode = code; |
|
339 |
|
340 //Now do the regular fork |
|
341 if(iContext.Node().iStage == SipCpr::EActive) |
|
342 { |
|
343 return SipCprStates::KDeRegister; |
|
344 } |
|
345 return MeshMachine::KNoTag; |
|
346 } |
|
347 }// namespace SipCprStates |