Skip to content

Commit

Permalink
[tcat] Implement tcat advertisement.
Browse files Browse the repository at this point in the history
Commit introduces implementation of TCAT advertisement over BLE compialnt with
Thread 1.3.1 specification.
  • Loading branch information
canisLupus1313 committed May 22, 2024
1 parent 8b04e9c commit 4827f09
Show file tree
Hide file tree
Showing 16 changed files with 593 additions and 48 deletions.
33 changes: 33 additions & 0 deletions examples/platforms/simulation/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <openthread/platform/ble.h>

#include "openthread/error.h"
#include "openthread/tcat.h"
#include "utils/code_utils.h"

#define PLAT_BLE_MSG_DATA_MAX 2048
Expand Down Expand Up @@ -87,6 +88,16 @@ static void deinitFds(void)
}
}

otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer)
{
OT_UNUSED_VARIABLE(aInstance);
static uint8_t sAdvertisemntBuffer[OT_TCAT_ADVERTISEMENT_MAX_LEN];

*aAdvertisementBuffer = sAdvertisemntBuffer;

return OT_ERROR_NONE;
}

otError otPlatBleEnable(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
Expand Down Expand Up @@ -214,3 +225,25 @@ OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance *aIns
* which is available in FTD/MTD library.
*/
}

void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities)
{
OT_UNUSED_VARIABLE(aInstance);
aBleLinkCapabilities->mGattNotifications = 1;
aBleLinkCapabilities->mL2CapDirect = 0;
aBleLinkCapabilities->mRsv = 0;
}

otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aAdvertisementData);
OT_UNUSED_VARIABLE(aAdvertisementLen);
return OT_ERROR_NONE;
}

bool otPlatBleSupportsMultiRadio(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return false;
}
13 changes: 12 additions & 1 deletion include/openthread/ble_secure.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ otError otBleSecureStart(otInstance *aInstance,
bool aTlvMode,
void *aContext);

/**
* Sets TCAT vendor info
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call.
*
* @retval OT_ERROR_NONE Successfully set value.
* @retval OT_ERROR_INVALID_ARGS Value not set.
*/
otError otBleSecureSetTcatVendorInfo(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo);

/**
* Enables the TCAT protocol over BLE Secure.
*
Expand All @@ -122,7 +133,7 @@ otError otBleSecureStart(otInstance *aInstance,
* @retval OT_ERROR_INVALID_STATE The BLE function has not been started or line mode is not selected.
*
*/
otError otBleSecureTcatStart(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo, otHandleTcatJoin aHandler);
otError otBleSecureTcatStart(otInstance *aInstance, otHandleTcatJoin aHandler);

/**
* Stops the BLE Secure server.
Expand Down
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (414)
#define OPENTHREAD_API_VERSION (415)

/**
* @addtogroup api-instance
Expand Down
67 changes: 67 additions & 0 deletions include/openthread/platform/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,23 @@ extern "C" {

#define OT_BLE_DEFAULT_POWER 0

/**
* TOBLE service UUID
*/

#define OT_TOBLE_SERVICE_UUID 0xfffb

/**
* Represent BLE link capabilities
*
*/
typedef struct otBleLinkCapabilities
{
uint8_t mRsv : 6;
bool mL2CapDirect : 1;
bool mGattNotifications : 1;
} otBleLinkCapabilities;

/**
* Represents a BLE packet.
*
Expand Down Expand Up @@ -151,6 +168,40 @@ otError otPlatBleDisable(otInstance *aInstance);
/****************************************************************************
* @section Bluetooth Low Energy GAP.
***************************************************************************/
/**
* Gets BLE Advertising buffer.
*
*
* @note This function shall be used only for BLE Peripheral role.
* Returned buffer should have enought space to fit max advertisement
* defined by specification.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_NO_BUFS No bufferspace available.
*
*/
otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer);

/**
* Sets BLE Advertising data.
*
*
* @note This function shall be used only for BLE Peripheral role.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_INVALID_STATE BLE Device is in invalid state.
* @retval OT_ERROR_INVALID_ARGS Invalid value has been supplied.
*
*/
otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen);

/**
* Starts BLE Advertising procedure.
Expand Down Expand Up @@ -281,6 +332,22 @@ otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, con
*/
extern void otPlatBleGattServerOnWriteRequest(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket);

/**
* Function to retrieve from platform BLE link capabilities.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aBleLinkCapabilities The pointer to retrieve the BLE ling capabilities.
*
*/
void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities);

