Message Protocol

The protocol used for control communications is described here, in the following sections. Also described is the relationship between different components, which is required for the communications protocol to make any "sense".

Introduction

Workers and Supervisors are the doers - entities that control voice calls. The distinction between them is explained in section Supervisor and Worker.

The method by which one Worker/Supervisor sends messages to another Worker/Supervisor is very simple. A text message is composed, sent to the server via a TCP socket, which then relays the message on to the desired destination. Thus, we have a star network. Every Worker/Supervisor has one TCP connection to the server, for sending/receiving messages relevant to/from the server.

We are opposed to "micro management". Thus, a Supervisor is not required to worry about the details of any one voice circuit. In fact, the only contact a Supervisor will have with any one voice circuit is to create the Worker to handle that voice circuit.

Similarily, when two Workers have to arrange the transfer of audio data between themselves, it is none of the Controller's business. The controller should merely say to one worker, "arrange audio transfer with that worker". Consequently, the Controller is not aware of what port the Worker is using for audio

The contents of all messages

Control communication is always via text messages on TCP sockets. The last byte in every message is a zero byte. By using a zero byte, we can determine if the remote stack has concatenated consecutive TCP messages.

Prior to any communication, a node must connect to the server and identify itself. Once identified, anyone connected to that server can talk to the node. A node (suppose it is "switch") will first do a TCP Connect to this server. This server will then spawn of a TCPConnection class to listen for all further communications from switch. Node switch then sends a zero terminated string of

"switch"0

to this server. This string identifies the remote node to this server. On receipt of this string, the server can make a unique label for the TCPConnection class, and add it to the internal list. Once the TCPConnection class has been added to the internal list, full bidirectional comms is now possible with node "switch".

The server assumes all remote nodes will correctly choose a valid unique ID. My preference is that the supervisor connects with a label such as "controller", "ssvoip", or "ssam". Workers spawned by that supervisor have a number appended to the supervisor's label. Thus, the voip supervisor connects as "ssvoip". All workers spawned by the voip supervisor will be called "ssvoip1", "ssvoip2", etc. This naming scheme makes debugging somewhat easier, as you can identify, from the label, the origin/destination of a message.

A message sent to the server has the format remoteNode : message

The server changes the message, and sends it to the remote node as sourceNode : message

Thus, this server has changed the message. This is acceptable, as it means that the receiving node is able to determine who sent the message. The receiving node cannot determine the source of the message by socket analysis. This happens as the network stack of the receiving node will always say that the source of each packet is this message server.

To illustrate, suppose A sends the message "status" to B. A sends to the sever

"B:status"0 (string, with a trailing zero byte)

the server receives this packet and then sends to B

"A:status"0 (string, with a trailing zero byte)

Note - the quotes are there to illustrate it is a string, and are not included in the packet.

Supervisor and Worker

It is important to note that a sofaswitch application will have two distinct endpoints in it. The application will have 1 Supervisor and multiple Workers.

Worker handles commands associated with one particular voip circuit. Thus, for a voice over IP application, there will be X workers for the X active voice calls in the voip application.
Supervisorresponsible for establishing (as required) new Workers. It can be used to terminate the sofaswitch application. Messages which are appropriate for a particular Worker are never ever sent via the supervisor
.

Even the controller can be split up into a Worker/Supervisor distinction. The Worker in the controller sends commands appropriate to managing one current call. The Supervisor creates Workers to handle new calls, as required.

Worker/Supervisor commands

The following commands are provided in this protocol. They are designed to be sent from a Worker/Supervisor to a Worker/Supervisor. Most will be sent by Workers, but there is no check if the source is allowed to send this message. Indeed, it is possible for any node connected to the server to control any other node connected to the server.

