XMPP support for GenieACS

I’ve been trying to get XMPP to work with GenieACS. It’s still a proof-of-concept, but it works. Tested with Nokia Beacon. The config locks it to only one XMPP server, and the UI and NBI connects when starting. Node library I’m using seems pretty solid as I have never experienced the XMPP connection getting lost.

There are a few “issues”:

  • XMPP servers requires unique usernames, and UI and NBI combined is atleast 6 sessions which means that the same username is used 6 times. I’m using different resources to try to get around this. Ejabberd should be able to accept this with the correct config.
  • No support for multiple XMPP domains.
  • No logging.
  • I’m terrible at nodeJS. The code is limited by my knowledge.

Is there any interest in XMPP support for GenieACS? If so I may need some help to do this correctly.

2 Likes

@zaidka, could you have a look? We’re running this code (@naalhode is a coworker) , but it would be great if it could find its way upstream.

Hi naalhode,

I would be interested to include the XMPP support for GenieACS in my TR-069 environment. Where can I find your proof-of-concept, have I just to update?

Best regards,
Christian

@naalhode @gittela Appreciate the effort, however I too recently implemented support for XMPP. Sorry I didn’t publish the code sooner which would have saved you time and effort. I’ll publish the code later today. Perhaps you can compare that with your own implementation and suggest fixes or improvements.

1 Like

'Doh! Oh well, I guess @naalhode will be more than happy to let go of the extra code maintenance…
What kind of functionality are you implementing? We’re already using this and I hope we can swap out our version with yours.

Do you think you’ll have the new version with xmpp out by this week?

Great news as I am also interested in XMPP support for GenieACS, will you be able to publish the new code this week?

Many thanks!

@naalhode, @gittela I just published the code last night. See ‘xmpp’ branch. Sorry I didn’t have the time to do that last week. This won’t be merged with master until the next major release (probably 1.3). But I don’t expect that to take long anyway as I want to quickly get it out the door to focus on 2.0.

Curious to hear your thoughts about how this compares to your own implementation and what things you might have done differently.

Here’s some instructions how to configure XMPP:

1- Install an XMPP server. No special requirements here. Any XMPP server should do the job fine.

2- Add the correct SRV DNS record for your XMPP server. See https://wiki.xmpp.org/web/SRV_Records. Also make sure to add A and AAAA records for the same domain.

3- Create two XMPP users, one for Genie, and one for your CPEs. Note that all your CPEs will be using the same XMPP user. We’ll use the following two users as examples:

ACS user: acs@xmpp.example.com
Passwrod: password1

CPE user: cpe@xmpp.example.com
Passwrod: password2

4- Pass the env vars GENIEACS_XMPP_JID and GENIEACS_XMPP_PASSWORD to Genie. If you’ve used the official GenieACS installation guide, those need to go in /opt/genieacs/genieacs.env. The first var should hold the XMPP user that Genie should use (e.g. acs@xmpp.example.com). While the second one is the password for that user. Make sure to restart genieacs-nbi and genieacs-ui after making this change.

GENIEACS_XMPP_JID=acs@xmpp.example.com
GENIEACS_XMPP_PASSWORD=password1

5- Modify the provision script ‘inform’ by adding the following:

declare("InternetGatewayDevice.XMPP.Connection.*", {path: daily, value: daily}, {path: 1});
declare("InternetGatewayDevice.XMPP.Connection.*.Enable", {path: daily, value: daily}, {value: true});
declare("InternetGatewayDevice.XMPP.Connection.*.Username", {path: daily, value: daily}, {value: "cpe"});
declare("InternetGatewayDevice.XMPP.Connection.*.Password", {path: daily, value: daily}, {value: "password2"});
declare("InternetGatewayDevice.XMPP.Connection.*.Resource", {path: daily, value: daily}, {value: username});
declare("InternetGatewayDevice.XMPP.Connection.*.Domain", {path: daily, value: daily}, {value: "xmpp.example.com"});
declare("InternetGatewayDevice.ManagementServer.ConnReqAllowedJabberIDs", {path: daily, value: daily}, {value: "acs@xmpp.example.com"});
3 Likes

