"Too many commit iterations" VoIP Provision

Hello community.

We have decided to completely reinstall GenieACS with the latest version (1.2.8). Internet provisioning also works very well. We have problems with telephony provisioning. As soon as more than one phone number is assigned to the customer, we get a commit error.

We increased the MAX_ITERATIONS to 64 in “genieacs.env”. That didn’t fix the error. Where can this be adjusted? Or can we write the template differently?

BR Tim

Our config:

let prov_data = {
    "voip": {
        "sip_account": [
            {
                "id": 1,
                "number": "###SIP-Rufnummer nth (0)###",
                "area_code": "###SIP-Vorwahl-Mod0 nth (0)###",
                "sip_user": "###SIP-Benutzer nth (0)###",
                "domain": "###Registrar###",
                "password": "###SIP-Passwort nth (0)###",
                "status": "active",
                "cancelled_on": null
            },
            {
                "id": 2,
                "number": "###SIP-Rufnummer nth (1)###",
                "area_code": "###SIP-Vorwahl-Mod0 nth (1)###",
                "sip_user": "###SIP-Benutzer nth (1)###",
                "domain": "###Registrar###",
                "password": "###SIP-Passwort nth (1)###",
                "status": "active",
                "cancelled_on": null
            },
            {
                "id": 3,
                "number": "###SIP-Rufnummer nth (2)###",
                "area_code": "###SIP-Vorwahl-Mod0 nth (2)###",
                "sip_user": "###SIP-Benutzer nth (2)###",
                "domain": "###Registrar###",
                "password": "###SIP-Passwort nth (2)###",
                "status": "active",
                "cancelled_on": null
            },
        ]
    }
}

let path = "InternetGatewayDevice.Services.VoiceService.2.VoiceProfile."

for (let [index, account] of Object.entries(prov_data.voip.sip_account)) {
    let elementExists = declare(path + account.id + ".Line.1.DirectoryNumber", { value: 1, object: 1 }, null);
     if (account.number !== "" ) {
       if (elementExists.value) {
updateProfile(account);       
       } else {
addNewProfile(account);   
       }
     }
}

declare("InternetGatewayDevice.Services.VoiceService.2.VoiceProfileNumberOfEntries", { path: Date.now() }, { value: prov_data.voip.sip_account.length });

function updateProfile(account) {
let identifier = path + account.id;
let now = Date.now();
declare(identifier + ".Enable", { path: now }, { value: "Enabled" });
declare(identifier + ".SIP.RegistrarServer", { path: now }, { value: account.domain });
declare(identifier + ".Line.1.SIP.AuthUserName", { path: now }, { value: account.sip_user });
declare(identifier + ".Line.1.SIP.AuthPassword", { path: now }, { value: account.password });
declare(identifier + ".Line.1.SIP.X_AVM-DE_CountryCode", { path: now }, { value: "49" });
declare(identifier + ".Line.1.SIP.X_AVM-DE_OKZ", { path: now }, { value: account.area_code });
declare(identifier + ".Line.1.SIP.X_AVM-DE_ProtocolPrefer", { path: now }, { value: 1 });
declare(identifier + ".Line.1.SIP.X_AVM-DE_CallingFeatures", { path: now }, { value: 0 });
declare(identifier + ".DTMFMethod", { path: now }, { value: "RFC2833" });
declare(identifier + ".X_AVM-DE_BackupConnectionFailOver", { path: now }, { value: "false" });
declare(identifier + ".Line.1.SIP.X_AVM-DE_CLIRType", { path: now }, { value: 6 });
declare(identifier + ".Line.1.DirectoryNumber", { path: now }, { value: account.number });
declare(identifier + ".X_AVM-DE_GUI_ReadOnly", { path: now }, { value: "false" });
declare(identifier + ".X_AVM-DE_route_always_over_internet", { path: now }, { value: "true" });
}

