Websockets as VOIP signal transport medium

Web resources are usually build on request/response paradigm such as HTTP , SIP messages . This means that server responds only when a client requests it to. This made web intercations very slow and unsuited for VOIP signalling
Long Poll involved repeated polling checks to load new server resources by itself instead of client made explicit request
AJAX and multipart XHR tried to patch the problem by selective reloading however they still required that client perform the mapping for an incomig reply to map to correct request.
However due to overhead latency involved with HTTP transaction and its working mode to open new TCP connetion for every request and reponse and add HTTP headers, none of them were suited to realtime operations

Websocket is the current (2017) most idelistic solution to perform realtime sigalling suited to VOIP requirnments due to its nature os establish a socket .

Websocket Protocol

Enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code.

protocol consists of an opening handshake followed by basic message framing, layered over TCP.
handshake is interpreted by HTTP servers as an Upgrade request.

Secure websocket example :

Request URL: wss://site.com:8084/socket.io/?transport=websocket&sid=hh3Dib_aBWgqyO1IAAEL
Request Method: GET
Status Code: 101 Switching Protocols

Response Headers
Connection: Upgrade
Sec-WebSocket-Accept: UVhTdFOWfywGyQTKDRZyGuhkfls=
Sec-WebSocket-Extensions: permessage-deflate
Upgrade: websocket

Request Headers
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: Upgrade
Host: site.com:8085
Origin: https://site.com:8084
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: 06FNaHge8GLGVuPFxV2fAQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36

Query String parameters
transport: websocket
sid: hh3Dib_aBWgqyO1IAAEL

Working with websockets

A new websocket can be opned with ws or wss and it can have sub protocols like in example .

var wsconnection = new WebSocket('wss://voipsever.com', ['soap', 'xmpp']);

It can be attached with event handlers

