Add VoiceProfile at AVM Devices

Hello,

I’m trying to create as many voice profiles as there are numbers for the subscriber. I’ve tried many variations and combinations, but I haven’t had any luck. The script only adds 2 numbers because I fail to create a third voice profile. By default, there are two preconfigured, so I can’t even add one profile.

I would greatly appreciate any help.

    /////Voice/////
    log('Setting Voice-services');
    // Area code is only set once, as it is always the same
    declare("InternetGatewayDevice.Services.VoiceService.*.VoiceProfile.1.Line.1.SIP.X_AVM-DE_OKZ", { value: now }, { value: config.voip.sip_account[0].area_code });

    // Assumption: 'config' contains the JSON data with the SIP accounts
    if (config && config.voip && config.voip.sip_account && config.voip.sip_account.length > 0) {
    // Determine the number of VoiceProfile instances
    const numVoiceProfiles = config.voip.sip_account.length;
    
    // Ensure that the required number of VoiceProfile instances exist
    declare("InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.*", null, {path: 1});


    log('Number of voice profiles: ' + numVoiceProfiles);

    // Iterate over any SIP account
    for (let [index, sipAccount] of Object.entries(config.voip.sip_account)) {
        const voiceProfilePath = `InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.${Number(index) + 1}`;
        const lineNumberParam = `${voiceProfilePath}.Line.1.DirectoryNumber`;
        const authUserNameParam = `${voiceProfilePath}.Line.1.SIP.AuthUserName`;
        const authPasswordParam = `${voiceProfilePath}.Line.1.SIP.AuthPassword`;
        const registrarServerParam = `${voiceProfilePath}.SIP.RegistrarServer`;
        const enableParam = `${voiceProfilePath}.Line.1.Enable`;

        // Log the settings for the current SIP account
        log('Setze Nummer: ' + sipAccount.number);
        log('Setze Authentifizierungsnamen: ' + sipAccount.sip_user);
        log('Setze Authentifizierungspasswort: ' + sipAccount.password);

        // Set the values for the current SIP account
        declare(lineNumberParam, { value: now }, { value: sipAccount.number });
        declare(authUserNameParam, { value: now }, { value: sipAccount.sip_user });
        declare(authPasswordParam, { value: now }, { value: sipAccount.password });
        declare(registrarServerParam, { value: now }, { value: "sip.stadtwerke-soest.de" });
        declare(enableParam, { value: now }, { value: "Enabled" });
    }
} else {
    log('No Voice-Data or Error');
}

Hi Milka,
certainly! It seems like your code is generally correct, but the issue might lie in the fact that you’re using a fixed path InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.* when declaring the VoiceProfile instances. This means you’re creating only two VoiceProfile instances regardless of how many SIP accounts are in your configuration file.

To fix this issue, you need to ensure that you create a corresponding VoiceProfile instance for each SIP account. To do this, you should dynamically create the path based on the index of the current SIP account in the loop.

Here’s the revised part of the code that addresses this problem:

javascript

// Ensure that the required number of VoiceProfile instances exist
for (let i = 0; i < numVoiceProfiles; i++) {
    declare(`InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.${i + 1}`, null, { path: 1 });
}

This code dynamically creates the necessary number of VoiceProfile instances based on the number of SIP accounts in your configuration file.

Hi PeterLustig,
I tried it this way and still only two numbers are installed and no third profile is created.
But the “+” Button at the interface works well…

Please do not use the method suggested. Instance ids are not guaranteed.

Use this script:


/////Voice/////
log('Setting Voice-services');
// Area code is only set once, as it is always the same
declare("InternetGatewayDevice.Services.VoiceService.*.VoiceProfile.1.Line.1.SIP.X_AVM-DE_OKZ", { value: now }, { value: config.voip.sip_account[0].area_code });

// Assumption: 'config' contains the JSON data with the SIP accounts
if (config && config.voip && config.voip.sip_account && config.voip.sip_account.length > 0) {
    // Ensure that the required number of VoiceProfile instances exist
    declare("InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.*", null, {path: 1});

    log('Number of voice profiles: ' + config.voip.sip_account.length);

    // Clear out existing entries. No changes are actually made until the end. If there is no actual changes
    // then nothing will be sent to the CPE
    declare(`${basePath}.[]`, null, {path: 0});

    const basePath = 'InternetGatewayDevice.Services.VoiceService.2.VoiceProfile';
    // Iterate over any SIP account
    for (let [index, sipAccount] of Object.entries(config.voip.sip_account)) {
        let params = {
            DirectoryNumber: sipAccount.number,
            AuthUserName: sipAccount.sip_user,
            AuthPassword: sipAccount.password,
            RegistrarServer: 'sip.stadtwerke-soest.de',
            Enable: true
        };

        const path = basePath + '.[' + Object.keys(params).map(key => key + ':' + params[key]).join(',') + ']';
        declare(path, {path: 1}, {path: 1});

        // Log the settings for the current SIP account
        log('Setze Nummer: ' + sipAccount.number);
        log('Setze Authentifizierungsnamen: ' + sipAccount.sip_user);
        log('Setze Authentifizierungspasswort: ' + sipAccount.password);
    }
} else {
    log('No Voice-Data or Error');
}

