diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index 61dc58a8965b90..9ae80a2af5a54f 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -24,7 +24,8 @@ executable("chip-tool") { "commands/common/Command.cpp", "commands/common/Commands.cpp", "commands/pairing/PairingCommand.cpp", - "commands/payload/ParseCommand.cpp", + "commands/payload/AdditionalDataParseCommand.cpp", + "commands/payload/SetupPayloadParseCommand.cpp", "config/PersistentStorage.cpp", "main.cpp", ] diff --git a/examples/chip-tool/README.md b/examples/chip-tool/README.md index acb3c2bdbe2faa..5bde02613f7c51 100644 --- a/examples/chip-tool/README.md +++ b/examples/chip-tool/README.md @@ -101,18 +101,25 @@ with the target cluster name and the target command name ### How to parse a setup code To parse a setup code, run the built executable with the `payload` cluster name -and the `parse` command +and the `parse-setup-payload` command - $ chip-tool payload parse code + $ chip-tool payload parse-setup-payload code #### QR Code - $ chip-tool payload parse "CH:#####" + $ chip-tool payload parse-setup-payload "CH:#####" #### QR Code with optional Vendor Info - $ chip-tool chip-tool payload parse "CH:#####" + $ chip-tool chip-tool payload parse-setup-payload "CH:#####" #### Manual Setup Code - $ chip-tool payload parse :#####" + $ chip-tool payload parse-setup-payload :#####" + +# Using the Client for Additional Data Payload + +To parse an additional data payload, run the built executable with the `payload` +cluster name and the `parse-additional-data-payload` command + + $ chip-tool payload parse-additional-data-payload "#####" diff --git a/examples/chip-tool/commands/payload/AdditionalDataParseCommand.cpp b/examples/chip-tool/commands/payload/AdditionalDataParseCommand.cpp new file mode 100644 index 00000000000000..3edad12d30ad4f --- /dev/null +++ b/examples/chip-tool/commands/payload/AdditionalDataParseCommand.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * 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 "AdditionalDataParseCommand.h" +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::SetupPayload; + +CHIP_ERROR AdditionalDataParseCommand::Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) +{ + std::vector payloadData; + AdditionalDataPayload resultPayload; + CHIP_ERROR err = CHIP_NO_ERROR; + std::string payloadString(mPayload); + + // Decode input payload + size_t len = payloadString.length(); + + for (size_t i = 0; i < len; i += 2) + { + auto str = payloadString.substr(i, 2); + uint8_t x = (uint8_t) stoi(str, 0, 16); + payloadData.push_back(x); + } + err = AdditionalDataPayloadParser(payloadData.data(), (uint32_t) payloadData.size()).populatePayload(resultPayload); + SuccessOrExit(err); + ChipLogProgress(chipTool, "AdditionalDataParseCommand, RotatingDeviceId=%s", resultPayload.rotatingDeviceId.c_str()); +exit: + return err; +} diff --git a/examples/chip-tool/commands/payload/AdditionalDataParseCommand.h b/examples/chip-tool/commands/payload/AdditionalDataParseCommand.h new file mode 100644 index 00000000000000..ddb0bd462618d4 --- /dev/null +++ b/examples/chip-tool/commands/payload/AdditionalDataParseCommand.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +#pragma once + +#include "../common/Command.h" + +class AdditionalDataParseCommand : public Command +{ +public: + AdditionalDataParseCommand() : Command("parse-additional-data-payload") { AddArgument("payload", &mPayload); } + CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) override; + +private: + char * mPayload; +}; diff --git a/examples/chip-tool/commands/payload/Commands.h b/examples/chip-tool/commands/payload/Commands.h index 83c1124af44910..e0ed52f25795f0 100644 --- a/examples/chip-tool/commands/payload/Commands.h +++ b/examples/chip-tool/commands/payload/Commands.h @@ -18,14 +18,13 @@ #pragma once -#include "ParseCommand.h" +#include "AdditionalDataParseCommand.h" +#include "SetupPayloadParseCommand.h" void registerCommandsPayload(Commands & commands) { const char * clusterName = "Payload"; - commands_list clusterCommands = { - make_unique(), - }; + commands_list clusterCommands = { make_unique(), make_unique() }; commands.Register(clusterName, clusterCommands); } diff --git a/examples/chip-tool/commands/payload/ParseCommand.cpp b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp similarity index 89% rename from examples/chip-tool/commands/payload/ParseCommand.cpp rename to examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp index 534efb14e2acc9..69d94884904e88 100644 --- a/examples/chip-tool/commands/payload/ParseCommand.cpp +++ b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp @@ -16,14 +16,14 @@ * */ -#include "ParseCommand.h" +#include "SetupPayloadParseCommand.h" #include #include #include using namespace ::chip; -CHIP_ERROR ParseCommand::Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) +CHIP_ERROR SetupPayloadParseCommand::Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) { std::string codeString(mCode); SetupPayload payload; @@ -38,7 +38,7 @@ CHIP_ERROR ParseCommand::Run(PersistentStorage & storage, NodeId localId, NodeId return err; } -CHIP_ERROR ParseCommand::Print(chip::SetupPayload payload) +CHIP_ERROR SetupPayloadParseCommand::Print(chip::SetupPayload payload) { std::string serialNumber; std::vector optionalVendorData; @@ -80,7 +80,7 @@ CHIP_ERROR ParseCommand::Print(chip::SetupPayload payload) return err; } -CHIP_ERROR ParseCommand::Parse(std::string codeString, chip::SetupPayload & payload) +CHIP_ERROR SetupPayloadParseCommand::Parse(std::string codeString, chip::SetupPayload & payload) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -98,7 +98,7 @@ CHIP_ERROR ParseCommand::Parse(std::string codeString, chip::SetupPayload & payl return err; } -bool ParseCommand::IsQRCode(std::string codeString) +bool SetupPayloadParseCommand::IsQRCode(std::string codeString) { return codeString.rfind(QRCODE_PREFIX) == 0; } diff --git a/examples/chip-tool/commands/payload/ParseCommand.h b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.h similarity index 88% rename from examples/chip-tool/commands/payload/ParseCommand.h rename to examples/chip-tool/commands/payload/SetupPayloadParseCommand.h index f7d2a41a7ad8cc..58aac2409200a6 100644 --- a/examples/chip-tool/commands/payload/ParseCommand.h +++ b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.h @@ -21,10 +21,10 @@ #include "../common/Command.h" #include -class ParseCommand : public Command +class SetupPayloadParseCommand : public Command { public: - ParseCommand() : Command("parse") { AddArgument("code", &mCode); } + SetupPayloadParseCommand() : Command("parse-setup-payload") { AddArgument("payload", &mCode); } CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) override; private: diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index 2a7ebf0af5cda0..f9c7f47ba6ddc6 100644 --- a/src/ble/BleLayer.cpp +++ b/src/ble/BleLayer.cpp @@ -163,6 +163,10 @@ const ChipBleUUID BleLayer::CHIP_BLE_CHAR_2_ID = { { // 18EE2EF5-263D-4559-959F- 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x12 } }; +const ChipBleUUID BleLayer::CHIP_BLE_CHAR_3_ID = { { // 64630238-8772-45F2-B87D-748A83218F04 + 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, + 0x21, 0x8F, 0x04 } }; + void BleLayerObject::Release() { // Decrement the ref count. When it reaches zero, NULL out the pointer to the chip::System::Layer @@ -600,7 +604,7 @@ bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const Chip return false; } - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) + if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) { // Find end point already associated with BLE connection, if any. BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); @@ -625,7 +629,7 @@ bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const Chip return false; } - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) + if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) { BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); @@ -649,7 +653,7 @@ bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const Ch return false; } - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) + if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) { // Find end point already associated with BLE connection, if any. BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); @@ -674,7 +678,7 @@ bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const Ch return false; } - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) + if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) { // Find end point already associated with BLE connection, if any. BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); diff --git a/src/ble/BleLayer.h b/src/ble/BleLayer.h index 3117bdeb310f3d..edd084aaa1ac01 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -334,6 +334,8 @@ class DLL_EXPORT BleLayer static const ChipBleUUID CHIP_BLE_CHAR_1_ID; // UUID of CHIP service characteristic used for peripheral indications. static const ChipBleUUID CHIP_BLE_CHAR_2_ID; + // UUID of CHIP service characteristic used for additional data + static const ChipBleUUID CHIP_BLE_CHAR_3_ID; BleConnectionDelegate * mConnectionDelegate; BlePlatformDelegate * mPlatformDelegate; diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index f44a9412dd9996..58a94bd6c832df 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -937,3 +937,12 @@ #ifndef CHIP_DEVICE_CONFIG_FIRMWARE_BUILD_TIME #define CHIP_DEVICE_CONFIG_FIRMWARE_BUILD_TIME __TIME__ #endif + +/** + * CHIP_ROTATING_DEVICE_ID + * + * Sample Rotating Device Id. + */ +#ifndef CHIP_ROTATING_DEVICE_ID +#define CHIP_ROTATING_DEVICE_ID "1122334455667788" +#endif diff --git a/src/lib/mdns/DiscoveryManager.cpp b/src/lib/mdns/DiscoveryManager.cpp index 40c6cf25169a78..4d7b183fd94a76 100644 --- a/src/lib/mdns/DiscoveryManager.cpp +++ b/src/lib/mdns/DiscoveryManager.cpp @@ -170,11 +170,11 @@ CHIP_ERROR DiscoveryManager::PublishUnprovisionedDevice(chip::Inet::IPAddressTyp char discriminatorBuf[5]; // hex representation of 16-bit discriminator char vendorProductBuf[10]; // "FFFF+FFFF" // TODO: The text entry will be updated in the spec, update accordingly. - TextEntry entries[2] = { - { "D", nullptr, 0 }, - { "VP", nullptr, 0 }, - }; - +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + TextEntry entries[3] = { { "D", nullptr, 0 }, { "VP", nullptr, 0 }, { "RI", nullptr, 0 } }; +#else + TextEntry entries[2] = { { "D", nullptr, 0 }, { "VP", nullptr, 0 } }; +#endif VerifyOrExit(mMdnsInitialized, error = CHIP_ERROR_INCORRECT_STATE); ChipLogProgress(Discovery, "setup mdns service"); SuccessOrExit(error = chip::DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(discriminator)); @@ -185,10 +185,16 @@ CHIP_ERROR DiscoveryManager::PublishUnprovisionedDevice(chip::Inet::IPAddressTyp SuccessOrExit(error = chip::DeviceLayer::ConfigurationMgr().GetProductId(productID)); snprintf(discriminatorBuf, sizeof(discriminatorBuf), "%04X", discriminator); snprintf(vendorProductBuf, sizeof(vendorProductBuf), "%04X+%04X", vendorID, productID); - entries[0].mData = reinterpret_cast(discriminatorBuf); - entries[0].mDataSize = strnlen(discriminatorBuf, sizeof(discriminatorBuf)); - entries[1].mData = reinterpret_cast(vendorProductBuf); - entries[1].mDataSize = strnlen(discriminatorBuf, sizeof(vendorProductBuf)); + entries[0].mData = reinterpret_cast(discriminatorBuf); + entries[0].mDataSize = strnlen(discriminatorBuf, sizeof(discriminatorBuf)); + entries[1].mData = reinterpret_cast(vendorProductBuf); + entries[1].mDataSize = strnlen(discriminatorBuf, sizeof(vendorProductBuf)); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + // Rotating Device ID + entries[2].mData = reinterpret_cast(CHIP_ROTATING_DEVICE_ID); + entries[2].mDataSize = strnlen(CHIP_ROTATING_DEVICE_ID, sizeof(CHIP_ROTATING_DEVICE_ID)); +#endif service.mTextEntryies = entries; service.mTextEntrySize = sizeof(entries) / sizeof(TextEntry); service.mPort = CHIP_PORT; diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 313e9d0de82da3..b442e86a7000a4 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -44,6 +44,9 @@ if (chip_device_platform != "none") { # By pass provision and secure session chip_bypass_rendezvous = false + + # Enable including the additional data in the advertisement packets + chip_enable_additional_data_advertising = true } buildconfig_header("platform_buildconfig") { @@ -79,6 +82,12 @@ if (chip_device_platform != "none") { defines += [ "CHIP_BYPASS_RENDEZVOUS=1" ] } + if (chip_enable_additional_data_advertising) { + defines += [ "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING=1" ] + } else { + defines += [ "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING=0" ] + } + if (chip_device_platform == "darwin") { defines += [ "CHIP_DEVICE_LAYER_TARGET_DARWIN=1", diff --git a/src/platform/Linux/CHIPBluezHelper.cpp b/src/platform/Linux/CHIPBluezHelper.cpp index 8d786e7e83ac10..7bff2faebaeef9 100644 --- a/src/platform/Linux/CHIPBluezHelper.cpp +++ b/src/platform/Linux/CHIPBluezHelper.cpp @@ -48,9 +48,11 @@ * Provides Bluez dbus implementatioon for BLE */ +#include #include #include #include +#include #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE #include @@ -65,6 +67,8 @@ #include using namespace ::nl; +using namespace chip::SetupPayload; +using namespace chip::Protocols; namespace chip { namespace DeviceLayer { @@ -695,6 +699,11 @@ static void BluezConnectionInit(BluezConnection * apConn) { apConn->mpC2 = char1; } + else if ((BluezIsCharOnService(char1, apConn->mpService) == TRUE) && + (strcmp(bluez_gatt_characteristic1_get_uuid(char1), CHIP_PLAT_BLE_UUID_C3_STRING) == 0)) + { + apConn->mpC3 = char1; + } else { g_object_unref(char1); @@ -1256,11 +1265,57 @@ void BluezObjectsCleanup(BluezEndpoint * apEndpoint) EndpointCleanup(apEndpoint); } +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +static void UpdateAdditionalDataCharacteristic(BluezGattCharacteristic1 * characteristic) +{ + if (characteristic == nullptr) + { + return; + } + + // Construct the TLV for the additional data + GVariant * cValue = nullptr; + CHIP_ERROR err = CHIP_NO_ERROR; + TLVWriter writer; + TLVWriter innerWriter; + chip::System::PacketBufferHandle bufferHandle = chip::System::PacketBuffer::New(); + chip::System::PacketBuffer * buffer = bufferHandle.Get_ForNow(); + + writer.Init(buffer); + + err = writer.OpenContainer(AnonymousTag, kTLVType_Structure, innerWriter); + SuccessOrExit(err); + + // Adding the rotating device id to the TLV data + err = innerWriter.PutString(ContextTag(kRotatingDeviceIdTag), CHIP_ROTATING_DEVICE_ID); + SuccessOrExit(err); + + err = writer.CloseContainer(innerWriter); + SuccessOrExit(err); + + writer.Finalize(); + + cValue = g_variant_new_from_data(G_VARIANT_TYPE("ay"), buffer->Start(), buffer->DataLength(), TRUE, g_free, + g_memdup(buffer->Start(), buffer->DataLength())); + bluez_gatt_characteristic1_set_value(characteristic, cValue); + + return; + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data", __func__); + } + return; +} +#endif + static void BluezPeripheralObjectsSetup(gpointer apClosure) { static const char * const c1_flags[] = { "write", nullptr }; static const char * const c2_flags[] = { "read", "indicate", nullptr }; + static const char * const c3_flags[] = { "read", nullptr }; BluezEndpoint * endpoint = static_cast(apClosure); VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); @@ -1293,6 +1348,27 @@ static void BluezPeripheralObjectsSetup(gpointer apClosure) ChipLogDetail(DeviceLayer, "CHIP BTP C1 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC1)); ChipLogDetail(DeviceLayer, "CHIP BTP C2 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC2)); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ChipLogDetail(DeviceLayer, "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING is TRUE"); + // Additional data characteristics + endpoint->mpC3 = + BluezCharacteristicCreate(endpoint->mpService, g_strdup("c3"), g_strdup(CHIP_PLAT_BLE_UUID_C3_STRING), endpoint->mpRoot); + bluez_gatt_characteristic1_set_flags(endpoint->mpC3, c3_flags); + g_signal_connect(endpoint->mpC3, "handle-read-value", G_CALLBACK(BluezCharacteristicReadValue), apClosure); + g_signal_connect(endpoint->mpC3, "handle-write-value", G_CALLBACK(BluezCharacteristicWriteValueError), NULL); + g_signal_connect(endpoint->mpC3, "handle-acquire-write", G_CALLBACK(BluezCharacteristicAcquireWriteError), NULL); + g_signal_connect(endpoint->mpC3, "handle-acquire-notify", G_CALLBACK(BluezCharacteristicAcquireNotify), apClosure); + g_signal_connect(endpoint->mpC3, "handle-start-notify", G_CALLBACK(BluezCharacteristicStartNotify), apClosure); + g_signal_connect(endpoint->mpC3, "handle-stop-notify", G_CALLBACK(BluezCharacteristicStopNotify), apClosure); + g_signal_connect(endpoint->mpC3, "handle-confirm", G_CALLBACK(BluezCharacteristicConfirm), apClosure); + // update the characteristic value + UpdateAdditionalDataCharacteristic(endpoint->mpC3); + ChipLogDetail(DeviceLayer, "CHIP BTP C3 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC3)); +#else + ChipLogDetail(DeviceLayer, "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING is FALSE"); + (void) c3_flags; +#endif + exit: return; } diff --git a/src/platform/Linux/CHIPBluezHelper.h b/src/platform/Linux/CHIPBluezHelper.h index 03ab1b2d825e6e..16e024a0a3bc60 100644 --- a/src/platform/Linux/CHIPBluezHelper.h +++ b/src/platform/Linux/CHIPBluezHelper.h @@ -56,6 +56,7 @@ #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE #include "ble/CHIPBleServiceData.h" +#include "platform/CHIPDeviceConfig.h" #include "platform/Linux/dbus/bluez/DbusBluez.h" namespace chip { @@ -75,6 +76,7 @@ namespace Internal { #define CHIP_PLAT_BLE_UUID_C1_STRING "18ee2ef5-263d-4559-959f-4f9c429f9d11" #define CHIP_PLAT_BLE_UUID_C2_STRING "18ee2ef5-263d-4559-959f-4f9c429f9d12" +#define CHIP_PLAT_BLE_UUID_C3_STRING "64630238-8772-45F2-B87D-748A83218F04" #define CHIP_BLE_BASE_SERVICE_UUID_STRING "-0000-1000-8000-00805f9b34fb" #define CHIP_BLE_SERVICE_PREFIX_LENGTH 8 @@ -161,6 +163,8 @@ struct BluezEndpoint BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; // map device path to the connection GHashTable * mpConnMap; @@ -185,6 +189,9 @@ struct BluezConnection BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; + bool mIsNotify; uint16_t mMtu; struct IOChannel mC1Channel; diff --git a/src/setup_payload/AdditionalDataPayload.h b/src/setup_payload/AdditionalDataPayload.h new file mode 100644 index 00000000000000..80a2c5dec0a0e6 --- /dev/null +++ b/src/setup_payload/AdditionalDataPayload.h @@ -0,0 +1,52 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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. + */ + +/** + * @file + * This file describes a Additional Data Payload class to hold + * data enumerated from a byte stream. + * Additional data may be conveyed during the provisioning phase via multiple + * protocols (BLE, DNS-SD and SoftAP). It contains Rotating Device Id which + * is an optional feature for a Node to implement and an optional feature for + * a Commissioner to utilize. + * The Rotating Device Identifier provides a per-device unique non-trackable + * identifier that could be used in one or more of the following ways: + * 1) Provided to the vendor’s customer support for help in pairing or + * establishing Node provenance + * 2) Used programmatically to obtain a Node’s Setup PIN or other information + * in order to provide a simplified setup flow. Note that the mechanism(s) by + * which the PIN may be obtained is outside of this specification. + */ + +#pragma once + +#include + +namespace chip { +namespace SetupPayload { + +constexpr uint8_t kRotatingDeviceIdLength = 18; +constexpr uint8_t kRotatingDeviceIdTag = 0x00; + +struct AdditionalDataPayload +{ +public: + std::string rotatingDeviceId; +}; + +} // namespace SetupPayload +} // namespace chip diff --git a/src/setup_payload/AdditionalDataPayloadParser.cpp b/src/setup_payload/AdditionalDataPayloadParser.cpp new file mode 100644 index 00000000000000..ed600cb3f4fc64 --- /dev/null +++ b/src/setup_payload/AdditionalDataPayloadParser.cpp @@ -0,0 +1,72 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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. + */ + +/** + * @file + * This file describes a AdditionalData Payload parser based on the + * CHIP specification. + */ + +#include "AdditionalDataPayloadParser.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace std; +using namespace chip::SetupPayload; +using namespace chip::TLV; +using namespace chip::TLV::Utilities; +using namespace chip::Protocols; + +CHIP_ERROR AdditionalDataPayloadParser::populatePayload(AdditionalDataPayload & outPayload) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLVReader reader; + TLVReader innerReader; + + reader.Init(mPayloadBufferData, mPayloadBufferLength); + err = reader.Next(kTLVType_Structure, AnonymousTag); + SuccessOrExit(err); + + // Open the container + err = reader.OpenContainer(innerReader); + SuccessOrExit(err); + + err = innerReader.Next(kTLVType_UTF8String, ContextTag(kRotatingDeviceIdTag)); + SuccessOrExit(err); + + // Get the value of the rotating device id + char rotatingDeviceId[kRotatingDeviceIdLength]; + err = innerReader.GetString(rotatingDeviceId, sizeof(rotatingDeviceId)); + SuccessOrExit(err); + outPayload.rotatingDeviceId = std::string(rotatingDeviceId); + + // Verify the end of the container + err = reader.VerifyEndOfContainer(); + SuccessOrExit(err); + +exit: + return err; +} diff --git a/src/setup_payload/AdditionalDataPayloadParser.h b/src/setup_payload/AdditionalDataPayloadParser.h new file mode 100644 index 00000000000000..ef2c1fa9d47230 --- /dev/null +++ b/src/setup_payload/AdditionalDataPayloadParser.h @@ -0,0 +1,80 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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. + */ + +/** + * @file + * This file describes a AdditionalData Payload parser based on the + * CHIP specification. + */ + +#pragma once + +#include "AdditionalDataPayload.h" + +#include +#include + +namespace chip { + +/** + * @class AdditionalDataPayloadParser + * A class that can be used to convert a HEX encoded payload to a AdditionalDataPayload object + * */ +class AdditionalDataPayloadParser +{ +private: + const uint8_t * mPayloadBufferData; + const uint32_t mPayloadBufferLength; + +public: + /** + * Constructs the Additional Data payload parser with payload buffer data + * and the buffer size + * + * @param[in] payloadBufferData The buffer data for the additional data payload, + * it needs to outlive the lifetime of this parse. + * @param[in] payloadBufferLength The buffer data length for the additional data payload. + */ + AdditionalDataPayloadParser(const uint8_t * payloadBufferData, const uint32_t payloadBufferLength) : + mPayloadBufferData(payloadBufferData), mPayloadBufferLength(payloadBufferLength) + {} + + /** + * Parses the Additional Data payload buffer and constructs all the fields + * of the Additional Data structure. + * + * @param[out] outPayload Additional data payload stucture. + * + * + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV element + * type. + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval #CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG + * If the reader encountered a implicitly-encoded TLV tag for which + * the corresponding profile id is unknown. + * @retval other Other CHIP or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + */ + CHIP_ERROR populatePayload(SetupPayload::AdditionalDataPayload & outPayload); +}; + +} // namespace chip diff --git a/src/setup_payload/BUILD.gn b/src/setup_payload/BUILD.gn index 63c9bb1d828df6..d83933e42dc6fc 100644 --- a/src/setup_payload/BUILD.gn +++ b/src/setup_payload/BUILD.gn @@ -22,6 +22,9 @@ static_library("setup_payload") { output_name = "libSetupPayload" sources = [ + "AdditionalDataPayload.h", + "AdditionalDataPayloadParser.cpp", + "AdditionalDataPayloadParser.h", "Base41.cpp", "Base41.h", "ManualSetupPayloadGenerator.cpp",