initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// amdtpc_api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Ambiq Micro AMDTP client.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AMDTPC_API_H
|
||||
#define AMDTPC_API_H
|
||||
|
||||
#include "att_api.h"
|
||||
#include "amdtp_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
AMDTP_RX_HDL_IDX, /*! Rx data */
|
||||
AMDTP_TX_DATA_HDL_IDX, /*! Tx data */
|
||||
AMDTP_TX_DATA_CCC_HDL_IDX, /*! Tx data client characteristic configuration descriptor */
|
||||
AMDTP_ACK_HDL_IDX, /*! Ack */
|
||||
AMDTP_ACK_CCC_HDL_IDX, /*! Ack client characteristic configuration descriptor */
|
||||
AMDTP_HDL_LIST_LEN /*! Handle list length */
|
||||
};
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AmdtpcDiscover
|
||||
*
|
||||
* \brief Perform service and characteristic discovery for AMDTP service.
|
||||
* Parameter pHdlList must point to an array of length AMDTP_HDL_LIST_LEN.
|
||||
* If discovery is successful the handles of discovered characteristics and
|
||||
* descriptors will be set in pHdlList.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param pHdlList Characteristic handle list.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AmdtpcDiscover(dmConnId_t connId, uint16_t *pHdlList);
|
||||
|
||||
void
|
||||
amdtpc_init(wsfHandlerId_t handlerId, amdtpRecvCback_t recvCback, amdtpTransCback_t transCback);
|
||||
|
||||
void
|
||||
amdtpc_start(uint16_t rxHdl, uint16_t ackHdl, uint8_t timerEvt);
|
||||
|
||||
void
|
||||
amdtpc_proc_msg(wsfMsgHdr_t *pMsg);
|
||||
|
||||
eAmdtpStatus_t
|
||||
AmdtpcSendPacket(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* AMDTPC_API_H */
|
||||
@@ -0,0 +1,438 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// amdtpc_main.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Ambiq Micro AMDTP client.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "bstream.h"
|
||||
#include "app_api.h"
|
||||
#include "amdtpc_api.h"
|
||||
#include "svc_amdtp.h"
|
||||
#include "wsf_trace.h"
|
||||
|
||||
static void amdtpcHandleWriteResponse(attEvt_t *pMsg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t rxPktBuf[AMDTP_PACKET_SIZE];
|
||||
uint8_t txPktBuf[AMDTP_PACKET_SIZE];
|
||||
uint8_t ackPktBuf[20];
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/* UUIDs */
|
||||
static const uint8_t amdtpSvcUuid[] = {ATT_UUID_AMDTP_SERVICE}; /*! AMDTP service */
|
||||
static const uint8_t amdtpRxChUuid[] = {ATT_UUID_AMDTP_RX}; /*! AMDTP Rx */
|
||||
static const uint8_t amdtpTxChUuid[] = {ATT_UUID_AMDTP_TX}; /*! AMDTP Tx */
|
||||
static const uint8_t amdtpAckChUuid[] = {ATT_UUID_AMDTP_ACK}; /*! AMDTP Ack */
|
||||
|
||||
/* Characteristics for discovery */
|
||||
|
||||
/*! Proprietary data */
|
||||
static const attcDiscChar_t amdtpRx =
|
||||
{
|
||||
amdtpRxChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
static const attcDiscChar_t amdtpTx =
|
||||
{
|
||||
amdtpTxChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! AMDTP Tx CCC descriptor */
|
||||
static const attcDiscChar_t amdtpTxCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
static const attcDiscChar_t amdtpAck =
|
||||
{
|
||||
amdtpAckChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! AMDTP Tx CCC descriptor */
|
||||
static const attcDiscChar_t amdtpAckCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! List of characteristics to be discovered; order matches handle index enumeration */
|
||||
static const attcDiscChar_t *amdtpDiscCharList[] =
|
||||
{
|
||||
&amdtpRx, /*! Rx */
|
||||
&amdtpTx, /*! Tx */
|
||||
&amdtpTxCcc, /*! Tx CCC descriptor */
|
||||
&amdtpAck, /*! Ack */
|
||||
&amdtpAckCcc /*! Ack CCC descriptor */
|
||||
};
|
||||
|
||||
/* sanity check: make sure handle list length matches characteristic list length */
|
||||
//WSF_ASSERT(AMDTP_HDL_LIST_LEN == ((sizeof(amdtpDiscCharList) / sizeof(attcDiscChar_t *))));
|
||||
|
||||
|
||||
/* Control block */
|
||||
static struct
|
||||
{
|
||||
bool_t txReady; // TRUE if ready to send notifications
|
||||
uint16_t attRxHdl;
|
||||
uint16_t attAckHdl;
|
||||
amdtpCb_t core;
|
||||
}
|
||||
amdtpcCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AmdtpDiscover
|
||||
*
|
||||
* \brief Perform service and characteristic discovery for AMDTP service.
|
||||
* Parameter pHdlList must point to an array of length AMDTP_HDL_LIST_LEN.
|
||||
* If discovery is successful the handles of discovered characteristics and
|
||||
* descriptors will be set in pHdlList.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param pHdlList Characteristic handle list.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void
|
||||
AmdtpcDiscover(dmConnId_t connId, uint16_t *pHdlList)
|
||||
{
|
||||
AppDiscFindService(connId, ATT_128_UUID_LEN, (uint8_t *) amdtpSvcUuid,
|
||||
AMDTP_HDL_LIST_LEN, (attcDiscChar_t **) amdtpDiscCharList, pHdlList);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send data to Server
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
amdtpcSendData(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
dmConnId_t connId;
|
||||
|
||||
if ((connId = AppConnIsOpen()) == DM_CONN_ID_NONE)
|
||||
{
|
||||
APP_TRACE_INFO0("AmdtpcSendData() no connection\n");
|
||||
return;
|
||||
}
|
||||
if (amdtpcCb.attRxHdl != ATT_HANDLE_NONE)
|
||||
{
|
||||
AttcWriteCmd(connId, amdtpcCb.attRxHdl, len, buf);
|
||||
amdtpcCb.txReady = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN1("Invalid attRxHdl = 0x%x\n", amdtpcCb.attRxHdl);
|
||||
}
|
||||
}
|
||||
|
||||
static eAmdtpStatus_t
|
||||
amdtpcSendAck(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
dmConnId_t connId;
|
||||
|
||||
AmdtpBuildPkt(&amdtpcCb.core, type, encrypted, enableACK, buf, len);
|
||||
|
||||
if ((connId = AppConnIsOpen()) == DM_CONN_ID_NONE)
|
||||
{
|
||||
APP_TRACE_INFO0("AmdtpcSendAck() no connection\n");
|
||||
return AMDTP_STATUS_TX_NOT_READY;
|
||||
}
|
||||
|
||||
if (amdtpcCb.attAckHdl != ATT_HANDLE_NONE)
|
||||
{
|
||||
//APP_TRACE_INFO2("rxHdl = 0x%x, ackHdl = 0x%x\n", amdtpcCb.attRxHdl, amdtpcCb.attAckHdl);
|
||||
AttcWriteCmd(connId, amdtpcCb.attAckHdl, amdtpcCb.core.ackPkt.len, amdtpcCb.core.ackPkt.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_INFO1("Invalid attAckHdl = 0x%x\n", amdtpcCb.attAckHdl);
|
||||
return AMDTP_STATUS_TX_NOT_READY;
|
||||
}
|
||||
return AMDTP_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
amdtpc_init(wsfHandlerId_t handlerId, amdtpRecvCback_t recvCback, amdtpTransCback_t transCback)
|
||||
{
|
||||
memset(&amdtpcCb, 0, sizeof(amdtpcCb));
|
||||
amdtpcCb.txReady = false;
|
||||
amdtpcCb.core.txState = AMDTP_STATE_TX_IDLE;
|
||||
amdtpcCb.core.rxState = AMDTP_STATE_INIT;
|
||||
amdtpcCb.core.timeoutTimer.handlerId = handlerId;
|
||||
|
||||
amdtpcCb.core.lastRxPktSn = 0;
|
||||
amdtpcCb.core.txPktSn = 0;
|
||||
|
||||
resetPkt(&amdtpcCb.core.rxPkt);
|
||||
amdtpcCb.core.rxPkt.data = rxPktBuf;
|
||||
|
||||
resetPkt(&amdtpcCb.core.txPkt);
|
||||
amdtpcCb.core.txPkt.data = txPktBuf;
|
||||
|
||||
resetPkt(&amdtpcCb.core.ackPkt);
|
||||
amdtpcCb.core.ackPkt.data = ackPktBuf;
|
||||
|
||||
amdtpcCb.core.recvCback = recvCback;
|
||||
amdtpcCb.core.transCback = transCback;
|
||||
|
||||
amdtpcCb.core.txTimeoutMs = TX_TIMEOUT_DEFAULT;
|
||||
|
||||
amdtpcCb.core.data_sender_func = amdtpcSendData;
|
||||
amdtpcCb.core.ack_sender_func = amdtpcSendAck;
|
||||
}
|
||||
|
||||
static void
|
||||
amdtpc_conn_close(dmEvt_t *pMsg)
|
||||
{
|
||||
/* clear connection */
|
||||
WsfTimerStop(&amdtpcCb.core.timeoutTimer);
|
||||
amdtpcCb.txReady = false;
|
||||
amdtpcCb.core.txState = AMDTP_STATE_TX_IDLE;
|
||||
amdtpcCb.core.rxState = AMDTP_STATE_INIT;
|
||||
amdtpcCb.core.lastRxPktSn = 0;
|
||||
amdtpcCb.core.txPktSn = 0;
|
||||
resetPkt(&amdtpcCb.core.rxPkt);
|
||||
resetPkt(&amdtpcCb.core.txPkt);
|
||||
resetPkt(&amdtpcCb.core.ackPkt);
|
||||
}
|
||||
|
||||
void
|
||||
amdtpc_start(uint16_t rxHdl, uint16_t ackHdl, uint8_t timerEvt)
|
||||
{
|
||||
amdtpcCb.txReady = true;
|
||||
amdtpcCb.attRxHdl = rxHdl;
|
||||
amdtpcCb.attAckHdl = ackHdl;
|
||||
amdtpcCb.core.timeoutTimer.msg.event = timerEvt;
|
||||
|
||||
dmConnId_t connId;
|
||||
|
||||
if ((connId = AppConnIsOpen()) == DM_CONN_ID_NONE)
|
||||
{
|
||||
APP_TRACE_INFO0("amdtpc_start() no connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
amdtpcCb.core.attMtuSize = AttGetMtu(connId);
|
||||
APP_TRACE_INFO1("MTU size = %d bytes", amdtpcCb.core.attMtuSize);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Timer Expiration handler
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
amdtpc_timeout_timer_expired(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
uint8_t data[1];
|
||||
data[0] = amdtpcCb.core.txPktSn;
|
||||
APP_TRACE_INFO1("amdtpc tx timeout, txPktSn = %d", amdtpcCb.core.txPktSn);
|
||||
AmdtpSendControl(&amdtpcCb.core, AMDTP_CONTROL_RESEND_REQ, data, 1);
|
||||
// fire a timer for receiving an AMDTP_STATUS_RESEND_REPLY ACK
|
||||
WsfTimerStartMs(&amdtpcCb.core.timeoutTimer, amdtpcCb.core.txTimeoutMs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn amdtpcValueNtf
|
||||
*
|
||||
* \brief Process a received ATT notification.
|
||||
*
|
||||
* \param pMsg Pointer to ATT callback event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t
|
||||
amdtpcValueNtf(attEvt_t *pMsg)
|
||||
{
|
||||
eAmdtpStatus_t status = AMDTP_STATUS_UNKNOWN_ERROR;
|
||||
amdtpPacket_t *pkt = NULL;
|
||||
#if 0
|
||||
APP_TRACE_INFO0("receive ntf data\n");
|
||||
APP_TRACE_INFO1("handle = 0x%x\n", pMsg->handle);
|
||||
for (int i = 0; i < pMsg->valueLen; i++)
|
||||
{
|
||||
APP_TRACE_INFO1("%02x ", pMsg->pValue[i]);
|
||||
}
|
||||
APP_TRACE_INFO0("\n");
|
||||
#endif
|
||||
|
||||
if (pMsg->handle == amdtpcCb.attRxHdl)
|
||||
{
|
||||
status = AmdtpReceivePkt(&amdtpcCb.core, &amdtpcCb.core.rxPkt, pMsg->valueLen, pMsg->pValue);
|
||||
}
|
||||
else if ( pMsg->handle == amdtpcCb.attAckHdl )
|
||||
{
|
||||
status = AmdtpReceivePkt(&amdtpcCb.core, &amdtpcCb.core.ackPkt, pMsg->valueLen, pMsg->pValue);
|
||||
}
|
||||
|
||||
if (status == AMDTP_STATUS_RECEIVE_DONE)
|
||||
{
|
||||
if (pMsg->handle == amdtpcCb.attRxHdl)
|
||||
{
|
||||
pkt = &amdtpcCb.core.rxPkt;
|
||||
}
|
||||
else if (pMsg->handle == amdtpcCb.attAckHdl)
|
||||
{
|
||||
pkt = &amdtpcCb.core.ackPkt;
|
||||
}
|
||||
|
||||
AmdtpPacketHandler(&amdtpcCb.core, (eAmdtpPktType_t)pkt->header.pktType, pkt->len - AMDTP_CRC_SIZE_IN_PKT, pkt->data);
|
||||
}
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
amdtpcHandleWriteResponse(attEvt_t *pMsg)
|
||||
{
|
||||
//APP_TRACE_INFO2("amdtpcHandleWriteResponse, status = %d, hdl = 0x%x\n", pMsg->hdr.status, pMsg->handle);
|
||||
if (pMsg->hdr.status == ATT_SUCCESS && pMsg->handle == amdtpcCb.attRxHdl)
|
||||
{
|
||||
amdtpcCb.txReady = true;
|
||||
// process next data
|
||||
AmdtpSendPacketHandler(&amdtpcCb.core);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
amdtpc_proc_msg(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
if (pMsg->event == DM_CONN_OPEN_IND)
|
||||
{
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_CLOSE_IND)
|
||||
{
|
||||
amdtpc_conn_close((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_UPDATE_IND)
|
||||
{
|
||||
}
|
||||
else if (pMsg->event == amdtpcCb.core.timeoutTimer.msg.event)
|
||||
{
|
||||
amdtpc_timeout_timer_expired(pMsg);
|
||||
}
|
||||
else if (pMsg->event == ATTC_WRITE_CMD_RSP)
|
||||
{
|
||||
amdtpcHandleWriteResponse((attEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == ATTC_HANDLE_VALUE_NTF)
|
||||
{
|
||||
amdtpcValueNtf((attEvt_t *) pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Send data to Server via write command
|
||||
//!
|
||||
//! @param type - packet type
|
||||
//! @param encrypted - is packet encrypted
|
||||
//! @param enableACK - does client need to response
|
||||
//! @param buf - data
|
||||
//! @param len - data length
|
||||
//!
|
||||
//! @return status
|
||||
//
|
||||
//*****************************************************************************
|
||||
eAmdtpStatus_t
|
||||
AmdtpcSendPacket(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
//
|
||||
// Check if the service is idle to send
|
||||
//
|
||||
if ( amdtpcCb.core.txState != AMDTP_STATE_TX_IDLE )
|
||||
{
|
||||
APP_TRACE_INFO1("data sending failed, tx state = %d", amdtpcCb.core.txState);
|
||||
return AMDTP_STATUS_BUSY;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if data length is valid
|
||||
//
|
||||
if ( len > AMDTP_MAX_PAYLOAD_SIZE )
|
||||
{
|
||||
APP_TRACE_INFO1("data sending failed, exceed maximum payload, len = %d.", len);
|
||||
return AMDTP_STATUS_INVALID_PKT_LENGTH;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if ready to send notification
|
||||
//
|
||||
if ( !amdtpcCb.txReady )
|
||||
{
|
||||
//set in callback amdtpsHandleValueCnf
|
||||
APP_TRACE_INFO1("data sending failed, not ready for notification.", NULL);
|
||||
return AMDTP_STATUS_TX_NOT_READY;
|
||||
}
|
||||
|
||||
AmdtpBuildPkt(&amdtpcCb.core, type, encrypted, enableACK, buf, len);
|
||||
|
||||
// send packet
|
||||
AmdtpSendPacketHandler(&amdtpcCb.core);
|
||||
|
||||
return AMDTP_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// amdtp_common.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the shared functions for the AMDTP service.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "amdtp_common.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "am_util_debug.h"
|
||||
#include "crc32.h"
|
||||
#include "am_util.h"
|
||||
|
||||
void
|
||||
resetPkt(amdtpPacket_t *pkt)
|
||||
{
|
||||
pkt->offset = 0;
|
||||
pkt->header.pktType = AMDTP_PKT_TYPE_UNKNOWN;
|
||||
pkt->len = 0;
|
||||
}
|
||||
|
||||
eAmdtpStatus_t
|
||||
AmdtpReceivePkt(amdtpCb_t *amdtpCb, amdtpPacket_t *pkt, uint16_t len, uint8_t *pValue)
|
||||
{
|
||||
uint8_t dataIdx = 0;
|
||||
uint32_t calDataCrc = 0;
|
||||
uint16_t header = 0;
|
||||
|
||||
if (pkt->offset == 0 && len < AMDTP_PREFIX_SIZE_IN_PKT)
|
||||
{
|
||||
APP_TRACE_INFO0("Invalid packet!!!");
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_INVALID_PKT_LENGTH, NULL, 0);
|
||||
return AMDTP_STATUS_INVALID_PKT_LENGTH;
|
||||
}
|
||||
|
||||
// new packet
|
||||
if (pkt->offset == 0)
|
||||
{
|
||||
BYTES_TO_UINT16(pkt->len, pValue);
|
||||
BYTES_TO_UINT16(header, &pValue[2]);
|
||||
pkt->header.pktType = (header & PACKET_TYPE_BIT_MASK) >> PACKET_TYPE_BIT_OFFSET;
|
||||
pkt->header.pktSn = (header & PACKET_SN_BIT_MASK) >> PACKET_SN_BIT_OFFSET;
|
||||
pkt->header.encrypted = (header & PACKET_ENCRYPTION_BIT_MASK) >> PACKET_ENCRYPTION_BIT_OFFSET;
|
||||
pkt->header.ackEnabled = (header & PACKET_ACK_BIT_MASK) >> PACKET_ACK_BIT_OFFSET;
|
||||
dataIdx = AMDTP_PREFIX_SIZE_IN_PKT;
|
||||
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
|
||||
{
|
||||
amdtpCb->rxState = AMDTP_STATE_GETTING_DATA;
|
||||
}
|
||||
#ifdef AMDTP_DEBUG_ON
|
||||
APP_TRACE_INFO1("pkt len = 0x%x", pkt->len);
|
||||
APP_TRACE_INFO1("pkt header = 0x%x", header);
|
||||
#endif
|
||||
APP_TRACE_INFO2("type = %d, sn = %d", pkt->header.pktType, pkt->header.pktSn);
|
||||
APP_TRACE_INFO2("enc = %d, ackEnabled = %d", pkt->header.encrypted, pkt->header.ackEnabled);
|
||||
}
|
||||
|
||||
// make sure we have enough space for new data
|
||||
if (pkt->offset + len - dataIdx > AMDTP_PACKET_SIZE)
|
||||
{
|
||||
APP_TRACE_INFO0("not enough buffer size!!!");
|
||||
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
|
||||
{
|
||||
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
|
||||
}
|
||||
// reset pkt
|
||||
resetPkt(pkt);
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_INSUFFICIENT_BUFFER, NULL, 0);
|
||||
return AMDTP_STATUS_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
// copy new data into buffer and also save crc into it if it's the last frame in a packet
|
||||
// 4 bytes crc is included in pkt length
|
||||
memcpy(pkt->data + pkt->offset, pValue + dataIdx, len - dataIdx);
|
||||
pkt->offset += (len - dataIdx);
|
||||
|
||||
// whole packet received
|
||||
if (pkt->offset >= pkt->len)
|
||||
{
|
||||
uint32_t peerCrc = 0;
|
||||
//
|
||||
// check CRC
|
||||
//
|
||||
BYTES_TO_UINT32(peerCrc, pkt->data + pkt->len - AMDTP_CRC_SIZE_IN_PKT);
|
||||
calDataCrc = CalcCrc32(0xFFFFFFFFU, pkt->len - AMDTP_CRC_SIZE_IN_PKT, pkt->data);
|
||||
#ifdef AMDTP_DEBUG_ON
|
||||
APP_TRACE_INFO1("calDataCrc = 0x%x ", calDataCrc);
|
||||
APP_TRACE_INFO1("peerCrc = 0x%x", peerCrc);
|
||||
APP_TRACE_INFO1("len: %d", pkt->len);
|
||||
#endif
|
||||
|
||||
if (peerCrc != calDataCrc)
|
||||
{
|
||||
APP_TRACE_INFO0("crc error\n");
|
||||
|
||||
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
|
||||
{
|
||||
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
|
||||
}
|
||||
// reset pkt
|
||||
resetPkt(pkt);
|
||||
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_CRC_ERROR, NULL, 0);
|
||||
|
||||
return AMDTP_STATUS_CRC_ERROR;
|
||||
}
|
||||
|
||||
return AMDTP_STATUS_RECEIVE_DONE;
|
||||
}
|
||||
|
||||
return AMDTP_STATUS_RECEIVE_CONTINUE;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// AMDTP packet handler
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
AmdtpPacketHandler(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, uint16_t len, uint8_t *buf)
|
||||
{
|
||||
// APP_TRACE_INFO2("received packet type = %d, len = %d\n", type, len);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case AMDTP_PKT_TYPE_DATA:
|
||||
//
|
||||
// data package recevied
|
||||
//
|
||||
// record packet serial number
|
||||
amdtpCb->lastRxPktSn = amdtpCb->rxPkt.header.pktSn;
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_SUCCESS, NULL, 0);
|
||||
if (amdtpCb->recvCback)
|
||||
{
|
||||
amdtpCb->recvCback(buf, len);
|
||||
}
|
||||
|
||||
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
|
||||
resetPkt(&amdtpCb->rxPkt);
|
||||
break;
|
||||
|
||||
case AMDTP_PKT_TYPE_ACK:
|
||||
{
|
||||
eAmdtpStatus_t status = (eAmdtpStatus_t)buf[0];
|
||||
// stop tx timeout timer
|
||||
WsfTimerStop(&amdtpCb->timeoutTimer);
|
||||
|
||||
if (amdtpCb->txState != AMDTP_STATE_TX_IDLE)
|
||||
{
|
||||
// APP_TRACE_INFO1("set txState back to idle, state = %d\n", amdtpCb->txState);
|
||||
amdtpCb->txState = AMDTP_STATE_TX_IDLE;
|
||||
}
|
||||
|
||||
if (status == AMDTP_STATUS_CRC_ERROR || status == AMDTP_STATUS_RESEND_REPLY)
|
||||
{
|
||||
// resend packet
|
||||
AmdtpSendPacketHandler(amdtpCb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// increase packet serial number if send successfully
|
||||
if (status == AMDTP_STATUS_SUCCESS)
|
||||
{
|
||||
amdtpCb->txPktSn++;
|
||||
if (amdtpCb->txPktSn == 16)
|
||||
{
|
||||
amdtpCb->txPktSn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// packet transfer successful or other error
|
||||
// reset packet
|
||||
resetPkt(&amdtpCb->txPkt);
|
||||
|
||||
// notify application layer
|
||||
if (amdtpCb->transCback)
|
||||
{
|
||||
amdtpCb->transCback(status);
|
||||
}
|
||||
}
|
||||
resetPkt(&amdtpCb->ackPkt);
|
||||
}
|
||||
break;
|
||||
|
||||
case AMDTP_PKT_TYPE_CONTROL:
|
||||
{
|
||||
eAmdtpControl_t control = (eAmdtpControl_t)buf[0];
|
||||
uint8_t resendPktSn = buf[1];
|
||||
if (control == AMDTP_CONTROL_RESEND_REQ)
|
||||
{
|
||||
APP_TRACE_INFO2("resendPktSn = %d, lastRxPktSn = %d", resendPktSn, amdtpCb->lastRxPktSn);
|
||||
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
|
||||
resetPkt(&amdtpCb->rxPkt);
|
||||
if (resendPktSn > amdtpCb->lastRxPktSn)
|
||||
{
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_RESEND_REPLY, NULL, 0);
|
||||
}
|
||||
else if (resendPktSn == amdtpCb->lastRxPktSn)
|
||||
{
|
||||
AmdtpSendReply(amdtpCb, AMDTP_STATUS_SUCCESS, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN2("resendPktSn = %d, lastRxPktSn = %d", resendPktSn, amdtpCb->lastRxPktSn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN1("unexpected contrl = %d\n", control);
|
||||
}
|
||||
resetPkt(&amdtpCb->ackPkt);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AmdtpBuildPkt(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint16_t header = 0;
|
||||
uint32_t calDataCrc;
|
||||
amdtpPacket_t *pkt;
|
||||
|
||||
if (type == AMDTP_PKT_TYPE_DATA)
|
||||
{
|
||||
pkt = &amdtpCb->txPkt;
|
||||
header = amdtpCb->txPktSn << PACKET_SN_BIT_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkt = &amdtpCb->ackPkt;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare header frame to be sent first
|
||||
//
|
||||
// length
|
||||
pkt->len = len + AMDTP_PREFIX_SIZE_IN_PKT + AMDTP_CRC_SIZE_IN_PKT;
|
||||
pkt->data[0] = (len + AMDTP_CRC_SIZE_IN_PKT) & 0xff;
|
||||
pkt->data[1] = ((len + AMDTP_CRC_SIZE_IN_PKT) >> 8) & 0xff;
|
||||
|
||||
// header
|
||||
header = header | (type << PACKET_TYPE_BIT_OFFSET);
|
||||
if (encrypted)
|
||||
{
|
||||
header = header | (1 << PACKET_ENCRYPTION_BIT_OFFSET);
|
||||
}
|
||||
if (enableACK)
|
||||
{
|
||||
header = header | (1 << PACKET_ACK_BIT_OFFSET);
|
||||
}
|
||||
pkt->data[2] = (header & 0xff);
|
||||
pkt->data[3] = (header >> 8);
|
||||
|
||||
// copy data
|
||||
memcpy(&(pkt->data[AMDTP_PREFIX_SIZE_IN_PKT]), buf, len);
|
||||
calDataCrc = CalcCrc32(0xFFFFFFFFU, len, buf);
|
||||
|
||||
// add checksum
|
||||
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len] = (calDataCrc & 0xff);
|
||||
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 1] = ((calDataCrc >> 8) & 0xff);
|
||||
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 2] = ((calDataCrc >> 16) & 0xff);
|
||||
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 3] = ((calDataCrc >> 24) & 0xff);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send Reply to Sender
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
AmdtpSendReply(amdtpCb_t *amdtpCb, eAmdtpStatus_t status, uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
|
||||
eAmdtpStatus_t st;
|
||||
|
||||
WSF_ASSERT(len < ATT_DEFAULT_PAYLOAD_LEN);
|
||||
|
||||
buf[0] = status;
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(buf + 1, data, len);
|
||||
}
|
||||
st = amdtpCb->ack_sender_func(AMDTP_PKT_TYPE_ACK, false, false, buf, len + 1);
|
||||
if (st != AMDTP_STATUS_SUCCESS)
|
||||
{
|
||||
APP_TRACE_WARN1("AmdtpSendReply status = %d\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send control message to Receiver
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
AmdtpSendControl(amdtpCb_t *amdtpCb, eAmdtpControl_t control, uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
|
||||
eAmdtpStatus_t st;
|
||||
|
||||
WSF_ASSERT(len < ATT_DEFAULT_PAYLOAD_LEN);
|
||||
|
||||
buf[0] = control;
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(buf + 1, data, len);
|
||||
}
|
||||
st = amdtpCb->ack_sender_func(AMDTP_PKT_TYPE_CONTROL, false, false, buf, len + 1);
|
||||
if (st != AMDTP_STATUS_SUCCESS)
|
||||
{
|
||||
APP_TRACE_WARN1("AmdtpSendControl status = %d\n", st);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AmdtpSendPacketHandler(amdtpCb_t *amdtpCb)
|
||||
{
|
||||
uint16_t transferSize = 0;
|
||||
uint16_t remainingBytes = 0;
|
||||
amdtpPacket_t *txPkt = &amdtpCb->txPkt;
|
||||
|
||||
if ( amdtpCb->txState == AMDTP_STATE_TX_IDLE )
|
||||
{
|
||||
txPkt->offset = 0;
|
||||
amdtpCb->txState = AMDTP_STATE_SENDING;
|
||||
}
|
||||
|
||||
if ( txPkt->offset >= txPkt->len )
|
||||
{
|
||||
// done sent packet
|
||||
amdtpCb->txState = AMDTP_STATE_WAITING_ACK;
|
||||
// start tx timeout timer
|
||||
WsfTimerStartMs(&amdtpCb->timeoutTimer, amdtpCb->txTimeoutMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
remainingBytes = txPkt->len - txPkt->offset;
|
||||
transferSize = ((amdtpCb->attMtuSize - 3) > remainingBytes)
|
||||
? remainingBytes
|
||||
: (amdtpCb->attMtuSize - 3);
|
||||
// send packet
|
||||
amdtpCb->data_sender_func(&txPkt->data[txPkt->offset], transferSize);
|
||||
txPkt->offset += transferSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// amdtp_common.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the shared functions for the AMDTP service.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AMDTP_COMMON_H
|
||||
#define AMDTP_COMMON_H
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_timer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AMDTP_MAX_PAYLOAD_SIZE 2048//512
|
||||
#define AMDTP_PACKET_SIZE (AMDTP_MAX_PAYLOAD_SIZE + AMDTP_PREFIX_SIZE_IN_PKT + AMDTP_CRC_SIZE_IN_PKT) // Bytes
|
||||
#define AMDTP_LENGTH_SIZE_IN_PKT 2
|
||||
#define AMDTP_HEADER_SIZE_IN_PKT 2
|
||||
#define AMDTP_CRC_SIZE_IN_PKT 4
|
||||
#define AMDTP_PREFIX_SIZE_IN_PKT AMDTP_LENGTH_SIZE_IN_PKT + AMDTP_HEADER_SIZE_IN_PKT
|
||||
|
||||
#define PACKET_TYPE_BIT_OFFSET 12
|
||||
#define PACKET_TYPE_BIT_MASK (0xf << PACKET_TYPE_BIT_OFFSET)
|
||||
#define PACKET_SN_BIT_OFFSET 8
|
||||
#define PACKET_SN_BIT_MASK (0xf << PACKET_SN_BIT_OFFSET)
|
||||
#define PACKET_ENCRYPTION_BIT_OFFSET 7
|
||||
#define PACKET_ENCRYPTION_BIT_MASK (0x1 << PACKET_ENCRYPTION_BIT_OFFSET)
|
||||
#define PACKET_ACK_BIT_OFFSET 6
|
||||
#define PACKET_ACK_BIT_MASK (0x1 << PACKET_ACK_BIT_OFFSET)
|
||||
|
||||
#define TX_TIMEOUT_DEFAULT 1000
|
||||
|
||||
//
|
||||
// amdtp states
|
||||
//
|
||||
typedef enum eAmdtpState
|
||||
{
|
||||
AMDTP_STATE_INIT,
|
||||
AMDTP_STATE_TX_IDLE,
|
||||
AMDTP_STATE_RX_IDLE,
|
||||
AMDTP_STATE_SENDING,
|
||||
AMDTP_STATE_GETTING_DATA,
|
||||
AMDTP_STATE_WAITING_ACK,
|
||||
AMDTP_STATE_MAX
|
||||
}eAmdtpState_t;
|
||||
|
||||
//
|
||||
// amdtp packet type
|
||||
//
|
||||
typedef enum eAmdtpPktType
|
||||
{
|
||||
AMDTP_PKT_TYPE_UNKNOWN,
|
||||
AMDTP_PKT_TYPE_DATA,
|
||||
AMDTP_PKT_TYPE_ACK,
|
||||
AMDTP_PKT_TYPE_CONTROL,
|
||||
AMDTP_PKT_TYPE_MAX
|
||||
}eAmdtpPktType_t;
|
||||
|
||||
typedef enum eAmdtpControl
|
||||
{
|
||||
AMDTP_CONTROL_RESEND_REQ,
|
||||
AMDTP_CONTROL_MAX
|
||||
}eAmdtpControl_t;
|
||||
|
||||
//
|
||||
// amdtp status
|
||||
//
|
||||
typedef enum eAmdtpStatus
|
||||
{
|
||||
AMDTP_STATUS_SUCCESS,
|
||||
AMDTP_STATUS_CRC_ERROR,
|
||||
AMDTP_STATUS_INVALID_METADATA_INFO,
|
||||
AMDTP_STATUS_INVALID_PKT_LENGTH,
|
||||
AMDTP_STATUS_INSUFFICIENT_BUFFER,
|
||||
AMDTP_STATUS_UNKNOWN_ERROR,
|
||||
AMDTP_STATUS_BUSY,
|
||||
AMDTP_STATUS_TX_NOT_READY, // no connection or tx busy
|
||||
AMDTP_STATUS_RESEND_REPLY,
|
||||
AMDTP_STATUS_RECEIVE_CONTINUE,
|
||||
AMDTP_STATUS_RECEIVE_DONE,
|
||||
AMDTP_STATUS_MAX
|
||||
}eAmdtpStatus_t;
|
||||
|
||||
//
|
||||
// packet prefix structure
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pktType : 4;
|
||||
uint8_t pktSn : 4;
|
||||
uint8_t encrypted : 1;
|
||||
uint32_t ackEnabled : 1;
|
||||
uint32_t reserved : 6; // Reserved for future usage
|
||||
}
|
||||
amdtpPktHeader_t;
|
||||
|
||||
//
|
||||
// packet
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
uint16_t offset;
|
||||
uint16_t len; // data plus checksum
|
||||
amdtpPktHeader_t header;
|
||||
uint8_t *data;
|
||||
}
|
||||
amdtpPacket_t;
|
||||
|
||||
/*! Application data reception callback */
|
||||
typedef void (*amdtpRecvCback_t)(uint8_t *buf, uint16_t len);
|
||||
|
||||
/*! Application data transmission result callback */
|
||||
typedef void (*amdtpTransCback_t)(eAmdtpStatus_t status);
|
||||
|
||||
typedef void (*amdtp_reply_func_t)(eAmdtpStatus_t status, uint8_t *data, uint16_t len);
|
||||
|
||||
typedef void (*amdtp_packet_handler_func_t)(eAmdtpPktType_t type, uint16_t len, uint8_t *buf);
|
||||
|
||||
typedef eAmdtpStatus_t (*amdtp_ack_sender_func_t)(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
typedef void (*amdtp_data_sender_func_t)(uint8_t *buf, uint16_t len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
eAmdtpState_t txState;
|
||||
eAmdtpState_t rxState;
|
||||
amdtpPacket_t rxPkt;
|
||||
amdtpPacket_t txPkt;
|
||||
amdtpPacket_t ackPkt;
|
||||
uint8_t txPktSn; // data packet serial number for Tx
|
||||
uint8_t lastRxPktSn; // last received data packet serial number
|
||||
uint16_t attMtuSize;
|
||||
wsfTimer_t timeoutTimer; // timeout timer after DTP update done
|
||||
wsfTimerTicks_t txTimeoutMs;
|
||||
amdtpRecvCback_t recvCback; // application callback for data reception
|
||||
amdtpTransCback_t transCback; // application callback for tx complete status
|
||||
amdtp_data_sender_func_t data_sender_func;
|
||||
amdtp_ack_sender_func_t ack_sender_func;
|
||||
}
|
||||
amdtpCb_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// function definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
AmdtpBuildPkt(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
eAmdtpStatus_t
|
||||
AmdtpReceivePkt(amdtpCb_t *amdtpCb, amdtpPacket_t *pkt, uint16_t len, uint8_t *pValue);
|
||||
|
||||
void
|
||||
AmdtpSendReply(amdtpCb_t *amdtpCb, eAmdtpStatus_t status, uint8_t *data, uint16_t len);
|
||||
|
||||
void
|
||||
AmdtpSendControl(amdtpCb_t *amdtpCb, eAmdtpControl_t control, uint8_t *data, uint16_t len);
|
||||
|
||||
void
|
||||
AmdtpSendPacketHandler(amdtpCb_t *amdtpCb);
|
||||
|
||||
void
|
||||
AmdtpPacketHandler(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, uint16_t len, uint8_t *buf);
|
||||
|
||||
void
|
||||
resetPkt(amdtpPacket_t *pkt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AMDTP_COMMON_H
|
||||
@@ -0,0 +1,109 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// amdtps_api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Brief description of the header. No need to get fancy here.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AMDTPS_API_H
|
||||
#define AMDTPS_API_H
|
||||
|
||||
#include "wsf_timer.h"
|
||||
#include "att_api.h"
|
||||
#include "amdtp_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//
|
||||
// Connection control block
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
dmConnId_t connId; // Connection ID
|
||||
bool_t amdtpToSend; // AMDTP notify ready to be sent on this channel
|
||||
}
|
||||
amdtpsConn_t;
|
||||
|
||||
/*! Configurable parameters */
|
||||
typedef struct
|
||||
{
|
||||
//! Short description of each member should go here.
|
||||
uint32_t reserved;
|
||||
}
|
||||
AmdtpsCfg_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// function definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void amdtps_init(wsfHandlerId_t handlerId, AmdtpsCfg_t *pCfg, amdtpRecvCback_t recvCback, amdtpTransCback_t transCback);
|
||||
|
||||
void amdtps_proc_msg(wsfMsgHdr_t *pMsg);
|
||||
|
||||
uint8_t amdtps_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
|
||||
|
||||
void amdtps_start(dmConnId_t connId, uint8_t timerEvt, uint8_t amdtpCccIdx);
|
||||
|
||||
void amdtps_stop(dmConnId_t connId);
|
||||
|
||||
eAmdtpStatus_t
|
||||
AmdtpsSendPacket(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AMDTPS_API_H
|
||||
@@ -0,0 +1,524 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// amdtps_main.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the main application for the AMDTP service.
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_buf.h" //for WsfBufAlloc and WsfBufFree
|
||||
#include "bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "svc_ch.h"
|
||||
#include "svc_amdtp.h"
|
||||
#include "app_api.h"
|
||||
#include "app_hw.h"
|
||||
#include "amdtps_api.h"
|
||||
#include "am_util_debug.h"
|
||||
#include "crc32.h"
|
||||
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t rxPktBuf[AMDTP_PACKET_SIZE];
|
||||
uint8_t txPktBuf[AMDTP_PACKET_SIZE];
|
||||
uint8_t ackPktBuf[20];
|
||||
|
||||
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
|
||||
static int totalLen = 0;
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
/* Control block */
|
||||
static struct
|
||||
{
|
||||
amdtpsConn_t conn[DM_CONN_MAX]; // connection control block
|
||||
bool_t txReady; // TRUE if ready to send notifications
|
||||
wsfHandlerId_t appHandlerId;
|
||||
AmdtpsCfg_t cfg; // configurable parameters
|
||||
amdtpCb_t core;
|
||||
}
|
||||
amdtpsCb;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Connection Open event
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
amdtps_conn_open(dmEvt_t *pMsg)
|
||||
{
|
||||
hciLeConnCmplEvt_t *evt = (hciLeConnCmplEvt_t*) pMsg;
|
||||
|
||||
APP_TRACE_INFO0("connection opened\n");
|
||||
APP_TRACE_INFO1("handle = 0x%x\n", evt->handle);
|
||||
APP_TRACE_INFO1("role = 0x%x\n", evt->role);
|
||||
APP_TRACE_INFO3("addrMSB = %02x%02x%02x%02x%02x%02x\n", evt->peerAddr[0], evt->peerAddr[1], evt->peerAddr[2]);
|
||||
APP_TRACE_INFO3("addrLSB = %02x%02x%02x%02x%02x%02x\n", evt->peerAddr[3], evt->peerAddr[4], evt->peerAddr[5]);
|
||||
APP_TRACE_INFO1("connInterval = 0x%x\n", evt->connInterval);
|
||||
APP_TRACE_INFO1("connLatency = 0x%x\n", evt->connLatency);
|
||||
APP_TRACE_INFO1("supTimeout = 0x%x\n", evt->supTimeout);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Connection Update event
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
amdtps_conn_update(dmEvt_t *pMsg)
|
||||
{
|
||||
hciLeConnUpdateCmplEvt_t *evt = (hciLeConnUpdateCmplEvt_t*) pMsg;
|
||||
|
||||
APP_TRACE_INFO1("connection update status = 0x%x", evt->status);
|
||||
APP_TRACE_INFO1("handle = 0x%x", evt->handle);
|
||||
APP_TRACE_INFO1("connInterval = 0x%x", evt->connInterval);
|
||||
APP_TRACE_INFO1("connLatency = 0x%x", evt->connLatency);
|
||||
APP_TRACE_INFO1("supTimeout = 0x%x", evt->supTimeout);
|
||||
}
|
||||
|
||||
static void amdtpsSetupToSend(void)
|
||||
{
|
||||
amdtpsConn_t *pConn = amdtpsCb.conn;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < DM_CONN_MAX; i++, pConn++)
|
||||
{
|
||||
if (pConn->connId != DM_CONN_ID_NONE)
|
||||
{
|
||||
pConn->amdtpToSend = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Find Next Connection to Send on
|
||||
//
|
||||
//*****************************************************************************
|
||||
static amdtpsConn_t*
|
||||
amdtps_find_next2send(void)
|
||||
{
|
||||
amdtpsConn_t *pConn = amdtpsCb.conn;
|
||||
return pConn;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send Notification to Client
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
amdtpsSendData(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
amdtpsSetupToSend();
|
||||
amdtpsConn_t *pConn = amdtps_find_next2send();
|
||||
/* send notification */
|
||||
if (pConn)
|
||||
{
|
||||
#ifdef AMDTP_DEBUG_ON
|
||||
APP_TRACE_INFO1("amdtpsSendData(), Send to connId = %d\n", pConn->connId);
|
||||
#endif
|
||||
AttsHandleValueNtf(pConn->connId, AMDTPS_TX_HDL, len, buf);
|
||||
|
||||
pConn->amdtpToSend = false;
|
||||
amdtpsCb.txReady = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN1("Invalid Conn = %d\n", pConn->connId);
|
||||
}
|
||||
}
|
||||
|
||||
static eAmdtpStatus_t
|
||||
amdtpsSendAck(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
AmdtpBuildPkt(&amdtpsCb.core, type, encrypted, enableACK, buf, len);
|
||||
// send packet
|
||||
amdtpsSetupToSend();
|
||||
amdtpsConn_t *pConn = amdtps_find_next2send();
|
||||
/* send notification */
|
||||
if (pConn)
|
||||
{
|
||||
#ifdef AMDTP_DEBUG_ON
|
||||
APP_TRACE_INFO1("amdtpsSendAck(), Send to connId = %d\n", pConn->connId);
|
||||
#endif
|
||||
AttsHandleValueNtf(pConn->connId, AMDTPS_ACK_HDL, amdtpsCb.core.ackPkt.len, amdtpsCb.core.ackPkt.data);
|
||||
|
||||
pConn->amdtpToSend = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN1("Invalid Conn = %d\n", pConn->connId);
|
||||
return AMDTP_STATUS_TX_NOT_READY;
|
||||
}
|
||||
|
||||
return AMDTP_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Timer Expiration handler
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
amdtps_timeout_timer_expired(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
uint8_t data[1];
|
||||
data[0] = amdtpsCb.core.txPktSn;
|
||||
APP_TRACE_INFO1("amdtps tx timeout, txPktSn = %d", amdtpsCb.core.txPktSn);
|
||||
AmdtpSendControl(&amdtpsCb.core, AMDTP_CONTROL_RESEND_REQ, data, 1);
|
||||
// fire a timer for receiving an AMDTP_STATUS_RESEND_REPLY ACK
|
||||
WsfTimerStartMs(&amdtpsCb.core.timeoutTimer, amdtpsCb.core.txTimeoutMs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn amdtpsHandleValueCnf
|
||||
*
|
||||
* \brief Handle a received ATT handle value confirm.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void
|
||||
amdtpsHandleValueCnf(attEvt_t *pMsg)
|
||||
{
|
||||
//APP_TRACE_INFO2("Cnf status = %d, handle = 0x%x\n", pMsg->hdr.status, pMsg->handle);
|
||||
if (pMsg->hdr.status == ATT_SUCCESS)
|
||||
{
|
||||
#if !defined(AMDTPS_RXONLY) && !defined(AMDTPS_RX2TX)
|
||||
if (pMsg->handle == AMDTPS_TX_HDL)
|
||||
{
|
||||
amdtpsCb.txReady = true;
|
||||
// process next data
|
||||
AmdtpSendPacketHandler(&amdtpsCb.core);
|
||||
#ifdef AMDTPS_TXTEST
|
||||
// fixme when last packet, continue to send next one.
|
||||
if (amdtpsCb.core.txState == AMDTP_STATE_WAITING_ACK)
|
||||
{
|
||||
uint8_t temp[3];
|
||||
temp[0] = AMDTP_STATUS_SUCCESS;
|
||||
AmdtpPacketHandler(&amdtpsCb.core, AMDTP_PKT_TYPE_ACK, 3, temp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0 //def AMDTPS_TXTEST
|
||||
// workround for ATT timeout issue
|
||||
/* Connection control block */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
wsfQueue_t prepWriteQueue; /* prepare write queue */
|
||||
wsfTimer_t idleTimer; /* service discovery idle timer */
|
||||
uint16_t handle; /* connection handle */
|
||||
uint16_t mtu; /* connection mtu */
|
||||
dmConnId_t connId; /* DM connection ID */
|
||||
bool_t mtuSent; /* MTU req or rsp sent */
|
||||
bool_t flowDisabled; /* Data flow disabled */
|
||||
bool_t transTimedOut; /* ATT transaction timed out */
|
||||
} attCcb_t;
|
||||
extern attCcb_t *attCcbByConnId(dmConnId_t connId);
|
||||
if (pMsg->hdr.status == 0x71)
|
||||
{
|
||||
attCcb_t *ccb = attCcbByConnId(1);
|
||||
ccb->transTimedOut = FALSE;
|
||||
}
|
||||
#endif
|
||||
APP_TRACE_WARN2("cnf status = %d, hdl = 0x%x\n", pMsg->hdr.status, pMsg->handle);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief initialize amdtp service
|
||||
//!
|
||||
//! @param handlerId - connection handle
|
||||
//! @param pCfg - configuration parameters
|
||||
//!
|
||||
//! @return None
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
amdtps_init(wsfHandlerId_t handlerId, AmdtpsCfg_t *pCfg, amdtpRecvCback_t recvCback, amdtpTransCback_t transCback)
|
||||
{
|
||||
memset(&amdtpsCb, 0, sizeof(amdtpsCb));
|
||||
amdtpsCb.appHandlerId = handlerId;
|
||||
amdtpsCb.txReady = false;
|
||||
amdtpsCb.core.txState = AMDTP_STATE_INIT;
|
||||
amdtpsCb.core.rxState = AMDTP_STATE_RX_IDLE;
|
||||
amdtpsCb.core.timeoutTimer.handlerId = handlerId;
|
||||
for (int i = 0; i < DM_CONN_MAX; i++)
|
||||
{
|
||||
amdtpsCb.conn[i].connId = DM_CONN_ID_NONE;
|
||||
}
|
||||
|
||||
amdtpsCb.core.lastRxPktSn = 0;
|
||||
amdtpsCb.core.txPktSn = 0;
|
||||
|
||||
resetPkt(&amdtpsCb.core.rxPkt);
|
||||
amdtpsCb.core.rxPkt.data = rxPktBuf;
|
||||
|
||||
resetPkt(&amdtpsCb.core.txPkt);
|
||||
amdtpsCb.core.txPkt.data = txPktBuf;
|
||||
|
||||
resetPkt(&amdtpsCb.core.ackPkt);
|
||||
amdtpsCb.core.ackPkt.data = ackPktBuf;
|
||||
|
||||
amdtpsCb.core.recvCback = recvCback;
|
||||
amdtpsCb.core.transCback = transCback;
|
||||
|
||||
amdtpsCb.core.txTimeoutMs = TX_TIMEOUT_DEFAULT;
|
||||
|
||||
amdtpsCb.core.data_sender_func = amdtpsSendData;
|
||||
amdtpsCb.core.ack_sender_func = amdtpsSendAck;
|
||||
}
|
||||
|
||||
static void
|
||||
amdtps_conn_close(dmEvt_t *pMsg)
|
||||
{
|
||||
hciDisconnectCmplEvt_t *evt = (hciDisconnectCmplEvt_t*) pMsg;
|
||||
dmConnId_t connId = evt->hdr.param;
|
||||
/* clear connection */
|
||||
amdtpsCb.conn[connId - 1].connId = DM_CONN_ID_NONE;
|
||||
amdtpsCb.conn[connId - 1].amdtpToSend = FALSE;
|
||||
|
||||
WsfTimerStop(&amdtpsCb.core.timeoutTimer);
|
||||
amdtpsCb.core.txState = AMDTP_STATE_INIT;
|
||||
amdtpsCb.core.rxState = AMDTP_STATE_RX_IDLE;
|
||||
amdtpsCb.core.lastRxPktSn = 0;
|
||||
amdtpsCb.core.txPktSn = 0;
|
||||
resetPkt(&amdtpsCb.core.rxPkt);
|
||||
resetPkt(&amdtpsCb.core.txPkt);
|
||||
resetPkt(&amdtpsCb.core.ackPkt);
|
||||
|
||||
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
|
||||
APP_TRACE_INFO1("*** RECEIVED TOTAL %d ***", totalLen);
|
||||
totalLen = 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
uint8_t
|
||||
amdtps_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
|
||||
{
|
||||
eAmdtpStatus_t status = AMDTP_STATUS_UNKNOWN_ERROR;
|
||||
amdtpPacket_t *pkt = NULL;
|
||||
#if 0
|
||||
uint16_t i = 0;
|
||||
APP_TRACE_INFO0("============= data arrived start ===============");
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
APP_TRACE_INFO1("%x\t", pValue[i]);
|
||||
}
|
||||
APP_TRACE_INFO0("");
|
||||
APP_TRACE_INFO0("============= data arrived end ===============");
|
||||
#endif
|
||||
if (handle == AMDTPS_RX_HDL)
|
||||
{
|
||||
#if defined(AMDTPS_RX2TX)
|
||||
amdtpsSendData(pValue, len);
|
||||
#endif
|
||||
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
|
||||
totalLen += len;
|
||||
APP_TRACE_INFO2("received data len %d, total %d", len, totalLen);
|
||||
return ATT_SUCCESS;
|
||||
#else /* RXONLY && RX2TX */
|
||||
status = AmdtpReceivePkt(&amdtpsCb.core, &amdtpsCb.core.rxPkt, len, pValue);
|
||||
#endif /* RXONLY && RX2TX */
|
||||
}
|
||||
else if (handle == AMDTPS_ACK_HDL)
|
||||
{
|
||||
status = AmdtpReceivePkt(&amdtpsCb.core, &amdtpsCb.core.ackPkt, len, pValue);
|
||||
}
|
||||
|
||||
if (status == AMDTP_STATUS_RECEIVE_DONE)
|
||||
{
|
||||
if (handle == AMDTPS_RX_HDL)
|
||||
{
|
||||
pkt = &amdtpsCb.core.rxPkt;
|
||||
}
|
||||
else if (handle == AMDTPS_ACK_HDL)
|
||||
{
|
||||
pkt = &amdtpsCb.core.ackPkt;
|
||||
}
|
||||
|
||||
AmdtpPacketHandler(&amdtpsCb.core, (eAmdtpPktType_t)pkt->header.pktType, pkt->len - AMDTP_CRC_SIZE_IN_PKT, pkt->data);
|
||||
}
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
amdtps_start(dmConnId_t connId, uint8_t timerEvt, uint8_t amdtpCccIdx)
|
||||
{
|
||||
//
|
||||
// set conn id
|
||||
//
|
||||
amdtpsCb.conn[connId - 1].connId = connId;
|
||||
amdtpsCb.conn[connId - 1].amdtpToSend = TRUE;
|
||||
|
||||
amdtpsCb.core.timeoutTimer.msg.event = timerEvt;
|
||||
amdtpsCb.core.txState = AMDTP_STATE_TX_IDLE;
|
||||
amdtpsCb.txReady = true;
|
||||
|
||||
amdtpsCb.core.attMtuSize = AttGetMtu(connId);
|
||||
APP_TRACE_INFO1("MTU size = %d bytes", amdtpsCb.core.attMtuSize);
|
||||
}
|
||||
|
||||
void
|
||||
amdtps_stop(dmConnId_t connId)
|
||||
{
|
||||
//
|
||||
// clear connection
|
||||
//
|
||||
amdtpsCb.conn[connId - 1].connId = DM_CONN_ID_NONE;
|
||||
amdtpsCb.conn[connId - 1].amdtpToSend = FALSE;
|
||||
|
||||
amdtpsCb.core.txState = AMDTP_STATE_INIT;
|
||||
amdtpsCb.txReady = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
amdtps_proc_msg(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
if (pMsg->event == DM_CONN_OPEN_IND)
|
||||
{
|
||||
amdtps_conn_open((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_CLOSE_IND)
|
||||
{
|
||||
amdtps_conn_close((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_UPDATE_IND)
|
||||
{
|
||||
amdtps_conn_update((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == amdtpsCb.core.timeoutTimer.msg.event)
|
||||
{
|
||||
amdtps_timeout_timer_expired(pMsg);
|
||||
}
|
||||
else if (pMsg->event == ATTS_HANDLE_VALUE_CNF)
|
||||
{
|
||||
amdtpsHandleValueCnf((attEvt_t *) pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Send data to Client via notification
|
||||
//!
|
||||
//! @param type - packet type
|
||||
//! @param encrypted - is packet encrypted
|
||||
//! @param enableACK - does client need to response
|
||||
//! @param buf - data
|
||||
//! @param len - data length
|
||||
//!
|
||||
//! @return status
|
||||
//
|
||||
//*****************************************************************************
|
||||
eAmdtpStatus_t
|
||||
AmdtpsSendPacket(eAmdtpPktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
//
|
||||
// Check if ready to send notification
|
||||
//
|
||||
if ( !amdtpsCb.txReady )
|
||||
{
|
||||
//set in callback amdtpsHandleValueCnf
|
||||
APP_TRACE_INFO1("data sending failed, not ready for notification.", NULL);
|
||||
return AMDTP_STATUS_TX_NOT_READY;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the service is idle to send
|
||||
//
|
||||
if ( amdtpsCb.core.txState != AMDTP_STATE_TX_IDLE )
|
||||
{
|
||||
APP_TRACE_INFO1("data sending failed, tx state = %d", amdtpsCb.core.txState);
|
||||
return AMDTP_STATUS_BUSY;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if data length is valid
|
||||
//
|
||||
if ( len > AMDTP_MAX_PAYLOAD_SIZE )
|
||||
{
|
||||
APP_TRACE_INFO1("data sending failed, exceed maximum payload, len = %d.", len);
|
||||
return AMDTP_STATUS_INVALID_PKT_LENGTH;
|
||||
}
|
||||
|
||||
AmdtpBuildPkt(&amdtpsCb.core, type, encrypted, enableACK, buf, len);
|
||||
|
||||
// send packet
|
||||
AmdtpSendPacketHandler(&amdtpsCb.core);
|
||||
|
||||
return AMDTP_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// amotas_api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Brief description of the header. No need to get fancy here.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef AMOTAS_API_H
|
||||
#define AMOTAS_API_H
|
||||
|
||||
#include "wsf_timer.h"
|
||||
#include "att_api.h"
|
||||
|
||||
// enable debug print for AMOTA profile
|
||||
// #define AMOTA_DEBUG_ON
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AMOTA_PACKET_SIZE (512 + 16) // Bytes
|
||||
#define AMOTA_LENGTH_SIZE_IN_PKT 2
|
||||
#define AMOTA_CMD_SIZE_IN_PKT 1
|
||||
#define AMOTA_CRC_SIZE_IN_PKT 4
|
||||
#define AMOTA_HEADER_SIZE_IN_PKT AMOTA_LENGTH_SIZE_IN_PKT + AMOTA_CMD_SIZE_IN_PKT
|
||||
|
||||
#define AMOTA_FW_HEADER_SIZE 44
|
||||
|
||||
#define AMOTA_FW_STORAGE_INTERNAL 0
|
||||
#define AMOTA_FW_STORAGE_EXTERNAL 1
|
||||
|
||||
/*! Configurable parameters */
|
||||
typedef struct
|
||||
{
|
||||
//! Short description of each member should go here.
|
||||
uint32_t reserved;
|
||||
}
|
||||
AmotasCfg_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External variable definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External function definitions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// function definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void amotas_init(wsfHandlerId_t handlerId, AmotasCfg_t *pCfg);
|
||||
|
||||
void amotas_proc_msg(wsfMsgHdr_t *pMsg);
|
||||
|
||||
uint8_t amotas_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
|
||||
|
||||
void amotas_start(dmConnId_t connId, uint8_t resetTimerEvt, uint8_t disconnectTimerEvt, uint8_t amotaCccIdx);
|
||||
|
||||
void amotas_stop(dmConnId_t connId);
|
||||
|
||||
extern void amotas_conn_close(dmConnId_t connId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AMOTAS_API_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,232 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// ancc_api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief apple notification center service client.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef ANCC_API_H
|
||||
#define ANCC_API_H
|
||||
|
||||
#include "att_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
/* ANCS Service */ // 7905F431-B5CE-4E99-A40F-4B1E122D00D0
|
||||
#define ATT_UUID_ANCS_SERVICE 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,\
|
||||
0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79
|
||||
/* ANCS characteristics */
|
||||
// 9FBF120D-6301-42D9-8C58-25E699A21DBD
|
||||
#define ATT_UUID_NOTIFICATION_SOURCE 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, \
|
||||
0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f
|
||||
|
||||
//69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9
|
||||
#define ATT_UUID_CTRL_POINT 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,\
|
||||
0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69
|
||||
|
||||
// 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
|
||||
#define ATT_UUID_DATA_SOURCE 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,\
|
||||
0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22
|
||||
|
||||
#define ANCC_LIST_ELEMENTS 64
|
||||
#define ANCC_APP_IDENTIFIER_SIZE_BYTES 64
|
||||
#define ANCC_ATTRI_BUFFER_SIZE_BYTES 512
|
||||
|
||||
/**@brief Category IDs for iOS notifications. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */
|
||||
BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */
|
||||
BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */
|
||||
BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */
|
||||
BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */
|
||||
BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */
|
||||
BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */
|
||||
BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */
|
||||
BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */
|
||||
BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */
|
||||
BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */
|
||||
BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */
|
||||
} ancc_category_id_values_t;
|
||||
|
||||
/**@brief Event IDs for iOS notifications. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */
|
||||
BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */
|
||||
BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */
|
||||
} ancc_evt_id_values_t;
|
||||
|
||||
/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */
|
||||
BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS App. */
|
||||
BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example dismiss an alarm. */
|
||||
} ancc_command_id_values_t;
|
||||
|
||||
/**@brief IDs for iOS notification attributes. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER, /**< Identifies that the attribute data is of an "App Identifier" type. */
|
||||
BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". Needs to be followed by a 2-bytes max length parameter*/
|
||||
BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". Needs to be followed by a 2-bytes max length parameter*/
|
||||
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". Needs to be followed by a 2-bytes max length parameter*/
|
||||
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */
|
||||
BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */
|
||||
BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */
|
||||
BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */
|
||||
} ancc_notif_attr_id_values_t;
|
||||
|
||||
/**@brief ActionID values. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ANCS_NOTIF_ACTION_ID_POSITIVE,
|
||||
BLE_ANCS_NOTIF_ACTION_ID_NEGATIVE,
|
||||
} ancc_notif_action_id_values_t;
|
||||
|
||||
|
||||
/**@brief Typedef for iOS notifications. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t event_id; /**< This field informs the accessory whether the given iOS notification was added, modified, or removed. The enumerated values for this field are defined in EventID Values.. */
|
||||
uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
|
||||
uint8_t category_id; /**< A numerical value providing a category in which the iOS notification can be classified. */
|
||||
uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
|
||||
uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification. */
|
||||
bool_t noti_valid; /**< A flag to indicate whether the notification is still valid in the list. */
|
||||
} ancc_notif_t;
|
||||
|
||||
/*! ancs client enumeration of handle indexes of characteristics to be discovered */
|
||||
enum
|
||||
{
|
||||
ANCC_NOTIFICATION_SOURCE_HDL_IDX, // ANCC Notification Source Handle
|
||||
ANCC_NOTIFICATION_SOURCE_CCC_HDL_IDX, // ANCC Notification Source CCC Handle
|
||||
ANCC_CONTROL_POINT_HDL_IDX, // ANCC Control Point Handle
|
||||
ANCC_DATA_SOURCE_HDL_IDX, // ANCC Data Source Handle
|
||||
ANCC_DATA_SOURCE_CCC_HDL_IDX, // ANCC Data Source CCC Handle
|
||||
ANCC_HDL_LIST_LEN /*! Handle list length */
|
||||
};
|
||||
|
||||
/*! Configurable parameters */
|
||||
typedef struct
|
||||
{
|
||||
wsfTimerTicks_t period; /*! action timer expiration period in ms */
|
||||
} anccCfg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NOTI_ATTR_NEW_NOTIFICATION = 0,
|
||||
NOTI_ATTR_NEW_ATTRIBUTE,
|
||||
NOTI_ATTR_RECEIVING_ATTRIBUTE
|
||||
} enum_active_state_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; // handle to indicate the current active notification in the list
|
||||
enum_active_state_t attrState;
|
||||
uint16_t bufIndex;
|
||||
uint16_t parseIndex;
|
||||
uint16_t attrLength;
|
||||
uint8_t attrId;
|
||||
uint16_t attrCount;
|
||||
uint8_t commandId;
|
||||
uint32_t notiUid;
|
||||
uint8_t appId[ANCC_APP_IDENTIFIER_SIZE_BYTES];
|
||||
uint8_t attrDataBuf[ANCC_ATTRI_BUFFER_SIZE_BYTES];
|
||||
} active_notif_t;
|
||||
|
||||
/*! Application data reception callback */
|
||||
typedef void (*anccAttrRecvCback_t)(active_notif_t* pAttr);
|
||||
typedef void (*anccNotiCmplCback_t)(active_notif_t* pAttr, uint32_t notiUid);
|
||||
|
||||
/*! Application notify remove callback */
|
||||
typedef void (*anccNotiRemoveCback_t)(ancc_notif_t* pAttr);
|
||||
typedef struct
|
||||
{
|
||||
dmConnId_t connId;
|
||||
uint16_t* hdlList;
|
||||
anccCfg_t cfg;
|
||||
wsfTimer_t actionTimer; // perform actions with proper delay
|
||||
wsfTimer_t discoverTimer; // perform service discovery delay
|
||||
ancc_notif_t anccList[ANCC_LIST_ELEMENTS]; // buffer size = MAX_LIST_ELEMENTS*sizeof(ancc_notif_t)
|
||||
active_notif_t active;
|
||||
anccAttrRecvCback_t attrCback;
|
||||
anccNotiCmplCback_t notiCback;
|
||||
anccNotiRemoveCback_t rmvCback;
|
||||
} anccCb_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Prototypes
|
||||
**************************************************************************************************/
|
||||
// operation interfaces
|
||||
void AncsPerformNotiAction(uint16_t *pHdlList, uint32_t notiUid, ancc_notif_action_id_values_t actionId);
|
||||
void AncsGetAppAttribute(uint16_t *pHdlList, uint8_t* appId);
|
||||
void AnccGetNotificationAttribute(uint16_t *pHdlList, uint32_t notiUid);
|
||||
|
||||
// initialization interfaces
|
||||
void AnccInit(wsfHandlerId_t handlerId, anccCfg_t* cfg, uint8_t disctimer_event);
|
||||
void AnccCbackRegister(anccAttrRecvCback_t attrCback, anccNotiCmplCback_t notiCback, anccNotiRemoveCback_t rmvCback);
|
||||
|
||||
// app routines
|
||||
void AnccNtfValueUpdate(uint16_t *pHdlList, attEvt_t * pMsg, uint8_t actionTimerEvt);
|
||||
void AnccActionHandler(uint8_t actionTimerEvt);
|
||||
void AnccActionStop(void);
|
||||
void AnccActionStart(uint8_t timerEvt);
|
||||
void AnccConnClose(void);
|
||||
void AnccConnOpen(dmConnId_t connId, uint16_t* hdlList);
|
||||
void AnccSvcDiscover(dmConnId_t connId, uint16_t *pHdlList);
|
||||
bool_t AnccStartServiceDiscovery(void);
|
||||
|
||||
/* Global variable */
|
||||
extern anccCb_t anccCb;
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* ANCC_API_H */
|
||||
@@ -0,0 +1,709 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// ancc_main.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief apple notification center service client.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "bstream.h"
|
||||
#include "app_api.h"
|
||||
#include "ancc_api.h"
|
||||
|
||||
#include "am_util.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*!
|
||||
* Apple Notification Center Service Client (ANCC)
|
||||
*/
|
||||
|
||||
/* UUIDs */
|
||||
static const uint8_t anccAncsSvcUuid[] = {ATT_UUID_ANCS_SERVICE}; /*! ANCS Service UUID */
|
||||
static const uint8_t anccNSChUuid[] = {ATT_UUID_NOTIFICATION_SOURCE}; /*! Notification Source UUID */
|
||||
static const uint8_t anccCPChUuid[] = {ATT_UUID_CTRL_POINT}; /*! control point UUID*/
|
||||
static const uint8_t anccDSChUuid[] = {ATT_UUID_DATA_SOURCE}; /*! data source UUID*/
|
||||
/* Characteristics for discovery */
|
||||
|
||||
#define DISCOVER_TIMER_DELAY (3000) // ms
|
||||
|
||||
/*! Proprietary data */
|
||||
static const attcDiscChar_t anccNSDat =
|
||||
{
|
||||
anccNSChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! Proprietary data descriptor */ //notification source
|
||||
static const attcDiscChar_t anccNSdatCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
// control point
|
||||
static const attcDiscChar_t anccCtrlPoint =
|
||||
{
|
||||
anccCPChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
// data source
|
||||
static const attcDiscChar_t anccDataSrc =
|
||||
{
|
||||
anccDSChUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_UUID_128
|
||||
};
|
||||
/*! Proprietary data descriptor */ //data source
|
||||
static const attcDiscChar_t anccDataSrcCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_REQUIRED | ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! List of characteristics to be discovered; order matches handle index enumeration */
|
||||
static const attcDiscChar_t *anccSvcDiscCharList[] =
|
||||
{
|
||||
&anccNSDat, /*! Proprietary data */
|
||||
&anccNSdatCcc, /*! Proprietary data descriptor */
|
||||
&anccCtrlPoint, /*! Control point */
|
||||
&anccDataSrc, /*! data source */
|
||||
&anccDataSrcCcc /*! data source descriptor */
|
||||
};
|
||||
|
||||
/* sanity check: make sure handle list length matches characteristic list length */
|
||||
WSF_CT_ASSERT(ANCC_HDL_LIST_LEN == ((sizeof(anccSvcDiscCharList) / sizeof(attcDiscChar_t *))));
|
||||
|
||||
/* Global variable */
|
||||
anccCb_t anccCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccSvcDiscover
|
||||
*
|
||||
* \brief Perform service and characteristic discovery for ancs service.
|
||||
* Parameter pHdlList must point to an array of length ANCC_HDL_LIST_LEN.
|
||||
* If discovery is successful the handles of discovered characteristics and
|
||||
* descriptors will be set in pHdlList.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param pHdlList Characteristic handle list.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccSvcDiscover(dmConnId_t connId, uint16_t *pHdlList)
|
||||
{
|
||||
AppDiscFindService(connId, ATT_128_UUID_LEN, (uint8_t *) anccAncsSvcUuid,
|
||||
ANCC_HDL_LIST_LEN, (attcDiscChar_t **) anccSvcDiscCharList, pHdlList);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccInit
|
||||
*
|
||||
* \brief Initialize the control variables of ancs client
|
||||
*
|
||||
* \param handlerId App handler id for timer operation.
|
||||
* \param cfg config variable.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccInit(wsfHandlerId_t handlerId, anccCfg_t* cfg, uint8_t disctimer_event)
|
||||
{
|
||||
memset(anccCb.anccList, 0, ANCC_LIST_ELEMENTS * sizeof(ancc_notif_t));
|
||||
anccCb.cfg.period = cfg->period;
|
||||
anccCb.actionTimer.handlerId = handlerId;
|
||||
anccCb.discoverTimer.handlerId = handlerId;
|
||||
anccCb.discoverTimer.msg.event = disctimer_event;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccConnOpen
|
||||
*
|
||||
* \brief Update the key parameters for control variables when connection open.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param hdlList Characteristic handle list.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccConnOpen(dmConnId_t connId, uint16_t* hdlList)
|
||||
{
|
||||
anccCb.connId = connId;
|
||||
anccCb.hdlList = hdlList;
|
||||
|
||||
WsfTimerStop(&anccCb.discoverTimer);
|
||||
WsfTimerStartMs(&anccCb.discoverTimer, DISCOVER_TIMER_DELAY);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccConnClose
|
||||
*
|
||||
* \brief Clear the key parameters for control variables when connection close.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccConnClose(void)
|
||||
{
|
||||
WsfTimerStop(&anccCb.discoverTimer);
|
||||
anccCb.connId = DM_CONN_ID_NONE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn anccNoConnActive
|
||||
*
|
||||
* \brief Return TRUE if no connections with active measurements.
|
||||
*
|
||||
* \return TRUE if no connections active.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool_t anccNoConnActive(void)
|
||||
{
|
||||
if (anccCb.connId != DM_CONN_ID_NONE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn anccActionListPush
|
||||
*
|
||||
* \brief Return TRUE if element is added/updated to the list.
|
||||
*
|
||||
* \return TRUE if element is added/updated to the list.
|
||||
* FALSE if list is full.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool_t anccActionListPush(ancc_notif_t* pElement)
|
||||
{
|
||||
uint16_t i;
|
||||
for ( i = 0; i < ANCC_LIST_ELEMENTS; i++ )
|
||||
{
|
||||
if ( (anccCb.anccList[i].notification_uid == pElement->notification_uid ) && (anccCb.anccList[i].noti_valid == true) )
|
||||
{
|
||||
// same notification uid received, update the element
|
||||
anccCb.anccList[i].notification_uid = pElement->notification_uid;
|
||||
anccCb.anccList[i].event_id = pElement->event_id;
|
||||
anccCb.anccList[i].event_flags = pElement->event_flags;
|
||||
anccCb.anccList[i].category_id = pElement->category_id;
|
||||
anccCb.anccList[i].category_count = pElement->category_count;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < ANCC_LIST_ELEMENTS; i++ )
|
||||
{
|
||||
if ( anccCb.anccList[i].noti_valid == false )
|
||||
{
|
||||
// found an empty slot
|
||||
anccCb.anccList[i].notification_uid = pElement->notification_uid;
|
||||
anccCb.anccList[i].event_id = pElement->event_id;
|
||||
anccCb.anccList[i].event_flags = pElement->event_flags;
|
||||
anccCb.anccList[i].category_id = pElement->category_id;
|
||||
anccCb.anccList[i].category_count = pElement->category_count;
|
||||
anccCb.anccList[i].noti_valid = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; //no empty slot left
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn anccActionListPop
|
||||
*
|
||||
* \brief Return TRUE if element is popped out and removed from the list.
|
||||
*
|
||||
* \return TRUE if element is popped out and removed from the list.
|
||||
* FALSE if list is already empty.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool_t anccActionListPop(void)
|
||||
{
|
||||
uint16_t i;
|
||||
for ( i = 0; i < ANCC_LIST_ELEMENTS; i++ )
|
||||
{
|
||||
if ( anccCb.anccList[ANCC_LIST_ELEMENTS - i - 1].noti_valid == true )
|
||||
{
|
||||
// found a valid element in the list
|
||||
anccCb.anccList[ANCC_LIST_ELEMENTS - i - 1].noti_valid = false;
|
||||
anccCb.active.handle = ANCC_LIST_ELEMENTS - i - 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; //no element left in the list
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccActionStart
|
||||
*
|
||||
* \brief Start periodic ancc operation. This function starts a timer to perform
|
||||
* periodic actions.
|
||||
*
|
||||
* \param timerEvt WSF event designated by the application for the timer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccActionStart(uint8_t timerEvt)
|
||||
{
|
||||
/* if this is first connection */
|
||||
if (anccNoConnActive() == FALSE)
|
||||
{
|
||||
/* initialize control block */
|
||||
anccCb.actionTimer.msg.event = timerEvt;
|
||||
|
||||
/* (re-)start timer */
|
||||
WsfTimerStop(&anccCb.actionTimer);
|
||||
WsfTimerStartMs(&anccCb.actionTimer, anccCb.cfg.period);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccActionStop
|
||||
*
|
||||
* \brief Stop periodic ancc action.
|
||||
*
|
||||
* \param connId DM connection identifier.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccActionStop(void)
|
||||
{
|
||||
/* stop timer */
|
||||
WsfTimerStop(&anccCb.actionTimer);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccGetNotificationAttribute
|
||||
*
|
||||
* \brief Send a command to the apple notification center service control point.
|
||||
*
|
||||
* \param pHdlList Characteristic handle list.
|
||||
* \param notiUid NotificationUid.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccGetNotificationAttribute(uint16_t *pHdlList, uint32_t notiUid)
|
||||
{
|
||||
// An example to get notification attributes
|
||||
uint16_t max_len = 256;
|
||||
uint8_t buf[19]; // retrieve the complete attribute list
|
||||
if (pHdlList[ANCC_CONTROL_POINT_HDL_IDX] != ATT_HANDLE_NONE)
|
||||
{
|
||||
buf[0] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES; // put command
|
||||
uint8_t * p = &buf[1];
|
||||
UINT32_TO_BSTREAM(p, notiUid); // encode notification uid
|
||||
|
||||
// encode attribute IDs
|
||||
buf[5] = BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER;
|
||||
buf[6] = BLE_ANCS_NOTIF_ATTR_ID_TITLE;
|
||||
// 2 byte length
|
||||
buf[7] = max_len;
|
||||
buf[8] = max_len >> 8;
|
||||
buf[9] = BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE;
|
||||
buf[10] = max_len;
|
||||
buf[11] = max_len >> 8;
|
||||
buf[12] = BLE_ANCS_NOTIF_ATTR_ID_MESSAGE;
|
||||
buf[13] = max_len;
|
||||
buf[14] = max_len >> 8;
|
||||
buf[15] = BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE;
|
||||
buf[16] = BLE_ANCS_NOTIF_ATTR_ID_DATE;
|
||||
buf[17] = BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL;
|
||||
buf[18] = BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL;
|
||||
AttcWriteReq(anccCb.connId, pHdlList[ANCC_CONTROL_POINT_HDL_IDX], sizeof(buf), buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AncsGetAppAttribute
|
||||
*
|
||||
* \brief Send a command to the apple notification center service control point.
|
||||
*
|
||||
* \param pHdlList Connection identifier.
|
||||
* \param pAppId Attribute handle.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AncsGetAppAttribute(uint16_t *pHdlList, uint8_t *pAppId)
|
||||
{
|
||||
// An example to get app attributes
|
||||
uint8_t buf[64]; // to hold the command, size of app identifier is unknown
|
||||
uint8_t count = 0;
|
||||
if (pHdlList[ANCC_CONTROL_POINT_HDL_IDX] != ATT_HANDLE_NONE)
|
||||
{
|
||||
buf[0] = BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES; // put command
|
||||
|
||||
while (pAppId[count++] != 0); // NULL terminated string
|
||||
if ( count > (64 - 2) )
|
||||
{
|
||||
// app identifier is too long
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&buf[1], pAppId, count);
|
||||
}
|
||||
|
||||
buf[count + 1] = 0; // app attribute id
|
||||
AttcWriteReq(anccCb.connId, pHdlList[ANCC_CONTROL_POINT_HDL_IDX], (count + 2), buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AncsPerformNotiAction
|
||||
*
|
||||
* \brief Send a command to the apple notification center service control point.
|
||||
*
|
||||
* \param pHdlList Characteristic handle list.
|
||||
* \param actionId Notification action identifier.
|
||||
* \param notiUid NotificationUid.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AncsPerformNotiAction(uint16_t *pHdlList, uint32_t notiUid, ancc_notif_action_id_values_t actionId)
|
||||
{
|
||||
// An example to performs notification action
|
||||
uint8_t buf[6]; //to hold the command, size of app identifier is unknown
|
||||
if (pHdlList[ANCC_CONTROL_POINT_HDL_IDX] != ATT_HANDLE_NONE)
|
||||
{
|
||||
buf[0] = BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION; // put command
|
||||
uint8_t * p = &buf[1];
|
||||
UINT32_TO_BSTREAM(p, notiUid); // encode notification uid
|
||||
buf[5] = actionId; //action id
|
||||
AttcWriteReq(anccCb.connId, pHdlList[ANCC_CONTROL_POINT_HDL_IDX], sizeof(buf), buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccActionHandler
|
||||
*
|
||||
* \brief Routine to handle ancc related actions.
|
||||
*
|
||||
* \param actionTimerEvt WsfTimer event indication.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccActionHandler(uint8_t actionTimerEvt)
|
||||
{
|
||||
// perform action
|
||||
if ( anccActionListPop() )
|
||||
{
|
||||
AnccGetNotificationAttribute(anccCb.hdlList, anccCb.anccList[anccCb.active.handle].notification_uid);
|
||||
AnccActionStart(actionTimerEvt);
|
||||
}
|
||||
else
|
||||
{
|
||||
//list empty
|
||||
AnccActionStop();
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn anccAttrHandler
|
||||
*
|
||||
* \brief Static routine to handle attribute receiving and processing.
|
||||
*
|
||||
* \param pMsg pointer to ATT message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool anccAttrHandler(attEvt_t * pMsg)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
uint16_t bytesRemaining = 0;
|
||||
|
||||
switch(anccCb.active.attrState)
|
||||
{
|
||||
case NOTI_ATTR_NEW_NOTIFICATION:
|
||||
// new notification
|
||||
anccCb.active.commandId = pMsg->pValue[0];
|
||||
if ( anccCb.active.commandId == BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES )
|
||||
{
|
||||
BYTES_TO_UINT32(anccCb.active.notiUid, &(pMsg->pValue[1]));
|
||||
count = 4;
|
||||
}
|
||||
else if ( anccCb.active.commandId == BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES )
|
||||
{
|
||||
while(pMsg->pValue[count + 1] != 0) // NULL terminated string
|
||||
{
|
||||
anccCb.active.appId[count] = pMsg->pValue[count + 1];
|
||||
count++;
|
||||
}
|
||||
anccCb.active.appId[count + 1] = 0; // NULL terminated string
|
||||
}
|
||||
else
|
||||
{
|
||||
// BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION
|
||||
return false;
|
||||
}
|
||||
anccCb.active.parseIndex += count + 1;
|
||||
anccCb.active.attrState = NOTI_ATTR_NEW_ATTRIBUTE;
|
||||
anccCb.active.attrId = 0;
|
||||
anccCb.active.attrCount = 0;
|
||||
|
||||
if ( pMsg->valueLen > ANCC_ATTRI_BUFFER_SIZE_BYTES )
|
||||
{
|
||||
// notification size overflow
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesRemaining = pMsg->valueLen;
|
||||
}
|
||||
// copy data
|
||||
memset(anccCb.active.attrDataBuf, 0, ANCC_ATTRI_BUFFER_SIZE_BYTES);
|
||||
anccCb.active.bufIndex = 0;
|
||||
for (uint16_t i = 0; i < bytesRemaining; i++)
|
||||
{
|
||||
anccCb.active.attrDataBuf[anccCb.active.bufIndex++] = pMsg->pValue[i];
|
||||
}
|
||||
// no break here by intention
|
||||
case NOTI_ATTR_NEW_ATTRIBUTE:
|
||||
// new attribute
|
||||
// check consistency of the attribute
|
||||
if ( anccCb.active.bufIndex - anccCb.active.parseIndex < 3 ) // 1 byte attribute id + 2 bytes attribute length
|
||||
{
|
||||
// attribute header not received completely
|
||||
anccCb.active.attrState = NOTI_ATTR_RECEIVING_ATTRIBUTE;
|
||||
return false;
|
||||
}
|
||||
|
||||
anccCb.active.attrId = anccCb.active.attrDataBuf[anccCb.active.parseIndex];
|
||||
BYTES_TO_UINT16(anccCb.active.attrLength, &(anccCb.active.attrDataBuf[anccCb.active.parseIndex + 1]));
|
||||
|
||||
if ( anccCb.active.attrLength > (anccCb.active.bufIndex - anccCb.active.parseIndex - 3) ) // 1 byte attribute id + 2 bytes attribute length
|
||||
{
|
||||
// attribute body not received completely
|
||||
anccCb.active.attrState = NOTI_ATTR_RECEIVING_ATTRIBUTE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse attribute
|
||||
anccCb.active.attrCount++;
|
||||
anccCb.active.parseIndex += 3; // 1 byte attribute id + 2 bytes attribute length
|
||||
|
||||
if ( anccCb.active.attrId == BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER )
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
while(anccCb.active.attrDataBuf[anccCb.active.parseIndex + temp] != 0) // NULL terminated string
|
||||
{
|
||||
anccCb.active.appId[temp] = anccCb.active.attrDataBuf[anccCb.active.parseIndex + temp];
|
||||
temp++;
|
||||
}
|
||||
anccCb.active.appId[temp] = 0; // NULL terminated string
|
||||
}
|
||||
|
||||
//
|
||||
// attribute received
|
||||
// execute callback function
|
||||
//
|
||||
(*anccCb.attrCback)(&anccCb.active);
|
||||
|
||||
anccCb.active.parseIndex += anccCb.active.attrLength;
|
||||
|
||||
if ( anccCb.active.attrCount >= 8 ) //custom criteria
|
||||
{
|
||||
//notification reception done
|
||||
anccCb.active.attrState = NOTI_ATTR_NEW_NOTIFICATION;
|
||||
anccCb.active.parseIndex = 0;
|
||||
anccCb.active.bufIndex = 0;
|
||||
|
||||
//
|
||||
// notification received
|
||||
// execute callback function
|
||||
//
|
||||
(*anccCb.notiCback)(&anccCb.active, anccCb.active.notiUid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // continue parsing
|
||||
// no need to break;
|
||||
case NOTI_ATTR_RECEIVING_ATTRIBUTE:
|
||||
// notification continuing
|
||||
bytesRemaining = 0;
|
||||
if ( anccCb.active.bufIndex + pMsg->valueLen > ANCC_ATTRI_BUFFER_SIZE_BYTES )
|
||||
{
|
||||
// notification size overflow
|
||||
anccCb.active.attrState = NOTI_ATTR_NEW_NOTIFICATION;
|
||||
anccCb.active.parseIndex = 0;
|
||||
anccCb.active.bufIndex = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesRemaining = pMsg->valueLen;
|
||||
}
|
||||
// copy data
|
||||
for (uint16_t i = 0; i < bytesRemaining; i++)
|
||||
{
|
||||
anccCb.active.attrDataBuf[anccCb.active.bufIndex++] = pMsg->pValue[i];
|
||||
}
|
||||
anccCb.active.attrState = NOTI_ATTR_NEW_ATTRIBUTE;
|
||||
return true;
|
||||
// no need to break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccNtfValueUpdate
|
||||
*
|
||||
* \brief Routine to handle any ancc related notify.
|
||||
*
|
||||
* \param pHdlList Characteristic handle list.
|
||||
* \param actionTimerEvt WsfTimer event indication.
|
||||
* \param pMsg pointer to ATT message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccNtfValueUpdate(uint16_t *pHdlList, attEvt_t * pMsg, uint8_t actionTimerEvt)
|
||||
{
|
||||
ancc_notif_t ancs_notif;
|
||||
uint8_t *p;
|
||||
|
||||
//notification received
|
||||
if (pMsg->handle == pHdlList[ANCC_NOTIFICATION_SOURCE_HDL_IDX])
|
||||
{
|
||||
// process notificiation source (brief)
|
||||
p = pMsg->pValue;
|
||||
ancs_notif.event_id = p[0];
|
||||
ancs_notif.event_flags = p[1];
|
||||
ancs_notif.category_id = p[2];
|
||||
ancs_notif.category_count = p[3];
|
||||
BYTES_TO_UINT32(ancs_notif.notification_uid, &p[4]);
|
||||
|
||||
if (BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED == ancs_notif.event_id)
|
||||
{
|
||||
if (NULL != anccCb.rmvCback)
|
||||
{
|
||||
anccCb.rmvCback(&ancs_notif);
|
||||
}
|
||||
}
|
||||
else if ( !anccActionListPush(&ancs_notif) )
|
||||
{
|
||||
// list full
|
||||
// APP_TRACE_INFO0("action list full...");
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// actions to be done with timer delays to avoid generating heavy traffic
|
||||
//
|
||||
AnccActionStart(actionTimerEvt);
|
||||
// APP_TRACE_INFO0("added to action list");
|
||||
}
|
||||
}
|
||||
else if ( pMsg->handle == pHdlList[ANCC_DATA_SOURCE_HDL_IDX] )
|
||||
{
|
||||
// process notificiation/app attributes
|
||||
while(anccAttrHandler(pMsg));
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccCbackRegister
|
||||
*
|
||||
* \brief Register the attribute received callback and notification completed callback.
|
||||
*
|
||||
* \param attrCback Pointer to attribute received callback function.
|
||||
* \param notiCback Pointer to notification completed callback function.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void AnccCbackRegister(anccAttrRecvCback_t attrCback, anccNotiCmplCback_t notiCback, anccNotiRemoveCback_t rmvCback)
|
||||
{
|
||||
anccCb.attrCback = attrCback;
|
||||
anccCb.notiCback = notiCback;
|
||||
anccCb.rmvCback = rmvCback;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn AnccStartServiceDiscovery
|
||||
*
|
||||
* \brief Do service discovery on connected connection.
|
||||
*
|
||||
* \return Return TRUE if service discovery is initiated successfully.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t AnccStartServiceDiscovery(void)
|
||||
{
|
||||
if (anccCb.connId != DM_CONN_ID_NONE)
|
||||
{
|
||||
appDiscStart(anccCb.connId);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// voles_api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Brief description of the header. No need to get fancy here.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef VOLES_API_H
|
||||
#define VOLES_API_H
|
||||
|
||||
#include "wsf_timer.h"
|
||||
#include "att_api.h"
|
||||
#include "vole_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//
|
||||
// Connection control block
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
dmConnId_t connId; // Connection ID
|
||||
bool_t voleToSend; // VOLE notify ready to be sent on this channel
|
||||
}
|
||||
volesConn_t;
|
||||
|
||||
/*! Configurable parameters */
|
||||
typedef struct
|
||||
{
|
||||
//! Short description of each member should go here.
|
||||
uint32_t reserved;
|
||||
}
|
||||
VolesCfg_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// function definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void voles_init(wsfHandlerId_t handlerId, eVoleCodecType codec_type);
|
||||
void voles_proc_msg(wsfMsgHdr_t *pMsg);
|
||||
void voles_transmit_voice_data(void);
|
||||
|
||||
int voles_set_codec_type(eVoleCodecType codec_type);
|
||||
|
||||
uint8_t voles_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
|
||||
|
||||
void voles_start(dmConnId_t connId, uint8_t timerEvt, uint8_t voleCccIdx);
|
||||
|
||||
void voles_stop(dmConnId_t connId);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VOLES_API_H
|
||||
@@ -0,0 +1,465 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// voles_main.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the main application for the VOLE service.
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_buf.h" //for WsfBufAlloc and WsfBufFree
|
||||
#include "bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "svc_ch.h"
|
||||
#include "svc_amvole.h"
|
||||
#include "app_api.h"
|
||||
#include "app_hw.h"
|
||||
#include "voles_api.h"
|
||||
#include "am_util_debug.h"
|
||||
#include "crc32.h"
|
||||
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
#include "sbc.h"
|
||||
#include "vole_common.h"
|
||||
#include "att_defs.h"
|
||||
#include "vole_board_config.h"
|
||||
#include "voice_data.h"
|
||||
|
||||
#include "ae_api.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
//*****************************************************************************
|
||||
eVoleCodecType g_vole_codec_type;
|
||||
uint8_t g_ble_data_buffer[ATT_MAX_MTU];
|
||||
|
||||
extern bool_t g_start_voice_send;
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
static sbc_t g_SBCInstance;
|
||||
int g_opusErr;
|
||||
uint32_t g_audioSampleRate = 16000;
|
||||
int32_t g_audioChannel = 1;
|
||||
|
||||
/* Control block */
|
||||
static struct
|
||||
{
|
||||
volesConn_t conn[DM_CONN_MAX]; // connection control block
|
||||
bool_t txReady; // TRUE if ready to send notifications
|
||||
wsfHandlerId_t appHandlerId;
|
||||
VolesCfg_t cfg; // configurable parameters
|
||||
voleCb_t core;
|
||||
}
|
||||
volesCb;
|
||||
|
||||
extern bool am_app_KWD_AMA_tx_ver_exchange_send(void);
|
||||
extern uint16_t am_app_KWD_AMA_stream_send(uint8_t* buf, uint32_t len);
|
||||
extern void am_app_led_off(void);
|
||||
|
||||
static void voles_conn_parameter_req(void)
|
||||
{
|
||||
hciConnSpec_t connSpec;
|
||||
connSpec.connIntervalMin = 6; //(15/1.25);//(30/1.25);
|
||||
connSpec.connIntervalMax = 12; //(15/1.25);//(30/1.25);
|
||||
connSpec.connLatency = 0; //0;
|
||||
connSpec.supTimeout = 400;
|
||||
connSpec.minCeLen = 0;
|
||||
connSpec.maxCeLen = 0xffff; //fixme
|
||||
DmConnUpdate(1, &connSpec);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Connection Open event
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
voles_conn_open(dmEvt_t *pMsg)
|
||||
{
|
||||
hciLeConnCmplEvt_t *evt = (hciLeConnCmplEvt_t*) pMsg;
|
||||
|
||||
APP_TRACE_INFO0("connection opened\n");
|
||||
APP_TRACE_INFO1("handle = 0x%x\n", evt->handle);
|
||||
APP_TRACE_INFO1("role = 0x%x\n", evt->role);
|
||||
APP_TRACE_INFO3("addrMSB = %02x%02x%02x%02x%02x%02x\n", evt->peerAddr[0], evt->peerAddr[1], evt->peerAddr[2]);
|
||||
APP_TRACE_INFO3("addrLSB = %02x%02x%02x%02x%02x%02x\n", evt->peerAddr[3], evt->peerAddr[4], evt->peerAddr[5]);
|
||||
APP_TRACE_INFO1("connInterval = %d x 1.25 ms\n", evt->connInterval);
|
||||
APP_TRACE_INFO1("connLatency = %d\n", evt->connLatency);
|
||||
APP_TRACE_INFO1("supTimeout = %d ms\n", evt->supTimeout * 10);
|
||||
|
||||
if ( evt->connInterval > 12 )
|
||||
{
|
||||
voles_conn_parameter_req();
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Connection Update event
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void
|
||||
voles_conn_update(dmEvt_t *pMsg)
|
||||
{
|
||||
hciLeConnUpdateCmplEvt_t *evt = (hciLeConnUpdateCmplEvt_t*) pMsg;
|
||||
|
||||
APP_TRACE_INFO1("connection update status = 0x%x", evt->status);
|
||||
APP_TRACE_INFO1("handle = 0x%x", evt->handle);
|
||||
APP_TRACE_INFO1("connInterval = 0x%x", evt->connInterval);
|
||||
APP_TRACE_INFO1("connLatency = 0x%x", evt->connLatency);
|
||||
APP_TRACE_INFO1("supTimeout = 0x%x", evt->supTimeout);
|
||||
|
||||
|
||||
if ( evt->connInterval > (15 / 1.25) )
|
||||
{
|
||||
// retry
|
||||
voles_conn_parameter_req();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t voles_msbc_encode_voice_data(uint8_t *input, uint8_t *output, uint16_t len)
|
||||
{
|
||||
int32_t i32CompressedLen = 0;
|
||||
|
||||
if ((input == NULL) || (output == NULL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sbc_encoder_encode(&g_SBCInstance, input, len,
|
||||
output, CODEC_MSBC_OUTPUT_SIZE, (int *)&i32CompressedLen);
|
||||
|
||||
APP_TRACE_INFO2("voles encode, input len:%d, compressedLen:%d", len, i32CompressedLen);
|
||||
|
||||
return i32CompressedLen;
|
||||
}
|
||||
|
||||
int voles_set_codec_type(eVoleCodecType codec_type)
|
||||
{
|
||||
APP_TRACE_INFO1("set codec type:%s", ((codec_type == 0) ? "MSBC code" : "OPUS codec"));
|
||||
|
||||
if (codec_type != VOLE_CODEC_TYPE_INVALID)
|
||||
{
|
||||
g_vole_codec_type = codec_type;
|
||||
return codec_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return VOLE_CODEC_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
eVoleCodecType voles_get_codec_type(void)
|
||||
{
|
||||
return g_vole_codec_type;
|
||||
}
|
||||
|
||||
// get the size for each sending packet
|
||||
int voles_ble_buffer_size(void)
|
||||
{
|
||||
eVoleCodecType codec_type = voles_get_codec_type();
|
||||
int buffer_size = 0;
|
||||
|
||||
switch(codec_type)
|
||||
{
|
||||
case MSBC_CODEC_IN_USE:
|
||||
buffer_size = BLE_MSBC_DATA_BUFFER_SIZE;
|
||||
break;
|
||||
|
||||
case OPUS_CODEC_IN_USE:
|
||||
buffer_size = BLE_OPUS_DATA_BUFFER_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
void voles_transmit_voice_data(void)
|
||||
{
|
||||
volePacket_t *txPkt = &volesCb.core.txPkt;
|
||||
uint32_t offset = txPkt->offset;
|
||||
int remain_data_len = 0;
|
||||
int enc_data_len = 0;
|
||||
uint8_t output_data[100] = {0};
|
||||
int output_len = 0;
|
||||
static int index = 0;
|
||||
eVoleCodecType codec_type = voles_get_codec_type();
|
||||
|
||||
txPkt->len = sizeof(voice_data);
|
||||
remain_data_len = txPkt->len - offset;
|
||||
|
||||
if (codec_type == MSBC_CODEC_IN_USE)
|
||||
{
|
||||
enc_data_len = (remain_data_len>CODEC_MSBC_INPUT_SIZE)?CODEC_MSBC_INPUT_SIZE:remain_data_len;
|
||||
}
|
||||
else if (codec_type == OPUS_CODEC_IN_USE)
|
||||
{
|
||||
enc_data_len = (remain_data_len>CODEC_OPUS_INPUT_SIZE)?CODEC_OPUS_INPUT_SIZE:remain_data_len;
|
||||
}
|
||||
|
||||
APP_TRACE_INFO3("send %s encode data, total len:%d, offset:%d", (codec_type == MSBC_CODEC_IN_USE) ? "mSBC" : "Opus",
|
||||
txPkt->len, offset);
|
||||
|
||||
if (offset >= txPkt->len)
|
||||
{
|
||||
am_app_led_off();
|
||||
g_start_voice_send = FALSE;
|
||||
memset(output_data, 0x0, sizeof(output_data));
|
||||
txPkt->offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (codec_type == MSBC_CODEC_IN_USE)
|
||||
{
|
||||
output_len = voles_msbc_encode_voice_data(&voice_data[offset + AUD_HEADER_LEN], output_data, enc_data_len);
|
||||
txPkt->offset += enc_data_len;
|
||||
}
|
||||
else if (codec_type == OPUS_CODEC_IN_USE)
|
||||
{
|
||||
output_len = audio_enc_encode_frame((short *)&voice_data[offset + AUD_HEADER_LEN], enc_data_len, output_data);
|
||||
APP_TRACE_INFO1("opus encode, output_len:%d", output_len);
|
||||
if (output_len == (CODEC_OPUS_OUTPUT_SIZE))
|
||||
{
|
||||
txPkt->offset += (2*CODEC_OPUS_INPUT_SIZE);
|
||||
//APP_TRACE_INFO1("opus_encode: ret:%d", output_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
txPkt->offset += enc_data_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( output_len > 0 )
|
||||
{
|
||||
memcpy(&g_ble_data_buffer[index], output_data, output_len);
|
||||
index += output_len;
|
||||
}
|
||||
|
||||
if ( index >= voles_ble_buffer_size() || output_len <= 0 )
|
||||
{
|
||||
if (index >0)
|
||||
{
|
||||
am_app_KWD_AMA_stream_send(g_ble_data_buffer, index);
|
||||
index = 0;
|
||||
memset(g_ble_data_buffer, 0x0, sizeof(g_ble_data_buffer));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t output_size = ((voles_get_codec_type() == MSBC_CODEC_IN_USE) ? CODEC_MSBC_OUTPUT_SIZE : (CODEC_OPUS_OUTPUT_SIZE));
|
||||
|
||||
if (output_len == output_size)
|
||||
{
|
||||
voles_transmit_voice_data();
|
||||
}
|
||||
else if (output_len>0 && output_len<output_size)
|
||||
{
|
||||
am_app_KWD_AMA_stream_send(output_data, output_len);
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//extern opus_encoder_t* octopus_encoder_create(int option);
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn volesHandleValueCnf
|
||||
*
|
||||
* \brief Handle a received ATT handle value confirm.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void
|
||||
volesHandleValueCnf(attEvt_t *pMsg)
|
||||
{
|
||||
if (pMsg->hdr.status == ATT_SUCCESS)
|
||||
{
|
||||
if (g_start_voice_send)
|
||||
{
|
||||
voles_transmit_voice_data();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN2("cnf status = %d, hdl = 0x%x\n", pMsg->hdr.status, pMsg->handle);
|
||||
}
|
||||
}
|
||||
|
||||
void voles_opus_encoder_init(void)
|
||||
{
|
||||
//
|
||||
// Opus codec init
|
||||
//
|
||||
audio_enc_init(0);
|
||||
|
||||
APP_TRACE_INFO0("Opus encoder initialization is finished!\r\n\n");
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//6
|
||||
//! @brief initialize vole service
|
||||
//!
|
||||
//! @param handlerId - connection handle
|
||||
//! @param pCfg - configuration parameters
|
||||
//!
|
||||
//! @return None
|
||||
//
|
||||
//*****************************************************************************
|
||||
void voles_init(wsfHandlerId_t handlerId, eVoleCodecType codec_type)
|
||||
{
|
||||
memset(&volesCb, 0, sizeof(volesCb));
|
||||
volesCb.appHandlerId = handlerId;
|
||||
|
||||
volesCb.core.txPkt.data = voice_data;
|
||||
|
||||
if (codec_type == MSBC_CODEC_IN_USE)
|
||||
{
|
||||
sbc_encode_init(&g_SBCInstance, 1); //0: SBC
|
||||
}
|
||||
else if (codec_type == OPUS_CODEC_IN_USE)
|
||||
{
|
||||
voles_opus_encoder_init();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
voles_conn_close(dmEvt_t *pMsg)
|
||||
{
|
||||
hciDisconnectCmplEvt_t *evt = (hciDisconnectCmplEvt_t*) pMsg;
|
||||
dmConnId_t connId = evt->hdr.param;
|
||||
/* clear connection */
|
||||
volesCb.conn[connId - 1].connId = DM_CONN_ID_NONE;
|
||||
volesCb.conn[connId - 1].voleToSend = FALSE;
|
||||
|
||||
WsfTimerStop(&volesCb.core.timeoutTimer);
|
||||
volesCb.core.txState = VOLE_STATE_INIT;
|
||||
volesCb.core.rxState = VOLE_STATE_RX_IDLE;
|
||||
volesCb.core.lastRxPktSn = 0;
|
||||
volesCb.core.txPktSn = 0;
|
||||
VoleResetPkt(&volesCb.core.rxPkt);
|
||||
VoleResetPkt(&volesCb.core.txPkt);
|
||||
VoleResetPkt(&volesCb.core.ackPkt);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
voles_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
|
||||
{
|
||||
APP_TRACE_INFO3("write cb, len:%d, value %x %x", len, pValue[0], pValue[1]);
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
voles_start(dmConnId_t connId, uint8_t timerEvt, uint8_t voleCccIdx)
|
||||
{
|
||||
//
|
||||
// set conn id
|
||||
//
|
||||
volesCb.conn[connId - 1].connId = connId;
|
||||
volesCb.conn[connId - 1].voleToSend = TRUE;
|
||||
|
||||
volesCb.core.timeoutTimer.msg.event = timerEvt;
|
||||
volesCb.core.txState = VOLE_STATE_TX_IDLE;
|
||||
volesCb.txReady = true;
|
||||
|
||||
volesCb.core.attMtuSize = AttGetMtu(connId);
|
||||
APP_TRACE_INFO1("MTU size = %d bytes", volesCb.core.attMtuSize);
|
||||
}
|
||||
|
||||
void
|
||||
voles_stop(dmConnId_t connId)
|
||||
{
|
||||
//
|
||||
// clear connection
|
||||
//
|
||||
volesCb.conn[connId - 1].connId = DM_CONN_ID_NONE;
|
||||
volesCb.conn[connId - 1].voleToSend = FALSE;
|
||||
|
||||
volesCb.core.txState = VOLE_STATE_INIT;
|
||||
volesCb.txReady = false;
|
||||
}
|
||||
|
||||
|
||||
void voles_proc_msg(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
if (pMsg->event == DM_CONN_OPEN_IND)
|
||||
{
|
||||
voles_conn_open((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_CLOSE_IND)
|
||||
{
|
||||
voles_conn_close((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == DM_CONN_UPDATE_IND)
|
||||
{
|
||||
voles_conn_update((dmEvt_t *) pMsg);
|
||||
}
|
||||
else if (pMsg->event == ATTS_HANDLE_VALUE_CNF)
|
||||
{
|
||||
volesHandleValueCnf((attEvt_t *) pMsg);
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @file am_app_KWD_AMA.h
|
||||
//!
|
||||
//! @brief header file of AMA protocol handler
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2017, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision v1.2.11 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AM_APP_KWD_AMA_H
|
||||
#define AM_APP_KWD_AMA_H
|
||||
|
||||
#include "accessories.pb.h"
|
||||
|
||||
#define AMA_TRANSPORT_HEADER_VERSION_MASK 0xF000
|
||||
#define AMA_TRANSPORT_HEADER_STEAM_ID_MASK 0x0F80
|
||||
#define AMA_TRANSPORT_HEADER_LENGTH_TYPE_MASK 0x01
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if USE_OUTPUT_AMVOS_AMA
|
||||
uint8_t ama_buf[AMA_BUFFER_SIZE + 3];
|
||||
#else
|
||||
uint8_t* buf;
|
||||
#endif
|
||||
uint32_t len;
|
||||
uint32_t reserved;
|
||||
} sRadioQueue_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VOS_AMA_INIT = 0, // New state for disconnected time
|
||||
VOS_AMA_IDLE,
|
||||
VOS_AMA_LISTENING,
|
||||
VOS_AMA_PROCESSING,
|
||||
VOS_AMA_SPEAKING
|
||||
} eVosAmaStatus_t;
|
||||
|
||||
//*****************************************************************************
|
||||
// External function declaration
|
||||
//*****************************************************************************
|
||||
|
||||
extern bool am_app_KWD_AMA_start_speech_send(void);
|
||||
extern int am_app_KWD_AMA_rx_handler(uint8_t *data, uint16_t len);
|
||||
extern bool am_app_KWD_AMA_keep_alive_send(void);
|
||||
|
||||
extern uint32_t g_ui32AmaDialogID;
|
||||
extern eVosAmaStatus_t g_eAmaStatus;
|
||||
|
||||
#endif // #ifndef AM_APP_KWD_AMA_H
|
||||
BIN
Binary file not shown.
+239
@@ -0,0 +1,239 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// accessories.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_ACCESSORIES_PB_H_INCLUDED
|
||||
#define PB_ACCESSORIES_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#include "common.pb.h"
|
||||
|
||||
#include "system.pb.h"
|
||||
|
||||
#include "transport.pb.h"
|
||||
|
||||
#include "speech.pb.h"
|
||||
|
||||
#include "calling.pb.h"
|
||||
|
||||
#include "central.pb.h"
|
||||
|
||||
#include "device.pb.h"
|
||||
|
||||
#include "media.pb.h"
|
||||
|
||||
#include "state.pb.h"
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _Command
|
||||
{
|
||||
Command_NONE = 0,
|
||||
Command_RESET_CONNECTION = 51,
|
||||
Command_SYNCHRONIZE_SETTINGS = 50,
|
||||
Command_KEEP_ALIVE = 55,
|
||||
Command_REMOVE_DEVICE = 56,
|
||||
Command_UPGRADE_TRANSPORT = 30,
|
||||
Command_SWITCH_TRANSPORT = 31,
|
||||
Command_START_SPEECH = 11,
|
||||
Command_PROVIDE_SPEECH = 10,
|
||||
Command_STOP_SPEECH = 12,
|
||||
Command_ENDPOINT_SPEECH = 13,
|
||||
Command_NOTIFY_SPEECH_STATE = 14,
|
||||
Command_FORWARD_AT_COMMAND = 40,
|
||||
Command_INCOMING_CALL = 41,
|
||||
Command_GET_CENTRAL_INFORMATION = 103,
|
||||
Command_GET_DEVICE_INFORMATION = 20,
|
||||
Command_GET_DEVICE_CONFIGURATION = 21,
|
||||
Command_OVERRIDE_ASSISTANT = 22,
|
||||
Command_START_SETUP = 23,
|
||||
Command_COMPLETE_SETUP = 24,
|
||||
Command_NOTIFY_DEVICE_CONFIGURATION = 25,
|
||||
Command_UPDATE_DEVICE_INFORMATION = 26,
|
||||
Command_NOTIFY_DEVICE_INFORMATION = 27,
|
||||
Command_ISSUE_MEDIA_CONTROL = 60,
|
||||
Command_GET_STATE = 100,
|
||||
Command_SET_STATE = 101,
|
||||
Command_SYNCHRONIZE_STATE = 102
|
||||
} Command;
|
||||
#define _Command_MIN Command_NONE
|
||||
#define _Command_MAX Command_SYNCHRONIZE_STATE
|
||||
#define _Command_ARRAYSIZE ((Command)(Command_SYNCHRONIZE_STATE + 1))
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _Response
|
||||
{
|
||||
ErrorCode error_code;
|
||||
pb_size_t which_payload;
|
||||
union
|
||||
{
|
||||
DeviceInformation device_information;
|
||||
State state;
|
||||
ConnectionDetails connection_details;
|
||||
DeviceConfiguration device_configuration;
|
||||
CentralInformation central_information;
|
||||
Dialog dialog;
|
||||
SpeechProvider speech_provider;
|
||||
} payload;
|
||||
/* @@protoc_insertion_point(struct:Response) */
|
||||
} Response;
|
||||
|
||||
typedef struct _ControlEnvelope
|
||||
{
|
||||
Command command;
|
||||
pb_size_t which_payload;
|
||||
union
|
||||
{
|
||||
Response response;
|
||||
ProvideSpeech provide_speech;
|
||||
StartSpeech start_speech;
|
||||
StopSpeech stop_speech;
|
||||
EndpointSpeech endpoint_speech;
|
||||
NotifySpeechState notify_speech_state;
|
||||
GetDeviceInformation get_device_information;
|
||||
GetDeviceConfiguration get_device_configuration;
|
||||
OverrideAssistant override_assistant;
|
||||
StartSetup start_setup;
|
||||
CompleteSetup complete_setup;
|
||||
NotifyDeviceConfiguration notify_device_configuration;
|
||||
UpdateDeviceInformation update_device_information;
|
||||
NotifyDeviceInformation notify_device_information;
|
||||
UpgradeTransport upgrade_transport;
|
||||
SwitchTransport switch_transport;
|
||||
ForwardATCommand forward_at_command;
|
||||
IncomingCall incoming_call;
|
||||
SynchronizeSettings synchronize_settings;
|
||||
ResetConnection reset_connection;
|
||||
KeepAlive keep_alive;
|
||||
RemoveDevice remove_device;
|
||||
IssueMediaControl issue_media_control;
|
||||
GetState get_state;
|
||||
SetState set_state;
|
||||
SynchronizeState synchronize_state;
|
||||
GetCentralInformation get_central_information;
|
||||
} payload;
|
||||
/* @@protoc_insertion_point(struct:ControlEnvelope) */
|
||||
} ControlEnvelope;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define Response_init_default {_ErrorCode_MIN, 0, {DeviceInformation_init_default}}
|
||||
#define ControlEnvelope_init_default {_Command_MIN, 0, {Response_init_default}}
|
||||
#define Response_init_zero {_ErrorCode_MIN, 0, {DeviceInformation_init_zero}}
|
||||
#define ControlEnvelope_init_zero {_Command_MIN, 0, {Response_init_zero}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define Response_device_information_tag 3
|
||||
#define Response_state_tag 7
|
||||
#define Response_connection_details_tag 8
|
||||
#define Response_device_configuration_tag 10
|
||||
#define Response_central_information_tag 13
|
||||
#define Response_dialog_tag 14
|
||||
#define Response_speech_provider_tag 15
|
||||
#define Response_error_code_tag 1
|
||||
#define ControlEnvelope_response_tag 9
|
||||
#define ControlEnvelope_provide_speech_tag 10
|
||||
#define ControlEnvelope_start_speech_tag 11
|
||||
#define ControlEnvelope_stop_speech_tag 12
|
||||
#define ControlEnvelope_endpoint_speech_tag 13
|
||||
#define ControlEnvelope_notify_speech_state_tag 14
|
||||
#define ControlEnvelope_get_device_information_tag 20
|
||||
#define ControlEnvelope_get_device_configuration_tag 21
|
||||
#define ControlEnvelope_override_assistant_tag 22
|
||||
#define ControlEnvelope_start_setup_tag 23
|
||||
#define ControlEnvelope_complete_setup_tag 24
|
||||
#define ControlEnvelope_notify_device_configuration_tag 25
|
||||
#define ControlEnvelope_update_device_information_tag 26
|
||||
#define ControlEnvelope_notify_device_information_tag 27
|
||||
#define ControlEnvelope_upgrade_transport_tag 30
|
||||
#define ControlEnvelope_switch_transport_tag 31
|
||||
#define ControlEnvelope_forward_at_command_tag 40
|
||||
#define ControlEnvelope_incoming_call_tag 41
|
||||
#define ControlEnvelope_synchronize_settings_tag 50
|
||||
#define ControlEnvelope_reset_connection_tag 51
|
||||
#define ControlEnvelope_keep_alive_tag 55
|
||||
#define ControlEnvelope_remove_device_tag 56
|
||||
#define ControlEnvelope_issue_media_control_tag 60
|
||||
#define ControlEnvelope_get_state_tag 100
|
||||
#define ControlEnvelope_set_state_tag 101
|
||||
#define ControlEnvelope_synchronize_state_tag 102
|
||||
#define ControlEnvelope_get_central_information_tag 103
|
||||
#define ControlEnvelope_command_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t Response_fields[9];
|
||||
extern const pb_field_t ControlEnvelope_fields[29];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Response_size 104
|
||||
#define ControlEnvelope_size (2 + (UpdateDeviceInformation_size > 302 ? UpdateDeviceInformation_size : 302))
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define ACCESSORIES_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// calling.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_CALLING_PB_H_INCLUDED
|
||||
#define PB_CALLING_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _ForwardATCommand
|
||||
{
|
||||
char command[34];
|
||||
/* @@protoc_insertion_point(struct:ForwardATCommand) */
|
||||
} ForwardATCommand;
|
||||
|
||||
typedef struct _IncomingCall
|
||||
{
|
||||
char caller_number[34];
|
||||
/* @@protoc_insertion_point(struct:IncomingCall) */
|
||||
} IncomingCall;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ForwardATCommand_init_default {""}
|
||||
#define IncomingCall_init_default {""}
|
||||
#define ForwardATCommand_init_zero {""}
|
||||
#define IncomingCall_init_zero {""}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ForwardATCommand_command_tag 1
|
||||
#define IncomingCall_caller_number_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t ForwardATCommand_fields[2];
|
||||
extern const pb_field_t IncomingCall_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ForwardATCommand_size 36
|
||||
#define IncomingCall_size 36
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define CALLING_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// central.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_CENTRAL_PB_H_INCLUDED
|
||||
#define PB_CENTRAL_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _Platform
|
||||
{
|
||||
Platform_UNDEFINED = 0,
|
||||
Platform_IOS = 1,
|
||||
Platform_ANDROID = 2
|
||||
} Platform;
|
||||
#define _Platform_MIN Platform_UNDEFINED
|
||||
#define _Platform_MAX Platform_ANDROID
|
||||
#define _Platform_ARRAYSIZE ((Platform)(Platform_ANDROID + 1))
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _GetCentralInformation
|
||||
{
|
||||
char dummy_field;
|
||||
/* @@protoc_insertion_point(struct:GetCentralInformation) */
|
||||
} GetCentralInformation;
|
||||
|
||||
typedef struct _CentralInformation
|
||||
{
|
||||
char name[32];
|
||||
Platform platform;
|
||||
/* @@protoc_insertion_point(struct:CentralInformation) */
|
||||
} CentralInformation;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define CentralInformation_init_default {"", _Platform_MIN}
|
||||
#define GetCentralInformation_init_default {0}
|
||||
#define CentralInformation_init_zero {"", _Platform_MIN}
|
||||
#define GetCentralInformation_init_zero {0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define CentralInformation_name_tag 1
|
||||
#define CentralInformation_platform_tag 2
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t CentralInformation_fields[3];
|
||||
extern const pb_field_t GetCentralInformation_fields[1];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define CentralInformation_size 36
|
||||
#define GetCentralInformation_size 0
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define CENTRAL_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// common.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_COMMON_PB_H_INCLUDED
|
||||
#define PB_COMMON_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _Transport
|
||||
{
|
||||
Transport_BLUETOOTH_LOW_ENERGY = 0,
|
||||
Transport_BLUETOOTH_RFCOMM = 1,
|
||||
Transport_BLUETOOTH_IAP = 2
|
||||
} Transport;
|
||||
#define _Transport_MIN Transport_BLUETOOTH_LOW_ENERGY
|
||||
#define _Transport_MAX Transport_BLUETOOTH_IAP
|
||||
#define _Transport_ARRAYSIZE ((Transport)(Transport_BLUETOOTH_IAP + 1))
|
||||
|
||||
typedef enum _ErrorCode
|
||||
{
|
||||
ErrorCode_SUCCESS = 0,
|
||||
ErrorCode_UNKNOWN = 1,
|
||||
ErrorCode_INTERNAL = 2,
|
||||
ErrorCode_UNSUPPORTED = 3,
|
||||
ErrorCode_USER_CANCELLED = 4,
|
||||
ErrorCode_NOT_FOUND = 5,
|
||||
ErrorCode_INVALID = 6,
|
||||
ErrorCode_BUSY = 7
|
||||
} ErrorCode;
|
||||
#define _ErrorCode_MIN ErrorCode_SUCCESS
|
||||
#define _ErrorCode_MAX ErrorCode_BUSY
|
||||
#define _ErrorCode_ARRAYSIZE ((ErrorCode)(ErrorCode_BUSY + 1))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// device.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_DEVICE_PB_H_INCLUDED
|
||||
#define PB_DEVICE_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#include "common.pb.h"
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _ConnectionStatus
|
||||
{
|
||||
ConnectionStatus_CONNECTION_STATUS_UNKNOWN = 0,
|
||||
ConnectionStatus_CONNECTION_STATUS_CONNECTED = 1,
|
||||
ConnectionStatus_CONNECTION_STATUS_DISCONNECTED = 2
|
||||
} ConnectionStatus;
|
||||
#define _ConnectionStatus_MIN ConnectionStatus_CONNECTION_STATUS_UNKNOWN
|
||||
#define _ConnectionStatus_MAX ConnectionStatus_CONNECTION_STATUS_DISCONNECTED
|
||||
#define _ConnectionStatus_ARRAYSIZE ((ConnectionStatus)(ConnectionStatus_CONNECTION_STATUS_DISCONNECTED + 1))
|
||||
|
||||
typedef enum _DevicePresence
|
||||
{
|
||||
DevicePresence_DEVICE_PRESENCE_UNKNOWN = 0,
|
||||
DevicePresence_DEVICE_PRESENCE_ACTIVE = 1,
|
||||
DevicePresence_DEVICE_PRESENCE_INACTIVE = 2,
|
||||
DevicePresence_DEVICE_PRESENCE_ACCESSIBLE = 3
|
||||
} DevicePresence;
|
||||
#define _DevicePresence_MIN DevicePresence_DEVICE_PRESENCE_UNKNOWN
|
||||
#define _DevicePresence_MAX DevicePresence_DEVICE_PRESENCE_ACCESSIBLE
|
||||
#define _DevicePresence_ARRAYSIZE ((DevicePresence)(DevicePresence_DEVICE_PRESENCE_ACCESSIBLE + 1))
|
||||
|
||||
typedef enum _DeviceBattery_Status
|
||||
{
|
||||
DeviceBattery_Status_UNKNOWN = 0,
|
||||
DeviceBattery_Status_CHARGING = 1,
|
||||
DeviceBattery_Status_DISCHARGING = 2,
|
||||
DeviceBattery_Status_FULL = 3
|
||||
} DeviceBattery_Status;
|
||||
#define _DeviceBattery_Status_MIN DeviceBattery_Status_UNKNOWN
|
||||
#define _DeviceBattery_Status_MAX DeviceBattery_Status_FULL
|
||||
#define _DeviceBattery_Status_ARRAYSIZE ((DeviceBattery_Status)(DeviceBattery_Status_FULL + 1))
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _GetDeviceConfiguration
|
||||
{
|
||||
char dummy_field;
|
||||
/* @@protoc_insertion_point(struct:GetDeviceConfiguration) */
|
||||
} GetDeviceConfiguration;
|
||||
|
||||
typedef struct _StartSetup
|
||||
{
|
||||
char dummy_field;
|
||||
/* @@protoc_insertion_point(struct:StartSetup) */
|
||||
} StartSetup;
|
||||
|
||||
typedef struct _UpdateDeviceInformation
|
||||
{
|
||||
pb_callback_t name;
|
||||
/* @@protoc_insertion_point(struct:UpdateDeviceInformation) */
|
||||
} UpdateDeviceInformation;
|
||||
|
||||
typedef struct _CompleteSetup
|
||||
{
|
||||
ErrorCode error_code;
|
||||
/* @@protoc_insertion_point(struct:CompleteSetup) */
|
||||
} CompleteSetup;
|
||||
|
||||
typedef struct _DeviceBattery
|
||||
{
|
||||
uint32_t level;
|
||||
uint32_t scale;
|
||||
DeviceBattery_Status status;
|
||||
/* @@protoc_insertion_point(struct:DeviceBattery) */
|
||||
} DeviceBattery;
|
||||
|
||||
typedef struct _DeviceConfiguration
|
||||
{
|
||||
bool needs_assistant_override;
|
||||
bool needs_setup;
|
||||
/* @@protoc_insertion_point(struct:DeviceConfiguration) */
|
||||
} DeviceConfiguration;
|
||||
|
||||
typedef struct _DeviceStatus
|
||||
{
|
||||
ConnectionStatus link;
|
||||
ConnectionStatus nfmi;
|
||||
DevicePresence presence;
|
||||
/* @@protoc_insertion_point(struct:DeviceStatus) */
|
||||
} DeviceStatus;
|
||||
|
||||
typedef struct _GetDeviceInformation
|
||||
{
|
||||
uint32_t device_id;
|
||||
/* @@protoc_insertion_point(struct:GetDeviceInformation) */
|
||||
} GetDeviceInformation;
|
||||
|
||||
typedef struct _OverrideAssistant
|
||||
{
|
||||
ErrorCode error_code;
|
||||
/* @@protoc_insertion_point(struct:OverrideAssistant) */
|
||||
} OverrideAssistant;
|
||||
|
||||
typedef struct _DeviceInformation
|
||||
{
|
||||
char serial_number[20];
|
||||
char name[16];
|
||||
pb_size_t supported_transports_count;
|
||||
Transport supported_transports[4];
|
||||
char device_type[14];
|
||||
uint32_t device_id;
|
||||
DeviceBattery battery;
|
||||
DeviceStatus status;
|
||||
uint32_t product_color;
|
||||
/* @@protoc_insertion_point(struct:DeviceInformation) */
|
||||
} DeviceInformation;
|
||||
|
||||
typedef struct _NotifyDeviceConfiguration
|
||||
{
|
||||
DeviceConfiguration device_configuration;
|
||||
/* @@protoc_insertion_point(struct:NotifyDeviceConfiguration) */
|
||||
} NotifyDeviceConfiguration;
|
||||
|
||||
typedef struct _NotifyDeviceInformation
|
||||
{
|
||||
DeviceInformation device_information;
|
||||
/* @@protoc_insertion_point(struct:NotifyDeviceInformation) */
|
||||
} NotifyDeviceInformation;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define DeviceBattery_init_default {0, 0, _DeviceBattery_Status_MIN}
|
||||
#define DeviceStatus_init_default {_ConnectionStatus_MIN, _ConnectionStatus_MIN, _DevicePresence_MIN}
|
||||
#define DeviceInformation_init_default {"", "", 0, {_Transport_MIN, _Transport_MIN, _Transport_MIN, _Transport_MIN}, "", 0, DeviceBattery_init_default, DeviceStatus_init_default, 0}
|
||||
#define GetDeviceInformation_init_default {0}
|
||||
#define DeviceConfiguration_init_default {0, 0}
|
||||
#define GetDeviceConfiguration_init_default {0}
|
||||
#define OverrideAssistant_init_default {_ErrorCode_MIN}
|
||||
#define StartSetup_init_default {0}
|
||||
#define CompleteSetup_init_default {_ErrorCode_MIN}
|
||||
#define NotifyDeviceConfiguration_init_default {DeviceConfiguration_init_default}
|
||||
#define UpdateDeviceInformation_init_default {{{NULL}, NULL}}
|
||||
#define NotifyDeviceInformation_init_default {DeviceInformation_init_default}
|
||||
#define DeviceBattery_init_zero {0, 0, _DeviceBattery_Status_MIN}
|
||||
#define DeviceStatus_init_zero {_ConnectionStatus_MIN, _ConnectionStatus_MIN, _DevicePresence_MIN}
|
||||
#define DeviceInformation_init_zero {"", "", 0, {_Transport_MIN, _Transport_MIN, _Transport_MIN, _Transport_MIN}, "", 0, DeviceBattery_init_zero, DeviceStatus_init_zero, 0}
|
||||
#define GetDeviceInformation_init_zero {0}
|
||||
#define DeviceConfiguration_init_zero {0, 0}
|
||||
#define GetDeviceConfiguration_init_zero {0}
|
||||
#define OverrideAssistant_init_zero {_ErrorCode_MIN}
|
||||
#define StartSetup_init_zero {0}
|
||||
#define CompleteSetup_init_zero {_ErrorCode_MIN}
|
||||
#define NotifyDeviceConfiguration_init_zero {DeviceConfiguration_init_zero}
|
||||
#define UpdateDeviceInformation_init_zero {{{NULL}, NULL}}
|
||||
#define NotifyDeviceInformation_init_zero {DeviceInformation_init_zero}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define UpdateDeviceInformation_name_tag 1
|
||||
#define CompleteSetup_error_code_tag 1
|
||||
#define DeviceBattery_level_tag 1
|
||||
#define DeviceBattery_scale_tag 2
|
||||
#define DeviceBattery_status_tag 3
|
||||
#define DeviceConfiguration_needs_assistant_override_tag 1
|
||||
#define DeviceConfiguration_needs_setup_tag 2
|
||||
#define DeviceStatus_link_tag 1
|
||||
#define DeviceStatus_nfmi_tag 2
|
||||
#define DeviceStatus_presence_tag 3
|
||||
#define GetDeviceInformation_device_id_tag 1
|
||||
#define OverrideAssistant_error_code_tag 1
|
||||
#define DeviceInformation_serial_number_tag 1
|
||||
#define DeviceInformation_name_tag 2
|
||||
#define DeviceInformation_supported_transports_tag 3
|
||||
#define DeviceInformation_device_type_tag 4
|
||||
#define DeviceInformation_device_id_tag 5
|
||||
#define DeviceInformation_battery_tag 6
|
||||
#define DeviceInformation_status_tag 7
|
||||
#define DeviceInformation_product_color_tag 8
|
||||
#define NotifyDeviceConfiguration_device_configuration_tag 1
|
||||
#define NotifyDeviceInformation_device_information_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t DeviceBattery_fields[4];
|
||||
extern const pb_field_t DeviceStatus_fields[4];
|
||||
extern const pb_field_t DeviceInformation_fields[9];
|
||||
extern const pb_field_t GetDeviceInformation_fields[2];
|
||||
extern const pb_field_t DeviceConfiguration_fields[3];
|
||||
extern const pb_field_t GetDeviceConfiguration_fields[1];
|
||||
extern const pb_field_t OverrideAssistant_fields[2];
|
||||
extern const pb_field_t StartSetup_fields[1];
|
||||
extern const pb_field_t CompleteSetup_fields[2];
|
||||
extern const pb_field_t NotifyDeviceConfiguration_fields[2];
|
||||
extern const pb_field_t UpdateDeviceInformation_fields[2];
|
||||
extern const pb_field_t NotifyDeviceInformation_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define DeviceBattery_size 14
|
||||
#define DeviceStatus_size 6
|
||||
#define DeviceInformation_size 100
|
||||
#define GetDeviceInformation_size 6
|
||||
#define DeviceConfiguration_size 4
|
||||
#define GetDeviceConfiguration_size 0
|
||||
#define OverrideAssistant_size 2
|
||||
#define StartSetup_size 0
|
||||
#define CompleteSetup_size 2
|
||||
#define NotifyDeviceConfiguration_size 6
|
||||
/* UpdateDeviceInformation_size depends on runtime parameters */
|
||||
#define NotifyDeviceInformation_size 102
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define DEVICE_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// media.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_MEDIA_PB_H_INCLUDED
|
||||
#define PB_MEDIA_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _MediaControl
|
||||
{
|
||||
MediaControl_PLAY = 0,
|
||||
MediaControl_PAUSE = 1,
|
||||
MediaControl_NEXT = 2,
|
||||
MediaControl_PREVIOUS = 3,
|
||||
MediaControl_PLAY_PAUSE = 4
|
||||
} MediaControl;
|
||||
#define _MediaControl_MIN MediaControl_PLAY
|
||||
#define _MediaControl_MAX MediaControl_PLAY_PAUSE
|
||||
#define _MediaControl_ARRAYSIZE ((MediaControl)(MediaControl_PLAY_PAUSE + 1))
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _IssueMediaControl
|
||||
{
|
||||
MediaControl control;
|
||||
/* @@protoc_insertion_point(struct:IssueMediaControl) */
|
||||
} IssueMediaControl;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define IssueMediaControl_init_default {_MediaControl_MIN}
|
||||
#define IssueMediaControl_init_zero {_MediaControl_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define IssueMediaControl_control_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t IssueMediaControl_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define IssueMediaControl_size 2
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define MEDIA_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,649 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Common parts of the nanopb library. Most of these are quite low-level
|
||||
* stuff. For the high-level interface, see pb_encode.h and pb_decode.h.
|
||||
*/
|
||||
|
||||
#ifndef PB_H_INCLUDED
|
||||
#define PB_H_INCLUDED
|
||||
|
||||
/*****************************************************************
|
||||
* Nanopb compilation time options. You can change these here by *
|
||||
* uncommenting the lines, or on the compiler command line. *
|
||||
*****************************************************************/
|
||||
|
||||
/* Enable support for dynamically allocated fields */
|
||||
/* #define PB_ENABLE_MALLOC 1 */
|
||||
|
||||
/* Define this if your CPU / compiler combination does not support
|
||||
* unaligned memory access to packed structures. */
|
||||
/* #define PB_NO_PACKED_STRUCTS 1 */
|
||||
|
||||
/* Increase the number of required fields that are tracked.
|
||||
* A compiler warning will tell if you need this. */
|
||||
/* #define PB_MAX_REQUIRED_FIELDS 256 */
|
||||
|
||||
/* Add support for tag numbers > 255 and fields larger than 255 bytes. */
|
||||
/* #define PB_FIELD_16BIT 1 */
|
||||
#define PB_FIELD_16BIT 1
|
||||
|
||||
/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */
|
||||
/* #define PB_FIELD_32BIT 1 */
|
||||
|
||||
/* Disable support for error messages in order to save some code space. */
|
||||
/* #define PB_NO_ERRMSG 1 */
|
||||
|
||||
/* Disable support for custom streams (support only memory buffers). */
|
||||
/* #define PB_BUFFER_ONLY 1 */
|
||||
|
||||
/* Switch back to the old-style callback function signature.
|
||||
* This was the default until nanopb-0.2.1. */
|
||||
/* #define PB_OLD_CALLBACK_STYLE */
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* You usually don't need to change anything below this line. *
|
||||
* Feel free to look around and use the defined macros, though. *
|
||||
******************************************************************/
|
||||
|
||||
|
||||
/* Version of the nanopb library. Just in case you want to check it in
|
||||
* your own program. */
|
||||
#define NANOPB_VERSION nanopb-0.3.9.1
|
||||
|
||||
/* Include all the system headers needed by nanopb. You will need the
|
||||
* definitions of the following:
|
||||
* - strlen, memcpy, memset functions
|
||||
* - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t
|
||||
* - size_t
|
||||
* - bool
|
||||
*
|
||||
* If you don't have the standard header files, you can instead provide
|
||||
* a custom header that defines or includes all this. In that case,
|
||||
* define PB_SYSTEM_HEADER to the path of this file.
|
||||
*/
|
||||
#ifdef PB_SYSTEM_HEADER
|
||||
#include PB_SYSTEM_HEADER
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PB_ENABLE_MALLOC
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macro for defining packed structures (compiler dependent).
|
||||
* This just reduces memory requirements, but is not required.
|
||||
*/
|
||||
#if defined(PB_NO_PACKED_STRUCTS)
|
||||
/* Disable struct packing */
|
||||
# define PB_PACKED_STRUCT_START
|
||||
# define PB_PACKED_STRUCT_END
|
||||
# define pb_packed
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
/* For GCC and clang */
|
||||
# define PB_PACKED_STRUCT_START
|
||||
# define PB_PACKED_STRUCT_END
|
||||
# define pb_packed __attribute__((packed))
|
||||
#elif defined(__ICCARM__) || defined(__CC_ARM)
|
||||
/* For IAR ARM and Keil MDK-ARM compilers */
|
||||
# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)")
|
||||
# define PB_PACKED_STRUCT_END _Pragma("pack(pop)")
|
||||
# define pb_packed
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
/* For Microsoft Visual C++ */
|
||||
# define PB_PACKED_STRUCT_START __pragma(pack(push, 1))
|
||||
# define PB_PACKED_STRUCT_END __pragma(pack(pop))
|
||||
# define pb_packed
|
||||
#else
|
||||
/* Unknown compiler */
|
||||
# define PB_PACKED_STRUCT_START
|
||||
# define PB_PACKED_STRUCT_END
|
||||
# define pb_packed
|
||||
#endif
|
||||
|
||||
/* Handly macro for suppressing unreferenced-parameter compiler warnings. */
|
||||
#ifndef PB_UNUSED
|
||||
#define PB_UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
/* Compile-time assertion, used for checking compatible compilation options.
|
||||
* If this does not work properly on your compiler, use
|
||||
* #define PB_NO_STATIC_ASSERT to disable it.
|
||||
*
|
||||
* But before doing that, check carefully the error message / place where it
|
||||
* comes from to see if the error has a real cause. Unfortunately the error
|
||||
* message is not always very clear to read, but you can see the reason better
|
||||
* in the place where the PB_STATIC_ASSERT macro was called.
|
||||
*/
|
||||
#ifndef PB_NO_STATIC_ASSERT
|
||||
#ifndef PB_STATIC_ASSERT
|
||||
#define PB_STATIC_ASSERT(COND, MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND) ? 1 : -1];
|
||||
#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
|
||||
#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER
|
||||
#endif
|
||||
#else
|
||||
#define PB_STATIC_ASSERT(COND, MSG)
|
||||
#endif
|
||||
|
||||
/* Number of required fields to keep track of. */
|
||||
#ifndef PB_MAX_REQUIRED_FIELDS
|
||||
#define PB_MAX_REQUIRED_FIELDS 64
|
||||
#endif
|
||||
|
||||
#if PB_MAX_REQUIRED_FIELDS < 64
|
||||
#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64).
|
||||
#endif
|
||||
|
||||
/* List of possible field types. These are used in the autogenerated code.
|
||||
* Least-significant 4 bits tell the scalar type
|
||||
* Most-significant 4 bits specify repeated/required/packed etc.
|
||||
*/
|
||||
|
||||
typedef uint_least8_t pb_type_t;
|
||||
|
||||
/**** Field data types ****/
|
||||
|
||||
/* Numeric types */
|
||||
#define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */
|
||||
#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */
|
||||
#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */
|
||||
#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */
|
||||
#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */
|
||||
|
||||
/* Marker for last packable field type. */
|
||||
#define PB_LTYPE_LAST_PACKABLE 0x04
|
||||
|
||||
/* Byte array with pre-allocated buffer.
|
||||
* data_size is the length of the allocated PB_BYTES_ARRAY structure. */
|
||||
#define PB_LTYPE_BYTES 0x05
|
||||
|
||||
/* String with pre-allocated buffer.
|
||||
* data_size is the maximum length. */
|
||||
#define PB_LTYPE_STRING 0x06
|
||||
|
||||
/* Submessage
|
||||
* submsg_fields is pointer to field descriptions */
|
||||
#define PB_LTYPE_SUBMESSAGE 0x07
|
||||
|
||||
/* Extension pseudo-field
|
||||
* The field contains a pointer to pb_extension_t */
|
||||
#define PB_LTYPE_EXTENSION 0x08
|
||||
|
||||
/* Byte array with inline, pre-allocated byffer.
|
||||
* data_size is the length of the inline, allocated buffer.
|
||||
* This differs from PB_LTYPE_BYTES by defining the element as
|
||||
* pb_byte_t[data_size] rather than pb_bytes_array_t. */
|
||||
#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09
|
||||
|
||||
/* Number of declared LTYPES */
|
||||
#define PB_LTYPES_COUNT 0x0A
|
||||
#define PB_LTYPE_MASK 0x0F
|
||||
|
||||
/**** Field repetition rules ****/
|
||||
|
||||
#define PB_HTYPE_REQUIRED 0x00
|
||||
#define PB_HTYPE_OPTIONAL 0x10
|
||||
#define PB_HTYPE_REPEATED 0x20
|
||||
#define PB_HTYPE_ONEOF 0x30
|
||||
#define PB_HTYPE_MASK 0x30
|
||||
|
||||
/**** Field allocation types ****/
|
||||
|
||||
#define PB_ATYPE_STATIC 0x00
|
||||
#define PB_ATYPE_POINTER 0x80
|
||||
#define PB_ATYPE_CALLBACK 0x40
|
||||
#define PB_ATYPE_MASK 0xC0
|
||||
|
||||
#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK)
|
||||
#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK)
|
||||
#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK)
|
||||
|
||||
/* Data type used for storing sizes of struct fields
|
||||
* and array counts.
|
||||
*/
|
||||
#if defined(PB_FIELD_32BIT)
|
||||
typedef uint32_t pb_size_t;
|
||||
typedef int32_t pb_ssize_t;
|
||||
#elif defined(PB_FIELD_16BIT)
|
||||
typedef uint_least16_t pb_size_t;
|
||||
typedef int_least16_t pb_ssize_t;
|
||||
#else
|
||||
typedef uint_least8_t pb_size_t;
|
||||
typedef int_least8_t pb_ssize_t;
|
||||
#endif
|
||||
#define PB_SIZE_MAX ((pb_size_t)-1)
|
||||
|
||||
/* Data type for storing encoded data and other byte streams.
|
||||
* This typedef exists to support platforms where uint8_t does not exist.
|
||||
* You can regard it as equivalent on uint8_t on other platforms.
|
||||
*/
|
||||
typedef uint_least8_t pb_byte_t;
|
||||
|
||||
/* This structure is used in auto-generated constants
|
||||
* to specify struct fields.
|
||||
* You can change field sizes if you need structures
|
||||
* larger than 256 bytes or field tags larger than 256.
|
||||
* The compiler should complain if your .proto has such
|
||||
* structures. Fix that by defining PB_FIELD_16BIT or
|
||||
* PB_FIELD_32BIT.
|
||||
*/
|
||||
PB_PACKED_STRUCT_START
|
||||
typedef struct pb_field_s pb_field_t;
|
||||
struct pb_field_s
|
||||
{
|
||||
pb_size_t tag;
|
||||
pb_type_t type;
|
||||
pb_size_t data_offset; /* Offset of field data, relative to previous field. */
|
||||
pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */
|
||||
pb_size_t data_size; /* Data size in bytes for a single item */
|
||||
pb_size_t array_size; /* Maximum number of entries in array */
|
||||
|
||||
/* Field definitions for submessage
|
||||
* OR default value for all other non-array, non-callback types
|
||||
* If null, then field will zeroed. */
|
||||
const void *ptr;
|
||||
} pb_packed;
|
||||
PB_PACKED_STRUCT_END
|
||||
|
||||
/* Make sure that the standard integer types are of the expected sizes.
|
||||
* Otherwise fixed32/fixed64 fields can break.
|
||||
*
|
||||
* If you get errors here, it probably means that your stdint.h is not
|
||||
* correct for your platform.
|
||||
*/
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE)
|
||||
PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE)
|
||||
#endif
|
||||
|
||||
/* This structure is used for 'bytes' arrays.
|
||||
* It has the number of bytes in the beginning, and after that an array.
|
||||
* Note that actual structs used will have a different length of bytes array.
|
||||
*/
|
||||
#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; }
|
||||
#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))
|
||||
|
||||
struct pb_bytes_array_s
|
||||
{
|
||||
pb_size_t size;
|
||||
pb_byte_t bytes[1];
|
||||
};
|
||||
typedef struct pb_bytes_array_s pb_bytes_array_t;
|
||||
|
||||
/* This structure is used for giving the callback function.
|
||||
* It is stored in the message structure and filled in by the method that
|
||||
* calls pb_decode.
|
||||
*
|
||||
* The decoding callback will be given a limited-length stream
|
||||
* If the wire type was string, the length is the length of the string.
|
||||
* If the wire type was a varint/fixed32/fixed64, the length is the length
|
||||
* of the actual value.
|
||||
* The function may be called multiple times (especially for repeated types,
|
||||
* but also otherwise if the message happens to contain the field multiple
|
||||
* times.)
|
||||
*
|
||||
* The encoding callback will receive the actual output stream.
|
||||
* It should write all the data in one call, including the field tag and
|
||||
* wire type. It can write multiple fields.
|
||||
*
|
||||
* The callback can be null if you want to skip a field.
|
||||
*/
|
||||
typedef struct pb_istream_s pb_istream_t;
|
||||
typedef struct pb_ostream_s pb_ostream_t;
|
||||
typedef struct pb_callback_s pb_callback_t;
|
||||
struct pb_callback_s
|
||||
{
|
||||
#ifdef PB_OLD_CALLBACK_STYLE
|
||||
/* Deprecated since nanopb-0.2.1 */
|
||||
union
|
||||
{
|
||||
bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);
|
||||
bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg);
|
||||
} funcs;
|
||||
#else
|
||||
/* New function signature, which allows modifying arg contents in callback. */
|
||||
union
|
||||
{
|
||||
bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg);
|
||||
bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg);
|
||||
} funcs;
|
||||
#endif
|
||||
|
||||
/* Free arg for use by callback */
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/* Wire types. Library user needs these only in encoder callbacks. */
|
||||
typedef enum
|
||||
{
|
||||
PB_WT_VARINT = 0,
|
||||
PB_WT_64BIT = 1,
|
||||
PB_WT_STRING = 2,
|
||||
PB_WT_32BIT = 5
|
||||
} pb_wire_type_t;
|
||||
|
||||
/* Structure for defining the handling of unknown/extension fields.
|
||||
* Usually the pb_extension_type_t structure is automatically generated,
|
||||
* while the pb_extension_t structure is created by the user. However,
|
||||
* if you want to catch all unknown fields, you can also create a custom
|
||||
* pb_extension_type_t with your own callback.
|
||||
*/
|
||||
typedef struct pb_extension_type_s pb_extension_type_t;
|
||||
typedef struct pb_extension_s pb_extension_t;
|
||||
struct pb_extension_type_s
|
||||
{
|
||||
/* Called for each unknown field in the message.
|
||||
* If you handle the field, read off all of its data and return true.
|
||||
* If you do not handle the field, do not read anything and return true.
|
||||
* If you run into an error, return false.
|
||||
* Set to NULL for default handler.
|
||||
*/
|
||||
bool (*decode)(pb_istream_t *stream, pb_extension_t *extension,
|
||||
uint32_t tag, pb_wire_type_t wire_type);
|
||||
|
||||
/* Called once after all regular fields have been encoded.
|
||||
* If you have something to write, do so and return true.
|
||||
* If you do not have anything to write, just return true.
|
||||
* If you run into an error, return false.
|
||||
* Set to NULL for default handler.
|
||||
*/
|
||||
bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension);
|
||||
|
||||
/* Free field for use by the callback. */
|
||||
const void *arg;
|
||||
};
|
||||
|
||||
struct pb_extension_s
|
||||
{
|
||||
/* Type describing the extension field. Usually you'll initialize
|
||||
* this to a pointer to the automatically generated structure. */
|
||||
const pb_extension_type_t *type;
|
||||
|
||||
/* Destination for the decoded data. This must match the datatype
|
||||
* of the extension field. */
|
||||
void *dest;
|
||||
|
||||
/* Pointer to the next extension handler, or NULL.
|
||||
* If this extension does not match a field, the next handler is
|
||||
* automatically called. */
|
||||
pb_extension_t *next;
|
||||
|
||||
/* The decoder sets this to true if the extension was found.
|
||||
* Ignored for encoding. */
|
||||
bool found;
|
||||
};
|
||||
|
||||
/* Memory allocation functions to use. You can define pb_realloc and
|
||||
* pb_free to custom functions if you want. */
|
||||
#ifdef PB_ENABLE_MALLOC
|
||||
# ifndef pb_realloc
|
||||
# define pb_realloc(ptr, size) realloc(ptr, size)
|
||||
# endif
|
||||
# ifndef pb_free
|
||||
# define pb_free(ptr) free(ptr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This is used to inform about need to regenerate .pb.h/.pb.c files. */
|
||||
#define PB_PROTO_HEADER_VERSION 30
|
||||
|
||||
/* These macros are used to declare pb_field_t's in the constant array. */
|
||||
/* Size of a structure member, in bytes. */
|
||||
#define pb_membersize(st, m) (sizeof ((st*)0)->m)
|
||||
/* Number of entries in an array. */
|
||||
#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0]))
|
||||
/* Delta from start of one member to the start of another member. */
|
||||
#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2))
|
||||
/* Marks the end of the field list */
|
||||
#define PB_LAST_FIELD {0, (pb_type_t)0, 0, 0, 0, 0, 0}
|
||||
|
||||
/* Macros for filling in the data_offset field */
|
||||
/* data_offset for first field in a message */
|
||||
#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))
|
||||
/* data_offset for subsequent fields */
|
||||
#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
|
||||
/* data offset for subsequent fields inside an union (oneof) */
|
||||
#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX)
|
||||
/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */
|
||||
#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \
|
||||
? PB_DATAOFFSET_FIRST(st, m1, m2) \
|
||||
: PB_DATAOFFSET_OTHER(st, m1, m2))
|
||||
|
||||
/* Required fields are the simplest. They just have delta (padding) from
|
||||
* previous field end, and the size of the field. Pointer is used for
|
||||
* submessages and default values.
|
||||
*/
|
||||
#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
/* Optional fields add the delta to the has_ variable. */
|
||||
#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, \
|
||||
pb_delta(st, has_ ## m, m), \
|
||||
pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
/* Repeated fields have a _count field and also the maximum number of entries. */
|
||||
#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \
|
||||
fd, \
|
||||
pb_delta(st, m ## _count, m), \
|
||||
pb_membersize(st, m[0]), \
|
||||
pb_arraysize(st, m), ptr}
|
||||
|
||||
/* Allocated fields carry the size of the actual data, not the pointer */
|
||||
#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \
|
||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Optional fields don't need a has_ variable, as information would be redundant */
|
||||
#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Same as optional fields*/
|
||||
#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Repeated fields have a _count field and a pointer to array of pointers */
|
||||
#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
|
||||
fd, pb_delta(st, m ## _count, m), \
|
||||
pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Callbacks are much like required fields except with special datatype. */
|
||||
#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \
|
||||
fd, 0, pb_membersize(st, m), 0, ptr}
|
||||
|
||||
/* Optional extensions don't have the has_ field, as that would be redundant.
|
||||
* Furthermore, the combination of OPTIONAL without has_ field is used
|
||||
* for indicating proto3 style fields. Extensions exist in proto2 mode only,
|
||||
* so they should be encoded according to proto2 rules. To avoid the conflict,
|
||||
* extensions are marked as REQUIRED instead.
|
||||
*/
|
||||
#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
|
||||
0, \
|
||||
0, \
|
||||
pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr)
|
||||
|
||||
#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr)
|
||||
|
||||
/* The mapping from protobuf types to LTYPEs is done using these macros. */
|
||||
#define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES
|
||||
#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64
|
||||
#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT
|
||||
#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32
|
||||
#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64
|
||||
#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32
|
||||
#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE
|
||||
#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32
|
||||
#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64
|
||||
#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
||||
#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
||||
#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
||||
#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
|
||||
#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
|
||||
#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
||||
#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES
|
||||
|
||||
/* This is the actual macro used in field descriptions.
|
||||
* It takes these arguments:
|
||||
* - Field tag number
|
||||
* - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64,
|
||||
* FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64
|
||||
* SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION
|
||||
* - Field rules: REQUIRED, OPTIONAL or REPEATED
|
||||
* - Allocation: STATIC, CALLBACK or POINTER
|
||||
* - Placement: FIRST or OTHER, depending on if this is the first field in structure.
|
||||
* - Message name
|
||||
* - Field name
|
||||
* - Previous field name (or field name again for first field)
|
||||
* - Pointer to default value or submsg fields.
|
||||
*/
|
||||
|
||||
#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
|
||||
PB_ ## rules ## _ ## allocation(tag, message, field, \
|
||||
PB_DATAOFFSET_ ## placement(message, field, prevfield), \
|
||||
PB_LTYPE_MAP_ ## type, ptr)
|
||||
|
||||
/* Field description for repeated static fixed count fields.*/
|
||||
#define PB_REPEATED_FIXED_COUNT(tag, type, placement, message, field, prevfield, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | PB_LTYPE_MAP_ ## type, \
|
||||
PB_DATAOFFSET_ ## placement(message, field, prevfield), \
|
||||
0, \
|
||||
pb_membersize(message, field[0]), \
|
||||
pb_arraysize(message, field), ptr}
|
||||
|
||||
/* Field description for oneof fields. This requires taking into account the
|
||||
* union name also, that's why a separate set of macros is needed.
|
||||
*/
|
||||
#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
|
||||
fd, pb_delta(st, which_ ## u, u.m), \
|
||||
pb_membersize(st, u.m), 0, ptr}
|
||||
|
||||
#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
|
||||
fd, pb_delta(st, which_ ## u, u.m), \
|
||||
pb_membersize(st, u.m[0]), 0, ptr}
|
||||
|
||||
#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
|
||||
PB_ONEOF_ ## allocation(union_name, tag, message, field, \
|
||||
PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \
|
||||
PB_LTYPE_MAP_ ## type, ptr)
|
||||
|
||||
#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
|
||||
fd, pb_delta(st, which_ ## u, m), \
|
||||
pb_membersize(st, m), 0, ptr}
|
||||
|
||||
#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
|
||||
fd, pb_delta(st, which_ ## u, m), \
|
||||
pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
|
||||
PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \
|
||||
PB_DATAOFFSET_ ## placement(message, field, prevfield), \
|
||||
PB_LTYPE_MAP_ ## type, ptr)
|
||||
|
||||
/* These macros are used for giving out error messages.
|
||||
* They are mostly a debugging aid; the main error information
|
||||
* is the true/false return value from functions.
|
||||
* Some code space can be saved by disabling the error
|
||||
* messages if not used.
|
||||
*
|
||||
* PB_SET_ERROR() sets the error message if none has been set yet.
|
||||
* msg must be a constant string literal.
|
||||
* PB_GET_ERROR() always returns a pointer to a string.
|
||||
* PB_RETURN_ERROR() sets the error and returns false from current
|
||||
* function.
|
||||
*/
|
||||
#ifdef PB_NO_ERRMSG
|
||||
#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream)
|
||||
#define PB_GET_ERROR(stream) "(errmsg disabled)"
|
||||
#else
|
||||
#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg))
|
||||
#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
|
||||
#endif
|
||||
|
||||
#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// bp_common.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c.
|
||||
* These functions are rarely needed by applications directly.
|
||||
*/
|
||||
|
||||
#ifndef PB_COMMON_H_INCLUDED
|
||||
#define PB_COMMON_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Iterator for pb_field_t list */
|
||||
struct pb_field_iter_s
|
||||
{
|
||||
const pb_field_t *start; /* Start of the pb_field_t array */
|
||||
const pb_field_t *pos; /* Current position of the iterator */
|
||||
unsigned required_field_index; /* Zero-based index that counts only the required fields */
|
||||
void *dest_struct; /* Pointer to start of the structure */
|
||||
void *pData; /* Pointer to current field value */
|
||||
void *pSize; /* Pointer to count/has field */
|
||||
};
|
||||
typedef struct pb_field_iter_s pb_field_iter_t;
|
||||
|
||||
/* Initialize the field iterator structure to beginning.
|
||||
* Returns false if the message type is empty. */
|
||||
bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct);
|
||||
|
||||
/* Advance the iterator to the next field.
|
||||
* Returns false when the iterator wraps back to the first field. */
|
||||
bool pb_field_iter_next(pb_field_iter_t *iter);
|
||||
|
||||
/* Advance the iterator until it points at a field with the given tag.
|
||||
* Returns false if no such field exists. */
|
||||
bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// pb_decode.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c.
|
||||
* The main function is pb_decode. You also need an input stream, and the
|
||||
* field descriptions created by nanopb_generator.py.
|
||||
*/
|
||||
|
||||
#ifndef PB_DECODE_H_INCLUDED
|
||||
#define PB_DECODE_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Structure for defining custom input streams. You will need to provide
|
||||
* a callback function to read the bytes from your storage, which can be
|
||||
* for example a file or a network socket.
|
||||
*
|
||||
* The callback must conform to these rules:
|
||||
*
|
||||
* 1) Return false on IO errors. This will cause decoding to abort.
|
||||
* 2) You can use state to store your own data (e.g. buffer pointer),
|
||||
* and rely on pb_read to verify that no-body reads past bytes_left.
|
||||
* 3) Your callback may be used with substreams, in which case bytes_left
|
||||
* is different than from the main stream. Don't use bytes_left to compute
|
||||
* any pointers.
|
||||
*/
|
||||
struct pb_istream_s
|
||||
{
|
||||
#ifdef PB_BUFFER_ONLY
|
||||
/* Callback pointer is not used in buffer-only configuration.
|
||||
* Having an int pointer here allows binary compatibility but
|
||||
* gives an error if someone tries to assign callback function.
|
||||
*/
|
||||
int *callback;
|
||||
#else
|
||||
bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count);
|
||||
#endif
|
||||
|
||||
void *state; /* Free field for use by callback implementation */
|
||||
size_t bytes_left;
|
||||
|
||||
#ifndef PB_NO_ERRMSG
|
||||
const char *errmsg;
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************
|
||||
* Main decoding functions *
|
||||
***************************/
|
||||
|
||||
/* Decode a single protocol buffers message from input stream into a C structure.
|
||||
* Returns true on success, false on any failure.
|
||||
* The actual struct pointed to by dest must match the description in fields.
|
||||
* Callback fields of the destination structure must be initialized by caller.
|
||||
* All other fields will be initialized by this function.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* uint8_t buffer[64];
|
||||
* pb_istream_t stream;
|
||||
*
|
||||
* // ... read some data into buffer ...
|
||||
*
|
||||
* stream = pb_istream_from_buffer(buffer, count);
|
||||
* pb_decode(&stream, MyMessage_fields, &msg);
|
||||
*/
|
||||
bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode, except does not initialize the destination structure
|
||||
* to default values. This is slightly faster if you need no default values
|
||||
* and just do memset(struct, 0, sizeof(struct)) yourself.
|
||||
*
|
||||
* This can also be used for 'merging' two messages, i.e. update only the
|
||||
* fields that exist in the new message.
|
||||
*
|
||||
* Note: If this function returns with an error, it will not release any
|
||||
* dynamically allocated fields. You will need to call pb_release() yourself.
|
||||
*/
|
||||
bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode, except expects the stream to start with the message size
|
||||
* encoded as varint. Corresponds to parseDelimitedFrom() in Google's
|
||||
* protobuf API.
|
||||
*/
|
||||
bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode_delimited, except that it does not initialize the destination structure.
|
||||
* See pb_decode_noinit
|
||||
*/
|
||||
bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode, except allows the message to be terminated with a null byte.
|
||||
* NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour
|
||||
* is not supported in most other protobuf implementations, so pb_decode_delimited()
|
||||
* is a better option for compatibility.
|
||||
*/
|
||||
bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
#ifdef PB_ENABLE_MALLOC
|
||||
/* Release any allocated pointer fields. If you use dynamic allocation, you should
|
||||
* call this for any successfully decoded message when you are done with it. If
|
||||
* pb_decode() returns with an error, the message is already released.
|
||||
*/
|
||||
void pb_release(const pb_field_t fields[], void *dest_struct);
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************
|
||||
* Functions for manipulating streams *
|
||||
**************************************/
|
||||
|
||||
/* Create an input stream for reading from a memory buffer.
|
||||
*
|
||||
* Alternatively, you can use a custom stream that reads directly from e.g.
|
||||
* a file or a network socket.
|
||||
*/
|
||||
pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize);
|
||||
|
||||
/* Function to read from a pb_istream_t. You can use this if you need to
|
||||
* read some custom header data, or to read data in field callbacks.
|
||||
*/
|
||||
bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Helper functions for writing field callbacks *
|
||||
************************************************/
|
||||
|
||||
/* Decode the tag for the next field in the stream. Gives the wire type and
|
||||
* field tag. At end of the message, returns false and sets eof to true. */
|
||||
bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof);
|
||||
|
||||
/* Skip the field payload data, given the wire type. */
|
||||
bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type);
|
||||
|
||||
/* Decode an integer in the varint format. This works for bool, enum, int32,
|
||||
* int64, uint32 and uint64 field types. */
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest);
|
||||
#else
|
||||
#define pb_decode_varint pb_decode_varint32
|
||||
#endif
|
||||
|
||||
/* Decode an integer in the varint format. This works for bool, enum, int32,
|
||||
* and uint32 field types. */
|
||||
bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
|
||||
|
||||
/* Decode an integer in the zig-zagged svarint format. This works for sint32
|
||||
* and sint64. */
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest);
|
||||
#else
|
||||
bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest);
|
||||
#endif
|
||||
|
||||
/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to
|
||||
* a 4-byte wide C variable. */
|
||||
bool pb_decode_fixed32(pb_istream_t *stream, void *dest);
|
||||
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to
|
||||
* a 8-byte wide C variable. */
|
||||
bool pb_decode_fixed64(pb_istream_t *stream, void *dest);
|
||||
#endif
|
||||
|
||||
/* Make a limited-length substream for reading a PB_WT_STRING field. */
|
||||
bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream);
|
||||
bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// pb_encode.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c.
|
||||
* The main function is pb_encode. You also need an output stream, and the
|
||||
* field descriptions created by nanopb_generator.py.
|
||||
*/
|
||||
|
||||
#ifndef PB_ENCODE_H_INCLUDED
|
||||
#define PB_ENCODE_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Structure for defining custom output streams. You will need to provide
|
||||
* a callback function to write the bytes to your storage, which can be
|
||||
* for example a file or a network socket.
|
||||
*
|
||||
* The callback must conform to these rules:
|
||||
*
|
||||
* 1) Return false on IO errors. This will cause encoding to abort.
|
||||
* 2) You can use state to store your own data (e.g. buffer pointer).
|
||||
* 3) pb_write will update bytes_written after your callback runs.
|
||||
* 4) Substreams will modify max_size and bytes_written. Don't use them
|
||||
* to calculate any pointers.
|
||||
*/
|
||||
struct pb_ostream_s
|
||||
{
|
||||
#ifdef PB_BUFFER_ONLY
|
||||
/* Callback pointer is not used in buffer-only configuration.
|
||||
* Having an int pointer here allows binary compatibility but
|
||||
* gives an error if someone tries to assign callback function.
|
||||
* Also, NULL pointer marks a 'sizing stream' that does not
|
||||
* write anything.
|
||||
*/
|
||||
int *callback;
|
||||
#else
|
||||
bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
|
||||
#endif
|
||||
void *state; /* Free field for use by callback implementation. */
|
||||
size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */
|
||||
size_t bytes_written; /* Number of bytes written so far. */
|
||||
|
||||
#ifndef PB_NO_ERRMSG
|
||||
const char *errmsg;
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************
|
||||
* Main encoding functions *
|
||||
***************************/
|
||||
|
||||
/* Encode a single protocol buffers message from C structure into a stream.
|
||||
* Returns true on success, false on any failure.
|
||||
* The actual struct pointed to by src_struct must match the description in fields.
|
||||
* All required fields in the struct are assumed to have been filled in.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* uint8_t buffer[64];
|
||||
* pb_ostream_t stream;
|
||||
*
|
||||
* msg.field1 = 42;
|
||||
* stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
||||
* pb_encode(&stream, MyMessage_fields, &msg);
|
||||
*/
|
||||
bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/* Same as pb_encode, but prepends the length of the message as a varint.
|
||||
* Corresponds to writeDelimitedTo() in Google's protobuf API.
|
||||
*/
|
||||
bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/* Same as pb_encode, but appends a null byte to the message for termination.
|
||||
* NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited()
|
||||
* is a better option for compatibility.
|
||||
*/
|
||||
bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/* Encode the message to get the size of the encoded data, but do not store
|
||||
* the data. */
|
||||
bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/**************************************
|
||||
* Functions for manipulating streams *
|
||||
**************************************/
|
||||
|
||||
/* Create an output stream for writing into a memory buffer.
|
||||
* The number of bytes written can be found in stream.bytes_written after
|
||||
* encoding the message.
|
||||
*
|
||||
* Alternatively, you can use a custom stream that writes directly to e.g.
|
||||
* a file or a network socket.
|
||||
*/
|
||||
pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize);
|
||||
|
||||
/* Pseudo-stream for measuring the size of a message without actually storing
|
||||
* the encoded data.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* pb_ostream_t stream = PB_OSTREAM_SIZING;
|
||||
* pb_encode(&stream, MyMessage_fields, &msg);
|
||||
* printf("Message size is %d\n", stream.bytes_written);
|
||||
*/
|
||||
#ifndef PB_NO_ERRMSG
|
||||
#define PB_OSTREAM_SIZING {0, 0, 0, 0, 0}
|
||||
#else
|
||||
#define PB_OSTREAM_SIZING {0, 0, 0, 0}
|
||||
#endif
|
||||
|
||||
/* Function to write into a pb_ostream_t stream. You can use this if you need
|
||||
* to append or prepend some custom headers to the message.
|
||||
*/
|
||||
bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Helper functions for writing field callbacks *
|
||||
************************************************/
|
||||
|
||||
/* Encode field header based on type and field number defined in the field
|
||||
* structure. Call this from the callback before writing out field contents. */
|
||||
bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field);
|
||||
|
||||
/* Encode field header by manually specifing wire type. You need to use this
|
||||
* if you want to write out packed arrays from a callback field. */
|
||||
bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number);
|
||||
|
||||
/* Encode an integer in the varint format.
|
||||
* This works for bool, enum, int32, int64, uint32 and uint64 field types. */
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
bool pb_encode_varint(pb_ostream_t *stream, uint64_t value);
|
||||
#else
|
||||
bool pb_encode_varint(pb_ostream_t *stream, uint32_t value);
|
||||
#endif
|
||||
|
||||
/* Encode an integer in the zig-zagged svarint format.
|
||||
* This works for sint32 and sint64. */
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
bool pb_encode_svarint(pb_ostream_t *stream, int64_t value);
|
||||
#else
|
||||
bool pb_encode_svarint(pb_ostream_t *stream, int32_t value);
|
||||
#endif
|
||||
|
||||
/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
|
||||
bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size);
|
||||
|
||||
/* Encode a fixed32, sfixed32 or float value.
|
||||
* You need to pass a pointer to a 4-byte wide C variable. */
|
||||
bool pb_encode_fixed32(pb_ostream_t *stream, const void *value);
|
||||
|
||||
#ifndef PB_WITHOUT_64BIT
|
||||
/* Encode a fixed64, sfixed64 or double value.
|
||||
* You need to pass a pointer to a 8-byte wide C variable. */
|
||||
bool pb_encode_fixed64(pb_ostream_t *stream, const void *value);
|
||||
#endif
|
||||
|
||||
/* Encode a submessage field.
|
||||
* You need to pass the pb_field_t array and pointer to struct, just like
|
||||
* with pb_encode(). This internally encodes the submessage twice, first to
|
||||
* calculate message size and then to actually write it out.
|
||||
*/
|
||||
bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// speech.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_SPEECH_PB_H_INCLUDED
|
||||
#define PB_SPEECH_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#include "common.pb.h"
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _AudioProfile
|
||||
{
|
||||
AudioProfile_CLOSE_TALK = 0,
|
||||
AudioProfile_NEAR_FIELD = 1,
|
||||
AudioProfile_FAR_FIELD = 2
|
||||
} AudioProfile;
|
||||
#define _AudioProfile_MIN AudioProfile_CLOSE_TALK
|
||||
#define _AudioProfile_MAX AudioProfile_FAR_FIELD
|
||||
#define _AudioProfile_ARRAYSIZE ((AudioProfile)(AudioProfile_FAR_FIELD + 1))
|
||||
|
||||
typedef enum _AudioFormat
|
||||
{
|
||||
AudioFormat_PCM_L16_16KHZ_MONO = 0,
|
||||
AudioFormat_OPUS_16KHZ_32KBPS_CBR_0_20MS = 1,
|
||||
AudioFormat_OPUS_16KHZ_16KBPS_CBR_0_20MS = 2,
|
||||
AudioFormat_MSBC = 3
|
||||
} AudioFormat;
|
||||
#define _AudioFormat_MIN AudioFormat_PCM_L16_16KHZ_MONO
|
||||
#define _AudioFormat_MAX AudioFormat_MSBC
|
||||
#define _AudioFormat_ARRAYSIZE ((AudioFormat)(AudioFormat_MSBC + 1))
|
||||
|
||||
typedef enum _AudioSource
|
||||
{
|
||||
AudioSource_STREAM = 0,
|
||||
AudioSource_BLUETOOTH_SCO = 1
|
||||
} AudioSource;
|
||||
#define _AudioSource_MIN AudioSource_STREAM
|
||||
#define _AudioSource_MAX AudioSource_BLUETOOTH_SCO
|
||||
#define _AudioSource_ARRAYSIZE ((AudioSource)(AudioSource_BLUETOOTH_SCO + 1))
|
||||
|
||||
typedef enum _SpeechState
|
||||
{
|
||||
SpeechState_IDLE = 0,
|
||||
SpeechState_LISTENING = 1,
|
||||
SpeechState_PROCESSING = 2,
|
||||
SpeechState_SPEAKING = 3
|
||||
} SpeechState;
|
||||
#define _SpeechState_MIN SpeechState_IDLE
|
||||
#define _SpeechState_MAX SpeechState_SPEAKING
|
||||
#define _SpeechState_ARRAYSIZE ((SpeechState)(SpeechState_SPEAKING + 1))
|
||||
|
||||
typedef enum _SpeechInitiator_Type
|
||||
{
|
||||
SpeechInitiator_Type_NONE = 0,
|
||||
SpeechInitiator_Type_PRESS_AND_HOLD = 1,
|
||||
SpeechInitiator_Type_TAP = 3,
|
||||
SpeechInitiator_Type_WAKEWORD = 4
|
||||
} SpeechInitiator_Type;
|
||||
#define _SpeechInitiator_Type_MIN SpeechInitiator_Type_NONE
|
||||
#define _SpeechInitiator_Type_MAX SpeechInitiator_Type_WAKEWORD
|
||||
#define _SpeechInitiator_Type_ARRAYSIZE ((SpeechInitiator_Type)(SpeechInitiator_Type_WAKEWORD + 1))
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _Dialog
|
||||
{
|
||||
uint32_t id;
|
||||
/* @@protoc_insertion_point(struct:Dialog) */
|
||||
} Dialog;
|
||||
|
||||
typedef struct _NotifySpeechState
|
||||
{
|
||||
SpeechState state;
|
||||
/* @@protoc_insertion_point(struct:NotifySpeechState) */
|
||||
} NotifySpeechState;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(256) SpeechInitiator_WakeWord_metadata_t;
|
||||
typedef struct _SpeechInitiator_WakeWord
|
||||
{
|
||||
uint32_t start_index_in_samples;
|
||||
uint32_t end_index_in_samples;
|
||||
bool near_miss;
|
||||
SpeechInitiator_WakeWord_metadata_t metadata;
|
||||
/* @@protoc_insertion_point(struct:SpeechInitiator_WakeWord) */
|
||||
} SpeechInitiator_WakeWord;
|
||||
|
||||
typedef struct _SpeechSettings
|
||||
{
|
||||
AudioProfile audio_profile;
|
||||
AudioFormat audio_format;
|
||||
AudioSource audio_source;
|
||||
/* @@protoc_insertion_point(struct:SpeechSettings) */
|
||||
} SpeechSettings;
|
||||
|
||||
typedef struct _EndpointSpeech
|
||||
{
|
||||
Dialog dialog;
|
||||
/* @@protoc_insertion_point(struct:EndpointSpeech) */
|
||||
} EndpointSpeech;
|
||||
|
||||
typedef struct _ProvideSpeech
|
||||
{
|
||||
Dialog dialog;
|
||||
/* @@protoc_insertion_point(struct:ProvideSpeech) */
|
||||
} ProvideSpeech;
|
||||
|
||||
typedef struct _SpeechInitiator
|
||||
{
|
||||
SpeechInitiator_Type type;
|
||||
SpeechInitiator_WakeWord wake_word;
|
||||
/* @@protoc_insertion_point(struct:SpeechInitiator) */
|
||||
} SpeechInitiator;
|
||||
|
||||
typedef struct _SpeechProvider
|
||||
{
|
||||
SpeechSettings speech_settings;
|
||||
Dialog dialog;
|
||||
/* @@protoc_insertion_point(struct:SpeechProvider) */
|
||||
} SpeechProvider;
|
||||
|
||||
typedef struct _StopSpeech
|
||||
{
|
||||
ErrorCode error_code;
|
||||
Dialog dialog;
|
||||
/* @@protoc_insertion_point(struct:StopSpeech) */
|
||||
} StopSpeech;
|
||||
|
||||
typedef struct _StartSpeech
|
||||
{
|
||||
SpeechSettings settings;
|
||||
SpeechInitiator initiator;
|
||||
Dialog dialog;
|
||||
bool suppressEarcon;
|
||||
/* @@protoc_insertion_point(struct:StartSpeech) */
|
||||
} StartSpeech;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define Dialog_init_default {0}
|
||||
#define SpeechSettings_init_default {_AudioProfile_MIN, _AudioFormat_MIN, _AudioSource_MIN}
|
||||
#define SpeechInitiator_init_default {_SpeechInitiator_Type_MIN, SpeechInitiator_WakeWord_init_default}
|
||||
#define SpeechInitiator_WakeWord_init_default {0, 0, 0, {0, {0}}}
|
||||
#define StartSpeech_init_default {SpeechSettings_init_default, SpeechInitiator_init_default, Dialog_init_default, 0}
|
||||
#define SpeechProvider_init_default {SpeechSettings_init_default, Dialog_init_default}
|
||||
#define ProvideSpeech_init_default {Dialog_init_default}
|
||||
#define StopSpeech_init_default {_ErrorCode_MIN, Dialog_init_default}
|
||||
#define EndpointSpeech_init_default {Dialog_init_default}
|
||||
#define NotifySpeechState_init_default {_SpeechState_MIN}
|
||||
#define Dialog_init_zero {0}
|
||||
#define SpeechSettings_init_zero {_AudioProfile_MIN, _AudioFormat_MIN, _AudioSource_MIN}
|
||||
#define SpeechInitiator_init_zero {_SpeechInitiator_Type_MIN, SpeechInitiator_WakeWord_init_zero}
|
||||
#define SpeechInitiator_WakeWord_init_zero {0, 0, 0, {0, {0}}}
|
||||
#define StartSpeech_init_zero {SpeechSettings_init_zero, SpeechInitiator_init_zero, Dialog_init_zero, 0}
|
||||
#define SpeechProvider_init_zero {SpeechSettings_init_zero, Dialog_init_zero}
|
||||
#define ProvideSpeech_init_zero {Dialog_init_zero}
|
||||
#define StopSpeech_init_zero {_ErrorCode_MIN, Dialog_init_zero}
|
||||
#define EndpointSpeech_init_zero {Dialog_init_zero}
|
||||
#define NotifySpeechState_init_zero {_SpeechState_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define Dialog_id_tag 1
|
||||
#define NotifySpeechState_state_tag 1
|
||||
#define SpeechInitiator_WakeWord_start_index_in_samples_tag 1
|
||||
#define SpeechInitiator_WakeWord_end_index_in_samples_tag 2
|
||||
#define SpeechInitiator_WakeWord_near_miss_tag 3
|
||||
#define SpeechInitiator_WakeWord_metadata_tag 4
|
||||
#define SpeechSettings_audio_profile_tag 1
|
||||
#define SpeechSettings_audio_format_tag 2
|
||||
#define SpeechSettings_audio_source_tag 3
|
||||
#define EndpointSpeech_dialog_tag 1
|
||||
#define ProvideSpeech_dialog_tag 1
|
||||
#define SpeechInitiator_type_tag 1
|
||||
#define SpeechInitiator_wake_word_tag 2
|
||||
#define SpeechProvider_speech_settings_tag 1
|
||||
#define SpeechProvider_dialog_tag 2
|
||||
#define StopSpeech_error_code_tag 1
|
||||
#define StopSpeech_dialog_tag 2
|
||||
#define StartSpeech_settings_tag 1
|
||||
#define StartSpeech_initiator_tag 2
|
||||
#define StartSpeech_dialog_tag 3
|
||||
#define StartSpeech_suppressEarcon_tag 4
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t Dialog_fields[2];
|
||||
extern const pb_field_t SpeechSettings_fields[4];
|
||||
extern const pb_field_t SpeechInitiator_fields[3];
|
||||
extern const pb_field_t SpeechInitiator_WakeWord_fields[5];
|
||||
extern const pb_field_t StartSpeech_fields[5];
|
||||
extern const pb_field_t SpeechProvider_fields[3];
|
||||
extern const pb_field_t ProvideSpeech_fields[2];
|
||||
extern const pb_field_t StopSpeech_fields[3];
|
||||
extern const pb_field_t EndpointSpeech_fields[2];
|
||||
extern const pb_field_t NotifySpeechState_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Dialog_size 6
|
||||
#define SpeechSettings_size 6
|
||||
#define SpeechInitiator_size 278
|
||||
#define SpeechInitiator_WakeWord_size 273
|
||||
#define StartSpeech_size 299
|
||||
#define SpeechProvider_size 16
|
||||
#define ProvideSpeech_size 8
|
||||
#define StopSpeech_size 10
|
||||
#define EndpointSpeech_size 8
|
||||
#define NotifySpeechState_size 2
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define SPEECH_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// state.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_STATE_PB_H_INCLUDED
|
||||
#define PB_STATE_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _GetState
|
||||
{
|
||||
uint32_t feature;
|
||||
/* @@protoc_insertion_point(struct:GetState) */
|
||||
} GetState;
|
||||
|
||||
typedef struct _State
|
||||
{
|
||||
uint32_t feature;
|
||||
pb_size_t which_value;
|
||||
union
|
||||
{
|
||||
bool boolean;
|
||||
uint32_t integer;
|
||||
} value;
|
||||
/* @@protoc_insertion_point(struct:State) */
|
||||
} State;
|
||||
|
||||
typedef struct _SetState
|
||||
{
|
||||
State state;
|
||||
/* @@protoc_insertion_point(struct:SetState) */
|
||||
} SetState;
|
||||
|
||||
typedef struct _SynchronizeState
|
||||
{
|
||||
State state;
|
||||
/* @@protoc_insertion_point(struct:SynchronizeState) */
|
||||
} SynchronizeState;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define State_init_default {0, 0, {0}}
|
||||
#define GetState_init_default {0}
|
||||
#define SetState_init_default {State_init_default}
|
||||
#define SynchronizeState_init_default {State_init_default}
|
||||
#define State_init_zero {0, 0, {0}}
|
||||
#define GetState_init_zero {0}
|
||||
#define SetState_init_zero {State_init_zero}
|
||||
#define SynchronizeState_init_zero {State_init_zero}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define GetState_feature_tag 1
|
||||
#define State_boolean_tag 2
|
||||
#define State_integer_tag 3
|
||||
#define State_feature_tag 1
|
||||
#define SetState_state_tag 1
|
||||
#define SynchronizeState_state_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t State_fields[4];
|
||||
extern const pb_field_t GetState_fields[2];
|
||||
extern const pb_field_t SetState_fields[2];
|
||||
extern const pb_field_t SynchronizeState_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define State_size 12
|
||||
#define GetState_size 6
|
||||
#define SetState_size 14
|
||||
#define SynchronizeState_size 14
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define STATE_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// system.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_SYSTEM_PB_H_INCLUDED
|
||||
#define PB_SYSTEM_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _KeepAlive
|
||||
{
|
||||
char dummy_field;
|
||||
/* @@protoc_insertion_point(struct:KeepAlive) */
|
||||
} KeepAlive;
|
||||
|
||||
typedef struct _RemoveDevice
|
||||
{
|
||||
char dummy_field;
|
||||
/* @@protoc_insertion_point(struct:RemoveDevice) */
|
||||
} RemoveDevice;
|
||||
|
||||
typedef struct _ResetConnection
|
||||
{
|
||||
uint32_t timeout;
|
||||
bool force_disconnect;
|
||||
/* @@protoc_insertion_point(struct:ResetConnection) */
|
||||
} ResetConnection;
|
||||
|
||||
typedef struct _SynchronizeSettings
|
||||
{
|
||||
uint32_t timestamp_hi;
|
||||
uint32_t timestamp_lo;
|
||||
/* @@protoc_insertion_point(struct:SynchronizeSettings) */
|
||||
} SynchronizeSettings;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ResetConnection_init_default {0, 0}
|
||||
#define SynchronizeSettings_init_default {0, 0}
|
||||
#define KeepAlive_init_default {0}
|
||||
#define RemoveDevice_init_default {0}
|
||||
#define ResetConnection_init_zero {0, 0}
|
||||
#define SynchronizeSettings_init_zero {0, 0}
|
||||
#define KeepAlive_init_zero {0}
|
||||
#define RemoveDevice_init_zero {0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ResetConnection_timeout_tag 1
|
||||
#define ResetConnection_force_disconnect_tag 2
|
||||
#define SynchronizeSettings_timestamp_hi_tag 1
|
||||
#define SynchronizeSettings_timestamp_lo_tag 2
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t ResetConnection_fields[3];
|
||||
extern const pb_field_t SynchronizeSettings_fields[3];
|
||||
extern const pb_field_t KeepAlive_fields[1];
|
||||
extern const pb_field_t RemoveDevice_fields[1];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ResetConnection_size 8
|
||||
#define SynchronizeSettings_size 12
|
||||
#define KeepAlive_size 0
|
||||
#define RemoveDevice_size 0
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define SYSTEM_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// transport.pb.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Auto-generated (see below).
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Fri Nov 09 16:58:28 2018. */
|
||||
|
||||
#ifndef PB_TRANSPORT_PB_H_INCLUDED
|
||||
#define PB_TRANSPORT_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#include "common.pb.h"
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef PB_BYTES_ARRAY_T(64) ConnectionDetails_identifier_t;
|
||||
typedef struct _ConnectionDetails
|
||||
{
|
||||
ConnectionDetails_identifier_t identifier;
|
||||
/* @@protoc_insertion_point(struct:ConnectionDetails) */
|
||||
} ConnectionDetails;
|
||||
|
||||
typedef struct _SwitchTransport
|
||||
{
|
||||
Transport new_transport;
|
||||
/* @@protoc_insertion_point(struct:SwitchTransport) */
|
||||
} SwitchTransport;
|
||||
|
||||
typedef struct _UpgradeTransport
|
||||
{
|
||||
Transport transport;
|
||||
/* @@protoc_insertion_point(struct:UpgradeTransport) */
|
||||
} UpgradeTransport;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ConnectionDetails_init_default {{0, {0}}}
|
||||
#define UpgradeTransport_init_default {_Transport_MIN}
|
||||
#define SwitchTransport_init_default {_Transport_MIN}
|
||||
#define ConnectionDetails_init_zero {{0, {0}}}
|
||||
#define UpgradeTransport_init_zero {_Transport_MIN}
|
||||
#define SwitchTransport_init_zero {_Transport_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ConnectionDetails_identifier_tag 1
|
||||
#define SwitchTransport_new_transport_tag 1
|
||||
#define UpgradeTransport_transport_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t ConnectionDetails_fields[2];
|
||||
extern const pb_field_t UpgradeTransport_fields[2];
|
||||
extern const pb_field_t SwitchTransport_fields[2];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ConnectionDetails_size 66
|
||||
#define UpgradeTransport_size 2
|
||||
#define SwitchTransport_size 2
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define TRANSPORT_MESSAGES \
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// ae.api.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Functions for interfacing with the encoder library
|
||||
//!
|
||||
//! @addtogroup
|
||||
//! @ingroup
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AE_API__H
|
||||
#define AE_API__H
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External Function Calls
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Initialization of the library
|
||||
//!
|
||||
//! Run the initialization function before any operation with the encoder.
|
||||
//! @param option - option to select whether to include 8-byte header into output.
|
||||
//! 0 for no header.
|
||||
//! other value for with header.
|
||||
//! @return numBytes - number of bytes of the data output, including header length.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
int audio_enc_init(int option);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Encodes a frame of audio
|
||||
//!
|
||||
//! @param p_pcm_buffer - pointer to the input buffer.
|
||||
//! @param n_pcm_samples - input length in samples.
|
||||
//! @param p_encoded_buffer - pointer to the output buffer.
|
||||
//!
|
||||
//! This is the major function of the encoder, the encoder encodes a fixed length
|
||||
//! of audio (20ms) in a fixed input format (16KHz, 16bit, mono, 640 bytes in length),
|
||||
//! with a fixed output format: CBR, 32000bps output rate (8:1 compression),
|
||||
//! complexity 4.
|
||||
//! When output header is selected, each output frame will have a 8 byte header in
|
||||
//! the beginning of the output data: 4 bytes of length (fixed to 80) followed by
|
||||
//! 4 bytes of range code.
|
||||
//!
|
||||
//! @return numBytes - number of bytes of the data output, including header length.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
int audio_enc_encode_frame(short *p_pcm_buffer, int n_pcm_samples, unsigned char *p_encoded_buffer);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get version information of the libary
|
||||
//!
|
||||
//! @return version_string - pointer to the libary version string.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
char* audio_get_lib_version(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get version information of the base package
|
||||
//!
|
||||
//! @return version_string - pointer to the base package version string.
|
||||
//! version information is 7 byte long without line break
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
char* audio_get_package_version(void);
|
||||
|
||||
#endif // AE_API__H
|
||||
|
||||
|
||||
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,848 @@
|
||||
/*
|
||||
*
|
||||
* Bluetooth low-complexity, subband codec (SBC) library
|
||||
*
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
* Copyright (C) 2012-2014 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
|
||||
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SBC_H
|
||||
#define __SBC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* sampling frequency */
|
||||
#define SBC_FREQ_16000 0x00
|
||||
#define SBC_FREQ_32000 0x01
|
||||
#define SBC_FREQ_44100 0x02
|
||||
#define SBC_FREQ_48000 0x03
|
||||
|
||||
/* blocks */
|
||||
#define SBC_BLK_4 0x00
|
||||
#define SBC_BLK_8 0x01
|
||||
#define SBC_BLK_12 0x02
|
||||
#define SBC_BLK_16 0x03
|
||||
|
||||
/* channel mode */
|
||||
#define SBC_MODE_MONO 0x00
|
||||
#define SBC_MODE_DUAL_CHANNEL 0x01
|
||||
#define SBC_MODE_STEREO 0x02
|
||||
#define SBC_MODE_JOINT_STEREO 0x03
|
||||
|
||||
/* allocation method */
|
||||
#define SBC_AM_LOUDNESS 0x00
|
||||
#define SBC_AM_SNR 0x01
|
||||
|
||||
/* subbands */
|
||||
#define SBC_SB_4 0x00
|
||||
#define SBC_SB_8 0x01
|
||||
|
||||
/* data endianess */
|
||||
#define SBC_LE 0x00
|
||||
#define SBC_BE 0x01
|
||||
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef __int64 ssize_t;
|
||||
#else
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#define _SSIZE_T_DEFINED
|
||||
#endif
|
||||
#define SBC_EXPORT
|
||||
#define SBC_X_BUFFER_SIZE 328
|
||||
#define SCALE_OUT_BITS 15
|
||||
|
||||
//#define SBC_ALIGNED
|
||||
#define SBC_ALWAYS_INLINE inline
|
||||
#define SBCDEC_FIXED_EXTRA_BITS 2
|
||||
#define SBC_ALIGN_BITS 4
|
||||
#define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
|
||||
|
||||
#define fabs(x) ((x) < 0 ? -(x) : (x))
|
||||
/* C does not provide an explicit arithmetic shift right but this will
|
||||
always be correct and every compiler *should* generate optimal code */
|
||||
#define ASR(val, bits) ((-2 >> 1 == -1) ? \
|
||||
((int32_t)(val)) >> (bits) : ((int32_t) (val)) / (1 << (bits)))
|
||||
|
||||
#define SCALE_SPROTO4_TBL 12
|
||||
#define SCALE_SPROTO8_TBL 14
|
||||
#define SCALE_NPROTO4_TBL 11
|
||||
#define SCALE_NPROTO8_TBL 11
|
||||
#define SCALE4_STAGED1_BITS 15
|
||||
#define SCALE4_STAGED2_BITS 16
|
||||
#define SCALE8_STAGED1_BITS 15
|
||||
#define SCALE8_STAGED2_BITS 16
|
||||
|
||||
typedef int32_t sbc_fixed_t;
|
||||
|
||||
#define SCALE4_STAGED1(src) ASR(src, SCALE4_STAGED1_BITS)
|
||||
#define SCALE4_STAGED2(src) ASR(src, SCALE4_STAGED2_BITS)
|
||||
#define SCALE8_STAGED1(src) ASR(src, SCALE8_STAGED1_BITS)
|
||||
#define SCALE8_STAGED2(src) ASR(src, SCALE8_STAGED2_BITS)
|
||||
|
||||
|
||||
#define MULA(a, b, res) ((a) * (b) + (res))
|
||||
#define MUL(a, b) ((a) * (b))
|
||||
#define SBC_FIXED_0(val) { val = 0; }
|
||||
|
||||
#define FIXED_A int32_t /* data type for fixed point accumulator */
|
||||
#define FIXED_T int16_t /* data type for fixed point constants */
|
||||
#define SBC_FIXED_EXTRA_BITS 0
|
||||
|
||||
#define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
|
||||
#define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
|
||||
#define SN4(val) ASR(val, SCALE_NPROTO4_TBL + 1 + SBCDEC_FIXED_EXTRA_BITS)
|
||||
#define SN8(val) ASR(val, SCALE_NPROTO8_TBL + 1 + SBCDEC_FIXED_EXTRA_BITS)
|
||||
|
||||
#define SBC_PROTO_FIXED4_SCALE \
|
||||
((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
|
||||
#define F_PROTO4(x) (FIXED_A) ((x * 2) * \
|
||||
((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
|
||||
#define F(x) F_PROTO4(x)
|
||||
static const FIXED_T _sbc_proto_fixed4[40] =
|
||||
{
|
||||
F(0.00000000E+00), F(5.36548976E-04),
|
||||
-F(1.49188357E-03), F(2.73370904E-03),
|
||||
F(3.83720193E-03), F(3.89205149E-03),
|
||||
F(1.86581691E-03), F(3.06012286E-03),
|
||||
|
||||
F(1.09137620E-02), F(2.04385087E-02),
|
||||
-F(2.88757392E-02), F(3.21939290E-02),
|
||||
F(2.58767811E-02), F(6.13245186E-03),
|
||||
-F(2.88217274E-02), F(7.76463494E-02),
|
||||
|
||||
F(1.35593274E-01), F(1.94987841E-01),
|
||||
-F(2.46636662E-01), F(2.81828203E-01),
|
||||
F(2.94315332E-01), F(2.81828203E-01),
|
||||
F(2.46636662E-01), -F(1.94987841E-01),
|
||||
|
||||
-F(1.35593274E-01), -F(7.76463494E-02),
|
||||
F(2.88217274E-02), F(6.13245186E-03),
|
||||
F(2.58767811E-02), F(3.21939290E-02),
|
||||
F(2.88757392E-02), -F(2.04385087E-02),
|
||||
|
||||
-F(1.09137620E-02), -F(3.06012286E-03),
|
||||
-F(1.86581691E-03), F(3.89205149E-03),
|
||||
F(3.83720193E-03), F(2.73370904E-03),
|
||||
F(1.49188357E-03), -F(5.36548976E-04),
|
||||
};
|
||||
#undef F
|
||||
|
||||
/*
|
||||
* To produce this cosine matrix in Octave:
|
||||
*
|
||||
* b = zeros(4, 8);
|
||||
* for i = 0:3
|
||||
* for j = 0:7 b(i+1, j+1) = cos((i + 0.5) * (j - 2) * (pi/4))
|
||||
* endfor
|
||||
* endfor;
|
||||
* printf("%.10f, ", b');
|
||||
*
|
||||
* Note: in each block of 8 numbers sign was changed for elements 2 and 7
|
||||
*
|
||||
* Change of sign for element 2 allows to replace constant 1.0 (not
|
||||
* representable in Q15 format) with -1.0 (fine with Q15).
|
||||
* Changed sign for element 7 allows to have more similar constants
|
||||
* and simplify subband filter function code.
|
||||
*/
|
||||
#define SBC_COS_TABLE_FIXED4_SCALE \
|
||||
((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
|
||||
#define F_COS4(x) (FIXED_A) ((x) * \
|
||||
((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
|
||||
#define F(x) F_COS4(x)
|
||||
static const FIXED_T cos_table_fixed_4[32] =
|
||||
{
|
||||
F(0.7071067812), F(0.9238795325), -F(1.0000000000), F(0.9238795325),
|
||||
F(0.7071067812), F(0.3826834324), F(0.0000000000), F(0.3826834324),
|
||||
|
||||
-F(0.7071067812), F(0.3826834324), -F(1.0000000000), F(0.3826834324),
|
||||
-F(0.7071067812), -F(0.9238795325), -F(0.0000000000), -F(0.9238795325),
|
||||
|
||||
-F(0.7071067812), -F(0.3826834324), -F(1.0000000000), -F(0.3826834324),
|
||||
-F(0.7071067812), F(0.9238795325), F(0.0000000000), F(0.9238795325),
|
||||
|
||||
F(0.7071067812), -F(0.9238795325), -F(1.0000000000), -F(0.9238795325),
|
||||
F(0.7071067812), -F(0.3826834324), -F(0.0000000000), -F(0.3826834324),
|
||||
};
|
||||
#undef F
|
||||
|
||||
/* A2DP specification: Section 12.8 Tables
|
||||
*
|
||||
* Original values are premultiplied by 4 for better precision (that is the
|
||||
* maximum which is possible without overflows)
|
||||
*
|
||||
* Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
|
||||
* in order to compensate the same change applied to cos_table_fixed_8
|
||||
*/
|
||||
#define SBC_PROTO_FIXED8_SCALE \
|
||||
((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
|
||||
#define F_PROTO8(x) (FIXED_A) ((x * 2) * \
|
||||
((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
|
||||
#define F(x) F_PROTO8(x)
|
||||
static const FIXED_T _sbc_proto_fixed8[80] =
|
||||
{
|
||||
F(0.00000000E+00), F(1.56575398E-04),
|
||||
F(3.43256425E-04), F(5.54620202E-04),
|
||||
-F(8.23919506E-04), F(1.13992507E-03),
|
||||
F(1.47640169E-03), F(1.78371725E-03),
|
||||
F(2.01182542E-03), F(2.10371989E-03),
|
||||
F(1.99454554E-03), F(1.61656283E-03),
|
||||
F(9.02154502E-04), F(1.78805361E-04),
|
||||
F(1.64973098E-03), F(3.49717454E-03),
|
||||
|
||||
F(5.65949473E-03), F(8.02941163E-03),
|
||||
F(1.04584443E-02), F(1.27472335E-02),
|
||||
-F(1.46525263E-02), F(1.59045603E-02),
|
||||
F(1.62208471E-02), F(1.53184106E-02),
|
||||
F(1.29371806E-02), F(8.85757540E-03),
|
||||
F(2.92408442E-03), -F(4.91578024E-03),
|
||||
-F(1.46404076E-02), F(2.61098752E-02),
|
||||
F(3.90751381E-02), F(5.31873032E-02),
|
||||
|
||||
F(6.79989431E-02), F(8.29847578E-02),
|
||||
F(9.75753918E-02), F(1.11196689E-01),
|
||||
-F(1.23264548E-01), F(1.33264415E-01),
|
||||
F(1.40753505E-01), F(1.45389847E-01),
|
||||
F(1.46955068E-01), F(1.45389847E-01),
|
||||
F(1.40753505E-01), F(1.33264415E-01),
|
||||
F(1.23264548E-01), -F(1.11196689E-01),
|
||||
-F(9.75753918E-02), -F(8.29847578E-02),
|
||||
|
||||
-F(6.79989431E-02), -F(5.31873032E-02),
|
||||
-F(3.90751381E-02), -F(2.61098752E-02),
|
||||
F(1.46404076E-02), -F(4.91578024E-03),
|
||||
F(2.92408442E-03), F(8.85757540E-03),
|
||||
F(1.29371806E-02), F(1.53184106E-02),
|
||||
F(1.62208471E-02), F(1.59045603E-02),
|
||||
F(1.46525263E-02), -F(1.27472335E-02),
|
||||
-F(1.04584443E-02), -F(8.02941163E-03),
|
||||
|
||||
-F(5.65949473E-03), -F(3.49717454E-03),
|
||||
-F(1.64973098E-03), -F(1.78805361E-04),
|
||||
-F(9.02154502E-04), F(1.61656283E-03),
|
||||
F(1.99454554E-03), F(2.10371989E-03),
|
||||
F(2.01182542E-03), F(1.78371725E-03),
|
||||
F(1.47640169E-03), F(1.13992507E-03),
|
||||
F(8.23919506E-04), -F(5.54620202E-04),
|
||||
-F(3.43256425E-04), -F(1.56575398E-04),
|
||||
};
|
||||
#undef F
|
||||
|
||||
/*
|
||||
* To produce this cosine matrix in Octave:
|
||||
*
|
||||
* b = zeros(8, 16);
|
||||
* for i = 0:7
|
||||
* for j = 0:15 b(i+1, j+1) = cos((i + 0.5) * (j - 4) * (pi/8))
|
||||
* endfor endfor;
|
||||
* printf("%.10f, ", b');
|
||||
*
|
||||
* Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
|
||||
*
|
||||
* Change of sign for element 4 allows to replace constant 1.0 (not
|
||||
* representable in Q15 format) with -1.0 (fine with Q15).
|
||||
* Changed signs for elements 13, 14, 15 allow to have more similar constants
|
||||
* and simplify subband filter function code.
|
||||
*/
|
||||
#define SBC_COS_TABLE_FIXED8_SCALE \
|
||||
((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
|
||||
#define F_COS8(x) (FIXED_A) ((x) * \
|
||||
((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
|
||||
#define F(x) F_COS8(x)
|
||||
static const FIXED_T cos_table_fixed_8[128] =
|
||||
{
|
||||
F(0.7071067812), F(0.8314696123), F(0.9238795325), F(0.9807852804),
|
||||
-F(1.0000000000), F(0.9807852804), F(0.9238795325), F(0.8314696123),
|
||||
F(0.7071067812), F(0.5555702330), F(0.3826834324), F(0.1950903220),
|
||||
F(0.0000000000), F(0.1950903220), F(0.3826834324), F(0.5555702330),
|
||||
|
||||
-F(0.7071067812), -F(0.1950903220), F(0.3826834324), F(0.8314696123),
|
||||
-F(1.0000000000), F(0.8314696123), F(0.3826834324), -F(0.1950903220),
|
||||
-F(0.7071067812), -F(0.9807852804), -F(0.9238795325), -F(0.5555702330),
|
||||
-F(0.0000000000), -F(0.5555702330), -F(0.9238795325), -F(0.9807852804),
|
||||
|
||||
-F(0.7071067812), -F(0.9807852804), -F(0.3826834324), F(0.5555702330),
|
||||
-F(1.0000000000), F(0.5555702330), -F(0.3826834324), -F(0.9807852804),
|
||||
-F(0.7071067812), F(0.1950903220), F(0.9238795325), F(0.8314696123),
|
||||
F(0.0000000000), F(0.8314696123), F(0.9238795325), F(0.1950903220),
|
||||
|
||||
F(0.7071067812), -F(0.5555702330), -F(0.9238795325), F(0.1950903220),
|
||||
-F(1.0000000000), F(0.1950903220), -F(0.9238795325), -F(0.5555702330),
|
||||
F(0.7071067812), F(0.8314696123), -F(0.3826834324), -F(0.9807852804),
|
||||
-F(0.0000000000), -F(0.9807852804), -F(0.3826834324), F(0.8314696123),
|
||||
|
||||
F(0.7071067812), F(0.5555702330), -F(0.9238795325), -F(0.1950903220),
|
||||
-F(1.0000000000), -F(0.1950903220), -F(0.9238795325), F(0.5555702330),
|
||||
F(0.7071067812), -F(0.8314696123), -F(0.3826834324), F(0.9807852804),
|
||||
F(0.0000000000), F(0.9807852804), -F(0.3826834324), -F(0.8314696123),
|
||||
|
||||
-F(0.7071067812), F(0.9807852804), -F(0.3826834324), -F(0.5555702330),
|
||||
-F(1.0000000000), -F(0.5555702330), -F(0.3826834324), F(0.9807852804),
|
||||
-F(0.7071067812), -F(0.1950903220), F(0.9238795325), -F(0.8314696123),
|
||||
-F(0.0000000000), -F(0.8314696123), F(0.9238795325), -F(0.1950903220),
|
||||
|
||||
-F(0.7071067812), F(0.1950903220), F(0.3826834324), -F(0.8314696123),
|
||||
-F(1.0000000000), -F(0.8314696123), F(0.3826834324), F(0.1950903220),
|
||||
-F(0.7071067812), F(0.9807852804), -F(0.9238795325), F(0.5555702330),
|
||||
-F(0.0000000000), F(0.5555702330), -F(0.9238795325), F(0.9807852804),
|
||||
|
||||
F(0.7071067812), -F(0.8314696123), F(0.9238795325), -F(0.9807852804),
|
||||
-F(1.0000000000), -F(0.9807852804), F(0.9238795325), -F(0.8314696123),
|
||||
F(0.7071067812), -F(0.5555702330), F(0.3826834324), -F(0.1950903220),
|
||||
-F(0.0000000000), -F(0.1950903220), F(0.3826834324), -F(0.5555702330),
|
||||
};
|
||||
#undef F
|
||||
|
||||
/*
|
||||
* Enforce 16 byte alignment for the data, which is supposed to be used
|
||||
* with SIMD optimized code.
|
||||
*/
|
||||
|
||||
#define SBC_ALIGN_BITS 4
|
||||
#define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SBC_ALIGNED __attribute__((aligned(1 << (SBC_ALIGN_BITS))))
|
||||
#else
|
||||
#define SBC_ALIGNED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constant tables for the use in SIMD optimized analysis filters
|
||||
* Each table consists of two parts:
|
||||
* 1. reordered "proto" table
|
||||
* 2. reordered "cos" table
|
||||
*
|
||||
* Due to non-symmetrical reordering, separate tables for "even"
|
||||
* and "odd" cases are needed
|
||||
*/
|
||||
|
||||
static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_even[40 + 16] =
|
||||
{
|
||||
#define C0 1.0932568993
|
||||
#define C1 1.3056875580
|
||||
#define C2 1.3056875580
|
||||
#define C3 1.6772280856
|
||||
|
||||
#define F(x) F_PROTO4(x)
|
||||
F(0.00000000E+00 * C0), F(3.83720193E-03 * C0),
|
||||
F(5.36548976E-04 * C1), F(2.73370904E-03 * C1),
|
||||
F(3.06012286E-03 * C2), F(3.89205149E-03 * C2),
|
||||
F(0.00000000E+00 * C3), -F(1.49188357E-03 * C3),
|
||||
F(1.09137620E-02 * C0), F(2.58767811E-02 * C0),
|
||||
F(2.04385087E-02 * C1), F(3.21939290E-02 * C1),
|
||||
F(7.76463494E-02 * C2), F(6.13245186E-03 * C2),
|
||||
F(0.00000000E+00 * C3), -F(2.88757392E-02 * C3),
|
||||
F(1.35593274E-01 * C0), F(2.94315332E-01 * C0),
|
||||
F(1.94987841E-01 * C1), F(2.81828203E-01 * C1),
|
||||
-F(1.94987841E-01 * C2), F(2.81828203E-01 * C2),
|
||||
F(0.00000000E+00 * C3), -F(2.46636662E-01 * C3),
|
||||
-F(1.35593274E-01 * C0), F(2.58767811E-02 * C0),
|
||||
-F(7.76463494E-02 * C1), F(6.13245186E-03 * C1),
|
||||
-F(2.04385087E-02 * C2), F(3.21939290E-02 * C2),
|
||||
F(0.00000000E+00 * C3), F(2.88217274E-02 * C3),
|
||||
-F(1.09137620E-02 * C0), F(3.83720193E-03 * C0),
|
||||
-F(3.06012286E-03 * C1), F(3.89205149E-03 * C1),
|
||||
-F(5.36548976E-04 * C2), F(2.73370904E-03 * C2),
|
||||
F(0.00000000E+00 * C3), -F(1.86581691E-03 * C3),
|
||||
#undef F
|
||||
#define F(x) F_COS4(x)
|
||||
F(0.7071067812 / C0), F(0.9238795325 / C1),
|
||||
-F(0.7071067812 / C0), F(0.3826834324 / C1),
|
||||
-F(0.7071067812 / C0), -F(0.3826834324 / C1),
|
||||
F(0.7071067812 / C0), -F(0.9238795325 / C1),
|
||||
F(0.3826834324 / C2), -F(1.0000000000 / C3),
|
||||
-F(0.9238795325 / C2), -F(1.0000000000 / C3),
|
||||
F(0.9238795325 / C2), -F(1.0000000000 / C3),
|
||||
-F(0.3826834324 / C2), -F(1.0000000000 / C3),
|
||||
#undef F
|
||||
|
||||
#undef C0
|
||||
#undef C1
|
||||
#undef C2
|
||||
#undef C3
|
||||
};
|
||||
|
||||
static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_odd[40 + 16] =
|
||||
{
|
||||
#define C0 1.3056875580
|
||||
#define C1 1.6772280856
|
||||
#define C2 1.0932568993
|
||||
#define C3 1.3056875580
|
||||
|
||||
#define F(x) F_PROTO4(x)
|
||||
F(2.73370904E-03 * C0), F(5.36548976E-04 * C0),
|
||||
-F(1.49188357E-03 * C1), F(0.00000000E+00 * C1),
|
||||
F(3.83720193E-03 * C2), F(1.09137620E-02 * C2),
|
||||
F(3.89205149E-03 * C3), F(3.06012286E-03 * C3),
|
||||
F(3.21939290E-02 * C0), F(2.04385087E-02 * C0),
|
||||
-F(2.88757392E-02 * C1), F(0.00000000E+00 * C1),
|
||||
F(2.58767811E-02 * C2), F(1.35593274E-01 * C2),
|
||||
F(6.13245186E-03 * C3), F(7.76463494E-02 * C3),
|
||||
F(2.81828203E-01 * C0), F(1.94987841E-01 * C0),
|
||||
-F(2.46636662E-01 * C1), F(0.00000000E+00 * C1),
|
||||
F(2.94315332E-01 * C2), -F(1.35593274E-01 * C2),
|
||||
F(2.81828203E-01 * C3), -F(1.94987841E-01 * C3),
|
||||
F(6.13245186E-03 * C0), -F(7.76463494E-02 * C0),
|
||||
F(2.88217274E-02 * C1), F(0.00000000E+00 * C1),
|
||||
F(2.58767811E-02 * C2), -F(1.09137620E-02 * C2),
|
||||
F(3.21939290E-02 * C3), -F(2.04385087E-02 * C3),
|
||||
F(3.89205149E-03 * C0), -F(3.06012286E-03 * C0),
|
||||
-F(1.86581691E-03 * C1), F(0.00000000E+00 * C1),
|
||||
F(3.83720193E-03 * C2), F(0.00000000E+00 * C2),
|
||||
F(2.73370904E-03 * C3), -F(5.36548976E-04 * C3),
|
||||
#undef F
|
||||
#define F(x) F_COS4(x)
|
||||
F(0.9238795325 / C0), -F(1.0000000000 / C1),
|
||||
F(0.3826834324 / C0), -F(1.0000000000 / C1),
|
||||
-F(0.3826834324 / C0), -F(1.0000000000 / C1),
|
||||
-F(0.9238795325 / C0), -F(1.0000000000 / C1),
|
||||
F(0.7071067812 / C2), F(0.3826834324 / C3),
|
||||
-F(0.7071067812 / C2), -F(0.9238795325 / C3),
|
||||
-F(0.7071067812 / C2), F(0.9238795325 / C3),
|
||||
F(0.7071067812 / C2), -F(0.3826834324 / C3),
|
||||
#undef F
|
||||
|
||||
#undef C0
|
||||
#undef C1
|
||||
#undef C2
|
||||
#undef C3
|
||||
};
|
||||
|
||||
static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_even[80 + 64] =
|
||||
{
|
||||
#define C0 2.7906148894
|
||||
#define C1 2.4270044280
|
||||
#define C2 2.8015616024
|
||||
#define C3 3.1710363741
|
||||
#define C4 2.5377944043
|
||||
#define C5 2.4270044280
|
||||
#define C6 2.8015616024
|
||||
#define C7 3.1710363741
|
||||
|
||||
#define F(x) F_PROTO8(x)
|
||||
F(0.00000000E+00 * C0), F(2.01182542E-03 * C0),
|
||||
F(1.56575398E-04 * C1), F(1.78371725E-03 * C1),
|
||||
F(3.43256425E-04 * C2), F(1.47640169E-03 * C2),
|
||||
F(5.54620202E-04 * C3), F(1.13992507E-03 * C3),
|
||||
-F(8.23919506E-04 * C4), F(0.00000000E+00 * C4),
|
||||
F(2.10371989E-03 * C5), F(3.49717454E-03 * C5),
|
||||
F(1.99454554E-03 * C6), F(1.64973098E-03 * C6),
|
||||
F(1.61656283E-03 * C7), F(1.78805361E-04 * C7),
|
||||
F(5.65949473E-03 * C0), F(1.29371806E-02 * C0),
|
||||
F(8.02941163E-03 * C1), F(1.53184106E-02 * C1),
|
||||
F(1.04584443E-02 * C2), F(1.62208471E-02 * C2),
|
||||
F(1.27472335E-02 * C3), F(1.59045603E-02 * C3),
|
||||
-F(1.46525263E-02 * C4), F(0.00000000E+00 * C4),
|
||||
F(8.85757540E-03 * C5), F(5.31873032E-02 * C5),
|
||||
F(2.92408442E-03 * C6), F(3.90751381E-02 * C6),
|
||||
-F(4.91578024E-03 * C7), F(2.61098752E-02 * C7),
|
||||
F(6.79989431E-02 * C0), F(1.46955068E-01 * C0),
|
||||
F(8.29847578E-02 * C1), F(1.45389847E-01 * C1),
|
||||
F(9.75753918E-02 * C2), F(1.40753505E-01 * C2),
|
||||
F(1.11196689E-01 * C3), F(1.33264415E-01 * C3),
|
||||
-F(1.23264548E-01 * C4), F(0.00000000E+00 * C4),
|
||||
F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
|
||||
F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
|
||||
F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
|
||||
-F(6.79989431E-02 * C0), F(1.29371806E-02 * C0),
|
||||
-F(5.31873032E-02 * C1), F(8.85757540E-03 * C1),
|
||||
-F(3.90751381E-02 * C2), F(2.92408442E-03 * C2),
|
||||
-F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
|
||||
F(1.46404076E-02 * C4), F(0.00000000E+00 * C4),
|
||||
F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
|
||||
F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
|
||||
F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
|
||||
-F(5.65949473E-03 * C0), F(2.01182542E-03 * C0),
|
||||
-F(3.49717454E-03 * C1), F(2.10371989E-03 * C1),
|
||||
-F(1.64973098E-03 * C2), F(1.99454554E-03 * C2),
|
||||
-F(1.78805361E-04 * C3), F(1.61656283E-03 * C3),
|
||||
-F(9.02154502E-04 * C4), F(0.00000000E+00 * C4),
|
||||
F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
|
||||
F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
|
||||
F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
|
||||
#undef F
|
||||
#define F(x) F_COS8(x)
|
||||
F(0.7071067812 / C0), F(0.8314696123 / C1),
|
||||
-F(0.7071067812 / C0), -F(0.1950903220 / C1),
|
||||
-F(0.7071067812 / C0), -F(0.9807852804 / C1),
|
||||
F(0.7071067812 / C0), -F(0.5555702330 / C1),
|
||||
F(0.7071067812 / C0), F(0.5555702330 / C1),
|
||||
-F(0.7071067812 / C0), F(0.9807852804 / C1),
|
||||
-F(0.7071067812 / C0), F(0.1950903220 / C1),
|
||||
F(0.7071067812 / C0), -F(0.8314696123 / C1),
|
||||
F(0.9238795325 / C2), F(0.9807852804 / C3),
|
||||
F(0.3826834324 / C2), F(0.8314696123 / C3),
|
||||
-F(0.3826834324 / C2), F(0.5555702330 / C3),
|
||||
-F(0.9238795325 / C2), F(0.1950903220 / C3),
|
||||
-F(0.9238795325 / C2), -F(0.1950903220 / C3),
|
||||
-F(0.3826834324 / C2), -F(0.5555702330 / C3),
|
||||
F(0.3826834324 / C2), -F(0.8314696123 / C3),
|
||||
F(0.9238795325 / C2), -F(0.9807852804 / C3),
|
||||
-F(1.0000000000 / C4), F(0.5555702330 / C5),
|
||||
-F(1.0000000000 / C4), -F(0.9807852804 / C5),
|
||||
-F(1.0000000000 / C4), F(0.1950903220 / C5),
|
||||
-F(1.0000000000 / C4), F(0.8314696123 / C5),
|
||||
-F(1.0000000000 / C4), -F(0.8314696123 / C5),
|
||||
-F(1.0000000000 / C4), -F(0.1950903220 / C5),
|
||||
-F(1.0000000000 / C4), F(0.9807852804 / C5),
|
||||
-F(1.0000000000 / C4), -F(0.5555702330 / C5),
|
||||
F(0.3826834324 / C6), F(0.1950903220 / C7),
|
||||
-F(0.9238795325 / C6), -F(0.5555702330 / C7),
|
||||
F(0.9238795325 / C6), F(0.8314696123 / C7),
|
||||
-F(0.3826834324 / C6), -F(0.9807852804 / C7),
|
||||
-F(0.3826834324 / C6), F(0.9807852804 / C7),
|
||||
F(0.9238795325 / C6), -F(0.8314696123 / C7),
|
||||
-F(0.9238795325 / C6), F(0.5555702330 / C7),
|
||||
F(0.3826834324 / C6), -F(0.1950903220 / C7),
|
||||
#undef F
|
||||
|
||||
#undef C0
|
||||
#undef C1
|
||||
#undef C2
|
||||
#undef C3
|
||||
#undef C4
|
||||
#undef C5
|
||||
#undef C6
|
||||
#undef C7
|
||||
};
|
||||
|
||||
static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_odd[80 + 64] =
|
||||
{
|
||||
#define C0 2.5377944043
|
||||
#define C1 2.4270044280
|
||||
#define C2 2.8015616024
|
||||
#define C3 3.1710363741
|
||||
#define C4 2.7906148894
|
||||
#define C5 2.4270044280
|
||||
#define C6 2.8015616024
|
||||
#define C7 3.1710363741
|
||||
|
||||
#define F(x) F_PROTO8(x)
|
||||
F(0.00000000E+00 * C0), -F(8.23919506E-04 * C0),
|
||||
F(1.56575398E-04 * C1), F(1.78371725E-03 * C1),
|
||||
F(3.43256425E-04 * C2), F(1.47640169E-03 * C2),
|
||||
F(5.54620202E-04 * C3), F(1.13992507E-03 * C3),
|
||||
F(2.01182542E-03 * C4), F(5.65949473E-03 * C4),
|
||||
F(2.10371989E-03 * C5), F(3.49717454E-03 * C5),
|
||||
F(1.99454554E-03 * C6), F(1.64973098E-03 * C6),
|
||||
F(1.61656283E-03 * C7), F(1.78805361E-04 * C7),
|
||||
F(0.00000000E+00 * C0), -F(1.46525263E-02 * C0),
|
||||
F(8.02941163E-03 * C1), F(1.53184106E-02 * C1),
|
||||
F(1.04584443E-02 * C2), F(1.62208471E-02 * C2),
|
||||
F(1.27472335E-02 * C3), F(1.59045603E-02 * C3),
|
||||
F(1.29371806E-02 * C4), F(6.79989431E-02 * C4),
|
||||
F(8.85757540E-03 * C5), F(5.31873032E-02 * C5),
|
||||
F(2.92408442E-03 * C6), F(3.90751381E-02 * C6),
|
||||
-F(4.91578024E-03 * C7), F(2.61098752E-02 * C7),
|
||||
F(0.00000000E+00 * C0), -F(1.23264548E-01 * C0),
|
||||
F(8.29847578E-02 * C1), F(1.45389847E-01 * C1),
|
||||
F(9.75753918E-02 * C2), F(1.40753505E-01 * C2),
|
||||
F(1.11196689E-01 * C3), F(1.33264415E-01 * C3),
|
||||
F(1.46955068E-01 * C4), -F(6.79989431E-02 * C4),
|
||||
F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
|
||||
F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
|
||||
F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
|
||||
F(0.00000000E+00 * C0), F(1.46404076E-02 * C0),
|
||||
-F(5.31873032E-02 * C1), F(8.85757540E-03 * C1),
|
||||
-F(3.90751381E-02 * C2), F(2.92408442E-03 * C2),
|
||||
-F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
|
||||
F(1.29371806E-02 * C4), -F(5.65949473E-03 * C4),
|
||||
F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
|
||||
F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
|
||||
F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
|
||||
F(0.00000000E+00 * C0), -F(9.02154502E-04 * C0),
|
||||
-F(3.49717454E-03 * C1), F(2.10371989E-03 * C1),
|
||||
-F(1.64973098E-03 * C2), F(1.99454554E-03 * C2),
|
||||
-F(1.78805361E-04 * C3), F(1.61656283E-03 * C3),
|
||||
F(2.01182542E-03 * C4), F(0.00000000E+00 * C4),
|
||||
F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
|
||||
F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
|
||||
F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
|
||||
#undef F
|
||||
#define F(x) F_COS8(x)
|
||||
-F(1.0000000000 / C0), F(0.8314696123 / C1),
|
||||
-F(1.0000000000 / C0), -F(0.1950903220 / C1),
|
||||
-F(1.0000000000 / C0), -F(0.9807852804 / C1),
|
||||
-F(1.0000000000 / C0), -F(0.5555702330 / C1),
|
||||
-F(1.0000000000 / C0), F(0.5555702330 / C1),
|
||||
-F(1.0000000000 / C0), F(0.9807852804 / C1),
|
||||
-F(1.0000000000 / C0), F(0.1950903220 / C1),
|
||||
-F(1.0000000000 / C0), -F(0.8314696123 / C1),
|
||||
F(0.9238795325 / C2), F(0.9807852804 / C3),
|
||||
F(0.3826834324 / C2), F(0.8314696123 / C3),
|
||||
-F(0.3826834324 / C2), F(0.5555702330 / C3),
|
||||
-F(0.9238795325 / C2), F(0.1950903220 / C3),
|
||||
-F(0.9238795325 / C2), -F(0.1950903220 / C3),
|
||||
-F(0.3826834324 / C2), -F(0.5555702330 / C3),
|
||||
F(0.3826834324 / C2), -F(0.8314696123 / C3),
|
||||
F(0.9238795325 / C2), -F(0.9807852804 / C3),
|
||||
F(0.7071067812 / C4), F(0.5555702330 / C5),
|
||||
-F(0.7071067812 / C4), -F(0.9807852804 / C5),
|
||||
-F(0.7071067812 / C4), F(0.1950903220 / C5),
|
||||
F(0.7071067812 / C4), F(0.8314696123 / C5),
|
||||
F(0.7071067812 / C4), -F(0.8314696123 / C5),
|
||||
-F(0.7071067812 / C4), -F(0.1950903220 / C5),
|
||||
-F(0.7071067812 / C4), F(0.9807852804 / C5),
|
||||
F(0.7071067812 / C4), -F(0.5555702330 / C5),
|
||||
F(0.3826834324 / C6), F(0.1950903220 / C7),
|
||||
-F(0.9238795325 / C6), -F(0.5555702330 / C7),
|
||||
F(0.9238795325 / C6), F(0.8314696123 / C7),
|
||||
-F(0.3826834324 / C6), -F(0.9807852804 / C7),
|
||||
-F(0.3826834324 / C6), F(0.9807852804 / C7),
|
||||
F(0.9238795325 / C6), -F(0.8314696123 / C7),
|
||||
-F(0.9238795325 / C6), F(0.5555702330 / C7),
|
||||
F(0.3826834324 / C6), -F(0.1950903220 / C7),
|
||||
#undef F
|
||||
|
||||
#undef C0
|
||||
#undef C1
|
||||
#undef C2
|
||||
#undef C3
|
||||
#undef C4
|
||||
#undef C5
|
||||
#undef C6
|
||||
#undef C7
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_4_40m0[] =
|
||||
{
|
||||
SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
|
||||
SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
|
||||
SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
|
||||
SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
|
||||
SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_4_40m1[] =
|
||||
{
|
||||
SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
|
||||
SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
|
||||
SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
|
||||
SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
|
||||
SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_8_80m0[] =
|
||||
{
|
||||
SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
|
||||
SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
|
||||
SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
|
||||
SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
|
||||
SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
|
||||
SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
|
||||
SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
|
||||
SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
|
||||
SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
|
||||
SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_8_80m1[] =
|
||||
{
|
||||
SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
|
||||
SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
|
||||
SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
|
||||
SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
|
||||
SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
|
||||
SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
|
||||
SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
|
||||
SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
|
||||
SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
|
||||
SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
|
||||
};
|
||||
|
||||
static const int32_t synmatrix4[8][4] =
|
||||
{
|
||||
{ SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
|
||||
{ SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
|
||||
{ SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
|
||||
{ SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
|
||||
{ SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
|
||||
{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
|
||||
{ SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
|
||||
{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
|
||||
};
|
||||
|
||||
static const int32_t synmatrix8[16][8] =
|
||||
{
|
||||
{ SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
|
||||
SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
|
||||
{ SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
|
||||
SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
|
||||
{ SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
|
||||
SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
|
||||
{ SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
|
||||
SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
|
||||
{ SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
|
||||
SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
|
||||
{ SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
|
||||
SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
|
||||
{ SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
|
||||
SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
|
||||
{ SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
|
||||
SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
|
||||
{ SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
|
||||
SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
|
||||
{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
|
||||
SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
|
||||
{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
|
||||
SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
|
||||
{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
|
||||
SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
|
||||
{ SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
|
||||
SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
|
||||
{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
|
||||
SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
|
||||
{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
|
||||
SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
|
||||
{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
|
||||
SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
|
||||
};
|
||||
|
||||
struct sbc_encoder_state
|
||||
{
|
||||
int position;
|
||||
/* Number of consecutive blocks handled by the encoder */
|
||||
uint8_t increment;
|
||||
int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
|
||||
/* Polyphase analysis filter for 4 subbands configuration,
|
||||
* it handles "increment" blocks at once */
|
||||
void (*sbc_analyze_4s)(struct sbc_encoder_state *state,
|
||||
int16_t *x, int32_t *out, int out_stride);
|
||||
/* Polyphase analysis filter for 8 subbands configuration,
|
||||
* it handles "increment" blocks at once */
|
||||
void (*sbc_analyze_8s)(struct sbc_encoder_state *state,
|
||||
int16_t *x, int32_t *out, int out_stride);
|
||||
/* Process input data (deinterleave, endian conversion, reordering),
|
||||
* depending on the number of subbands and input data byte order */
|
||||
int (*sbc_enc_process_input_4s_le)(int position,
|
||||
const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
|
||||
int nsamples, int nchannels);
|
||||
int (*sbc_enc_process_input_4s_be)(int position,
|
||||
const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
|
||||
int nsamples, int nchannels);
|
||||
int (*sbc_enc_process_input_8s_le)(int position,
|
||||
const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
|
||||
int nsamples, int nchannels);
|
||||
int (*sbc_enc_process_input_8s_be)(int position,
|
||||
const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
|
||||
int nsamples, int nchannels);
|
||||
/* Scale factors calculation */
|
||||
void (*sbc_calc_scalefactors)(int32_t sb_sample_f[16][2][8],
|
||||
uint32_t scale_factor[2][8],
|
||||
int blocks, int channels, int subbands);
|
||||
/* Scale factors calculation with joint stereo support */
|
||||
int (*sbc_calc_scalefactors_j)(int32_t sb_sample_f[16][2][8],
|
||||
uint32_t scale_factor[2][8],
|
||||
int blocks, int subbands);
|
||||
const char *implementation_info;
|
||||
};
|
||||
|
||||
/* A2DP specification: Appendix B, page 69 */
|
||||
static const int sbc_offset4[4][4] =
|
||||
{
|
||||
{ -1, 0, 0, 0 },
|
||||
{ -2, 0, 0, 1 },
|
||||
{ -2, 0, 0, 1 },
|
||||
{ -2, 0, 0, 1 }
|
||||
};
|
||||
|
||||
/* A2DP specification: Appendix B, page 69 */
|
||||
static const int sbc_offset8[4][8] =
|
||||
{
|
||||
{ -2, 0, 0, 0, 0, 0, 0, 1 },
|
||||
{ -3, 0, 0, 0, 0, 0, 1, 2 },
|
||||
{ -4, 0, 0, 0, 0, 0, 1, 2 },
|
||||
{ -4, 0, 0, 0, 0, 0, 1, 2 }
|
||||
};
|
||||
|
||||
struct sbc_struct
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
uint8_t frequency;
|
||||
uint8_t blocks;
|
||||
uint8_t subbands;
|
||||
uint8_t mode;
|
||||
uint8_t allocation;
|
||||
uint8_t bitpool;
|
||||
uint8_t endian;
|
||||
|
||||
void *priv;
|
||||
void *priv_alloc_base;
|
||||
};
|
||||
|
||||
typedef struct sbc_struct sbc_t;
|
||||
|
||||
int sbc_init(sbc_t *sbc, unsigned long flags);
|
||||
int sbc_reinit(sbc_t *sbc, unsigned long flags);
|
||||
int sbc_init_msbc(sbc_t *sbc, unsigned long flags);
|
||||
int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
|
||||
const void *conf, size_t conf_len);
|
||||
int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
|
||||
const void *conf, size_t conf_len);
|
||||
|
||||
ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
|
||||
|
||||
/* Decodes ONE input block into ONE output block */
|
||||
ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
|
||||
void *output, size_t output_len, size_t *written);
|
||||
|
||||
/* Encodes ONE input block into ONE output block */
|
||||
ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
|
||||
void *output, size_t output_len, ssize_t *written);
|
||||
|
||||
/* Returns the output block size in bytes */
|
||||
size_t sbc_get_frame_length(sbc_t *sbc);
|
||||
|
||||
/* Returns the time one input/output block takes to play in msec*/
|
||||
unsigned sbc_get_frame_duration(sbc_t *sbc);
|
||||
|
||||
/* Returns the input block size in bytes */
|
||||
size_t sbc_get_codesize(sbc_t *sbc);
|
||||
|
||||
const char *sbc_get_implementation_info(sbc_t *sbc);
|
||||
void sbc_finish(sbc_t *sbc);
|
||||
void pcm_to_sbc(char *filename, char *output, int msbc);
|
||||
void sbc_to_pcm(char *filename, char *output, int msbc);
|
||||
void sbc_init_primitives(struct sbc_encoder_state *state);
|
||||
void sbc_decode_init(sbc_t *sbc, int msbc);
|
||||
ssize_t sbc_decoder_decode(sbc_t *sbc, const void *input, size_t input_len,
|
||||
void *output, size_t output_len, size_t *written);
|
||||
void sbc_decoder_uninit(sbc_t *sbc);
|
||||
void sbc_encode_init(sbc_t *sbc, int msbc);
|
||||
ssize_t sbc_encoder_encode(sbc_t *sbc, const void *input, size_t input_len,
|
||||
void *output, size_t output_len, ssize_t *written);
|
||||
void sbc_encoder_uninit(sbc_t *sbc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SBC_H */
|
||||
@@ -0,0 +1,400 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// vole_common.c
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the shared functions for the Vole service.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "vole_common.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "am_util_debug.h"
|
||||
#include "crc32.h"
|
||||
#include "am_util.h"
|
||||
|
||||
void
|
||||
VoleResetPkt(volePacket_t *pkt)
|
||||
{
|
||||
// pkt->offset = 0;
|
||||
// pkt->header.pktType = VOLE_PKT_TYPE_UNKNOWN;
|
||||
// pkt->len = 0;
|
||||
}
|
||||
|
||||
eVoleStatus_t
|
||||
VoleReceivePkt(voleCb_t *voleCb, volePacket_t *pkt, uint16_t len, uint8_t *pValue)
|
||||
{
|
||||
uint8_t dataIdx = 0;
|
||||
uint32_t calDataCrc = 0;
|
||||
uint16_t header = 0;
|
||||
|
||||
if (pkt->offset == 0 && len < VOLE_PREFIX_SIZE_IN_PKT)
|
||||
{
|
||||
APP_TRACE_INFO0("Invalid packet!!!");
|
||||
VoleSendReply(voleCb, VOLE_STATUS_INVALID_PKT_LENGTH, NULL, 0);
|
||||
return VOLE_STATUS_INVALID_PKT_LENGTH;
|
||||
}
|
||||
|
||||
// new packet
|
||||
if (pkt->offset == 0)
|
||||
{
|
||||
BYTES_TO_UINT16(pkt->len, pValue);
|
||||
BYTES_TO_UINT16(header, &pValue[2]);
|
||||
pkt->header.pktType = (header & PACKET_TYPE_BIT_MASK) >> PACKET_TYPE_BIT_OFFSET;
|
||||
pkt->header.pktSn = (header & PACKET_SN_BIT_MASK) >> PACKET_SN_BIT_OFFSET;
|
||||
pkt->header.encrypted = (header & PACKET_ENCRYPTION_BIT_MASK) >> PACKET_ENCRYPTION_BIT_OFFSET;
|
||||
pkt->header.ackEnabled = (header & PACKET_ACK_BIT_MASK) >> PACKET_ACK_BIT_OFFSET;
|
||||
dataIdx = VOLE_PREFIX_SIZE_IN_PKT;
|
||||
if (pkt->header.pktType == VOLE_PKT_TYPE_DATA)
|
||||
{
|
||||
voleCb->rxState = VOLE_STATE_GETTING_DATA;
|
||||
}
|
||||
#ifdef VOLE_DEBUG_ON
|
||||
APP_TRACE_INFO1("pkt len = 0x%x", pkt->len);
|
||||
APP_TRACE_INFO1("pkt header = 0x%x", header);
|
||||
#endif
|
||||
APP_TRACE_INFO2("type = %d, sn = %d", pkt->header.pktType, pkt->header.pktSn);
|
||||
APP_TRACE_INFO2("enc = %d, ackEnabled = %d", pkt->header.encrypted, pkt->header.ackEnabled);
|
||||
}
|
||||
|
||||
// make sure we have enough space for new data
|
||||
if (pkt->offset + len - dataIdx > VOLE_PACKET_SIZE)
|
||||
{
|
||||
APP_TRACE_INFO0("not enough buffer size!!!");
|
||||
if (pkt->header.pktType == VOLE_PKT_TYPE_DATA)
|
||||
{
|
||||
voleCb->rxState = VOLE_STATE_RX_IDLE;
|
||||
}
|
||||
// reset pkt
|
||||
VoleResetPkt(pkt);
|
||||
VoleSendReply(voleCb, VOLE_STATUS_INSUFFICIENT_BUFFER, NULL, 0);
|
||||
return VOLE_STATUS_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
// copy new data into buffer and also save crc into it if it's the last frame in a packet
|
||||
// 4 bytes crc is included in pkt length
|
||||
memcpy(pkt->data + pkt->offset, pValue + dataIdx, len - dataIdx);
|
||||
pkt->offset += (len - dataIdx);
|
||||
|
||||
// whole packet received
|
||||
if (pkt->offset >= pkt->len)
|
||||
{
|
||||
uint32_t peerCrc = 0;
|
||||
//
|
||||
// check CRC
|
||||
//
|
||||
BYTES_TO_UINT32(peerCrc, pkt->data + pkt->len - VOLE_CRC_SIZE_IN_PKT);
|
||||
calDataCrc = CalcCrc32(0xFFFFFFFFU, pkt->len - VOLE_CRC_SIZE_IN_PKT, pkt->data);
|
||||
#ifdef VOLE_DEBUG_ON
|
||||
APP_TRACE_INFO1("calDataCrc = 0x%x ", calDataCrc);
|
||||
APP_TRACE_INFO1("peerCrc = 0x%x", peerCrc);
|
||||
APP_TRACE_INFO1("len: %d", pkt->len);
|
||||
#endif
|
||||
|
||||
if (peerCrc != calDataCrc)
|
||||
{
|
||||
APP_TRACE_INFO0("crc error\n");
|
||||
|
||||
if (pkt->header.pktType == VOLE_PKT_TYPE_DATA)
|
||||
{
|
||||
voleCb->rxState = VOLE_STATE_RX_IDLE;
|
||||
}
|
||||
// reset pkt
|
||||
VoleResetPkt(pkt);
|
||||
|
||||
VoleSendReply(voleCb, VOLE_STATUS_CRC_ERROR, NULL, 0);
|
||||
|
||||
return VOLE_STATUS_CRC_ERROR;
|
||||
}
|
||||
|
||||
return VOLE_STATUS_RECEIVE_DONE;
|
||||
}
|
||||
|
||||
return VOLE_STATUS_RECEIVE_CONTINUE;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Vole packet handler
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
VolePacketHandler(voleCb_t *voleCb, eVolePktType_t type, uint16_t len, uint8_t *buf)
|
||||
{
|
||||
// APP_TRACE_INFO2("received packet type = %d, len = %d\n", type, len);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VOLE_PKT_TYPE_DATA:
|
||||
//
|
||||
// data package recevied
|
||||
//
|
||||
// record packet serial number
|
||||
voleCb->lastRxPktSn = voleCb->rxPkt.header.pktSn;
|
||||
VoleSendReply(voleCb, VOLE_STATUS_SUCCESS, NULL, 0);
|
||||
if (voleCb->recvCback)
|
||||
{
|
||||
voleCb->recvCback(buf, len);
|
||||
}
|
||||
|
||||
voleCb->rxState = VOLE_STATE_RX_IDLE;
|
||||
VoleResetPkt(&voleCb->rxPkt);
|
||||
break;
|
||||
|
||||
case VOLE_PKT_TYPE_ACK:
|
||||
{
|
||||
eVoleStatus_t status = (eVoleStatus_t)buf[0];
|
||||
// stop tx timeout timer
|
||||
WsfTimerStop(&voleCb->timeoutTimer);
|
||||
|
||||
if (voleCb->txState != VOLE_STATE_TX_IDLE)
|
||||
{
|
||||
// APP_TRACE_INFO1("set txState back to idle, state = %d\n", voleCb->txState);
|
||||
voleCb->txState = VOLE_STATE_TX_IDLE;
|
||||
}
|
||||
|
||||
if (status == VOLE_STATUS_CRC_ERROR || status == VOLE_STATUS_RESEND_REPLY)
|
||||
{
|
||||
// resend packet
|
||||
VoleSendPacketHandler(voleCb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// increase packet serial number if send successfully
|
||||
if (status == VOLE_STATUS_SUCCESS)
|
||||
{
|
||||
voleCb->txPktSn++;
|
||||
if (voleCb->txPktSn == 16)
|
||||
{
|
||||
voleCb->txPktSn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// packet transfer successful or other error
|
||||
// reset packet
|
||||
VoleResetPkt(&voleCb->txPkt);
|
||||
|
||||
// notify application layer
|
||||
if (voleCb->transCback)
|
||||
{
|
||||
voleCb->transCback(status);
|
||||
}
|
||||
}
|
||||
VoleResetPkt(&voleCb->ackPkt);
|
||||
}
|
||||
break;
|
||||
|
||||
case VOLE_PKT_TYPE_CONTROL:
|
||||
{
|
||||
eVoleControl_t control = (eVoleControl_t)buf[0];
|
||||
uint8_t resendPktSn = buf[1];
|
||||
if (control == VOLE_CONTROL_RESEND_REQ)
|
||||
{
|
||||
APP_TRACE_INFO2("resendPktSn = %d, lastRxPktSn = %d", resendPktSn, voleCb->lastRxPktSn);
|
||||
voleCb->rxState = VOLE_STATE_RX_IDLE;
|
||||
VoleResetPkt(&voleCb->rxPkt);
|
||||
if (resendPktSn > voleCb->lastRxPktSn)
|
||||
{
|
||||
VoleSendReply(voleCb, VOLE_STATUS_RESEND_REPLY, NULL, 0);
|
||||
}
|
||||
else if (resendPktSn == voleCb->lastRxPktSn)
|
||||
{
|
||||
VoleSendReply(voleCb, VOLE_STATUS_SUCCESS, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN2("resendPktSn = %d, lastRxPktSn = %d", resendPktSn, voleCb->lastRxPktSn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_TRACE_WARN1("unexpected contrl = %d\n", control);
|
||||
}
|
||||
VoleResetPkt(&voleCb->ackPkt);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VoleBuildPkt(voleCb_t *voleCb, eVolePktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint16_t header = 0;
|
||||
uint32_t calDataCrc;
|
||||
volePacket_t *pkt;
|
||||
|
||||
if (type == VOLE_PKT_TYPE_DATA)
|
||||
{
|
||||
pkt = &voleCb->txPkt;
|
||||
header = voleCb->txPktSn << PACKET_SN_BIT_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkt = &voleCb->ackPkt;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare header frame to be sent first
|
||||
//
|
||||
// length
|
||||
pkt->len = len + VOLE_PREFIX_SIZE_IN_PKT + VOLE_CRC_SIZE_IN_PKT;
|
||||
pkt->data[0] = (len + VOLE_CRC_SIZE_IN_PKT) & 0xff;
|
||||
pkt->data[1] = ((len + VOLE_CRC_SIZE_IN_PKT) >> 8) & 0xff;
|
||||
|
||||
// header
|
||||
header = header | (type << PACKET_TYPE_BIT_OFFSET);
|
||||
if (encrypted)
|
||||
{
|
||||
header = header | (1 << PACKET_ENCRYPTION_BIT_OFFSET);
|
||||
}
|
||||
if (enableACK)
|
||||
{
|
||||
header = header | (1 << PACKET_ACK_BIT_OFFSET);
|
||||
}
|
||||
pkt->data[2] = (header & 0xff);
|
||||
pkt->data[3] = (header >> 8);
|
||||
|
||||
// copy data
|
||||
memcpy(&(pkt->data[VOLE_PREFIX_SIZE_IN_PKT]), buf, len);
|
||||
calDataCrc = CalcCrc32(0xFFFFFFFFU, len, buf);
|
||||
|
||||
// add checksum
|
||||
pkt->data[VOLE_PREFIX_SIZE_IN_PKT + len] = (calDataCrc & 0xff);
|
||||
pkt->data[VOLE_PREFIX_SIZE_IN_PKT + len + 1] = ((calDataCrc >> 8) & 0xff);
|
||||
pkt->data[VOLE_PREFIX_SIZE_IN_PKT + len + 2] = ((calDataCrc >> 16) & 0xff);
|
||||
pkt->data[VOLE_PREFIX_SIZE_IN_PKT + len + 3] = ((calDataCrc >> 24) & 0xff);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send Reply to Sender
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
VoleSendReply(voleCb_t *voleCb, eVoleStatus_t status, uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
|
||||
eVoleStatus_t st;
|
||||
|
||||
WSF_ASSERT(len < ATT_DEFAULT_PAYLOAD_LEN);
|
||||
|
||||
buf[0] = status;
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(buf + 1, data, len);
|
||||
}
|
||||
st = voleCb->ack_sender_func(VOLE_PKT_TYPE_ACK, false, false, buf, len + 1);
|
||||
if (st != VOLE_STATUS_SUCCESS)
|
||||
{
|
||||
APP_TRACE_WARN1("VoleSendReply status = %d\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Send control message to Receiver
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
VoleSendControl(voleCb_t *voleCb, eVoleControl_t control, uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
|
||||
eVoleStatus_t st;
|
||||
|
||||
WSF_ASSERT(len < ATT_DEFAULT_PAYLOAD_LEN);
|
||||
|
||||
buf[0] = control;
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(buf + 1, data, len);
|
||||
}
|
||||
st = voleCb->ack_sender_func(VOLE_PKT_TYPE_CONTROL, false, false, buf, len + 1);
|
||||
if (st != VOLE_STATUS_SUCCESS)
|
||||
{
|
||||
APP_TRACE_WARN1("VoleSendControl status = %d\n", st);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VoleSendPacketHandler(voleCb_t *voleCb)
|
||||
{
|
||||
uint16_t transferSize = 0;
|
||||
uint16_t remainingBytes = 0;
|
||||
volePacket_t *txPkt = &voleCb->txPkt;
|
||||
|
||||
if ( voleCb->txState == VOLE_STATE_TX_IDLE )
|
||||
{
|
||||
txPkt->offset = 0;
|
||||
voleCb->txState = VOLE_STATE_SENDING;
|
||||
}
|
||||
|
||||
if ( txPkt->offset >= txPkt->len )
|
||||
{
|
||||
// done sent packet
|
||||
voleCb->txState = VOLE_STATE_WAITING_ACK;
|
||||
// start tx timeout timer
|
||||
WsfTimerStartMs(&voleCb->timeoutTimer, voleCb->txTimeoutMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
remainingBytes = txPkt->len - txPkt->offset;
|
||||
transferSize = ((voleCb->attMtuSize - 3) > remainingBytes)
|
||||
? remainingBytes
|
||||
: (voleCb->attMtuSize - 3);
|
||||
// send packet
|
||||
APP_TRACE_INFO1("VoleSendPacketHandler, send len:%d", transferSize);
|
||||
voleCb->data_sender_func(&txPkt->data[txPkt->offset], transferSize);
|
||||
txPkt->offset += transferSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// vole_common.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief This file provides the shared functions for the Vole service.
|
||||
//!
|
||||
//! @{
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef VOLE_COMMON_H
|
||||
#define VOLE_COMMON_H
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_timer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Macro definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define VOLE_MAX_PAYLOAD_SIZE 10//2048//512
|
||||
#define VOLE_PACKET_SIZE (VOLE_MAX_PAYLOAD_SIZE + VOLE_PREFIX_SIZE_IN_PKT + VOLE_CRC_SIZE_IN_PKT) // Bytes
|
||||
#define VOLE_LENGTH_SIZE_IN_PKT 2
|
||||
#define VOLE_HEADER_SIZE_IN_PKT 2
|
||||
#define VOLE_CRC_SIZE_IN_PKT 4
|
||||
#define VOLE_PREFIX_SIZE_IN_PKT VOLE_LENGTH_SIZE_IN_PKT + VOLE_HEADER_SIZE_IN_PKT
|
||||
|
||||
#define PACKET_TYPE_BIT_OFFSET 12
|
||||
#define PACKET_TYPE_BIT_MASK (0xf << PACKET_TYPE_BIT_OFFSET)
|
||||
#define PACKET_SN_BIT_OFFSET 8
|
||||
#define PACKET_SN_BIT_MASK (0xf << PACKET_SN_BIT_OFFSET)
|
||||
#define PACKET_ENCRYPTION_BIT_OFFSET 7
|
||||
#define PACKET_ENCRYPTION_BIT_MASK (0x1 << PACKET_ENCRYPTION_BIT_OFFSET)
|
||||
#define PACKET_ACK_BIT_OFFSET 6
|
||||
#define PACKET_ACK_BIT_MASK (0x1 << PACKET_ACK_BIT_OFFSET)
|
||||
|
||||
#define TX_TIMEOUT_DEFAULT 1000
|
||||
|
||||
#define MANUFACT_ADV 0x1234
|
||||
#define AUD_HEADER_LEN 44
|
||||
|
||||
|
||||
struct au_header
|
||||
{
|
||||
uint32_t magic; /* '.snd' */
|
||||
uint32_t hdr_size; /* size of header (min 24) */
|
||||
uint32_t data_size; /* size of data */
|
||||
uint32_t encoding; /* see to AU_FMT_XXXX */
|
||||
uint32_t sample_rate; /* sample rate */
|
||||
uint32_t channels; /* number of channels (voices) */
|
||||
};
|
||||
|
||||
typedef enum codecType
|
||||
{
|
||||
MSBC_CODEC_IN_USE = 0,
|
||||
OPUS_CODEC_IN_USE = 1,
|
||||
|
||||
VOLE_CODEC_TYPE_INVALID = 0xFF
|
||||
}eVoleCodecType;
|
||||
|
||||
//
|
||||
// Vole states
|
||||
//
|
||||
typedef enum eVoleState
|
||||
{
|
||||
VOLE_STATE_INIT,
|
||||
VOLE_STATE_TX_IDLE,
|
||||
VOLE_STATE_RX_IDLE,
|
||||
VOLE_STATE_SENDING,
|
||||
VOLE_STATE_GETTING_DATA,
|
||||
VOLE_STATE_WAITING_ACK,
|
||||
VOLE_STATE_MAX
|
||||
}eVoleState_t;
|
||||
|
||||
//
|
||||
// Vole packet type
|
||||
//
|
||||
typedef enum eVolePktType
|
||||
{
|
||||
VOLE_PKT_TYPE_UNKNOWN,
|
||||
VOLE_PKT_TYPE_DATA,
|
||||
VOLE_PKT_TYPE_ACK,
|
||||
VOLE_PKT_TYPE_CONTROL,
|
||||
VOLE_PKT_TYPE_MAX
|
||||
}eVolePktType_t;
|
||||
|
||||
typedef enum eVoleControl
|
||||
{
|
||||
VOLE_CONTROL_RESEND_REQ,
|
||||
VOLE_CONTROL_MAX
|
||||
}eVoleControl_t;
|
||||
|
||||
//
|
||||
// Vole status
|
||||
//
|
||||
typedef enum eVoleStatus
|
||||
{
|
||||
VOLE_STATUS_SUCCESS,
|
||||
VOLE_STATUS_CRC_ERROR,
|
||||
VOLE_STATUS_INVALID_METADATA_INFO,
|
||||
VOLE_STATUS_INVALID_PKT_LENGTH,
|
||||
VOLE_STATUS_INSUFFICIENT_BUFFER,
|
||||
VOLE_STATUS_UNKNOWN_ERROR,
|
||||
VOLE_STATUS_BUSY,
|
||||
VOLE_STATUS_TX_NOT_READY, // no connection or tx busy
|
||||
VOLE_STATUS_RESEND_REPLY,
|
||||
VOLE_STATUS_RECEIVE_CONTINUE,
|
||||
VOLE_STATUS_RECEIVE_DONE,
|
||||
VOLE_STATUS_MAX
|
||||
}eVoleStatus_t;
|
||||
|
||||
//
|
||||
// packet prefix structure
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pktType : 4;
|
||||
uint8_t pktSn : 4;
|
||||
uint8_t encrypted : 1;
|
||||
uint32_t ackEnabled : 1;
|
||||
uint32_t reserved : 6; // Reserved for future usage
|
||||
}
|
||||
volePktHeader_t;
|
||||
|
||||
//
|
||||
// packet
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t len; // data plus checksum
|
||||
volePktHeader_t header;
|
||||
uint8_t *data;
|
||||
}
|
||||
volePacket_t;
|
||||
|
||||
/*! Application data reception callback */
|
||||
typedef void (*voleRecvCback_t)(uint8_t *buf, uint16_t len);
|
||||
|
||||
/*! Application data transmission result callback */
|
||||
typedef void (*voleTransCback_t)(eVoleStatus_t status);
|
||||
|
||||
typedef void (*vole_reply_func_t)(eVoleStatus_t status, uint8_t *data, uint16_t len);
|
||||
|
||||
typedef void (*vole_packet_handler_func_t)(eVolePktType_t type, uint16_t len, uint8_t *buf);
|
||||
|
||||
typedef eVoleStatus_t (*vole_ack_sender_func_t)(eVolePktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
typedef void (*vole_data_sender_func_t)(uint8_t *buf, uint16_t len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
eVoleState_t txState;
|
||||
eVoleState_t rxState;
|
||||
volePacket_t rxPkt;
|
||||
volePacket_t txPkt;
|
||||
volePacket_t ackPkt;
|
||||
uint8_t txPktSn; // data packet serial number for Tx
|
||||
uint8_t lastRxPktSn; // last received data packet serial number
|
||||
uint16_t attMtuSize;
|
||||
// int total_tx_len;
|
||||
wsfTimer_t timeoutTimer; // timeout timer after DTP update done
|
||||
wsfTimerTicks_t txTimeoutMs;
|
||||
voleRecvCback_t recvCback; // application callback for data reception
|
||||
voleTransCback_t transCback; // application callback for tx complete status
|
||||
vole_data_sender_func_t data_sender_func;
|
||||
vole_ack_sender_func_t ack_sender_func;
|
||||
}
|
||||
voleCb_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// function definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
VoleBuildPkt(voleCb_t *voleCb, eVolePktType_t type, bool_t encrypted, bool_t enableACK, uint8_t *buf, uint16_t len);
|
||||
|
||||
eVoleStatus_t
|
||||
VoleReceivePkt(voleCb_t *voleCb, volePacket_t *pkt, uint16_t len, uint8_t *pValue);
|
||||
|
||||
void
|
||||
VoleSendReply(voleCb_t *voleCb, eVoleStatus_t status, uint8_t *data, uint16_t len);
|
||||
|
||||
void
|
||||
VoleSendControl(voleCb_t *voleCb, eVoleControl_t control, uint8_t *data, uint16_t len);
|
||||
|
||||
void
|
||||
VoleSendPacketHandler(voleCb_t *voleCb);
|
||||
|
||||
void
|
||||
VolePacketHandler(voleCb_t *voleCb, eVolePktType_t type, uint16_t len, uint8_t *buf);
|
||||
|
||||
void
|
||||
VoleResetPkt(volePacket_t *pkt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VOLE_COMMON_H
|
||||
Reference in New Issue
Block a user