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

📄 ag_pair.c

📁 bluetooth audio gateway
💻 C
字号:
#include "ag_private.h"
#include "ag.h"

#include <message.h>
#include <ps.h>
#include <print.h>
#include <string.h>



/*
    pairReqAction

    Request to enter pairing mode (can pair as either master or slave).
*/
void pairReqAction(bd_addr_t addr, bool_t auth, uint16 timeout)
{
    if (agIdleQuery())
    {
        MAKE_MSG(CM_PAIR_REQ);
        msg->role = CmMaster;
        msg->timeout = D_SEC(timeout);
        msg->authentication = auth;
        msg->bd_addr.nap = addr.nap;
        msg->bd_addr.uap = addr.uap;
        msg->bd_addr.lap = addr.lap;
        agPutCmMsg(msg);

        agSetCurrentState(AgPairing);

        /* 
            TODO: using this code the AG will re-pair OK with the same
            remote device i.e. a new link key will be generated.
            However, if ag is paired with dev A and then using this
            pairs with dev B then dev A will still be in the SM
            database and will be allowed to access the AG ... this is
            probably not what we want (depending on the number of
            connections the AG supports.)
        */
    }
    else
    {
        agSendErrorToClient(AgErrorPairRequestWhenNotIdle, 0);
    }
}


/*
    agPinCodeReq

    Pin code request received so pass it on
*/
void agPinCodeReq(const CM_PIN_CODE_REQ_T *req)
{
	/* 
		Only allow pairing if in pairing mode. This complies with the recommendations made 
		in the Security white paper compiled by the Bluetooth SIG. Pairing should only
		be allowed when in "pairing mode".
	*/
	if (AGState.currentState == AgPairing)
		handlePinReq(req->addr);
	else
		agSendErrorToClient(AgErrorUnexpectedPrimitive, 0);
}


/*
    pinResAction

    Reply with PIN code received from the client Send PIN to
    Connection Manager to contunue pairing.
*/
void pinResAction(bd_addr_t addr, uint8 pin_len, const uint8 *pin)
{
    if (AGState.currentState == AgPairing)
    {   
        MAKE_MSG(CM_PIN_CODE_RES);
        msg->addr.nap = addr.nap;
        msg->addr.uap = addr.uap;
        msg->addr.lap = addr.lap;
        msg->pin_length = pin_len;        
        memcpy(msg->pin, pin, pin_len);            
        agPutCmMsg(msg);
    }
    else
    {
        agSendErrorToClient(AgErrorUnexpectedPrimitive, 0);
    }
}


/*
    AGpairCfm

    Pairing has completed, status flag indicates the outcome.
*/

void agPairCfm(const CM_PAIR_CFM_T *cfm)
{
    if (cfm->status == CmPairingNotFinished)
    {
        /* Pairing not finished so just store the link key */
        (void) PsStore(AG_PS_LINK_KEY, cfm->link_key, SIZE_LINK_KEY);        
    }
    else
    {               
        ag_pair_status_t pair_status = AgPairingError;
        uint8 link_key[AG_SIZE_LINK_KEY];
        memset(link_key, 0, AG_SIZE_LINK_KEY);

        /* AG is now idle */                           
        agSetCurrentState(AgIdle);
        
        /* determine the pairing outcome */
        switch(cfm->status)
        {
        case CmPairingComplete:
            pair_status = AgPairingComplete;        
            break;            

        case CmPairingTimeout:
            pair_status = AgPairingTimedOut;
            break;

        case CmPairingCancelled:
            pair_status = AgPairingCancelled;
            break;            

        case CmPairingFail:
            pair_status = AgPairingFailed;
            break;

            /* handled separately above but have here for consistency */
        case CmPairingNotFinished:            
        default:
            PRINT(("ag_pair: Unknown pairing complete return type 0x%x \n", cfm->status));
            pair_status = AgPairingError;
            break;
        }
        
        /* Tell the interface pairing has completed */        
        if(!PsRetrieve(AG_PS_LINK_KEY, link_key, AG_SIZE_LINK_KEY))
            handlePairCfm(cfm->bd_addr, pair_status, 0);
        else
            handlePairCfm(cfm->bd_addr, pair_status, link_key);
    }
}


/*
    agLinkKeyReq

    Link key request from the Connection Manager, pas it on to the
    client.
*/
void agLinkKeyReq(const CM_LINK_KEY_REQ_T *req)
{
    /* Tell the interface about the link key request */
    handleLinkKeyReq(agGetConnectionHandle(&req->addr));
}


/*
    linkKeyResAction

    Link key response received from the client, pass it on to the
    Connection Manager.
*/
void linkKeyResAction(bool_t accept, uint16 handle, const uint8 *key)
{
	handle = handle;

    if (AGState.currentState == AgConnecting)
    {
        MAKE_MSG(CM_LINK_KEY_RES);
        msg->accept = accept;
        msg->addr = AGState.remote_addr;

        /* Only copy link key if acceting otherwise just send zeros */
        if (accept)
            memcpy(msg->key_val, key, SIZE_LINK_KEY);        
        else
            memset(msg->key_val, 0, AG_SIZE_LINK_KEY);
        agPutCmMsg(msg);
    }
    else
    {
        agSendErrorToClient(AgErrorUnexpectedPrimitive, 0);
    }
}


/*
    agSmAddDeviceReqAction

    Add a device the AG is already paired with to the Bluestack
    security manager's trusted device database. This speeds up
    connection times since the link key is automatically sent out when
    authentication is requested.
*/
void agSmAddDeviceReqAction(bd_addr_t addr, bool_t trust, const uint8 *key)
{
    MAKE_MSG(CM_ADD_SM_DEVICE_REQ);    
    msg->addr.nap = addr.nap;
    msg->addr.uap = addr.uap;
    msg->addr.lap = addr.lap;    
    memcpy(msg->link_key, key, SIZE_LINK_KEY);
    msg->trust = trust;   
    agPutCmMsg(msg);
}

⌨️ 快捷键说明

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