|
1 /** @file |
|
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: CUpnpServiceImplementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <e32def.h> |
|
22 #include <e32math.h> |
|
23 #include <f32file.h> |
|
24 #include <s32file.h> |
|
25 #include "upnpserviceimplementation.h" |
|
26 #include "upnphttpmessage.h" |
|
27 #include "upnpsoapmessage.h" |
|
28 #include "upnpsoapmessagefactory.h" |
|
29 #include "upnpgenamessage.h" |
|
30 #include "upnpgenamessagefactory.h" |
|
31 #include "upnpstring.h" |
|
32 #include "upnpcommonupnplits.h" |
|
33 #include "upnphttpmessagefactory.h" |
|
34 #include "upnpdevice.h" |
|
35 #include "upnpdeviceimplementationbase.h" |
|
36 #include "upnpcommonstructs.h" |
|
37 #include "upnplist.h" |
|
38 #include "upnpfileutils.h" |
|
39 #include "upnpdispatcher.h" |
|
40 #include "upnpcontenthandlerscontroller.h" |
|
41 #include "upnpeventcontroller.h" |
|
42 #include "upnpsoapparser.h" |
|
43 |
|
44 #define KLogFile _L("UPnPStack.txt") |
|
45 #include "upnpcustomlog.h" |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // CUpnpService::SetDispatcher |
|
49 // ----------------------------------------------------------------------------- |
|
50 // |
|
51 EXPORT_C void CUpnpServiceImplementation::SetDispatcher( CUpnpDispatcher* aDispatcher ) |
|
52 { |
|
53 if(iDispatcher) |
|
54 { |
|
55 iDispatcher->RemoveCustomer(*this, EFalse); |
|
56 } |
|
57 |
|
58 iDispatcher = aDispatcher; |
|
59 } |
|
60 |
|
61 // ----------------------------------------------------------------------------- |
|
62 // CUpnpService::SendL |
|
63 // ----------------------------------------------------------------------------- |
|
64 // |
|
65 EXPORT_C void CUpnpServiceImplementation::SendL( CUpnpHttpMessage *aMessage ) |
|
66 { |
|
67 if ( iDispatcher ) |
|
68 { |
|
69 iDispatcher->SendMessageL( aMessage, *this ); |
|
70 } |
|
71 } |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CUpnpService::Path |
|
75 // ----------------------------------------------------------------------------- |
|
76 // |
|
77 EXPORT_C const TDesC8& CUpnpServiceImplementation::Path() |
|
78 { |
|
79 return *iPath; |
|
80 } |
|
81 |
|
82 // ============================ MEMBER FUNCTIONS =============================== |
|
83 |
|
84 // ----------------------------------------------------------------------------- |
|
85 // CUpnpServiceImplementation::CUpnpServiceImplementation |
|
86 // C++ default constructor can NOT contain any code, that |
|
87 // might leave. |
|
88 // ----------------------------------------------------------------------------- |
|
89 // |
|
90 EXPORT_C CUpnpServiceImplementation::CUpnpServiceImplementation( CUpnpDevice& aDevice ) |
|
91 : CUpnpService(aDevice) |
|
92 { |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // CUpnpServiceImplementation::~CUpnpServiceImplementation |
|
97 // Destructor. |
|
98 // ----------------------------------------------------------------------------- |
|
99 // |
|
100 EXPORT_C CUpnpServiceImplementation::~CUpnpServiceImplementation() |
|
101 { |
|
102 DeviceImpl().DetachService( this ); |
|
103 iEventedVariables.Reset(); |
|
104 delete iEventController; |
|
105 delete iSaxController; |
|
106 delete iSoapParser; |
|
107 } |
|
108 |
|
109 // ----------------------------------------------------------------------------- |
|
110 // CUpnpServiceImplementation::BaseConstructL |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 EXPORT_C void CUpnpServiceImplementation::BaseConstructL( const TDesC& aFileName, |
|
114 const TDesC8& aServiceType ) |
|
115 { |
|
116 //subscriber library initialization |
|
117 LOGS("CUpnpServiceImplementation::BaseConstructL"); |
|
118 |
|
119 HBufC8* descr = UpnpFileUtil::ReadFileL( aFileName ); |
|
120 CleanupStack::PushL(descr); |
|
121 // File ready |
|
122 |
|
123 this->ConstructL( *descr, aServiceType ); |
|
124 |
|
125 CleanupStack::PopAndDestroy(descr); |
|
126 |
|
127 iEventController = CUpnpEventController::NewL( *this ); |
|
128 |
|
129 // from device |
|
130 DeviceImpl().AttachServiceL( this ); |
|
131 iComplete = ETrue; |
|
132 iDispatcher->AddCustomerL( *this, EFalse ); |
|
133 |
|
134 iSaxController = CUpnpContentHandlersController::NewL(); |
|
135 iSoapParser = new (ELeave) TUpnpSoapParser( *iSaxController ); |
|
136 } |
|
137 |
|
138 // ----------------------------------------------------------------------------- |
|
139 // CUpnpServiceImplementation::MessageReceivedLD |
|
140 // ----------------------------------------------------------------------------- |
|
141 // |
|
142 EXPORT_C void CUpnpServiceImplementation::MessageReceivedLD( CUpnpHttpMessage* aMessage ) |
|
143 { |
|
144 LOGS("CUpnpServiceImplementation::MessageReceivedL(CUpnpHttpMessage*)"); |
|
145 |
|
146 if ( !aMessage ) |
|
147 { |
|
148 return; |
|
149 } |
|
150 |
|
151 CleanupStack::PushL( aMessage ); |
|
152 if ( aMessage->IsSoap() ) |
|
153 { |
|
154 // checking content type of action. Checking that content type exists. |
|
155 TPtrC8 tempHeaderValue = aMessage->GetHeaderValue( UpnpGENA::KContentType() ); |
|
156 TPtrC8 headerValue; |
|
157 TInt posOfSemicolon = tempHeaderValue.Find( UpnpString::KSemiColon() ); |
|
158 |
|
159 // checking if content type contains semicolon |
|
160 if ( posOfSemicolon != KErrNotFound ) |
|
161 { |
|
162 tempHeaderValue.Set( tempHeaderValue.Left( posOfSemicolon ) ); |
|
163 TPtrC8 trimmed( UpnpString::Trim( tempHeaderValue, EFalse ) ); |
|
164 headerValue.Set( trimmed ); |
|
165 } |
|
166 else |
|
167 { |
|
168 headerValue.Set( tempHeaderValue ); |
|
169 } |
|
170 |
|
171 if ( headerValue.CompareC( UpnpGENA::KDefaultContentType ) != 0 ) |
|
172 { |
|
173 // content type of action is not text/xml. Invalid action. |
|
174 CUpnpHttpMessage* messageOut |
|
175 = RUpnpHttpMessageFactory::HttpResponseErrorL(aMessage, |
|
176 EHttpUnsupportedMediaType |
|
177 ); |
|
178 CleanupStack::PushL( messageOut ); |
|
179 SendL( messageOut ); |
|
180 CleanupStack::PopAndDestroy( messageOut ); |
|
181 CleanupStack::PopAndDestroy( aMessage ); |
|
182 return; |
|
183 } |
|
184 |
|
185 TRAPD( err, HandleActionL( reinterpret_cast<CUpnpSoapMessage*>( aMessage ) ) ); |
|
186 if ( err ) |
|
187 { |
|
188 SendL( reinterpret_cast<CUpnpSoapMessage*>( aMessage ), |
|
189 MapGenericErrorToUpnp( err ) ); |
|
190 } |
|
191 } |
|
192 else if ( aMessage->IsGena() ) |
|
193 { |
|
194 TRAPD( err, HandleActionL( reinterpret_cast<CUpnpGenaMessage*>( aMessage ) ) ); |
|
195 if ( err ) |
|
196 { |
|
197 // send proper errormessage |
|
198 CUpnpHttpMessage* messageOut |
|
199 = RUpnpHttpMessageFactory::UpnpResponseErrorL(aMessage, |
|
200 EActionFailed |
|
201 ); |
|
202 CleanupStack::PushL( messageOut ); |
|
203 SendL( messageOut ); |
|
204 CleanupStack::PopAndDestroy( messageOut ); |
|
205 } |
|
206 } |
|
207 else |
|
208 { |
|
209 //should never happen |
|
210 LOGS1( "CUpnpServiceImplementation::MessageReceivedLD msg type %d", aMessage->Type() ); |
|
211 ASSERT( EFalse ); |
|
212 } |
|
213 CleanupStack::PopAndDestroy( aMessage ); |
|
214 } |
|
215 |
|
216 // ----------------------------------------------------------------------------- |
|
217 // CUpnpServiceImplementation::MapGenericErrorToUpnp |
|
218 // ----------------------------------------------------------------------------- |
|
219 // |
|
220 TUpnpErrorCode CUpnpServiceImplementation::MapGenericErrorToUpnp( TInt aError ) |
|
221 { |
|
222 if ( aError == KErrArgument ) |
|
223 { |
|
224 return EInvalidArgs; |
|
225 } |
|
226 else |
|
227 { |
|
228 return EActionFailed; |
|
229 } |
|
230 } |
|
231 |
|
232 // ----------------------------------------------------------------------------- |
|
233 // CUpnpServiceImplementation::HandleActionL |
|
234 // ----------------------------------------------------------------------------- |
|
235 // |
|
236 void CUpnpServiceImplementation::HandleActionL(CUpnpGenaMessage* aMessage) |
|
237 { |
|
238 LOGS("CUpnpServiceImplementation::HandleActionL(CUpnpGenaMessage*)"); |
|
239 |
|
240 if ( !aMessage ) |
|
241 { |
|
242 return; |
|
243 } |
|
244 |
|
245 TPtrC8 method = aMessage->Method(); |
|
246 |
|
247 if (method.Compare(UpnpGENA::KGenaSubscribe) == 0) |
|
248 { |
|
249 // Subscription or renewing: |
|
250 iEventController->SubscribeL( aMessage ); |
|
251 } |
|
252 else if (method.Compare(UpnpGENA::KGenaUnSubscribe) == 0) |
|
253 { |
|
254 // UnSubscription: |
|
255 iEventController->UnSubscribeL( aMessage ); |
|
256 } |
|
257 } |
|
258 |
|
259 // ----------------------------------------------------------------------------- |
|
260 // CUpnpServiceImplementation::HandleActionL |
|
261 // (other items were commented in a header). |
|
262 // ----------------------------------------------------------------------------- |
|
263 // |
|
264 void CUpnpServiceImplementation::HandleActionL( CUpnpSoapMessage* aMessage ) |
|
265 { |
|
266 LOGS("CUpnpServiceImplementation::HandleActionL(CUpnpSoapMessage*)"); |
|
267 if ( !aMessage ) |
|
268 { |
|
269 return; |
|
270 } |
|
271 |
|
272 // parse SOAP to CUpnpAction |
|
273 CUpnpAction* action = CreateActionLC( aMessage->ActionName() ); |
|
274 |
|
275 if ( !action ) |
|
276 { |
|
277 // send errormessage |
|
278 SendL( aMessage, EInvalidAction ); |
|
279 } |
|
280 else |
|
281 { |
|
282 iSoapParser->UpdateActionWithRequestL( aMessage, action ); |
|
283 TInt actionError( action->Error() ); |
|
284 if ( ( EUpnpOk == actionError ) || ( EHttp200Ok == actionError ) ) |
|
285 { |
|
286 CleanupStack::Pop( action ); |
|
287 // a valid action received |
|
288 ActionReceivedLD( action ); |
|
289 } |
|
290 else |
|
291 { |
|
292 TUpnpErrorCode upnpError; |
|
293 // error |
|
294 if ( actionError < 0 ) //is generic symbian error |
|
295 |
|
296 { |
|
297 upnpError = MapGenericErrorToUpnp( actionError ); |
|
298 } |
|
299 else |
|
300 { |
|
301 upnpError = (TUpnpErrorCode) actionError; |
|
302 } |
|
303 SendL( aMessage, upnpError ); |
|
304 CleanupStack::PopAndDestroy( action ); |
|
305 } |
|
306 } |
|
307 } |
|
308 |
|
309 // ----------------------------------------------------------------------------- |
|
310 // CUpnpServiceImplementation::SendL |
|
311 // (other items were commented in a header). |
|
312 // ----------------------------------------------------------------------------- |
|
313 // |
|
314 EXPORT_C void CUpnpServiceImplementation::SendL( CUpnpAction* aAction, |
|
315 TUpnpErrorCode aError) |
|
316 { |
|
317 LOGS1("CUpnpServiceImplementation::SendL(CUpnpAction*, TUpnpErrorCode: %d)", aError); |
|
318 |
|
319 CUpnpHttpMessage* msg( NULL ); |
|
320 if ( EHttpOk == aError ) |
|
321 { |
|
322 msg = reinterpret_cast<CUpnpHttpMessage*> |
|
323 (RUpnpSoapMessageFactory::SoapResponseL( aAction )); |
|
324 } |
|
325 else |
|
326 { |
|
327 LOGS1("Error: %i", aError); |
|
328 msg = reinterpret_cast<CUpnpHttpMessage*> |
|
329 (RUpnpSoapMessageFactory::SoapResponseL( aAction, aError )); |
|
330 } |
|
331 CleanupStack::PushL( msg ); |
|
332 SendL( msg ); |
|
333 CleanupStack::PopAndDestroy( msg ); |
|
334 } |
|
335 |
|
336 // ----------------------------------------------------------------------------- |
|
337 // CUpnpServiceImplementation::SendL |
|
338 // (other items were commented in a header). |
|
339 // ----------------------------------------------------------------------------- |
|
340 // |
|
341 EXPORT_C void CUpnpServiceImplementation::SendL(CUpnpSoapMessage* aMessage, |
|
342 TUpnpErrorCode aError) |
|
343 { |
|
344 LOGS1("CUpnpServiceImplementation::SendL(CUpnpSoapMessage*, TUpnpErrorCode: %d)", aError); |
|
345 |
|
346 CUpnpHttpMessage* msg = reinterpret_cast<CUpnpHttpMessage*>( |
|
347 RUpnpSoapMessageFactory::SoapResponseL(aMessage, aError)); |
|
348 CleanupStack::PushL(msg); |
|
349 SendL(msg); |
|
350 CleanupStack::PopAndDestroy(msg); |
|
351 } |
|
352 |
|
353 // ----------------------------------------------------------------------------- |
|
354 // CUpnpServiceImplementation::SetStateVariableL |
|
355 // ----------------------------------------------------------------------------- |
|
356 // |
|
357 EXPORT_C void CUpnpServiceImplementation::SetStateVariableL( const TDesC8& aName, |
|
358 const TDesC8& aValue, |
|
359 TBool aIsModerated ) |
|
360 { |
|
361 LOGS("CUpnpServiceImplementation::SetStateVariableL"); |
|
362 TInt totalDesLength(0); |
|
363 totalDesLength = KGenaXml().Length() + KGenaPropertysetStart().Length()+ |
|
364 KGenaPropertysetEnd().Length(); |
|
365 for ( TInt i(0);i<iStateVariables.Count();i++ ) |
|
366 { |
|
367 if ( iStateVariables[i]->Eventable().CompareF(KYes) == 0 ) |
|
368 { |
|
369 totalDesLength+=KGenaPropertyStart().Length(); |
|
370 totalDesLength+=iStateVariables[i]->Name().Length(); |
|
371 totalDesLength+=KCloseBracket().Length(); |
|
372 if ( aName.Compare( iStateVariables[i]->Name() ) == 0 ) |
|
373 { |
|
374 totalDesLength+=aValue.Length(); |
|
375 } |
|
376 else |
|
377 { |
|
378 totalDesLength+=iStateVariables[i]->Value().Length(); |
|
379 } |
|
380 totalDesLength+=KOpenBracket().Length(); |
|
381 totalDesLength+=( UpnpString::KSlash )().Length(); |
|
382 totalDesLength+=iStateVariables[i]->Name().Length(); |
|
383 totalDesLength+=KGenaPropertyEnd().Length(); |
|
384 } |
|
385 } |
|
386 if (totalDesLength<KMaxGenaMessageLength) |
|
387 { |
|
388 CUpnpStateVariable* variable = StateVariable( aName ); |
|
389 if( !variable ) |
|
390 { |
|
391 User::Leave( KErrBadHandle ); |
|
392 } |
|
393 |
|
394 variable->SetValueL( aValue, aIsModerated ); |
|
395 } |
|
396 else |
|
397 { |
|
398 iEventController->SendModeratedNotification(); |
|
399 } |
|
400 } |
|
401 |
|
402 // ----------------------------------------------------------------------------- |
|
403 // CUpnpServiceImplementation::StateVariableValue |
|
404 // ----------------------------------------------------------------------------- |
|
405 // |
|
406 EXPORT_C const TPtrC8 CUpnpServiceImplementation::StateVariableValue( |
|
407 const TDesC8& aVariableName ) |
|
408 { |
|
409 CUpnpStateVariable* variable = StateVariable(aVariableName); |
|
410 if (variable) |
|
411 { |
|
412 return variable->Value(); |
|
413 } |
|
414 return KNullDesC8(); |
|
415 } |
|
416 |
|
417 // ----------------------------------------------------------------------------- |
|
418 // CUpnpServiceImplementation::StateVariable |
|
419 // ----------------------------------------------------------------------------- |
|
420 // |
|
421 EXPORT_C CUpnpStateVariable* CUpnpServiceImplementation::StateVariable( |
|
422 const TDesC8& aVariableName ) |
|
423 { |
|
424 CUpnpStateVariable* variable = NULL; |
|
425 variable = CUpnpService::StateVariable(aVariableName); |
|
426 if (variable) |
|
427 { |
|
428 variable->SetParentImplementation(*this); |
|
429 } |
|
430 return variable; |
|
431 } |
|
432 |
|
433 // ----------------------------------------------------------------------------- |
|
434 // CUpnpServiceImplementation::AddEventVariable |
|
435 // (other items were commented in a header). |
|
436 // ----------------------------------------------------------------------------- |
|
437 // |
|
438 EXPORT_C void CUpnpServiceImplementation::AddEventVariable |
|
439 (const CUpnpStateVariable& aVariable, |
|
440 TBool aIsModerated ) |
|
441 { |
|
442 LOGS("CUpnpServiceImplementation::AddEventVariable"); |
|
443 |
|
444 if (iEventedVariables.Find(&aVariable) == KErrNotFound) |
|
445 { |
|
446 iEventedVariables.Append(&aVariable); |
|
447 } |
|
448 if (aIsModerated) |
|
449 { |
|
450 iEventController->SendModeratedNotification(); |
|
451 } |
|
452 else |
|
453 { |
|
454 iEventController->SendNonModeratedNotification(); |
|
455 } |
|
456 |
|
457 } |
|
458 |
|
459 // ----------------------------------------------------------------------------- |
|
460 // CUpnpServiceImplementation::SetVariableMaxEventRate |
|
461 // (other items were commented in a header). |
|
462 // ----------------------------------------------------------------------------- |
|
463 // |
|
464 EXPORT_C void CUpnpServiceImplementation::SetVariableMaxEventRate |
|
465 (const TDesC8& aVariable, TInt aMaxRate) |
|
466 |
|
467 { |
|
468 LOGS("CUpnpServiceImplementation::SetVariableMaxEventRate"); |
|
469 |
|
470 for(TInt i = 0; i < iEventedVariables.Count(); i++) |
|
471 { |
|
472 if(iEventedVariables[i]->Name().Compare(aVariable)==0) |
|
473 { |
|
474 iEventedVariables[i]->SetMaxEventRate(aMaxRate, KMaxEventRate); |
|
475 } |
|
476 } |
|
477 |
|
478 } |
|
479 |
|
480 // ----------------------------------------------------------------------------- |
|
481 // CUpnpServiceImplementation::StateVariableEvented |
|
482 // ----------------------------------------------------------------------------- |
|
483 // |
|
484 EXPORT_C void CUpnpServiceImplementation::StateVariableEvented( |
|
485 const TDesC8& /*aVariableName*/) |
|
486 { |
|
487 } |
|
488 |
|
489 // ----------------------------------------------------------------------------- |
|
490 // CUpnpServiceImplementation::SubcribersAmount |
|
491 // ----------------------------------------------------------------------------- |
|
492 // |
|
493 EXPORT_C TInt CUpnpServiceImplementation::SubcribersAmount() |
|
494 { |
|
495 return iEventController->SubscribersAmount(); |
|
496 } |
|
497 |
|
498 // ----------------------------------------------------------------------------- |
|
499 // CUpnpServiceImplementation::DeviceImpl |
|
500 // ----------------------------------------------------------------------------- |
|
501 // |
|
502 CUpnpDeviceImplementationBase& CUpnpServiceImplementation::DeviceImpl() |
|
503 { |
|
504 return (CUpnpDeviceImplementationBase&) Device(); |
|
505 } |
|
506 |
|
507 // ----------------------------------------------------------------------------- |
|
508 // CUpnpServiceImplementation::EventedStateVariables |
|
509 // ----------------------------------------------------------------------------- |
|
510 // |
|
511 EXPORT_C RPointerArray<CUpnpStateVariable>& |
|
512 CUpnpServiceImplementation::EventedStateVariables() |
|
513 { |
|
514 return iEventedVariables; |
|
515 } |
|
516 |
|
517 // End of File |