Hi akcoder,

Thank you for your assistance. I’ve attempted to implement your code and encountered the following issue:

Channel has faulted; channel="bootstrap" retries=0 faultCode="script.ReferenceError" faultMessage="Cannot access 'basePath' before initialization"

Upon moving the const basePath declaration before its usage for initialization, I seem to have encountered a loop:

Channel has faulted; channel="bootstrap" retries=0 faultCode="too_many_commits" faultMessage="Too many commit iterations"

Update: It appears that the loop occurred during the creation of the VoiceProfile.

/////Voice/////
log('Setting Voice-services');
// Area code is only set once, as it is always the same
declare("InternetGatewayDevice.Services.VoiceService.*.VoiceProfile.1.Line.1.SIP.X_AVM-DE_OKZ", { value: now }, { value: config.voip.sip_account[0].area_code });

// Assumption: 'config' contains the JSON data with the SIP accounts
if (config && config.voip && config.voip.sip_account && config.voip.sip_account.length > 0) {
    // Ensure that the required number of VoiceProfile instances exist
    declare("InternetGatewayDevice.Services.VoiceService.2.VoiceProfile.*", null, {path: 1});

    log('Number of voice profiles: ' + config.voip.sip_account.length);

    const basePath = 'InternetGatewayDevice.Services.VoiceService.2.VoiceProfile';

    // Clear out existing entries. No changes are actually made until the end. If there is no actual changes
    // then nothing will be sent to the CPE
    declare(`${basePath}.[]`, null, {path: 0});

    // Iterate over any SIP account
    for (let [index, sipAccount] of Object.entries(config.voip.sip_account)) {
        let params = {
            DirectoryNumber: sipAccount.number,
            AuthUserName: sipAccount.sip_user,
            AuthPassword: sipAccount.password,
            RegistrarServer: 'sip.stadtwerke-soest.de',
            Enable: true
        };

        const path = basePath + '.[' + Object.keys(params).map(key => key + ':' + params[key]).join(',') + ']';
        declare(path, {path: 1}, {path: 1});

        // Log the settings for the current SIP account
        log('Setze Nummer: ' + sipAccount.number);
        log('Setze Authentifizierungsnamen: ' + sipAccount.sip_user);
        log('Setze Authentifizierungspasswort: ' + sipAccount.password);
    }
} else {
    log('No Voice-Data or Error');
}
1 Like

Hi akcode,

I see, it seems that moving const basePath didn’t resolve the loop issue.

2024-03-01T19:37:40.650Z [WARN] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: CPE fault; acsRequestId="18dfb85ad51003f" cpeFaultCode="9005" cpeFaultString="Invalid parameter name"
2024-03-01T19:37:40.657Z [INFO] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: ACS request; acsRequestId="18dfb85ad510040" acsRequestName="GetParameterNames"
2024-03-01T19:37:40.709Z [INFO] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: ACS request; acsRequestId="18dfb85ad510041" acsRequestName="GetParameterNames"
2024-03-01T19:37:40.734Z [INFO] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: ACS request; acsRequestId="18dfb85ad510042" acsRequestName="GetParameterValues"
2024-03-01T19:37:40.747Z [INFO] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: ACS request; acsRequestId="18dfb85ad510043" acsRequestName="AddObject"
2024-03-01T19:37:40.755Z [INFO] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: ACS request; acsRequestId="18dfb85ad510044" acsRequestName="GetParameterValues"
2024-03-01T19:37:40.765Z [WARN] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: CPE fault; acsRequestId="18dfb85ad510044" cpeFaultCode="9005" cpeFaultString="Invalid parameter name"
2024-03-01T19:37:40.772Z [WARN] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: Channel has faulted; channel="bootstrap" retries=0 faultCode="too_many_commits" faultMessage="Too many commit iterations"
2024-03-01T19:37:40.773Z [WARN] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: Channel has faulted; channel="default" retries=0 faultCode="too_many_commits" faultMessage="Too many commit iterations"
2024-03-01T19:37:40.773Z [WARN] ::ffff:100.65.0.128 00040E-FRITZ%21Box-DC15C84E2603: Channel has faulted; channel="inform" retries=0 faultCode="too_many_commits" faultMessage="Too many commit iterations"

Changing the variables to the correct ones that the system can understand resolved the loop issue.

    for (let [index, sipAccount] of Object.entries(config.voip.sip_account)) {
        let params = {
            'Line.1.DirectoryNumber': sipAccount.number,
            'Line.1.SIP.AuthUserName': sipAccount.sip_user,
            'Line.1.SIP.AuthPassword': sipAccount.password,
            'SIP.RegistrarServer': 'sip.stadtwerke-soest.de',
            'Line.1.SIP.X_AVM-DE_OKZ': sipAccount.area_code,
            'Line.1.Enable': 'Enabled'
        };

ty @akcoder @PeterLustig for your help