From 14917282e844011b8bf6cff854b2986884b73bd1 Mon Sep 17 00:00:00 2001 From: Yogeswaran K <166126056+yogeswaransky@users.noreply.github.com> Date: Thu, 10 Sep 2026 19:55:21 +0530 Subject: [PATCH 1/2] RDKB-66418: Handle rbus method failure efficiently (#423) * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K * RDKB-66418: Handle rbus method failure efficiently Signed-off-by: Yogeswaran K --------- Signed-off-by: Yogeswaran K Co-authored-by: shibu-kv --- source/bulkdata/profile.c | 9 +- .../protocol/rbusMethod/rbusmethodinterface.c | 8 +- source/test/mocks/rbusMock.cpp | 9 ++ source/test/mocks/rbusMock.h | 2 + source/test/protocol/ProtocolTest.cpp | 96 +++++++++++++++++++ 5 files changed, 120 insertions(+), 4 deletions(-) diff --git a/source/bulkdata/profile.c b/source/bulkdata/profile.c index bacdcbd49..ec02fac11 100644 --- a/source/bulkdata/profile.c +++ b/source/bulkdata/profile.c @@ -798,7 +798,7 @@ static void* CollectAndReport(void* data) ret = sendReportsOverRBUSMethod(profile->t2RBUSDest->rbusMethodName, profile->t2RBUSDest->rbusMethodParamList, jsonReport); } } - if((ret == T2ERROR_FAILURE && strcmp(profile->protocol, "HTTP") == 0) || ret == T2ERROR_NO_RBUS_METHOD_PROVIDER) + if(ret == T2ERROR_FAILURE || ret == T2ERROR_NO_RBUS_METHOD_PROVIDER) { T2Debug("Vector list size = %lu\n", (unsigned long) Vector_Size(profile->cachedReportList)); if(profile->cachedReportList != NULL && Vector_Size(profile->cachedReportList) >= MAX_CACHED_REPORTS) @@ -824,7 +824,7 @@ static void* CollectAndReport(void* data) // Save messages from profile->cachedReportList to a file in persistent location . saveCachedReportToPersistenceFolder(profile->name, profile->cachedReportList); - if(strcmp(profile->protocol, "RBUS_METHOD") == 0) + if(strcmp(profile->protocol, "RBUS_METHOD") == 0 && ret == T2ERROR_NO_RBUS_METHOD_PROVIDER) { profile->SendErr++; if(profile->SendErr > 3 && !(rbusCheckMethodExists(profile->t2RBUSDest->rbusMethodName))) //to delete the profile in the next CollectAndReport or triggercondition @@ -875,6 +875,11 @@ static void* CollectAndReport(void* data) goto reportThreadEnd; } } + else if(strcmp(profile->protocol, "RBUS_METHOD") == 0) + { + /* Only no-provider failures should contribute to profile deletion. */ + profile->SendErr = 0; + } } else if(profile->cachedReportList != NULL && Vector_Size(profile->cachedReportList) > 0) { diff --git a/source/protocol/rbusMethod/rbusmethodinterface.c b/source/protocol/rbusMethod/rbusmethodinterface.c index 15ce064b6..ce7a8819b 100644 --- a/source/protocol/rbusMethod/rbusmethodinterface.c +++ b/source/protocol/rbusMethod/rbusmethodinterface.c @@ -42,6 +42,7 @@ static pthread_cond_t rbusMethodCond; static clockid_t rbusMethodCondClock = CLOCK_REALTIME; static bool rbusMethodCallbackDone = false; static bool isRbusMethod = false ; +static rbusError_t gRbusAsyncRetStatus = RBUS_ERROR_BUS_ERROR; static void sendOverRBUSMethodInit() { @@ -93,6 +94,7 @@ static void asyncMethodHandler(rbusHandle_t handle, char const* methodName, rbus * This ensures no cross-thread unlock (which is UB for default mutexes) * and provides proper memory visibility for isRbusMethod. */ pthread_mutex_lock(&rbusMethodMutex); + gRbusAsyncRetStatus = retStatus; if(retStatus == RBUS_ERROR_SUCCESS) { isRbusMethod = true ; @@ -194,8 +196,10 @@ T2ERROR sendReportsOverRBUSMethod(char *methodName, Vector* inputParams, char* p } else if (rbusMethodCallbackDone) { - T2Info("Return status of send via rbusMethod is failure\n"); - ret = T2ERROR_NO_RBUS_METHOD_PROVIDER; + T2Info("Return status of send via rbusMethod is failure: rbusRet=%s\n", + rbusError_ToString(gRbusAsyncRetStatus)); + /* Callback received => provider is up; don't classify as NO_RBUS_METHOD_PROVIDER. */ + ret = T2ERROR_FAILURE; } else { diff --git a/source/test/mocks/rbusMock.cpp b/source/test/mocks/rbusMock.cpp index 262365002..4867f22c7 100644 --- a/source/test/mocks/rbusMock.cpp +++ b/source/test/mocks/rbusMock.cpp @@ -157,6 +157,15 @@ extern "C" bool rbusValue_GetBoolean(rbusValue_t value) return g_rbusMock->rbusValue_GetBoolean(value); } +extern "C" int32_t rbusValue_GetInt32(rbusValue_t value) +{ + if (!g_rbusMock) + { + return 0; + } + return g_rbusMock->rbusValue_GetInt32(value); +} + extern "C" char const* rbusValue_GetString(rbusValue_t value, int* len) { if (!g_rbusMock) diff --git a/source/test/mocks/rbusMock.h b/source/test/mocks/rbusMock.h index b8fbf22fb..2e64f4541 100644 --- a/source/test/mocks/rbusMock.h +++ b/source/test/mocks/rbusMock.h @@ -44,6 +44,7 @@ class rbusMock MOCK_METHOD(rbusValueType_t, rbusValue_GetType, (rbusValue_t v), ()); MOCK_METHOD(struct _rbusObject*, rbusValue_GetObject, (rbusValue_t v), ()); MOCK_METHOD(bool, rbusValue_GetBoolean, (rbusValue_t value), ()); + MOCK_METHOD(int32_t, rbusValue_GetInt32, (rbusValue_t value), ()); MOCK_METHOD(char const*, rbusValue_GetString, (rbusValue_t value, int* len), ()); MOCK_METHOD(rbusProperty_t, rbusProperty_Init, (rbusProperty_t* pproperty, char const* name, rbusValue_t value), ()); MOCK_METHOD(void, rbusValue_SetProperty, (rbusValue_t value, struct _rbusProperty* property), ()); @@ -100,6 +101,7 @@ extern "C" rbusError_t rbus_open(rbusHandle_t* handle, char const* componentName extern "C" rbusValueType_t rbusValue_GetType(rbusValue_t v); extern "C" struct _rbusObject* rbusValue_GetObject(rbusValue_t v); extern "C" bool rbusValue_GetBoolean(rbusValue_t value); +extern "C" int32_t rbusValue_GetInt32(rbusValue_t value); extern "C" char const* rbusValue_GetString(rbusValue_t value, int* len); extern "C" rbusProperty_t rbusProperty_Init(rbusProperty_t* pproperty, char const* name, rbusValue_t value); extern "C" void rbusValue_SetProperty(rbusValue_t value, struct _rbusProperty* property); diff --git a/source/test/protocol/ProtocolTest.cpp b/source/test/protocol/ProtocolTest.cpp index 14252f26c..42186ec20 100644 --- a/source/test/protocol/ProtocolTest.cpp +++ b/source/test/protocol/ProtocolTest.cpp @@ -490,6 +490,102 @@ TEST_F(protocolTestFixture, SENDREPORTSOVERRBUSMETHOD2) Vector_Destroy(inputParams, free); } +/* +TEST_F(protocolTestFixture, SENDREPORTSOVERRBUSMETHOD_ASYNC_CALLBACK_FAILURE_RETURNS_FAILURE) +{ + char* method = strdup("RBUS_METHOD"); + RBUSMethodParam *rbusMethodParam = (RBUSMethodParam *) malloc(sizeof(RBUSMethodParam)); + rbusMethodParam->name = "Device.X_RDK_Xmidt.SendData"; + rbusMethodParam->value = "This is a value string"; + Vector* inputParams = NULL; + Vector_Create(&inputParams); + Vector_PushBack(inputParams, rbusMethodParam); + char* payload = strdup("This is a payload string"); + + rbusObject_t fakeParamsObj = (rbusObject_t)0x1001; + + EXPECT_CALL(*g_rbusMock, rbusObject_Init(_,_)) + .Times(1) + .WillOnce(Return((rbusObject_t)0xffffffff)); + EXPECT_CALL(*g_rbusMock, rbusValue_Init(_)) + .Times(3) + .WillOnce(Return((rbusValue_t)0xffffffff)) + .WillOnce(Return((rbusValue_t)0xffffffff)) + .WillOnce(Return((rbusValue_t)0xffffffff)); + EXPECT_CALL(*g_rbusMock, rbusValue_SetString(_,_)) + .Times(2); + EXPECT_CALL(*g_rbusMock, rbusObject_SetValue(_,_,_)) + .Times(3); + EXPECT_CALL(*g_rbusMock, rbusValue_Release(_)) + .Times(3); + EXPECT_CALL(*g_rbusMock, rbusValue_SetInt32(_,_)) + .Times(1); + EXPECT_CALL(*g_rbusMock, rbusMethodCaller(_,_,_,_)) + .Times(1) + .WillOnce(::testing::Invoke( + [fakeParamsObj](char *methodName, rbusObject_t* input, char* output, rbusMethodCallBackPtr rbusMethodCallBack) { + (void)input; + (void)output; + rbusMethodCallBack(NULL, methodName, RBUS_ERROR_INVALID_RESPONSE_FROM_DESTINATION, fakeParamsObj); + return T2ERROR_SUCCESS; + })); + EXPECT_CALL(*g_rbusMock, rbusObject_Release(_)) + .Times(1); + + EXPECT_EQ(T2ERROR_FAILURE, sendReportsOverRBUSMethod(method, inputParams, payload)); + + free(method); + free(payload); + Vector_Destroy(inputParams, free); +} + +TEST_F(protocolTestFixture, SENDREPORTSOVERRBUSMETHOD_ASYNC_CALLBACK_SUCCESS_RETURNS_SUCCESS) +{ + char* method = strdup("RBUS_METHOD"); + RBUSMethodParam *rbusMethodParam = (RBUSMethodParam *) malloc(sizeof(RBUSMethodParam)); + rbusMethodParam->name = "Device.X_RDK_Xmidt.SendData"; + rbusMethodParam->value = "This is a value string"; + Vector* inputParams = NULL; + Vector_Create(&inputParams); + Vector_PushBack(inputParams, rbusMethodParam); + char* payload = strdup("This is a payload string"); + + EXPECT_CALL(*g_rbusMock, rbusObject_Init(_,_)) + .Times(1) + .WillOnce(Return((rbusObject_t)0xffffffff)); + EXPECT_CALL(*g_rbusMock, rbusValue_Init(_)) + .Times(3) + .WillOnce(Return((rbusValue_t)0xffffffff)) + .WillOnce(Return((rbusValue_t)0xffffffff)) + .WillOnce(Return((rbusValue_t)0xffffffff)); + EXPECT_CALL(*g_rbusMock, rbusValue_SetString(_,_)) + .Times(2); + EXPECT_CALL(*g_rbusMock, rbusObject_SetValue(_,_,_)) + .Times(3); + EXPECT_CALL(*g_rbusMock, rbusValue_Release(_)) + .Times(3); + EXPECT_CALL(*g_rbusMock, rbusValue_SetInt32(_,_)) + .Times(1); + EXPECT_CALL(*g_rbusMock, rbusMethodCaller(_,_,_,_)) + .Times(1) + .WillOnce(::testing::Invoke( + [](char *methodName, rbusObject_t* input, char* output, rbusMethodCallBackPtr rbusMethodCallBack) { + (void)input; + (void)output; + rbusMethodCallBack(NULL, methodName, RBUS_ERROR_SUCCESS, NULL); + return T2ERROR_SUCCESS; + })); + EXPECT_CALL(*g_rbusMock, rbusObject_Release(_)) + .Times(1); + + EXPECT_EQ(T2ERROR_SUCCESS, sendReportsOverRBUSMethod(method, inputParams, payload)); + + free(method); + free(payload); + Vector_Destroy(inputParams, free); +} +*/ + TEST_F(protocolTestFixture, sendCachedReportsOverRBUSMethod) { char* method = strdup("RBUS_METHOD"); From 7a923068c2e863ba96633d8c5b615296c18d560b Mon Sep 17 00:00:00 2001 From: shibu-kv Date: Thu, 10 Sep 2026 07:27:56 -0700 Subject: [PATCH 2/2] Changelog updates for 1.10.4 release --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b7d7993..3108098b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.10.4](https://github.com/rdkcentral/telemetry/compare/1.10.3...1.10.4) + +- RDKB-66418: Handle rbus method failure efficiently [`#423`](https://github.com/rdkcentral/telemetry/pull/423) + #### [1.10.3](https://github.com/rdkcentral/telemetry/compare/1.10.2...1.10.3) +> 4 September 2026 + - RDKB-66724: Increased Retry for Trigger condition RBUS failure [`#422`](https://github.com/rdkcentral/telemetry/pull/422) +- Changelog updates for 1.10.3 release [`68d1320`](https://github.com/rdkcentral/telemetry/commit/68d1320ff3368103833d4e11f17ea74f36de3055) #### [1.10.2](https://github.com/rdkcentral/telemetry/compare/1.10.1...1.10.2)