examples/ForumNokia/BluetoothPMPExample/src/Connector.cpp

00001 /*
00002  * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003  *    
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *    
00007  *  * Redistributions of source code must retain the above copyright notice, this
00008  *    list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright notice,
00010  *    this list of conditions and the following disclaimer in the documentation
00011  *    and/or other materials provided with the distribution.
00012  *  * Neither the name of Nokia Corporation nor the names of its contributors
00013  *    may be used to endorse or promote products derived from this software
00014  *    without specific prior written permission.
00015  *    
00016  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021  *    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  *    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023  *    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024  *    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *    
00027  *    Description:  
00028  */
00029 
00030 // INCLUDE FILES
00031 #include "Connector.h"
00032 #include "BluetoothPMPExampleApp.h"
00033 
00034 _LIT(KRfComm,"RFCOMM");
00035 
00036 CConnector* CConnector::NewL(MConnectorObserver& aObserver, 
00037                              RSocketServ& aSocketServ)
00038     {
00039     CConnector* self = CConnector::NewLC(aObserver, aSocketServ);
00040     CleanupStack::Pop(self);
00041     return self;
00042     }
00043 
00044 
00045 CConnector* CConnector::NewLC(MConnectorObserver& aObserver, 
00046                               RSocketServ& aSocketServ)
00047     {
00048     CConnector* self = new (ELeave) CConnector(aObserver, aSocketServ);
00049     CleanupStack::PushL(self);
00050     self->ConstructL();
00051     return self;
00052     }
00053 
00054 
00055 void CConnector::ConstructL()
00056     {
00057     }
00058 
00059 
00060 CConnector::CConnector(MConnectorObserver& aObserver, 
00061                        RSocketServ& aSocketServ):
00062     CActive(CActive::EPriorityStandard),
00063     iObserver(aObserver),
00064     iSocketServ(aSocketServ),
00065     iState(ENone)
00066     {
00067     CActiveScheduler::Add(this);
00068     }
00069 
00070 
00071 CConnector::~CConnector()
00072     {
00073     Cancel();
00074     // disconnect and kill socket
00075     Disconnect();
00076     }
00077 
00078 
00079 void CConnector::DoCancel()
00080     {
00081     iSock.CancelAll();
00082     }
00083 
00084 
00085 // ----------------------------------------------------------------------------
00086 // CConnector::ConnectL(THostName aName, TBTDevAddr aAddr, TInt aPort)
00087 //
00088 // create a connection to given address on given port.  
00089 // ----------------------------------------------------------------------------
00090 TRequestStatus CConnector::ConnectL(THostName aName, TBTDevAddr aAddr, 
00091                                     TInt aPort)
00092     {
00093     iName=aName;
00094     iAddr=aAddr;
00095     iPort=aPort;
00096 
00097     // load protocol, RFCOMM
00098     TProtocolDesc pdesc;
00099     User::LeaveIfError(iSocketServ.FindProtocol(KRfComm(), pdesc));
00100 
00101     // open socket
00102     User::LeaveIfError(iSock.Open(iSocketServ, KRfComm));
00103     // set address and port
00104     TBTSockAddr addr;
00105     addr.SetBTAddr(iAddr);
00106     addr.SetPort(iPort);
00107     
00108     // connect socket
00109     TRequestStatus status;
00110     iSock.Connect(addr, status);
00111     User::WaitForRequest(status);
00112     if ( status!=KErrNone )
00113         {
00114         // error opening conn
00115         return status;
00116         }
00117         
00118     iState=EConnecting;
00119     WaitAndReceive();
00120     return status;
00121     }
00122 
00123 
00124 // ----------------------------------------------------------------------------
00125 // CConnector::Disconnect()
00126 //
00127 // disconnect from remote device, shutdown connected socket
00128 // ----------------------------------------------------------------------------
00129 void CConnector::Disconnect()
00130     {
00131     TRequestStatus status;
00132     // shutdown socket
00133     if (iState == ENone)
00134         {
00135         return;
00136         }
00137     iSock.Shutdown(RSocket::ENormal, status);
00138     User::WaitForRequest(status);
00139     iSock.Close();
00140     }
00141 
00142 
00143 // ----------------------------------------------------------------------------
00144 // CConnector::SendData(const TDesC8& aData)
00145 //
00146 // send given data to remote device, write to connected socket
00147 // ----------------------------------------------------------------------------
00148 void CConnector::SendData(const TDesC8& aData)
00149     {
00150     // cancel any read requests on socket
00151     iSock.CancelRead();
00152     Cancel();
00153     // send message
00154     iState=ESending;
00155     iSock.Write(aData, iStatus);
00156     SetActive();
00157     }
00158 
00159 
00160 // ----------------------------------------------------------------------------
00161 // CConnector::WaitAndReceiveL()
00162 //
00163 // wait for and receive data from remote device, read connected socket
00164 // ----------------------------------------------------------------------------
00165 void CConnector::WaitAndReceive()
00166     {
00167     // cancel pending operations
00168     iSock.CancelRead();
00169     Cancel();
00170     // receive data from socket
00171     iState=EWaiting;
00172     iSock.RecvOneOrMore(iBuffer, 0, iStatus, iLen);
00173     SetActive();
00174     }
00175 
00176 
00177 void CConnector::RunL()
00178     {
00179     if ( iStatus!=KErrNone )
00180         {
00181         iObserver.HandleConnectorErrorL(iName,iStatus.Int());
00182         return;
00183         }
00184 
00185     switch (iState)
00186         {
00187         case EConnecting:
00188             {
00189             // wait incoming data on socket
00190             WaitAndReceive();
00191             break;
00192             }
00193         case EWaiting:
00194             {
00195             // we got incoming data!
00196             HBufC* text = HBufC::NewLC(iBuffer.Length());
00197             text->Des().Copy(iBuffer);
00198             // observer will handle data
00199             HandleConnectorDataReceivedL(iName, *text);
00200             CleanupStack::PopAndDestroy(text);
00201 
00202             // start expecting new incoming data
00203             WaitAndReceive(); 
00204             break;
00205             }
00206         case ESending:
00207             {
00208             // tried to send a message
00209             if(iState!=KErrNone)
00210                 {
00211                 // Add error handling / socket re-read code
00212                 // here, not implemented in this example
00213                 }
00214 
00215             // start expecting new incoming data
00216             WaitAndReceive();
00217             break;
00218             }
00219         default:
00220             break;
00221         }
00222     }
00223 
00224 TInt CConnector::RunError(TInt /*aError*/)
00225     {
00226     // Add error handling here, not implemented in this example
00227     return KErrNone;
00228     }
00229 
00230 // ----------------------------------------------------------------------------
00231 // CConnector::HandleConnectorDataReceivedL(THostNama aName, TDesC& aData)
00232 //
00233 // a callback to observer indicating that connector has received data
00234 // ----------------------------------------------------------------------------
00235 void CConnector::HandleConnectorDataReceivedL(THostName aName, const TDesC& aData)
00236 {
00237     iObserver.HandleConnectorDataReceivedL(aName, aData);
00238 }
00239 

Generated by  doxygen 1.6.2