added wan and cpe-service state in metadata#475
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #475 +/- ##
==========================================
+ Coverage 80.35% 81.58% +1.22%
==========================================
Files 58 60 +2
Lines 11307 11924 +617
Branches 1115 1172 +57
==========================================
+ Hits 9086 9728 +642
+ Misses 1787 1721 -66
- Partials 434 475 +41 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
aa13edf to
54d8c1f
Compare
f8867eb to
fda9b43
Compare
There was a problem hiding this comment.
Pull request overview
Adds WAN state and CPE service state into Parodus metadata (for WebPA connectivity status reporting), including RBUS subscription support and persistence of CPE service state across process restarts.
Changes:
- Extend upstream metadata packing to include
wan-stateandcpe-service-state, and update metadata on relevant events. - Add RBUS WAN state subscription/handler logic and integrate it into startup.
- Add/extend unit tests and CMake test targets to cover RBUS handling, metadata packing, and persisted CPE service state.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/upstream.c |
Increases metadata field count, adds CPE service state extraction and metadata mutex. |
src/upstream.h |
Exposes new metadata mutex APIs and RBUS WAN-state APIs via header changes. |
src/upstream_rbus.c |
Adds WAN state subscription + handler and updates metadata on subscribe/event callbacks. |
src/config.c |
Implements read/write of persisted CPE service state and sets defaults. |
src/config.h |
Adds metadata keys and config struct fields for WAN/CPE service state and persistence path. |
src/connection.c |
Ensures metadata repack is mutex-protected after successful connection. |
src/main.c |
Calls WAN state subscription during startup when RBUS is enabled. |
src/ParodusInternal.h |
Introduces PARODUS_FREE macro used by new RBUS code path. |
tests/CMakeLists.txt |
Adds new test_packMetaData and test_upstream_rbus targets. |
tests/test_packMetaData.c |
New CUnit tests for metadata packing/unpacking and CPE service state parsing. |
tests/test_upstream_rbus.c |
New cmocka tests for RBUS subscribe/handlers and WAN failover handler behavior. |
tests/test_upstream.c |
Adds stub for new persistence writer to keep upstream unit test linking. |
tests/test_upstream_sock.c |
Adds stub for new persistence writer to keep upstream sock unit test linking. |
tests/test_config.c |
Adds tests for persisted CPE service state read/write and default restore behavior. |
tests/test_connection.c |
Adds metadata mutex mocks needed by connection tests. |
tests/test_conn_interface.c |
Adds metadata mutex mocks needed by conn interface tests. |
Comments suppressed due to low confidence (2)
src/upstream.h:68
extractCpeServiceStateis defined as a non-static function inupstream.cand is called fromtests/test_packMetaData.c, but it is not declared inupstream.h. With modern C compilers (C99+), calling an undeclared function is an error (or at least a warning that may be treated as error). Please add a prototype in the public header (or make itstaticand avoid calling it cross-TU in tests).
void packMetaData();
void lock_metadata_mutex(void);
void unlock_metadata_mutex(void);
void *handle_upstream();
void *processUpstreamMessage();
void registerRBUSlistener();
int getDeviceId(char **device_id, size_t *device_id_len);
int sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size);
void getServiceNameAndSendResponse(wrp_msg_t *msg, void **msg_bytes, size_t msg_size);
void createUpstreamRetrieveMsg(wrp_msg_t *message, wrp_msg_t **retrieve_msg);
void set_global_UpStreamMsgQ(UpStreamMsg * UpStreamQ);
#ifdef WAN_FAILOVER_SUPPORTED
int subscribeCurrentActiveInterfaceEvent();
#endif
int subscribeWanStateEvent();
void wanStateEventHandler(rbusHandle_t handle, rbusEvent_t const* event, rbusEventSubscription_t* subscription);
UpStreamMsg * get_global_UpStreamMsgQ(void);
pthread_cond_t *get_global_nano_con(void);
pthread_mutex_t *get_global_nano_mut(void);
void clear_metadata();
src/upstream.c:126
packMetaData()overwrites the globalmetadataPackpointer on every call, but it doesn't free the previous buffer first. With the new WAN/CPE state updates callingpackMetaData()on each change, this can turn into an unbounded memory growth ifwrp_pack_metadataallocates a fresh buffer each time (as the tests imply by freeingmetadataPack). Consider freeing the oldmetadataPack(and resettingmetaPackSize) before repacking, under the same metadata mutex.
void packMetaData()
{
char boot_time[256]={'\0'};
//Pack the metadata initially to reuse for every upstream msg sending to server
ParodusPrint("-------------- Packing metadata ----------------\n");
sprintf(boot_time, "%d", get_parodus_cfg()->boot_time);
struct data meta_pack[METADATA_COUNT] = {
{HW_MODELNAME, get_parodus_cfg()->hw_model},
{HW_SERIALNUMBER, get_parodus_cfg()->hw_serial_number},
{HW_MANUFACTURER, get_parodus_cfg()->hw_manufacturer},
{HW_DEVICEMAC, get_parodus_cfg()->hw_mac},
{HW_LAST_REBOOT_REASON, get_parodus_cfg()->hw_last_reboot_reason},
{FIRMWARE_NAME , get_parodus_cfg()->fw_name},
{BOOT_TIME, boot_time},
{LAST_RECONNECT_REASON, get_global_reconnect_reason()},
{WEBPA_PROTOCOL, get_parodus_cfg()->webpa_protocol},
{WEBPA_UUID,get_parodus_cfg()->webpa_uuid},
{WEBPA_INTERFACE, getWebpaInterface()},
{PARTNER_ID, get_parodus_cfg()->partner_id},
{WAN_STATE, get_parodus_cfg()->wan_state},
{CPE_SERVICE_STATE, get_parodus_cfg()->cpe_service_state}
};
const data_t metapack = {METADATA_COUNT, meta_pack};
metaPackSize = wrp_pack_metadata( &metapack , &metadataPack );
if (metaPackSize > 0)
{
ParodusInfo("metadata encoding is successful with size %zu\n", metaPackSize);
}
else
{
ParodusError("Failed to encode metadata\n");
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -45,6 +46,8 @@ typedef struct UpStreamMsg__ | |||
| /*----------------------------------------------------------------------------*/ | |||
|
|
|||
| void packMetaData(); | |||
| void lock_metadata_mutex(void); | |||
| void unlock_metadata_mutex(void); | |||
| void *handle_upstream(); | |||
| void *processUpstreamMessage(); | |||
| void registerRBUSlistener(); | |||
| @@ -56,6 +59,8 @@ void set_global_UpStreamMsgQ(UpStreamMsg * UpStreamQ); | |||
| #ifdef WAN_FAILOVER_SUPPORTED | |||
| int subscribeCurrentActiveInterfaceEvent(); | |||
| #endif | |||
| int subscribeWanStateEvent(); | |||
| void wanStateEventHandler(rbusHandle_t handle, rbusEvent_t const* event, rbusEventSubscription_t* subscription); | |||
| UpStreamMsg * get_global_UpStreamMsgQ(void); | |||
| ParodusInfo("********** Starting component: Parodus **********\n "); | ||
| drop_root_privilege(); | ||
| #ifdef ENABLE_WEBCFGBIN | ||
| registerRbusLogger(); | ||
| subscribeRBUSevent(); | ||
| regXmidtSendDataMethod(); | ||
| subscribeWanStateEvent(); | ||
| #endif | ||
| setDefaultValuesToCfg(cfg); | ||
| if (0 != parseCommandLine(argc,argv,cfg)) { |
| fprintf(fp, "fully-manageable\n"); | ||
| fclose(fp); | ||
|
|
||
| char buf[64] = {0}; | ||
| int rc = read_persisted_cpe_service_state(buf, sizeof(buf)); | ||
| assert_int_equal(rc, 0); | ||
| assert_string_equal(buf, "fully-manageable"); | ||
| remove(CPE_SERVICE_STATE_FILE); | ||
| } | ||
|
|
||
| void test_read_persisted_cpe_service_state_invalid() | ||
| { | ||
| FILE *fp = fopen(CPE_SERVICE_STATE_FILE, "w"); | ||
| fprintf(fp, "bogus-state\n"); | ||
| fclose(fp); | ||
|
|
||
| char buf[64] = {0}; | ||
| int rc = read_persisted_cpe_service_state(buf, sizeof(buf)); | ||
| assert_int_not_equal(rc, 0); | ||
| remove(CPE_SERVICE_STATE_FILE); |
| void test_extractCpeServiceState_Invalid_Format(void) | ||
| { | ||
| // Invalid states | ||
| extractCpeServiceState("event:device-status/mac:646772ad8633/firmware-download-completed"); | ||
| CU_ASSERT_STRING_EQUAL(get_parodus_cfg()->cpe_service_state, "unknown"); | ||
| } | ||
|
|
||
| void test_extractCpeServiceState_Invalid_Format1(void) | ||
| { | ||
| // Invalid states | ||
| extractCpeServiceState("event:device-status/mac:646772ad8633"); | ||
| CU_ASSERT_STRING_EQUAL(get_parodus_cfg()->cpe_service_state, "unknown"); | ||
| } | ||
|
|
||
| void test_extractCpeServiceState_Invalid_Format2(void) | ||
| { | ||
| // Invalid states | ||
| extractCpeServiceState("event:device-status/"); | ||
| CU_ASSERT_STRING_EQUAL(get_parodus_cfg()->cpe_service_state, "unknown"); | ||
| } | ||
|
|
||
| void test_extractCpeServiceState_Invalid_Format3(void) | ||
| { | ||
| // Invalid states | ||
| extractCpeServiceState("xyz"); | ||
| CU_ASSERT_STRING_EQUAL(get_parodus_cfg()->cpe_service_state, "unknown"); | ||
| } |
| void subscribeAsyncHandler( rbusHandle_t handle, rbusEventSubscription_t* subscription, rbusError_t error) | ||
| { | ||
| (void)handle; | ||
| ParodusInfo("subscribeAsyncHandler event %s, error %d - %s\n",subscription->eventName, error, rbusError_ToString(error)); | ||
| if(error == RBUS_ERROR_SUCCESS) | ||
| { | ||
| if(strncmp(subscription->eventName, WAN_STATE_EVENT, strlen(WAN_STATE_EVENT)) == 0) | ||
| { | ||
| ParodusInfo("Successfully subscribed to %s\n", WAN_STATE_EVENT); | ||
| /*get orange's data by alias 'orange'*/ | ||
| char* value = NULL; | ||
| int rc = RBUS_ERROR_SUCCESS; | ||
| if((rc = rbus_getStr(handle, WAN_STATE_EVENT, &value)) == RBUS_ERROR_SUCCESS) | ||
| { |
69a12bc to
5b98d87
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (1)
src/upstream.c:116
packMetaData()is now called on WAN/CPE state changes, so it may run multiple times over the process lifetime. It currently overwrites the globalmetadataPackpointer on eachwrp_pack_metadatacall without explicitly releasing/resetting the previous buffer. Ifwrp_pack_metadatadoes not free/reuse the incoming*databuffer, this will leak memory. To make ownership unambiguous and safe, free the oldmetadataPack(and set it to NULL / resetmetaPackSize) before repacking, under the metadata mutex.
{CPE_SERVICE_STATE, get_parodus_cfg()->cpe_service_state}
};
const data_t metapack = {METADATA_COUNT, meta_pack};
metaPackSize = wrp_pack_metadata( &metapack , &metadataPack );
| #ifdef ENABLE_WEBCFGBIN | ||
| subscribeWanStateEvent(); | ||
| #endif | ||
| if (0 != parseCommandLine(argc,argv,cfg)) { | ||
| abort(); | ||
| } |
|
|
||
| if(strcmp(param, "Device.X_RDK_WanManager.WanState") == 0) | ||
| { | ||
| *value = strdup("xyz"); | ||
| return RBUS_ERROR_SUCCESS; | ||
| } |
|
|
||
| /* Verify each field value */ | ||
| char boot_time_str[256]; | ||
| sprintf(boot_time_str, "%d", cfg.boot_time); |
| void test_read_persisted_cpe_service_state_valid() | ||
| { | ||
| FILE *fp = fopen(CPE_SERVICE_STATE_FILE, "w"); | ||
| fprintf(fp, "fully-manageable\n"); | ||
| fclose(fp); |
| { | ||
| remove(CPE_SERVICE_STATE_FILE); | ||
| int fd = open(CPE_SERVICE_STATE_FILE,O_CREAT | O_WRONLY,0644); | ||
| chmod(CPE_SERVICE_STATE_FILE, 0444); /* read-only */ | ||
| write_cpe_service_state_to_file("operational"); |
8e78b8a to
ba78341
Compare
RDKB-64737 : Connectivity status metadata over Webpa