examples/DataComms/Rconnection/rconnection.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 
00031 
00032 
00033 #include "rconnection.h"
00034 
00035 _LIT(KContinueNote,"Press any key to continue\n");
00036 _LIT(KOpenErr,"Open() unsuccessful\n");
00037 _LIT(KStartErr,"RConnection::Start() unsuccessful\n");
00038 _LIT(KInterfaceUp,"Connection has started and interface is up\n");
00039 _LIT(KInterfaceDown,"Connection has closed and interface is down\n");
00040 _LIT(KConnectionUpNote,"Connection is up....\n");
00041 _LIT(KConnectionStartNote,"Start() was called on the connection\n");
00042 _LIT(KConnectionClosingNote,"The connection is about to be closed\n");
00043 _LIT(KWaitNote,"Waiting for the connection to close.....\n");
00044 _LIT(KUpLinkData,"Data volume on uplink=%d bytes\n");
00045 _LIT(KDownLinkData,"Data volume on downlink=%d bytes\n");
00046 _LIT(KDataTransferNote,"Calling DataSendAndReceive()\n");
00047 _LIT(KSocketErrNote,"Socket preparation failed\n");
00048 _LIT(KSocketSetNote,"Socket successfully established\n");
00049 
00050 _LIT(KRow1,"**********************************************************\n");
00051 _LIT(KRow2,"    Section Demonstrating  :                  \n");
00052 _LIT(KRow3,"**********************************************************\n");
00053 _LIT(KTab,"\t");
00054 _LIT(KNewLine,"\n");
00055 
00056 #define KEchoPort 0xAB                  //Port value for client socket.
00057 #define KMaxBufferLength 2048   //Maximum length of buffer used to send and receive data.
00058 #define KDelay 1000000                  //Time interval in microseconds to wait before carrying out the next task.
00059 
00063 CRConnection::CRConnection(CConsoleBase* aConsole)
00064         :iConsole(aConsole)     
00065         {
00066         //Set the destination address and port.
00067         //Before running the example user should start an Echo server 
00068         //and then specify the respective IP Address and port of the echo server 
00069         //for iDestAddr.
00070         //Until the Echo Server is established send and receive functionality won't work properly. 
00071         
00072         
00073         _LIT(KDestAddr,"127.0.0.1");  
00074         const TInt KSockPort= 7;
00075         
00076         iDestAddr.Input(KDestAddr);
00077         iDestAddr.SetPort(KSockPort);
00078           
00079         StartESOCK();
00080         }
00081 
00082 
00086 CRConnection::~CRConnection()
00087         {
00088         //Closing the monitor and socket server session.
00089         iMonitor.Close();
00090         iSocketServ.Close();
00091         }
00092 
00098 void CRConnection::StartESOCK() 
00099         {
00100         
00101         //Connects to the socket server.
00102         TInt err=iSocketServ.Connect();
00103         if(err!=KErrNone)
00104                 {
00105                 _LIT(KConnectErr,"Connect failed\n");
00106                 User::Panic(KConnectErr,err);           
00107                 }       
00108         
00109         //Opens the monitor to receive notification when another connection
00110         //that uses the same socket server goes up or down. 
00111         err=iMonitor.Open(iSocketServ);
00112         if(err!=KErrNone)
00113                 {
00114                 iConsole->Printf(KOpenErr);
00115                 return; 
00116                 }       
00117         }
00118                 
00126 TInt CRConnection::ConnectWithoutDbOverrideL()
00127         {
00128         // Opens an RConnection and associates it with the same socket server session as iMonitor.
00129         // To use an RConnection instance first it needs to be opened on an existing socket server session 
00130         // and then Start() must be called to associate it with an underlying interface.
00131         TInt err=iConnection.Open(iSocketServ); 
00132         if(err!=KErrNone)
00133                 {
00134                 iConsole->Printf(KOpenErr);
00135                 return err;     
00136                 }
00137         
00138         //Starts the connection using default CommDb settings.
00139         err=iConnection.Start();
00140         if(err!=KErrNone)
00141                 {
00142                 iConsole->Printf(KStartErr);
00143                 return err;     
00144                 }
00145         else
00146                 {
00147                 iConsole->Printf(KConnectionStartNote); 
00148                 return err;
00149                 }                               
00150         }
00151         
00155 TInt CRConnection::ConnectWithDbOverrideL()
00156         {
00157         // To use an RConnection instance first it needs to be opened on an existing socket server session 
00158         // and then Start() must be called to associate it with an underlying interface.
00159         TInt err=iConnection.Open(iSocketServ); 
00160         if(err!=KErrNone)
00161                 {
00162                 iConsole->Printf(KOpenErr);
00163                 return err;
00164                 }
00165         
00166         // Overrides some Commdb connection preferences.
00167         const TInt KIapId=9;
00168         TCommDbConnPref prefs;
00169         prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
00170         prefs.SetIapId(KIapId);    //The commdb is set for Ethernet with Daemon Static IP. 
00171                                                                         
00172         //Starts an outgoing connection.
00173         err=iConnection.Start(prefs);
00174         
00175         if(err==KErrNone)
00176                 {
00177                 iConsole->Printf(KConnectionStartNote); 
00178                 return err;
00179                 }
00180         else
00181                 {
00182                 iConsole->Printf(KStartErr);
00183                 return err;     
00184                 }               
00185         }
00191 void CRConnection::GetProgressNotification()
00192         {
00193         TRequestStatus status;
00194         TNifProgressBuf buffer; //filled with progress/error information on completion 
00195         while((TUint)(buffer().iStage)!=KConnectionUp) 
00196                 {
00197                 iConnection.ProgressNotification(buffer,status);
00198                 User::WaitForRequest(status);
00199                 if(status==KErrNone&&(buffer().iError)==KErrNone)
00200                         {
00201                         DisplayProgressinfo(buffer());
00202                         }
00203                 User::After(KDelay);
00204                 }
00205         iConsole->Printf(KConnectionUpNote); //Link layer is now open.  
00206                 
00207                         
00208         }
00209         
00214 void CRConnection::DisplayProgressinfo(const TNifProgress& aProgress)
00215         {
00216         switch(aProgress.iStage)
00217                 {
00218                 case KStartingSelection:
00219                         {
00220                         _LIT(KStartSelectionNote,"Starting Selection...........\n");
00221                         iConsole->Printf(KStartSelectionNote);
00222                         break;  
00223                         }
00224                                         
00225                 case KFinishedSelection:
00226                         {
00227                         _LIT(KFinishedSelectionNote,"Finished Selection...........\n");
00228                         iConsole->Printf(KFinishedSelectionNote);
00229                         break;  
00230                         }
00231                                         
00232                 case KConnectionOpen:
00233                         {
00234                         _LIT(KWlanAgtConnected,"Wlan agent connected....\n");
00235                         iConsole->Printf(KWlanAgtConnected);
00236                         break;  
00237                         }
00238                                                 
00239                 //Generic progress notifications from the configuration daemon.                         
00240                 case KConfigDaemonLoading:
00241                         {
00242                         _LIT(KConfigDaemonLoadingNote,"Daemon loading....\n");
00243                         iConsole->Printf(KConfigDaemonLoadingNote);
00244                         break;  
00245                         }
00246                                         
00247                 case KConfigDaemonLoaded:
00248                         {
00249                         _LIT(KConfigDaemonLoadedNote,"Daemon loaded....\n");
00250                         iConsole->Printf(KConfigDaemonLoadedNote);
00251                         break;  
00252                         }
00253                                                 
00254                 case KConfigDaemonStartingRegistration:
00255                         {
00256                         _LIT(KConfigDaemonStartingRegistrationNote,"Daemon starting registration....\n");
00257                         iConsole->Printf(KConfigDaemonStartingRegistrationNote);
00258                         break;  
00259                         }
00260                                                 
00261                 case KConfigDaemonFinishedRegistration:
00262                         {
00263                         _LIT(KConfigDaemonFinishedRegistrationNote,"Daemon registration finished....\n");
00264                         iConsole->Printf(KConfigDaemonFinishedRegistrationNote);
00265                         break;  
00266                         }       
00267         
00268                 default:
00269                         break;                  
00270                 }
00271         }
00272 
00278 TInt CRConnection::PrepareSocket()
00279         {
00280         TInt err = iSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection);
00281         if (err != KErrNone)
00282                 {
00283                 return err;     
00284                 }
00285                 
00286         //Sets a socket option. These options affect operations such as the routing of packets, 
00287         //out-of-band data transfer, and so on. Here the option level "KSolInetIp" is set for an IP socket,
00288         //and the option being set is "KSoReuseAddr". This means the socket is allowed to be bound to a local
00289         //address that is already in use.
00290         //The third parameter i.e 1 states that the option is enabled.A value of 0 means disabled.
00291         
00292         err = iSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1); 
00293         if (err != KErrNone)
00294                 {
00295                 return err;     
00296                 }
00297         
00298         //Sets a local port for the socket.
00299         err = iSocket.SetLocalPort(KEchoPort); 
00300         if (err != KErrNone)
00301                 {
00302                 return err;     
00303                 }
00304         return err;             
00305         }
00311 TInt CRConnection::SendUdpData(TUint aPayloadSize)
00312         {
00313         
00314         TBuf8<KMaxBufferLength> buffer;
00315         // construct an ICMP packet to send on the socket.
00316         buffer.SetMax();
00317         buffer.FillZ();
00318         buffer[0] = (TUint8) 0x08; // ICMP type = 8.
00319         buffer[1] = (TUint8) 0x00; // ICMP code = 0.
00320         buffer[2] = (TUint8) 0xF7; // ICMP checksum high byte.
00321         buffer[3] = (TUint8) 0xFF; // ICMP checksum low byte.
00322         
00323         // NB the rest of the buffer is zero
00324         // hence the checksum (0xFFFF - 0x800) since 0x8
00325         // is the only non-zero element of the buffer
00326 
00327         // set the length of the data to be sent to that specified (payload size!).
00328         buffer.SetLength(aPayloadSize);
00329 
00330         TRequestStatus status;
00331 
00332         // send the data out over the socket.
00333         iSocket.SendTo(buffer, iDestAddr, 0, status);
00334         User::WaitForRequest(status);
00335 
00336         return status.Int();
00337         }
00338 
00344 TInt CRConnection::RecvUdpData(TUint aPayloadSize)
00345         {
00346         
00347         TInt timeoutInSecs = 30;
00348         RTimer timer;
00349         
00350         /* 
00351         Creates a timer so that we can handle error situation arising due to lost udp packet
00352         and dont completely rely on being errored by esock alone. This code waits for 30sec for
00353         udp data packet to arrive from the server. If the data is not available within this
00354         time the socket waiting for data is closed and the error value of KErrTimedOut is 
00355         returned. 
00356         */
00357         TInt ret;
00358         if ((ret = timer.CreateLocal()) != KErrNone)
00359                 {
00360                 timer.Close(); // closing the timer.
00361                 return ret;
00362                 }
00363         TRequestStatus timerStatus;
00364         timer.After(timerStatus, timeoutInSecs * 1000000); //setting timer.
00365         
00366         TBuf8<KMaxBufferLength> buffer;
00367         buffer.Zero();
00368         buffer.SetLength(aPayloadSize);
00369 
00370         TRequestStatus status;
00371         iSocket.RecvFrom(buffer, iDestAddr, 0, status); //waiting on data from the server.
00372         User::WaitForRequest(status, timerStatus);
00373 
00374         // Timer expired, and if no data is received cancel the receive operation.
00375         if(timerStatus != KRequestPending)
00376                 {
00377                 iSocket.CancelAll();
00378                 User::WaitForRequest(status);
00379                 timer.Close();
00380                 return KErrTimedOut;
00381                 }
00382         // otherwise cancel the timer.
00383         timer.Cancel();
00384         User::WaitForRequest(timerStatus);
00385         timer.Close();
00386 
00387         //when data is successfully received, check against the previously sent buffer data,
00388         //to see what is received is what was sent.
00389         if (status != KErrNone)
00390                 return status.Int();
00391         else
00392                 {   
00393                 if(buffer[0] == 0x08)
00394                         {
00395                         if(buffer[1] == 0x00)
00396                                 {
00397                                 if(buffer[2] == 0xF7)
00398                                         {
00399                                         if(buffer[3] == 0xFF)
00400                                                 {
00401                                                 ;       
00402                                                 }
00403                                         else 
00404                                                 {
00405                                                 _LIT(KFourthDataSet,"Fourth set of data not received\n");
00406                                                 iConsole->Printf(KFourthDataSet);
00407                                                 }               
00408                                         }
00409                                 else
00410                                         {
00411                                         _LIT(KThirdDataSet,"Third set of data not received\n");
00412                                         iConsole->Printf(KThirdDataSet);        
00413                                         }       
00414 
00415                                 }
00416                         else
00417                                 {
00418                                 _LIT(KSecondDataSet,"Second set of data not received\n");
00419                                 iConsole->Printf(KSecondDataSet);       
00420                                 }
00421                         }
00422                 else
00423                         {
00424                         _LIT(KFirstDataSet,"First set of data not received\n");
00425                         iConsole->Printf(KFirstDataSet);        
00426                         }       
00427                         
00428                 }
00429         return KErrNone;
00430         }
00431 
00435 void CRConnection::DataSendAndReceive(TUint aPayloadSize)
00436         {
00437         //Sends UDP Data.
00438         TInt err = SendUdpData(aPayloadSize);
00439         if (err != KErrNone)
00440                 {
00441                 _LIT(KDataSentErrNote,"DataSend Failed\n");
00442                 iConsole->Printf(KDataSentErrNote);
00443                 return ;        
00444                 }
00445         else
00446                 {
00447                 _LIT(KDataSentNote,"DataSend Successful\n");
00448                 iConsole->Printf(KDataSentNote);        
00449                 }
00450 
00451         //Receives UDP Data.
00452         err = RecvUdpData(aPayloadSize);
00453         if(err!=KErrNone)
00454                 {
00455                 _LIT(KDataReceiveErrNote,"DataReceive Failed\n");
00456                 iConsole->Printf(KDataReceiveErrNote);
00457                 return ;        
00458                 }
00459         else
00460                 {
00461                 _LIT(KDataReceiveNote,"DataReceive Successful\n");
00462                 iConsole->Printf(KDataReceiveNote);
00463                 }       
00464                 
00465         }
00466 
00470 void CRConnection::DataTransferredRequest()
00471         {
00472         TPckg<TUint> uplinkVolumeDes(0); //holds the amount of data received.
00473         TPckg<TUint> downlinkVolumeDes(0); //holds the amount of data transmitted.
00474         
00475         TRequestStatus datastatus;
00476 
00477         iConnection.DataTransferredRequest(uplinkVolumeDes, downlinkVolumeDes, datastatus);
00478         User::WaitForRequest(datastatus);
00479         
00480         if(datastatus==KErrNone)
00481                 {
00482                 iConsole->Printf(KUpLinkData,uplinkVolumeDes());
00483                 iConsole->Printf(KDownLinkData,downlinkVolumeDes());    
00484                 }
00485                         
00486         }
00491 void CRConnection::DataTransferNotificationRequest()
00492         {
00493         const TUint KHundredBytes = 100; //The threshold value for notification.
00494         const TUint KThousandBytes = 1000; //The total amount of data to send/receive.
00495         TPckg< TUint > uplinkPkg(0); //Holds the amount of data sent.
00496         TPckg< TUint > downlinkPkg(0);//Holds the amount of data received.
00497         TRequestStatus dataSentStatus,dataReceivedStatus;
00498         
00499         //Registers for data sent notification. The process gets notified when 100 bytes of data are sent. 
00500         iConnection.DataSentNotificationRequest(KHundredBytes, uplinkPkg, dataSentStatus );
00501         
00502         //Registers for data received notification. The process gets notified when 100 bytes of data are received.
00503         iConnection.DataReceivedNotificationRequest(KHundredBytes, downlinkPkg, dataReceivedStatus );
00504         iConsole->Printf(KDataTransferNote);
00505         
00506         //Sends and receives 1000 bytes of data.
00507         DataSendAndReceive(KThousandBytes);
00508                 
00509         /*
00510         Gets the total data sent/received = datavolume+UdpPacketOverhead
00511         here datavolume=1000 bytes,thus total data send/receive > 1000 as 
00512         some overhead gets added on top of the actual datavolume.
00513         */
00514         
00515         User::WaitForRequest(dataSentStatus);
00516         User::WaitForRequest(dataReceivedStatus);
00517         if ((dataSentStatus.Int())== KErrNone)
00518                 {
00519                 _LIT(KSentSuccessNote,"DataSentNotificationRequest is successful and\n ");      
00520                 iConsole->Printf(KSentSuccessNote);
00521                 }
00522         else
00523                 {
00524                 _LIT(KSentFailureNote,"DataSentNotificationRequest has failed and \n");
00525                 iConsole->Printf(KSentFailureNote);
00526                 }
00527         iConsole->Printf(KUpLinkData,uplinkPkg());
00528                                         
00529         if (dataReceivedStatus.Int()==KErrNone)
00530                 {
00531                 _LIT(KReceivedSuccessNote,"DataReceivedNotificationRequest is successful and \n");      
00532                 iConsole->Printf(KReceivedSuccessNote);
00533                 }
00534         else 
00535                 {
00536                 _LIT(KReceivedFailureNote,"DataReceivedNotificationRequest has failed and \n");
00537                 iConsole->Printf(KReceivedFailureNote);
00538                 }               
00539         iConsole->Printf(KDownLinkData,downlinkPkg());  
00540 
00541         }
00542         
00543 void CRConnection::DisplaySectionToDemo(const TDesC& aText)
00544         {
00545         TBuf<120> newtext;
00546         newtext.Append(KTab);
00547         newtext.Append(aText);
00548         newtext.Append(KTab);
00549         newtext.Append(KNewLine);
00550         iConsole->Printf(KRow1);
00551         iConsole->Printf(KRow2);
00552         iConsole->Printf(newtext);
00553         iConsole->Printf(KRow3);
00554         iConsole->Printf(KNewLine);
00555         }
00556 
00567 void CRConnection::DemoApiWithoutDbOverrideL()
00568         {
00569         _LIT(KDemoApiWithoutDbOverride,"RConnection API without CommDb override\n");
00570         iConsole->ClearScreen();
00571         DisplaySectionToDemo(KDemoApiWithoutDbOverride);
00572         
00573         TRequestStatus status;
00574         TPckgBuf<TInterfaceNotification> info;
00575         //Makes a request for notification when the interface goes up i.e. the connection starts.
00576         iMonitor.AllInterfaceNotification(info,status);
00577                 
00578         //Makes an explicit connection without CommDb override. 
00579         TInt err=ConnectWithoutDbOverrideL();
00580         if(err!=KErrNone)
00581                 return;
00582         
00583         //Waits on TRequestStatus until the interface is up.
00584         User::WaitForRequest(status);
00585         if(info().iState==EInterfaceUp)
00586                 {
00587                 iConsole->Printf(KInterfaceUp); 
00588                 }                               
00589         
00590         //Gets and prints progress notification for the connection.
00591         GetProgressNotification();
00592         User::After(KDelay);  // waits for a while and then proceeds. This helps to get a sequential flow.
00593         
00594         err=PrepareSocket(); // Once the socket is ready for data transfer, send and receive operations can be carried out.
00595         if(err!=KErrNone)
00596                 {
00597                 iConsole->Printf(KSocketErrNote);
00598                 return; 
00599                 }
00600         else
00601                 {
00602                 iConsole->Printf(KSocketSetNote);       
00603                 }       
00604         
00605         iConsole->Printf(KDataTransferNote);
00606         
00607         const TUint KPayLoadSize=512;
00608         //Sends and receives data through the socket.
00609         DataSendAndReceive(KPayLoadSize);
00610         
00611         DataTransferredRequest();// Gets and prints the amount of data that has been transferred.
00612                 
00613         User::After(KDelay);//Wait for a while, before proceeding.      
00614 
00615         //Makes a request for notification when the interface goes down i.e. the connection closes.
00616         iMonitor.AllInterfaceNotification(info,status); 
00617                 
00618         // All the operations related to the socket and connection are done, so close both.
00619         iSocket.Close();
00620         iConsole->Printf(KConnectionClosingNote);
00621         iConnection.Close();
00622         iConsole->Printf(KWaitNote); 
00623         
00624         //Waits for the 'interface down' notification
00625         User::WaitForRequest(status);
00626         if(info().iState==EInterfaceDown)
00627                 {
00628                 iConsole->Printf(KInterfaceDown);       
00629                 }
00630                 
00631         iConsole->Printf(KContinueNote);
00632         iConsole->Getch();
00633 
00634         }
00635         
00646 void CRConnection::DemoApiWithDbOverrideL()
00647         {
00648         
00649         _LIT(KDemoApiWithDbOverride,"RConnection API with CommDb override\n");
00650         iConsole->ClearScreen();
00651         DisplaySectionToDemo(KDemoApiWithDbOverride);
00652                 
00653         TRequestStatus status;
00654         TPckgBuf<TInterfaceNotification> info;
00655         
00656         // Requests notification when the connection is established.
00657         // Notification request is issued before calling Start().
00658         iMonitor.AllInterfaceNotification(info,status);
00659         
00660         //Start an explicit connection with CommDb override. 
00661         TInt err=ConnectWithDbOverrideL();
00662         if(err!=KErrNone)
00663                 return;
00664         
00665         //Waits on TRequestStatus until the interface is up.
00666         User::WaitForRequest(status);
00667         if(info().iState==EInterfaceUp)
00668                 {
00669                 iConsole->Printf(KInterfaceUp); 
00670                 }       
00671 
00672         //Gets and prints progress notification for the connection.
00673         GetProgressNotification();
00674         
00675         //Waits for a while before next operation.
00676         User::After(KDelay);
00677         
00678         err=PrepareSocket(); //Once the socket is ready for data transfer, send and receive operations can be carried out.
00679         if(err!=KErrNone)
00680                 {
00681                 iConsole->Printf(KSocketErrNote);
00682                 return; 
00683                 }
00684         else    
00685                 {
00686                 iConsole->Printf(KSocketSetNote);       
00687                 }
00688         //Sends and receives data and requests notification when a threshold amount of data is transferred.
00689         DataTransferNotificationRequest(); 
00690         User::After(KDelay);
00691 
00692         //Makes a request for notification when the interface goes down i.e. the connection closes.
00693         iMonitor.AllInterfaceNotification(info,status);
00694                 
00695         //Closes socket 
00696         iSocket.Close();
00697         iConsole->Printf(KConnectionClosingNote);
00698                 
00699         //Closes the connection.
00700         iConnection.Close();
00701         iConsole->Printf(KWaitNote); 
00702         
00703         //Waits on the TRequestStatus until the interface is down 
00704         User::WaitForRequest(status);
00705         if(info().iState==EInterfaceDown)
00706                 {
00707                 iConsole->Printf(KInterfaceDown);       
00708                 }       
00709         
00710         iConsole->Printf(KContinueNote);
00711         iConsole->Getch();
00712         
00713         }
00714 
00724 void CRConnection::AttachToExistingInterfaceL()
00725         {
00726         
00727         _LIT(KAttachToConnection,"Attaching to a connection\n");
00728         iConsole->ClearScreen();
00729         DisplaySectionToDemo(KAttachToConnection);
00730         
00731         // Attaching to a connection is done as follows:
00732         // 1)first open a connection interface.
00733         // 2)on this connection interface, obtain the no. of active connections and their connection info.
00734         // 3)a second connection is opened.
00735         // 4)this 2nd connection is attached to the existing active connection interface.
00736          
00737         RConnection conn;
00738         
00739         //Opens the first RConnection.
00740         TInt err = conn.Open(iSocketServ);
00741         if(err==KErrNone)
00742                 {
00743                 CleanupClosePushL(conn);        
00744                 }
00745         else
00746                 {
00747                 iConsole->Printf(KOpenErr);
00748                 return; 
00749                 }       
00750         
00751         //Opens the 2nd connection. 
00752         err =  iConnection.Open(iSocketServ);
00753         if(err!=KErrNone)
00754                 {
00755                 iConsole->Printf(KOpenErr);
00756                 return; 
00757                 }       
00758         
00759         //Starts the 1st connection.
00760         err=conn.Start();
00761         if(err!=KErrNone)
00762                 {
00763                 iConsole->Printf(KStartErr);
00764                 return; 
00765                 }
00766         
00767         // Enumerates the total number of connections on the 1st connection interface.
00768         // This call returns a count of 1.      
00769         TUint connectionCount;
00770         err = conn.EnumerateConnections(connectionCount);
00771         if((err != KErrNone) || (connectionCount < 1))
00772                 {
00773                 return;
00774                 }
00775         
00776         
00777         // Gets connection info for the 1st connection (conn) which will be used by the 
00778         // 2nd connection to attach to. 
00779         TConnectionInfoBuf connectionInfo;
00780         err = conn.GetConnectionInfo(connectionCount, connectionInfo); // gets connection info about the indexed connection
00781                                                                                                                                    // (the 1st connection).
00782         if(err != KErrNone)
00783                 {
00784                 return;
00785                 }
00786 
00787         // Attaches iConnection to the existing underlying interface.
00788         // The connection is used for normal data transfer.
00789         // Both connections are now actively associated with an interface.
00790         err = iConnection.Attach(connectionInfo,RConnection::EAttachTypeNormal);
00791         if(err==KErrNone)
00792                 {
00793                 _LIT(KAttachNote,"Attached to interface\n");    
00794                 iConsole->Printf(KAttachNote);                  
00795                 }
00796         else
00797                 return; 
00798         
00799         // Gets progress info and prints it to the console. 
00800     TNifProgress progress;
00801     err = iConnection.Progress(progress);
00802     if(err==KErrNone&&progress.iError==KErrNone)
00803             {
00804             if((TUint)(progress.iStage)==KConnectionUp)
00805                 iConsole->Printf(KConnectionUpNote);    
00806             }
00807         
00808         User::After(KDelay);  //waits for a while before proceeding.
00809         
00810         iConsole->Printf(KConnectionClosingNote);
00811                 
00812         //closes both connections.
00813         iConnection.Close();
00814         CleanupStack::PopAndDestroy(&conn); //conn.
00815         
00816         _LIT(KConnectionClosedNote,"Connection Closed\n");
00817         iConsole->Printf(KConnectionClosedNote);
00818         
00819         }
00820 

Generated by  doxygen 1.6.2