Use SIP over TCP and RTP to create a RingCentral device

Tyler Liu
RingCentral Developers
4 min readMar 18, 2021

I wrote an article titled How to Programmatically Create a RingCentral Device. In that article, I provide all the details on how to programmatically create a RingCentral device. From a technical perspective, it uses SIP over WebSocket and WebRTC. It is not the only technical stack to create a RingCentral device. In this article, I am going to introduce another technical stack: SIP over TCP and RTP. Another notable difference of this article from the previous article is we used C# instead of JavaScript for the implementation.

Provision a SIP device via Restful API

Just as we did in How to Programmatically Create a RingCentral Device, the first step is to invoke this Rest API to provision a sip device:

Please note that, this time we specified transport as TCP instead of WSS. And device.computerName is required, here we simply use the machine name. As I tested, you can use any string as device.computerName and it doesn’t affect the experiment we are going to do.

sipInfo is the following data structure:

Register the device via SIP over TCP

We will make a TCP connection to sipInfo.outboundProxy :

using var client = new TcpClient();
var tokens = sipInfo.outboundProxy.Split(":");
await client.ConnectAsync(tokens[0], int.Parse(tokens[1]));

We then send the first REGISTER command:

The data structure above is similar to the one we mentioned in How to Programmatically Create a RingCentral Device, please refer to that article for more details.

TCP server side will return immediately:

followed by:

There is one line in the header part which is required in next step:

WWW-Authenticate: Digest realm="sip.ringcentral.com", nonce="YBxDcWAcQkWj6uL63rFVzAqUCMbimtSK"

We can extract the nonce value from the WWW-Authenticate header above and calculate a new Authorization header:

With the auth calculated we send a new REGISTER command:

This time, if everything goes as expected, server side will return immediately:

Registration is done, hooray!

Answer a phone call and get RTP audio data

Whenever there is an incoming call to our device, the TCP client will receive a message like this:

The message has three parts. The first line is the subject, remaining parts are the headers and the body which are separated by a blank line.

The body part is called SDP: Session Description Protocol. We need to reply to the message, with our own SDP body. But how to generate such a SDP string for reply? We need the help of a library named sipsorcery. In the code sample below, most of the classes are from the sipsorcery library:

So we create a RTPSession instance and we add an audio track to it. The audio format is PCMU which is very well known and supported by all kinds of platforms and SIP devices.

Then we set the remote description (remote SDP) followed by creating an answer. The answer is our local SDP, and we can call answer.ToString to get the SDP string.

With answer SDP ready, we can reply to the invite message:

How do we receive remote audio data? The audio data is transferred as RTP packets:

rtpSession.OnRtpPacketReceived +=
(IPEndPoint remoteEndPoint, SDPMediaTypesEnum mediaType, RTPPacket rtpPacket) =>
{
Console.WriteLine("OnRtpPacketReceived");
};

We simply print a message to the console. You may want to save the packets to an audio file or play them with the speaker. It is left as an exercise to the readers.

Last but not least, if the RTP packets do not come as expected, add the following magic line:

await rtpSession.SendDtmf(0, CancellationToken.None);

The purpose of sending a DTMF tone is if our SDP had a private IP address then the server needs to get at least one RTP packet to know where to send.

Summary

In this article, we built a RingCentral device from scratch using Restful API to provision a device, we used SIP over TCP to register the device and finally we answered an inbound call and used RTP to get audio data.

Source code

Please refer to the RingCentral.Softphonoe.Net SDK. Here is a screenshot of it working:

Please let us know what you think by leaving your questions and comments below. To learn even more about other features we have make sure to visit our developer site and if you’re ever stuck make sure to go to our developer forum.

Want to stay up to date and in the know about new APIs and features? Join our Game Changer Program and earn great rewards for building your skills and learning more about RingCentral!

--

--