initial commit

This commit is contained in:
2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions
@@ -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 */
@@ -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);
}
@@ -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;
}
@@ -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 */
@@ -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;
}