hangup The Worker which receives this terminates the current call
callnode Causes a Worker/Supervisor to start a voip call to voip destination. This command is not relevant for an answering machine type node.
status A query on the Worker/Supervisor's status. If an argument is supplied, then status is required of that entity. For example, you could specify the status of a particular conference room
duration A query for the worker to reply with the duration of the current call, or the supervisor to reply with how long it has been up
identify The node will reply with an english sentence describing how long it has been up
debug casue the receiving node to turn on (or not) debugging features.
answer the worker node will answer the incoming voip call or not. There will be the word "true" or "false" after the word answer, to say if we answer the call.
transferudp Used in the exchange to advise remote nodes of where the local udp receive port is
queryaddress no longer used, as it has been superseded by the transferudp command
adviseaddress no longer used, as it has been superseded by the transferudp command
quitnow can only be processed by the Supervisor, which causes this sofaswitch application to die
help cause the recipient node to reply with the list of understood commands
querydestaddress no longer used, as it has been superseded by the transferudp command
senddtmf advise the recipient worker to send the folling dtmf stream to the remote voip node. Typically, a voip worker would receive this message, and send dtmf to the other end of the call.
requestnewid A Supervisor will receive this message, create a new Worker, and reply with the id of the created Worker. An argument can be supplied. Currently, the only entity which uses this is the conference room supervisor, where the argument specifies the name of the conference room. In this case, the created newid is placed in the specified conference room. The conference room is created, if it is not there.
setreceivedmsgfile An answering machine Worker will receive this message, and write incoming audio to the specified file
setannouncementfileAn answering machine Worker will receive this message, and read audio from the specified file, and send this audio to the address specified in the previous transfer udp message.

Server commands

Some commands are actioned by the server, and not passed on to the destination node. These commands do not have a destination node specified. They are therefore of the format:

"command"0

which contains no colon character, and is terminated by a zero byte. As before, the quotes are there to illustrate it is a string, and are not included in the packet.

quitnowCause the server to end. On ending, every application connected to the server will end also.
listCause the server to respond with a list of all the currently connected nodes. The command "list" is similar to the notion of presence as used in XMPP, except that here, presence is driven by the client.

Example of the transferdp message and how it works.

Below is the sequence of three messages, as sent by worker nodes, to setup the transfer of audio beteen the worker nodes of voip41 (voice over ip worker) and ssam3 (answering machine worker). Note that controller10 is a worker node in the controller, and is responsible for handling one call.

controller10 sends voip41: transferudp ssam3 (worker to worker)
voip41 sends ssam3: 192.168.1.109:62054 (worker to worker)
ssam3 sends voip41: 192.168.1.54: 45021 done(worker to worker)

The controller10 tells voip41 that it has to send audio to the ssam3 node. Once the controller has sent this message, the controller has no further news on if anything has happened. voip41 receives the transferudp message and advises ssam3 of an ip/port address. This second message in the transfer advises ssam3 of where to send audio data to. ssam3, on receipt of message 2, can start sending audio to the address specified in message 2. ssam3 then advises voip41 of the address that voip41 should send audio to. When voip41 receives message 3, voip41 can start sending audio to 192.168.1.54:45021. On receipt of message 3, voip 41 will send no more messages, as message 3 contains the word "done"

The list above describes the messages, as received by the server. From the description above, the server will change the message around to contain the sender's name. Consequently, the messages reeived by the three workers in this example will be

voip41receives controller10: transferudp ssam3 (worker to worker)
ssam3 receives voip41: 192.168.1.109:62054 (worker to worker)
voip41receives ssam3: 192.168.1.54:45021 done (worker to worker)

Example of a Supervisor requesting a new id

The controller supervisor has decided it needs a new worker in a sofaswitch application. Since the controller supervisor is not interested in micro management, the controller supervisor will create a worker. node. Consequently, the controller forks/thread create (whatever) and creates a new Worker node (controller10). Now, controller10 sends a message to the sofaswitch application supervisor (voip) requestnewid. The voip supervisor creates a new worker (voip20). The voip supervisor sends a message to controller10 stating that a newid has been created, and it is voip20. The messages, as received by the server are:

controller10 sends voip:requestnewid (worker to supervisor)
voip sends controller10:requestnewid voip20 (worker to worker)

Then, controller10 will send messages to voip20 asking it to transferudp, or make a call, or whatever.

Example of calling a remote voip address

The controller supervisor should not issue the callnode command. Given that we do not believe in micro management, we will let the controller supervisor to create a controller-worker thread/process to issue the callnode command. The controller worker will be called controller10. The messages that are sent are:

controller10 sends voip:requestnewid (worker to supervisor)
voip sends controller10:requestnewid voip20 (worker to worker)
controller10 sends voip20:callnode h323:h323.voxgratia.org(worker to worker)
voip20 sends controller10: callestablished voip20 (worker to worker)

The callestablished message is sent when the call is up and running. In this example, controller10 knew who was making the call. However, it need not be so. The controller does not have to request a new id to initiate a voip call to a remote node. Instead, the controller can ask the voip supervisor to create a new call.

In this case the voip supervisor will create a voip worker, and get the voip worker to make the voip call. The voip worker will then advise (from this example) controller10 that the call is established, and the id of the voip worker. Here, the controller worker is required to wait for the call established message to find out who is managing the call.

