📜 ⬆️ ⬇️

And we decided to make friends with Baresip and Nodejs

What is Baresip? As stated on the project site, this is a cross-platform, modular SIP agent with audio and video support.

And where does nodejs? Yes, it turned out that in a large project written on nodejs and using Freeswitch and its portaudio module due to the incorrect work of the latter, it was necessary to implement another sip client for audio calls.

The choice during the technical meeting of one of our developers with Google fell on Baresip.
')

Main tasks:



The result is a small npm module node_baresip

Link to baresip page

Search api


Since baresip is a console utility, I decided that for sure there is either a library or some way of interacting with the running application.
And I was right but not until the end :)

As it turned out in baresip, everything is tied to text commands and can be entered via:

This hardcore api :)

For the first implementation, I chose http.

Implement node_baresip


Sending commands will look like this:
Call console
d sip:user@domain.com 

Call via http
 http://127.0.0.1:8000/?duser@domain.com 


Baresiphttpwrapper.js was written with a generic interface:

Later you can either write a normal api and make another wrapper, or wait for someone to write it and rewrite the wrapper :)

Further the main file of the baresip.js module is implemented

To track the status, you have to request a list of calls every 2 seconds and determine which calls are old, which were completed, which outgoing calls and which incoming calls and issue the corresponding events:
Code
 self.intervalObject = setInterval( function(){ self.baresipWrapper.getCallList( function( err, callList){ if( err){ console.log( "Error get call list:", err, config); var callList = []; } var esatblishedCalls = self.findEsatblishedCalls( callList); var newCalls = self.findNewCalls( callList); var deleteCalls = self.findDeletedCalls( callList); for (var i in newCalls){ // ADD CALL self.callList[newCalls[i].sip] = newCalls[i]; self.callList[newCalls[i].sip].id = self.generateCallId(); self.emit( "new_call", self.callList[newCalls[i].sip]); if( newCalls[i].status == "INCOMING") { self.emit("incoming_call", newCalls[i]); } else if( newCalls[i].status == "ESTABLISHED"){ self.emit( "established_call", self.callList[newCalls[i].sip]); } } for (var i in deleteCalls){ delete self.callList[deleteCalls[i].sip]; self.emit( "end_call", deleteCalls[i]); } for( var i in esatblishedCalls) { self.callList[esatblishedCalls[i].sip].status = "ESTABLISHED"; self.emit( "established_call", esatblishedCalls[i]); } }); }, self.callListMonitorTimeout); 


Developments

I made the control interface almost the same as in the wrapper.


Funny baresip surprises




If the last 2 can be solved by simple checks, then the first one took some time.
Initially, I tried to enter a call identifier into the baresip code to control any call via api, but since I know C badly realize a cross-platform code that can generate unique identifiers I could not.
A simpler decision was made. I added the command for setting the previous call to hold; it was even added to the baresip code itself. This minor revision decided to solve the problems and did not have to go further.

Impressions


The baresip itself turned out to be a very reliable cross-platform sip agent with a large set of codecs and various modules, only the interaction interface pumped up :)

PS:
Finally, we added the active call setting on hold before answering the incoming call :)
github.com/alfredh/baresip/commit/25225de72f2ba6c89abe862e2e027906c9ef8a76

Source: https://habr.com/ru/post/263681/


All Articles