function addNewProfile(account) {
let identifier = path + account.id;
let now = Date.now();
    declare(path + "[X_AVM-DE_EPC:" + account.number + "]", { path: now }, { path: 1});
    commit();
    declare(identifier + ".Enable", { path: now }, { value: "Enabled" });
    declare(identifier + ".SIP.RegistrarServer", { path: now }, { value: account.domain });
    declare(identifier + ".Line.1.SIP.AuthUserName", { path: now }, { value: account.sip_user });
    declare(identifier + ".Line.1.SIP.AuthPassword", { path: now }, { value: account.password });
    declare(identifier + ".Line.1.SIP.X_AVM-DE_CountryCode", { path: now }, { value: "49" });
    declare(identifier + ".Line.1.SIP.X_AVM-DE_OKZ", { path: now }, { value: account.area_code });
    declare(identifier + ".Line.1.SIP.X_AVM-DE_ProtocolPrefer", { path: now }, { value: 1 });
    declare(identifier + ".Line.1.SIP.X_AVM-DE_CallingFeatures", { path: now }, { value: 0 });
    declare(identifier + ".DTMFMethod", { path: now }, { value: "RFC2833" });
    declare(identifier + ".X_AVM-DE_BackupConnectionFailOver", { path: now }, { value: "false" });
    declare(identifier + ".Line.1.SIP.X_AVM-DE_CLIRType", { path: now }, { value: 6 });
    declare(identifier + ".Line.1.DirectoryNumber", { path: now }, { value: account.number });
    declare(identifier + ".X_AVM-DE_GUI_ReadOnly", { path: now }, { value: "false" });
    declare(identifier + ".X_AVM-DE_route_always_over_internet", { path: now }, { value: "true" });
}

declare("Tags.voip", null, {value: true});
return;

We have now added the following under admin > config:

cwmp.maxCommitIterations(value “64”). Then the error comes again. If we also raise that to 128, we get an "internal error “9002”.

What else do we need to adjust?

BR

First, remove the config change. Next, enable debug mode (instructions can be found by searching the forum) and review the debug log carefully. Its highly likely you have dueling provision scripts/presets. Example, one sets a value to true, and another sets the value to false.

Second, remove line 51, *NumberOfEntries are parameters are not writable. You control the number of entries by adding/removing objects. Adapt this code for your needs. Line 24 tells GenieACS to remove all entries for the given base path. No actual changes are made until after the for loop when GenieACS reconciles the desired changes, with the actual changes that need to happen. You need to do things this way because you cannot control the instance numbers the CPE assigns.

Here is a quick stab I took, you will need to fill in the missing data obviously. Line 59 clears the slate. Line 62 builds the full instance path and line 66 does the declaration.

let prov_data = [
    {
        "Line.1.DirectoryNumber": "some_value",
        "Enable": true,
        "X_AVM-DE_EPC": "###SIP-Rufnummer nth (0)###",
        "Line.1.SIP.X_AVM-DE_OKZ": "###SIP-Vorwahl-Mod0 nth (0)###",
        "Line.1.SIP.AuthUserName": "###SIP-Benutzer nth (0)###",
        ".SIP.RegistrarServer": "###Registrar###",
        "Line.1.SIP.AuthPassword": "###SIP-Passwort nth (0)###",
        "Line.1.SIP.X_AVM-DE_CountryCode": 49,
        "Line.1.SIP.X_AVM-DE_ProtocolPrefer": 1,
        "Line.1.SIP.X_AVM-DE_CallingFeatures": 0,
        "DTMFMethod": 'RFC2833',
        "X_AVM-DE_BackupConnectionFailOver": false,
        "Line.1.SIP.X_AVM-DE_CLIRType": 6,
        "X_AVM-DE_GUI_ReadOnly": false,
        "X_AVM-DE_route_always_over_internet": true,

    },
    {
        "Line.1.DirectoryNumber": "some_value",
        "Enable": true,
        "X_AVM-DE_EPC": "###SIP-Rufnummer nth (1)###",
        "Line.1.SIP.X_AVM-DE_OKZ": "###SIP-Vorwahl-Mod0 nth (1)###",
        "Line.1.SIP.AuthUserName": "###SIP-Benutzer nth (1)###",
        ".SIP.RegistrarServer": "###Registrar###",
        "Line.1.SIP.AuthPassword": "###SIP-Passwort nth (1)###",
        "Line.1.SIP.X_AVM-DE_CountryCode": 49,
        "Line.1.SIP.X_AVM-DE_ProtocolPrefer": 1,
        "Line.1.SIP.X_AVM-DE_CallingFeatures": 0,
        "DTMFMethod": 'RFC2833',
        "X_AVM-DE_BackupConnectionFailOver": false,
        "Line.1.SIP.X_AVM-DE_CLIRType": 6,
        "X_AVM-DE_GUI_ReadOnly": false,
        "X_AVM-DE_route_always_over_internet": true,

    },
    {
        "Line.1.DirectoryNumber": "some_value",
        "Enable": true,
        "X_AVM-DE_EPC": "###SIP-Rufnummer nth (2)###",
        "Line.1.SIP.X_AVM-DE_OKZ": "###SIP-Vorwahl-Mod0 nth (2)###",
        "Line.1.SIP.AuthUserName": "###SIP-Benutzer nth (2)###",
        ".SIP.RegistrarServer": "###Registrar###",
        "Line.1.SIP.AuthPassword": "###SIP-Passwort nth (2)###",
        "Line.1.SIP.X_AVM-DE_CountryCode": 49,
        "Line.1.SIP.X_AVM-DE_ProtocolPrefer": 1,
        "Line.1.SIP.X_AVM-DE_CallingFeatures": 0,
        "DTMFMethod": 'RFC2833',
        "X_AVM-DE_BackupConnectionFailOver": false,
        "Line.1.SIP.X_AVM-DE_CLIRType": 6,
        "X_AVM-DE_GUI_ReadOnly": false,
        "X_AVM-DE_route_always_over_internet": true,
    },
];

