RDKB-64112: Account ID check removal from IDM#7
RDKB-64112: Account ID check removal from IDM#7veeraputhiran-thangavel wants to merge 11 commits intodevelopfrom
Conversation
Remove all accountId-based pairing restrictions so devices pair irrespective of accountId value when both run new code, and work correctly with valid accountId in mixed scenarios. Changes: - Remove while(1) blocking loop in start_discovery that waited for RFC accountId to become non-Unknown (XLE could never start discovery when RFC was not yet provisioned) - Remove digit-only validation that rejected accountIds containing non-digit characters (rejected 'Unknown') - Remove accountId match check that required peer accountId to equal own accountId (prevented XLE from being added when it returned Unknown) - Remove now-unused static accountId[] global declaration idm_server.c is unchanged. Coverage: XLE new + XB new : works for valid and Unknown accountId XLE new + XB old : works when XLE RFC accountId is valid XLE old + XB new : works when XLE RFC accountId is valid
There was a problem hiding this comment.
Pull request overview
This PR aims to remove accountId-based pairing restrictions in the IDM client so discovered devices can be associated regardless of accountId value/content.
Changes:
- Removed the local accountId retrieval/wait loop during discovery startup.
- Simplified device association logic to no longer validate/compare accountId before inserting devices into the discovered list.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetAccountId","AccountId", &temp, FALSE)) | ||
| { | ||
| int valid_account=1,loop=0; | ||
| g_message("Discovered device sent accountId as %s",temp); | ||
| for(loop=0;loop<(int)(strlen(temp));loop++) | ||
| { | ||
| if(temp[loop] < '0' || temp[loop] > '9') | ||
| { | ||
| g_message("not a valid account due to %c presence",temp[loop]); | ||
| valid_account=0; | ||
| break; | ||
| } | ||
| } | ||
| if(valid_account==1) | ||
| { | ||
| g_message("Discovered device AccountId is valid"); | ||
| if(g_strcmp0(g_strstrip(accountId),temp)==0) | ||
| { | ||
| g_mutex_lock(mutex); | ||
| xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL); | ||
| g_mutex_unlock(mutex); | ||
| g_message("Inserted new/updated device %s in the list as accountId %s is same", sno,temp); | ||
| callback(&di,1,1); | ||
| } | ||
| else | ||
| { | ||
| g_message("Not adding to the list as accountId %s is different",temp); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| g_message("Its not valid accountID so accountId %s not adding to the list",temp); | ||
| } | ||
| g_mutex_lock(mutex); | ||
| xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL); |
There was a problem hiding this comment.
Device insertion/callback is still gated by the success of the "GetAccountId" action (the list insertion and callback happen only inside the processStringRequest("GetAccountId", ...) block). This means devices that return an error / don't implement GetAccountId will never be associated, which conflicts with the PR goal of removing accountId-based pairing restrictions. Consider inserting the device (and firing the callback) regardless of GetAccountId success, and treat accountId as optional metadata (log it when available).
| if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetAccountId","AccountId", &temp, FALSE)) | ||
| { | ||
| int valid_account=1,loop=0; | ||
| g_message("Discovered device sent accountId as %s",temp); | ||
| for(loop=0;loop<(int)(strlen(temp));loop++) | ||
| { | ||
| if(temp[loop] < '0' || temp[loop] > '9') | ||
| { | ||
| g_message("not a valid account due to %c presence",temp[loop]); | ||
| valid_account=0; | ||
| break; | ||
| } | ||
| } | ||
| if(valid_account==1) | ||
| { | ||
| g_message("Discovered device AccountId is valid"); | ||
| if(g_strcmp0(g_strstrip(accountId),temp)==0) | ||
| { | ||
| g_mutex_lock(mutex); | ||
| xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL); | ||
| g_mutex_unlock(mutex); | ||
| g_message("Inserted new/updated device %s in the list as accountId %s is same", sno,temp); | ||
| callback(&di,1,1); | ||
| } | ||
| else | ||
| { | ||
| g_message("Not adding to the list as accountId %s is different",temp); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| g_message("Its not valid accountID so accountId %s not adding to the list",temp); | ||
| } | ||
| g_mutex_lock(mutex); | ||
| xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL); | ||
| g_mutex_unlock(mutex); | ||
| g_message("Associating device %s accountId=%s", sno,temp); | ||
| callback(&di,1,1); | ||
| g_free(temp); | ||
| } |
There was a problem hiding this comment.
If processStringRequest("GetAccountId", ...) returns FALSE, the newly allocated gwydata is neither inserted into xdevlist nor freed, which leaks memory. When restructuring the GetAccountId handling, also ensure gwydata is freed on all failure paths (including missing UDN/receiverid).
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Device list insertion and callback now happen regardless of whether GetAccountId succeeds, so devices that don't implement the action or return an error are still associated. When GetAccountId succeeds the accountId is logged as metadata. When it fails a diagnostic message is logged and pairing continues. This fully removes accountId-based pairing restrictions from the client side.
- New idm_log.h / idm_log.c: shared logging module for idm_client and
idm_server. Writes timestamped lines to
/rdklogs/logs/InterDeviceManager.txt.0 with RDK log format:
YYMMDD-HH:MM:SS.uuuuuu [mod=INTERDEVICEMANAGER, lvl=<LEVEL>] [tid=NNN] func line - message
- Persistent file descriptor with inode-check reopen on rdklogger rotation
- Thread-safe via pthread_mutex_t; _GNU_SOURCE guard for localtime_r/syscall
- IDM_LOG_INFO(fmt, ...) macro for INFO-level logging
- IDM_LOG_ERR(fmt, ...) macro for ERROR-level logging
- Format attribute __attribute__((format(printf, 4, 5))) for compile-time
format-string validation
- T2 telemetry: t2_event_s("IDM_DISCOVERY_STARTED_split", ...)
and t2_event_s("IDM_DEVICE_ASSOCIATED_split", ...) at key events
- Makefile.am: idm_log.c added to libupnpidm_la_SOURCES
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.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!idm_log_fp) | ||
| idm_log_fp = fopen(IDM_LOG_FILE, "a"); | ||
| return idm_log_fp; | ||
| } | ||
|
|
||
| /** | ||
| * idm_consolelog — write one timestamped log line. | ||
| * Called via the IDM_LOG_INFO() macro which supplies __func__ and __LINE__. | ||
| */ | ||
| void idm_consolelog(const char *func, int line, const char *level, | ||
| const char *fmt, ...) | ||
| { | ||
| pthread_mutex_lock(&idm_log_mutex); | ||
| FILE *out = idm_log_reopen(); | ||
| if (!out) | ||
| { | ||
| pthread_mutex_unlock(&idm_log_mutex); | ||
| return; | ||
| } |
There was a problem hiding this comment.
If fopen(IDM_LOG_FILE, "a") fails, idm_consolelog returns without emitting anything, which can silently drop important diagnostics. Consider logging the failure (including errno) via g_message/stdio fallback, and/or retrying later with backoff.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
| if (!idm_log_fp) | |
| idm_log_fp = fopen(IDM_LOG_FILE, "a"); | |
| return idm_log_fp; | |
| } | |
| /** | |
| * idm_consolelog — write one timestamped log line. | |
| * Called via the IDM_LOG_INFO() macro which supplies __func__ and __LINE__. | |
| */ | |
| void idm_consolelog(const char *func, int line, const char *level, | |
| const char *fmt, ...) | |
| { | |
| pthread_mutex_lock(&idm_log_mutex); | |
| FILE *out = idm_log_reopen(); | |
| if (!out) | |
| { | |
| pthread_mutex_unlock(&idm_log_mutex); | |
| return; | |
| } | |
| if (!idm_log_fp) | |
| idm_log_fp = fopen(IDM_LOG_FILE, "a"); | |
| return idm_log_fp; | |
| } | |
| /** | |
| * idm_consolelog — write one timestamped log line. | |
| * Called via the IDM_LOG_INFO() macro which supplies __func__ and __LINE__. | |
| */ | |
| void idm_consolelog(const char *func, int line, const char *level, | |
| const char *fmt, ...) | |
| { | |
| pthread_mutex_lock(&idm_log_mutex); | |
| FILE *out = idm_log_reopen(); | |
| if (!out) | |
| { | |
| pthread_mutex_unlock(&idm_log_mutex); | |
| return; | |
| } |
Change IDM_LOG_FILE from /rdklogs/logs/InterDeviceManager.txt.0 to /rdklogs/logs/Consolelog.txt.0 so IDM log output is consolidated into the standard console log file.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…sites Agent-Logs-Url: https://github.com/rdkcentral/secure-upnp/sessions/a0e5b975-4a9e-4407-8e68-8d5db314bb62 Co-authored-by: veeraputhiran-thangavel <224542127+veeraputhiran-thangavel@users.noreply.github.com>
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.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add IDM_LOG_ERR() alongside every existing g_message/g_critical error print so errors appear in both the GLib log (g_message) and the RDK console log (Consolelog.txt.0 via idm_log.c). Errors covered (30 call sites): - SE cert passcode retrieval failure (rdkconfig_get) - g_tls_certificate_new_from_file_with_password failure - HW cert fallback path: NULL certFile/keyFile, file not found, g_tls_certificate_new_from_files failure - Normal cert path: same three cases - GUPnP service proxy action error (processStringRequest) - gssdp_resource_browser_rescan failures (cp and cp_bgw variants) - xupnp stuck >5 minutes — all four code paths (IDM_DEBUG and production, inactive and null-count variants) - NULL cp/dproxy received in available callbacks (broadband + gateway) - Gateway receiver id NULL, UDN NULL - Memory allocation failure for GwyDeviceData - sproxy NULL on device available - Device receiver id NULL, device UDN NULL (non-broadband path) - Missing mandatory start_discovery parameters - p12 cert file creation failure - SE HW certificate not accessible - idm_server_start failure - pthread_create failure for EventHandler thread - Mandatory TLS cert files absent - GUPnP context creation failure g_message/g_critical calls are preserved unchanged.
Remove the 6 IDM_LOG_ERR calls inside the verify_devices() polling loop that fire every ~30s when gssdp is broken: - gssdp_resource_browser_rescan failed (cp and cp_bgw) - xupnp stuck >5min cp/cp_bgw inactive count threshold - xupnp stuck >5min cp/cp_bgw null count threshold These will be re-added with rate-limiting in a follow-up commit. The existing g_message calls in the same paths are left untouched. The remaining 24 IDM_LOG_ERR calls (startup / event-driven paths) carry no flooding risk and are retained.
- idm_log.c: when fopen(IDM_LOG_FILE) fails, emit a rate-limited diagnostic via stderr (once per 60 s) with errno string instead of silently dropping the message. Add <errno.h> and <string.h> includes. - idm_client.c: remove trailing \n from all 24 IDM_LOG_ERR/INFO fmt strings; idm_consolelog already appends a newline via fputc, so the extra \n was producing blank lines between log entries. Addresses Copilot review comments #1-#4 on idm_log.c/idm_log.h.
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.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * All writes go to /rdklogs/logs/Consolelog.txt.0. | ||
| * Log rotation is handled externally by rdklogger; the open file descriptor | ||
| * is transparently reopened after rotation via inode comparison. |
There was a problem hiding this comment.
The header comment says “All writes go to /rdklogs/logs/Consolelog.txt.0.”, but the implementation can also emit rate-limited diagnostics to stderr when fopen() fails (and otherwise drops the log line). Consider updating this comment to describe the stderr fallback / drop behavior so expectations match reality.
| * All writes go to /rdklogs/logs/Consolelog.txt.0. | |
| * Log rotation is handled externally by rdklogger; the open file descriptor | |
| * is transparently reopened after rotation via inode comparison. | |
| * Log lines are normally written to /rdklogs/logs/Consolelog.txt.0. | |
| * Log rotation is handled externally by rdklogger; the open file descriptor | |
| * is transparently reopened after rotation via inode comparison. If the log | |
| * file cannot be opened, the implementation may emit rate-limited diagnostics | |
| * to stderr; otherwise the attempted log line is dropped. |
The three IDM_LOG_INFO prints:
- start_discovery called for serial %s (line 927)
- device associated sno=%s (BGW path, line 732)
- device associated sno=%s (XB path, line 839)
are redundant with CcspTraceInfo prints in rdk-interdevicemanager:
- discovery start: CcspTraceInfo line 770 logs base MAC + start
- pairing: CcspTraceInfo line 378 in discovery_cb logs IPv4/IPv6/MAC/
discovery_status/authentication_status for every callback() invocation
Removing avoids duplicate entries in Consolelog.txt.0 and eliminates
the noisy self-association entries seen in field logs (MWN2983C0544
appearing as 'device associated' alongside the real XB serial).
Reason for change: Remove all accountId-based pairing restrictions so devices pair irrespective of accountId
Test Procedure:
Risks: Low
Coverage:
Signed-off-by:Veeraputhiran_Thangavel@comcast.com