📄 ag_pair.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 + -