initial commit
This commit is contained in:
Vendored
+138
@@ -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 */
|
||||
Vendored
+368
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user