Genieacs API - addObject doesn't return instance ID

Hi there,
Using version 1.1.

My use case is that I want to add a port forward via API. In order to do this I need to add a ‘PortForward’ instance.

I post the data as follows:

‘{ “name”: “addObject”, “objectName”: “InternetGatewayDevice.WANDevice.3.WANConnectionDevice.1.WANIPConnection.4.PortMapping” }’

This works fine. However the object returned by Genie doesn’t include the instance number:

{“name”:“addObject”,“objectName”:“InternetGatewayDevice.WANDevice.3.WANConnectionDevice.1.WANIPConnection.4.PortMapping”,“device”:“18F145-NF18ACV-180611503777”,“timestamp”:“2019-10-16T00:08:30.339Z”,“_id”:“5da65f7efc3b3a332e6d08f3”}

Here is the actual response from the CPE:

<cwmp:AddObjectResponse>
<InstanceNumber>5</InstanceNumber>
<Status>0</Status>
</cwmp:AddObjectResponse>

How can I get the instance number from Genie without having to then query again for the highest instance number (not guaranteed to be correct either)

Thanks,

David.

So… I’ve battled this exact use case before and I can tell you to quote Steve Jobs, your “holding (doing) it wrong” :slight_smile:

First off, because of the underlying async nature of how communication with the CPE occurs, its going to be near impossible to get the instance ID. Genie does a good job of trying to make the async communication with the CPE appear synchronous, but at a fundamental level the addObject could actually occur at any point in time (now, or hours from now).

So here is how you want to handle this.

Create a provision script called PortForwards using this code.

Create a preset like so called UpdatePortForwards with a tag precondition of “UpdatePortForwards” and under configuration add a provision script and put in “PortForwards”.

In your genieacs/config/ext folder put the cpe-config.js file using this code.

Have your API return code that looks like this:

[
  {
    "InternalClient": "192.168.1.2",
    "PortMappingDescription": "Foo",
    "PortMappingProtocol": "TCP",
    "PortMappingEnabled": 1,
    "RemoteHost": "",
    "InternalPort": 8080,
    "ExternalPort": 8080,
    "ExternalPortEndRange": 8080
  }
]

Where each array entry maps directly to a key/value for an instance in PortMapping.

Finally, add the tag UpdatePortForwards to the CPE in GenieACS and initiate a connection with the CPE.

While this whole process may seem more complicated initially, it will always ensure the port forwarding instances are created/deleted as needed.

I’ve had this code in production for two years with absolutely zero issues.

2 Likes

You’re the man Dan.

Like most great things in life, I figured this out in the shower this morning.

Yes - my architecture was wrong.

I was trying to do this without maintaining state in my provisioning API - which is nigh on impossible. If I maintan the end state, everything gets a lot easier.

Really appreciate your help and the code!

:grinning:

Maintaining state has its own set of dragons. Embrace the stateless :slight_smile:. Using the code/technique I use I do not have to maintain state at all in my subscriber management system. I only have to maintain what I desire things to look like and let Genie take care of making the CPE match what its supposed to be.

-dan