wsconnection.onopen = function () {
wsconnection.onerror = function (error) {
  console.log('WebSocket Error ' + error);
wsconnection.onmessage = function (e) {
  console.log('message received : ' + e.data);

Send Data on websocket

message string


Blob or ArrayBuffer object to send binary data
Ex : Sending canvas ImageData as ArrayBuffer

var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];

Ex : sending file as Blob

var file = document.querySelector('input[type="file"]').files[0];

Closing the connection

if (socket.readyState === WebSocket.OPEN) {

Registry for Close codes for WS
1000 Normal Closure [IESG_HYBI] [RFC6455]
1001 Going Away [IESG_HYBI] [RFC6455]
1002 Protocol error [IESG_HYBI] [RFC6455]
1003 Unsupported Data [IESG_HYBI] [RFC6455]
1004 Reserved [IESG_HYBI] [RFC6455]
1005 No Status Rcvd [IESG_HYBI] [RFC6455]
1006 Abnormal Closure [IESG_HYBI] [RFC6455]
1007 Invalid frame payload data [IESG_HYBI] [RFC6455]
1008 Policy Violation [IESG_HYBI] [RFC6455]
1009 Message Too Big [IESG_HYBI] [RFC6455]
1010 Mandatory Ext. [IESG_HYBI] [RFC6455]
1011 Internal Error [IESG_HYBI] [RFC6455][RFC Errata 3227]
1012 Service Restart [Alexey_Melnikov] [http://www.ietf.org/mail-archive/web/hybi/current/msg09670.html]
1013 Try Again Later [Alexey_Melnikov] [http://www.ietf.org/mail-archive/web/hybi/current/msg09670.html]
1014 The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to 502 HTTP Status Code. [Alexey_Melnikov] [https://www.ietf.org/mail-archive/web/hybi/current/msg10748.html]
1015 TLS handshake [IESG_HYBI] [RFC6455]
1016-3999 Unassigned
4000-4999 Reserved for Private Use [RFC6455]

WebSocket Subprotocol Name Registry

  • MBWS.huawei.com MBWS
  • MBLWS.huawei.com MBLWS
  • soap soap
  • wamp WAMP (“The WebSocket Application Messaging Protocol”)
  • v10.stomp Name: STOMP 1.0 specification
  • v11.stomp Name: STOMP 1.1 specification
  • v12.stomp Name: STOMP 1.2 specification
  • ocpp1.2 OCPP 1.2 open charge alliance
  • ocpp1.5 OCPP 1.5 open charge alliance
  • ocpp1.6 OCPP 1.6 open charge alliance
  • ocpp2.0 OCPP 2.0 open charge alliance
  • ocpp2.0.1 OCPP 2.0.1
  • rfb RFB [RFC6143]
  • sip WebSocket Transport for SIP (Session Initiation Protocol) [RFC7118]
  • notificationchannel-netapi-rest.openmobilealliance.org OMA RESTful Network API for Notification Channel
  • wpcp Web Process Control Protocol (WPCP)
  • amqp Advanced Message Queuing Protocol (AMQP) 1.0+
  • mqtt mqtt [MQTT Version 5.0]
  • jsflow jsFlow pubsub/queue protocol
  • rwpcp Reverse Web Process Control Protocol (RWPCP)
  • xmpp WebSocket Transport for the Extensible Messaging and Presence Protocol (XMPP) [RFC7395]
  • ship SHIP – Smart Home IP SHIP (Smart Home IP) is a an IP based approach to plug and play home automation and smart energy / energy efficiency, which can easily be extended to additional domains such as Ambient Assisted Living (AAL). SHIP can be used solely on the customer premises or can be integrated into a cloud based solution.
  • mielecloudconnect Miele Cloud Connect Protocol This protocol is used to securely connect household or professional appliances to an internet service portal via a public communication network in order to enable remote services.
  • v10.pcp.sap.com Push Channel Protocol
  • msrp WebSocket Transport for MSRP (Message Session Relay Protocol) [RFC7977]
  • v1.saltyrtc.org
  • TLCP-2.0.0.lightstreamer.com TLCP (Text Lightstreamer Client Protocol)
  • bfcp WebSocket Transport for BFCP (Binary Floor Control Protocol)
  • sldp.softvelum.com Softvelum Low Delay Protocol SLDP is a low latency live streaming protocol for delivering media from servers to MSE-based browsers and WebSocket-enabled applications.
  • opcua+uacp OPC UA Connection Protocol
  • opcua+uajson OPC UA JSON Encoding
  • v1.swindon-lattice+json Swindon Web Server Protocol (JSON encoding)
  • v1.usp USP (Broadband Forum User Services Platform)
  • mles-websocket mles-websocket
  • coap Constrained Application Protocol (CoAP) [RFC8323]
  • TLCP-2.1.0.lightstreamer.com TLCP (Text Lightstreamer Client Protocol)
  • sqlnet.oracle.com sqlnet This protocol is used for communication between Oracle database client and database server, and its usage as subprotocol of websocket is primarly geared towards cloud deployments. sqlnet supports bi-directional data transfer and is full duplex in nature.
  • oneM2M.R2.0.json oneM2M R2.0 JSON
  • oneM2M.R2.0.xml oneM2M R2.0 XML
  • oneM2M.R2.0.cbor oneM2M R2.0 CBOR
  • transit Transit
  • 2016.serverpush.dash.mpeg.org MPEG-DASH-ServerPush-23009-6-2017
  • 2018.mmt.mpeg.org MPEG-MMT-23008-1-2018
  • webrtc.softvelum.com Softvelum WebSocket signaling protocol WebRTC live streaming requires WebSocket-based signaling protocol for every specific implementation. Softvelum products will use this subprotocol for signaling

websocket libraries

C++: libwebsockets
Erlang: Shirasu.ws
Java: Jetty
Node.JS: ws
PHP: Ratchet, phpws

Ref :
RFC 6455 – The websocket protocol
Websocket Protocol Registeries : http://www.iana.org/assignments/websocket/websocket.xml
IANA websocket -https://www.iana.org/assignments/websocket/websocket.xhtml


SIP stack written in C. Available under GPL

pjsip dev guide architecture diagram

PJSip user agent

local_info+tag, local_contact,

pj_status_t pjsip_ua_init(endpt, param);
pj_status_t pjsip_ua_destroy(void);
pjsip_module* pjsip_ua_instance(void);
pjsip_endpoint* pjsip_ua_get_endpt(ua);

PJSip dialog


state, session_counter, initial_cseq, local_cseq, remote_cseq, route_set,

local_info+tag, local_contact, remote_info+tag, remote_contact, next_set


pj_status_t pjsip_dlg_create_uac(ua, local_uri, contact, …);
pj_status_t pjsip_dlg_create_uas(ua, rdata, contact, &dlg);
pj_status_t pjsip_dlg_fork(old_dlg,rdata,&dlg);
pj_status_t pjsip_dlg_set_route_set(dlg, route_set);
pj_status_t pjsip_dlg_inc_session(dlg);
pj_status_t pjsip_dlg_dec_session(dlg);
pj_status_t pjsip_dlg_add_usage(dlg, mod);
pj_status_t pjsip_dlg_create_request(dlg,method,cseq,&tdata);
pj_status_t pjsip_dlg_send_request(dlg,tdata,&tsx);
pj_status_t pjsip_dlg_create_response(dlg,rdata,code,txt,&tdata);
pj_status_t pjsip_dlg_modify_response(dlg,tdata,code,txt);
pj_status_t pjsip_dlg_send_response(dlg,tsx,tdata);
pj_status_t pjsip_dlg_send_msg(dlg,tdata);
pjsip_dialog* pjsip_tsx_get_dlg(tsx);
pjsip_dialog* pjsip_rdata_get_dlg(rdata);

PJsip module

Attributes: name, id, priority, …

pj_bool_t on_rx_request(rdata);
pj_bool_t on_rx_response(rdata);
void on_tsx_state(tsx,event);

SDP state Offer/ Answer transition

SDP negotiator structure

SDP negotiator class diagram PJSIP dev guide


Pre requisities :

GNU make (other make will not work),
GNU binutils for the target, and
GNU gcc for the target.
In addition, the following libraries are optional, but they will be used if they are present:

ALSA header files/libraries (optional) if ALSA support is wanted.
OpenSSL header files/libraries (optional) if TLS support is wanted.

Video support

Video4Linux2 (v4l2) development library
​ffmpeg development library for video codecs: H.264 (together with libx264) and H263P/H263-1998.
Simple DirectMedia Layer SDL
libyuv for format conversion and video manipulation / Ffmpeg
OpenH264 / VideoToolbox (only for Mac) / ffmpeg

get tar and untar sourcecode

wget https://www.pjsip.org/release/2.9/pjproject-2.9.tar.bz2
tar -xvzf pjproject-2.9.tar.bz2

configure to make ‘build.mak’, and ‘os-auto.mak’

./configure --enable-shared --disable-static --enable-memalign-hack --enable-gpl --enable-libx264

It runs checks , pay attention to traces such as


checking opus/opus.h usability... yes
checking opus/opus.h presence... yes
checking for opus/opus.h... yes
checking for opus_repacketizer_get_size in -lopus... yes
OPUS library found, OPUS support enabled

For more features customization `configure’ configures pjproject 2.x to adapt to many kinds of systems.

Usage: ./aconfigure [OPTION]… [VAR=VALUE]…

To assign environment variables (e.g., CC, CFLAGS…), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

-h, –help display this help and exit
–help=short display options specific to this package
–help=recursive display the short help of all the included packages
-V, –version display version information and exit
-q, –quiet, –silent do not print checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for–cache-file=config.cache’
-n, –no-create do not create output files
–srcdir=DIR find the sources in DIR [configure dir or `..’]

Installation directories:
–prefix=PREFIX install architecture-independent files in PREFIX
–exec-prefix=EPREFIX install architecture-dependent files in EPREFIX

By default, make install' will install all the files in /usr/local/bin’, /usr/local/lib' etc. You can specify an installation prefix other than/usr/local’ using --prefix', for instance–prefix=$HOME’.

For better control, use the options below.

Fine tuning of the installation directories:
–bindir=DIR user executables [EPREFIX/bin]
–sbindir=DIR system admin executables [EPREFIX/sbin]
–libexecdir=DIR program executables [EPREFIX/libexec]
–sysconfdir=DIR read-only single-machine data [PREFIX/etc]
–sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
–localstatedir=DIR modifiable single-machine data [PREFIX/var]
–libdir=DIR object code libraries [EPREFIX/lib]
–includedir=DIR C header files [PREFIX/include]
–oldincludedir=DIR C header files for non-gcc [/usr/include]
–datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
–datadir=DIR read-only architecture-independent data [DATAROOTDIR]
–infodir=DIR info documentation [DATAROOTDIR/info]
–localedir=DIR locale-dependent data [DATAROOTDIR/locale]
–mandir=DIR man documentation [DATAROOTDIR/man]
–docdir=DIR documentation root [DATAROOTDIR/doc/pjproject]
–htmldir=DIR html documentation [DOCDIR]
–dvidir=DIR dvi documentation [DOCDIR]
–pdfdir=DIR pdf documentation [DOCDIR]
–psdir=DIR ps documentation [DOCDIR]

System types:
–build=BUILD configure for building on BUILD [guessed]
–host=HOST cross-compile to build programs to run on HOST [BUILD]
–target=TARGET configure for building compilers for TARGET [HOST]

Optional Features:
–disable-option-checking ignore unrecognized –enable/–with options
–disable-FEATURE do not include FEATURE (same as –enable-FEATURE=no)
–enable-FEATURE[=ARG] include FEATURE [ARG=yes]
Disable floating point where possible
–enable-epoll Use /dev/epoll ioqueue on Linux (experimental)
–enable-shared Build shared libraries
–disable-resample Disable resampling implementations
–disable-sound Exclude sound (i.e. use null sound)
–disable-video Disable video feature
–enable-ext-sound PJMEDIA will not provide any sound device backend
–disable-small-filter Exclude small filter in resampling
–disable-large-filter Exclude large filter in resampling
–disable-speex-aec Exclude Speex Acoustic Echo Canceller/AEC
–disable-g711-codec Exclude G.711 codecs from the build
–disable-l16-codec Exclude Linear/L16 codec family from the build
–disable-gsm-codec Exclude GSM codec in the build
–disable-g722-codec Exclude G.722 codec in the build
–disable-g7221-codec Exclude G.7221 codec in the build
–disable-speex-codec Exclude Speex codecs in the build
–disable-ilbc-codec Exclude iLBC codec in the build
–enable-libsamplerate Link with libsamplerate when available.
–enable-resample-dll Build libresample as shared library
–disable-sdl Disable SDL (default: not disabled)
–disable-ffmpeg Disable ffmpeg (default: not disabled)
–disable-v4l2 Disable Video4Linux2 (default: not disabled)
–disable-openh264 Disable OpenH264 (default: not disabled)
–enable-ipp Enable Intel IPP support. Specify the Intel IPP
package and samples location using IPPROOT and
IPPSAMPLES env var or with –with-ipp and
–with-ipp-samples options
–disable-darwin-ssl Exclude Darwin SSL (default: autodetect)
–disable-ssl Exclude SSL support the build (default: autodetect)

–disable-opencore-amr Exclude OpenCORE AMR support from the build
(default: autodetect)

–disable-silk Exclude SILK support from the build (default:

–disable-opus Exclude OPUS support from the build (default:

–disable-bcg729 Disable bcg729 (default: not disabled)
–disable-libyuv Exclude libyuv in the build
–disable-libwebrtc Exclude libwebrtc in the build

Optional Packages:
–with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
–without-PACKAGE do not use PACKAGE (same as –with-PACKAGE=no)
–with-external-speex Use external Speex development files, not the one in
“third_party” directory. When this option is set,
make sure that Speex is accessible to use (hint: use
CFLAGS and LDFLAGS env var to set the include/lib
–with-external-gsm Use external GSM codec library, not the one in
“third_party” directory. When this option is set,
make sure that the GSM include/lib files are
accessible to use (hint: use CFLAGS and LDFLAGS env
var to set the include/lib paths)
–with-external-srtp Use external SRTP development files, not the one in
“third_party” directory. When this option is set,
make sure that SRTP is accessible to use (hint: use
CFLAGS and LDFLAGS env var to set the include/lib
–with-external-yuv Use external libyuv development files, not the one
in “third_party” directory. When this option is set,
make sure that libyuv is accessible to use (hint:
use CFLAGS and LDFLAGS env var to set the
include/lib paths)
–with-external-webrtc Use external webrtc development files, not the one
in “third_party” directory. When this option is set,
make sure that webrtc is accessible to use (hint:
use CFLAGS and LDFLAGS env var to set the
include/lib paths)
–with-external-pa Use external PortAudio development files. When this
option is set, make sure that PortAudio is
accessible to use (hint: use CFLAGS and LDFLAGS env
var to set the include/lib paths)
–with-sdl=DIR Specify alternate libSDL prefix
–with-ffmpeg=DIR Specify alternate FFMPEG prefix
–with-openh264=DIR Specify alternate OpenH264 prefix
–with-ipp=DIR Specify the Intel IPP location
–with-ipp-samples=DIR Specify the Intel IPP samples location
–with-ipp-arch=ARCH Specify the Intel IPP ARCH suffix, e.g. “64” or
“em64t. Default is blank for IA32”
–with-ssl=DIR Specify alternate SSL library prefix. This option
will try to find OpenSSL first, then if not found,
GnuTLS. To skip OpenSSL finding, use –with-gnutls
option instead.
–with-gnutls=DIR Specify alternate GnuTLS prefix
This option is obsolete and replaced by
–with-opencore-amr=DIR Specify alternate libopencore-amr prefix
Specify alternate libvo-amrwbenc prefix
–with-silk=DIR Specify alternate SILK prefix
–with-opus=DIR Specify alternate OPUS prefix
–with-bcg729=DIR Specify alternate bcg729 prefix

Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L if you have libraries in a
nonstandard directory
LIBS libraries to pass to the linker, e.g. -l
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if
you have headers in a nonstandard directory
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor

Make and install

make dep
make install


create library instance and initiate with default config and logging

lib = pj.Lib()
lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))

create UDP transport listening on any available port

transport = lib.create_transport(pj.TransportType.UDP,

create sipuri and local account

my_sip_uri = "sip:" + transport.info().host + ":" + str(transport.info().port)
acc = lib.create_account_for_transport(transport, cb=MyAccountCallback())

Function to make call

def make_call(uri):
        print "Making call to", uri
        return acc.make_call(uri, cb=MyCallCallback())
    except pj.Error, e:
        print "Exception: " + str(e)
        return None

Ask user input for destination URI and Call

print "Enter destination URI to call: ",
input = sys.stdin.readline().rstrip("\r\n")
if input == "":
lck = lib.auto_lock()
current_call = make_call(input)
del lck

shutdown the library

transport = None
 acc = None
 lib = None


➜  ~ python simplecall.py sip:altanai@

09:58:09.571        os_core_unix.c !pjlib 2.9 for POSIX initialized
09:58:09.573        sip_endpoint.c  .Creating endpoint instance…
09:58:09.574        pjlib  .select() I/O Queue created (0x7fcfe00590d8)
09:58:09.574        sip_endpoint.c  .Module "mod-msg-print" registered
09:58:09.574        sip_transport.c  .Transport manager created.
09:58:09.575        pjsua_core.c  .PJSUA state changed: NULL --> CREATED
09:58:10.073        pjsua_core.c  .pjsua version 2.9 for Darwin-18.7/x86_64 initialized
Call is  CALLING last code = 0 ()

Debug Help

Isssue1 Undefined symbols for architecture x86_64:
“_pjmedia_codec_opencore_amrnb_deinit”, referenced from:
_amr_encode_decode in mips_test.o
_create_stream_amr in mips_test.o
“_pjmedia_codec_opencore_amrnb_init”, referenced from:
_amr_encode_decode in mips_test.o
_create_stream_amr in mips_test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [../bin/pjmedia-test-x86_64-apple-darwin18.7.0] Error 1
make[1]: *** [pjmedia-test-x86_64-apple-darwin18.7.0] Error 2
make: *** [all] Error 1
*Solution* Mac often throws this linker error. Follow

./configure --enable-shared --disable-static --enable-memalign-hack
make dep
make install
cd pjproject-2.9/pjsip-apps/src/python/
python setup.py install

H 323

International standard for multimedia communication ( real-time voice, video, and data communication) over packet-switched networks
includes the standards H.323, H.225.0, H.245, the H.450-series documents, and the H.460-series.
T.120 for data collaboration and file transfer.
Ability to utilize network services for address resolution, including ENUM, LDAP, and DNS an provide various supplementary services Call transfer , forward , park/pick-up , Hold , Waiting , Message Waiting Indication , Call Completion on Busy / No-Answer , Call Intrusion etc
Support for T.120 data conferencing, fax and modem relay

Elements of an H.323 System

• Terminals ( Telephones , Video phones , IVR , Voicemail Systems, Soft phones like, NetMeeting)
• Multipoint Control Units (MCUs) – manages the call signaling and optionally have Multipoint Processors to handle media mixing, switching or other media processing got multipoint conferences
• Gateways – MGC handles call signaling and other non media-related functions while MG handles the media
• Gatekeeper – admission control and address resolution
• Border Elements

Protocols in H323 framework

H.225.0 defines the call signaling between endpoints and the Gatekeeper
RTP/RTCP (RFC 3550) is used to transmit media such as audio and video over IP networks
H.225.0 Annex G and H.501 define the procedures and protocol for communication within and between Peer Elements
H.245 control establishment and closure of media channels within the context of a call and to perform conference control
H.450.x is a series of supplementary service protocols
H.460.x is a series of version-independent extensions to the base H.323 protocol
T.120 specifies how to do data conferencing
T.38 defines how to relay fax signals
V.150.1 defines how to relay modem signals
H.235 defines security within H.323 systems
X.680 defines the ASN.1 syntax used by the Recommendations
X.691 defines the Packed Encoding Rules (PER) used to
encode messages for transmission on the network

Ref :