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;
|
||||
}
|
||||
Reference in New Issue
Block a user