Skip to content

Commit

Permalink
[tcat] Implement new tcat General commands.
Browse files Browse the repository at this point in the history
New General TLV's implemented:
	- Get network name
	- Get device id
	- Get ext pan ID
	- get provisioning URL
  • Loading branch information
canisLupus1313 committed Aug 21, 2024
1 parent de7b198 commit b0bd483
Show file tree
Hide file tree
Showing 12 changed files with 482 additions and 126 deletions.
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 (434)
#define OPENTHREAD_API_VERSION (435)

/**
* @addtogroup api-instance
Expand Down
55 changes: 34 additions & 21 deletions include/openthread/tcat.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +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.
#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_ADVERTISED_DEVICEID_SIZE 5 ///< TCAT max size of any type of advertised Device ID.
#define OT_TCAT_MAX_DEVICEID_SIZE 64 ///< TCAT max size of device ID.

/**
* Represents TCAT status code.
Expand Down Expand Up @@ -116,25 +117,35 @@ typedef enum otTcatCommandClass
} otTcatCommandClass;

/**
* Represents Device ID type.
* Represents Advertised Device ID type. (used during TCAT advertisement)
*
*/
typedef enum otTcatDeviceIdType
typedef enum otTcatAdvertisedDeviceIdType
{
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;
} otTcatAdvertisedDeviceIdType;

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

/**
* Represents General Device ID type.
*
*/
typedef struct otTcatGeneralDeviceId
{
uint16_t mDeviceIdLen;
uint8_t mDeviceId[OT_TCAT_MAX_DEVICEID_SIZE];
} otTcatGeneralDeviceId;

/**
* This structure represents a TCAT vendor information.
Expand All @@ -144,16 +155,18 @@ typedef struct otTcatDeviceId
*/
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 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 */
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 otTcatAdvertisedDeviceId *mAdvertisedDeviceIds; /** Vendor managed advertised device ID array.
Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY */
const otTcatGeneralDeviceId *mGeneralDeviceId; /** Vendor managed general device ID array.
(if NULL: device ID is set to EUI-64 in binary format)*/

} otTcatVendorInfo;

