diff --git a/dslmngr.c b/dslmngr.c index df8cbf07bc30369b563e5def7be6178026394d49..5a30ae154d03f22fd4c23b518c357a1f06fbed46 100644 --- a/dslmngr.c +++ b/dslmngr.c @@ -1907,3 +1907,70 @@ __error_ret: return -1; } + +static int uci_get_oem_params(char *vendor_id, char *sw_version, char *serial_nr) +{ + struct uci_context *ctx; + struct uci_package *pkg; + struct uci_element *e; + const char *value; + + ctx = uci_alloc_context(); + if (!ctx) + return -1; + + if (uci_load(ctx, "dsl", &pkg)) { + uci_free_context(ctx); + return -1; + } + + uci_foreach_element(&pkg->sections, e) { + struct uci_section *s = uci_to_section(e); + if (!strcmp(s->type, "oem-parameters")) { + value = uci_lookup_option_string(ctx, s, "country_code"); + if (value) + sscanf(value, "%2hhX%2hhX", vendor_id, vendor_id + 1); + value = uci_lookup_option_string(ctx, s, "vendor_id"); + if (value) + strncpy(vendor_id + 2, value, 4); + value = uci_lookup_option_string(ctx, s, "vendor_suffix"); + if (value) + sscanf(value, "%2hhX%2hhX", vendor_id + 6, vendor_id + 7); + value = uci_lookup_option_string(ctx, s, "sw_version"); + if (value) + strncpy(sw_version, value, 16); + value = uci_lookup_option_string(ctx, s, "serial_nr"); + if (value) + strncpy(serial_nr, value, 32); + } + } + + uci_free_context(ctx); + return 0; +} + +int dsl_oem_init() +{ + if (xdsl_ops.set_oem_parameter) { + char vendor_id[8] = { 0 }; // 2 byte hex country code + 4 byte string id + 2 byte hex suffix + char sw_version[16] = { 0 }; + char serial_nr[32] = { 0 }; + char zero[32] = { 0 }; + + if (uci_get_oem_params(vendor_id, sw_version, serial_nr) != 0) { + DSLMNGR_LOG(LOG_ERR, "Unable to read OEM parameters from config, skipping OEM init\n"); + return -1; + } + // Note: These are BRCM specific parameters from bcmadsl.h + if (memcmp(vendor_id, zero, 8) != 0) { + (*xdsl_ops.set_oem_parameter)(4, (void *)vendor_id, 8); + } + if (memcmp(sw_version, zero, 16) != 0) { + (*xdsl_ops.set_oem_parameter)(5, (void *)sw_version, 16); + } + if (memcmp(serial_nr, zero, 32) != 0) { + (*xdsl_ops.set_oem_parameter)(6, (void *)serial_nr, 32); + } + } + return 0; +} diff --git a/dslmngr.h b/dslmngr.h index 358c4870915772e337405c4c189af4a0480be0a5..bd08ec70e316fb8c8abebecc6e0d4ce122e62e67 100644 --- a/dslmngr.h +++ b/dslmngr.h @@ -40,6 +40,7 @@ extern int current_log_level; #define CHECK_POINT() printf("Check point at %s@%s:%d\n", __func__, __FILE__, __LINE__) +int dsl_oem_init(); int dsl_add_ubus_objects(struct ubus_context *ctx); int dsl_line_status(struct ubus_context *ctx, struct ubus_object *obj, diff --git a/main.c b/main.c index 26ee72baf149afb88cd20a54bed150dffb3b6a53..7040a7e57c260582acfd6c72279ee8aae8efee0f 100644 --- a/main.c +++ b/main.c @@ -92,6 +92,7 @@ int main(int argc, char **argv) fprintf(stderr, "dslmngr: event thread create error!\n"); /* dslmngr_cmd_main(ctx); */ + dsl_oem_init(); if (dsl_add_ubus_objects(ctx) != 0) goto __ret;