let path = "InternetGatewayDevice.Services.VoiceService.2.VoiceProfile."

declare(path + ".[]", null, {path: 0});

for (let data of prov_data) {
    const path = path + '.[' + Object.keys(data).map(function (key) { return key + ':' + data[key]; }).join(',') + ']';

    log("\r\n\r\nVoiceProfile - " + path + "\r\n\r\n", data);

    declare(path, {path: 1}, {path: 1});
}

Hello akcoder. Thank you in advance for your help! Your configuration is actually completely different.

But runs on a “path” error. We tried to enable the log in genieacs.env (see source code below). We also gave the rights to the GenieACS user. Unfortunately the “yaml” is not written. We added “cwmp.debug” with the CWMP ID of the FRITZ!Box under admin > config.

Do you know what’s going wrong? Do we still need to set up the GenieACS user in the GUI?

GENIEACS_CWMP_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-cwmp-access.log
GENIEACS_NBI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-nbi-access.log
GENIEACS_FS_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-fs-access.log
GENIEACS_UI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-ui-access.log
GENIEACS_DEBUG_FILE=/var/log/genieacs/genieacs-debug.yaml
NODE_OPTIONS=--enable-source-maps
GENIEACS_EXT_DIR=/opt/genieacs/ext

GENIEACS_UI_JWT_SECRET= very_secret_secret

Unless you are in a production environment, I would just enable debug. (cwmp.debug = true).

Regardless of how you go about it, you cannot trust that instance ids are the same. Hence why I reworked your provision script. The code I wrote does not depend on a specific instance ids.

Hey akcoder.

We’re having trouble creating a log that gives you meaningful impressions.

Should we use your script or our own for VoiP?

We looked at the yaml file and couldn’t find anything similar for VoiP with your script. So we think it’s wrong.

We’re really not great Linux professionals. Basic knowledge is available.

BR

I would use mine, but check that everything matches what you expect. My script does not rely on instance ids, which you cannot rely on being the same between devices.

Have you verified permissions to the log dir? Are there other log entries in /var/log/genieacs/? When you enabled debug, did you enter the value with no quotes?

image

Hello akcoder.

I think we’re talking past each other a bit. Probably because I phrased it wrong.

So this:

The cwmp.debug is enabled. We have the value set to true with no quotes. We have also entered all logs in genieacs.env.
image

The genieacs-debug.yaml file is also permanently populated by all devices. We also see all possible requests there, but no log for VoiP, as in your script below. log("\r\n\r\nVoiceProfile - " + path + “\r\n\r\n”, data);

So theoretically everything works, but as soon as something runs into an error, the FRITZ!Box doesn’t do anything. And since your script hits an error, not a single value is set either. The internet provisioning doesn’t work either because the VoIP script runs into an error.

Thank you for your patience with us :wink:

BR Tim