⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btconnectionhost.cpp

📁 S60培训教材代码(连载)
💻 CPP
字号:
/* Copyright (c) 2002, Nokia Mobile Phones. All rights reserved */

#include "BTConnectionHost.h"
#include "MessageProtocolConstants.h"
#include "Log.h"
#include "S60BTLab.pan"
#include "BTHostNotify.h"
#include "s60btlabapp.h"
#include "BTServiceAdvertiser.h"

static const TInt KListeningQueSize = 1;

    
CBTConnectionHost* CBTConnectionHost::NewL(MBTHostNotify& aNotify, MLog& aLog)
    {
    CBTConnectionHost* self = new (ELeave) CBTConnectionHost(aNotify, aLog);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop();
    return self;
    }

CBTConnectionHost::CBTConnectionHost(MBTHostNotify& aNotify, MLog& aLog) :
    CBTConnectionBase(aLog),
    iNotify(aNotify),
    iState(EDisconnected)
    {
    }

CBTConnectionHost::~CBTConnectionHost()
    {
    TRAPD(err,StopL());
    if (err != KErrNone)
        {
        TRAPD(logErr, iLog.LogL(_L8("Error stoping host, error = "), err);)
        Panic(ES60BTLabServerStop);
        }
    delete iAdvertiser;
    iAdvertiser = NULL;
    }

void CBTConnectionHost::ConstructL()
    {
    iAdvertiser = new (ELeave) CBTServiceAdvertiser(KUidS60BTLab.iUid);
    }

void CBTConnectionHost::DoCancel()
    {
    if (IsActive())
        {
        if (EConnected == iState)
            {
            iDataSocket.CancelRecv();
            }
        else if (EConnecting == iState)
            {
            iListeningSocket.CancelAccept();
            }
        }
    }

void CBTConnectionHost::RunL()
    {
    TInt status = iStatus.Int();
    if (KErrNone != status)
        {
        StopL();
        if (KErrDisconnected == status)
            {
            iLog.LogL(_L8("Disconnected"));
            iNotify.ClientDisconnected(status);
            }
        else if (EConnected == iState)
            {
            iLog.LogL(_L8("Read error "), status);
            iNotify.ClientDisconnected(status);
            }
        else if (EConnecting == iState)
            {
            iNotify.ClientConnected(status);
            }
        else if (KErrAbort == status)
            {
            iLog.LogL(_L8("Aborted"));
            }
        }
    else
        {
        switch (iState)
            {
            case EConnecting:
                iLog.LogL(_L8("Connected"));
                iState = EConnected;
                iLog.LogL(_L8("Invoking callback"));
                // TODO: notify the calling code (CS60BTLabAppView in this case)
                // that a client is now connected.
                // Hint: use MBTHostNotify::ClientConnected()
                // (this class has a MBTHostNotify& member variable)
                break;

            case EConnected:
                // Get the key press of the incoming data

                // TODO: notify the calling code (CS60BTLabAppView in this case)
                // that data has been read from the client
                // Hint: use MBTHostNotify::ClientDataRead()
                // The data is contained in iBuffer
                break;

            default:
                Panic(ES60BTLabInvalidHostState);
                break;
            }
        }
    }

