diff --git a/rfcMgr/rfc_xconf_handler.cpp b/rfcMgr/rfc_xconf_handler.cpp index f695ef21..53db964d 100644 --- a/rfcMgr/rfc_xconf_handler.cpp +++ b/rfcMgr/rfc_xconf_handler.cpp @@ -56,10 +56,13 @@ int RuntimeFeatureControlProcessor:: InitializeRuntimeFeatureControlProcessor(vo return FAILURE; } + GetRFCPartnerID(); + if((filePresentCheck(RFC_PROPERTIES_PERSISTENCE_FILE) == RDK_API_SUCCESS) && (_ebuild_type != ePROD || dbgServices == true)) { rfc_file = RFC_PROPERTIES_PERSISTENCE_FILE; rfc_state = Local; + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Found Persistent file %s, Updating State %d \n", __FUNCTION__, __LINE__, rfc_file.c_str(), rfc_state); } else { @@ -88,7 +91,6 @@ int RuntimeFeatureControlProcessor:: InitializeRuntimeFeatureControlProcessor(vo } GetAccountID(); - GetRFCPartnerID(); GetOsClass(); #if !defined(RDKB_SUPPORT) @@ -191,22 +193,7 @@ bool RuntimeFeatureControlProcessor::ExecuteCommand(const std::string& command, bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configKey, const std::string& configValue, int rebootValue, bool& rfcRebootCronNeeded) { - std::string paramName; - size_t tr181Pos = configKey.find("tr181"); - - if (tr181Pos != std::string::npos) { - size_t dotPos = configKey.find(".", tr181Pos); - if (dotPos != std::string::npos) { - paramName = configKey.substr(dotPos + 1); - } - } - - if (paramName.empty()) { - return false; - } - - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "Parameter name %s\n", paramName.c_str()); - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "Parameter value %s\n", configValue.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Key:%s , Value:%s ImmediateReboot:%d \n", __FUNCTION__, __LINE__, configKey.c_str(), configValue.c_str(), rebootValue); // Initialize rbus connection rbusHandle_t rbusHandle; @@ -216,6 +203,15 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK return false; } + // Remove tr181 prefix from configKey if present (do this FIRST) + std::string paramName = configKey; + if (paramName.find("tr181.") == 0) { + paramName = paramName.substr(6); // Remove "tr181." prefix + } + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "Parameter name (after tr181 removal): %s\n", paramName.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "Parameter value: %s\n", configValue.c_str()); + // Check for WanFailOverSupportEnable std::string wanFailOverSupportEnable; rbusValue_t wfoValue = NULL; @@ -229,6 +225,7 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK rbusValue_Release(wfoValue); } + // Use paramName consistently for all special case checks if (wanFailOverSupportEnable == "true") { if (paramName == "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UPnP.Refactor.Enable" || paramName == "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Xupnp") { @@ -300,7 +297,7 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK return true; } - // Get parameter type and current value using rbus + // Get parameter type and current value using rbus (with correct parameter name) rbusValue_t paramVal = NULL; rc = rbus_get(rbusHandle, paramName.c_str(), ¶mVal); if (rc != RBUS_ERROR_SUCCESS || paramVal == NULL) { @@ -352,7 +349,7 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK std::ofstream paramFile("/tmp/.paramRFC"); if (paramFile.is_open()) { - paramFile << "name: " << paramName << "\n"; + paramFile << "name: " << paramName << "\n"; paramFile << "type: " << paramTypeStr << "\n"; paramFile << "value: " << paramValue << "\n"; paramFile.close(); @@ -366,7 +363,7 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK bool isRfcNameSpace = (paramName.find(".X_RDKCENTRAL-COM_RFC.") != std::string::npos); - if (paramValue != configValue || isRfcNameSpace) { + if (paramValue != configValue) { rbusValue_t newValue; rbusValue_Init(&newValue); @@ -398,8 +395,7 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK } } catch (const std::exception& e) { setSuccess = false; - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "Failed to convert value %s for parameter %s: %s\n", - configValue.c_str(), paramName.c_str(), e.what()); + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "Failed to convert value %s for parameter %s: %s\n", configValue.c_str(), paramName.c_str(), e.what()); } if (setSuccess) { @@ -407,19 +403,11 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK rbusValue_Release(newValue); if (rc == RBUS_ERROR_SUCCESS) { - if (isRfcNameSpace && paramValue == configValue) { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: rbus SET called for RFC namespace param: %s value=%s\n", - paramName.c_str(), configValue.c_str()); - } else { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: updated for %s from value old=%s, to new=%s\n", - paramName.c_str(), paramValue.c_str(), configValue.c_str()); - } + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: updated for %s from value old=%s, to new=%s\n", paramName.c_str(), paramValue.c_str(), configValue.c_str()); // Special handling for account ID if (paramName == RFC_ACCOUNT_ID_KEY_STR) { - std::string cmd = "t2CountNotify \"SYST_INFO_ACCID_set\""; - std::string notifyOutput; - ExecuteCommand(cmd, notifyOutput); + NotifyTelemetry2Count("SYST_INFO_ACCID_set"); } // Special handling for Syndication.PartnerId @@ -429,24 +417,72 @@ bool RuntimeFeatureControlProcessor::ParseConfigValue(const std::string& configK } } + // Only schedule reboot if values actually changed if (rebootValue == 1) { if (!rfcRebootCronNeeded) { rfcRebootCronNeeded = true; - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: Enabling RfcRebootCronNeeded since %s old value=%s, new value=%s, RebootValue=%d\n", - paramName.c_str(), paramValue.c_str(), configValue.c_str(), rebootValue); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: Enabling RfcRebootCronNeeded since %s old value=%s, new value=%s, RebootValue=%d\n", paramName.c_str(), paramValue.c_str(), configValue.c_str(), rebootValue); } } } else { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "RFC: rbus SET failed for %s with value %s: %s\n", - paramName.c_str(), configValue.c_str(), rbusError_ToString(rc)); + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "RFC: rbus SET failed for %s with value %s: %s\n", paramName.c_str(), configValue.c_str(), rbusError_ToString(rc)); + } + } else { + rbusValue_Release(newValue); + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "RFC: Failed to set value for %s due to conversion error\n", paramName.c_str()); + } + } else if (isRfcNameSpace) { + // For RFC namespace parameters, always perform rbus_set even if values are same + rbusValue_t newValue; + rbusValue_Init(&newValue); + + bool setSuccess = true; + try { + switch (paramType) { + case RBUS_STRING: + rbusValue_SetString(newValue, configValue.c_str()); + break; + case RBUS_BOOLEAN: + rbusValue_SetBoolean(newValue, (configValue == "true" || configValue == "1")); + break; + case RBUS_INT32: + rbusValue_SetInt32(newValue, std::stoi(configValue)); + break; + case RBUS_UINT32: + rbusValue_SetUInt32(newValue, std::stoul(configValue)); + break; + case RBUS_SINGLE: + rbusValue_SetSingle(newValue, std::stof(configValue)); + break; + case RBUS_DOUBLE: + rbusValue_SetDouble(newValue, std::stod(configValue)); + break; + default: + setSuccess = false; + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "Unsupported parameter type: %d\n", paramType); + break; + } + } catch (const std::exception& e) { + setSuccess = false; + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "Failed to convert value %s for parameter %s: %s\n", configValue.c_str(), paramName.c_str(), e.what()); + } + + if (setSuccess) { + rc = rbus_set(rbusHandle, paramName.c_str(), newValue, NULL); + rbusValue_Release(newValue); + + if (rc == RBUS_ERROR_SUCCESS) { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: rbus SET called for RFC namespace param: %s value=%s\n", paramName.c_str(), configValue.c_str()); + } else { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "RFC: rbus SET failed for %s with value %s: %s\n", paramName.c_str(), configValue.c_str(), rbusError_ToString(rc)); } } else { rbusValue_Release(newValue); RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "RFC: Failed to set value for %s due to conversion error\n", paramName.c_str()); } + // Note: No reboot logic for RFC namespace parameters when values are same } else { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: For param %s new and old values are same value %s\n", - paramName.c_str(), configValue.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "RFC: For param %s new and old values are same value %s\n", paramName.c_str(), configValue.c_str()); } rbus_close(rbusHandle); @@ -509,60 +545,121 @@ int RuntimeFeatureControlProcessor::ProcessJsonResponseB(char* featureXConfMsg) if (features) { int numFeatures = GetJsonArraySize(features); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Number of features to process: %d\n", __FUNCTION__, __LINE__, numFeatures); + for (int index = 0; index < numFeatures; index++) { JSON* feature = GetJsonArrayItem(features, index); - if (feature) { - RuntimeFeatureControlObject *rfcObj = new RuntimeFeatureControlObject; + if (!feature) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Failed to get feature at index %d\n", __FUNCTION__, __LINE__, index); + continue; + } - if (SUCCESS != getRFCName(feature, rfcObj)) { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Name\n", __FUNCTION__, __LINE__); - delete rfcObj; - continue; - } + RuntimeFeatureControlObject *rfcObj = new RuntimeFeatureControlObject; + if (!rfcObj) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Failed to allocate memory for RuntimeFeatureControlObject\n", __FUNCTION__, __LINE__); + continue; + } - if (SUCCESS != getRFCEnableParam(feature, rfcObj)) { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Enable Param\n", __FUNCTION__, __LINE__); - delete rfcObj; - continue; - } + if (SUCCESS != getRFCName(feature, rfcObj)) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Name\n", __FUNCTION__, __LINE__); + delete rfcObj; + continue; + } - if (SUCCESS != getEffectiveImmediateParam(feature, rfcObj)) { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Effective Immediate\n", __FUNCTION__, __LINE__); - delete rfcObj; - continue; - } + if (SUCCESS != getRFCEnableParam(feature, rfcObj)) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Enable Param\n", __FUNCTION__, __LINE__); + delete rfcObj; + continue; + } - if (SUCCESS != getFeatureInstance(feature, rfcObj)) { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] RFC Feature Instance not configured\n", __FUNCTION__, __LINE__); - } else { - std::string filename = ".RFC_" + rfcObj->name + ".ini"; - rfcList += rfcObj->featureInstance + "=true,"; - writeRemoteFeatureCntrlFile(filename, rfcObj); - } + if (SUCCESS != getEffectiveImmediateParam(feature, rfcObj)) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] JSON Parsing Failed for Feature Effective Immediate\n", __FUNCTION__, __LINE__); + delete rfcObj; + continue; + } - writeRemoteFeatureCntrlFile(VARFILE, rfcObj); - - // Special telemetry handling - if (rfcObj->name == "PeriodicFWCheck" && rfcObj->enable) { - std::string notifyCmd = "t2CountNotify \"SYS_INFO_RFC_PeriodicFWCheck\""; - std::string output; - ExecuteCommand(notifyCmd, output); - } else if (rfcObj->name == "IPv6onLnF" && rfcObj->enable) { - std::string notifyCmd = "t2CountNotify \"INFO_IPv6_LNF_Support\""; - std::string output; - ExecuteCommand(notifyCmd, output); - } + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Processing feature: %s, enabled: %s, effectiveImmediate: %s\n", + __FUNCTION__, __LINE__, rfcObj->name.c_str(), + rfcObj->enable ? "true" : "false", + rfcObj->effectiveImmediate ? "true" : "false"); - // Apply configuration if needed - std::string key = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature." + rfcObj->name + ".Enable"; - std::string value = rfcObj->enable ? "true" : "false"; - int effectiveImmediate = rfcObj->effectiveImmediate ? 1 : 0; + if (SUCCESS != getFeatureInstance(feature, rfcObj)) { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] RFC Feature Instance not configured for %s\n", __FUNCTION__, __LINE__, rfcObj->name.c_str()); + } else { + std::string filename = ".RFC_" + rfcObj->name + ".ini"; + rfcList += rfcObj->featureInstance + "=true,"; + writeRemoteFeatureCntrlFile(filename, rfcObj); + } - ParseConfigValue(key, value, effectiveImmediate, rfcRebootCronNeeded); + writeRemoteFeatureCntrlFile(VARFILE, rfcObj); + + // Process configData entries + int effectiveImmediate = rfcObj->effectiveImmediate ? 1 : 0; + char configDataStr[] = "configData"; + JSON *configData = GetJsonItem(feature, configDataStr); + if (configData) { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Processing configData for feature: %s\n", + __FUNCTION__, __LINE__, rfcObj->name.c_str()); + + // Iterate through configData child nodes (following your CreateConfigDataValueMap pattern) + JSON *child = configData->child; + int configEntryCount = 0; + while (child) { + configEntryCount++; + if (child->string && child->valuestring) { + const char* configKey = child->string; + const char* configValue = child->valuestring; + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Processing config entry %d: %s = %s (effectiveImmediate=%d)\n", + __FUNCTION__, __LINE__, configEntryCount, configKey, configValue, effectiveImmediate); + + // Extract feature name from key (6th field when split by '.') - matching shell script logic + std::string keyStr = configKey; + std::string featureName; + size_t pos = 0; + int fieldCount = 0; + while ((pos = keyStr.find('.')) != std::string::npos && fieldCount < 5) { + keyStr = keyStr.substr(pos + 1); + fieldCount++; + } + if ((pos = keyStr.find('.')) != std::string::npos) { + featureName = keyStr.substr(0, pos); + } else { + featureName = keyStr; + } + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Extracted feature name: %s from key: %s\n", + __FUNCTION__, __LINE__, featureName.c_str(), configKey); + + // Special telemetry handling for individual configData entries (matching shell script) + if (featureName == "PeriodicFWCheck" && strcmp(configValue, "true") == 0) { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Notify Telemetry for SYS_INFO_RFC_PeriodicFWCheck\n", __FUNCTION__, __LINE__); + NotifyTelemetry2Count("SYS_INFO_RFC_PeriodicFWCheck"); + } else if (featureName == "IPv6onLnF" && strcmp(configValue, "true") == 0) { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Notify Telemetry for INFO_IPv6_LNF_Support\n", __FUNCTION__, __LINE__); + NotifyTelemetry2Count("INFO_IPv6_LNF_Support"); + } + + // Use the key exactly as it appears in JSON + ParseConfigValue(std::string(configKey), std::string(configValue), effectiveImmediate, rfcRebootCronNeeded); + } else { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Invalid config key or value in configData for feature: %s (entry %d)\n", + __FUNCTION__, __LINE__, rfcObj->name.c_str(), configEntryCount); + } + child = child->next; + } - delete rfcObj; + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Processed %d config entries for feature: %s\n", + __FUNCTION__, __LINE__, configEntryCount, rfcObj->name.c_str()); + } else { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] No configData found for feature: %s\n", + __FUNCTION__, __LINE__, rfcObj->name.c_str()); } + + delete rfcObj; } + } else { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Failed to get features array from JSON\n", __FUNCTION__, __LINE__); } rc = rbus_set(rbusHandle, "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ClearDBEnd", trueVal, NULL); @@ -583,9 +680,15 @@ int RuntimeFeatureControlProcessor::ProcessJsonResponseB(char* featureXConfMsg) WriteFile(".version", _firmware_version); HandleScheduledReboot(rfcRebootCronNeeded); + FreeJson(pJson); + rbusValue_Release(falseVal); rbusValue_Release(trueVal); rbus_close(rbusHandle); + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] ProcessJsonResponseB completed successfully. Reboot needed: %s\n", + __FUNCTION__, __LINE__, rfcRebootCronNeeded ? "true" : "false"); + return SUCCESS; } @@ -840,10 +943,16 @@ int RuntimeFeatureControlProcessor::GetExperience( void ) } if( !*tempbuf ) // we got nothing back, "X1" is default { - *tempbuf = 'X'; - *(tempbuf + 1) = '1'; - *(tempbuf + 2) = 0; - i=3; +#ifdef RDKB_SUPPORT + *tempbuf = 0; + i = 0; +#else + // we got nothing back, "X1" is default in video + *tempbuf = 'X'; + *(tempbuf + 1) = '1'; + *(tempbuf + 2) = 0; + i=3; +#endif } _experience = tempbuf; @@ -1510,14 +1619,24 @@ std::stringstream RuntimeFeatureControlProcessor::CreateXconfHTTPUrl() url << "firmwareVersion=" << _firmware_version << "&"; url << "env=" << _build_type_str << "&"; url << "model=" << _model_number << "&"; - url << "manufacturer=" << _manufacturer << "&"; +#if defined(RDKB_SUPPORT) + url << "ecmMacAddress=" << _ecm_mac_address << "&"; +#else + url << "manufacturer=" << _manufacturer << "&"; +#endif url << "controllerId=" << RFC_VIDEO_CONTROL_ID << "&"; url << "channelMapId=" << RFC_CHANNEL_MAP_ID << "&"; url << "VodId=" << RFC_VIDEO_VOD_ID << "&"; url << "partnerId=" << _partner_id << "&"; - url << "osClass=" << _osclass << "&"; +#if !defined(RDKB_SUPPORT) + url << "osClass=" << _osclass << "&"; +#endif url << "accountId=" << _accountId << "&"; - url << "Experience=" << _experience << "&"; +#if defined(RDKB_SUPPORT) + url << "experience=" << _experience << "&"; +#else + url << "Experience=" << _experience << "&"; +#endif url << "version=" << 2; #ifndef URLENCODING_DISABLED @@ -1528,16 +1647,26 @@ std::stringstream RuntimeFeatureControlProcessor::CreateXconfHTTPUrl() EncodeString("firmwareVersion=", _firmware_version, encodedUrl, "&"); EncodeString("env=", _build_type_str, encodedUrl, "&"); EncodeString("model=", _model_number, encodedUrl, "&"); - EncodeString("manufacturer=", _manufacturer, encodedUrl, "&"); +#if defined(RDKB_SUPPORT) + EncodeString("ecmMacAddress=", _ecm_mac_address, encodedUrl, "&"); +#else + EncodeString("manufacturer=", _manufacturer, encodedUrl, "&"); +#endif encodedUrl << "controllerId=" << RFC_VIDEO_CONTROL_ID << "&"; encodedUrl << "channelMapId=" << RFC_CHANNEL_MAP_ID << "&"; encodedUrl << "VodId=" << RFC_VIDEO_VOD_ID << "&"; EncodeString("partnerId=", _partner_id, encodedUrl, "&"); - EncodeString("osClass=", _osclass, encodedUrl, "&"); +#if !defined(RDKB_SUPPORT) + EncodeString("osClass=", _osclass, encodedUrl, "&"); +#endif EncodeString("accountId=", _accountId, encodedUrl, "&"); +#if !defined(RDKB_SUPPORT) EncodeString("Experience=", _experience, encodedUrl, "&"); +#else + EncodeString("experience=", _experience, encodedUrl, "&"); +#endif encodedUrl << "version=2"; RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] Encoding is enabled plain URL: %s\n", __FUNCTION__, __LINE__, url.str().c_str()); diff --git a/rfcMgr/xconf_handler.cpp b/rfcMgr/xconf_handler.cpp index 377cf2e7..6c345a97 100644 --- a/rfcMgr/xconf_handler.cpp +++ b/rfcMgr/xconf_handler.cpp @@ -66,6 +66,45 @@ std::string getErouterMac() return erouterMac; } +std::string geteCMMac() +{ + std::string macAddress; + + // Array of commands to try in order + const char* commands[] = { + "dmcli eRT retv Device.DPoE.Mac_address", + "dmcli eRT retv Device.X_CISCO_COM_CableModem.MACAddress", + "dmcli eRT retv Device.DeviceInfo.X_COMCAST-COM_CM_MAC", + "dmcli eRT retv Device.DeviceInfo.X_-COM_WAN_MAC", + "sysevent get eth_wan_mac" + }; + + // Try each command until we get a valid MAC address + for (const auto& command : commands) { + FILE* pipe = popen(command, "r"); + if (pipe) { + char buffer[128] = {0}; + if (fgets(buffer, sizeof(buffer), pipe) != nullptr) { + macAddress = buffer; + // Trim trailing newline + if (!macAddress.empty() && macAddress.back() == '\n') { + macAddress.pop_back(); + } + pclose(pipe); + + // If we got a non-empty result, return it + if (!macAddress.empty()) { + break; + } + } else { + pclose(pipe); + } + } + } + + return macAddress; +} + int XconfHandler:: initializeXconfHandler() { char tmpbuf[200] = {0}; @@ -109,7 +148,19 @@ int XconfHandler:: initializeXconfHandler() _model_number = tmpbuf; } -#if !defined(RDKB_SUPPORT) +#if defined(RDKB_SUPPORT) + memset(tmpbuf, '\0', sizeof(tmpbuf)); + std::string cmmac = geteCMMac(); + if (!cmmac.empty()) { + strncpy(tmpbuf, cmmac.c_str(), sizeof(tmpbuf) - 1); + tmpbuf[sizeof(tmpbuf) - 1] = '\0'; + len = strlen(tmpbuf); + } + if( len ) + { + _ecm_mac_address = tmpbuf; + } +#else memset(tmpbuf, '\0', sizeof(tmpbuf)); len = GetMFRName( tmpbuf, sizeof(tmpbuf) ); if( len ) @@ -136,3 +187,4 @@ int XconfHandler:: initializeXconfHandler() } #endif + diff --git a/rfcMgr/xconf_handler.h b/rfcMgr/xconf_handler.h index 77c4b381..f7e52ac2 100644 --- a/rfcMgr/xconf_handler.h +++ b/rfcMgr/xconf_handler.h @@ -54,6 +54,7 @@ namespace xconf { std::string _build_type_str; std::string _model_number; /* Device Model Number */ std::string _manufacturer; /* Device Manufacturer */ + std::string _ecm_mac_address; /* Cable Modem Mac Address*/ std::string _partner_id; /* Device Partner ID */ int ExecuteRequest(FileDwnl_t *file_dwnl, MtlsAuth_t *security, int *httpCode); };