Skip to content
Snippets Groups Projects
Verified Commit bebf7b0e authored by schneider's avatar schneider Committed by rahix
Browse files

chore(ble): Copy more app related files from the stack

parent 9eead8a4
No related branches found
No related tags found
No related merge requests found
/*************************************************************************************************/
/*!
* \file
*
* \brief Application framework main module.
*
* Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
/* card10:
* copied from: lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/apps/app/app_main.c
*
* Reason: we need to correctly implement AppHandleNumericComparison
*/
#include <string.h>
#include "wsf_types.h"
#include "wsf_msg.h"
#include "sec_api.h"
#include "wsf_trace.h"
#include "wsf_timer.h"
#include "wsf_assert.h"
#include "util/bstream.h"
#include "dm_api.h"
#include "app_api.h"
#include "app_main.h"
#include "app_ui.h"
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! Configuration pointer for advertising */
appAdvCfg_t *pAppAdvCfg;
/*! Configuration pointer for extended and periodic advertising */
appExtAdvCfg_t *pAppExtAdvCfg;
/*! Configuration pointer for slave */
appSlaveCfg_t *pAppSlaveCfg;
/*! Configuration pointer for master */
appMasterCfg_t *pAppMasterCfg;
/*! Configuration pointer for extended master */
appExtMasterCfg_t *pAppExtMasterCfg;
/*! Configuration pointer for security */
appSecCfg_t *pAppSecCfg;
/*! Configuration pointer for connection parameter update */
appUpdateCfg_t *pAppUpdateCfg;
/*! Configuration pointer for discovery */
appDiscCfg_t *pAppDiscCfg;
/*! Configuration pointer for application */
appCfg_t *pAppCfg;
/*! Connection control block array */
appConnCb_t appConnCb[DM_CONN_MAX];
/*! WSF handler ID */
wsfHandlerId_t appHandlerId;
/*! Main control block */
appCb_t appCb;
/*! Configuration structure for incoming request actions */
const appReqActCfg_t appReqActCfg =
{
APP_ACT_ACCEPT /*! Action for the remote connection parameter request */
};
/*! Configuration pointer for incoming request actions on master */
appReqActCfg_t *pAppMasterReqActCfg = (appReqActCfg_t *) &appReqActCfg;
/*! Configurable pointer for incoming request actions on slave */
appReqActCfg_t *pAppSlaveReqActCfg = (appReqActCfg_t *) &appReqActCfg;
/*************************************************************************************************/
/*!
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void appProcMsg(wsfMsgHdr_t *pMsg)
{
switch(pMsg->event)
{
case APP_BTN_POLL_IND:
appUiBtnPoll();
break;
case APP_UI_TIMER_IND:
appUiTimerExpired(pMsg);
break;
default:
break;
}
}
/*************************************************************************************************/
/*!
* \brief Check the bonded state of a connection.
*
* \param connId DM connection ID.
*
* \return Bonded state.
*/
/*************************************************************************************************/
bool_t appCheckBonded(dmConnId_t connId)
{
WSF_ASSERT((connId > 0) && (connId <= DM_CONN_MAX));
return appConnCb[connId - 1].bonded;
}
/*************************************************************************************************/
/*!
* \brief Check the bond-by-LTK state of a connection.
*
* \param connId DM connection ID.
*
* \return Bond-by-LTK state.
*/
/*************************************************************************************************/
bool_t appCheckBondByLtk(dmConnId_t connId)
{
WSF_ASSERT((connId > 0) && (connId <= DM_CONN_MAX));
return appConnCb[connId - 1].bondByLtk;
}
/*************************************************************************************************/
/*!
* \brief Return the number of existing connections of the given role.
*
* \param role Connection role
*
* \return Number of connections.
*/
/*************************************************************************************************/
uint8_t appNumConns(uint8_t role)
{
appConnCb_t *pCcb = appConnCb;
uint8_t i, j;
for (i = DM_CONN_MAX, j = 0; i > 0; i--, pCcb++)
{
if ((pCcb->connId != DM_CONN_ID_NONE) && (DmConnRole(pCcb->connId) == role))
{
j++;
}
}
return j;
}
/*************************************************************************************************/
/*!
* \brief App framework handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void AppHandlerInit(wsfHandlerId_t handlerId)
{
appHandlerId = handlerId;
AppDbInit();
}
/*************************************************************************************************/
/*!
* \brief WSF event handler for app framework.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AppHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
APP_TRACE_INFO1("App got evt %d", pMsg->event);
if (pMsg->event >= APP_MASTER_MSG_START)
{
/* pass event to master handler */
(*appCb.masterCback)(pMsg);
}
else if (pMsg->event >= APP_SLAVE_MSG_START)
{
/* pass event to slave handler */
(*appCb.slaveCback)(pMsg);
}
else
{
appProcMsg(pMsg);
}
}
else
{
if (event & APP_BTN_DOWN_EVT)
{
AppUiBtnPressed();
}
}
}
/*************************************************************************************************/
/*!
* \brief Handle a passkey request during pairing. If the passkey is to displayed, a
* random passkey is generated and displayed. If the passkey is to be entered
* the user is prompted to enter the passkey.
*
* \param pAuthReq DM authentication requested event structure.
*
* \return None.
*/
/*************************************************************************************************/
void AppHandlePasskey(dmSecAuthReqIndEvt_t *pAuthReq)
{
uint32_t passkey;
uint8_t buf[SMP_PIN_LEN];
if (pAuthReq->display)
{
/* generate random passkey, limit to 6 digit max */
SecRand((uint8_t *) &passkey, sizeof(uint32_t));
passkey %= 1000000;
/* convert to byte buffer */
buf[0] = UINT32_TO_BYTE0(passkey);
buf[1] = UINT32_TO_BYTE1(passkey);
buf[2] = UINT32_TO_BYTE2(passkey);
/* send authentication response to DM */
DmSecAuthRsp((dmConnId_t) pAuthReq->hdr.param, SMP_PIN_LEN, buf);
/* display passkey */
AppUiDisplayPasskey(passkey);
}
else
{
/* prompt user to enter passkey */
AppUiAction(APP_UI_PASSKEY_PROMPT);
}
}
/*************************************************************************************************/
/*!
* \brief Handle a numeric comparison indication during pairing. The confirmation value is
* displayed and the user is prompted to verify that the local and peer confirmation
* values match.
*
* \param pCnfInd DM confirmation indication event structure.
*
* \return None.
*/
/*************************************************************************************************/
void AppHandleNumericComparison(dmSecCnfIndEvt_t *pCnfInd)
{
uint32_t confirm = DmSecGetCompareValue(pCnfInd->confirm);
/* display confirmation value */
AppUiDisplayConfirmValue(confirm);
/* TODO: Verify that local and peer confirmation values match */
DmSecCompareRsp((dmConnId_t)pCnfInd->hdr.param, TRUE);
}
/*************************************************************************************************/
/*!
* \brief Close the connection with the give connection identifier.
*
* \param connId Connection identifier.
*
* \return None.
*/
/*************************************************************************************************/
void AppConnClose(dmConnId_t connId)
{
DmConnClose(DM_CLIENT_ID_APP, connId, HCI_ERR_REMOTE_TERMINATED);
}
/*************************************************************************************************/
/*!
* \brief Get a list of connection identifiers of open connections.
*
* \param pConnIdList Buffer to hold connection IDs (must be DM_CONN_MAX bytes).
*
* \return Number of open connections.
*
*/
/*************************************************************************************************/
uint8_t AppConnOpenList(dmConnId_t *pConnIdList)
{
appConnCb_t *pCcb = appConnCb;
uint8_t i;
uint8_t pos = 0;
memset(pConnIdList, DM_CONN_ID_NONE, DM_CONN_MAX);
for (i = DM_CONN_MAX; i > 0; i--, pCcb++)
{
if (pCcb->connId != DM_CONN_ID_NONE)
{
pConnIdList[pos++] = pCcb->connId;
}
}
return pos;
}
/*************************************************************************************************/
/*!
* \brief Check if a connection is open.
*
* \return Connection ID of open connection or DM_CONN_ID_NONE if no open connections.
*/
/*************************************************************************************************/
dmConnId_t AppConnIsOpen(void)
{
appConnCb_t *pCcb = appConnCb;
uint8_t i;
for (i = DM_CONN_MAX; i > 0; i--, pCcb++)
{
if (pCcb->connId != DM_CONN_ID_NONE)
{
return pCcb->connId;
}
}
return DM_CONN_ID_NONE;
}
/*************************************************************************************************/
/*!
* \brief Get the device database record handle associated with an open connection.
*
* \param connId Connection identifier.
*
* \return Database record handle or APP_DB_HDL_NONE.
*/
/*************************************************************************************************/
appDbHdl_t AppDbGetHdl(dmConnId_t connId)
{
return appConnCb[connId-1].dbHdl;
}
/*************************************************************************************************/
/*!
* \brief Add device to resolving list.
*
* \param pMsg Pointer to DM callback event message.
* \param connId Connection identifier.
*
* \return None.
*/
/*************************************************************************************************/
void AppAddDevToResList(dmEvt_t *pMsg, dmConnId_t connId)
{
dmSecKey_t *pPeerKey;
appDbHdl_t hdl = appConnCb[connId - 1].dbHdl;
/* if LL Privacy is supported and the peer device has distributed its IRK */
if (HciLlPrivacySupported() && ((pPeerKey = AppDbGetKey(hdl, DM_KEY_IRK, NULL))!= NULL))
{
/* add peer device to resolving list. If all-zero local or peer IRK is used then
LL will only use or accept local or peer identity address respectively. */
DmPrivAddDevToResList(pPeerKey->irk.addrType, pPeerKey->irk.bdAddr, pPeerKey->irk.key,
DmSecGetLocalIrk(), TRUE, pMsg->hdr.param);
}
}
/*************************************************************************************************/
/*!
* \brief Update privacy mode for a given peer device.
*
* \param hdl Database record handle.
*
* \return None.
*/
/*************************************************************************************************/
void AppUpdatePrivacyMode(appDbHdl_t hdl)
{
/* if peer device's been added to resolving list but RPA Only attribute not found on peer device */
if ((hdl != APP_DB_HDL_NONE) && AppDbGetPeerAddedToRl(hdl) && !AppDbGetPeerRpao(hdl))
{
dmSecKey_t *pPeerKey = AppDbGetKey(hdl, DM_KEY_IRK, NULL);
if (pPeerKey != NULL)
{
/* set device privacy mode for this peer device */
DmPrivSetPrivacyMode(pPeerKey->irk.addrType, pPeerKey->irk.bdAddr, DM_PRIV_MODE_DEVICE);
/* make sure resolving list flag cleared */
AppDbSetPeerAddedToRl(hdl, FALSE);
}
}
}
/*************************************************************************************************/
/*!
* \file
*
* \brief Application framework device database example, using simple RAM-based storage.
*
* Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
/* card10:
* copied from: lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/apps/app/common/app_db.c
*
* Reason: we need to implement persistent storage for pairings
*/
#include <string.h>
#include "wsf_types.h"
#include "wsf_assert.h"
#include "util/bda.h"
#include "app_api.h"
#include "app_main.h"
#include "app_db.h"
#include "app_cfg.h"
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! Database record */
typedef struct
{
/*! Common for all roles */
bdAddr_t peerAddr; /*! Peer address */
uint8_t addrType; /*! Peer address type */
dmSecIrk_t peerIrk; /*! Peer IRK */
dmSecCsrk_t peerCsrk; /*! Peer CSRK */
uint8_t keyValidMask; /*! Valid keys in this record */
bool_t inUse; /*! TRUE if record in use */
bool_t valid; /*! TRUE if record is valid */
bool_t peerAddedToRl; /*! TRUE if peer device's been added to resolving list */
bool_t peerRpao; /*! TRUE if RPA Only attribute's present on peer device */
/*! For slave local device */
dmSecLtk_t localLtk; /*! Local LTK */
uint8_t localLtkSecLevel; /*! Local LTK security level */
bool_t peerAddrRes; /*! TRUE if address resolution's supported on peer device (master) */
/*! For master local device */
dmSecLtk_t peerLtk; /*! Peer LTK */
uint8_t peerLtkSecLevel; /*! Peer LTK security level */
/*! for ATT server local device */
uint16_t cccTbl[APP_DB_NUM_CCCD]; /*! Client characteristic configuration descriptors */
uint32_t peerSignCounter; /*! Peer Sign Counter */
/*! for ATT client */
uint16_t hdlList[APP_DB_HDL_LIST_LEN]; /*! Cached handle list */
uint8_t discStatus; /*! Service discovery and configuration status */
} appDbRec_t;
/*! Database type */
typedef struct
{
appDbRec_t rec[APP_DB_NUM_RECS]; /*! Device database records */
char devName[ATT_DEFAULT_PAYLOAD_LEN]; /*! Device name */
uint8_t devNameLen; /*! Device name length */
} appDb_t;
/**************************************************************************************************
Local Variables
**************************************************************************************************/
/*! Database */
static appDb_t appDb;
/*! When all records are allocated use this index to determine which to overwrite */
static appDbRec_t *pAppDbNewRec = appDb.rec;
/*************************************************************************************************/
/*!
* \brief Initialize the device database.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbInit(void)
{
return;
}
/*************************************************************************************************/
/*!
* \brief Create a new device database record.
*
* \param addrType Address type.
* \param pAddr Peer device address.
*
* \return Database record handle.
*/
/*************************************************************************************************/
appDbHdl_t AppDbNewRecord(uint8_t addrType, uint8_t *pAddr)
{
appDbRec_t *pRec = appDb.rec;
uint8_t i;
/* find a free record */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
if (!pRec->inUse)
{
break;
}
}
/* if all records were allocated */
if (i == 0)
{
/* overwrite a record */
pRec = pAppDbNewRec;
/* get next record to overwrite */
pAppDbNewRec++;
if (pAppDbNewRec == &appDb.rec[APP_DB_NUM_RECS])
{
pAppDbNewRec = appDb.rec;
}
}
/* initialize record */
memset(pRec, 0, sizeof(appDbRec_t));
pRec->inUse = TRUE;
pRec->addrType = addrType;
BdaCpy(pRec->peerAddr, pAddr);
pRec->peerAddedToRl = FALSE;
pRec->peerRpao = FALSE;
return (appDbHdl_t) pRec;
}
/*************************************************************************************************/
/*!
* \brief Get the next database record for a given record. For the first record, the function
* should be called with 'hdl' set to 'APP_DB_HDL_NONE'.
*
* \param hdl Database record handle.
*
* \return Next record handle found. APP_DB_HDL_NONE, otherwise.
*/
/*************************************************************************************************/
appDbHdl_t AppDbGetNextRecord(appDbHdl_t hdl)
{
appDbRec_t *pRec;
/* if first record is requested */
if (hdl == APP_DB_HDL_NONE)
{
pRec = appDb.rec;
}
/* if valid record passed in */
else if (AppDbRecordInUse(hdl))
{
pRec = (appDbRec_t *)hdl;
pRec++;
}
/* invalid record passed in */
else
{
return APP_DB_HDL_NONE;
}
/* look for next valid record */
while (pRec < &appDb.rec[APP_DB_NUM_RECS])
{
/* if record is in use */
if (pRec->inUse && pRec->valid)
{
/* record found */
return (appDbHdl_t)pRec;
}
/* look for next record */
pRec++;
}
/* end of records */
return APP_DB_HDL_NONE;
}
/*************************************************************************************************/
/*!
* \brief Delete a new device database record.
*
* \param hdl Database record handle.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbDeleteRecord(appDbHdl_t hdl)
{
((appDbRec_t *) hdl)->inUse = FALSE;
}
/*************************************************************************************************/
/*!
* \brief Validate a new device database record. This function is called when pairing is
* successful and the devices are bonded.
*
* \param hdl Database record handle.
* \param keyMask Bitmask of keys to validate.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbValidateRecord(appDbHdl_t hdl, uint8_t keyMask)
{
((appDbRec_t *) hdl)->valid = TRUE;
((appDbRec_t *) hdl)->keyValidMask = keyMask;
}
/*************************************************************************************************/
/*!
* \brief Check if a record has been validated. If it has not, delete it. This function
* is typically called when the connection is closed.
*
* \param hdl Database record handle.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbCheckValidRecord(appDbHdl_t hdl)
{
if (((appDbRec_t *) hdl)->valid == FALSE)
{
AppDbDeleteRecord(hdl);
}
}
/*************************************************************************************************/
/*!
* \brief Check if a database record is in use.
* \param hdl Database record handle.
*
* \return TURE if record in use. FALSE, otherwise.
*/
/*************************************************************************************************/
bool_t AppDbRecordInUse(appDbHdl_t hdl)
{
appDbRec_t *pRec = appDb.rec;
uint8_t i;
/* see if record is in database record list */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
if (pRec->inUse && pRec->valid && (pRec == ((appDbRec_t *)hdl)))
{
return TRUE;
}
}
return FALSE;
}
/*************************************************************************************************/
/*!
* \brief Check if there is a stored bond with any device.
*
* \param hdl Database record handle.
*
* \return TRUE if a bonded device is found, FALSE otherwise.
*/
/*************************************************************************************************/
bool_t AppDbCheckBonded(void)
{
appDbRec_t *pRec = appDb.rec;
uint8_t i;
/* find a record */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
if (pRec->inUse)
{
return TRUE;
}
}
return FALSE;
}
/*************************************************************************************************/
/*!
* \brief Delete all database records.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbDeleteAllRecords(void)
{
appDbRec_t *pRec = appDb.rec;
uint8_t i;
/* set in use to false for all records */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
pRec->inUse = FALSE;
}
}
/*************************************************************************************************/
/*!
* \brief Find a device database record by peer address.
*
* \param addrType Address type.
* \param pAddr Peer device address.
*
* \return Database record handle or APP_DB_HDL_NONE if not found.
*/
/*************************************************************************************************/
appDbHdl_t AppDbFindByAddr(uint8_t addrType, uint8_t *pAddr)
{
appDbRec_t *pRec = appDb.rec;
uint8_t peerAddrType = DmHostAddrType(addrType);
uint8_t i;
/* find matching record */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
if (pRec->inUse && (pRec->addrType == peerAddrType) && BdaCmp(pRec->peerAddr, pAddr))
{
return (appDbHdl_t) pRec;
}
}
return APP_DB_HDL_NONE;
}
/*************************************************************************************************/
/*!
* \brief Find a device database record by data in an LTK request.
*
* \param encDiversifier Encryption diversifier associated with key.
* \param pRandNum Pointer to random number associated with key.
*
* \return Database record handle or APP_DB_HDL_NONE if not found.
*/
/*************************************************************************************************/
appDbHdl_t AppDbFindByLtkReq(uint16_t encDiversifier, uint8_t *pRandNum)
{
appDbRec_t *pRec = appDb.rec;
uint8_t i;
/* find matching record */
for (i = APP_DB_NUM_RECS; i > 0; i--, pRec++)
{
if (pRec->inUse && (pRec->localLtk.ediv == encDiversifier) &&
(memcmp(pRec->localLtk.rand, pRandNum, SMP_RAND8_LEN) == 0))
{
return (appDbHdl_t) pRec;
}
}
return APP_DB_HDL_NONE;
}
/*************************************************************************************************/
/*!
* \brief Get a key from a device database record.
*
* \param hdl Database record handle.
* \param type Type of key to get.
* \param pSecLevel If the key is valid, the security level of the key.
*
* \return Pointer to key if key is valid or NULL if not valid.
*/
/*************************************************************************************************/
dmSecKey_t *AppDbGetKey(appDbHdl_t hdl, uint8_t type, uint8_t *pSecLevel)
{
dmSecKey_t *pKey = NULL;
/* if key valid */
if ((type & ((appDbRec_t *) hdl)->keyValidMask) != 0)
{
switch(type)
{
case DM_KEY_LOCAL_LTK:
*pSecLevel = ((appDbRec_t *) hdl)->localLtkSecLevel;
pKey = (dmSecKey_t *) &((appDbRec_t *) hdl)->localLtk;
break;
case DM_KEY_PEER_LTK:
*pSecLevel = ((appDbRec_t *) hdl)->peerLtkSecLevel;
pKey = (dmSecKey_t *) &((appDbRec_t *) hdl)->peerLtk;
break;
case DM_KEY_IRK:
pKey = (dmSecKey_t *)&((appDbRec_t *)hdl)->peerIrk;
break;
case DM_KEY_CSRK:
pKey = (dmSecKey_t *)&((appDbRec_t *)hdl)->peerCsrk;
break;
default:
break;
}
}
return pKey;
}
/*************************************************************************************************/
/*!
* \brief Set a key in a device database record.
*
* \param hdl Database record handle.
* \param pKey Key data.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetKey(appDbHdl_t hdl, dmSecKeyIndEvt_t *pKey)
{
switch(pKey->type)
{
case DM_KEY_LOCAL_LTK:
((appDbRec_t *) hdl)->localLtkSecLevel = pKey->secLevel;
((appDbRec_t *) hdl)->localLtk = pKey->keyData.ltk;
break;
case DM_KEY_PEER_LTK:
((appDbRec_t *) hdl)->peerLtkSecLevel = pKey->secLevel;
((appDbRec_t *) hdl)->peerLtk = pKey->keyData.ltk;
break;
case DM_KEY_IRK:
((appDbRec_t *)hdl)->peerIrk = pKey->keyData.irk;
/* make sure peer record is stored using its identity address */
((appDbRec_t *)hdl)->addrType = pKey->keyData.irk.addrType;
BdaCpy(((appDbRec_t *)hdl)->peerAddr, pKey->keyData.irk.bdAddr);
break;
case DM_KEY_CSRK:
((appDbRec_t *)hdl)->peerCsrk = pKey->keyData.csrk;
/* sign counter must be initialized to zero when CSRK is generated */
((appDbRec_t *)hdl)->peerSignCounter = 0;
break;
default:
break;
}
}
/*************************************************************************************************/
/*!
* \brief Get the client characteristic configuration descriptor table.
*
* \param hdl Database record handle.
*
* \return Pointer to client characteristic configuration descriptor table.
*/
/*************************************************************************************************/
uint16_t *AppDbGetCccTbl(appDbHdl_t hdl)
{
return ((appDbRec_t *) hdl)->cccTbl;
}
/*************************************************************************************************/
/*!
* \brief Set a value in the client characteristic configuration table.
*
* \param hdl Database record handle.
* \param idx Table index.
* \param value client characteristic configuration value.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetCccTblValue(appDbHdl_t hdl, uint16_t idx, uint16_t value)
{
WSF_ASSERT(idx < APP_DB_NUM_CCCD);
((appDbRec_t *) hdl)->cccTbl[idx] = value;
}
/*************************************************************************************************/
/*!
* \brief Get the discovery status.
*
* \param hdl Database record handle.
*
* \return Discovery status.
*/
/*************************************************************************************************/
uint8_t AppDbGetDiscStatus(appDbHdl_t hdl)
{
return ((appDbRec_t *) hdl)->discStatus;
}
/*************************************************************************************************/
/*!
* \brief Set the discovery status.
*
* \param hdl Database record handle.
* \param state Discovery status.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetDiscStatus(appDbHdl_t hdl, uint8_t status)
{
((appDbRec_t *) hdl)->discStatus = status;
}
/*************************************************************************************************/
/*!
* \brief Get the cached handle list.
*
* \param hdl Database record handle.
*
* \return Pointer to handle list.
*/
/*************************************************************************************************/
uint16_t *AppDbGetHdlList(appDbHdl_t hdl)
{
return ((appDbRec_t *) hdl)->hdlList;
}
/*************************************************************************************************/
/*!
* \brief Set the cached handle list.
*
* \param hdl Database record handle.
* \param pHdlList Pointer to handle list.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetHdlList(appDbHdl_t hdl, uint16_t *pHdlList)
{
memcpy(((appDbRec_t *) hdl)->hdlList, pHdlList, sizeof(((appDbRec_t *) hdl)->hdlList));
}
/*************************************************************************************************/
/*!
* \brief Get the device name.
*
* \param pLen Returned device name length.
*
* \return Pointer to UTF-8 string containing device name or NULL if not set.
*/
/*************************************************************************************************/
char *AppDbGetDevName(uint8_t *pLen)
{
/* if first character of name is NULL assume it is uninitialized */
if (appDb.devName[0] == 0)
{
*pLen = 0;
return NULL;
}
else
{
*pLen = appDb.devNameLen;
return appDb.devName;
}
}
/*************************************************************************************************/
/*!
* \brief Set the device name.
*
* \param len Device name length.
* \param pStr UTF-8 string containing device name.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetDevName(uint8_t len, char *pStr)
{
/* check for maximum device length */
len = (len <= sizeof(appDb.devName)) ? len : sizeof(appDb.devName);
memcpy(appDb.devName, pStr, len);
}
/*************************************************************************************************/
/*!
* \brief Get address resolution attribute value read from a peer device.
*
* \param hdl Database record handle.
*
* \return TRUE if address resolution is supported in peer device. FALSE, otherwise.
*/
/*************************************************************************************************/
bool_t AppDbGetPeerAddrRes(appDbHdl_t hdl)
{
return ((appDbRec_t *)hdl)->peerAddrRes;
}
/*************************************************************************************************/
/*!
* \brief Set address resolution attribute value for a peer device.
*
* \param hdl Database record handle.
* \param addrRes Address resolution attribue value.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetPeerAddrRes(appDbHdl_t hdl, uint8_t addrRes)
{
((appDbRec_t *)hdl)->peerAddrRes = addrRes;
}
/*************************************************************************************************/
/*!
* \brief Get sign counter for a peer device.
*
* \param hdl Database record handle.
*
* \return Sign counter for peer device.
*/
/*************************************************************************************************/
uint32_t AppDbGetPeerSignCounter(appDbHdl_t hdl)
{
return ((appDbRec_t *)hdl)->peerSignCounter;
}
/*************************************************************************************************/
/*!
* \brief Set sign counter for a peer device.
*
* \param hdl Database record handle.
* \param signCounter Sign counter for peer device.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetPeerSignCounter(appDbHdl_t hdl, uint32_t signCounter)
{
((appDbRec_t *)hdl)->peerSignCounter = signCounter;
}
/*************************************************************************************************/
/*!
* \brief Get the peer device added to resolving list flag value.
*
* \param hdl Database record handle.
*
* \return TRUE if peer device's been added to resolving list. FALSE, otherwise.
*/
/*************************************************************************************************/
bool_t AppDbGetPeerAddedToRl(appDbHdl_t hdl)
{
return ((appDbRec_t *)hdl)->peerAddedToRl;
}
/*************************************************************************************************/
/*!
* \brief Set the peer device added to resolving list flag to a given value.
*
* \param hdl Database record handle.
* \param peerAddedToRl Peer device added to resolving list flag value.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetPeerAddedToRl(appDbHdl_t hdl, bool_t peerAddedToRl)
{
((appDbRec_t *)hdl)->peerAddedToRl = peerAddedToRl;
}
/*************************************************************************************************/
/*!
* \brief Get the resolvable private address only attribute flag for a given peer device.
*
* \param hdl Database record handle.
*
* \return TRUE if RPA Only attribute is present on peer device. FALSE, otherwise.
*/
/*************************************************************************************************/
bool_t AppDbGetPeerRpao(appDbHdl_t hdl)
{
return ((appDbRec_t *)hdl)->peerRpao;
}
/*************************************************************************************************/
/*!
* \brief Set the resolvable private address only attribute flag for a given peer device.
*
* \param hdl Database record handle.
* \param peerRpao Resolvable private address only attribute flag value.
*
* \return None.
*/
/*************************************************************************************************/
void AppDbSetPeerRpao(appDbHdl_t hdl, bool_t peerRpao)
{
((appDbRec_t *)hdl)->peerRpao = peerRpao;
}
/*************************************************************************************************/
/*!
* \file
*
* \brief Application framework user interface.
*
* Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#include "wsf_types.h"
#include "wsf_os.h"
#include "wsf_trace.h"
#include "app_ui.h"
/* card10:
* copied from: lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/apps/app/common/app_ui.c
*
* Reason: has several user interactions which we likley have to implement
*/
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! \brief Callback struct */
appUiCback_t appUiCbackTbl;
/*************************************************************************************************/
/*!
* \brief Perform a user interface action based on the event value passed to the function.
*
* \param event User interface event value.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiAction(uint8_t event)
{
switch (event)
{
case APP_UI_NONE:
/* no action */
break;
case APP_UI_RESET_CMPL:
APP_TRACE_INFO0(">>> Reset complete <<<");
break;
case APP_UI_ADV_START:
APP_TRACE_INFO0(">>> Advertising started <<<");
break;
case APP_UI_ADV_STOP:
APP_TRACE_INFO0(">>> Advertising stopped <<<");
break;
case APP_UI_SCAN_START:
APP_TRACE_INFO0(">>> Scanning started <<<");
break;
case APP_UI_SCAN_STOP:
APP_TRACE_INFO0(">>> Scanning stopped <<<");
break;
case APP_UI_SCAN_REPORT:
APP_TRACE_INFO0(">>> Scan data received from peer <<<");
break;
case APP_UI_CONN_OPEN:
APP_TRACE_INFO0(">>> Connection opened <<<");
break;
case APP_UI_CONN_CLOSE:
APP_TRACE_INFO0(">>> Connection closed <<<");
break;
case APP_UI_SEC_PAIR_CMPL:
APP_TRACE_INFO0(">>> Pairing completed successfully <<<");
break;
case APP_UI_SEC_PAIR_FAIL:
APP_TRACE_INFO0(">>> Pairing failed <<<");
break;
case APP_UI_SEC_ENCRYPT:
APP_TRACE_INFO0(">>> Connection encrypted <<<");
break;
case APP_UI_SEC_ENCRYPT_FAIL:
APP_TRACE_INFO0(">>> Encryption failed <<<");
break;
case APP_UI_PASSKEY_PROMPT:
APP_TRACE_INFO0(">>> Prompt user to enter passkey <<<");
break;
case APP_UI_ALERT_CANCEL:
APP_TRACE_INFO0(">>> Cancel a low or high alert <<<");
break;
case APP_UI_ALERT_LOW:
APP_TRACE_INFO0(">>> Low alert <<<");
break;
case APP_UI_ALERT_HIGH:
APP_TRACE_INFO0(">>> High alert <<<");
break;
case APP_UI_ADV_SET_START_IND:
APP_TRACE_INFO0(">>> Advertising set(s) started <<<");
break;
case APP_UI_ADV_SET_STOP_IND:
APP_TRACE_INFO0(">>> Advertising set(s) stopped <<<");
break;
case APP_UI_SCAN_REQ_RCVD_IND:
APP_TRACE_INFO0(">>> Scan request received <<<");
break;
case APP_UI_EXT_SCAN_START_IND:
APP_TRACE_INFO0(">>> Extended scanning started <<<");
break;
case APP_UI_EXT_SCAN_STOP_IND:
APP_TRACE_INFO0(">>> Extended scanning stopped <<<");
break;
case APP_UI_PER_ADV_SET_START_IND:
APP_TRACE_INFO0(">>> Periodic advertising set started <<<");
break;
case APP_UI_PER_ADV_SET_STOP_IND:
APP_TRACE_INFO0(">>> Periodic advertising set stopped <<<");
break;
case APP_UI_PER_ADV_SYNC_EST_IND:
APP_TRACE_INFO0(">>> Periodic advertising sync established <<<");
break;
case APP_UI_PER_ADV_SYNC_LOST_IND:
APP_TRACE_INFO0(">>> Periodic advertising sync lost <<<");
break;
default:
break;
}
if (appUiCbackTbl.actionCback)
{
(*appUiCbackTbl.actionCback)(event);
}
}
/*************************************************************************************************/
/*!
* \brief Display a passkey.
*
* \param passkey Passkey to display.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiDisplayPasskey(uint32_t passkey)
{
APP_TRACE_INFO1(">>> Passkey: %d <<<", passkey);
}
/*************************************************************************************************/
/*!
* \brief Display a confirmation value.
*
* \param confirm Confirm value to display.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiDisplayConfirmValue(uint32_t confirm)
{
APP_TRACE_INFO1(">>> Confirm Value: %d <<<", confirm);
}
/*************************************************************************************************/
/*!
* \brief Display an RSSI value.
*
* \param rssi Rssi value to display.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiDisplayRssi(int8_t rssi)
{
APP_TRACE_INFO1(">>> RSSI: %d dBm<<<", rssi);
}
/*************************************************************************************************/
/*!
* \brief Handle a UI timer expiration event.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
void appUiTimerExpired(wsfMsgHdr_t *pMsg)
{
}
/*************************************************************************************************/
/*!
* \brief Perform button press polling. This function is called to handle WSF
* message APP_BTN_POLL_IND.
*
* \return None.
*/
/*************************************************************************************************/
void appUiBtnPoll(void)
{
if (appUiCbackTbl.btnPollCback)
{
(*appUiCbackTbl.btnPollCback)();
}
}
/*************************************************************************************************/
/*!
* \brief Handle a hardware button press. This function is called to handle WSF
* event APP_BTN_DOWN_EVT.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiBtnPressed(void)
{
}
/*************************************************************************************************/
/*!
* \brief Register a callback function to receive application button press events.
*
* \return None.
*
* \note Registered by application to receive button events
*/
/*************************************************************************************************/
void AppUiBtnRegister(appUiBtnCback_t btnCback)
{
appUiCbackTbl.btnCback = btnCback;
}
/*************************************************************************************************/
/*!
* \brief Register a callback function to receive action events.
*
* \return None.
*
* \note Registered by platform
*/
/*************************************************************************************************/
void AppUiActionRegister(appUiActionCback_t actionCback)
{
appUiCbackTbl.actionCback = actionCback;
}
/*************************************************************************************************/
/*!
* \brief Register a callback function to receive APP_BTN_POLL_IND events.
*
* \return None.
*
* \note Registered by platform
*/
/*************************************************************************************************/
void AppUiBtnPollRegister(appUiBtnPollCback_t btnPollCback)
{
appUiCbackTbl.btnPollCback = btnPollCback;
}
/*************************************************************************************************/
/*!
* \brief Play a sound.
*
* \param pSound Pointer to sound tone/duration array.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiSoundPlay(const appUiSound_t *pSound)
{
}
/*************************************************************************************************/
/*!
* \brief Stop the sound that is currently playing.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiSoundStop(void)
{
}
/*************************************************************************************************/
/*!
* \brief Button test function-- for test purposes only.
*
* \return None.
*/
/*************************************************************************************************/
void AppUiBtnTest(uint8_t btn)
{
if (appUiCbackTbl.btnCback)
{
(*appUiCbackTbl.btnCback)(btn);
}
}
...@@ -3,5 +3,8 @@ ble_sources = files( ...@@ -3,5 +3,8 @@ ble_sources = files(
'stack.c', 'stack.c',
'ble_main.c', 'ble_main.c',
'svc_dis.c', 'svc_dis.c',
'svc_core.c' 'svc_core.c',
'app/app_main.c',
'app/common/app_db.c',
'app/common/app_ui.c'
) )
...@@ -59,11 +59,11 @@ sources = files( ...@@ -59,11 +59,11 @@ sources = files(
'stack/ble-profiles/sources/apps/app/app_master_ae.c', 'stack/ble-profiles/sources/apps/app/app_master_ae.c',
'stack/ble-profiles/sources/apps/app/app_slave_leg.c', 'stack/ble-profiles/sources/apps/app/app_slave_leg.c',
'stack/ble-profiles/sources/apps/app/app_slave_ae.c', 'stack/ble-profiles/sources/apps/app/app_slave_ae.c',
'stack/ble-profiles/sources/apps/app/app_main.c', #'stack/ble-profiles/sources/apps/app/app_main.c',
'stack/ble-profiles/sources/apps/app/app_server.c', 'stack/ble-profiles/sources/apps/app/app_server.c',
'stack/ble-profiles/sources/apps/app/app_master_leg.c', 'stack/ble-profiles/sources/apps/app/app_master_leg.c',
'stack/ble-profiles/sources/apps/app/common/app_db.c', #'stack/ble-profiles/sources/apps/app/common/app_db.c',
'stack/ble-profiles/sources/apps/app/common/app_ui.c', #'stack/ble-profiles/sources/apps/app/common/app_ui.c',
'stack/ble-profiles/sources/apps/app/common/app_hw.c', 'stack/ble-profiles/sources/apps/app/common/app_hw.c',
'stack/ble-profiles/sources/apps/app/app_terminal.c', 'stack/ble-profiles/sources/apps/app/app_terminal.c',
'stack/ble-profiles/sources/apps/wdxs/wdxs_oad.c', 'stack/ble-profiles/sources/apps/wdxs/wdxs_oad.c',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment