Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6f4e0eb
Reason for change:
akumar0702 Sep 9, 2026
0883315
adv sec read the dml as iinteger not as string
akumar0702 Sep 15, 2026
d031f23
use pthread_cond_timedwait instead of timeout logic in .sh
akumar0702 Sep 16, 2026
6af968c
Merge remote-tracking branch 'origin/develop' into feature/RDKB-66844
SanthoshGujulvajagadeesh Sep 22, 2026
3bc3cdf
Move NI pause resume logic from shell script to C
SanthoshGujulvajagadeesh Sep 22, 2026
ae204c9
Update cujo-ni-cli cmd to avoid parsing error
SanthoshGujulvajagadeesh Sep 22, 2026
b48d647
Update logging and add T2 markers
SanthoshGujulvajagadeesh Sep 22, 2026
377f47c
Add header for T2 event marker
SanthoshGujulvajagadeesh Sep 22, 2026
f803ff6
Fix unit test binary compilation error
SanthoshGujulvajagadeesh Sep 22, 2026
f5a8e73
Add mock telemetry library for unit test
SanthoshGujulvajagadeesh Sep 22, 2026
9e133cb
Fix unit test compilation issue
SanthoshGujulvajagadeesh Sep 22, 2026
ac365ab
remove refresh timeout logic on multiple ST_TR181_STATUS_STARTING events
SanthoshGujulvajagadeesh Sep 23, 2026
8203e31
Fix gtest compilation issue
SanthoshGujulvajagadeesh Sep 23, 2026
264f19c
Skip ST_TR181_STATUS_STARTING event if NI pause is in progress
SanthoshGujulvajagadeesh Sep 23, 2026
1183277
Have NI enabled and activated check in speedtest handler
SanthoshGujulvajagadeesh Sep 23, 2026
31bcdcb
Fix rbus leak on rbus_get failure case
SanthoshGujulvajagadeesh Sep 23, 2026
5ce0e0d
Re-introduce refresh timeout on ST_TR181_STATUS_STARTING event
SanthoshGujulvajagadeesh Sep 26, 2026
295d2c7
Fix race in worker cleanup
SanthoshGujulvajagadeesh Sep 28, 2026
d673f29
Fix another moderate race condition
SanthoshGujulvajagadeesh Sep 28, 2026
0262968
Remove ni_speedtest_shutdown since not required in CosaSecurityRemove
SanthoshGujulvajagadeesh Sep 28, 2026
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
2 changes: 1 addition & 1 deletion source/AdvSecurityDml/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ hardware_platform = i686-linux-gnu
lib_LTLIBRARIES = libdmlasecurity.la
libdmlasecurity_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/source/AdvSecurityDml -I$(top_srcdir)/source/AdvSecuritySsp $(CPPFLAGS) -I$(top_srcdir)/../Utopia/source/include/sysevent -I${PKG_CONFIG_SYSROOT_DIR}$(includedir)/rbus
libdmlasecurity_la_SOURCES = plugin_main.c cosa_adv_security_internal.c cosa_adv_security_dml.c cosa_adv_security_webconfig.c advsecurity_helpers.c advsecurity_param.c
libdmlasecurity_la_LDFLAGS = -lccsp_common -lsyscfg -lsysevent -lwebconfig_framework -lmsgpackc -ltrower-base64 -lsecure_wrapper -lrbus -lev -lpthread $(SSP_LDFLAGS)
libdmlasecurity_la_LDFLAGS = -lccsp_common -lsyscfg -lsysevent -lwebconfig_framework -lmsgpackc -ltrower-base64 -lsecure_wrapper -lrbus -lev -lpthread -ltelemetry_msgsender $(SSP_LDFLAGS)
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

if WIFI_DATA_COLLECTION
libdmlasecurity_la_CPPFLAGS += -DDML_SUPPORT -DWIFI_DATA_COLLECTION
Expand Down
226 changes: 226 additions & 0 deletions source/AdvSecurityDml/cosa_adv_security_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
#define ADVSEC_SYSEVENT_CURRENT_WAN_IFNAME_EVENT "current_wan_ifname"

#define LEVL_DML "Device.WiFi.Levl"
#define SPEEDTEST_STATUS_DML "Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Status"
#define SPEEDTEST_TIMEOUT_DML "Device.IP.Diagnostics.X_RDK_SpeedTest.SubscriberUnPauseTimeOut"
#define ADVSEC_NETWORKINTELLIGENCE_ENABLED_PATH "/tmp/advsec_networkintelligence_enabled"
#define CUJONICLI_SET_QOSD_ENABLE_CMD "/usr/bin/cujo-ni-cli '{\"method\":\"set_configs\", \"configs\": {\"cujoniqos.daemon.enable\": %d}}' &"
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

#define ADVSEC_WAIT_FOR_TIMEOUT (60 * 60)
#define MAX_VALUE 32
Expand Down Expand Up @@ -155,6 +159,11 @@ static char *g_RaptrEnabled = "Adv_RaptrRFCEnable";
#ifdef NETWORK_INTELLIGENCE
static char *g_AdvSecNetworkIntelligenceEnabled = "Adv_AdvSecNetworkIntelligenceRFCEnable";
static char *g_NetworkIntelligenceMemoryLimit = "Advsecurity_NetworkIntelligenceMemoryLimit";
STATIC pthread_mutex_t ni_speedtest_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t ni_speedtest_cond = PTHREAD_COND_INITIALIZER;
static struct timespec ni_speedtest_timeout;
STATIC BOOL ni_speedtest_thread_running = FALSE;
static BOOL ni_speedtest_wake_early = FALSE;
static char *g_NetworkIntelligenceActivate = "Adv_AdvSecNetworkIntelligenceActivate";
#endif
#ifdef WIFI_DATA_COLLECTION
Expand Down Expand Up @@ -434,6 +443,215 @@ static void eventReceiveHandler(
}
#endif

#ifdef NETWORK_INTELLIGENCE
static BOOL is_ni_enabled_and_activated(void)
{
struct stat st;

if (stat(ADVSEC_NETWORKINTELLIGENCE_ENABLED_PATH, &st) != 0)
{
return FALSE;
}
if (stat(ADVSEC_NETWORKINTELLIGENCE_ACTIVATED_PATH, &st) != 0)
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.
{
return FALSE;
}
return TRUE;
}

static BOOL ni_qosd_enable(BOOL enable)
{
errno_t rc;

rc = v_secure_system(CUJONICLI_SET_QOSD_ENABLE_CMD, enable ? 1 : 0);
if (!WIFEXITED(rc) || WEXITSTATUS(rc) != 0)
{
CcspTraceError(("%s: cujo-ni-cli set_configs cujoniqos.daemon.enable=%d failed, rc=%d\n",
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.
__FUNCTION__, enable ? 1 : 0, WEXITSTATUS(rc)));
return FALSE;
}
if (enable)
{
t2_event_d("SYS_INFO_CUJO_NI_resume", 1);
}
else
{
t2_event_d("SYS_INFO_CUJO_NI_pause", 1);
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.
}
return TRUE;
}

static void *ni_speedtest_handler(void *arg)
{
int waitStatus = 0;
BOOL timedOut;

(void)arg;

pthread_detach(pthread_self());

pthread_mutex_lock(&ni_speedtest_mutex);
if (!ni_qosd_enable(FALSE))
{
CcspTraceError(("%s: failed to pause Network Intelligence for speedtest\n", __FUNCTION__));
ni_speedtest_thread_running = FALSE;
pthread_mutex_unlock(&ni_speedtest_mutex);
return NULL;
}

while (!ni_speedtest_wake_early && waitStatus != ETIMEDOUT)
{
waitStatus = pthread_cond_timedwait(&ni_speedtest_cond, &ni_speedtest_mutex, &ni_speedtest_timeout);
if (waitStatus != 0 && waitStatus != ETIMEDOUT)
{
CcspTraceError(("%s: pthread_cond_timedwait failed, error=%d\n", __FUNCTION__, waitStatus));
break;
}
}
timedOut = (waitStatus == ETIMEDOUT);
ni_speedtest_wake_early = FALSE;

if (timedOut)
{
CcspTraceWarning(("%s: speedtest timeout expired, resuming Network Intelligence\n", __FUNCTION__));
t2_event_d("IMP_CUJO_NI_SubscriberUnPauseTimeOut", 1);
}
if (!ni_qosd_enable(TRUE))
{
CcspTraceError(("%s: failed to resume Network Intelligence after speedtest\n", __FUNCTION__));
}

ni_speedtest_thread_running = FALSE;
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.
pthread_mutex_unlock(&ni_speedtest_mutex);

return NULL;
}

static BOOL ni_speedtest_trigger(uint32_t timeout)
{
struct timespec ni_resume_timeout;
pthread_t tid;
int err;

if (clock_gettime(CLOCK_REALTIME, &ni_resume_timeout) != 0)
{
CcspTraceError(("%s: clock_gettime failed, errno=%d\n", __FUNCTION__, errno));
return FALSE;
}
ni_resume_timeout.tv_sec += timeout;
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

pthread_mutex_lock(&ni_speedtest_mutex);
if (ni_speedtest_thread_running)
{
ni_speedtest_timeout = ni_resume_timeout;
pthread_cond_signal(&ni_speedtest_cond);
pthread_mutex_unlock(&ni_speedtest_mutex);
CcspTraceInfo(("%s: Network Intelligence already paused for speedtest, refreshed timeout\n", __FUNCTION__));
return TRUE;
}

ni_speedtest_timeout = ni_resume_timeout;

ni_speedtest_wake_early = FALSE;
ni_speedtest_thread_running = TRUE;

err = pthread_create(&tid, NULL, ni_speedtest_handler, NULL);
if (err != 0)
{
ni_speedtest_thread_running = FALSE;
pthread_mutex_unlock(&ni_speedtest_mutex);
CcspTraceError(("%s: failed to create speedtest timer thread, error=%d\n", __FUNCTION__, err));
return FALSE;
}
pthread_mutex_unlock(&ni_speedtest_mutex);
return TRUE;
}

static void ni_speedtest_complete(void)
{
pthread_mutex_lock(&ni_speedtest_mutex);
if (ni_speedtest_thread_running)
{
ni_speedtest_wake_early = TRUE;
pthread_cond_signal(&ni_speedtest_cond);
}
pthread_mutex_unlock(&ni_speedtest_mutex);
}

static BOOL speedtestGetTimeout(uint32_t *timeout)
{
rbusValue_t value = NULL;
int ret;

ret = rbus_get(rbus_handle, SPEEDTEST_TIMEOUT_DML, &value);
if (ret != RBUS_ERROR_SUCCESS)
{
CcspTraceError(("%s: rbus_get failed for %s, error=%d\n", __FUNCTION__, SPEEDTEST_TIMEOUT_DML, ret));
if (value != NULL)
{
rbusValue_Release(value);
}
return FALSE;
Comment thread
Copilot marked this conversation as resolved.
}

*timeout = rbusValue_GetUInt32(value);
rbusValue_Release(value);

return TRUE;
}

STATIC void speedtestEventReceiveHandler(
rbusHandle_t handle,
rbusEvent_t const* event,
rbusEventSubscription_t* subscription)
{
rbusValue_t value;
uint32_t status;
uint32_t timeout;

(void)handle;
(void)subscription;

value = rbusObject_GetValue(event->data, NULL);
if (value == NULL)
{
CcspTraceError(("SpeedTest status event has no value\n"));
return;
}
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

status = rbusValue_GetUInt32(value);
CcspTraceInfo(("%s: speedtest status event received, status=%u\n", __FUNCTION__, status));

if (!is_ni_enabled_and_activated())
{
CcspTraceInfo(("%s: Network Intelligence is disabled or not activated, skipping speedtest event\n", __FUNCTION__));
return;
}
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

if (status == ST_TR181_STATUS_STARTING)
{
if (!speedtestGetTimeout(&timeout))
{
CcspTraceError(("%s: failed to get speedtest unpause timeout, Network Intelligence will not be paused\n", __FUNCTION__));
return;
}
if (timeout == 0)
{
CcspTraceInfo(("%s: speedtest unpause timeout is 0, skipping Network Intelligence pause\n", __FUNCTION__));
return;
}
if (!ni_speedtest_trigger(timeout))
{
CcspTraceError(("%s: Network Intelligence speedtest trigger failed, Network Intelligence will not be paused\n", __FUNCTION__));
}
}
else if (status == ST_TR181_STATUS_COMPLETE)
{
ni_speedtest_complete();
}
}
#endif

#if defined(WIFI_DATA_COLLECTION) || defined(NETWORK_INTELLIGENCE)
static int touch_file(const char *filepath)
{
Expand Down Expand Up @@ -1587,6 +1805,14 @@ CosaSecurityInitialize
CcspTraceError(("AdvSecurityEventConsumer: rbusEvent_Subscribe %s failed: %d\n", LEVL_DML, ret));
return ANSC_STATUS_FAILURE;
}
#endif
#ifdef NETWORK_INTELLIGENCE
ret = rbusEvent_Subscribe(rbus_handle, SPEEDTEST_STATUS_DML, speedtestEventReceiveHandler, NULL, 0);
if(ret != RBUS_ERROR_SUCCESS)
{
CcspTraceError(("AdvSecurityEventConsumer: rbusEvent_Subscribe %s failed: %d\n", SPEEDTEST_STATUS_DML, ret));
return ANSC_STATUS_FAILURE;
}
#endif
return returnStatus;
}
Expand Down
3 changes: 3 additions & 0 deletions source/AdvSecurityDml/cosa_adv_security_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <errno.h>
#include "ansc_platform.h"
#include "ansc_string_util.h"
#include <telemetry_busmessage_sender.h>

#define ADVSEC_MIN_LOG_TIMEOUT (60 * 1)
#define ADVSEC_MAX_LOG_TIMEOUT (60 * 48)
Expand All @@ -43,6 +44,8 @@
#define ADVSEC_LogLevel_VERBOSE 4
#define BUFLEN_1024 1024
#define PARTNER_REDIRECTORURL_PARAMNAME "Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.AdvsecRedirectorURL"
#define ST_TR181_STATUS_STARTING 1
#define ST_TR181_STATUS_COMPLETE 5
Comment thread
SanthoshGujulvajagadeesh marked this conversation as resolved.

typedef enum {
ADVSEC_SAFEBROWSING=0,
Expand Down
4 changes: 2 additions & 2 deletions source/AdvSecurityDml/cosa_adv_security_webconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pErr advsec_webconfig_process_request(void *Data)
int advsec_webconfig_rollback()
{
// return 0 to notify framework when rollback is success
CcspTraceInfo((" Entering %s \n",__FUNCTION__));
CcspTraceInfo(("Entering %s\n", __FUNCTION__));

int ret = 0;

Expand All @@ -215,7 +215,7 @@ int advsec_webconfig_rollback()
void advsec_webconfig_free_resources(void *arg)
{

CcspTraceInfo((" Entering %s \n",__FUNCTION__));
CcspTraceInfo(("Entering %s\n", __FUNCTION__));
execData *blob_exec_data = (execData*) arg;

/* CID 158652: Dereference before null check */
Expand Down
4 changes: 2 additions & 2 deletions source/AdvSecurityDml/cosa_network_intelligence_webconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pErr ni_webconfig_process_request(void *Data)
int ni_webconfig_rollback()
{
// return 0 to notify framework when rollback is success
CcspTraceInfo((" Entering %s \n",__FUNCTION__));
CcspTraceInfo(("Entering %s\n", __FUNCTION__));

int ret = 0;

Expand All @@ -105,7 +105,7 @@ int ni_webconfig_rollback()
/* Callback function to free webconfig resources */
void ni_webconfig_free_resources(void *arg)
{
CcspTraceInfo((" Entering %s \n",__FUNCTION__));
CcspTraceInfo(("Entering %s\n", __FUNCTION__));
execData *blob_exec_data = (execData*) arg;

if ( blob_exec_data != NULL )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class CcspAdvSecurityDmlTestFixture : public ::testing::Test {
g_syseventMock = new SyseventMock();
g_webconfigFwMock = new webconfigFwMock();
g_anscWrapperApiMock = new AnscWrapperApiMock();
g_telemetryMock = new telemetryMock();
}

void TearDown() override {
Expand All @@ -60,6 +61,7 @@ class CcspAdvSecurityDmlTestFixture : public ::testing::Test {
delete g_syseventMock;
delete g_webconfigFwMock;
delete g_anscWrapperApiMock;
delete g_telemetryMock;
g_syscfgMock = nullptr;
g_securewrapperMock = nullptr;
g_msgpackMock = nullptr;
Expand All @@ -76,6 +78,7 @@ class CcspAdvSecurityDmlTestFixture : public ::testing::Test {
g_syseventMock = nullptr;
g_webconfigFwMock = nullptr;
g_anscWrapperApiMock = nullptr;
g_telemetryMock = nullptr;
}
};

Expand Down
Loading
Loading