examples/SFExamples/symbian_os_communications_programming_book_v2/chapter8/receivingmessages/CWeatherReportWatcher.cpp

00001 // 
00002 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
00003 // All rights reserved.
00004 // This component and the accompanying materials are made available
00005 // under the terms of the License "Eclipse Public License v1.0"
00006 // which accompanies this distribution, and is available
00007 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00008 // 
00009 // Initial Contributors:
00010 // Nokia Corporation - initial contribution.
00011 // 
00012 // Contributors:
00013 // 
00014 // Description:
00015 // 
00016 
00017 #include "CWeatherReportWatcher.h"
00018 
00019 #include <smsuaddr.h>
00020 #include <GSMUBUF.H>
00021 #include <GSMUMSG.H>
00022 #include <SMSUSTRM.H>
00023 
00024 _LIT8(KWeatherReportPrefixString, "Weather:");
00025 const TInt KMaxWeatherReportLength = 9;
00026 
00027 CWeatherReportWatcher::~CWeatherReportWatcher()
00028         {
00029         iSmsSocket.Close();
00030         iSocketServer.Close();
00031         }
00032 
00033 CWeatherReportWatcher* CWeatherReportWatcher::NewL(MWeatherReportObserver& aWeatherReportObserver, RFs& aFs)
00034         {
00035         CWeatherReportWatcher* self = new (ELeave) CWeatherReportWatcher(aWeatherReportObserver, aFs);
00036         CleanupStack::PushL(self);
00037         self->ConstructL();
00038         CleanupStack::Pop(self);
00039         return self;
00040         }
00041 
00042 // CActive functions
00043 void CWeatherReportWatcher::DoCancel()
00044         {
00045         // Any outstanding operation would usually be cancelled here.
00046         // However, it will never be called in this code.
00047         }
00048 
00049 void CWeatherReportWatcher::RunL()
00050         {
00051         if (iState == EWaitingForWeatherReport)
00052                 {
00053                 CSmsBuffer* smsBuffer=CSmsBuffer::NewL();
00054                 CleanupStack::PushL(smsBuffer);
00055                 
00056                 CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, smsBuffer);
00057                 
00058                 // smsMessage has taken ownership of smsBuffer so remove it from the cleanup stack.
00059                 CleanupStack::Pop(smsBuffer);
00060                 
00061                 CleanupStack::PushL(smsMessage);
00062 
00063                 RSmsSocketReadStream readstream(iSmsSocket);
00064                 
00065                 // This function may leave
00066                 readstream >> *smsMessage;
00067 
00068                 // Extract the text from the SMS buffer
00069                 TBuf<KMaxWeatherReportLength> weatherReportBuf;
00070                 TInt bufferLength = smsBuffer->Length();        
00071                 if (bufferLength > KMaxWeatherReportLength)
00072                         bufferLength = KMaxWeatherReportLength;
00073                 smsBuffer->Extract(weatherReportBuf, 0, bufferLength);
00074 
00075                 MWeatherReportObserver::TWeatherReport weatherReport = MWeatherReportObserver::ENone;
00076 
00077                 // Process the message
00078                 if (weatherReportBuf.Length() >= KMaxWeatherReportLength)
00079                         {
00080                         // Get the last character. The last character represents the weather report.
00081                         TUint16 lastCharacter = weatherReportBuf[KMaxWeatherReportLength - 1];
00082                 
00083                         // Process the message
00084                         switch (lastCharacter)
00085                                 {
00086                         case '1':
00087                                 weatherReport = MWeatherReportObserver::ESunny;
00088                                 break;
00089                         case '2':
00090                                 weatherReport = MWeatherReportObserver::ECloudy;
00091                                 break;
00092                         case '3':
00093                                 weatherReport = MWeatherReportObserver::ERainy;
00094                                 break;
00095                         
00096                                 // No deafault. Leave weather report as 'None'.
00097                                 }
00098                         }
00099                         
00100                 // Update the UI with the new weather report
00101                 iWeatherReportObserver.NewWeatherReport(weatherReport);
00102 
00103                 CleanupStack::PopAndDestroy(smsMessage);
00104                 
00105                 // Acknowledge receipt of the SMS message, otherwise it will be resent
00106                 TPckgBuf<TUint> sbuf;
00107                 iStatus = KRequestPending;
00108                 iSmsSocket.Ioctl(KIoctlReadMessageSucceeded, iStatus, &sbuf, KSolSmsProv);
00109                 
00110                 // Wait for the acknowledgement to be sent, go active.
00111                 iState = EAcknowledgingWeatherReport;
00112                 SetActive();
00113                 }
00114         else if (iState == EAcknowledgingWeatherReport)
00115                 {
00116                 // The acknowledgement has now been sent so wait for another weather report.
00117                 WaitForWeatherReportL();
00118                 }
00119         }
00120         
00121 CWeatherReportWatcher::CWeatherReportWatcher(MWeatherReportObserver& aWeatherReportObserver, RFs& aFs) : CActive(EPriorityStandard), iWeatherReportObserver(aWeatherReportObserver), iFs(aFs)
00122         {
00123         }
00124 
00125 void CWeatherReportWatcher::ConstructL()
00126         {
00127         CActiveScheduler::Add(this);
00128 
00129         // Connect to sockets server
00130         // SMS messages are intercepted via sockets
00131         User::LeaveIfError(iSocketServer.Connect());
00132         
00133         // Open SMS socket
00134         User::LeaveIfError(iSmsSocket.Open(iSocketServer,KSMSAddrFamily,KSockDatagram,KSMSDatagramProtocol));
00135         
00136         // Set SMS prefix - only intercept SMS messages starting with a particular string
00137         TSmsAddr smsAddress;
00138         smsAddress.SetSmsAddrFamily(ESmsAddrMatchText);
00139         smsAddress.SetTextMatch(KWeatherReportPrefixString);
00140         iSmsSocket.Bind(smsAddress);
00141         
00142         WaitForWeatherReportL();
00143         }
00144 
00145 void CWeatherReportWatcher::WaitForWeatherReportL()
00146         {
00147         
00148         // Wait for an appropriate SMS message
00149         // the RunL will be called when an appropriate SMS message is received
00150         
00151         // Note that the smsAddress has already been set in ConstructL so we will only
00152         // intercept messages starting with 'Weather:'
00153         
00154         iSbuf()=KSockSelectRead;
00155         iStatus = KRequestPending;
00156         iSmsSocket.Ioctl(KIOctlSelect, iStatus, &iSbuf, KSOLSocket);
00157         iState = EWaitingForWeatherReport;
00158         
00159         SetActive();
00160         }

Generated by  doxygen 1.6.2