/**
Expand Down
87 changes: 87 additions & 0 deletions src/cli/README_TCAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,103 @@

## Command List

- advid [#advid]
- devid [#devid]
- help [#help]
- start [#start]
- stop [#stop]

### advid

Displays currently set TCAT advertised ids.

```bash
tcat advid
type oui24, value: f378aa
Done
```

### advid ianapen \<id\>

Sets TCAT advertised ianapen id.

```bash
tcat advid ianapen f378aabb
Done
```

### advid oui24 \<id\>

Sets TCAT advertised oui24 id.

```bash
tcat advid oui24 f378aa
Done
```

### advid oui36 \<id\>

Sets TCAT advertised oui36 id.

```bash
tcat advid oui36 f378aabbcc
Done
```

### advid discriminator \<id\>

Sets TCAT advertised discriminator id.

```bash
tcat advid discriminator f378aabbdd
Done
```

### advid clear

Clears TCAT advertised id.

```bash
tcat advid clear
Done
```

### devid

Displays currently set TCAT device id.

```bash
tcat devid
abcd
Done
```

### devid \<id\>

Sets TCAT device id.

```bash
tcat devid abcd
Done
```

### devid clear

Clears TCAT device id.

```bash
tcat devid clear
Done
```

### help

print help

```bash
tcat help
advid
devid
help
start
stop
Expand Down
93 changes: 73 additions & 20 deletions src/cli/cli_tcat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

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

#include <openthread/ble_secure.h>

Expand Down Expand Up @@ -88,11 +89,26 @@ namespace ot {

namespace Cli {

otTcatDeviceId sVendorDeviceIds[OT_TCAT_DEVICE_ID_MAX];
otTcatAdvertisedDeviceId sAdvertisedDeviceIds[OT_TCAT_DEVICE_ID_MAX];
otTcatGeneralDeviceId sGeneralDeviceId;

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

static bool IsDeviceIdSet(void)
{
bool ret = false;
for (const otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
{
if (vendorDeviceId.mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY)
{
ExitNow(ret = true);
}
}
exit:
return ret;
}

static void HandleBleSecureReceive(otInstance *aInstance,
const otMessage *aMessage,
int32_t aOffset,
Expand Down Expand Up @@ -121,30 +137,26 @@ static void HandleBleSecureReceive(otInstance *aInstance,
IgnoreReturnValue(otBleSecureFlush(aInstance));
}

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

mVendorInfo.mDeviceIds = sVendorDeviceIds;
mVendorInfo.mAdvertisedDeviceIds = sAdvertisedDeviceIds;

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

Expand All @@ -166,7 +178,7 @@ template <> otError Tcat::Process<Cmd("vendorid")>(Arg aArgs[])
}
else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_EMPTY])
{
for (otTcatDeviceId &vendorDeviceId : sVendorDeviceIds)
for (otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
{
vendorDeviceId.mDeviceIdType = OT_TCAT_DEVICE_ID_EMPTY;
vendorDeviceId.mDeviceIdLen = 0;
Expand All @@ -178,11 +190,11 @@ template <> otError Tcat::Process<Cmd("vendorid")>(Arg aArgs[])
ExitNow(error = OT_ERROR_INVALID_ARGS);
}

if (!aArgs[1].IsEmpty() && aArgs[1].GetLength() < (OT_TCAT_MAX_VENDORID_SIZE * 2 + 1))
if (!aArgs[1].IsEmpty() && aArgs[1].GetLength() < (OT_TCAT_MAX_ADVERTISED_DEVICEID_SIZE * 2 + 1))
{
devId.mDeviceIdLen = OT_TCAT_MAX_VENDORID_SIZE;
devId.mDeviceIdLen = OT_TCAT_MAX_ADVERTISED_DEVICEID_SIZE;
SuccessOrExit(error = aArgs[1].ParseAsHexString(devId.mDeviceIdLen, devId.mDeviceId));
for (otTcatDeviceId &vendorDeviceId : sVendorDeviceIds)
for (otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
{
if (vendorDeviceId.mDeviceIdType == devId.mDeviceIdType ||
vendorDeviceId.mDeviceIdType == OT_TCAT_DEVICE_ID_EMPTY)
Expand All @@ -200,6 +212,35 @@ template <> otError Tcat::Process<Cmd("vendorid")>(Arg aArgs[])
return error;
}

template <> otError Tcat::Process<Cmd("devid")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;

if (aArgs[0].IsEmpty())
{
if (sGeneralDeviceId.mDeviceIdLen != 0)
{
OutputLine("TCAT DeviceId:");
OutputBytesLine(sGeneralDeviceId.mDeviceId, sGeneralDeviceId.mDeviceIdLen);
}
ExitNow();
}

if (aArgs[0] == "clear")
{
ClearAllBytes(sGeneralDeviceId);
}
else
{
VerifyOrExit(aArgs[0].GetLength() < (OT_TCAT_MAX_DEVICEID_SIZE * 2 + 1), error = OT_ERROR_INVALID_ARGS);
sGeneralDeviceId.mDeviceIdLen = OT_TCAT_MAX_DEVICEID_SIZE;
SuccessOrExit(error = aArgs[0].ParseAsHexString(sGeneralDeviceId.mDeviceIdLen, sGeneralDeviceId.mDeviceId));
}

exit:
return error;
}

template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
Expand All @@ -210,6 +251,16 @@ template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])
mVendorInfo.mPskdString = kPskdVendor;
mVendorInfo.mProvisioningUrl = kUrl;

if (IsDeviceIdSet())
{
mVendorInfo.mAdvertisedDeviceIds = sAdvertisedDeviceIds;
}

if (sGeneralDeviceId.mDeviceIdLen != 0)
{
mVendorInfo.mGeneralDeviceId = &sGeneralDeviceId;
}

otBleSecureSetCertificate(GetInstancePtr(), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_X509_CERT),
sizeof(OT_CLI_TCAT_X509_CERT), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_PRIV_KEY),
sizeof(OT_CLI_TCAT_PRIV_KEY));
Expand Down Expand Up @@ -244,10 +295,12 @@ otError Tcat::Process(Arg aArgs[])
aCommandString, &Tcat::Process<Cmd(aCommandString)> \
}

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

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

#undef CmdEntry

otError error = OT_ERROR_NONE;
const Command *command;

Expand Down
Loading

0 comments on commit b0bd483

Please sign in to comment.