/**
* Function to retrieve from platform multiradio support of BLE and IEEE.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
bool otPlatBleSupportsMultiRadio(otInstance *aInstance);
/**
* @}
*
Expand Down
44 changes: 35 additions & 9 deletions include/openthread/tcat.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ extern "C" {
#define OT_TCAT_MAX_SERVICE_NAME_LENGTH \
15 ///< Maximum string length of a UDP or TCP service name (does not include null char).

#define OT_TCAT_ADVERTISEMENT_MAX_LEN 29 ///< Maximum length of TCAT advertisement.
#define OT_TCAT_OPCODE 0x2 ///< TCAT Advertisement Operation Code.
#define OT_TCAT_MAX_VENDORID_SIZE 5 ///< TCAT max size of vendor ID including null as termination.

/**
* Represents TCAT status code.
*
Expand Down Expand Up @@ -111,6 +115,27 @@ typedef enum otTcatCommandClass

} otTcatCommandClass;

/**
* Represents Device ID type.
*
*/
typedef enum otTcatDeviceIdType
{
OT_TCAT_DEVICE_ID_EMPTY = 0, ///< Vendor device ID type not set
OT_TCAT_DEVICE_ID_OUI24 = 1, ///< Vendor device ID type IEEE OUI-24
OT_TCAT_DEVICE_ID_OUI36 = 2, ///< Vendor device ID type IEEE OUI-36
OT_TCAT_DEVICE_ID_DISCRIMINATOR = 3, ///< Vendor device ID type Device Discriminator
OT_TCAT_DEVICE_ID_IANAPEN = 4, ///< Vendor device ID type IANA PEN
OT_TCAT_DEVICE_ID_MAX = 5, ///< Vendor device ID type size
} otTcatDeviceIdType;

typedef struct otTcatDeviceId
{
otTcatDeviceIdType mDeviceIdType;
uint16_t mDeviceIdLen;
uint8_t mDeviceId[OT_TCAT_MAX_VENDORID_SIZE];
} otTcatDeviceId;

/**
* This structure represents a TCAT vendor information.
*
Expand All @@ -119,15 +144,16 @@ typedef enum otTcatCommandClass
*/
typedef struct otTcatVendorInfo
{
const char *mProvisioningUrl; ///< Provisioning URL path string
const char *mVendorName; ///< Vendor name string
const char *mVendorModel; ///< Vendor model string
const char *mVendorSwVersion; ///< Vendor software version string
const char *mVendorData; ///< Vendor specific data string
const char *mPskdString; ///< Vendor managed pre-shared key for device
const char *mInstallCode; ///< Vendor managed install code string
const char *mDeviceId; ///< Vendor managed device ID string (if NULL: device ID is set to EUI-64 in binary format)

const char *mProvisioningUrl; ///< Provisioning URL path string
const char *mVendorName; ///< Vendor name string
const char *mVendorModel; ///< Vendor model string
const char *mVendorSwVersion; ///< Vendor software version string
const char *mVendorData; ///< Vendor specific data string
const char *mPskdString; ///< Vendor managed pre-shared key for device
const char *mInstallCode; ///< Vendor managed install code string
const otTcatDeviceId *mDeviceIds; /** Vendor managed device ID array.
(if NULL: device ID is set to EUI-64 in binary format)
Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY */
} otTcatVendorInfo;

