diff --git a/CHANGELOG.md b/CHANGELOG.md index a04f17b60..0b1a0f949 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,41 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.4.2](https://github.com/rdkcentral/tr69hostif/compare/1.4.1...1.4.2) + +- RDK-59998 : Remove getprofiledata dml from hostif [`#455`](https://github.com/rdkcentral/tr69hostif/pull/455) +- Update workflow for the partner Defaults usage [`#451`](https://github.com/rdkcentral/tr69hostif/pull/451) +- RDKEMW-15141 Update the Missing Coverity Reports Fixes [`#441`](https://github.com/rdkcentral/tr69hostif/pull/441) +- Merge tag '1.4.1' into develop [`7005cc7`](https://github.com/rdkcentral/tr69hostif/commit/7005cc788d3a55b18928a7228bffb42a31f61211) + +#### [1.4.1](https://github.com/rdkcentral/tr69hostif/compare/1.4.0...1.4.1) + +> 8 April 2026 + +- RDKEMW-15041: Add RFC Handlers for meminsight RFC [`#426`](https://github.com/rdkcentral/tr69hostif/pull/426) +- tr69hostif 1.4.1 release changelog updates [`16fb130`](https://github.com/rdkcentral/tr69hostif/commit/16fb1306008950273f9cfcf65be958641a0e008a) +- Merge tag '1.4.0' into develop [`fe37481`](https://github.com/rdkcentral/tr69hostif/commit/fe374814ab61d33d3dcd23581eef526c9f467a3d) + +#### [1.4.0](https://github.com/rdkcentral/tr69hostif/compare/1.3.9...1.4.0) + +> 3 April 2026 + +- Added Workflow for the JSON parse logic [`#444`](https://github.com/rdkcentral/tr69hostif/pull/444) +- RDKEMW-10029 : Syncing of Gerrit commits that are required for security components [`#440`](https://github.com/rdkcentral/tr69hostif/pull/440) +- Rebase with Develop [`#439`](https://github.com/rdkcentral/tr69hostif/pull/439) +- tr69hostif 1.4.0 release changelog updates [`1c76955`](https://github.com/rdkcentral/tr69hostif/commit/1c76955b93fa406a3c35e66ffe5b01e41bbfe6ba) +- Merge tag '1.3.9' into develop [`172808d`](https://github.com/rdkcentral/tr69hostif/commit/172808d7d26343a6a7142dae366749e71f846b7c) +- RDKEMW-10029: Remove duplicate RedRecovery parameter [`20db7b3`](https://github.com/rdkcentral/tr69hostif/commit/20db7b3f884dd200b6d67db41d139999d80ab567) + #### [1.3.9](https://github.com/rdkcentral/tr69hostif/compare/1.3.8...1.3.9) +> 1 April 2026 + - Add rrd enable default value to false [`#443`](https://github.com/rdkcentral/tr69hostif/pull/443) - tr69hostif: Add Document for L2 Coverage and Thunder Plugin details [`#442`](https://github.com/rdkcentral/tr69hostif/pull/442) - RDKEMW-15382 Crash observed in hostif [`#427`](https://github.com/rdkcentral/tr69hostif/pull/427) - tr69hostif - Updated Runtime Dependencies and JSON usage [`#437`](https://github.com/rdkcentral/tr69hostif/pull/437) +- tr69hostif 1.3.9 release changelog updates [`672754a`](https://github.com/rdkcentral/tr69hostif/commit/672754a347a5cc1b259e449c6e73cc8912842126) - Merge tag '1.3.8' into develop [`1b5fe07`](https://github.com/rdkcentral/tr69hostif/commit/1b5fe07477da9823ec145a667ec7b3029f019961) #### [1.3.8](https://github.com/rdkcentral/tr69hostif/compare/1.3.7...1.3.8) diff --git a/docs/api/thunder-plugin-interfaces.md b/docs/api/thunder-plugin-interfaces.md index 92f87783a..7768605bb 100644 --- a/docs/api/thunder-plugin-interfaces.md +++ b/docs/api/thunder-plugin-interfaces.md @@ -24,6 +24,116 @@ flowchart LR F --> A ``` +## Current Handler Workflow and Parse Logic + +The current implementation centralizes only the HTTP transport in `getJsonRPCData()`. Each +handler still constructs its own JSON-RPC request body, parses the raw response with `cJSON`, +walks the response tree, validates result fields, and maps those fields into `HOSTIF_MsgData_t`. + +```mermaid +flowchart TD + A[TR-181 GET or SET handler] --> B[Build JSON-RPC request string inline] + B --> C[getJsonRPCData in hostIf_utils.cpp] + C --> D[get_security_token] + D --> E[WPEFrameworkSecurityUtility] + C --> F[libcurl POST to /jsonrpc] + F --> G[Thunder plugin org.rdk.*] + G --> H[Raw JSON response string] + H --> I[cJSON_Parse inside handler] + I --> J[result lookup] + J --> K[field lookup and type checks] + K --> L[Convert to TR-181 output type] + L --> M[Populate HOSTIF_MsgData_t] + + I -. duplicated across handlers .-> N[Repeated parse/validation code] + K -. inconsistent checks .-> N +``` + +### Parse Flow Seen in Current Code + +Representative handlers follow the same pattern: + +1. Build a JSON string inline for a specific method call. +2. Call `getJsonRPCData()` to get a raw response buffer. +3. Parse the response with `cJSON_Parse(response.c_str())`. +4. Read `result` and then one or more nested keys such as `interfaces`, `enabled`, `ssid`, `strength`, `ipaddress`, or `success`. +5. Convert the extracted field into TR-181 output storage. + +This pattern is present in multiple places, including: + +- [src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp](../../src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp) +- [src/hostif/profiles/wifi/Device_WiFi.cpp](../../src/hostif/profiles/wifi/Device_WiFi.cpp) +- [src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp](../../src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp) +- [src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp](../../src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp) +- [src/hostif/profiles/wifi/Device_WiFi_SSID.cpp](../../src/hostif/profiles/wifi/Device_WiFi_SSID.cpp) + +### Review of Current Implementation + +The refactor proposal is valid and should be pursued. The code already shows that the problem is +not the transport alone, but the handler-local parsing contract. + +Key observations from the current implementation: + +- `getJsonRPCData()` already centralizes token retrieval, headers, timeout setup, and `curl_easy_perform()`. +- The current curl write callback is also part of the transport contract and should be normalized during the refactor, so the common helper owns response buffering with the expected libcurl callback shape. +- Response parsing is duplicated per handler, so fixes to JSON validation have to be repeated in many files. +- Some handlers use weak response checks such as `if(response.c_str())`, which is always non-null for a `std::string`; the real intent should be an emptiness check. +- Field validation is inconsistent. Some handlers validate array/object/string types carefully, while others dereference `cJSON` members with minimal checking. +- JSON-RPC error payload handling is not centralized. Callers mostly look only for `result`, with no shared handling for an `error` object or malformed schema. +- Request construction is duplicated as raw string concatenation, which makes method-specific bugs harder to audit. + +### Recommended Common Helper Direction + +The next step should be to extend [src/hostif/src/hostIf_utils.cpp](../../src/hostif/src/hostIf_utils.cpp) with a common Thunder helper layer that owns both transport and response validation. + +Suggested split: + +- `invokeThunderJsonRpc(method, params, responseRoot)` + Returns parsed root JSON after curl, HTTP, and top-level JSON-RPC validation. +- `getThunderResultObject(root)` + Returns validated `result` object or reports JSON-RPC `error` details. +- Typed extractors such as `readThunderString`, `readThunderBool`, `readThunderInt`, `readThunderArrayItemByKey` + Eliminate repeated field/type checks in handlers. + +```mermaid +flowchart TD + A[TR-181 handler] --> B[Common Thunder helper API] + B --> C[Build request object] + C --> D[getJsonRPCData or successor transport helper] + D --> E[libcurl + token + timeouts] + E --> F[Thunder JSON-RPC endpoint] + F --> G[Raw response] + G --> H[Central cJSON_Parse] + H --> I[Central JSON-RPC validation] + I --> J[Central result extraction] + J --> K[Typed field extractor] + K --> L[Handler receives validated value] + L --> M[Populate HOSTIF_MsgData_t] + + I --> N[Shared error logging] + K --> O[Consistent type checks] +``` + +### Expected Benefits of Centralizing Parse Logic + +- One implementation of timeout, HTTP status, JSON parse failure, and JSON-RPC error handling. +- Consistent empty-response and missing-field behavior across all Thunder-backed TR-181 parameters. +- Less duplicate code in handlers, especially for Wi-Fi and DeviceInfo parameters. +- Easier unit testing of success, malformed JSON, missing `result`, missing field, and wrong-type scenarios. +- Lower risk of handler-specific parsing bugs when new Thunder methods are added. + +### Recommended Refactor Scope + +Prioritize the highest-duplication handlers first: + +1. `org.rdk.NetworkManager.GetAvailableInterfaces` +2. `org.rdk.NetworkManager.GetConnectedSSID` +3. `org.rdk.NetworkManager.GetIPSettings` +4. `org.rdk.Account.getLastCheckoutResetTime` +5. `org.rdk.AuthService.*` + +These methods account for most of the repeated request/parse logic in the current codebase. + ## Request/Response Infrastructure ### Endpoint diff --git a/docs/architecture/partner-defaults-workflow.md b/docs/architecture/partner-defaults-workflow.md new file mode 100644 index 000000000..90d057767 --- /dev/null +++ b/docs/architecture/partner-defaults-workflow.md @@ -0,0 +1,374 @@ +# Partner Defaults Workflow + +## Overview + +`tr69hostif` resolves partner-specific bootstrap defaults through `XBSStore`, which loads JSON defaults from `partners_defaults.json`, merges any device-specific additions from `partners_defaults_device.json`, overlays persisted bootstrap overrides, and reloads when PartnerId becomes available later in boot. + +This workflow exists because the daemon may start before AuthService has written the runtime PartnerId. In that early-boot window, the code intentionally uses a reduced `default_boot` section. Once the actual PartnerId is discovered, the store reloads and switches to either the matching partner section or the generic `default` section. + +## Architecture + +### Component Diagram + +```mermaid +flowchart TB + START[tr69hostif startup] --> BS[XBSStore::getInstance] + BS --> INI[/opt/secure/RFC/bootstrap ini or tr181store cache/] + BS --> JSON[/etc/partners_defaults.json/] + BS --> JSONDEV[/etc/partners_defaults_device.json/] + BS --> PID[PartnerId lookup] + PID --> AUTH[/opt/www/authService/partnerId3.dat/] + PID --> BSI[/opt/secure/RFC/bootstrap.ini/] + + PID --> DECIDE{PartnerId available?} + DECIDE -->|No| BOOT[Use default_boot] + DECIDE -->|Yes, matching section| PARTNER[Use partner section] + DECIDE -->|Yes, no match| DEF[Use default] + + BOOT --> MERGE[Merge device-specific defaults] + PARTNER --> MERGE + DEF --> MERGE + + MERGE --> STORE[In-memory bootstrap map] + STORE --> GET[GET Device.* bootstrap params] + STORE --> SET[Persisted overrides and journal] + + WATCH[PartnerId watcher thread] --> RELOAD[Reload on PartnerId change] + RELOAD --> PID +``` + +## Key Components + +### `XBSStore` + +`XBSStore` owns bootstrap default resolution, in-memory storage, persisted override handling, and the PartnerId monitoring thread. The startup path is implemented in `XBSStore::getInstance()`, `init()`, `loadBSPropertiesIntoCache()`, and `loadFromJson()`. + +### `partners_defaults.json` + +This file contains the generic and per-partner bootstrap defaults. The current layout includes at least these top-level sections: + +- `default_boot` for early-boot fallback values +- `default` for generic steady-state defaults when a resolved partner block is unavailable +- one or more partner-specific sections such as `community` + +### `partners_defaults_device.json` + +If present, this file overlays device-specific values on top of the selected partner configuration. Existing keys are replaced; missing keys are appended. + +### PartnerId sources + +The store resolves PartnerId in this order: + +1. `/opt/www/authService/partnerId3.dat` +2. `/opt/secure/RFC/bootstrap.ini` + +If neither source yields a value during startup, the code falls back to `default_boot`. + +## Workflow Phases + +### 1. Startup Cache Load + +At startup, `XBSStore::getInstance()` constructs the singleton, loads any persisted bootstrap values from disk, then calls `loadFromJson()` to apply firmware defaults. + +Persisted values are read before JSON defaults so the store can preserve runtime overrides and remove only stale firmware-default entries during a firmware update. + +### 2. PartnerId Resolution + +`loadFromJson()` calls `hostIf_DeviceInfo::get_PartnerId_From_Script()` to resolve the current PartnerId. + +Possible outcomes: + +1. PartnerId is available and matches a JSON section: use that section. +2. PartnerId is available but no matching section exists: fall back to `default`. +3. PartnerId is not available yet: fall back to `default_boot`. + +This is the key distinction between `default_boot` and `default`: + +- `default_boot` is a temporary early-boot profile used only when PartnerId is not yet known. +- `default` is the generic steady-state fallback used after PartnerId resolution when the partner block is missing. + +### 3. Device-Specific Overlay + +After selecting the base configuration, `getPartnerDeviceConfig()` optionally reads `partners_defaults_device.json` and merges those entries into the chosen partner object. + +Overlay rules: + +1. If a key already exists in the selected base object, the device-specific file replaces it. +2. If a key does not exist, the device-specific file adds it. +3. If the device-specific file does not exist, startup continues without error. + +### 4. Store Population + +The merged JSON object is iterated and each key-value pair is written into the in-memory bootstrap map through `setRawValue(..., HOSTIF_SRC_DEFAULT)`. + +During this phase, the code also: + +1. marks initial update state when the persistent bootstrap file does not yet exist +2. removes obsolete firmware-default entries that disappeared from the new JSON but were not overridden by RFC or WebPA +3. updates journal state through `XBSStoreJournal` + +### 5. Runtime Reload When PartnerId Appears + +After singleton creation, `XBSStore` starts a detached watcher thread that monitors `/opt/www/authService/partnerId3.dat` with `inotify`. + +When the file is created or modified: + +1. the thread re-reads PartnerId +2. compares it to the stored PartnerId value +3. updates the PartnerId bootstrap entry if it changed +4. calls `loadFromJson()` again to rebuild defaults using the resolved partner section + +This is how the daemon transitions from `default_boot` to the partner-specific or `default` steady-state configuration. + +## Sequence Diagram + +```mermaid +sequenceDiagram + participant Main as tr69hostif startup + participant BS as XBSStore + participant PID as PartnerId lookup + participant JSON as partners_defaults.json + participant DEV as partners_defaults_device.json + participant Watch as PartnerId watcher + + Main->>BS: getInstance() + BS->>BS: load cached bootstrap overrides + BS->>PID: get_PartnerId_From_Script() + + alt PartnerId unavailable + PID-->>BS: empty + BS->>JSON: load default_boot + else PartnerId section exists + PID-->>BS: partner name + BS->>JSON: load partner section + else PartnerId missing in JSON + PID-->>BS: partner name + BS->>JSON: load default + end + + BS->>DEV: merge device-specific overrides + BS->>BS: populate in-memory map + BS-->>Main: bootstrap values ready + + Main->>Watch: start detached monitor thread + Watch->>PID: wait for partnerId3.dat update + PID-->>Watch: new PartnerId + Watch->>BS: loadFromJson() + BS->>JSON: reload partner or default section +``` + +## Threading Model + +The partner-defaults workflow uses two execution contexts: + +| Context | Purpose | Notes | +|---------|---------|-------| +| Startup thread | Initial bootstrap load | Runs during singleton initialization | +| Detached PartnerId watcher thread | Watches for `partnerId3.dat` creation or modification | Calls `loadFromJson()` again when PartnerId changes | + +Synchronization notes: + +1. `XBSStore` uses a recursive mutex around store access and reload operations. +2. The watcher thread updates the in-memory store only after detecting a changed PartnerId. +3. `default_boot` is intentionally temporary and may be replaced later in the same process lifetime. + +## Memory And Persistence Model + +### Ownership + +1. JSON objects parsed with `cJSON` are temporary and released after reload completes. +2. Effective bootstrap values are copied into the in-memory dictionary. +3. Persisted runtime overrides remain on disk and survive daemon restart. + +### Persistence Layers + +Effective value precedence for bootstrap-backed parameters is: + +1. persisted RFC or WebPA override +2. device-specific overlay from `partners_defaults_device.json` when present +3. selected partner default from `partners_defaults.json` + +Operationally, the JSON files provide firmware defaults, while runtime changes are kept in the bootstrap store and journal under `/opt/secure/RFC/`. + +### How `bootstrap.ini` Is Created And Updated + +The bootstrap store file is owned by `tr69hostif` itself. The file path is obtained from `/etc/rfc.properties` through the `BS_STORE_FILENAME` property, and in the current environment that path resolves to `/opt/secure/RFC/bootstrap.ini`. + +The creation and update flow is: + +1. `XBSStore::init()` loads the configured bootstrap-store filename. +2. `loadBSPropertiesIntoCache()` attempts to read the existing file into the in-memory dictionary. +3. If the file does not yet exist, startup continues and `loadFromJson()` marks the bootstrap load as an initial update. +4. During the initial update, each selected JSON default is written through `setRawValue()`, which creates the `/opt/secure/RFC` directory if needed and appends `key=value` entries into `bootstrap.ini`. +5. After initial creation, later updates rewrite the full file from the in-memory dictionary so the persistent store remains synchronized with the active bootstrap cache. + +This means the firmware JSON files are the source of default values, but `bootstrap.ini` is the persistent runtime copy managed by `XBSStore`. + +### PartnerId Read Dependency On `bootstrap.ini` + +When AuthService has not yet created `/opt/www/authService/partnerId3.dat`, PartnerId lookup falls back to `/opt/secure/RFC/bootstrap.ini`. + +That fallback matters in two ways: + +1. it allows a previously persisted PartnerId to survive reboot +2. if no PartnerId is present in either location, the system remains in the `default_boot` path until a later reload occurs + +## Error Handling And Fallbacks + +| Condition | Behavior | +|-----------|----------| +| `partnerId3.dat` missing at startup | use `default_boot` | +| PartnerId resolved but no matching JSON section | use `default` | +| `partners_defaults_device.json` missing | continue without device-specific overlay | +| malformed JSON in partner defaults file | `loadFromJson()` fails and logs an error | +| malformed JSON in device-specific defaults file | device-specific merge fails and logs an error | + +One deliberate behavior is that the firmware initial management notification is skipped when the store is still using `default_boot`. That notification is sent only once the active configuration is no longer the boot-time fallback. + +## Scenario Guide + +### Scenario 1: First Boot With No PartnerId Available Yet + +In this case: + +1. `/opt/www/authService/partnerId3.dat` does not exist yet +2. `/opt/secure/RFC/bootstrap.ini` either does not exist yet or does not contain a PartnerId +3. `loadFromJson()` falls back to `default_boot` + +Expected behavior: + +- `XBSStore` populates the cache from the `default_boot` section +- `bootstrap.ini` is created if this is the first persistent bootstrap load +- only the reduced early-boot parameter set is available + +This is the intended startup-safe behavior, not an error condition by itself. + +### Scenario 2: Parameter Exists In JSON But Has An Empty Default Value + +Some `default_boot` parameters intentionally use empty strings as placeholders. + +For a GET request, `XBSStore::getValue()` checks whether the resolved value length is greater than zero. If the stored value is an empty string, the code treats the request the same way it treats a missing value. + +Expected behavior: + +- the parameter may exist in the selected JSON section +- the stored value may still be empty +- the GET path returns an internal-error-style result because `getValue()` requires a non-empty string to treat the lookup as successful + +This behavior most commonly appears during the `default_boot` stage for parameters such as early NTP or URL placeholders. + +### Scenario 3: Parameter Missing From `default_boot` But Present In `default` + +If the system is still using `default_boot`, only keys present in that section are loaded into the bootstrap cache. + +Expected behavior: + +- parameters missing from `default_boot` are not available yet +- the same parameter may become available later after PartnerId resolution reloads the store into a partner-specific section or `default` + +This explains why a parameter can appear unavailable early in boot and available later without any manual repair step. + +### Scenario 4: PartnerId Resolves Later And Store Reloads + +Once the watcher thread detects creation or modification of `partnerId3.dat`, it re-reads PartnerId and compares it with the currently stored PartnerId value. + +If the value changed: + +1. the stored PartnerId entry is updated +2. `loadFromJson()` runs again +3. the active bootstrap configuration moves from `default_boot` to either the matching partner section or `default` + +Expected behavior: + +- more steady-state parameters become available +- placeholder empty defaults may be replaced by actual partner defaults +- firmware-initial notification is allowed once the active configuration is no longer `default_boot` + +### Scenario 5: Unknown Partner In `partners_defaults.json` + +If PartnerId is resolved successfully but the base defaults file does not contain a matching partner block, `XBSStore` falls back to the `default` section. + +Expected behavior: + +- the daemon stays operational +- the bootstrap store uses generic steady-state defaults +- no partner-specific entries from the missing section are applied + +This is a base-defaults fallback, not a bootstrap-store corruption case. + +### Scenario 6: Unknown Partner In `partners_defaults_device.json` + +The device-specific overlay file is processed separately from the base partner-defaults file. + +If the resolved PartnerId is absent only in `partners_defaults_device.json`: + +- base partner selection may still succeed normally from `partners_defaults.json` +- the device-specific overlay path falls back to `default` inside the device-specific file +- generic device-specific overrides are applied instead of partner-specific device overrides + +This scenario means the overlay file is incomplete for that partner. It does not necessarily mean the main partner-defaults file is wrong. + +### Scenario 7: Persisted Overrides Present + +If RFC or WebPA has previously overridden bootstrap-backed values, those persisted values remain active even when firmware defaults are reloaded. + +Expected behavior: + +- the runtime override remains the effective value +- firmware defaults are still refreshed in the journal as reference values +- a firmware update does not silently replace the higher-precedence override + +This is why runtime behavior may differ from the raw value currently visible in `partners_defaults.json`. + +## Troubleshooting Without Logs + +When investigating partner-default behavior, validate the following in order: + +1. `/etc/rfc.properties` points `BS_STORE_FILENAME` to the expected bootstrap file. +2. `/etc/partners_defaults.json` contains the expected `default_boot`, `default`, and partner-specific sections. +3. `/etc/partners_defaults_device.json` contains the expected partner section if device-specific overrides are required. +4. `/opt/secure/RFC/bootstrap.ini` exists and contains the persisted bootstrap state expected for that device. +5. `/opt/www/authService/partnerId3.dat` exists when the device is expected to have completed PartnerId discovery. + +If a parameter appears unavailable, determine which of these cases applies first: + +1. the system is still in `default_boot` +2. the parameter is present but intentionally empty +3. the parameter is absent from the currently selected section +4. PartnerId resolved to a section that does not exist and the system fell back to `default` +5. the device-specific overlay is missing the active partner section + +## Operational Notes + +### Why `default_boot` exists + +Early boot may not have AuthService output yet, but some parameters still need safe values so dependent services can start. The `default_boot` section provides that minimum set. + +### Why `default` is separate + +Once PartnerId is known, falling back to `default` means the device has entered its steady-state configuration path, even if there is no explicit partner section for that ID. + +### Typical Parameters In Each Section + +In the current repository version: + +- `default_boot` contains a reduced set of NTP, Xconf, WebPA, and locale-related keys. +- `default` contains the broader partner bootstrap and feature baseline, including multiple NTP servers and several RFC feature flags. + +## Testing + +Relevant unit-test coverage exists for the bootstrap-store behavior in `src/hostif/profiles/DeviceInfo/gtest/gtest_main.cpp`, including: + +1. reading bootstrap values before PartnerId becomes available +2. reading bootstrap values after PartnerId is resolved +3. device-specific merge behavior through `getPartnerDeviceConfig()` +4. missing device-specific file handling + +The current tests validate the reload path and merge helpers, but they do not fully document every production JSON section. When partner-default content changes, update both the JSON fixtures and the documentation. + +## See Also + +- [System Overview](overview.md) +- [Data Flow](data-flow.md) +- [JSON Usage](json-usage.md) +- [DeviceInfo Profile](../../src/hostif/profiles/DeviceInfo/docs/README.md) \ No newline at end of file diff --git a/src/hostif/handlers/src/hostIf_DeviceClient_ReqHandler.cpp b/src/hostif/handlers/src/hostIf_DeviceClient_ReqHandler.cpp index 94c95af91..71d94607a 100644 --- a/src/hostif/handlers/src/hostIf_DeviceClient_ReqHandler.cpp +++ b/src/hostif/handlers/src/hostIf_DeviceClient_ReqHandler.cpp @@ -494,11 +494,6 @@ int DeviceClientReqHandler::handleGetMsg(HOSTIF_MsgData_t *stMsgData) { ret = pIface->get_Device_DeviceInfo_X_RDKCENTRAL_COM_BootStatus(stMsgData); } - - else if(strcasecmp(stMsgData->paramName,"Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.getProfileData") == 0) - { - ret = pIface->get_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggergetProfileData(stMsgData); - } else if (strcasecmp(stMsgData->paramName,"Device.DeviceInfo.X_RDKCENTRAL-COM_PreferredGatewayType") == 0) { ret = pIface->get_Device_DeviceInfo_X_RDKCENTRAL_COM_PreferredGatewayType(stMsgData); diff --git a/src/hostif/parodusClient/pal/libpd.cpp b/src/hostif/parodusClient/pal/libpd.cpp index d626ca593..4b918d0d3 100644 --- a/src/hostif/parodusClient/pal/libpd.cpp +++ b/src/hostif/parodusClient/pal/libpd.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,7 @@ static long timeValDiff(struct timespec *starttime, struct timespec *finishtime) libpd_instance_t libparodus_instance = NULL; char parodus_url[URL_SIZE] = {'\0'}; char client_url[URL_SIZE] = {'\0'}; -bool exit_parodus_recv = false; +std::atomic_bool exit_parodus_recv(false); pthread_cond_t parodus_cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t parodus_lock = PTHREAD_MUTEX_INITIALIZER; /*----------------------------------------------------------------------------*/ @@ -84,8 +85,10 @@ void libpd_set_notifyConfigFile(const char* configFile) void stop_parodus_recv_wait() { - exit_parodus_recv = true; + pthread_mutex_lock(&parodus_lock); + exit_parodus_recv.store(true); pthread_cond_signal(&parodus_cond); + pthread_mutex_unlock(&parodus_lock); } /** * Initialize libpd and Load Data model, Invoke connection to parodus @@ -143,7 +146,7 @@ static void parodus_receive_wait() RDK_LOG(RDK_LOG_DEBUG,LOG_PARODUS_IF,"Entering parodus_receive_wait.. \n"); - while (!exit_parodus_recv) + while (!exit_parodus_recv.load()) { rtn = libparodus_receive (libparodus_instance, &wrp_msg, 2000); if (rtn == 1) @@ -155,16 +158,19 @@ static void parodus_receive_wait() clock_gettime(CLOCK_MONOTONIC, &currTime); currTime.tv_sec += 5; pthread_mutex_lock(&parodus_lock); - int wait_ret = pthread_cond_timedwait(&parodus_cond, &parodus_lock,&currTime); - if(wait_ret == ETIMEDOUT) + if (!exit_parodus_recv.load()) { - RDK_LOG(RDK_LOG_DEBUG,LOG_PARODUS_IF,"parodus_receive_wait(): wait for key acquisition timed out"); - } - else if(wait_ret != 0) - { - RDK_LOG(RDK_LOG_ERROR,LOG_PARODUS_IF,"parodus_receive_wait(): pthread_cond_timedwait failed with error %d", wait_ret); + int wait_ret = pthread_cond_timedwait(&parodus_cond, &parodus_lock,&currTime); + if(wait_ret == ETIMEDOUT) + { + RDK_LOG(RDK_LOG_DEBUG,LOG_PARODUS_IF,"parodus_receive_wait(): wait for key acquisition timed out"); + } + else if(wait_ret != 0) + { + RDK_LOG(RDK_LOG_ERROR,LOG_PARODUS_IF,"parodus_receive_wait(): pthread_cond_timedwait failed with error %d", wait_ret); + } } - RDK_LOG(RDK_LOG_INFO,LOG_PARODUS_IF,"[%s:%d] Unlocking mutex... \n", __FUNCTION__, __LINE__); + RDK_LOG(RDK_LOG_INFO,LOG_PARODUS_IF,"[%s:%d] Unlocking mutex... \n", __FUNCTION__, __LINE__); pthread_mutex_unlock(&parodus_lock); continue; } diff --git a/src/hostif/parodusClient/pal/webpa_attribute.cpp b/src/hostif/parodusClient/pal/webpa_attribute.cpp index 73fa2681c..edaa9f934 100644 --- a/src/hostif/parodusClient/pal/webpa_attribute.cpp +++ b/src/hostif/parodusClient/pal/webpa_attribute.cpp @@ -121,6 +121,11 @@ static WAL_STATUS getParamAttributes(const char *pParameterName, AttrVal ***attr unsigned int i = 0; HOSTIF_MsgData_t Param = {0}; + if ((pParameterName == NULL) || (attr == NULL) || (TotalParams == NULL)) + { + return WAL_ERR_INVALID_PARAM; + } + memset(&Param, '\0', sizeof(HOSTIF_MsgData_t)); // Check if pParameterName is in the list of notification parameters and check if the parameter is one among them diff --git a/src/hostif/parodusClient/waldb/data-model/data-model-generic.xml b/src/hostif/parodusClient/waldb/data-model/data-model-generic.xml index 1ef1a86dd..8381385e0 100644 --- a/src/hostif/parodusClient/waldb/data-model/data-model-generic.xml +++ b/src/hostif/parodusClient/waldb/data-model/data-model-generic.xml @@ -3607,11 +3607,6 @@ - - - - - @@ -3635,7 +3630,15 @@ - + + + + + + + + + @@ -3647,6 +3650,11 @@ + + + + + diff --git a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp index ec84367f0..37ded3ce1 100644 --- a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp +++ b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp @@ -130,7 +130,8 @@ #define MAX_PORT_RANGE 3020 #define MEMINSIGHT_SERVICE "meminsight-runner.service" -#define MEMINSIGHT_ENABLE_FILE "/opt/.enable_meminsight" +#define MEMINSIGHT_TRIGGER_FILE "/opt/.enable_meminsight" +#define MEMINSIGHT_TMP_TRIGGER_FILE "/tmp/.enable_meminsight" #define DEVICEID_SCRIPT_PATH "/lib/rdk/getDeviceId.sh" #define SCRIPT_OUTPUT_BUFFER_SIZE 512 #define ENTRY_WIDTH 64 @@ -3118,7 +3119,7 @@ int hostIf_DeviceInfo::findLocalPortAvailable() { struct sockaddr_in address = {0,0,0}; int sockfd = -1, status; - int port = MIN_PORT_RANGE; + uint16_t port = MIN_PORT_RANGE; while (port <= MAX_PORT_RANGE) { address.sin_family = AF_INET; @@ -4052,9 +4053,9 @@ int hostIf_DeviceInfo::set_xRDKCentralComRFC(HOSTIF_MsgData_t * stMsgData) { ret = set_Device_DeviceInfo_X_RDKCENTRAL_COM_Canary_wakeUpEnd(stMsgData); } - else if (strcasecmp(stMsgData->paramName, X_MEMINSIGHT_ENABLE) == 0) + else if (strcasecmp(stMsgData->paramName, MEMINSIGHT_TRIGGER) == 0) { - ret = set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable(stMsgData); + ret = set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger(stMsgData); } else if (strcasecmp(stMsgData->paramName,RDK_REBOOTSTOP_ENABLE) == 0) { @@ -4317,127 +4318,6 @@ int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggerI return retVal; } -int hostIf_DeviceInfo::get_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggergetProfileData(HOSTIF_MsgData_t *stMsgData) -{ - stMsgData->paramtype = hostIf_StringType; - int retStatus = NOK; - const char *filename = "/etc/rrd/remote_debugger.json"; - FILE *fp = nullptr; - char *fileBuf = nullptr; - long fileSz = 0; - size_t bytesRead = 0; - cJSON *root = nullptr; - cJSON *filtered = nullptr; - char *outStr = nullptr; - size_t outLen = 0; - RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF, "[%s] Entering …\n", __FUNCTION__); - fp = fopen(filename, "rb"); - if (!fp) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Cannot open %s\n", __FUNCTION__, filename); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - if (fseek(fp, 0L, SEEK_END) != 0) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] fseek failed\n", __FUNCTION__); - fclose(fp); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - fileSz = ftell(fp); - rewind(fp); - if (fileSz < 0) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] fileSz is negative, Returning....\n", __FUNCTION__); - fclose(fp); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - fileBuf = (char*)malloc((size_t)fileSz + 1); - if (!fileBuf) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] malloc(%ld) failed\n", __FUNCTION__, fileSz + 1); - fclose(fp); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - bytesRead = fread(fileBuf, 1U, (size_t)fileSz, fp); - fileBuf[bytesRead] = '\0'; - fclose(fp); fp = nullptr; - root = cJSON_Parse(fileBuf); - if (!root) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] JSON parse error: %s\n", __FUNCTION__, cJSON_GetErrorPtr()); - free(fileBuf); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - filtered = cJSON_CreateObject(); - if (!filtered) - { - free(fileBuf); - cJSON_Delete(root); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - - for (cJSON *top = root->child; top; top = top->next) - { - if (top->type != cJSON_Object) - { - continue; - } - cJSON *arr = cJSON_CreateArray(); - if (!arr) - { - free(fileBuf); - cJSON_Delete(root); - cJSON_Delete(filtered); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - for (cJSON *sub = top->child; sub; sub = sub->next) - { - cJSON_AddItemToArray(arr, cJSON_CreateString(sub->string)); - } - if (cJSON_GetArraySize(arr) > 0) - { - cJSON_AddItemToObject(filtered, top->string, arr); - } - else - { - cJSON_Delete(arr); - } - } - - outStr = cJSON_PrintUnformatted(filtered); - if (!outStr) - { - free(fileBuf); - cJSON_Delete(root); - cJSON_Delete(filtered); - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Leaving with NOK\n", __FUNCTION__); - return retStatus; - } - outLen = strlen(outStr); - if (outLen >= sizeof(stMsgData->paramValue)) - { - outLen = sizeof(stMsgData->paramValue) - 1; - } - memcpy(stMsgData->paramValue, outStr, outLen); - stMsgData->paramValue[outLen] = '\0'; - stMsgData->paramLen = outLen; - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Extracted profile map: %s\n", __FUNCTION__, outStr); - retStatus = OK; - free(fileBuf); - cJSON_Delete(root); - cJSON_Delete(filtered); - free(outStr); - RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF, "[%s] Leaving with OK\n", __FUNCTION__); - return retStatus; -} - int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggerWebCfgData (HOSTIF_MsgData_t *stMsgData) { char *issueStr = NULL; @@ -4526,10 +4406,10 @@ int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_Canary_wakeUpEnd ( return retVal; } -int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable(HOSTIF_MsgData_t *stMsgData) +int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger(HOSTIF_MsgData_t *stMsgData) { int ret = NOK; - bool is_xmem_enabled = false; + std::string is_xmem_triggered = "stop"; // default to stop if invalid value is passed if (!stMsgData) { @@ -4537,44 +4417,59 @@ int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable return NOK; } - if (stMsgData->paramtype != hostIf_BooleanType) + if (stMsgData->paramtype != hostIf_StringType) { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Invalid parameter type for %s. Expected boolean(0/1)\n", __FUNCTION__, __LINE__, stMsgData->paramName); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Invalid parameter type for %s. Expected string\n", __FUNCTION__, __LINE__, stMsgData->paramName); stMsgData->faultCode = fcInvalidParameterType; return NOK; } - is_xmem_enabled = get_boolean(stMsgData->paramValue); + is_xmem_triggered = getStringValue(stMsgData); - if (is_xmem_enabled) + if (strncmp(is_xmem_triggered.c_str(), "start", 5) == 0) { - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Enabling MemInsight feature\n", __FUNCTION__, __LINE__); + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Triggering MemInsight feature\n", __FUNCTION__, __LINE__); - std::ofstream enableFile(MEMINSIGHT_ENABLE_FILE); - if (enableFile.is_open()) + std::ofstream triggerFile(MEMINSIGHT_TRIGGER_FILE); + std::ofstream tmpTriggerFile(MEMINSIGHT_TMP_TRIGGER_FILE); + if (triggerFile.is_open() || tmpTriggerFile.is_open()) { - enableFile.close(); - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully enabled MemInsight. File created: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_ENABLE_FILE); + if (triggerFile.is_open()) { + triggerFile.close(); + } + if (tmpTriggerFile.is_open()) { + tmpTriggerFile.close(); + } + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully triggered MemInsight. File created: %s & %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_TRIGGER_FILE, MEMINSIGHT_TMP_TRIGGER_FILE); ret = OK; } else { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Failed to create MemInsight enable file: %s. Error: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_ENABLE_FILE, strerror(errno)); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Failed to create MemInsight trigger file: %s or %s. Error: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_TRIGGER_FILE, MEMINSIGHT_TMP_TRIGGER_FILE, strerror(errno)); stMsgData->faultCode = fcInternalError; ret = NOK; } } - else + else if (strncmp(is_xmem_triggered.c_str(), "stop", 4) == 0) { RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Disabling MemInsight feature\n", __FUNCTION__, __LINE__); - std::ifstream checkFile(MEMINSIGHT_ENABLE_FILE); - if (checkFile.is_open()) + std::ifstream checkFile(MEMINSIGHT_TRIGGER_FILE); + std::ifstream tmpCheckFile(MEMINSIGHT_TMP_TRIGGER_FILE); + if (checkFile.is_open() || tmpCheckFile.is_open()) { - checkFile.close(); - if (remove(MEMINSIGHT_ENABLE_FILE) == 0) + if (checkFile.is_open()) { + checkFile.close(); + } + if (tmpCheckFile.is_open()) { + tmpCheckFile.close(); + } + int tempTriggerRm = remove(MEMINSIGHT_TMP_TRIGGER_FILE); + int triggerRm = remove(MEMINSIGHT_TRIGGER_FILE); + + if (triggerRm == 0 || tempTriggerRm == 0) { - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully disabled MemInsight. File removed: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_ENABLE_FILE); + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully disabled MemInsight. File removed: %s & %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_TRIGGER_FILE, MEMINSIGHT_TMP_TRIGGER_FILE); ret = OK; int sysRet = v_secure_system("systemctl is-active %s", MEMINSIGHT_SERVICE); @@ -4610,21 +4505,21 @@ int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable } else { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Failed to remove MemInsight enable file: %s. Error: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_ENABLE_FILE, strerror(errno)); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] Failed to remove MemInsight trigger file: %s or %s. Error: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_TRIGGER_FILE, MEMINSIGHT_TMP_TRIGGER_FILE, strerror(errno)); stMsgData->faultCode = fcInternalError; ret = NOK; } } else { - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] MemInsight is already disabled. File not found: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_ENABLE_FILE); + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] MemInsight is already set to stop. File not found: %s\n", __FUNCTION__, __LINE__, MEMINSIGHT_TRIGGER_FILE); ret = OK; } } if (ret == OK) { - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully set MemInsight enable to %s\n", __FUNCTION__, __LINE__, is_xmem_enabled ? "true" : "false"); + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s:%d] Successfully set MemInsight Triggered to %s\n", __FUNCTION__, __LINE__, is_xmem_triggered.c_str()); } return ret; } diff --git a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.h b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.h index 9868f0494..49fa6fb31 100644 --- a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.h +++ b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.h @@ -201,9 +201,10 @@ #define CANARY_START_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Canary.wakeUpStart" #define CANARY_END_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Canary.wakeUpEnd" -/* Profile: X_RDKCENTRAL-COM_RFC.Feature.xMemInsight */ -#define X_MEMINSIGHT_ENABLE "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.xMemInsight.Enable" -#define X_MEMINSIGHT_ARGS "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.xMemInsight.Args" +/* Profile: X_RDKCENTRAL-COM_RFC.Feature.meminsight */ +#define MEMINSIGHT_ENABLE "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.meminsight.Enable" +#define MEMINSIGHT_ARGS "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.meminsight.Args" +#define MEMINSIGHT_TRIGGER "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.meminsight.Trigger" /* Profile: X_RDKCENTRAL-COM_xAccount.HotelCheckout */ #define HOTEL_CHECKOUT_LAST_RESET_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_xAccount.HotelCheckout.LastResetTime" @@ -1292,7 +1293,6 @@ class hostIf_DeviceInfo { int set_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggerIssueType(HOSTIF_MsgData_t *); int set_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggerWebCfgData(HOSTIF_MsgData_t *); - int get_Device_DeviceInfo_X_RDKCENTRAL_COM_RDKRemoteDebuggergetProfileData(HOSTIF_MsgData_t *); #endif /* @@ -1313,18 +1313,19 @@ class hostIf_DeviceInfo { /* - * @brief set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable + * @brief set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Enable * - * This method is used to enable/disable the xmeminsight memory & CPU Analysis Tool. + * This method is used to enable/disable the meminsight memory & CPU Analysis Tool. * with following TR-069 definition: - * Parameter Name: Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.xMemInsight.Enable - * Data type: boolean - Enable (True)/ disable (False) xmeminsight tool. + * Parameter Name: Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MemInsight.Enable + * Data type: boolean - Enable (True)/ disable (False) meminsight tool. * * @retval OK if it is successful. * @retval NOK if operation fails. */ - int set_Device_DeviceInfo_X_RDKCENTRAL_COM_XMemInsight_Enable(HOSTIF_MsgData_t *); + int set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger(HOSTIF_MsgData_t *); + int set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Enable(HOSTIF_MsgData_t *); diff --git a/src/hostif/profiles/DeviceInfo/XrdkCentralComBSStore.cpp b/src/hostif/profiles/DeviceInfo/XrdkCentralComBSStore.cpp index 6e09464af..9b8f8050c 100755 --- a/src/hostif/profiles/DeviceInfo/XrdkCentralComBSStore.cpp +++ b/src/hostif/profiles/DeviceInfo/XrdkCentralComBSStore.cpp @@ -119,7 +119,7 @@ bool createBspCompleteFiles() void XBSStore::getAuthServicePartnerID() { - const std::string partnerIdPath = "/opt/www/authService/partnerId3.dat"; + const std::string filePath = "/opt/www/authService/partnerId3.dat"; // Initialize inotify int inotifyFd = inotify_init(); @@ -129,7 +129,6 @@ void XBSStore::getAuthServicePartnerID() } // Extracting the parent directories dynamically - std::string filePath(partnerIdPath); std::string authServiceDir = getParentDirectory(filePath); // "/opt/www/authService" std::string wwwDir = getParentDirectory(authServiceDir); // "/opt/www" std::string parentDir = getParentDirectory(wwwDir); // "/opt" diff --git a/src/hostif/profiles/Ethernet/Device_Ethernet_Interface.cpp b/src/hostif/profiles/Ethernet/Device_Ethernet_Interface.cpp index ca3e07461..6b393f7ee 100644 --- a/src/hostif/profiles/Ethernet/Device_Ethernet_Interface.cpp +++ b/src/hostif/profiles/Ethernet/Device_Ethernet_Interface.cpp @@ -200,7 +200,7 @@ static int getEthernetInterfaceName (unsigned int ethInterfaceNum, char* name) unsigned int count = 0; for (struct if_nameindex* ifnp = ifname; ifnp->if_index != 0; ifnp++) { - if ((strncmp (ifnp->if_name, "eth", 3) == 0) && (++count == ethInterfaceNum)) + if ((ifnp->if_name != NULL) && (strncmp (ifnp->if_name, "eth", 3) == 0) && (++count == ethInterfaceNum)) { rc=strcpy_s (name, BUFF_LENGTH_64,ifnp->if_name); ERR_CHK(rc); diff --git a/src/hostif/profiles/IP/Device_IP.cpp b/src/hostif/profiles/IP/Device_IP.cpp index 21c12ab4c..16029733e 100644 --- a/src/hostif/profiles/IP/Device_IP.cpp +++ b/src/hostif/profiles/IP/Device_IP.cpp @@ -320,6 +320,9 @@ char* hostIf_IP::getVirtualInterfaceName (struct if_nameindex *phy_if_list, unsi char *p, *v; for (struct ifaddrs *ifa_node = ifa; ifa_node; ifa_node = ifa_node->ifa_next) { + if ((ifa_node->ifa_name == NULL) || (ifa_node->ifa_addr == NULL)) + continue; + if (ifa_node->ifa_addr->sa_family == AF_INET) // virtual interfaces are IPv4-specific, so use IPv4 address family to hunt for them. { for (struct if_nameindex *phy_if = phy_if_list; phy_if->if_index != 0; phy_if++)