void CBTConnectionHost::StartL()
    {
    iLog.LogL(_L8("StartL - function entry"));
    if (iState != EDisconnected)
        {
        User::Leave(KErrInUse);
        }
    // TODO: If any of the actions that are implemented in the following 6 TODO sections
    // return an error, the function should leave.
    // Hint: use User::LeaveIfError()

    // TODO: Connect to the socket server here using RSocketServ::Connect() with iSocketServer

    // TODO: Open a listening socket here using iListeningSocket and RSocket::Open()
    // Use: addrFamily  - KBTAddrFamily,
    //      sockType    - KSockStream
    //      protocol    - KRFCOMM
    

    // TODO: Get the next available port number here
    // Use RSocket::GetOpt on the listening socket with 
    // KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iPort as parameters


    TBTSockAddr listeningAddress;
    listeningAddress.SetPort(iPort);
    iLog.LogL(_L8("Get port = "), iPort);

    // TODO: Bind the listeningAddress variable to the listening socket
    // Use RSocket::Bind()

    // TODO: Listen for connections 
    // Use RSocket::Listen() with KListeningQueSize defined at the top of the file


    iDataSocket.Close();    // close old data connection - if any

    // Open a blank socket to send and receive data
    User::LeaveIfError(iDataSocket.Open(iSocketServer));  

    // TODO: Accept incoming connections asychronously
    // Use RSocket::Accept() on the listening socket, passing the blank socket 
    // and the iStatus member variable of this class (declared in CActive)
    

    // set an internal state variable to determine what
    // action to take in this class' RunL function
    iState = EConnecting;

    // Indicate to Active Scheduler that a request is outstanding
    SetActive();

    iLog.LogL(_L8("Accept next Connection"));

    // TODO: Set the incoming Bluetooth Security requirements
    // Use CBTConnectionHost::SetSecurityOnChannelL()
    // No authentication or encryption is required, but authorisation is.
    // This displays a dialog on the host to request user confirmation of 
    // the incoming connection.
    // Also use the port number obtained using RSocket::GetOpt

    // TODO: Start advertising the service in the Service Discovery Database
    // Use CBTServiceAdvertiser::StartAdvertisingL()
    // Hint: there is a CBTServiceAdvertiser* member variable in this class
    }

void CBTConnectionHost::SetSecurityOnChannelL(TBool aAuthentication,
                                           TBool aEncryption, 
                                           TBool aAuthorisation,
                                           TInt aChannel)
    { 
    // a connection to the security manager
    RBTMan secManager;

    // a security session
    RBTSecuritySettings secSettingsSession;

    // define the security on this port
    User::LeaveIfError(secManager.Connect());
    CleanupClosePushL(secManager);
    User::LeaveIfError(secSettingsSession.Open(secManager));
    CleanupClosePushL(secSettingsSession);

    // the security settings 
    TBTServiceSecurity serviceSecurity(KUidS60BTLab, KSolBtRFCOMM, aChannel);

    //Define security requirements
    serviceSecurity.SetAuthentication(aAuthentication);    
    serviceSecurity.SetEncryption(aEncryption); 
    serviceSecurity.SetAuthorisation(aAuthorisation);

    TRequestStatus status;
    secSettingsSession.RegisterService(serviceSecurity, status);
    
    User::WaitForRequest(status); // wait until the security settings are set
    User::LeaveIfError(status.Int());
    
    CleanupStack::PopAndDestroy();  //  secManager
    CleanupStack::PopAndDestroy();  //  secSettingsSession
    }
    

void CBTConnectionHost::RemoveSecurityL(TInt aChannel)
    {
    // a connection to the security manager
    RBTMan secManager;

    // a security session
    RBTSecuritySettings secSettingsSession;

    // define the security on this port
    User::LeaveIfError(secManager.Connect());
    CleanupClosePushL(secManager);
    User::LeaveIfError(secSettingsSession.Open(secManager));
    CleanupClosePushL(secSettingsSession);

    TBTServiceSecurity serviceSecurity(KUidS60BTLab, KSolBtRFCOMM, aChannel);

    TRequestStatus status;
    secSettingsSession.UnregisterService(serviceSecurity, status);
    
    User::WaitForRequest(status); // wait until the security settings are set
    User::LeaveIfError(status.Int());
    
    CleanupStack::PopAndDestroy();  //  secManager
    CleanupStack::PopAndDestroy();  //  secSettingsSession
    }

void CBTConnectionHost::StopL()
    {
    iLog.LogL(_L8("StopL - function entry"));
    if (EDisconnected != iState)
        {
        RemoveSecurityL(iPort);
        if (iAdvertiser && iAdvertiser->IsAdvertising())
            {
            iAdvertiser->StopAdvertisingL();
            }
        iLog.LogL(_L8("calling Cancel()"));
        Cancel();
        iLog.LogL(_L8("closing data sock"));
        iDataSocket.Close();
        iLog.LogL(_L8("closing listening sock"));
        iListeningSocket.Close();
        iLog.LogL(_L8("closing sockserv"));
        iSocketServer.Close();

        iState = EDisconnected;
        }
    iLog.LogL(_L8("StopL - function exit"));
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -