Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ autom4te.cache/
# =============================================================================

# Generated by ./configure (from Makefile.am / Makefile.in)
# NOTE: c_sourcecode/src/Makefile.am is a source file and is NOT ignored.
# src/Makefile (root src/) is a hand-written file and is NOT ignored.
# NOTE: c_sourcecode/src/Makefile.am and c_sourcecode/watcher/Makefile.am are source files.
c_sourcecode/Makefile
c_sourcecode/src/Makefile
c_sourcecode/watcher/Makefile

# Autoconf output files
c_sourcecode/config.status
Expand All @@ -33,8 +33,9 @@ c_sourcecode/config.h
c_sourcecode/config.h.in
c_sourcecode/stamp-h1

# Compiled crashupload binary
# Compiled binaries
c_sourcecode/src/crashupload
c_sourcecode/watcher/inotify-minidump-watcher

# Core dump produced if the binary crashes during local development/testing
c_sourcecode/src/core
Expand Down Expand Up @@ -80,3 +81,4 @@ unittest/ratelimit_gtest
unittest/scanner_gtest
unittest/upload_gtest
unittest/utils_gtest
unittest/watcher_gtest
2 changes: 1 addition & 1 deletion c_sourcecode/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# limitations under the License.
##########################################################################

SUBDIRS = src
SUBDIRS = src watcher

EXTRA_DIST = README.md

Expand Down
92 changes: 35 additions & 57 deletions c_sourcecode/README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,54 @@
# Crashupload C Implementation - Skeleton Code
# Crashupload C source (`c_sourcecode/`)

This directory contains skeleton C implementation for the crashupload migration from shell scripts to C.
This directory is the autotools tree for the C binaries:

## Architecture
- **crashupload** — dump discovery, archive, rate-limit, and upload (`src/`)
- **inotify-minidump-watcher** — directory watcher that starts upload on matching file creates (`watcher/`)

Based on **optimized design** from:
- `docs/migration/hld/updateduploadDumps-hld.md`
- `docs/migration/lld/updateduploadDumps-lld.md`
- `docs/migration/diagrams/flowcharts/optimizeduploadDumps-flowcharts.md`
- `docs/migration/diagrams/sequence/updateuploadDumps-sequence.md`
- `docs/migration/requirements/uploadDumps-requirements.md`

## Structure
## Layout

```
c_sourcecode/
├── common/ # Common type definitions, constants, errors
│ ├── types.h
│ ├── constants.h
│ └── errors.h
├── src/ # Source code
│ ├── main.c # Main entry point (7-step optimized flow)
│ ├── init/ # Consolidated initialization
│ ├── config/ # Configuration management
│ ├── platform/ # Platform abstraction
│ ├── core/ # Core processing modules
│ │ ├── scanner.* # Dump file scanner
│ │ ├── archive_smart.* # Smart archive creator
│ │ ├── upload_typeaware.* # Type-aware upload
│ │ └── ratelimit_unified.* # Unified rate limiter
│ ├── utils/ # Utility modules
│ │ ├── prerequisites.* # Combined network+time check
│ │ ├── privacy.* # Unified privacy check
│ │ ├── cleanup_batch.* # Batch cleanup
│ │ ├── lock_manager.* # Process locking
│ │ └── logger.* # Logging
│ └── Makefile # Build system
├── configure.ac
├── Makefile.am
├── common/ # Shared types, constants, errors
├── include/ # Public headers used by crashupload
├── src/ # crashupload binary
└── watcher/ # inotify-minidump-watcher binary
```

## Key Optimizations

1. **Consolidated Initialization** - Single `system_initialize()` call (3 steps → 1)
2. **Combined Prerequisites** - `prerequisites_wait()` checks network + time together
3. **Unified Privacy** - `privacy_uploads_blocked()` combines opt-out + privacy mode
4. **Smart Archive** - Direct compression first, /tmp fallback if needed
5. **Type-Aware Upload** - Minidump (5 retries, 3s delay) vs Coredump (3 retries, 10s delay)
6. **Unified Rate Limit** - Single check for recovery + 10/10min limit
7. **Batch Cleanup** - Single directory scan for all cleanup operations
## Build

## Building
From this directory:

```bash
cd src
autoreconf -i
./configure
make
make install
```

## Status
`make` produces:

- `src/crashupload`
- `watcher/inotify-minidump-watcher`

Both are `bin_PROGRAMS` and install to `$prefix/bin` (typically `/usr/bin` on device images).

**SKELETON**: All files contain function signatures and data structures from the design documents, but function bodies need implementation. Each TODO comment indicates what needs to be implemented.
Yocto/RDK builds pass extra `CFLAGS`/`LDFLAGS` (for example `-DYOCTO_BUILD` and `-lsecure_wrapper`). Do not hard-code those in a way that breaks the existing recipe flags.

## Next Steps
Local coverage-style builds used by L1 go through `crashupload/cov_build.sh`, which configures and installs both binaries.

1. Implement function bodies following TODO markers
2. Add unit tests (GTest framework recommended)
3. Build and test incrementally
4. Validate against shell script behavior
5. Performance test on target platforms
## Tests

L1 (GTest) lives in `../unittest/`. Watcher tests are `watcher_gtest` and are included in `../run_ut.sh`.

```bash
cd ..
./run_ut.sh
```

## Performance Targets
## Notes

Based on optimized design:
- Startup: 100-120ms (vs 150-200ms standard)
- Memory: 6-8MB (vs 8-10MB standard)
- Binary: ~35KB (vs ~45KB standard)
- Decision points: 22 (vs 35 standard) - 37% reduction
- `src/` and `watcher/` are separate subdirectories so crashupload link flags (curl, rbus, archive, telemetry) are not applied to the watcher.
- The watcher only links `libsecure_wrapper`, matching the legacy `crashupload/src/Makefile`.
5 changes: 5 additions & 0 deletions c_sourcecode/common/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
#define MAX_CORE_FILES 4
#define LOGMAPPER_FILE_PATH "/etc/breakpad-logmapper.conf"
#define LOG_FILES_PATH "/tmp/minidump_log_files.txt"
/* Default persistent store; overridden by include.properties PERSISTENT_PATH. */
#define PERSISTENT_PATH "/opt/persistent"
/* Extender getWanInterfaceName() defaults to br-home. Do not reuse ARM_INTERFACE —
* that string is a broadband device.properties key in get_interface_value(). */
#define EXTENDER_WAN_INTERFACE "br-home"

/* Device types */
typedef enum {
Expand Down
3 changes: 2 additions & 1 deletion c_sourcecode/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ CFLAGS="$CFLAGS -Wall -Werror -O2 -DT2_EVENT_ENABLED"
#CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200809L"

AC_CONFIG_FILES([Makefile
src/Makefile])
src/Makefile
watcher/Makefile])
AC_OUTPUT

echo ""
Expand Down
2 changes: 2 additions & 0 deletions c_sourcecode/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ crashupload_SOURCES += \

# Clean up
CLEANFILES = *~

EXTRA_DIST = README.md
47 changes: 47 additions & 0 deletions c_sourcecode/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# crashupload (`src/`)

This directory is the source for the **crashupload** binary. It is built by autotools from `c_sourcecode/` (`SUBDIRS = src watcher`).

## What it does

`crashupload` is the C replacement path for dump packaging and upload. The entry point is `main.c`, which initializes logging/config/platform, waits for prerequisites, takes the process lock, scans for dumps, archives, uploads, rate-limits, and cleans up.

## Modules

| Path | Role |
|------|------|
| `main.c` | Process entry and main flow |
| `init/` | Consolidated system initialization |
| `config/` | Runtime configuration load |
| `platform/` | Device/platform specifics |
| `scanner/` | Dump file discovery |
| `archive/` | Archive creation |
| `upload/` | Upload to crash portal |
| `ratelimit/` | Upload rate limiting |
| `rfcInterface/` | RFC parameter access |
| `rbusInterface/` | RBUS init/uninit |
| `t2Interface/` | Telemetry markers |
| `utils/` | Logger, locks, files, prerequisites, batch cleanup |

Headers used across modules also live in `../common/` and `../include/`.

## Build

Do not run a standalone Makefile in this folder. Build from the parent tree:

```bash
cd ..
autoreconf -i
./configure
make
```

The binary is `src/crashupload` (installed as `/usr/bin/crashupload`).

## Tests

L1 coverage for these sources is under `../../unittest/` (`*_gtest` binaries). Run from the crashupload repo root:

```bash
./run_ut.sh
```
2 changes: 1 addition & 1 deletion c_sourcecode/src/archive/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "../utils/logger.h"

// For unit testing: allow static functions to be visible
#ifdef UNIT_TEST
#ifdef GTEST_ENABLE
#define STATIC_TESTABLE
#else
#define STATIC_TESTABLE static
Expand Down
14 changes: 2 additions & 12 deletions c_sourcecode/src/config/config_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,6 @@ int config_init_load(config_t *config, int argc, char *argv[])
}
CRASHUPLOAD_INFO("COMM_INTERFACE=%s\n", config->comm_interface);
}