FYI resolved both issues. the 500 error was resolved with updating the node.js

Still having some issues as genieACS does not seem to register to xmpp correctly. Working on it.

@zaidka I’ve been following up the method in your comment but I genieACS is not making any attempts for communicating with the xmpp server, I can see this with tcpdump.

how can I see what’s the problem ? Is there a specific debug logging I can enable ?

@gittela , naalhode how did you fare?

Many thanks
Ert

I haven’t had time to test the official version yet, we’re still running our own custom installation. Will try to get around it today or next week.

1 Like

It only connects to the XMPP server when necessary to make a connection request. Make sure the CPE is connected and is reporting a Jabber ID.

Hi Zaidka,
The ACS Server communicated to the CPE and push the XMPP configuration to the CPE, but we dont see any communication between ACS and XMPP.

I am not an expert in XMPP/ACS and this is first time trying this out. In the steps metioned above , there is reference to SRV record. Can you tell me know how to create and make ACS point to the XMPP server - Thanks!

Regard,Dinesh

@zaidka I use ejabberd as the xmpp server. The registration between CPE and XMPP is successful. The ACS installed the xmpp branch version, but no interaction log with ACS can be seen in the log of xmpp server, and there is no log in the log of genieacs. , Can’t judge whether ACS and XMPP are communicating normally, check the above information, “It only connects to the XMPP server when necessary to make a connection request. Make sure the CPE is connected and is reporting a Jabber ID.” How to judge the CPE report jabberID? The log in ACS nbi is always empty

The CPE should report the parameter Device.ManagementServer.ConnReqJabberID in the inform message. Try refreshing that param manually if it’s not reported by default. If that parameter is present and has a value, then it’ll attempt to connect to the XMPP server when issuing a connection request.

I’m still blocked. Seems I’m doing everything right but I don’t observer any messages from GenieACS to XMPP server. Any pointers more than welcome dear friends.

I use the xmpp branch on git, The xmpp server use ejabberd. From the log message,I find XMPP server send out a bind message,but genieacs does not respond.
XMPP Server send (I remove “<”):

stream:features>
bind xmlns=‘urn:ietf:params:xml:ns:xmpp-bind’/>
session xmlns=‘urn:ietf:params:xml:ns:xmpp-session’>
optional/>
/session>
c ver=‘NqMDrgCx03HLh3URMusgDnNsR30=’ node=‘http://www.process-one.net/en/ejabberd/’ hash=‘sha-1’
xmlns=‘http://jabber.org/protocol/caps’/>
sm xmlns=‘urn:xmpp:sm:2’/>
sm xmlns=‘urn:xmpp:sm:3’/>
ver xmlns=‘urn:xmpp:features:rosterver’/>
csi xmlns=‘urn:xmpp:csi:0’/>
/stream:features>

But , genieacs no bind response.
In git xmpp-clients.ts line 297:
else if (feature.name ===‘bind’)(
** if (feature.children.some(©=> c.name === ‘required’)){**
** yield* bind(socket,resource);**
** return 0;**
}
This code shouldn’t be reached, is there a problem? can you help to check?

About Device.ManagementServer.ConnReqJabberID in the inform I have a question:
For the CPE behind Nat, its wan ip is a private address, and the ACS can only receive the request. When the ACS refreshes this object, it will report the “Device is offline” error, because the ACS cannot ping the CPE, but the CPE can ping the ACS. Without this object
‘Device.ManagementServer.ConnReqJabberID’, the ACS cannot communicate with the XMPP server. Is this a problem?

No errors or exceptions from Genie side? Can you share packet capture of the full exchange?

That’s fine. The CPE should report the Jabber ID as soon as it connects with the XMPP server by means of sending an Inform message.

I remove this code: if (feature.children.some(©=> c.name === ‘required’)){** and then re-build ,now it works to me.

else if (feature.name ===‘bind’)(
** yield* bind(socket,resource);**
** return 0;**

1 Like