|
1 // Copyright (c) 2005-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 // Name : csipregistering.cpp |
|
15 // Part of : SIP Registration |
|
16 // Version : SIP/4.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "csipregistering.h" |
|
22 #include "SipAssert.h" |
|
23 #include "CSIPRegistrar.h" |
|
24 #include "siprequest.h" |
|
25 #include "sipresponse.h" |
|
26 #include "sipcontactheader.h" |
|
27 #include "sipminexpiresheader.h" |
|
28 #include "MRegistrationOwner.h" |
|
29 #include "CSIPResponseUtility.h" |
|
30 #include "siperr.h" |
|
31 #include "sipstrings.h" |
|
32 #include "sipstrconsts.h" |
|
33 |
|
34 |
|
35 // ----------------------------------------------------------------------------- |
|
36 // CSIPRegistering::NewL |
|
37 // ----------------------------------------------------------------------------- |
|
38 // |
|
39 CSIPRegistering* CSIPRegistering::NewL(MRegistrationContext& aRegistration) |
|
40 { |
|
41 CSIPRegistering* self = CSIPRegistering::NewLC(aRegistration); |
|
42 CleanupStack::Pop(self); |
|
43 return self; |
|
44 } |
|
45 |
|
46 // ----------------------------------------------------------------------------- |
|
47 // CSIPRegistering::NewLC |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 CSIPRegistering* CSIPRegistering::NewLC(MRegistrationContext& aRegistration) |
|
51 { |
|
52 CSIPRegistering* self = new (ELeave) CSIPRegistering(aRegistration); |
|
53 CleanupStack::PushL(self); |
|
54 return self; |
|
55 } |
|
56 |
|
57 // ----------------------------------------------------------------------------- |
|
58 // CSIPRegistering::SetNeighbourStates |
|
59 // ----------------------------------------------------------------------------- |
|
60 // |
|
61 void CSIPRegistering::SetNeighbourStates( |
|
62 CSIPRegistrationState* aResponse423Received, |
|
63 CSIPRegistrationState* aRegistered, |
|
64 CSIPRegistrationState* aUnregistered) |
|
65 { |
|
66 __SIP_ASSERT_RETURN(aResponse423Received, KErrArgument); |
|
67 __SIP_ASSERT_RETURN(aRegistered, KErrArgument); |
|
68 __SIP_ASSERT_RETURN(aUnregistered, KErrArgument); |
|
69 |
|
70 iResponse423Received = aResponse423Received; |
|
71 iRegistered = aRegistered; |
|
72 iUnregistered = aUnregistered; |
|
73 } |
|
74 |
|
75 // ----------------------------------------------------------------------------- |
|
76 // CSIPRegistering::~CSIPRegistering |
|
77 // ----------------------------------------------------------------------------- |
|
78 // |
|
79 CSIPRegistering::~CSIPRegistering() |
|
80 { |
|
81 } |
|
82 |
|
83 // ----------------------------------------------------------------------------- |
|
84 // CSIPRegistering::CSIPRegistering |
|
85 // ----------------------------------------------------------------------------- |
|
86 // |
|
87 CSIPRegistering::CSIPRegistering(MRegistrationContext& aRegistration) |
|
88 : CSIPRegistrationState(aRegistration) |
|
89 { |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // CSIPRegistering::RegisterL |
|
94 // ----------------------------------------------------------------------------- |
|
95 // |
|
96 void CSIPRegistering::RegisterL(TTransactionId& aTransactionId, |
|
97 CSIPRequest* aRequest, |
|
98 CSIPRouteHeader* aOutboundProxy) |
|
99 { |
|
100 __SIP_ASSERT_LEAVE(aRequest, KErrArgument); |
|
101 |
|
102 // if registrar is not NULL, fill in CallId and CSeq to request |
|
103 if (iRegistration.Registrar()) |
|
104 { |
|
105 iRegistration.Registrar()->FillCallIdAndCSeqL(*aRequest); |
|
106 } |
|
107 iRegistration.RegisterL(aTransactionId, aRequest, aOutboundProxy); |
|
108 } |
|
109 |
|
110 // ----------------------------------------------------------------------------- |
|
111 // CSIPRegistering::ReceiveL |
|
112 // ----------------------------------------------------------------------------- |
|
113 // |
|
114 void CSIPRegistering::ReceiveL(TTransactionId aTransactionId, |
|
115 CSIPResponse* aResponse) |
|
116 { |
|
117 __SIP_ASSERT_LEAVE(aResponse, KErrArgument); |
|
118 // the expires parameter value must not be 0, other wise panic in debug |
|
119 // mode, leaves in release mode. |
|
120 __SIP_ASSERT_LEAVE(iRegistration.Contact().ExpiresParameter() > 0, |
|
121 KErrGeneral); |
|
122 |
|
123 if (aResponse->Type() == CSIPResponse::E2XX) |
|
124 { |
|
125 // ConnectionMgr may have changed the the host part of the Contact |
|
126 iRegistration.UpdateContactFromRequestL(); |
|
127 if (iRegistration.Request()) |
|
128 { |
|
129 iRegistration.Request()->DeleteHeaders( |
|
130 SIPStrings::StringF(SipStrConsts::ERouteHeader)); |
|
131 } |
|
132 TInt err = |
|
133 CSIPResponseUtility::Check2XXResponse(iRegistration,*aResponse); |
|
134 if (err) |
|
135 { |
|
136 iRegistration.ReceivedErrorResponseL(); |
|
137 User::LeaveIfError(PassErrorToOwner(err,aTransactionId)); |
|
138 delete aResponse; |
|
139 iRegistration.SelfDetach(ETrue); |
|
140 iRegistration.ChangeState(iUnregistered); |
|
141 } |
|
142 // if there is no error, call function Received2XXResponseL, |
|
143 // which will update bindings, start timer for non refresh binding |
|
144 else |
|
145 { |
|
146 iRegistration.Received2XXResponseL(*aResponse,aTransactionId); |
|
147 // pass response to owner |
|
148 PassResponseToOwnerL(aResponse, aTransactionId, |
|
149 iRegistration.RegistrationId()); |
|
150 //if EFalse, detach from lower layer only for non refresh binding. |
|
151 iRegistration.SelfDetach(EFalse); |
|
152 // for non refresh register, the request ownership is not passed |
|
153 // to lower, it can be deleted after 2xx response received. |
|
154 iRegistration.ClearRequest(); |
|
155 iRegistration.ChangeState(iRegistered); |
|
156 } |
|
157 } |
|
158 else if (aResponse->IsErrorResponse()) |
|
159 { |
|
160 // if 423 response is received and there is min expires header, |
|
161 // set min expires header from response to request and send |
|
162 // the request again. |
|
163 const RStringF KMinExpiresHeaderName = |
|
164 SIPStrings::StringF(SipStrConsts::EMinExpiresHeader); |
|
165 |
|
166 if (aResponse->ResponseCode() == K423Response && |
|
167 aResponse->HasHeader(KMinExpiresHeaderName)) |
|
168 { |
|
169 iRegistration.Received423ResponseL(*aResponse); |
|
170 iRegistration.ChangeState(iResponse423Received); |
|
171 iRegistration.CurrentState().RegisterL( |
|
172 aTransactionId,iRegistration.Request(),NULL); |
|
173 delete aResponse; |
|
174 } |
|
175 // either response code is 423, but no MinExpires-header in response |
|
176 // or response code not 423 |
|
177 else |
|
178 { |
|
179 // function ReceivedErrorResponseL removes binding. |
|
180 iRegistration.ReceivedErrorResponseL(); |
|
181 // pass response to owner |
|
182 PassResponseToOwnerL(aResponse, aTransactionId); |
|
183 iRegistration.SelfDetach(ETrue); |
|
184 iRegistration.ChangeState(iUnregistered); |
|
185 } |
|
186 } |
|
187 else // response type == 1XX |
|
188 { |
|
189 // pass provisional response to owner |
|
190 PassResponseToOwnerL(aResponse, aTransactionId); |
|
191 } |
|
192 } |
|
193 |
|
194 // ----------------------------------------------------------------------------- |
|
195 // CSIPRegistering::TransactionEnded |
|
196 // ----------------------------------------------------------------------------- |
|
197 // |
|
198 TInt CSIPRegistering::TransactionEnded(TTransactionId aTransactionId, |
|
199 TInt aReason) |
|
200 { |
|
201 if (aReason != KErrNone) |
|
202 { |
|
203 // changes state to unregistered if error received. |
|
204 iRegistration.ChangeState(iUnregistered); |
|
205 } |
|
206 // pass error to owner. |
|
207 return (PassErrorToOwner(aReason, aTransactionId)); |
|
208 } |