Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
9 changes: 7 additions & 2 deletions source/bulkdata/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down
8 changes: 6 additions & 2 deletions source/protocol/rbusMethod/rbusmethodinterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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 ;
Expand Down Expand Up @@ -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
{
Expand Down
9 changes: 9 additions & 0 deletions source/test/mocks/rbusMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions source/test/mocks/rbusMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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), ());
Expand Down Expand Up @@ -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);
Expand Down
96 changes: 96 additions & 0 deletions source/test/protocol/ProtocolTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Loading