initial commit
This commit is contained in:
Vendored
+262
@@ -0,0 +1,262 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Wireless Data Exchange profile application interface.
|
||||
*
|
||||
* Copyright (c) 2017-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef WDXC_API_H
|
||||
#define WDXC_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \addtogroup WIRELESS_DATA_EXCHANGE_PROFILE
|
||||
* \{ */
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief WDXC enumeration of handle indexes of characteristics to be discovered */
|
||||
enum
|
||||
{
|
||||
WDXC_DC_HDL_IDX, /*!< \brief WDX Device Configuration */
|
||||
WDXC_DC_CCC_HDL_IDX, /*!< \brief WDX Device Configuration CCC descriptor */
|
||||
WDXC_FTC_HDL_IDX, /*!< \brief WDX File Transfer Control */
|
||||
WDXC_FTC_CCC_HDL_IDX, /*!< \brief WDX File Transfer Control CCC descriptor */
|
||||
WDXC_FTD_HDL_IDX, /*!< \brief WDX File Transfer Data */
|
||||
WDXC_FTD_CCC_HDL_IDX, /*!< \brief WDX File Transfer Data CCC descriptor */
|
||||
WDXC_AU_HDL_IDX, /*!< \brief WDX Authenticationa */
|
||||
WDXC_AU_CCC_HDL_IDX, /*!< \brief WDX Authentication CCC descriptor */
|
||||
WDXC_HDL_LIST_LEN /*!< \brief WDX handle list length. */
|
||||
};
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/**************************************************************************************************
|
||||
Callback Function Datatypes
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief WDXC File Transfer Data callback.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param handle Handle of the file.
|
||||
* \param len length of pData in bytes.
|
||||
* \param pData File data.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
typedef void WdxcFtdCallback_t(dmConnId_t connId, uint16_t handle, uint16_t len, uint8_t *pData);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief WDXC File Transfer Control callback.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param handle Handle of the file.
|
||||
* \param op Control operation.
|
||||
* \param status Status of operation.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
typedef void WdxcFtcCallback_t(dmConnId_t connId, uint16_t handle, uint8_t op, uint8_t status);
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the WDXC.
|
||||
*
|
||||
* \param pFtdCallback Application Callback for File Transfer Data.
|
||||
* \param pFtcCallback Application Callback for File Transfer Control.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcInit(WdxcFtdCallback_t *pFtdCallback, WdxcFtcCallback_t *pFtcCallback);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called by application to notify the WDXC of DM and ATT Events.
|
||||
*
|
||||
* \param pEvt Pointer to the Event
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcProcMsg(wsfMsgHdr_t *pEvt);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Perform service and characteristic discovery for Wireless Data Exchange service.
|
||||
* Parameter pHdlList must point to an array of length \ref WDXC_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 WdxcWdxsDiscover(dmConnId_t connId, uint16_t *pHdlList);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Perform File Discovery
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pFileInfo Buffer to hold information about files
|
||||
* \param maxFiles Size of pFileInfo in number of \ref wsfEfsFileInfo_t objects
|
||||
*
|
||||
* \note When file discovery completes, the ftcCallback() will be called with operator equal to
|
||||
* \ref WDX_FTC_OP_EOF and file handle equal to \ref WDX_FLIST_HANDLE.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcDiscoverFiles(dmConnId_t connId, wsfEfsFileInfo_t *pFileInfo, uint8_t maxFiles);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to start a stream of a given file handle on the given connection.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of the file.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcStreamStart(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Stop the active stream.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcStreamStop(dmConnId_t connId);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to abort a wdx operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to abort operation on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendAbort(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to erase a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to erase on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendEraseFile(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to verify a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendVerifyFile(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to put a block of data into a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to put
|
||||
* \param fileSize The size of the file in bytes
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendPutReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset,
|
||||
uint32_t len, uint32_t fileSize, uint8_t type);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to perform a get a block of data from a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to get
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendGetReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset, uint32_t len, uint8_t type);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a data block to the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param len Size of pData in bytes
|
||||
* \param pData Data to put to the file
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtdSendBlock(dmConnId_t connId, uint32_t len, uint8_t *pData);
|
||||
|
||||
/*! \} */ /* WIRELESS_DATA_EXCHANGE_PROFILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WDXC_MAIN_H */
|
||||
Vendored
+211
@@ -0,0 +1,211 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Wireless Data Exchange profile client - File Transfer.
|
||||
*
|
||||
* Copyright (c) 2017-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_efs.h"
|
||||
#include "util/bstream.h"
|
||||
#include "svc_wdxs.h"
|
||||
#include "wdx_defs.h"
|
||||
#include "wdxc_api.h"
|
||||
#include "wdxc_main.h"
|
||||
#include "dm_api.h"
|
||||
#include "app_api.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
External Variables
|
||||
**************************************************************************************************/
|
||||
extern wdxcCb_t wdxcCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to abort a wdx operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to abort operation on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendAbort(dmConnId_t connId, uint16_t fileHdl)
|
||||
{
|
||||
uint8_t buf[WDX_FTC_ABORT_LEN];
|
||||
uint8_t *p = buf;
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTC_HDL_IDX];
|
||||
|
||||
UINT8_TO_BSTREAM(p, WDX_FTC_OP_ABORT);
|
||||
UINT16_TO_BSTREAM(p, fileHdl);
|
||||
|
||||
AttcWriteReq(connId, handle, WDX_FTC_ABORT_LEN, buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to erase a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to erase on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendEraseFile(dmConnId_t connId, uint16_t fileHdl)
|
||||
{
|
||||
uint8_t buf[WDX_FTC_ERASE_LEN];
|
||||
uint8_t *p = buf;
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTC_HDL_IDX];
|
||||
|
||||
UINT8_TO_BSTREAM(p, WDX_FTC_OP_ERASE_REQ);
|
||||
UINT16_TO_BSTREAM(p, fileHdl);
|
||||
|
||||
AttcWriteReq(connId, handle, WDX_FTC_ERASE_LEN, buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to verify a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendVerifyFile(dmConnId_t connId, uint16_t fileHdl)
|
||||
{
|
||||
uint8_t buf[WDX_FTC_VERIFY_LEN];
|
||||
uint8_t *p = buf;
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTC_HDL_IDX];
|
||||
|
||||
UINT8_TO_BSTREAM(p, WDX_FTC_OP_VERIFY_REQ);
|
||||
UINT16_TO_BSTREAM(p, fileHdl);
|
||||
|
||||
AttcWriteReq(connId, handle, WDX_FTC_VERIFY_LEN, buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to put a block of data into a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to put
|
||||
* \param fileSize The size of the file in bytes
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendPutReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset,
|
||||
uint32_t len, uint32_t fileSize, uint8_t type)
|
||||
{
|
||||
uint8_t buf[WDX_FTC_PUT_LEN];
|
||||
uint8_t *p = buf;
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTC_HDL_IDX];
|
||||
|
||||
UINT8_TO_BSTREAM(p, WDX_FTC_OP_PUT_REQ);
|
||||
UINT16_TO_BSTREAM(p, fileHdl);
|
||||
|
||||
UINT32_TO_BSTREAM(p, offset);
|
||||
UINT32_TO_BSTREAM(p, len);
|
||||
UINT32_TO_BSTREAM(p, fileSize);
|
||||
UINT8_TO_BSTREAM(p, type);
|
||||
|
||||
AttcWriteReq(connId, handle, WDX_FTC_PUT_LEN, buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to perform a get a block of data from a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to get
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendGetReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset, uint32_t len, uint8_t type)
|
||||
{
|
||||
uint8_t buf[WDX_FTC_GET_LEN];
|
||||
uint8_t *p = buf;
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTC_HDL_IDX];
|
||||
|
||||
UINT8_TO_BSTREAM(p, WDX_FTC_OP_GET_REQ);
|
||||
UINT16_TO_BSTREAM(p, fileHdl);
|
||||
|
||||
UINT32_TO_BSTREAM(p, offset);
|
||||
UINT32_TO_BSTREAM(p, len);
|
||||
UINT8_TO_BSTREAM(p, type);
|
||||
|
||||
AttcWriteReq(connId, handle, WDX_FTC_GET_LEN, buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a data block to the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param len Size of pData in bytes
|
||||
* \param pData Data to put to the file
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtdSendBlock(dmConnId_t connId, uint32_t len, uint8_t *pData)
|
||||
{
|
||||
uint16_t handle;
|
||||
|
||||
WSF_ASSERT(wdxcCb.conn[connId - 1].pHdlList != NULL)
|
||||
|
||||
handle = wdxcCb.conn[connId - 1].pHdlList[WDXC_FTD_HDL_IDX];
|
||||
|
||||
AttcWriteReq(connId, handle, (uint16_t) len, pData);
|
||||
}
|
||||
Vendored
+434
@@ -0,0 +1,434 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Wireless Data Exchange profile client.
|
||||
*
|
||||
* Copyright (c) 2013-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "util/wstr.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_efs.h"
|
||||
#include "wsf_os.h"
|
||||
#include "sec_api.h"
|
||||
#include "util/bstream.h"
|
||||
#include "dm_api.h"
|
||||
#include "att_api.h"
|
||||
#include "app_api.h"
|
||||
#include "svc_wdxs.h"
|
||||
#include "wdx_defs.h"
|
||||
#include "wdxc_api.h"
|
||||
#include "wdxc_main.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! WDXC control block */
|
||||
wdxcCb_t wdxcCb;
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! UUIDs */
|
||||
static const uint8_t wdxcDcUuid[ATT_128_UUID_LEN] = {WDX_DC_UUID}; /* WDX Device Configuration Characteristic */
|
||||
static const uint8_t wdxcFtcUuid[ATT_128_UUID_LEN] = {WDX_FTC_UUID}; /* WDX File Transfer Control Characteristic */
|
||||
static const uint8_t wdxcFtdUuid[ATT_128_UUID_LEN] = {WDX_FTD_UUID}; /* WDX File Transfer Data Characteristic */
|
||||
static const uint8_t wdxcAuUuid[ATT_128_UUID_LEN] = {WDX_AU_UUID}; /* WDX Authentication Characteristic */
|
||||
|
||||
/*! WDXC Device Configuration */
|
||||
static const attcDiscChar_t wdxcWdxsDc =
|
||||
{
|
||||
wdxcDcUuid,
|
||||
ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! WDXC Device Configuration CCC descriptor */
|
||||
static const attcDiscChar_t wdxcWdxsDcCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! WDXC File Transfer Control */
|
||||
static const attcDiscChar_t wdxcWdxsFtc =
|
||||
{
|
||||
wdxcFtcUuid,
|
||||
ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! WDXC File Transfer Control CCC descriptor */
|
||||
static const attcDiscChar_t wdxcWdxsFtcCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! WDXC File Transfer Data */
|
||||
static const attcDiscChar_t wdxcWdxsFtd =
|
||||
{
|
||||
wdxcFtdUuid,
|
||||
ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! WDXC File Transfer Data CCC descriptor */
|
||||
static const attcDiscChar_t wdxcWdxsFtdCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! WDXC Authentication */
|
||||
static const attcDiscChar_t wdxcWdxsAu =
|
||||
{
|
||||
wdxcAuUuid,
|
||||
ATTC_SET_UUID_128
|
||||
};
|
||||
|
||||
/*! WDXC Authentication CCC descriptor */
|
||||
static const attcDiscChar_t wdxcWdxsAuCcc =
|
||||
{
|
||||
attCliChCfgUuid,
|
||||
ATTC_SET_DESCRIPTOR
|
||||
};
|
||||
|
||||
/*! List of characteristics to be discovered; order matches handle index enumeration */
|
||||
static const attcDiscChar_t *wdxcWdxsDiscCharList[] =
|
||||
{
|
||||
&wdxcWdxsDc, /*! WDXC Device Configuration */
|
||||
&wdxcWdxsDcCcc, /*! WDXC Device Configuration CCC descriptor */
|
||||
&wdxcWdxsFtc, /*! WDXC File Transfer Control */
|
||||
&wdxcWdxsFtcCcc, /*! WDXC File Transfer Control CCC descriptor */
|
||||
&wdxcWdxsFtd, /*! WDXC File Transfer Data */
|
||||
&wdxcWdxsFtdCcc, /*! WDXC File Transfer Data CCC descriptor */
|
||||
&wdxcWdxsAu, /*! WDXC Authentication */
|
||||
&wdxcWdxsAuCcc, /*! WDXC Authentication CCC descriptor */
|
||||
};
|
||||
|
||||
/*! sanity check: make sure handle list length matches characteristic list length */
|
||||
WSF_CT_ASSERT(WDXC_HDL_LIST_LEN == ((sizeof(wdxcWdxsDiscCharList) / sizeof(attcDiscChar_t *))));
|
||||
|
||||
const uint8_t wdxcSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(WDX_SVC_UUID)};
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Perform service and characteristic discovery for Wireless Data Exchange service.
|
||||
* Parameter pHdlList must point to an array of length WDXC_WDX_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 WdxcWdxsDiscover(dmConnId_t connId, uint16_t *pHdlList)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
|
||||
/* Store pointer to the attribute handles in the control block */
|
||||
pConnCb->pHdlList = pHdlList;
|
||||
|
||||
/* Perform service discovery */
|
||||
AppDiscFindService(connId, ATT_16_UUID_LEN, (uint8_t *) wdxcSvcUuid,
|
||||
WDXC_HDL_LIST_LEN, (attcDiscChar_t **) wdxcWdxsDiscCharList, pHdlList);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Perform File Discovery
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pFileInfo Buffer to hold information about files
|
||||
* \param maxFiles Size of pFileInfo in number of wsfEfsFileInfo_t objects
|
||||
*
|
||||
* \note When discovery is complete, the ftcCallback will be called with op equal to
|
||||
* WDX_FTC_OP_EOF and the file handle equal to WDX_FLIST_HANDLE.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcDiscoverFiles(dmConnId_t connId, wsfEfsFileInfo_t *pFileInfo, uint8_t maxFiles)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
|
||||
/* Verify WDXC is Idle */
|
||||
if (pConnCb->fileHdl == WSF_EFS_INVALID_HANDLE)
|
||||
{
|
||||
uint16_t len = maxFiles * WDX_FLIST_RECORD_SIZE + WDX_FLIST_HDR_SIZE;
|
||||
|
||||
/* Update control information */
|
||||
pConnCb->pFileList = pFileInfo;
|
||||
pConnCb->fileCount = 0;
|
||||
pConnCb->maxFiles = maxFiles;
|
||||
pConnCb->fileHdl = WDX_FLIST_HANDLE;
|
||||
pConnCb->fDlPos = 0;
|
||||
|
||||
/* Perform a get on file zero (the file list handle) where the length of the get is
|
||||
* the most file information pFileInfo can hold */
|
||||
WdxcFtcSendGetReq(connId, WDX_FLIST_HANDLE, 0, len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Parse File Listing FTD data
|
||||
*
|
||||
* \param pValue FTD Data.
|
||||
* \param len Size of pValue in bytes
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void wdxsParseFileList(dmConnId_t connId, uint8_t *pValue, uint16_t len)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
uint16_t pos = 0;
|
||||
|
||||
/* Depending on the MTU, blocks of FTD data from the file list may end mid-value.
|
||||
* Maintain a global position called wdxcCb.fDlPos, and process FTD data byte by byte */
|
||||
|
||||
while (pos < len)
|
||||
{
|
||||
if (pConnCb->fDlPos < WDX_FLIST_HDR_SIZE)
|
||||
{
|
||||
/* Ignore file list header */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the file index and the position within the file index (the mark) */
|
||||
uint8_t mark = (pConnCb->fDlPos - WDX_FLIST_HDR_SIZE) % WDX_FLIST_RECORD_SIZE;
|
||||
uint8_t file = (pConnCb->fDlPos - WDX_FLIST_HDR_SIZE) / WDX_FLIST_RECORD_SIZE;
|
||||
wsfEfsFileInfo_t *pInfo;
|
||||
|
||||
/* Ignore data if there is insufficient space in pConnCb->pFileList */
|
||||
if (file >= pConnCb->maxFiles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pInfo = &pConnCb->pFileList[file];
|
||||
|
||||
/* Process a byte of data */
|
||||
switch (mark)
|
||||
{
|
||||
case 0: pConnCb->fileCount++; pInfo->handle = pValue[pos]; break;
|
||||
case 1: pInfo->handle |= ((uint16_t)pValue[pos]) << 8; break;
|
||||
case 2: pInfo->attributes.type = pValue[pos]; break;
|
||||
case 3: pInfo->attributes.permissions = pValue[pos]; break;
|
||||
case 4: pInfo->size = pValue[pos]; break;
|
||||
case 5: pInfo->size |= ((uint32_t)pValue[pos]) << 8; break;
|
||||
case 6: pInfo->size |= ((uint32_t)pValue[pos]) << 16; break;
|
||||
case 7: pInfo->size |= ((uint32_t)pValue[pos]) << 24; break;
|
||||
default:
|
||||
if (mark > 7 && mark < 8 + WSF_EFS_NAME_LEN)
|
||||
{
|
||||
pInfo->attributes.name[mark - 8] = pValue[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->attributes.version[mark - (8 + WSF_EFS_NAME_LEN)] = pValue[pos];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pConnCb->fDlPos++;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Parse a file transfer control message.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param pValue Pointer to buffer containing value.
|
||||
* \param len length of buffer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void wdxcParseFtc(dmConnId_t connId, uint8_t *pValue, uint16_t len)
|
||||
{
|
||||
/* Notification on a File Transfer Control (FTC) Attribute */
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
uint8_t *p = pValue;
|
||||
uint8_t op, status;
|
||||
uint16_t handle;
|
||||
|
||||
BSTREAM_TO_UINT8(op, p);
|
||||
BSTREAM_TO_UINT16(handle, p);
|
||||
|
||||
if (op == WDX_FTC_OP_ABORT || op == WDX_FTC_OP_EOF)
|
||||
{
|
||||
pConnCb->fileHdl = WSF_EFS_INVALID_HANDLE;
|
||||
status = WDX_FTC_ST_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
BSTREAM_TO_UINT8(status, p)
|
||||
}
|
||||
|
||||
/* Call appliation callback */
|
||||
if (wdxcCb.pFtdCallback)
|
||||
{
|
||||
(*wdxcCb.pFtcCallback)(connId, handle, op, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Parse a wdxc file transfer data message.
|
||||
*
|
||||
* \param pValue Pointer to buffer containing value.
|
||||
* \param len length of buffer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void wdxcParseFtd(dmConnId_t connId, uint8_t *pValue, uint16_t len)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
|
||||
if (pConnCb->fileHdl == WDX_FLIST_HANDLE)
|
||||
{
|
||||
/* File Discovery is in progress */
|
||||
wdxsParseFileList(connId, pValue, len);
|
||||
}
|
||||
else if (pConnCb->fileHdl != WSF_EFS_INVALID_HANDLE)
|
||||
{
|
||||
/* Notify application of File Transfer Data (FTD) */
|
||||
if (wdxcCb.pFtdCallback)
|
||||
{
|
||||
(*wdxcCb.pFtdCallback)(connId, pConnCb->fileHdl, len, pValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Process a value received in an ATT read response, notification, or indication
|
||||
* message. Parameter pHdlList must point to an array of length WDXC_WDX_HDL_LIST_LEN.
|
||||
* If the attribute handle of the message matches a handle in the handle list the value
|
||||
* is processed, otherwise it is ignored.
|
||||
*
|
||||
* \param pMsg ATT callback message.
|
||||
*
|
||||
* \return ATT_SUCCESS if handle is found, ATT_ERR_NOT_FOUND otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t wdxcWdxsValueUpdate(attEvt_t *pMsg)
|
||||
{
|
||||
uint16_t *pHdlList = wdxcCb.conn[pMsg->hdr.param-1].pHdlList;
|
||||
uint8_t status = ATT_SUCCESS;
|
||||
|
||||
/* device configuration */
|
||||
if (pMsg->handle == pHdlList[WDXC_DC_HDL_IDX])
|
||||
{
|
||||
/* Not Supported */
|
||||
}
|
||||
/* file transfer control */
|
||||
else if (pMsg->handle == pHdlList[WDXC_FTC_HDL_IDX])
|
||||
{
|
||||
APP_TRACE_INFO0("WDXC file transfer control.");
|
||||
wdxcParseFtc((dmConnId_t) pMsg->hdr.param, pMsg->pValue, pMsg->valueLen);
|
||||
}
|
||||
/* file transfer data */
|
||||
else if (pMsg->handle == pHdlList[WDXC_FTD_HDL_IDX])
|
||||
{
|
||||
wdxcParseFtd((dmConnId_t) pMsg->hdr.param, pMsg->pValue, pMsg->valueLen);
|
||||
}
|
||||
/* authentication */
|
||||
else if (pMsg->handle == pHdlList[WDXC_AU_HDL_IDX])
|
||||
{
|
||||
/* Not Supported */
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ATT_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called by application to notify the WDXC of System Events.
|
||||
*
|
||||
* \param pEvt Pointer to the Event
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcProcMsg(wsfMsgHdr_t *pEvt)
|
||||
{
|
||||
switch (pEvt->event)
|
||||
{
|
||||
case ATTC_HANDLE_VALUE_NTF:
|
||||
wdxcWdxsValueUpdate((attEvt_t *)pEvt);
|
||||
break;
|
||||
|
||||
case DM_CONN_CLOSE_IND:
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[pEvt->param - 1];
|
||||
|
||||
/* Set file handle to invalid to indicate no file operation is in progress */
|
||||
pConnCb->fileHdl = WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the WDXC.
|
||||
*
|
||||
* \param pFtdCallback File transfer data callback
|
||||
* \param pFtcCallback File transfer control callback
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcInit(WdxcFtdCallback_t *pFtdCallback, WdxcFtcCallback_t *pFtcCallback)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
APP_TRACE_INFO0("WDXC: WdxcHandlerInit");
|
||||
|
||||
/* Initialize the control block */
|
||||
memset(&wdxcCb, 0, sizeof(wdxcCb));
|
||||
|
||||
for (i = 0; i < DM_CONN_MAX; i++)
|
||||
{
|
||||
wdxcCb.conn[i].fileHdl = WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Store callbacks */
|
||||
wdxcCb.pFtcCallback = pFtcCallback;
|
||||
wdxcCb.pFtdCallback = pFtdCallback;
|
||||
}
|
||||
Vendored
+141
@@ -0,0 +1,141 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Wireless Data Exchange profile implementation.
|
||||
*
|
||||
* Copyright (c) 2013-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef WDXC_MAIN_H
|
||||
#define WDXC_MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \addtogroup WIRELESS_DATA_EXCHANGE_PROFILE
|
||||
* \{ */
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief WDXC Connection Control Block */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t *pHdlList; /*!< \brief Attrtibute Handles */
|
||||
|
||||
/* Operation in progress Control */
|
||||
uint16_t fileHdl; /*!< \brief File Handle */
|
||||
|
||||
/* File Listing Control */
|
||||
wsfEfsFileInfo_t *pFileList; /*!< \brief File Listing storage */
|
||||
uint16_t maxFiles; /*!< \brief Size of pFileList in number of wsfEfsFileInfo_t objects */
|
||||
uint16_t fileCount; /*!< \brief Number of files on peer device */
|
||||
uint16_t fDlPos; /*!< \brief Position in the download of file information */
|
||||
} wdxcConnCb_t;
|
||||
|
||||
/*! \brief WDXC Control Block */
|
||||
typedef struct
|
||||
{
|
||||
wdxcConnCb_t conn[DM_CONN_MAX]; /*!< \brief Connection control */
|
||||
WdxcFtdCallback_t *pFtdCallback; /*!< \brief File Transfer Data Application Callback */
|
||||
WdxcFtcCallback_t *pFtcCallback; /*!< \brief File Transfer Control Application Callback */
|
||||
} wdxcCb_t;
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to abort a wdx operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to abort operation on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendAbort(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to erase a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to erase on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendEraseFile(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to verify a file.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendVerifyFile(dmConnId_t connId, uint16_t fileHdl);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to put a block of data into a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to put
|
||||
* \param fileSize The size of the file in bytes
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendPutReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset,
|
||||
uint32_t len, uint32_t fileSize, uint8_t type);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to perform a get a block of data from a file on the peer device
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of file to verify on peer device
|
||||
* \param offset The offset from the beginning of the file in bytes
|
||||
* \param len The number of bytes to get
|
||||
* \param type reserved
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcFtcSendGetReq(dmConnId_t connId, uint16_t fileHdl, uint32_t offset, uint32_t len, uint8_t type);
|
||||
|
||||
/*! \} */ /* WIRELESS_DATA_EXCHANGE_PROFILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WDXC_MAIN_H */
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Wireless Data Exchange profile client - Stream utility functions.
|
||||
*
|
||||
* Copyright (c) 2017-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "util/wstr.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_efs.h"
|
||||
#include "util/bstream.h"
|
||||
#include "dm_api.h"
|
||||
#include "att_api.h"
|
||||
#include "app_api.h"
|
||||
#include "wdx_defs.h"
|
||||
#include "wdxc_api.h"
|
||||
#include "wdxc_main.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
External Variables
|
||||
**************************************************************************************************/
|
||||
extern wdxcCb_t wdxcCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a request to start a stream of a given file handle on the given connection.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param fileHdl Handle of the file.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcStreamStart(dmConnId_t connId, uint16_t fileHdl)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
|
||||
/* Verify WDXC is Idle */
|
||||
if (pConnCb->fileHdl == WSF_EFS_INVALID_HANDLE)
|
||||
{
|
||||
pConnCb->fileHdl = fileHdl;
|
||||
|
||||
/* Send a get request with len set the MTU length (offset is ignored for streams) */
|
||||
WdxcFtcSendGetReq(connId, fileHdl, 0, AttGetMtu(connId), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Stop the active stream.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WdxcStreamStop(dmConnId_t connId)
|
||||
{
|
||||
wdxcConnCb_t *pConnCb = &wdxcCb.conn[connId - 1];
|
||||
|
||||
/* Send an abort to stop the stream */
|
||||
WdxcFtcSendAbort(connId, pConnCb->fileHdl);
|
||||
|
||||
/* Set file handle to invalid to indicate no file operation is in progress */
|
||||
pConnCb->fileHdl = WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
Reference in New Issue
Block a user