/* TODO: During broadband we have to implement
* CORE_PATH="/minidumps"
LOG_PATH="/rdklogs/logs"
if [ ! -d $LOG_PATH ];then mkdir -p $LOG_PATH; fi
if [ "$MULTI_CORE" = "yes" ] ;then
COMM_INTERFACE=`get_interface_value`
else
COMM_INTERFACE=$INTERFACE
fi
*/
/* NOTE: /nvram/coredump.properties and /opt/coredump.properties do not exist on RDKB.
* Non-prod build override via /opt/coredump.properties applies only to non-broadband devices. */
}
Expand All @@ -162,7 +151,8 @@ int config_init_load(config_t *config, int argc, char *argv[])
config->device_type = DEVICE_TYPE_EXTENDER;
CRASHUPLOAD_INFO("device type=%d\n", config->device_type);
strcpy(config->core_log_file, "/var/log/messages");
CRASHUPLOAD_INFO("core log=%s\n", config->core_log_file);
snprintf(config->comm_interface, sizeof(config->comm_interface), "%s", EXTENDER_WAN_INTERFACE);
CRASHUPLOAD_INFO("core log=%s comm_interface=%s\n", config->core_log_file, config->comm_interface);
}
else if (0 == (strncmp(device_prop_data, "XHC1", 4)))
{
Expand Down
82 changes: 77 additions & 5 deletions c_sourcecode/src/platform/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,57 @@
#include "../rbusInterface/rbus_interface.h"
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#ifdef GTEST_ENABLE
#define STATIC_TESTABLE
#else
#define STATIC_TESTABLE static
#endif

#define EXTENDER_CTS_MODEL "GR-EXT02A-CTS"

/*
* Script parity (extender utils.sh getModelNum):
* MODEL_NUM=GR-EXT02A-CTS -> strip hyphens
* else BOX_TYPE (e.g. XE2). GetModelNum() only reads MODEL_NUM=.
*/
STATIC_TESTABLE void apply_extender_model(char *model, size_t model_size, const char *box_type)
{
size_t i;
size_t j;

if (!model || model_size == 0)
{
return;
}

if (strcmp(model, EXTENDER_CTS_MODEL) == 0)
{
j = 0;
for (i = 0; model[i] != '\0' && j + 1 < model_size; i++)
{
if (model[i] != '-')
{
model[j++] = model[i];
}
}
model[j] = '\0';
return;
}

if (box_type && box_type[0] != '\0' && strcmp(box_type, "UNKNOWN") != 0)
{
snprintf(model, model_size, "%s", box_type);
return;
}

if (model[0] == '\0')
{
snprintf(model, model_size, "%s", "UNKNOWN");
}
}

/* function NormalizeMac - gets the eSTB MAC address of the device.

Expand Down Expand Up @@ -160,14 +211,30 @@ int platform_initialize(const config_t *config, platform_config_t *platform)
{
CRASHUPLOAD_ERROR("GetEstbMac is failed. Trying to get mac from wan interface\n");
char wan_if[32] = {0};
snprintf(wan_if, sizeof(wan_if), "%s", get_interface_value());
if (config->device_type == DEVICE_TYPE_EXTENDER)
{
if (config->comm_interface[0] != '\0'){
snprintf(wan_if, sizeof(wan_if), "%s", config->comm_interface);
CRASHUPLOAD_INFO("Got WAN interface from comm_interface %s", wan_if);
}
else{
snprintf(wan_if, sizeof(wan_if), "%s", EXTENDER_WAN_INTERFACE);
Comment thread
gomathishankar37 marked this conversation as resolved.
CRASHUPLOAD_INFO("Got WAN interface from fallback default %s", wan_if);
}
}
else
{
snprintf(wan_if, sizeof(wan_if), "%s", get_interface_value());
CRASHUPLOAD_INFO("Got WAN interface from get_interface_value() %s", wan_if);
}
if (wan_if[0] != '\0' && strcmp(wan_if, "unknown") != 0)
{
ret = GetHwMacAddress(wan_if, platform->mac_address, sizeof(platform->mac_address));
if (ret)
{
NormalizeMac(platform->mac_address, sizeof(platform->mac_address));
CRASHUPLOAD_INFO("Broadband MAC fallback via %s: %s\n", wan_if, platform->mac_address);
CRASHUPLOAD_INFO("%s MAC fallback via %s: %s\n",
device_type_to_str(config->device_type), wan_if, platform->mac_address);
}
}
}
Expand All @@ -177,16 +244,21 @@ int platform_initialize(const config_t *config, platform_config_t *platform)
strcpy(platform->mac_address, "000000000000");
}
}
// TODO: For broadband and extender we have change the code
ret = GetModelNum(platform->model, sizeof(platform->model));
if (ret)
if (config && config->device_type == DEVICE_TYPE_EXTENDER)
{
apply_extender_model(platform->model, sizeof(platform->model), config->box_type);
CRASHUPLOAD_INFO("Model Num=%s\n", platform->model);
}
else if (ret)
{
CRASHUPLOAD_INFO("Model Num=%s\n", platform->model);
}
else
{
CRASHUPLOAD_ERROR("GetModel is failed. Setting default value\n");
strcpy(platform->model, "UNKNOWN");
strncpy(platform->model, "UNKNOWN", sizeof(platform->model) - 1);
platform->model[sizeof(platform->model) - 1] = '\0';
}
ret = file_get_sha1("/version.txt", platform->platform_sha1, sizeof(platform->platform_sha1));
if (ret == 0)
Expand Down
2 changes: 0 additions & 2 deletions c_sourcecode/src/rfcInterface/rfcinterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ int write_RFCProperty(char *type, const char *key, const char *value, RFCVALDATA
* */
int read_RFCProperty(const char *type, const char *key, char *out_value, size_t datasize)
{
// TODO: Need to implement for RDK-M
(void)type;
(void)key;
(void)out_value;
Expand All @@ -189,7 +188,6 @@ int read_RFCProperty(const char *type, const char *key, char *out_value, size_t
* */
int write_RFCProperty(const char *type, const char *key, const char *value, RFCVALDATATYPE datatype)
{
// TODO: Need to implement for RDK-M
(void)type;
(void)key;
(void)value;
Expand Down
Loading
Loading