From 2da216b1df673ea8e7c110e4347dbf49f7f0d81a Mon Sep 17 00:00:00 2001 From: John Hanna Date: Wed, 25 Nov 2020 17:29:41 -0800 Subject: [PATCH 01/42] RotatingId: version0 --- src/ble/BLEEndPoint.cpp | 7 +++++++ src/ble/BleLayer.cpp | 12 ++++++++---- src/ble/BleLayer.h | 2 ++ src/platform/Linux/CHIPBluezHelper.cpp | 19 +++++++++++++++++++ src/platform/Linux/CHIPBluezHelper.h | 6 ++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index a72485f1d3a66c..55852935aa528a 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -410,6 +410,13 @@ void BLEEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, BLE_ERROR err) // If unsubscribe fails, release BLE connection and free end point immediately. Free(); } + if (!mBle->mPlatformDelegate->UnsubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_3_ID)) + { + ChipLogError(Ble, "BtpEngine unsub failed"); + + // If unsubscribe fails, release BLE connection and free end point immediately. + Free(); + } else if (mConnObj != BLE_CONNECTION_UNINITIALIZED) { // Unsubscribe request was sent successfully, and a confirmation wasn't spontaneously generated or diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index f25a0a29061bd0..673a10be793d6f 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 = { { // 18EE2EF5-263D-4559-959F-4F9C429F9D13 + 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, + 0x9F, 0x9D, 0x13 } }; + void BleLayerObject::Release() { // Decrement the ref count. When it reaches zero, NULL out the pointer to the chip::System::Layer @@ -598,7 +602,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); @@ -623,7 +627,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); @@ -647,7 +651,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); @@ -672,7 +676,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 b1ddd0af11abe0..123fd2fc2f0da0 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -336,6 +336,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 charadteristic used for additional data + static const ChipBleUUID CHIP_BLE_CHAR_3_ID; BleConnectionDelegate * mConnectionDelegate; BlePlatformDelegate * mPlatformDelegate; diff --git a/src/platform/Linux/CHIPBluezHelper.cpp b/src/platform/Linux/CHIPBluezHelper.cpp index dca1995851f4b8..2c9896b016a74a 100644 --- a/src/platform/Linux/CHIPBluezHelper.cpp +++ b/src/platform/Linux/CHIPBluezHelper.cpp @@ -695,6 +695,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); @@ -1261,6 +1266,7 @@ 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__)); @@ -1290,8 +1296,21 @@ static void BluezPeripheralObjectsSetup(gpointer apClosure) g_signal_connect(endpoint->mpC2, "handle-stop-notify", G_CALLBACK(BluezCharacteristicStopNotify), apClosure); g_signal_connect(endpoint->mpC2, "handle-confirm", G_CALLBACK(BluezCharacteristicConfirm), apClosure); + // 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); + 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)); + ChipLogDetail(DeviceLayer, "CHIP BTP C3 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC3)); exit: return; diff --git a/src/platform/Linux/CHIPBluezHelper.h b/src/platform/Linux/CHIPBluezHelper.h index 090853997ca5d8..c60b9993e390a3 100644 --- a/src/platform/Linux/CHIPBluezHelper.h +++ b/src/platform/Linux/CHIPBluezHelper.h @@ -75,6 +75,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 "18ee2ef5-263d-4559-959f-4f9c429f9d13" #define CHIP_BLE_BASE_SERVICE_UUID_STRING "-0000-1000-8000-00805f9b34fb" #define CHIP_BLE_SERVICE_PREFIX_LENGTH 8 @@ -161,6 +162,8 @@ struct BluezEndpoint BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; // map device path to the connection GHashTable * mpConnMap; @@ -185,6 +188,9 @@ struct BluezConnection BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; + bool mIsNotify; uint16_t mMtu; struct IOChannel mC1Channel; From d7be05e99602de0c6f21fcff9dd1603d08a06a6e Mon Sep 17 00:00:00 2001 From: John Hanna Date: Wed, 2 Dec 2020 15:51:45 -0800 Subject: [PATCH 02/42] RotatingId: version1 --- src/platform/Linux/CHIPBluezHelper.cpp | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/platform/Linux/CHIPBluezHelper.cpp b/src/platform/Linux/CHIPBluezHelper.cpp index 2c9896b016a74a..d3cd1c0240c01b 100644 --- a/src/platform/Linux/CHIPBluezHelper.cpp +++ b/src/platform/Linux/CHIPBluezHelper.cpp @@ -1261,6 +1261,44 @@ void BluezObjectsCleanup(BluezEndpoint * apEndpoint) EndpointCleanup(apEndpoint); } +static void UpdateAdditionalDataCharacteristic(BluezGattCharacteristic1 * characteristic) +{ + // Construct the TLV for the additional data + GVariant * cValue = nullptr; + unsigned long err = 0; + TLVWriter writer; + chip::System::PacketBufferHandle bufferHandle = chip::System::PacketBuffer::New(); + chip::System::PacketBuffer * buffer = bufferHandle.Get_ForNow(); + char testRotatingDeviceId[] = "1122334455667788"; + + writer.Init(buffer); + TLVType containerType; + err = writer.StartContainer(AnonymousTag, kTLVType_Structure, containerType); + SuccessOrExit(err); + + // Adding the rotating device id to the TLV data + err = writer.PutString(CommonTag(0), testRotatingDeviceId); + SuccessOrExit(err); + + err = writer.EndContainer(containerType); + SuccessOrExit(err); + + writer.Finalize(); + + cValue = g_variant_new_from_data(G_VARIANT_TYPE("ay"), buffer->Start(), buffer->DataLength(), TRUE, NULL, NULL); + bluez_gatt_characteristic1_set_value(characteristic, cValue); + + ChipLogDetail(DeviceLayer, "Set Characteristics value to %s", g_variant_get_string(cValue, NULL)); + return; + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data", __func__); + } + return; +} + static void BluezPeripheralObjectsSetup(gpointer apClosure) { @@ -1307,6 +1345,8 @@ static void BluezPeripheralObjectsSetup(gpointer 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 C1 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC1)); ChipLogDetail(DeviceLayer, "CHIP BTP C2 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC2)); From ceffd58ce9fea30ff7b21f8e77e4cf6dfe525889 Mon Sep 17 00:00:00 2001 From: John Hanna Date: Wed, 25 Nov 2020 17:29:41 -0800 Subject: [PATCH 03/42] RotatingId: version0 --- src/ble/BLEEndPoint.cpp | 7 +++++++ src/ble/BleLayer.cpp | 12 ++++++++---- src/ble/BleLayer.h | 2 ++ src/platform/Linux/CHIPBluezHelper.cpp | 19 +++++++++++++++++++ src/platform/Linux/CHIPBluezHelper.h | 6 ++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index a72485f1d3a66c..55852935aa528a 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -410,6 +410,13 @@ void BLEEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, BLE_ERROR err) // If unsubscribe fails, release BLE connection and free end point immediately. Free(); } + if (!mBle->mPlatformDelegate->UnsubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_3_ID)) + { + ChipLogError(Ble, "BtpEngine unsub failed"); + + // If unsubscribe fails, release BLE connection and free end point immediately. + Free(); + } else if (mConnObj != BLE_CONNECTION_UNINITIALIZED) { // Unsubscribe request was sent successfully, and a confirmation wasn't spontaneously generated or diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index f25a0a29061bd0..673a10be793d6f 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 = { { // 18EE2EF5-263D-4559-959F-4F9C429F9D13 + 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, + 0x9F, 0x9D, 0x13 } }; + void BleLayerObject::Release() { // Decrement the ref count. When it reaches zero, NULL out the pointer to the chip::System::Layer @@ -598,7 +602,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); @@ -623,7 +627,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); @@ -647,7 +651,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); @@ -672,7 +676,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 b1ddd0af11abe0..123fd2fc2f0da0 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -336,6 +336,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 charadteristic used for additional data + static const ChipBleUUID CHIP_BLE_CHAR_3_ID; BleConnectionDelegate * mConnectionDelegate; BlePlatformDelegate * mPlatformDelegate; diff --git a/src/platform/Linux/CHIPBluezHelper.cpp b/src/platform/Linux/CHIPBluezHelper.cpp index dca1995851f4b8..2c9896b016a74a 100644 --- a/src/platform/Linux/CHIPBluezHelper.cpp +++ b/src/platform/Linux/CHIPBluezHelper.cpp @@ -695,6 +695,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); @@ -1261,6 +1266,7 @@ 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__)); @@ -1290,8 +1296,21 @@ static void BluezPeripheralObjectsSetup(gpointer apClosure) g_signal_connect(endpoint->mpC2, "handle-stop-notify", G_CALLBACK(BluezCharacteristicStopNotify), apClosure); g_signal_connect(endpoint->mpC2, "handle-confirm", G_CALLBACK(BluezCharacteristicConfirm), apClosure); + // 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); + 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)); + ChipLogDetail(DeviceLayer, "CHIP BTP C3 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC3)); exit: return; diff --git a/src/platform/Linux/CHIPBluezHelper.h b/src/platform/Linux/CHIPBluezHelper.h index 090853997ca5d8..c60b9993e390a3 100644 --- a/src/platform/Linux/CHIPBluezHelper.h +++ b/src/platform/Linux/CHIPBluezHelper.h @@ -75,6 +75,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 "18ee2ef5-263d-4559-959f-4f9c429f9d13" #define CHIP_BLE_BASE_SERVICE_UUID_STRING "-0000-1000-8000-00805f9b34fb" #define CHIP_BLE_SERVICE_PREFIX_LENGTH 8 @@ -161,6 +162,8 @@ struct BluezEndpoint BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; // map device path to the connection GHashTable * mpConnMap; @@ -185,6 +188,9 @@ struct BluezConnection BluezGattService1 * mpService; BluezGattCharacteristic1 * mpC1; BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; + bool mIsNotify; uint16_t mMtu; struct IOChannel mC1Channel; From 4b6f8e1a34aa29e24cb07710f0bd67f4bcb99762 Mon Sep 17 00:00:00 2001 From: John Hanna Date: Wed, 2 Dec 2020 15:51:45 -0800 Subject: [PATCH 04/42] RotatingId: version1 --- src/platform/Linux/CHIPBluezHelper.cpp | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/platform/Linux/CHIPBluezHelper.cpp b/src/platform/Linux/CHIPBluezHelper.cpp index 2c9896b016a74a..d3cd1c0240c01b 100644 --- a/src/platform/Linux/CHIPBluezHelper.cpp +++ b/src/platform/Linux/CHIPBluezHelper.cpp @@ -1261,6 +1261,44 @@ void BluezObjectsCleanup(BluezEndpoint * apEndpoint) EndpointCleanup(apEndpoint); } +static void UpdateAdditionalDataCharacteristic(BluezGattCharacteristic1 * characteristic) +{ + // Construct the TLV for the additional data + GVariant * cValue = nullptr; + unsigned long err = 0; + TLVWriter writer; + chip::System::PacketBufferHandle bufferHandle = chip::System::PacketBuffer::New(); + chip::System::PacketBuffer * buffer = bufferHandle.Get_ForNow(); + char testRotatingDeviceId[] = "1122334455667788"; + + writer.Init(buffer); + TLVType containerType; + err = writer.StartContainer(AnonymousTag, kTLVType_Structure, containerType); + SuccessOrExit(err); + + // Adding the rotating device id to the TLV data + err = writer.PutString(CommonTag(0), testRotatingDeviceId); + SuccessOrExit(err); + + err = writer.EndContainer(containerType); + SuccessOrExit(err); + + writer.Finalize(); + + cValue = g_variant_new_from_data(G_VARIANT_TYPE("ay"), buffer->Start(), buffer->DataLength(), TRUE, NULL, NULL); + bluez_gatt_characteristic1_set_value(characteristic, cValue); + + ChipLogDetail(DeviceLayer, "Set Characteristics value to %s", g_variant_get_string(cValue, NULL)); + return; + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data", __func__); + } + return; +} + static void BluezPeripheralObjectsSetup(gpointer apClosure) { @@ -1307,6 +1345,8 @@ static void BluezPeripheralObjectsSetup(gpointer 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 C1 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC1)); ChipLogDetail(DeviceLayer, "CHIP BTP C2 %s", bluez_gatt_characteristic1_get_service(endpoint->mpC2)); From c3ea235b62d248b35136509e960134ad31b7fa78 Mon Sep 17 00:00:00 2001 From: Kevin Schoedel <67607049+kpschoedel@users.noreply.github.com> Date: Wed, 25 Nov 2020 17:09:23 -0500 Subject: [PATCH 05/42] Fix Darwin host build (#3990) #### Problem Some conversions to use PacketBufferHandle (#3909) broke Darwin builds, which aren't currently run in CI. #### Summary of Changes Fix src/platform/Darwin/BleConnectionDelegateImpl.mm to match the API change in #3909. --- src/platform/Darwin/BleConnectionDelegateImpl.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/Darwin/BleConnectionDelegateImpl.mm b/src/platform/Darwin/BleConnectionDelegateImpl.mm index 7f40a54a1be4e1..9fdd6fb8f44c11 100644 --- a/src/platform/Darwin/BleConnectionDelegateImpl.mm +++ b/src/platform/Darwin/BleConnectionDelegateImpl.mm @@ -269,7 +269,7 @@ - (void)peripheral:(CBPeripheral *)peripheral std::is_sameMaxDataLength()), uint16_t>::value, "Unexpected type for max data length"); msgBuf->SetDataLength(static_cast(characteristic.value.length)); - if (!_mBleLayer->HandleIndicationReceived((__bridge void *) peripheral, &svcId, &charId, msgBuf.Release_ForNow())) { + if (!_mBleLayer->HandleIndicationReceived((__bridge void *) peripheral, &svcId, &charId, std::move(msgBuf))) { // since this error comes from device manager core // we assume it would do the right thing, like closing the connection ChipLogError(Ble, "Failed at handling incoming BLE data"); From 9ca3ff104ca0944ea652276399c6d8e5425d64ab Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Thu, 26 Nov 2020 22:18:29 +0100 Subject: [PATCH 06/42] Add '-Wextra' to compiler flags (#3902) --- build/config/compiler/BUILD.gn | 2 ++ examples/common/QRCode/BUILD.gn | 29 +++++++++++++++++++++ examples/lighting-app/efr32/BUILD.gn | 3 +-- examples/lock-app/efr32/BUILD.gn | 3 +-- src/lib/core/CHIPKeyIds.cpp | 2 +- src/lib/support/logging/CHIPLoggingLogV.cpp | 2 +- src/platform/EFR32/freertos_bluetooth.c | 6 ++--- third_party/mbedtls/mbedtls.gni | 5 +++- 8 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 examples/common/QRCode/BUILD.gn diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index b2482243214611..66c26a49bbe987 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -138,6 +138,7 @@ config("disabled_warnings") { "-Wno-deprecated-declarations", "-Wno-unknown-warning-option", "-Wno-missing-field-initializers", + "-Wno-unused-parameter", ] if (!is_debug) { # assert() causes unused variable warnings in release. @@ -154,6 +155,7 @@ config("disabled_warnings") { config("strict_warnings") { cflags = [ "-Wall", + "-Wextra", "-Wshadow", ] diff --git a/examples/common/QRCode/BUILD.gn b/examples/common/QRCode/BUILD.gn new file mode 100644 index 00000000000000..f954876835f0bb --- /dev/null +++ b/examples/common/QRCode/BUILD.gn @@ -0,0 +1,29 @@ +# 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. + +config("qrcode-common_config") { + include_dirs = [ "repo/c" ] + + cflags = [ "-Wno-type-limits" ] +} + +static_library("QRCode") { + output_name = "libqrcode-common" + + output_dir = "${root_out_dir}/lib" + + sources = [ "repo/c/qrcodegen.c" ] + + public_configs = [ ":qrcode-common_config" ] +} diff --git a/examples/lighting-app/efr32/BUILD.gn b/examples/lighting-app/efr32/BUILD.gn index 3b96a0835a2e9c..afc819bc2480f2 100644 --- a/examples/lighting-app/efr32/BUILD.gn +++ b/examples/lighting-app/efr32/BUILD.gn @@ -67,6 +67,7 @@ efr32_executable("lighting_app") { public_deps = [ ":sdk", + "${chip_root}/examples/common/QRCode", "${chip_root}/examples/common/chip-app-server:chip-app-server", "${chip_root}/examples/lighting-app/lighting-common", "${chip_root}/src/lib", @@ -81,11 +82,9 @@ efr32_executable("lighting_app") { "${efr32_project_dir}/include", "${chip_root}/src/app/util", "${examples_plat_dir}", - "${chip_root}/examples/common/QRCode/repo/c", ] sources = [ - "${chip_root}/examples/common/QRCode/repo/c/qrcodegen.c", "${examples_plat_dir}/${efr32_family}/${efr32_board}/hal-config.h", "${examples_plat_dir}/${efr32_family}/${efr32_board}/init_board.c", "${examples_plat_dir}/${efr32_family}/${efr32_board}/init_mcu.c", diff --git a/examples/lock-app/efr32/BUILD.gn b/examples/lock-app/efr32/BUILD.gn index 8097362db5b1d0..89d8b087e20395 100644 --- a/examples/lock-app/efr32/BUILD.gn +++ b/examples/lock-app/efr32/BUILD.gn @@ -67,6 +67,7 @@ efr32_executable("lock_app") { public_deps = [ ":sdk", + "${chip_root}/examples/common/QRCode", "${chip_root}/examples/common/chip-app-server:chip-app-server", "${chip_root}/examples/lock-app/lock-common", "${chip_root}/src/lib", @@ -81,11 +82,9 @@ efr32_executable("lock_app") { "${efr32_project_dir}/include", "${chip_root}/src/app/util", "${examples_plat_dir}", - "${chip_root}/examples/common/QRCode/repo/c", ] sources = [ - "${chip_root}/examples/common/QRCode/repo/c/qrcodegen.c", "${examples_plat_dir}/${efr32_family}/${efr32_board}/hal-config.h", "${examples_plat_dir}/${efr32_family}/${efr32_board}/init_board.c", "${examples_plat_dir}/${efr32_family}/${efr32_board}/init_mcu.c", diff --git a/src/lib/core/CHIPKeyIds.cpp b/src/lib/core/CHIPKeyIds.cpp index 6c2f02f5f411b9..fb5ca5879b7116 100644 --- a/src/lib/core/CHIPKeyIds.cpp +++ b/src/lib/core/CHIPKeyIds.cpp @@ -97,7 +97,7 @@ uint32_t ChipKeyId::MakeAppKeyId(uint32_t keyType, uint32_t rootKeyId, uint32_t bool useCurrentEpochKey) { return (keyType | (rootKeyId & kMask_RootKeyNumber) | (appGroupMasterKeyId & kMask_GroupLocalNumber) | - (useCurrentEpochKey ? kFlag_UseCurrentEpochKey : (epochKeyId & kMask_EpochKeyNumber))); + (useCurrentEpochKey ? static_cast(kFlag_UseCurrentEpochKey) : (epochKeyId & kMask_EpochKeyNumber))); } /** diff --git a/src/lib/support/logging/CHIPLoggingLogV.cpp b/src/lib/support/logging/CHIPLoggingLogV.cpp index 5178d398e26881..32895ff5bc04cc 100644 --- a/src/lib/support/logging/CHIPLoggingLogV.cpp +++ b/src/lib/support/logging/CHIPLoggingLogV.cpp @@ -123,7 +123,7 @@ DLL_EXPORT __CHIP_LOGGING_LINK_ATTRIBUTE void LogV(uint8_t module, uint8_t categ return; } - if (prefixLen >= sizeof(formattedMsg)) + if (static_cast(prefixLen) >= sizeof(formattedMsg)) { prefixLen = sizeof(formattedMsg) - 1; } diff --git a/src/platform/EFR32/freertos_bluetooth.c b/src/platform/EFR32/freertos_bluetooth.c index c76679db7d2806..d23e16b55694ee 100644 --- a/src/platform/EFR32/freertos_bluetooth.c +++ b/src/platform/EFR32/freertos_bluetooth.c @@ -34,9 +34,9 @@ void BluetoothUpdate(); volatile struct gecko_cmd_packet * bluetooth_evt; SemaphoreHandle_t BluetoothMutex = NULL; -volatile static uint32_t command_header; -volatile static void * command_data; -volatile static gecko_cmd_handler command_handler_func = NULL; +static volatile uint32_t command_header; +static volatile void * command_data; +static volatile gecko_cmd_handler command_handler_func = NULL; // Bluetooth task #ifndef BLUETOOTH_STACK_SIZE diff --git a/third_party/mbedtls/mbedtls.gni b/third_party/mbedtls/mbedtls.gni index 85dd8372c6afc5..d56d81a88a7c3a 100644 --- a/third_party/mbedtls/mbedtls.gni +++ b/third_party/mbedtls/mbedtls.gni @@ -20,7 +20,10 @@ template("mbedtls_target") { _mbedtls_root = "${mbedtls_root}/repo" config("${mbedtls_target_name}_warnings") { - cflags = [ "-Wno-maybe-uninitialized" ] + cflags = [ + "-Wno-maybe-uninitialized", + "-Wno-string-concatenation", + ] } config("${mbedtls_target_name}_config") { From 2f053dfff5f836c5d8bd248ad83824f31089afef Mon Sep 17 00:00:00 2001 From: Markus Becker Date: Fri, 27 Nov 2020 07:05:26 +0100 Subject: [PATCH 07/42] Implement Level Control Cluster (#3806) * New seekbar in Android CHIPTool * Sample usage in lighting-app/nrfconnect Signed-off-by: Markus Becker --- .../lighting-app/lighting-common/BUILD.gn | 1 + .../lighting-common/gen/af-gen-event.h | 72 ++++++ .../gen/call-command-handler.cpp | 238 ++++++++++++++++++ .../gen/call-command-handler.h | 3 + .../lighting-common/gen/endpoint_config.h | 27 +- .../lighting-common/gen/gen_config.h | 24 +- .../lighting-app/nrfconnect/CMakeLists.txt | 4 +- .../lighting-app/nrfconnect/main/AppTask.cpp | 10 +- .../nrfconnect/main/LightingManager.cpp | 29 ++- .../nrfconnect/main/ZclCallbacks.cpp | 37 ++- .../nrfconnect/main/include/LightingManager.h | 4 +- .../clusterclient/OnOffClientFragment.kt | 29 ++- .../res/layout/on_off_client_fragment.xml | 14 +- .../res/layout/select_action_fragment.xml | 2 +- .../app/src/main/res/values/strings.xml | 4 +- .../clusters/level-control/level-control.cpp | 2 + .../java/CHIPDeviceController-JNI.cpp | 6 +- .../devicecontroller/ChipCommandType.java | 3 +- .../ChipDeviceController.java | 7 +- 19 files changed, 485 insertions(+), 31 deletions(-) diff --git a/examples/lighting-app/lighting-common/BUILD.gn b/examples/lighting-app/lighting-common/BUILD.gn index 67fdf31361aed3..3678a2e4381f93 100644 --- a/examples/lighting-app/lighting-common/BUILD.gn +++ b/examples/lighting-app/lighting-common/BUILD.gn @@ -24,6 +24,7 @@ config("includes") { source_set("lighting-common") { sources = [ "${chip_root}/examples/common/chip-app-server/DataModelHandler.cpp", + "${chip_root}/src/app/clusters/level-control/level-control.cpp", "${chip_root}/src/app/clusters/on-off-server/on-off.cpp", "${chip_root}/src/app/reporting/reporting-default-configuration.cpp", "${chip_root}/src/app/reporting/reporting.cpp", diff --git a/examples/lighting-app/lighting-common/gen/af-gen-event.h b/examples/lighting-app/lighting-common/gen/af-gen-event.h index e69de29bb2d1d6..2d3bbadcfbce8c 100644 --- a/examples/lighting-app/lighting-common/gen/af-gen-event.h +++ b/examples/lighting-app/lighting-common/gen/af-gen-event.h @@ -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. + */ + +/** + * + * Copyright (c) 2020 Silicon Labs + * + * 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. + */ +// This file is generated by Simplicity Studio. Please do not edit manually. +// +// + +// Enclosing macro to prevent multiple inclusion +#ifndef __AF_GEN_EVENT__ +#define __AF_GEN_EVENT__ + +// Code used to configure the cluster event mechanism +#define EMBER_AF_GENERATED_EVENT_CODE \ + EmberEventControl emberAfLevelControlClusterServerTickCallbackControl1; \ + static void clusterTickWrapper(EmberEventControl * control, EmberAfTickFunction callback, uint8_t endpoint) \ + { \ + /* emberAfPushEndpointNetworkIndex(endpoint); */ \ + emberEventControlSetInactive(control); \ + (*callback)(endpoint); \ + /* emberAfPopNetworkIndex(); */ \ + } \ + \ + void emberAfLevelControlClusterServerTickCallbackWrapperFunction1(void) \ + { \ + clusterTickWrapper(&emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallback, \ + 1); \ + } + +// EmberEventData structs used to populate the EmberEventData table +#define EMBER_AF_GENERATED_EVENTS \ + { &emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallbackWrapperFunction1 }, + +#define EMBER_AF_GENERATED_EVENT_STRINGS "Level Control Cluster Server EP 1", + +// The length of the event context table used to track and retrieve cluster events +#define EMBER_AF_EVENT_CONTEXT_LENGTH 4 + +// EmberAfEventContext structs used to populate the EmberAfEventContext table +#define EMBER_AF_GENERATED_EVENT_CONTEXT \ + { 0x1, 0x8, false, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP, &emberAfLevelControlClusterServerTickCallbackControl1 }, + +#endif // __AF_GEN_EVENT__ diff --git a/examples/lighting-app/lighting-common/gen/call-command-handler.cpp b/examples/lighting-app/lighting-common/gen/call-command-handler.cpp index 21f6503ed6ecfb..60dd259ac4f510 100644 --- a/examples/lighting-app/lighting-common/gen/call-command-handler.cpp +++ b/examples/lighting-app/lighting-common/gen/call-command-handler.cpp @@ -104,6 +104,9 @@ EmberAfStatus emberAfClusterSpecificCommandParse(EmberAfClusterCommand * cmd) case ZCL_ON_OFF_CLUSTER_ID: result = emberAfOnOffClusterServerCommandParse(cmd); break; + case ZCL_LEVEL_CONTROL_CLUSTER_ID: + result = emberAfLevelControlClusterServerCommandParse(cmd); + break; default: // Unrecognized cluster ID, error status will apply. break; @@ -143,3 +146,238 @@ EmberAfStatus emberAfOnOffClusterServerCommandParse(EmberAfClusterCommand * cmd) } return status(wasHandled, true, cmd->mfgSpecific); } + +// Cluster: Level Control, server +EmberAfStatus emberAfLevelControlClusterServerCommandParse(EmberAfClusterCommand * cmd) +{ + bool wasHandled = false; + if (!cmd->mfgSpecific) + { + switch (cmd->commandId) + { + case ZCL_MOVE_TO_LEVEL_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t level; // Ver.: always + uint16_t transitionTime; // Ver.: always + uint8_t optionMask; // Ver.: since zcl6-errata-14-0129-15 + uint8_t optionOverride; // Ver.: since zcl6-errata-14-0129-15 + // Command is not a fixed length + if (cmd->bufLen < payloadOffset + 1u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + level = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + if (cmd->bufLen < payloadOffset + 2u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + transitionTime = emberAfGetInt16u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 2u; + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionMask = 0xFF; + } + else + { + optionMask = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + } + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionOverride = 0xFF; + } + else + { + optionOverride = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + } + wasHandled = emberAfLevelControlClusterMoveToLevelCallback(level, transitionTime, optionMask, optionOverride); + break; + } + case ZCL_MOVE_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t moveMode; // Ver.: always + uint8_t rate; // Ver.: always + uint8_t optionMask; // Ver.: since zcl6-errata-14-0129-15 + uint8_t optionOverride; // Ver.: since zcl6-errata-14-0129-15 + // Command is not a fixed length + if (cmd->bufLen < payloadOffset + 1u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + moveMode = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + if (cmd->bufLen < payloadOffset + 1u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + rate = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionMask = 0xFF; + } + else + { + optionMask = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + } + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionOverride = 0xFF; + } + else + { + optionOverride = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + } + wasHandled = emberAfLevelControlClusterMoveCallback(moveMode, rate, optionMask, optionOverride); + break; + } + case ZCL_STEP_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t stepMode; // Ver.: always + uint8_t stepSize; // Ver.: always + uint16_t transitionTime; // Ver.: always + uint8_t optionMask; // Ver.: since zcl6-errata-14-0129-15 + uint8_t optionOverride; // Ver.: since zcl6-errata-14-0129-15 + // Command is not a fixed length + if (cmd->bufLen < payloadOffset + 1u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + stepMode = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + if (cmd->bufLen < payloadOffset + 1u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + stepSize = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + if (cmd->bufLen < payloadOffset + 2u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + transitionTime = emberAfGetInt16u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 2u; + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionMask = 0xFF; + } + else + { + optionMask = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + } + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionOverride = 0xFF; + } + else + { + optionOverride = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + } + wasHandled = emberAfLevelControlClusterStepCallback(stepMode, stepSize, transitionTime, optionMask, optionOverride); + break; + } + case ZCL_STOP_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t optionMask; // Ver.: since zcl6-errata-14-0129-15 + uint8_t optionOverride; // Ver.: since zcl6-errata-14-0129-15 + // Command is not a fixed length + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionMask = 0xFF; + } + else + { + optionMask = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + } + if ((cmd->bufLen < payloadOffset + 1u)) + { + // Argument is not always present: + // - it is present only in versions higher than: zcl6-errata-14-0129-15 + optionOverride = 0xFF; + } + else + { + optionOverride = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + } + wasHandled = emberAfLevelControlClusterStopCallback(optionMask, optionOverride); + break; + } + case ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t level; // Ver.: always + uint16_t transitionTime; // Ver.: always + // Command is fixed length: 3 + if (cmd->bufLen < payloadOffset + 3u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + level = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + transitionTime = emberAfGetInt16u(cmd->buffer, payloadOffset, cmd->bufLen); + wasHandled = emberAfLevelControlClusterMoveToLevelWithOnOffCallback(level, transitionTime); + break; + } + case ZCL_MOVE_WITH_ON_OFF_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t moveMode; // Ver.: always + uint8_t rate; // Ver.: always + // Command is fixed length: 2 + if (cmd->bufLen < payloadOffset + 2u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + moveMode = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + rate = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + wasHandled = emberAfLevelControlClusterMoveWithOnOffCallback(moveMode, rate); + break; + } + case ZCL_STEP_WITH_ON_OFF_COMMAND_ID: { + uint16_t payloadOffset = cmd->payloadStartIndex; + uint8_t stepMode; // Ver.: always + uint8_t stepSize; // Ver.: always + uint16_t transitionTime; // Ver.: always + // Command is fixed length: 4 + if (cmd->bufLen < payloadOffset + 4u) + { + return EMBER_ZCL_STATUS_MALFORMED_COMMAND; + } + stepMode = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + stepSize = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen); + payloadOffset += 1u; + transitionTime = emberAfGetInt16u(cmd->buffer, payloadOffset, cmd->bufLen); + wasHandled = emberAfLevelControlClusterStepWithOnOffCallback(stepMode, stepSize, transitionTime); + break; + } + case ZCL_STOP_WITH_ON_OFF_COMMAND_ID: { + // Command is fixed length: 0 + wasHandled = emberAfLevelControlClusterStopWithOnOffCallback(); + break; + } + default: { + // Unrecognized command ID, error status will apply. + break; + } + } + } + return status(wasHandled, true, cmd->mfgSpecific); +} diff --git a/examples/lighting-app/lighting-common/gen/call-command-handler.h b/examples/lighting-app/lighting-common/gen/call-command-handler.h index 56c84133c3f612..94460a9a29918c 100644 --- a/examples/lighting-app/lighting-common/gen/call-command-handler.h +++ b/examples/lighting-app/lighting-common/gen/call-command-handler.h @@ -47,4 +47,7 @@ // Cluster: On/off, server EmberAfStatus emberAfOnOffClusterServerCommandParse(EmberAfClusterCommand * cmd); +// Cluster: Level Control, server +EmberAfStatus emberAfLevelControlClusterServerCommandParse(EmberAfClusterCommand * cmd); + #endif // SILABS_EMBER_AF_COMMAND_PARSE_HEADER diff --git a/examples/lighting-app/lighting-common/gen/endpoint_config.h b/examples/lighting-app/lighting-common/gen/endpoint_config.h index fafd2e3a13e318..e13dfcab99d0b5 100644 --- a/examples/lighting-app/lighting-common/gen/endpoint_config.h +++ b/examples/lighting-app/lighting-common/gen/endpoint_config.h @@ -47,12 +47,16 @@ { \ { 0x0000, ZCL_BOOLEAN_ATTRIBUTE_TYPE, 1, (0x00), { (uint8_t *) 0x00 } }, /* 0 / On/off / on/off*/ \ { 0xFFFD, ZCL_INT16U_ATTRIBUTE_TYPE, 2, (0x00), { (uint8_t *) 0x0001 } }, /* 1 / On/off / cluster revision*/ \ + { 0x0000, ZCL_INT8U_ATTRIBUTE_TYPE, 1, (0x00), { (uint8_t *) 0x00 } }, /* 2 / Level Control / current level*/ \ + { 0xFFFD, ZCL_INT16U_ATTRIBUTE_TYPE, 2, (0x00), { (uint8_t *) 0x0001 } }, /* 3 / Level Control / cluster revision*/ \ } // Cluster function static arrays #define GENERATED_FUNCTION_ARRAYS \ - const EmberAfGenericClusterFunction emberAfFuncArrayOnOffClusterServer[] = { ( \ - EmberAfGenericClusterFunction) emberAfOnOffClusterServerInitCallback }; + const EmberAfGenericClusterFunction emberAfFuncArrayOnOffClusterServer[] = { ( \ + EmberAfGenericClusterFunction) emberAfOnOffClusterServerInitCallback }; \ + const EmberAfGenericClusterFunction emberAfFuncArrayLevelControlClusterServer[] = { ( \ + EmberAfGenericClusterFunction) emberAfLevelControlClusterServerInitCallback }; // Clusters definitions #define GENERATED_CLUSTERS \ @@ -61,12 +65,16 @@ 0x0006, (EmberAfAttributeMetadata *) &(generatedAttributes[0]), 2, \ 3, (CLUSTER_MASK_SERVER | CLUSTER_MASK_INIT_FUNCTION), emberAfFuncArrayOnOffClusterServer, \ }, \ + { \ + 0x0008, (EmberAfAttributeMetadata *) &(generatedAttributes[2]), 2, \ + 3, (CLUSTER_MASK_SERVER | CLUSTER_MASK_INIT_FUNCTION), emberAfFuncArrayLevelControlClusterServer, \ + }, \ } // Endpoint types #define GENERATED_ENDPOINT_TYPES \ { \ - { (EmberAfCluster *) &(generatedClusters[0]), 1, 3 }, \ + { (EmberAfCluster *) &(generatedClusters[0]), 2, 4 }, \ } // Cluster manufacturer codes @@ -142,8 +150,16 @@ { 0x0006, 0x00, COMMAND_MASK_INCOMING_SERVER }, /* On/off / Off */ \ { 0x0006, 0x01, COMMAND_MASK_INCOMING_SERVER }, /* On/off / On */ \ { 0x0006, 0x02, COMMAND_MASK_INCOMING_SERVER }, /* On/off / Toggle */ \ + { 0x0008, 0x00, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / MoveToLevel */ \ + { 0x0008, 0x01, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / Move */ \ + { 0x0008, 0x02, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / Step */ \ + { 0x0008, 0x03, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / Stop */ \ + { 0x0008, 0x04, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / MoveToLevelWithOnOff */ \ + { 0x0008, 0x05, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / MoveWithOnOff */ \ + { 0x0008, 0x06, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / StepWithOnOff */ \ + { 0x0008, 0x07, COMMAND_MASK_INCOMING_SERVER }, /* Level Control / StopWithOnOff */ \ } -#define EMBER_AF_GENERATED_COMMAND_COUNT (3) +#define EMBER_AF_GENERATED_COMMAND_COUNT (11) // Command manufacturer codes #define GENERATED_COMMAND_MANUFACTURER_CODES \ @@ -158,6 +174,7 @@ #define EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS \ { \ { EMBER_ZCL_REPORTING_DIRECTION_REPORTED, 1, 0x0006, 0x0000, CLUSTER_MASK_SERVER, 0x0000, { { 1, 65534, 0 } } }, \ + { EMBER_ZCL_REPORTING_DIRECTION_REPORTED, 1, 0x0008, 0x0000, CLUSTER_MASK_SERVER, 0x0000, { { 1, 65534, 0 } } }, \ } -#define EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE (1) +#define EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE (2) #endif // SILABS_AF_ENDPOINT_CONFIG diff --git a/examples/lighting-app/lighting-common/gen/gen_config.h b/examples/lighting-app/lighting-common/gen/gen_config.h index f7efba427e27c3..1820036777482a 100644 --- a/examples/lighting-app/lighting-common/gen/gen_config.h +++ b/examples/lighting-app/lighting-common/gen/gen_config.h @@ -59,16 +59,18 @@ #define EM_AF_GENERATED_NETWORK_STRINGS "Primary (pro)", /**** ZCL Section ****/ #define ZA_PROMPT "ZigbeeMinimalSoc" #define ZCL_USING_ON_OFF_CLUSTER_SERVER +#define ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER #define EMBER_AF_MANUFACTURER_CODE 0x1002 #define EMBER_AF_DEFAULT_RESPONSE_POLICY_ALWAYS /**** Cluster endpoint counts ****/ #define EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_LEVEL_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT (1) /**** Cluster Endpoint Summaries ****/ -#define EMBER_AF_MAX_SERVER_CLUSTER_COUNT (1) +#define EMBER_AF_MAX_SERVER_CLUSTER_COUNT (2) #define EMBER_AF_MAX_CLIENT_CLUSTER_COUNT (0) -#define EMBER_AF_MAX_TOTAL_CLUSTER_COUNT (1) +#define EMBER_AF_MAX_TOTAL_CLUSTER_COUNT (2) /**** CLI Section ****/ #define EMBER_AF_GENERATE_CLI @@ -90,6 +92,17 @@ #define EMBER_CALLBACK_ON_OFF_CLUSTER_ON #define EMBER_CALLBACK_ON_OFF_CLUSTER_TOGGLE #define EMBER_CALLBACK_ON_OFF_CLUSTER_ON_OFF_CLUSTER_SERVER_INIT +#define EMBER_CALLBACK_ON_OFF_CLUSTER_ON_OFF_CLUSTER_SET_VALUE +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_LEVEL_CONTROL_CLUSTER_SERVER_INIT +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_LEVEL_CONTROL_CLUSTER_SERVER_TICK +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_MOVE_TO_LEVEL +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_MOVE_TO_LEVEL_WITH_ON_OFF +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_MOVE +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_MOVE_WITH_ON_OFF +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_STEP +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_STEP_WITH_ON_OFF +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_STOP +#define EMBER_CALLBACK_LEVEL_CONTROL_CLUSTER_STOP_WITH_ON_OFF #define EMBER_CALLBACK_ENERGY_SCAN_RESULT #define EMBER_CALLBACK_SCAN_COMPLETE #define EMBER_CALLBACK_NETWORK_FOUND @@ -131,6 +144,13 @@ // Use this macro to check if HAL Library plugin is included #define EMBER_AF_PLUGIN_HAL_LIBRARY +// Use this macro to check if Level Control Server Cluster plugin is included +#define EMBER_AF_PLUGIN_LEVEL_CONTROL +// User options for plugin Level Control Server Cluster +#define EMBER_AF_PLUGIN_LEVEL_CONTROL_MAXIMUM_LEVEL 255 +#define EMBER_AF_PLUGIN_LEVEL_CONTROL_MINIMUM_LEVEL 0 +#define EMBER_AF_PLUGIN_LEVEL_CONTROL_RATE 0 + // Use this macro to check if mbed TLS plugin is included #define EMBER_AF_PLUGIN_MBEDTLS // User options for plugin mbed TLS diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index bd6d0977b04d04..f632de4c5c50e5 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -58,4 +58,6 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/util/process-cluster-message.cpp ${CHIP_ROOT}/src/app/util/process-global-message.cpp ${CHIP_ROOT}/src/app/util/util.cpp - ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off.cpp) + ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off.cpp + ${CHIP_ROOT}/src/app/clusters/level-control/level-control.cpp + ) diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index eaf136200d0ae7..6200ebd785ec84 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -239,7 +239,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) actor = AppEvent::kEventType_Button; } - if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action, actor)) + if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action, actor, 0, NULL)) LOG_INF("Action is already in progress or active."); } @@ -449,6 +449,10 @@ void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { LOG_INF("Turn Off Action has been initiated"); } + else if (aAction == LightingManager::LEVEL_ACTION) + { + LOG_INF("Level Action has been initiated"); + } } void AppTask::ActionCompleted(LightingManager::Action_t aAction, int32_t aActor) @@ -461,6 +465,10 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction, int32_t aActor) { LOG_INF("Turn Off Action has been completed"); } + else if (aAction == LightingManager::LEVEL_ACTION) + { + LOG_INF("Level Action has been completed"); + } if (aActor == AppEvent::kEventType_Button) { diff --git a/examples/lighting-app/nrfconnect/main/LightingManager.cpp b/examples/lighting-app/nrfconnect/main/LightingManager.cpp index 6ce56ae41a4173..b185a9f6a3a9e4 100644 --- a/examples/lighting-app/nrfconnect/main/LightingManager.cpp +++ b/examples/lighting-app/nrfconnect/main/LightingManager.cpp @@ -59,7 +59,7 @@ void LightingManager::SetCallbacks(LightingCallback_fn aActionInitiated_CB, Ligh mActionCompleted_CB = aActionCompleted_CB; } -bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor) +bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor, uint8_t size, uint8_t * value) { // TODO: this function is called InitiateAction because we want to implement some features such as ramping up here. bool action_initiated = false; @@ -76,6 +76,18 @@ bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor) action_initiated = true; new_state = kState_Off; } + else if (aAction == LEVEL_ACTION) + { + action_initiated = true; + if (*value == 0) + { + new_state = kState_Off; + } + else + { + new_state = kState_On; + } + } if (action_initiated) { @@ -84,7 +96,14 @@ bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor) mActionInitiated_CB(aAction, aActor); } - Set(new_state == kState_On); + if (aAction == ON_ACTION || aAction == OFF_ACTION) + { + Set(new_state == kState_On); + } + else if (aAction == LEVEL_ACTION) + { + SetLevel(*value); + } if (mActionCompleted_CB) { @@ -95,6 +114,12 @@ bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor) return action_initiated; } +void LightingManager::SetLevel(uint8_t aLevel) +{ + LOG_INF("LEVEL %u", aLevel); + // TODO: use the level for PWM +} + void LightingManager::Set(bool aOn) { if (aOn) diff --git a/examples/lighting-app/nrfconnect/main/ZclCallbacks.cpp b/examples/lighting-app/nrfconnect/main/ZclCallbacks.cpp index 73af7a94d11464..7e442931832065 100644 --- a/examples/lighting-app/nrfconnect/main/ZclCallbacks.cpp +++ b/examples/lighting-app/nrfconnect/main/ZclCallbacks.cpp @@ -31,19 +31,42 @@ using namespace chip; void emberAfPostAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask, uint16_t manufacturerCode, uint8_t type, uint8_t size, uint8_t * value) { - if (clusterId != ZCL_ON_OFF_CLUSTER_ID) + ChipLogProgress(Zcl, "Cluster callback: %d", clusterId); + + if (clusterId == ZCL_ON_OFF_CLUSTER_ID) { - ChipLogProgress(Zcl, "Unknown cluster ID: %d", clusterId); - return; + if (attributeId != ZCL_ON_OFF_ATTRIBUTE_ID) + { + ChipLogProgress(Zcl, "Unknown attribute ID: %d", attributeId); + return; + } + + LightingMgr().InitiateAction(*value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, + AppEvent::kEventType_Lighting, size, value); } + else if (clusterId == ZCL_LEVEL_CONTROL_CLUSTER_ID) + { + if (attributeId != ZCL_MOVE_TO_LEVEL_COMMAND_ID) + { + ChipLogProgress(Zcl, "Unknown attribute ID: %d", attributeId); + return; + } - if (attributeId != ZCL_ON_OFF_ATTRIBUTE_ID) + ChipLogProgress(Zcl, "Value: %u, length %u", *value, size); + if (size == 1) + { + LightingMgr().InitiateAction(LightingManager::LEVEL_ACTION, AppEvent::kEventType_Lighting, size, value); + } + else + { + ChipLogError(Zcl, "wrong length for level: %d", size); + } + } + else { - ChipLogProgress(Zcl, "Unknown attribute ID: %d", attributeId); + ChipLogProgress(Zcl, "Unknown cluster ID: %d", clusterId); return; } - - LightingMgr().InitiateAction(*value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, AppEvent::kEventType_Lighting); } /** @brief Cluster Init diff --git a/examples/lighting-app/nrfconnect/main/include/LightingManager.h b/examples/lighting-app/nrfconnect/main/include/LightingManager.h index 88d4c513dcaa71..03fc91c9326d04 100644 --- a/examples/lighting-app/nrfconnect/main/include/LightingManager.h +++ b/examples/lighting-app/nrfconnect/main/include/LightingManager.h @@ -30,6 +30,7 @@ class LightingManager { ON_ACTION = 0, OFF_ACTION, + LEVEL_ACTION, INVALID_ACTION }; @@ -44,7 +45,7 @@ class LightingManager int Init(const char * gpioDeviceName, gpio_pin_t gpioPin); bool IsTurnedOn() const { return mState == kState_On; } - bool InitiateAction(Action_t aAction, int32_t aActor); + bool InitiateAction(Action_t aAction, int32_t aActor, uint8_t size, uint8_t * value); void SetCallbacks(LightingCallback_fn aActionInitiated_CB, LightingCallback_fn aActionCompleted_CB); private: @@ -57,6 +58,7 @@ class LightingManager LightingCallback_fn mActionCompleted_CB; void Set(bool aOn); + void SetLevel(uint8_t aLevel); static LightingManager sLight; }; diff --git a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt index 79dacfcef9e19c..acdae29ea5c0e3 100644 --- a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt +++ b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt @@ -5,6 +5,8 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.SeekBar +import android.widget.Toast import androidx.fragment.app.Fragment import chip.devicecontroller.ChipCommandType import chip.devicecontroller.ChipDeviceController @@ -20,6 +22,7 @@ class OnOffClientFragment : Fragment() { get() = ChipClient.getDeviceController() private var commandType: ChipCommandType? = null + private var levelValue: Int? = null override fun onCreateView( inflater: LayoutInflater, @@ -32,6 +35,24 @@ class OnOffClientFragment : Fragment() { onBtn.setOnClickListener { sendOnCommandClick() } offBtn.setOnClickListener { sendOffCommandClick() } toggleBtn.setOnClickListener { sendToggleCommandClick() } + + levelBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) { + + } + + override fun onStartTrackingTouch(seekBar: SeekBar?) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar?) { + Toast.makeText(requireContext(), + "Level is: " + levelBar.progress, + Toast.LENGTH_SHORT).show() + commandType = ChipCommandType.LEVEL + levelValue = levelBar.progress + if (deviceController.isConnected) sendCommand() else connectToDevice() + } + }) } } @@ -64,16 +85,19 @@ class OnOffClientFragment : Fragment() { private fun sendOnCommandClick() { commandType = ChipCommandType.ON + levelValue = 0 if (deviceController.isConnected) sendCommand() else connectToDevice() } private fun sendOffCommandClick() { commandType = ChipCommandType.OFF + levelValue = 0 if (deviceController.isConnected) sendCommand() else connectToDevice() } private fun sendToggleCommandClick() { commandType = ChipCommandType.TOGGLE + levelValue = 0 if (deviceController.isConnected) sendCommand() else connectToDevice() } @@ -92,10 +116,11 @@ class OnOffClientFragment : Fragment() { } commandStatusTv.text = - requireContext().getString(R.string.send_command_type_label_text, chipCommandType.name) + requireContext().getString(R.string.send_command_type_label_text, chipCommandType.name, levelValue) try { - deviceController.beginSendCommand(commandType) + // mask levelValue from integer to uint8_t and if null use 0 + deviceController.beginSendCommand(commandType, ( 0xff and (levelValue ?: 0))) } catch (e: ChipDeviceControllerException) { commandStatusTv.text = e.toString() } diff --git a/src/android/CHIPTool/app/src/main/res/layout/on_off_client_fragment.xml b/src/android/CHIPTool/app/src/main/res/layout/on_off_client_fragment.xml index d52f5b76654de7..daaebed96ec204 100644 --- a/src/android/CHIPTool/app/src/main/res/layout/on_off_client_fragment.xml +++ b/src/android/CHIPTool/app/src/main/res/layout/on_off_client_fragment.xml @@ -56,14 +56,24 @@ android:text="@string/send_command_off_btn_text" android:textSize="16sp"/> + + - \ No newline at end of file + diff --git a/src/android/CHIPTool/app/src/main/res/layout/select_action_fragment.xml b/src/android/CHIPTool/app/src/main/res/layout/select_action_fragment.xml index c6bc362dfc11b3..0e6fc318f8faba 100644 --- a/src/android/CHIPTool/app/src/main/res/layout/select_action_fragment.xml +++ b/src/android/CHIPTool/app/src/main/res/layout/select_action_fragment.xml @@ -33,7 +33,7 @@ android:layout_width="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" - android:text="@string/on_off_btn_text" /> + android:text="@string/on_off_level_btn_text" />