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

📄 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"));
                iNotify.ClientConnected(status);
                break;

            case EConnected:
                // Get the key press of the incoming data
                iNotify.ClientDataRead(iBuffer);
                break;

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

void CBTConnectionHost::StartL()
    {
    iLog.LogL(_L8("StartL - function entry"));
    if (iState != EDisconnected)
        {
        User::Leave(KErrInUse);
        }

    User::LeaveIfError(iSocketServer.Connect());
    User::LeaveIfError(iListeningSocket.Open(iSocketServer, KBTAddrFamily, KSockStream, KRFCOMM));

    // Get the next available port number to listen on
    User::LeaveIfError(
        iListeningSocket.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iPort)
    );

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

    User::LeaveIfError(iListeningSocket.Bind(listeningAddress));
    User::LeaveIfError(iListeningSocket.Listen(KListeningQueSize));

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

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

    // accept any incoming connections
    iListeningSocket.Accept(iDataSocket, iStatus);

    // 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"));

    SetSecurityOnChannelL(EFalse, EFalse, ETrue, iPort);

    iAdvertiser->StartAdvertisingL(iPort);
    }

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 + -