Thus, the voip supervisor can be used to create a Worker (which then implements the callnode command) In this case, a suitable message flow would be:

controller10 sends voip:callnode h323:h323.voxgratia.org (worker to supervisor)
voip20 sends controller10: callestablished voip20 (worker to worker)

Once the controller know who the worker nodes are, it can start the transferudp sequence. However if the voip worker and ssam worker complete the transferudp sequence before the call is established (from the voip perspective), and the controller then tells the ssam worker the announcement file, the very first part of the announcement file will not be heard by the remote voip node.

Consequently, the ssam announcement file should be set after the call is established. The ssam received message file can be set at any time. Although, setting the ssam announcement file too late will mean that the first part of the incoming voice call will be missed.

Example of creating outgoing voip call.

In this example, the controller spawns of a worker, which the controller labels as "controller1".

In this example, the box at 192.168.1.100 is being asked to call the node at box 192.168.1.200. The answering machine resides at address 192.168.1.2. The box at 192.168.1.100 has registered with the controller under the basename of ssvoip_send, as it is responsible for initiating calls with remote computers.

Notice that in Example of receiving a voip call and Example of creating outgoing voip call. we have shown "both ends" of the voip call.Incoming, and outgoing. One controller, and one answering machine, was used to manage both ends. Further, we could have placed the incoming and outgoing ends of the call on the same sofaswitch voip application.

In this example, ssvoip_send1 reported to the contrcontroller2 let the call run for 5 seconds, and then sent a hangup message to the two worker nodes managed by controller2.

send timesent by message
0:31.493 controller1 ssvoip_send:REQUESTNEWID
0:31.494 controller1 ssam:REQUESTNEWID
0:31.494 ssvoip_send controller1:REQUESTNEWID ssvoip_send1
0:31.495 ssam controller1:REQUESTNEWID ssam1
0:31.586 controller1 ssvoip_send1:callnode h323:192.168.1.200
0:31.586 controller1 ssam1:setannouncementfile sample_message.wav
0:31.626 controller1 ssam1:setreceivedmsgfile recorded_ssam1.wav
0:31.990 ssvoip_send1 controller1:CallEstablished ssvoip_send1
0:31.991 controller1 ssvoip_send1:transferudp ssam1
0:31.992 ssvoip_send1 ssam1:transferudp ssam1 192.168.1.100:60000
0:31.999 ssam1 ssvoip_send1:transferudp ssam1 192.168.1.2:64000 done
0:37.017 ssvoip_send1 controller1:Terminating
0:37.017 controller1 ssam1:hangup
0:37.018 ssam1 controller1:Terminating

Example of receiving a voip call

In this example, the box at 192.168.1.200 is being asked to process an incoming call from the node at box 192.168.1.100. The answering machine resides at address 192.168.1.2. The box at 192.168.1.100 has registered with the controller under the basename of ssvoip_rec, as it is responsible for processing incoming voip calls.

Notice that in Example of receiving a voip call and Example of creating outgoing voip call. we have shown "both ends" of the voip call.Incoming, and outgoing. One controller, and one answering machine, was used to manage both ends. Further, we could have placed the incoming and outgoing ends of the call on the same sofaswitch voip application.

In this example, controller2 let the call run for 5 seconds, and then sent a hangup message to the two worker nodes managed by controller2.

send timesent by message
0:31.871 ssvoip_rec2 controller:QueryAcceptIncoming derek [192.168.1.100]
0:31.874 controller2 ssam:REQUESTNEWID
0:31.875 ssam controller2:REQUESTNEWID ssam2
0:31.966 controller2 ssvoip_rec2:answer true
0:31.966 controller2 ssam2:setannouncementfile sample_message.wav
0:31.984 ssvoip_rec2 controller2:CallEstablished ssvoip_rec2
0:31.984 controller2 ssam2:setreceivedmsgfile recorded_ssam2.wav
0:31.984 controller2 ssvoip_rec2:transferudp ssam2
0:32.049 ssvoip_rec2 controller2:CallEstablished ssvoip_rec2
0:32.049 ssvoip_rec2 ssam2:transferudp ssam2 192.168.1.200:60001
0:32.050 ssam2 ssvoip_rec2:transferudp ssam2 192.168.1.2:64001 done
0:36.966 controller2 ssvoip_rec2:hangup
0:36.966 controller2 ssam2:hangup
0:36.967 ssvoip_rec2 controller2:Terminating
0:36.967 ssam2 controller2:Terminating

Generated on Fri Jul 28 13:52:45 2006 for Sofa Switch by  doxygen 1.4.6