initial commit
This commit is contained in:
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Asset Tracking profile server.
|
||||
*
|
||||
* Copyright (c) 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 ATPS_API_H
|
||||
#define ATPS_API_H
|
||||
|
||||
#include "att_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \addtogroup ASSET_TRACKING_PROFILE_SERVER
|
||||
* \{ */
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Asset Tracking Profile server initialization.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsInit(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the antenna identifiers for a connection ID.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param numAntenna Number of antenna and len of pAntennaIds in bytes.
|
||||
* \param pAntennaIds Array containing identifiers of antenna for this connection.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsSetAntennaIds(dmConnId_t connId, uint8_t numAntenna, uint8_t *pAntennaIds);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called by application to notify the Asset Tracking Profile server of DM Events.
|
||||
*
|
||||
* \param pEvt Pointer to the DM Event.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsProcDmMsg(dmEvt_t *pEvt);
|
||||
|
||||
/*! \} */ /* ASSET_TRACKING_PROFILE_SERVER */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* ATPS_API_H */
|
||||
Vendored
+430
@@ -0,0 +1,430 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Asset Tracking profile server.
|
||||
*
|
||||
* Copyright (c) 2018-2019 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 "hci_defs.h"
|
||||
#include "app_api.h"
|
||||
#include "atps_api.h"
|
||||
#include "svc_cte.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Asset tracking profile connection states. */
|
||||
#define ATPS_STATE_ACL_DISABLED 0
|
||||
#define ATPS_STATE_ACL_STARTING 1
|
||||
#define ATPS_STATE_ACL_ENABLED 2
|
||||
#define ATPS_STATE_ACL_STOPPING 3
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Asset Tracking Profile Server connection control block. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state; /*! Connection state. */
|
||||
uint8_t enableBits; /*! Constant Tone Extension enable. */
|
||||
uint8_t minLen; /*! Constant Tone Extension minimum length. */
|
||||
uint8_t minTxCount; /*! Constant Tone Extension minimum transmit count. */
|
||||
uint8_t duration; /*! Constant Tone Extension transmit duration. */
|
||||
uint16_t interval; /*! Constant Tone Extension interval. */
|
||||
uint8_t phyType; /*! Constant Tone Extension PHY type. */
|
||||
bool_t numAntenna; /*! Number of antenna and len of pAntennaIds in bytes. */
|
||||
uint8_t *pAntennaIds; /*! Array containing identifiers of antenna for this connection. */
|
||||
} atpsConnCb_t;
|
||||
|
||||
/*! Asset Tracking Profile Server control block. */
|
||||
typedef struct
|
||||
{
|
||||
atpsConnCb_t connCb[DM_CONN_MAX]; /*! Connection control block. */
|
||||
uint8_t switchSampleRates; /*! Supported Switching Sampling Rates. */
|
||||
uint8_t switchPatternMaxLen; /*! Max Length of Switching Pattern. */
|
||||
uint8_t numAntennae; /*! Number of Antennae. */
|
||||
uint8_t cteMaxLen; /*! Max CTE Length. */
|
||||
} atpsCb_t;
|
||||
|
||||
static atpsCb_t atpsCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write enable attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param enableBits Enable bitfield value from client.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetEnable(dmConnId_t connId, uint8_t enableBits)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
bool_t enableAcl = !!(enableBits & CTE_ENABLE_ACL_BIT);
|
||||
|
||||
if (enableBits & CTE_ENABLE_ADV_BIT)
|
||||
{
|
||||
/* Connectionless advertising CTE not supported. */
|
||||
return ATT_ERR_WRITE_REJ;
|
||||
}
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
|
||||
if (enableAcl)
|
||||
{
|
||||
if (pCcb->state == ATPS_STATE_ACL_DISABLED)
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_STARTING;
|
||||
DmConnCteTxConfig(connId, HCI_CTE_TYPE_PERMIT_AOA_RSP_BIT, pCcb->numAntenna, pCcb->pAntennaIds);
|
||||
|
||||
/* Delay write response */
|
||||
return ATT_RSP_PENDING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pCcb->state == ATPS_STATE_ACL_ENABLED)
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_STOPPING;
|
||||
DmConnCteRspStop(connId);
|
||||
|
||||
/* Delay write response */
|
||||
return ATT_RSP_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write minimum length attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param minLen Minimum length value.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetMinLen(dmConnId_t connId, uint8_t minLen)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
if ((minLen < CTE_MIN_MIN_LEN) || (minLen > CTE_MAX_MIN_LEN) || (minLen > atpsCb.cteMaxLen))
|
||||
{
|
||||
return ATT_ERR_RANGE;
|
||||
}
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->minLen = minLen;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write advertising minimum tx count attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param minLen Minimum tx count value.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetAdvMinTxCnt(dmConnId_t connId, uint8_t minTxCount)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
if ((minTxCount < CTE_MIN_MIN_TX_CNT) || (minTxCount > CTE_MAX_MIN_TX_CNT))
|
||||
{
|
||||
return ATT_ERR_RANGE;
|
||||
}
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->minTxCount = minTxCount;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write advertising minimum tx duration attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param duration Minimum tx count value.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetAdvTxDuration(dmConnId_t connId, uint8_t duration)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->duration = duration;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write advertising intergval attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param interval Interval value.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetAdvInterval(dmConnId_t connId, uint8_t interval)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
if (interval < CTE_MIN_INTERVAL)
|
||||
{
|
||||
return ATT_ERR_RANGE;
|
||||
}
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->interval = interval;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process write advertising PHY attribute from locator.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param phyType PHY type.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteSetAdvPhy(dmConnId_t connId, uint8_t phyType)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
|
||||
if (phyType > CTE_PHY_2M)
|
||||
{
|
||||
return ATT_ERR_RANGE;
|
||||
}
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->phyType = phyType;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief ATTS write callback for Continuous Tone Extension, CTE, service.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t atpsCteWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
/* Only individual write requests with response are supported. */
|
||||
if (operation != ATT_PDU_WRITE_REQ)
|
||||
{
|
||||
return ATT_ERR_NOT_SUP;
|
||||
}
|
||||
|
||||
switch (handle)
|
||||
{
|
||||
case CTE_ENABLE_HDL:
|
||||
status = atpsCteSetEnable(connId, *pValue);
|
||||
break;
|
||||
|
||||
case CTE_MIN_LEN_HDL:
|
||||
status = atpsCteSetMinLen(connId, *pValue);
|
||||
break;
|
||||
|
||||
case CTE_ADV_MIN_TX_CNT_HDL:
|
||||
status = atpsCteSetAdvMinTxCnt(connId, *pValue);
|
||||
break;
|
||||
|
||||
case CTE_ADV_TX_DURATION_HDL:
|
||||
status = atpsCteSetAdvTxDuration(connId, *pValue);
|
||||
break;
|
||||
|
||||
case CTE_ADV_INTERVAL_HDL:
|
||||
status = atpsCteSetAdvInterval(connId, *pValue);
|
||||
break;
|
||||
|
||||
case CTE_ADV_EXT_PHY_HDL:
|
||||
status = atpsCteSetAdvPhy(connId, *pValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = ATT_ERR_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the antenna identifiers for a connection ID.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param numAntenna Number of antenna and len of pAntennaIds in bytes.
|
||||
* \param pAntennaIds Array containing identifiers of antenna for this connection.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsSetAntennaIds(dmConnId_t connId, uint8_t numAntenna, uint8_t *pAntennaIds)
|
||||
{
|
||||
atpsConnCb_t *pCcb;
|
||||
|
||||
WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX));
|
||||
WSF_ASSERT(numAntenna <= atpsCb.numAntennae);
|
||||
|
||||
pCcb = &atpsCb.connCb[connId-1];
|
||||
pCcb->numAntenna = numAntenna;
|
||||
pCcb->pAntennaIds = pAntennaIds;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called by application to notify the Asset Tracking Profile server of DM Events.
|
||||
*
|
||||
* \param pEvt Pointer to the DM Event.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsProcDmMsg(dmEvt_t *pEvt)
|
||||
{
|
||||
uint8_t status;
|
||||
atpsConnCb_t *pCcb = &atpsCb.connCb[pEvt->hdr.param - 1];
|
||||
|
||||
switch (pEvt->hdr.event)
|
||||
{
|
||||
case DM_RESET_CMPL_IND:
|
||||
DmReadAntennaInfo();
|
||||
break;
|
||||
|
||||
case DM_READ_ANTENNA_INFO_IND:
|
||||
atpsCb.cteMaxLen = pEvt->readAntennaInfo.cteMaxLen;
|
||||
atpsCb.switchSampleRates = pEvt->readAntennaInfo.switchSampleRates;
|
||||
atpsCb.numAntennae = pEvt->readAntennaInfo.numAntennae;
|
||||
atpsCb.switchPatternMaxLen = pEvt->readAntennaInfo.switchPatternMaxLen;
|
||||
break;
|
||||
|
||||
case DM_CONN_OPEN_IND:
|
||||
pCcb->state = ATPS_STATE_ACL_DISABLED;
|
||||
break;
|
||||
|
||||
case DM_CONN_CTE_TX_CFG_IND:
|
||||
if (pEvt->hdr.status == HCI_SUCCESS)
|
||||
{
|
||||
DmConnCteRspStart((dmConnId_t) pEvt->hdr.param);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttsContinueWriteReq((dmConnId_t) pEvt->hdr.param, CTE_ENABLE_HDL, ATT_ERR_WRITE_REJ);
|
||||
pCcb->state = ATPS_STATE_ACL_DISABLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case DM_CONN_CTE_RSP_START_IND:
|
||||
status = (pEvt->hdr.status == HCI_SUCCESS) ? ATT_SUCCESS : ATT_ERR_WRITE_REJ;
|
||||
AttsContinueWriteReq((dmConnId_t) pEvt->hdr.param, CTE_ENABLE_HDL, status);
|
||||
|
||||
if (status == ATT_SUCCESS)
|
||||
{
|
||||
pCcb->enableBits |= CTE_ENABLE_ACL_BIT;
|
||||
pCcb->state = ATPS_STATE_ACL_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_DISABLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case DM_CONN_CTE_RSP_STOP_IND:
|
||||
status = (pEvt->hdr.status == HCI_SUCCESS) ? ATT_SUCCESS : ATT_ERR_WRITE_REJ;
|
||||
AttsContinueWriteReq((dmConnId_t) pEvt->hdr.param, CTE_ENABLE_HDL, status);
|
||||
|
||||
if (status == ATT_SUCCESS)
|
||||
{
|
||||
pCcb->enableBits &= ~CTE_ENABLE_ACL_BIT;
|
||||
pCcb->state = ATPS_STATE_ACL_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_ENABLED;
|
||||
}
|
||||
break;
|
||||
|
||||
case DM_CTE_REQ_FAIL_IND:
|
||||
if (pCcb->state == ATPS_STATE_ACL_STARTING)
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_DISABLED;
|
||||
}
|
||||
else if (pCcb->state == ATPS_STATE_ACL_STOPPING)
|
||||
{
|
||||
pCcb->state = ATPS_STATE_ACL_ENABLED;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Asset Tracking Profile server initialization.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AtpsInit(void)
|
||||
{
|
||||
SvcCteCbackRegister(atpsCteWriteCback);
|
||||
SvcCteAddGroup();
|
||||
}
|
||||
Reference in New Issue
Block a user