RDKB-64152 : Add debug logs of Eth client details retrieved from HAL#55
RDKB-64152 : Add debug logs of Eth client details retrieved from HAL#55suriya-prem wants to merge 36 commits intodevelopfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds additional debug-level logging around Ethernet client/device details obtained from the HAL, to aid field debugging for RDKB-64152.
Changes:
- Add debug dumps of associated Ethernet device details (MAC/port/VLAN/rates/active) in multiple Ethernet logging/telemetry paths.
- Add additional debug tracing inside the HAL associated-device monitor thread.
- Change some existing Ethernet host log markers from warning-level to debug-level.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
source/TR-181/middle_layer_src/cosa_ethernet_internal.c |
Adds debug dumps of associated devices and changes existing ETH_MAC_* / ETH_PHYRATE_* markers to debug. |
source/TR-181/board_sbapi/source-arm/cosa_ethernet_apis_arm.c |
Adds debug dumps of associated devices after retrieving them from HAL. |
source/TR-181/board_sbapi/eth_hal_interface.c |
Adds debug tracing throughout the associated-device monitor thread, including per-device detail logs. |
source/TR-181/board_sbapi/cosa_ethernet_apis.c |
Adds debug dump of device details in the associated-device callback path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (eth_dev != NULL) { | ||
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | ||
| eth_dev->eth_devMacAddress[0], eth_dev->eth_devMacAddress[1], eth_dev->eth_devMacAddress[2], eth_dev->eth_devMacAddress[3], | ||
| eth_dev->eth_devMacAddress[4], eth_dev->eth_devMacAddress[5], eth_dev->eth_port, eth_dev->eth_vlanid, eth_dev->eth_devTxRate, | ||
| eth_dev->eth_devRxRate, eth_dev->eth_Active ? "TRUE" : "FALSE")); | ||
| } | ||
|
|
||
| AnscCopyMemory(Eth_Host.eth_macAddr,eth_dev->eth_devMacAddress,6); | ||
| Eth_Host.eth_Active = eth_dev->eth_Active; | ||
| Eth_Host.eth_port = eth_dev->eth_port; |
There was a problem hiding this comment.
In CosaDmlEth_AssociatedDevice_callback, the added NULL check is ineffective: eth_dev is dereferenced before the check (e.g., when building mac_id) and it is still dereferenced after the check (AnscCopyMemory / field accesses). If eth_dev can ever be NULL, this will still crash; if it can’t, the check should be removed to avoid misleading readers. Consider adding an early guard at the top (before any dereference) and returning failure when eth_dev == NULL (or keep behavior unchanged and drop the check).
| bProcessFurther = FALSE; | ||
| } | ||
|
|
||
| CcspTraceDebug(("%s:%d bProcessFurther:%d, ulTotalEthDeviceCount:%ld, isDeleteAllDone:%d\n", |
There was a problem hiding this comment.
This debug log uses %ld to print ulTotalEthDeviceCount, which is declared as ULONG (unsigned long) in this function. Using the wrong signed format specifier can produce incorrect output and is undefined behavior on some platforms. Switch to %lu (or cast and use the matching specifier) for ulTotalEthDeviceCount.
| CcspTraceDebug(("%s:%d bProcessFurther:%d, ulTotalEthDeviceCount:%ld, isDeleteAllDone:%d\n", | |
| CcspTraceDebug(("%s:%d bProcessFurther:%d, ulTotalEthDeviceCount:%lu, isDeleteAllDone:%d\n", |
| count_client = ethGetClientsCount(i, total_eth_device, output_struct); | ||
| CcspTraceWarning(("ETH_MAC_%d_TOTAL_COUNT:%d\n", i, count_client)); | ||
| CcspTraceDebug(("ETH_MAC_%d_TOTAL_COUNT:%d\n", i, count_client)); | ||
| if (count_client) |
There was a problem hiding this comment.
These ETH_MAC_* / ETH_PHYRATE_* logs were changed from CcspTraceWarning to CcspTraceDebug, which reduces default visibility and can break any existing log-scraping/telemetry that depends on warning-level markers. If the goal is to add debug detail, consider keeping the existing warning logs and adding separate debug logs instead of changing the level.
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", | ||
| __FUNCTION__, pstRecvEthDevice[iLoopCount].eth_devMacAddress[0], | ||
| pstRecvEthDevice[iLoopCount].eth_devMacAddress[1], pstRecvEthDevice[iLoopCount].eth_devMacAddress[2], | ||
| pstRecvEthDevice[iLoopCount].eth_devMacAddress[3], pstRecvEthDevice[iLoopCount].eth_devMacAddress[4], | ||
| pstRecvEthDevice[iLoopCount].eth_devMacAddress[5], pstRecvEthDevice[iLoopCount].eth_port, | ||
| pstRecvEthDevice[iLoopCount].eth_vlanid, pstRecvEthDevice[iLoopCount].eth_devTxRate, | ||
| pstRecvEthDevice[iLoopCount].eth_devRxRate, pstRecvEthDevice[iLoopCount].eth_Active ? "TRUE" : "FALSE")); |
There was a problem hiding this comment.
These new debug logs emit full client MAC addresses (and port/VLAN/rate metadata). Even at debug level, this increases exposure of potentially sensitive identifiers and can generate high-volume PII in logs when enabled. Consider masking/hashing MACs (e.g., only last 3 bytes) or gating this behind a dedicated runtime flag/build option used specifically for debugging.
| mac_id, | ||
| (eth_dev->eth_Active) ? "Connected" : "Disconnected" )); | ||
|
|
||
| if (eth_dev != NULL) { |
There was a problem hiding this comment.
Coverity issue no longer present as of: undefined
Show issue
Coverity Issue - Dereference before null check
Null-checking "eth_dev" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
Medium Impact, CWE-476
REVERSE_INULL
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
source/TR-181/board_sbapi/cosa_ethernet_apis.c:872
- The added
if (eth_dev != NULL)only guards the new debug log, but the function still unconditionally dereferenceseth_devimmediately afterwards (e.g., insprintf(...)). Either treat NULL as impossible and remove the check, or if NULL is possible, return an error early to avoid a NULL dereference.
if (eth_dev != NULL) {
CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__,
eth_dev->eth_devMacAddress[0], eth_dev->eth_devMacAddress[1], eth_dev->eth_devMacAddress[2], eth_dev->eth_devMacAddress[3],
eth_dev->eth_devMacAddress[4], eth_dev->eth_devMacAddress[5], eth_dev->eth_port, eth_dev->eth_vlanid, eth_dev->eth_devTxRate,
eth_dev->eth_devRxRate, eth_dev->eth_Active ? "TRUE" : "FALSE"));
}
sprintf
(
mac_id,
"%02X:%02X:%02X:%02X:%02X:%02X",
eth_dev->eth_devMacAddress[0],
eth_dev->eth_devMacAddress[1],
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CcspTraceDebug(("%s:total_eth_device : %lu\n", __FUNCTION__, total_eth_device)); | ||
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | ||
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | ||
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | ||
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | ||
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | ||
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | ||
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
The new debug loop dereferences output_struct[iLoopCount] without checking output_struct is non-NULL. Previously this function could tolerate output_struct == NULL (helpers guard against it), but this log will crash if HAL ever returns success with a NULL pointer. Add a guard (e.g., if (output_struct && total_eth_device > 0)) around the per-device debug dump or ensure the HAL contract guarantees non-NULL when total_eth_device > 0.
| CcspTraceDebug(("%s:total_eth_device : %lu\n", __FUNCTION__, total_eth_device)); | |
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | |
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | |
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | |
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | |
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | |
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | |
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | |
| } | |
| if (output_struct && total_eth_device > 0) | |
| { | |
| CcspTraceDebug(("%s:total_eth_device : %lu\n", __FUNCTION__, total_eth_device)); | |
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) | |
| { | |
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | |
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | |
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | |
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | |
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | |
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | |
| } | |
| } | |
| CcspTraceDebug(("%s:total_eth_device : %lu\n", __FUNCTION__, total_eth_device)); | ||
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | ||
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | ||
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | ||
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | ||
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | ||
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | ||
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | ||
| } |
There was a problem hiding this comment.
Same as in Ethernet_Log(): this new debug loop unconditionally dereferences output_struct[iLoopCount]. If CcspHalExtSw_getAssociatedDevice can ever return success with output_struct == NULL, this will crash. Please guard the dump with if (output_struct && total_eth_device > 0) (or otherwise enforce the non-NULL contract).
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | ||
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | ||
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | ||
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | ||
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | ||
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | ||
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); |
There was a problem hiding this comment.
This new debug dump iterates and dereferences output_struct[iLoopCount] without checking output_struct is non-NULL. Prior logic only passed the pointer into helpers that guard against NULL, so this introduces a possible crash if HAL returns success with a NULL array pointer. Add a NULL guard (or enforce the HAL contract) before iterating.
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | |
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | |
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | |
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | |
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | |
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | |
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | |
| if (output_struct != NULL) | |
| { | |
| for (int iLoopCount = 0; iLoopCount < (int) total_eth_device; iLoopCount++) { | |
| CcspTraceDebug(("%s: MAC Address : %02X:%02X:%02X:%02X:%02X:%02X, Port:%d, VLAN ID:%d, TX Rate:%d, RX Rate:%d, Active:%s\n", __FUNCTION__, | |
| output_struct[iLoopCount].eth_devMacAddress[0], output_struct[iLoopCount].eth_devMacAddress[1], | |
| output_struct[iLoopCount].eth_devMacAddress[2], output_struct[iLoopCount].eth_devMacAddress[3], | |
| output_struct[iLoopCount].eth_devMacAddress[4], output_struct[iLoopCount].eth_devMacAddress[5], | |
| output_struct[iLoopCount].eth_port, output_struct[iLoopCount].eth_vlanid, output_struct[iLoopCount].eth_devTxRate, | |
| output_struct[iLoopCount].eth_devRxRate, output_struct[iLoopCount].eth_Active ? "TRUE" : "FALSE")); | |
| } |
| eth_dev->eth_devRxRate, eth_dev->eth_Active ? "TRUE" : "FALSE")); | ||
| } | ||
|
|
||
| sprintf |
There was a problem hiding this comment.
Coverity issue no longer present as of: undefined
Show issue
Coverity Issue - Dereference after null check
Dereferencing null pointer "eth_dev".
Medium Impact, CWE-476
FORWARD_NULL
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| { | ||
| CcspTraceDebug(("%s:%d Entered to create a thread\n", __FUNCTION__, __LINE__)); | ||
| AssociatedDevice_callback = callback_proc; | ||
| pthread_t GetAssociatedDeviceThread; | ||
| pthread_create(&GetAssociatedDeviceThread, NULL, &CcspHalExtSw_AssociatedDeviceMonitorThread, NULL); |
There was a problem hiding this comment.
The monitoring thread is created but the pthread_create() return value is not checked, and the thread is neither detached nor joined. Since the thread runs indefinitely, leaving it joinable can leak thread resources and makes failures silent. Consider checking pthread_create()'s return code and detaching the thread (or storing the handle for a later join).
| mac_id, | ||
| (eth_dev->eth_Active) ? "Connected" : "Disconnected" )); | ||
|
|
||
There was a problem hiding this comment.
This line contains a stray tab on an otherwise blank line. Please remove trailing whitespace to avoid noise in diffs and potential style/lint failures.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| mac_id, | ||
| (eth_dev->eth_Active) ? "Connected" : "Disconnected" )); | ||
|
|
||
There was a problem hiding this comment.
There is a blank line containing a tab character after the log statement. Trailing whitespace can cause noisy diffs and may fail whitespace/lint checks; please remove the tab so this is a truly empty line.
| CcspTraceDebug(("%s:%d Entered to monitor thread\n", __FUNCTION__, __LINE__)); | ||
| //Monitor Associated Devices based on periodical time |
There was a problem hiding this comment.
The new debug messages use awkward phrasing (e.g., "Entered to monitor thread" / "Entered to create a thread"). Consider rewording for clarity so logs are easier to scan (e.g., "Entered monitor thread" and "Creating monitor thread").
| void CcspHalExtSw_ethAssociatedDevice_callback_register(CcspHalExtSw_ethAssociatedDevice_callback callback_proc) | ||
| { | ||
| { | ||
| CcspTraceDebug(("%s:%d Entered to create a thread\n", __FUNCTION__, __LINE__)); |
There was a problem hiding this comment.
The debug log added in the callback register function uses awkward phrasing ("Entered to create a thread"). Consider rewording for clarity (e.g., "Creating monitor thread").
| CcspTraceDebug(("%s:%d Entered to create a thread\n", __FUNCTION__, __LINE__)); | |
| CcspTraceDebug(("%s:%d Creating monitor thread\n", __FUNCTION__, __LINE__)); |
RDKB-64152 : Add debug logs of Eth client details from HAL
Reason for change: For debugging purpose
Test Procedure: Change log level to debug for getting newly logs.
Risks: Low
Signed-off-by:Suriyanarayanan_MP@comcast.com