/**
Expand Down
93 changes: 89 additions & 4 deletions src/cli/cli_tcat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
#include "cli/cli_utils.hpp"

#include "cli/cli_tcat.hpp"
#include "common/code_utils.hpp"

#include <openthread/ble_secure.h>

#include <mbedtls/oid.h>
#include <openthread/error.h>
#include <openthread/tcat.h>
#include <openthread/platform/ble.h>

Expand Down Expand Up @@ -79,7 +81,9 @@ namespace ot {

namespace Cli {

const char kPskdVendor[] = "J01NM3";
otTcatDeviceId sVendorDeviceIds[OT_TCAT_DEVICE_ID_MAX];

const char kPskdVendor[] = "JJJJJJ";
const char kUrl[] = "dummy_url";

static void HandleBleSecureReceive(otInstance *aInstance,
Expand All @@ -99,7 +103,8 @@ static void HandleBleSecureReceive(otInstance *aInstance,
uint16_t nLen;
uint8_t buf[kTextMaxLen];

nLen = otMessageRead(aMessage, (uint16_t)aOffset, buf + kBufPrefixLen, sizeof(buf) - kBufPrefixLen - 1);
nLen =
otMessageRead(aMessage, static_cast<uint16_t>(aOffset), buf + kBufPrefixLen, sizeof(buf) - kBufPrefixLen - 1);

memcpy(buf, "RECV:", kBufPrefixLen);

Expand All @@ -109,6 +114,85 @@ static void HandleBleSecureReceive(otInstance *aInstance,
IgnoreReturnValue(otBleSecureFlush(aInstance));
}

template <> otError Tcat::Process<Cmd("vendorid")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
otTcatDeviceId devId;
static const char *const kVendorIdTypes[] = {"empty", "oui24", "oui36", "discriminator", "ianapen"};

mVendorInfo.mDeviceIds = sVendorDeviceIds;

if (aArgs[0].IsEmpty())
{
if (mVendorInfo.mDeviceIds[0].mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY)
{
OutputLine("Set vendorIds:");
for (size_t i = 0; mVendorInfo.mDeviceIds[i].mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY; i++)
{
OutputFormat("type %s, value: ", kVendorIdTypes[mVendorInfo.mDeviceIds[i].mDeviceIdType]);
OutputBytesLine(const_cast<uint8_t *>(mVendorInfo.mDeviceIds[i].mDeviceId),
mVendorInfo.mDeviceIds[i].mDeviceIdLen);
}
}
else
{
OutputLine("%s", kVendorIdTypes[OT_TCAT_DEVICE_ID_EMPTY]);
}
ExitNow();
}

if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_OUI24])
{
devId.mDeviceIdType = OT_TCAT_DEVICE_ID_OUI24;
}
else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_OUI36])
{
devId.mDeviceIdType = OT_TCAT_DEVICE_ID_OUI36;
}
else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_DISCRIMINATOR])
{
devId.mDeviceIdType = OT_TCAT_DEVICE_ID_DISCRIMINATOR;
}
else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_IANAPEN])
{
devId.mDeviceIdType = OT_TCAT_DEVICE_ID_IANAPEN;
}
else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_EMPTY])
{
for (otTcatDeviceId &vendorDeviceId : sVendorDeviceIds)
{
vendorDeviceId.mDeviceIdType = OT_TCAT_DEVICE_ID_EMPTY;
vendorDeviceId.mDeviceIdLen = 0;
}
ExitNow();
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}

if (!aArgs[1].IsEmpty() && aArgs[1].GetLength() < (OT_TCAT_MAX_VENDORID_SIZE * 2 + 1))
{
devId.mDeviceIdLen = OT_TCAT_MAX_VENDORID_SIZE;
SuccessOrExit(error = aArgs[1].ParseAsHexString(devId.mDeviceIdLen, devId.mDeviceId));
for (otTcatDeviceId &vendorDeviceId : sVendorDeviceIds)
{
if (vendorDeviceId.mDeviceIdType == devId.mDeviceIdType ||
vendorDeviceId.mDeviceIdType == OT_TCAT_DEVICE_ID_EMPTY)
{
vendorDeviceId = devId;
break;
}
}
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
exit:
return error;
}

template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
Expand All @@ -129,8 +213,9 @@ template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])

otBleSecureSetSslAuthMode(GetInstancePtr(), true);

SuccessOrExit(error = otBleSecureSetTcatVendorInfo(GetInstancePtr(), &mVendorInfo));
SuccessOrExit(error = otBleSecureStart(GetInstancePtr(), nullptr, HandleBleSecureReceive, true, nullptr));
SuccessOrExit(error = otBleSecureTcatStart(GetInstancePtr(), &mVendorInfo, nullptr));
SuccessOrExit(error = otBleSecureTcatStart(GetInstancePtr(), nullptr));

exit:
return error;
Expand All @@ -152,7 +237,7 @@ otError Tcat::Process(Arg aArgs[])
aCommandString, &Tcat::Process<Cmd(aCommandString)> \
}

static constexpr Command kCommands[] = {CmdEntry("start"), CmdEntry("stop")};
static constexpr Command kCommands[] = {CmdEntry("start"), CmdEntry("stop"), CmdEntry("vendorid")};

static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");

Expand Down
9 changes: 7 additions & 2 deletions src/core/api/ble_secure_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,14 @@ otError otBleSecureStart(otInstance *aInstance,
return AsCoreType(aInstance).Get<Ble::BleSecure>().Start(aConnectHandler, aReceiveHandler, aTlvMode, aContext);
}

otError otBleSecureTcatStart(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo, otHandleTcatJoin aHandler)
otError otBleSecureSetTcatVendorInfo(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo)
{
return AsCoreType(aInstance).Get<Ble::BleSecure>().TcatStart(AsCoreType(aVendorInfo), aHandler);
return AsCoreType(aInstance).Get<Ble::BleSecure>().TcatSetVendorInfo(AsCoreType(aVendorInfo));
}

otError otBleSecureTcatStart(otInstance *aInstance, otHandleTcatJoin aHandler)
{
return AsCoreType(aInstance).Get<Ble::BleSecure>().TcatStart(aHandler);
}

void otBleSecureStop(otInstance *aInstance) { AsCoreType(aInstance).Get<Ble::BleSecure>().Stop(); }
Expand Down
Loading

0 comments on commit 4827f09

Please sign in to comment.