Transferring Data to the Remote Device

Context

When the MLlcpLinkListener::LlcpRemoteFound callback is called, the application issues CMyOwnLlcpApplication::SendHelloWorldText() to send the "Hello World!" ASCII text.

Steps

  • Call the CMyOwnLlcpApplication::SendHelloWorldText method as shown in the following code snippet:

    Example:

    // CMyOwnLlcpApplication::SendHelloWorldText()
    // -----------------------------------------------------------------------------
    //
    TInt CMyOwnLlcpApplication::SendHelloWorldText()
        {
        TInt error = KErrNone;
        
        if ( iLocalConnection )
            {
            iLocalConnection->Transfer( iStatus, _L8( "Hello World!" ) );
            SetActive();
            }
        else
            {
            // The LLCP link is not established, cannot send any data.
            error = KErrNotReady;
            }
            
        return error;
        }
    // -----------------------------------------------------------------------------
    // End of CMyOwnLlcpApplication::SendHelloWorldText()
    
    

    Note: If the iLocalConnection object has already been created, the MLlcpConnOrientedTransporter::Transmit() method is called. iLocalConnection is a member variable for the MLlcpConnOrientedTransporter object and created in the CMyOwnLlcpApplication::LlcpRemoteFound method. If iLocalConnection is NULL, the CMyOwnLlcpApplication::LlcpRemoteFound method is not called, and no LLCP link between the local and remote devices is established.

    The actual data transfer in the COwnLlcpConnection::Transfer() method is as shown in the following code snippet:

    // COwnLlcpConnection::Transfer()
    // -----------------------------------------------------------------------------
    //
    void COwnLlcpConnection::Transfer( TRequestStatus& aStatus, const TDesC8& aData )
        {
        TInt error = KErrNone;
        aStatus = KRequestPending;
        TRequestStatus* status = &aStatus // local
        
        // Copy the data to an internal buffer. 
        iTransmitBuf.Zero();
        error = iTransmitBuf.ReAlloc( aData.Length() );
        
        if ( error == KErrNone )
            {
            iTransmitBuf.Append( aData );
            
            if ( iConnState == ENotConnected )
                {
                // Start connecting if the connection is in idle state
                iConnection->Connect( iStatus );
                SetActive();
                iConnState = EConnecting;
                
                iClientStatus = status;
                }
            else if ( iConnState == EConnected && iActionState == EIdle )
                {
                // Send the data.
                iConnection->Transmit( iStatus, iTransmitBuf );
                SetActive();
                iActionState = ETransmitting;
                
                iClientStatus = status;
                }
            else
                {
                // iConnState == EConnecting, cannot do anything.
                error = KErrInUse;
                }
            }
            
        if ( error != KErrNone )
            {
            User::RequestComplete( status, error );
            }
        }
    // -----------------------------------------------------------------------------
    // End of COwnLlcpConnection::Transfer()

    The COwnLlcpConnection::Transfer() method copies descriptor to its internal buffer and then data transfer occurs immediately between local and remote device.

    Note:

    • The COwnLlcpConnection::Transfer() method cannot start transferring data if there is a pending transfer or receive request. In such a scenario, KErrInUse is returned. This means that COwnLlcpConnection object does not support simultaneous transfer and receipt. However, MLlcpConnOrientedTransporter supports simultaneous data transfer and receipt between the local and remote devices.

    • If the COwnLlcpConnection object is not connected, COwnLlcpConnection requests the MLlcpConnOrientedTransporter::Connect() method. When MLlcpConnOrientedTransporter is connected, COwnLlcpConnection::RunL() method is called as shown in the following code snippet.
      // Handling the connecting request
              case EConnecting:
                  {
                  if ( error == KErrNone )
                      {
                      // Update the state
                      iConnState = EConnected;
                      
                      // Send the data if there is data to send
                      if ( iTransmitBuf.Length() > 0 )
                          {
                          iConnection->Transmit( iStatus, iTransmitBuf );
                          SetActive();
                          iActionState = ETransmitting;
                          }
                      }
                  else
                      {
                      if ( iClientStatus )
                          {
                          User::RequestComplete( iClientStatus, error );
                          iClientStatus = NULL;
                          }
                      
                      iConnState = ENotConnected;
                      }
                  }
                  break;
              // End of handling the connecting request
      
      If a connection request is successfully completed, actual data transfer will be issued through MLlcpConnOrientedTransporter::Tranmit().
    • The maximum amount of data that MLlcpConnOrientedTransporter::Transmit()can handle is the value returned by the MLlcpConnOrientedTransporter::SupportedDataLength() method. If the data is greater than the value, clients of MLlcpConnOrientedTransporter::Transmit() must send data in multiple packets. The minimum size of MLlcpConnOrientedTransporter::SupportedDataLength() is 128 bytes.

    The following diagram illustrates the sequence diagram of data transferring:

    Figure: Sequence diagram of data transferring