initial commit

This commit is contained in:
2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions
@@ -0,0 +1,138 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief Battery service server.
*
* Copyright (c) 2012-2018 Arm Ltd.
*
* Copyright (c) 2019 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
#ifndef BAS_API_H
#define BAS_API_H
#include "wsf_timer.h"
#include "att_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/*! \addtogroup BATTERY_PROFILE
* \{ */
/**************************************************************************************************
Data Types
**************************************************************************************************/
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*! \brief Battery service configurable parameters */
typedef struct
{
wsfTimerTicks_t period; /*!< \brief Battery measurement timer expiration period in seconds */
uint16_t count; /*!< \brief Perform battery measurement after this many timer periods */
uint8_t threshold; /*!< \brief Send battery level notification to peer when below this level. */
} basCfg_t;
/*************************************************************************************************/
/*!
* \brief Initialize the battery service server.
*
* \param handlerId WSF handler ID of the application using this service.
* \param pCfg Battery service configurable parameters.
*
* \return None.
*/
/*************************************************************************************************/
void BasInit(wsfHandlerId_t handlerId, basCfg_t *pCfg);
/*************************************************************************************************/
/*!
* \brief Start periodic battery level measurement. This function starts a timer to perform
* periodic battery measurements.
*
* \param connId DM connection identifier.
* \param timerEvt WSF event designated by the application for the timer.
* \param battCccIdx Index of battery level CCC descriptor in CCC descriptor handle table.
*
* \return None.
*/
/*************************************************************************************************/
void BasMeasBattStart(dmConnId_t connId, uint8_t timerEvt, uint8_t battCccIdx);
/*************************************************************************************************/
/*!
* \brief Stop periodic battery level measurement.
*
* \param connId DM connection identifier.
*
* \return None.
*/
/*************************************************************************************************/
void BasMeasBattStop(dmConnId_t connId);
/*************************************************************************************************/
/*!
* \brief Process received WSF message.
*
* \param pMsg Event message.
*
* \return None.
*/
/*************************************************************************************************/
void BasProcMsg(wsfMsgHdr_t *pMsg);
/*************************************************************************************************/
/*!
* \brief Send the battery level to the peer device.
*
* \param connId DM connection identifier.
* \param idx Index of battery level CCC descriptor in CCC descriptor handle table.
* \param level The battery level.
*
* \return None.
*/
/*************************************************************************************************/
void BasSendBattLevel(dmConnId_t connId, uint8_t idx, uint8_t level);
/*************************************************************************************************/
/*!
* \brief ATTS read callback for battery service used to read the battery level. Use this
* function as a parameter to SvcBattCbackRegister().
*
* \param connId DM connection identifier.
* \param handle ATT handle.
* \param operation ATT operation.
* \param offset read offset.
* \param pAttr pointer to Attribute
*
* \return ATT status.
*/
/*************************************************************************************************/
uint8_t BasReadCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
uint16_t offset, attsAttr_t *pAttr);
/*! \} */ /* BATTERY_PROFILE */
#ifdef __cplusplus
};
#endif
#endif /* BAS_API_H */
@@ -0,0 +1,368 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief Battery service server.
*
* Copyright (c) 2012-2018 Arm Ltd.
*
* Copyright (c) 2019 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*************************************************************************************************/
#include <string.h>
#include "wsf_types.h"
#include "wsf_assert.h"
#include "wsf_trace.h"
#include "util/bstream.h"
#include "att_api.h"
#include "svc_ch.h"
#include "svc_batt.h"
#include "app_api.h"
#include "app_hw.h"
#include "bas_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! \brief battery level initialization value */
#define BAS_BATT_LEVEL_INIT 0xFF
/**************************************************************************************************
Local Variables
**************************************************************************************************/
/*! \brief Connection control block */
typedef struct
{
dmConnId_t connId; /*! \brief Connection ID */
bool_t battToSend; /*! \brief battery measurement ready to be sent on this channel */
uint8_t sentBattLevel; /*! \brief value of last sent battery level */
} basConn_t;
/*! \brief Control block */
static struct
{
basConn_t conn[DM_CONN_MAX]; /*! \brief connection control block */
wsfTimer_t measTimer; /*! \brief periodic measurement timer */
basCfg_t cfg; /*! \brief configurable parameters */
uint16_t currCount; /*! \brief current measurement period count */
bool_t txReady; /*! \brief TRUE if ready to send notifications */
uint8_t measBattLevel; /*! \brief value of last measured battery level */
} basCb;
/*************************************************************************************************/
/*!
* \brief Return TRUE if no connections with active measurements.
*
* \return TRUE if no connections active.
*/
/*************************************************************************************************/
static bool_t basNoConnActive(void)
{
basConn_t *pConn = basCb.conn;
uint8_t i;
for (i = 0; i < DM_CONN_MAX; i++, pConn++)
{
if (pConn->connId != DM_CONN_ID_NONE)
{
return FALSE;
}
}
return TRUE;
}
/*************************************************************************************************/
/*!
* \brief Setup to send measurements on active connections.
*
* \return None.
*/
/*************************************************************************************************/
static void basSetupToSend(void)
{
basConn_t *pConn = basCb.conn;
uint8_t i;
for (i = 0; i < DM_CONN_MAX; i++, pConn++)
{
if (pConn->connId != DM_CONN_ID_NONE)
{
pConn->battToSend = TRUE;
}
}
}
/*************************************************************************************************/
/*!
* \brief Find next connection with measurement to send.
*
* \param cccIdx Battery measurement CCC descriptor index.
*
* \return Connection control block.
*/
/*************************************************************************************************/
static basConn_t *basFindNextToSend(uint8_t cccIdx)
{
basConn_t *pConn = basCb.conn;
uint8_t i;
for (i = 0; i < DM_CONN_MAX; i++, pConn++)
{
if (pConn->connId != DM_CONN_ID_NONE && pConn->battToSend &&
pConn->sentBattLevel != basCb.measBattLevel)
{
if (AttsCccEnabled(pConn->connId, cccIdx))
{
return pConn;
}
}
}
return NULL;
}
/*************************************************************************************************/
/*!
* \brief Send periodic battery measurement.
*
* \param pConn Connection control block.
*
* \return None.
*/
/*************************************************************************************************/
static void basSendPeriodicBattlevel(basConn_t *pConn)
{
BasSendBattLevel(pConn->connId, basCb.measTimer.msg.status, basCb.measBattLevel);
pConn->sentBattLevel = basCb.measBattLevel;
pConn->battToSend = FALSE;
basCb.txReady = FALSE;
}
/*************************************************************************************************/
/*!
* \brief Handle connection open.
*
* \param pMsg Event message.
*
* \return None.
*/
/*************************************************************************************************/
static void basConnOpen(dmEvt_t *pMsg)
{
basCb.txReady = TRUE;
}
/*************************************************************************************************/
/*!
* \brief Handle a received ATT handle value confirm.
*
* \param pMsg Event message.
*
* \return None.
*/
/*************************************************************************************************/
static void basHandleValueCnf(attEvt_t *pMsg)
{
basConn_t *pConn;
if (pMsg->hdr.status == ATT_SUCCESS && pMsg->handle == BATT_LVL_HDL)
{
basCb.txReady = TRUE;
/* find next connection to send (note ccc idx is stored in timer status) */
if ((pConn = basFindNextToSend(basCb.measTimer.msg.status)) != NULL)
{
basSendPeriodicBattlevel(pConn);
}
}
}
/*************************************************************************************************/
/*!
* \brief This function is called by the application when the periodic measurement
* timer expires.
*
* \param pMsg Event message.
*
* \return None.
*/
/*************************************************************************************************/
void basMeasTimerExp(wsfMsgHdr_t *pMsg)
{
basConn_t *pConn;
/* if there are active connections */
if (basNoConnActive() == FALSE)
{
if (--basCb.currCount == 0)
{
/* reset count */
basCb.currCount = basCb.cfg.count;
/* set up battery measurement to be sent on all connections */
basSetupToSend();
/* read battery measurement sensor data */
AppHwBattRead(&basCb.measBattLevel);
/* if ready to send measurements */
if (basCb.txReady)
{
/* find next connection to send (note ccc idx is stored in timer status) */
if ((pConn = basFindNextToSend(pMsg->status)) != NULL)
{
basSendPeriodicBattlevel(pConn);
}
}
}
/* restart timer */
WsfTimerStartSec(&basCb.measTimer, basCb.cfg.period);
}
}
/*************************************************************************************************/
/*!
* \brief Initialize the battery service server.
*
* \param handerId WSF handler ID of the application using this service.
* \param pCfg Battery service configurable parameters.
*
* \return None.
*/
/*************************************************************************************************/
void BasInit(wsfHandlerId_t handlerId, basCfg_t *pCfg)
{
basCb.measTimer.handlerId = handlerId;
basCb.cfg = *pCfg;
}
/*************************************************************************************************/
/*!
* \brief Start periodic battery level measurement. This function starts a timer to perform
* periodic battery measurements.
*
* \param connId DM connection identifier.
* \param timerEvt WSF event designated by the application for the timer.
* \param battCccIdx Index of battery level CCC descriptor in CCC descriptor handle table.
*
* \return None.
*/
/*************************************************************************************************/
void BasMeasBattStart(dmConnId_t connId, uint8_t timerEvt, uint8_t battCccIdx)
{
/* if this is first connection */
if (basNoConnActive())
{
/* initialize control block */
basCb.measTimer.msg.event = timerEvt;
basCb.measTimer.msg.status = battCccIdx;
basCb.measBattLevel = BAS_BATT_LEVEL_INIT;
basCb.currCount = basCb.cfg.count;
/* start timer */
WsfTimerStartSec(&basCb.measTimer, basCb.cfg.period);
}
/* set conn id and last sent battery level */
basCb.conn[connId - 1].connId = connId;
basCb.conn[connId - 1].sentBattLevel = BAS_BATT_LEVEL_INIT;
}
/*************************************************************************************************/
/*!
* \brief Stop periodic battery level measurement.
*
* \param connId DM connection identifier.
*
* \return None.
*/
/*************************************************************************************************/
void BasMeasBattStop(dmConnId_t connId)
{
/* clear connection */
basCb.conn[connId - 1].connId = DM_CONN_ID_NONE;
basCb.conn[connId - 1].battToSend = FALSE;
/* if no remaining connections */
if (basNoConnActive())
{
/* stop timer */
WsfTimerStop(&basCb.measTimer);
}
}
/*************************************************************************************************/
/*!
* \brief Process received WSF message.
*
* \param pMsg Event message.
*
* \return None.
*/
/*************************************************************************************************/
void BasProcMsg(wsfMsgHdr_t *pMsg)
{
if (pMsg->event == DM_CONN_OPEN_IND)
{
basConnOpen((dmEvt_t *) pMsg);
}
else if (pMsg->event == ATTS_HANDLE_VALUE_CNF)
{
basHandleValueCnf((attEvt_t *) pMsg);
}
else if (pMsg->event == basCb.measTimer.msg.event)
{
basMeasTimerExp(pMsg);
}
}
/*************************************************************************************************/
/*!
* \brief Send the battery level to the peer device.
*
* \param connId DM connection identifier.
* \param idx Index of battery level CCC descriptor in CCC descriptor handle table.
* \param level The battery level.
*
* \return None.
*/
/*************************************************************************************************/
void BasSendBattLevel(dmConnId_t connId, uint8_t idx, uint8_t level)
{
if (AttsCccEnabled(connId, idx))
{
AttsHandleValueNtf(connId, BATT_LVL_HDL, CH_BATT_LEVEL_LEN, &level);
}
}
/*************************************************************************************************/
/*!
* \brief ATTS read callback for battery service used to read the battery level. Use this
* function as a parameter to SvcBattCbackRegister().
*
* \return ATT status.
*/
/*************************************************************************************************/
uint8_t BasReadCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
uint16_t offset, attsAttr_t *pAttr)
{
/* read the battery level and set attribute value */
AppHwBattRead(pAttr->pValue);
return ATT_SUCCESS;
}