Wisdom of Helios


Leave a comment

Image Postioning on Android

A picture is worth a thousand words” refers to the notion that a complex idea can be conveyed with just a single still image. It also aptly characterizes one of the main goals of visualization, namely making it possible to absorb large amounts of data quickly. In Android an image is typically shown in an ImageView which is a dedicated view for showing image. This view takes the charge of load, optimize and scaling of the image and make the developer free  to focus on app-specific details . Unless you need special optimizations for your application, you should take advantage of the built-in image view whenever possible.

To display an image simply we have to declare an ImageView inside a LayOut and set its source to a resource in your project. Image resources are placed in the /res/drawable folders. This example will display an image named “antelope”:

<ImageView

android:id=“@+id/ivantilop”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:layout_margin=“10dp”

android:src=“@drawable/antelope”

android:sacleType=“fitCenter”   />

[/sourcecode ]

Please have a look on the attribute  sclaeType . It defines how the image will fit and be scaled to the view. In this example scaleType  is set to “fitCenter” , so the image will be shown  in the center of container view with scaling and preserve the aspect ratio. I’m going to list the scale type options and how they alter the image.

Here is the code snippet :

<RelativeLayout xmlns:android=http://schemas.android.com/apk/res/android&#8221;

xmlns:tools=http://schemas.android.com/tools&#8221;

android:layout_width=“match_parent”

android:layout_height=“match_parent” >

<LinearLayout

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“vertical”

android:layout_alignParentLeft=“true”

android:layout_alignParentTop=“true”

android:background=“@android:color/holo_orange_light”>

<ImageView

android:id=“@+id/ivantilop”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:layout_margin=“10dp”

android:src=“@drawable/antelop”

android:sacleType=“fitCenter”

/>

</LinearLayout>

</RelativeLayout>

[/sourcecode ]

This is the original image which is taken for Nat Geo website.

55577_1600x1200-wallpaper-cb1341586649

scaleType

                   Description

Example

center

Displays the image in the center of container view. No scaling . Preserves aspect ratio (native resolution) and centered in the view, regardless of how much space the view consumes.  Screenshot_2000-01-02-04-54-05

centerCrop

Displays the image in the center of container view. Scales in such a way that both the X axis (width) and Y axis(height) is equal or larger than the corresponding axis of the view (minus padding) , while maintaining the image aspect ratio; crops any part of the image that exceeds the size of the view.

 Screenshot_2000-01-02-05-04-38

centerInside

Displays the image in the center of container view. Scales in such a way that both the X axis (width) and Y axis(height) is equal or smaller than the corresponding axis of the view (minus padding) to fit inside the view , while maintaining the image aspect ratio. If the image is already smaller than the view, then this is the same as center.  Screenshot_2000-01-02-05-18-55

fitCenter

same as center using Scaling. Maintains the Image aspect ratio to fit inside the center of the view. At least one axis (height or width) will exactly match the corresponding axis of the view.

Screenshot_2000-01-02-05-18-55

fitStart

Same as fitCenter but aligned to the top-left of the container view.

    Screenshot_2000-01-02-05-35-01

fitEnd

Same as fitCenter but aligned to the right-bottom of the container view.

      Screenshot_2000-01-02-05-38-47

fitXY

Scales the X and Y dimensions of the image to exactly match the container view. Does not preserve the aspect ratio of the image.

   Screenshot_2000-01-02-05-48-14

 

fitMatrix

Scales the image using supplied Matrix Class. Usually this Matrix is implemented using setImageMatrix(Matrix) method.  This type of scaling is use to transform/process the image such as rotation.


6 Comments

Running native codes (C codes) in Android using JNI and NDK

Although Android applications are mainly written by Java, developers sometimes may still want to leverage many good ready-made C/C++ libraries. Android applications run in the Dalvik virtual machine. The NDK allows you to implement parts of your applications using native-code languages such as C and C++. This can provide benefits to certain classes of applications, in the form of reuse of existing code and in some cases increased speed.

JNI

JNI or Java Native Interface is the interface between the Java code running in a JVM and the native code running outside the JVM. It works both ways, that is you can use JNI to call native code from your Java programs and to call Java code from your native code. The native code normally resides within a library (.so file) and is typically written in C/C++.

Reasons to use JNI:

ü  Wrapping lower level functionality and make an abstraction level i,e, Camera, Sensors, audio devices etc.

ü  Suppose you have an existing C/C++ code library or a full game you’d like to port to Android, but you don’t want to translate them into Java. One solution is to keep as much code as possible in C/C++ and then use the Android NDK and the Java Native Interface to communicate between the two languages.

ü  Bypass performance bottlenecks.

Android NDK

Android NDK is a set of tools that embed native language (c\c++) in an android application. It’s easy to setup and use. Android applications run in the Dalvik virtual machine. The NDK allows you to implement parts of your applications using native-code languages such as C and C++. This can provide benefits to certain classes of applications, in the form of reuse of existing code and in some cases increased speed.

To build a shared library, you can use the ndk-build shell script included with the Android NDK. It needs to run in a Unix-like environment so, if you’re on Windows, you will require Cygwin.

You always have to compile your native code against a specific architecture. The Android NDK includes a cross-compiler (compilers and linkers etc) that will generate binaries for the ARM architecture. Since ARM is by far the most common architecture on the Android devices today it should work on most devices

NDK supports following instruction sets –

ü  ARMv5TE

ü  ARMv7-A

ARMv5TE runs on every ARM based Android devices. ARMv7-A will run only on devices such as the Verizon Droid or Google Nexus One that have a compatible CPU.

ARMv5TE is the default, but switching to ARMv7-A is as easy as adding a single line to the application’s Application.mk file, without needing to change anything else in the file.

NDK provides headers and libraries that allow you to build activities, handle user input, use hardware sensors, access application resources, and more, when programming in C or C++.  Note that native code accessible via JNI still runs inside the Dalvik VM, and as such is subject to the same life-cycle rules that any Android application lives by.

 

List of NDK Development tools –

The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms.

It provides a set of system headers for stable native APIs that are guaranteed to be supported in all later releases of the platform:

  • libc (C library) headers
  • libm (math library) headers
  • JNI interface headers
  • libz (Zlib compression) headers
  • liblog (Android logging) header
  • OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers
  • libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).
  • A Minimal set of headers for C++ support
  • OpenSL ES native audio libraries
  • Android native application APIS

The NDK also provides a build system that lets you work efficiently with your sources, without having to handle the toolchain/platform/CPU/ABI details. You create very short build files to describe which sources to compile and which Android application will use them — the build system compiles the sources and places the shared libraries directly in your application project.

Ways to write native codes in Android

  • Write your application using the Android framework and use JNI to access the APIs provided by the Android NDK. This technique allows you to take advantage of the convenience of the Android framework, but still allows you to write native code when necessary. You can install applications that use native code through the JNI on devices that run Android 1.5 or later.
  • Write a native activity, which allows you to implement the lifecycle callbacks in native code. The Android SDK provides the NativeActivityclass, which is a convenience class that notifies your native code of any activity lifecycle callbacks (onCreate(), onPause(), onResume(), etc). You can implement the callbacks in your native code to handle these events when they occur. Applications that use native activities must be run on Android 2.3 (API Level 9) or later.

You cannot access features such as Services and Content Providers natively, so if you want to use them or any other framework API, you can still write JNI code to do so.

Basic procedures to run native code

1)  A folder named ‘jni’ (lowercase) must be created by you in the Eclipse project’s root directory. This would place a folder at the same level as the Eclipse/Java ‘bin’, ‘src’, and ‘res’ folders. It would also be at the same level as the ‘AndroidManifest.xml’ file. Inside this folder is where the source c or c++ documents need to be placed.

 

 

 

2)  Create Android mk file, before the NDK build tools will compile your code they need a ‘Makefile’ file. Android.mk file describes your sources to the build-system.Information on writing the ‘Android.mk’ file can be found in the ‘docs’ folder inside the ‘android-ndk-***‘ folder.

The file syntax is designed to allow you to group your sources into ‘modules’. A module is one of the following: – a static librarya shared library. Only shared libraries will be installed/copied to your application package. Static libraries can be used to generate shared libraries though. You can define one or more modules in each Android.mk file, and you can use the same source file in several modules.

We can consider an example –

  LOCAL_PATH := $(call my-dir)

   include $(CLEAR_VARS)

   LOCAL_MODULE    := hellojni

   LOCAL_SRC_FILES := NativeSource.c

   include $(BUILD_SHARED_LIBRARY)

Let us explain these lines:

LOCAL_PATH := $(call my-dir)

An Android.mk file must begin with the definition of the LOCAL_PATH variable. It is used to locate source files in the development tree. In this example, the macro function ‘my-dir’, provided by the build system, is used to return the path of the current directory (i.e. the directory containing the Android.mk file itself).

include $(CLEAR_VARS)

The CLEAR_VARS variable is provided by the build system and points to a special GNU Makefile that will clear many LOCAL_XXX variables for you (e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc…), with the exception of LOCAL_PATH. This is needed because all build control files are parsed in a single GNU Make execution context where all variables are global.

LOCAL_MODULE    := hellojni

The LOCAL_MODULE variable must be defined to identify each module you describe in your Android.mk. The name must be *unique* and not contain any spaces. Note that the build system will automatically add proper prefix and suffix to the corresponding generated file. In other words, a shared library module named ‘hellojni’ will generate ‘libhellojni.so’.  [If you name your module ‘libhellojni’, the build system will not add another ‘lib’ prefix and will generate libhellojni.so as well. This is to support Android.mk files that originate from the Android platform sources, would you need to use these.]

LOCAL_SRC_FILES := NativeSource.c

The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source files that will be built and assembled into a module. Note that you should not list header and included files here, because the build system will compute dependencies automatically for you; just list the source files that will be passed directly to a compiler

include $(BUILD_SHARED_LIBRARY)

The BUILD_SHARED_LIBRARY is a variable provided by the build system that points to a GNU Makefile script that is in charge of collecting all the information you defined in LOCAL_XXX variables since the latest ‘include $(CLEAR_VARS)’ and determine what to build, and how to do it exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.

3)  This is just a Java file that lives in standard src directory in your Eclipse project. It serves as the glue to the native code that we’ll write later.


package com.ndkadd.munir;

public class UseNDK {

static

{

System.loadLibrary("hellojni"); // we will load all the modules described in the Android.mk file

}

public native int AddNumbers(int value1 , int value2);

}

                 A C header file named  com_ndkadd_munir_UseNDK.h will be created    on the defined path.Next, copy the JNI header from NDKAddDemo/bin/class    to   NDKAddDemo/jni

4) Create the Native code header file, to do this , run Cygwin, go to the bin directory of the project in Cygwin. Enter one more step farther into classes folder. In my case, I entered /cygdrive/c/workspace/NDKAddDemo/bin/classes in Cygwin terminal. Run javah tool in this location to create jni header file

m.hoque@S-11627522 /cygdrive/c/workspace/NDKAddDemo/bin/classes

$ javah -jni com.ndkadd.munir.UseNDK

A C header file named  com_ndkadd_munir_UseNDK.h will be created    on the defined path.Next, copy the JNI header from NDKAddDemo/bin/class    to   NDKAddDemo/jni

 

5)  Writing C/C++ code is little tricky here. In the JNI framework, native functions are implemented in separate .c or .cpp files. When the JVM invokes the function, it passes a JNIEnv pointer, a jobject pointer, and any Java arguments declared by the Java method. You must have to implement the methods in the header file here. You can consider an example here –


#include<com_ndkadd_munir_UseNDK.h>
#include<string.h>
JNIEXPORT jint JNICALL Java_com_ndkadd_munir_UseNDK_AddNumbers
(JNIEnv *env, jobject obj, jint v1, jint v2)
{
return(v1+v2);
}

The env pointer is a structure that contains the interface to the JVM. It includes all of the functions necessary to interact with the JVM and to work with Java objects. Example JNI functions are converting native arrays to/from Java arrays, converting native strings to/from Java strings, instantiating objects, throwing exceptions, etc. Basically, anything that Java code can do can be done using JNIEnv.


 6) Compile everything and build you Shared Library, We will use the Android NDK ToolChain here. Go to Project root, the project root is the base folder for the Eclipse Android project.

m.hoque@S-11627522 /cygdrive/c/workspace/NDKAddDemo

$ /cygdrive/c/workspace/android-ndk-r7b/ndk-build

The NDK build tools will compile the code, and then if there are no errors it will name the object code ‘libndkadd.so’ and place it in the Android project in a new folder that it creates especially for this purpose. The name of the folder is ‘libs/armeabi/‘. The build tools also manage the creation of some other files that are necessary.

Use your native code inside Android activity,  here is my main.xml file –

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textgreetings"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <EditText
        android:id="@+id/editV1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editV2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number" />

    <Button
        android:id="@+id/btnAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add" />

    <TextView
        android:id="@+id/textResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout>

And, here is the Activity –

package com.ndkadd.munir;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class NDKAddDemoActivity extends Activity implements OnClickListener {
	UseNDK ntv = new UseNDK();
	private Button btnCalculate;
	private EditText editResult;
	private EditText editV1;
	private EditText editV2;
	private TextView result;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnCalculate = (Button)findViewById(R.id.btnAdd);
        // editResult = (EditText)findViewById(R.id.textResult);
         editV1 = (EditText)findViewById(R.id.editV1);
         editV2 = (EditText)findViewById(R.id.editV2);
         result = (TextView)findViewById(R.id.textResult);
         btnCalculate.setOnClickListener(this);

     }

 	@Override
 	public void onClick(View v) {
 		// TODO Auto-generated method stub
 		if(v.getId() == R.id.btnAdd)
 		{
 		int v1, v2, res = 0;
         v1 = Integer.parseInt(editV1.getText().toString());
         v2 = Integer.parseInt(editV2.getText().toString());
         res = ntv.AddNumbers(v1, v2);
         Log.d("Result", "dsdfsf");
         result.setText(new Integer(res).toString());
 		}

 	}
    }

I had a wish to write more about JNI and NDK by someday. Enough for today. 🙂 🙂 😀


Leave a comment

Multimedia CODEC

What is a Codec ?

Codec is a hardware or computer programs that encode/decode digital data streams or signals.  Codec shrinks large movie files, and makes them playable on your computer. Codec programs are required for your media player to play your downloaded music and movies.

Codec = Coder + Decoder .

A codec encodes a data stream/signal for transmission, storage or encryption and decodes it for playback or editing.

Do we need Codecs ?

Video and music files are large(Uncompressed 1080i high-definition video recorded at 60 frames per second eats up 410 gigabytes per hour of vide), they become difficult to transfer across the Internet quickly. To help speed up downloads, mathematical “codecs” were built to encode (“shrink”) a signal for transmission and then decode it for viewing or editing. Without codecs, downloads would take three to five times longer than they do now.

Codec is a translator for compressing/decompressing raw media data.

Raw Data is huge. Codec compress them  and facilitate to store.

Lossy and Lossless Codecs

Lossy Codecs reduce quality by some amount in order to achieve compression. Often, this type of compression is virtually indistinguishable from the original uncompressed sound or images, depending on the codec and the settings used. Lower data rates also reduce cost and improve performance when the data is transmitted.

Lossless codecs are typically used for archiving data in a compressed form while retaining all of the information present in the original stream. If preserving the original quality of the stream is more important than eliminating the correspondingly larger data sizes, lossless codecs are preferred. This is especially true if the data is to undergo further processing (for example editing) in which case the repeated application of processing (encoding and decoding) on lossy codecs will degrade the quality of the resulting data such that it is no longer identifiable (visually, audibly or both).

Using more than one codec or encoding scheme successively can also degrade quality significantly. The decreasing cost of storage capacity and network bandwidth has a tendency to reduce the need for lossy codecs for some media.

 

 

Media Codecs and their variations

Codecs are often designed to emphasize certain aspects of the media, or their use, to be encoded. For example, a digital video (using a DV codec) of a sports event needs to encode motion well but not necessarily exact colors, while a video of an art exhibit needs to encode color and surface texture well.

Audio codecs for cell phones need to have very low latency between source encoding and playback. In contrast, audio codecs for recording or broadcast can use high-latency audio compression techniques to achieve higher fidelity at a lower bit-rate.

So, there are thousands of codecs available. There are codecs for audio and video compression, for streaming media over the Internet, videoconferencing, playing mp3’s, speech, or screen capture. If you are a regular downloader, you will probably need ten to twelve codecs to play your music and movies.

Many multimedia data streams contain both audio and video, and often some metadata that permit synchronization of audio and video. Each of these three streams may be handled by different programs, processes, or hardware; but for the multimedia data streams to be useful in stored or transmitted form, they must be encapsulated together in a container format.

Lower bitrate codecs allow more users, but they also have more distortion. Beyond the initial increase in distortion, lower bit rate codecs also achieve their lower bit rates by using more complex algorithms that make certain assumptions, such as those about the media and the packet loss rate. Other codecs may not make those same assumptions. When a user with a low bitrate codec talks to a user with another codec, additional distortion is introduced by each transcoding.

Difference between Codec and  Compression and Container Format

Compression format or standard – a format is a document (the standard), a way of storing data, while a codec is a program (an implementation) which can read or write such files. In practice, however, “codec” is sometimes used loosely to refer to formats.

Container specifies how different data elements and metadata coexist in a computer file or stream

Once the media data is compressed into suitable formats and reasonable sizes, it needs to be packaged, transported, and presented. That’s the purpose of container formats–to be discrete “black boxes” for holding a variety of media formats. Good container formats can handle files compressed with a variety of different codecs.

Theoretically, a container format could wrap any kinds of data, most container formats are specialized for specific data requirements.

Container does not describe how the data warped is encoded.

Popular Codecs and Containers

I will strongly recommend to read two articles from PC magazine – Codec and Container to get some ideas.


5 Comments

Basics of Session Initiation Protocol (SIP) (part-5)

The previous posts were –

Basics of Session Initiation Protocol (part – 1)

Basics of Session Initiation Protocol  (part-2)

Basics of Session Initiation Protocol  (part-3)

Basics of Session Initiation Protocol  (part-4)

A Typical example of SIP:

Let us consider an example user Alice wants to communicate with user  Bob . Proxy 1 and Proxy 2 help to setup the session on behalf of the users. This common arrangement of the proxies and the end-users is called “SIP Trapezoid”.

The messages appear vertically in the order they appear i.e. the message on top comes first followed by others. The direction of arrows shows the sender and recipient of each message.

The transaction starts with Alice making an INVITE request for Bob. But Alice doesn’t know the exact location of Bob in the IP network. So it passes the request to Proxy1. Proxy1 on behalf of Alice forwards an INVITE request for Bob to Proxy2. It sends a TRYING response to Alice informing that it is trying to reach Bob. The response could have been different.

Receiving INVITE X2 from Proxy1, Proxy2 works in a similar fashion as Proxy1. It forwards an INVITE request to Bob(note: Here Proxy2 knows the location of Bob. If it didn’t know the location, it would have forwarded it to another proxy server. So an INVITE request may travel through several proxies before reaching the recipient). After forwarding INVITE X3 Proxy2 issues a TRYING response to Proxy1.

Bob’s SIP/Soft phone, on receiving the INVITE request, starts ringing informing Bob that a call request has come. It sends a RINGING response back to Proxy2 which reaches Alice through Proxy1. So Alice gets a feedback that Bob has received the INVITE request.

Bob at this point has a choice to accept or decline the call. Let’s assume that he decides to accept it. As soon as he accepts the call, a 200 OK response is sent by the phone to Proxy2. Retracing the route of INVITE, it reaches Alice. The softphone of Alice sends an ACK message to confirm the setup of the call. This 3-way-handshaking (INVITE+OK+ACK) is used for reliable call setup. Note that the ACK message is not using the proxies to reach Bob as by now Alice knows the exact location of Bob.

Once the connection has been setup, media flows between the two endpoints. Media flow is controlled using protocols different from SIP e.g.  SDP, RTP etc.

When one party in the session decides to disconnect, it (Bob in this case) sends a BYE message to the other party. The other party sends a 200 OK message to confirm the termination of the session.

This part is unabashedly copied form here . SIP Tutorial has written a nice topic on it.

Relation among Call, Dialog, Transaction & Message

If you are confused with the relation among Call, Dialog, Transaction & Message, you are not alone. Quite a good number of people get confused regarding the relation in the beginning.

Messages are the individual textual bodies exchanged between a server and a client. There can be two types of messages. They are – Requests and Responses.

Transaction occurs between a client and a server and comprises all messages from the first request sent from the client to the server up to a final (non-1xx) response sent from the server to the client. If the request is INVITE and the final response is a non-2xx, the transaction also includes an ACK to the response. The ACK for a 2xx response to an INVITE request is a separate transaction.

Dialog is a peer-to-peer SIP relationship between two UAs that persists for some time. A dialog is identified by a Call-ID, a local tag and a remote tag. A dialog used to be referred as a ‘call leg’.

Call of a callee comprises of all the dialogs it is involved in. I think a Call is same as a Session.

My Aritcle is over here. It was just for the beginners. I will recommend further reading on SIP .


5 Comments

Basics of Session Initiation Protocol (SIP) (part-4)

The previous posts were –

Basics of Session Initiation Protocol (part – 1)

Basics of Session Initiation Protocol  (part-2)

Basics of Session Initiation Protocol  (part-3)

SIP Message Samples:

The following samples show the message exchange between two User Agents for the purpose of setting up a voice call. SIP user alice@mssys.com invites SIP user bob@msinfo.com to a call for the purpose of discussing lunch. Alice sends an INVITE request containing an SDP body. Bob replies with a 200 OK response also containing an SDP body.

Request Commands:

Request Message Line

Description

INVITE sip:bob@msinfo.com SIP/2.0 Request line: Method type, request URI (SIP address of called party), SIP version.
Via: SIP/2.0/UDP Address of previous hop. It contains the local address of alice (initiator)i.e. mssys.com where it is expecting the responses to come.
Max Forward : 70 It is used to limit the number of hops that this request may take before reaching the recipient (Here is 70). It is decreased by one at each hop. It is necessary to prevent the request from traveling forever in case it is trapped in a loop.
From: Alice <sip:alice@mssys.com> User originating this request
TO :  Bob< sip:bob@msinfo.com>tag=1928301774; User being invited, as specified originally. It also optionally contains a tag which is a pseudo-random sequence inserted by the SIP application. It works as an identifier of the caller in the dialog.
Call-ID: 2388990012@alice_ws.mssys.com Globally unique ID of this call. It is  generated as the combination of a pseudo-random string and the softphone’s IP address.
CSeq: 1243 INVITE Command sequence. Identifies transaction. It contains an integer and a method name. When a transaction starts, the first message is given a random CSeq. After that it is incremented by one with each new message. It is used to detect non-delivery of a message or out-of-order delivery of messages.
Contact< sip:alice@mssys.com > It contains a SIP or SIPS URI that is a direct route to alice. It contains a username and a fully qualified domain name(FQDN). It may also have an IP address. (Via field is used to send the response to the request. Contact field is used to send future requests. That is why the 200 OK response from user2 goes to user1 through proxies. But when user2 generates a BYE request (a new request and not a response to INVITE), it goes directly to user1 bypassing the proxies)
Subject: Lunch today. Call subject and/or nature.
Content-Type: application/SDP Type of body—in this case SDP.(This is beyond the scope of SIP and is controlled by SDP which will be discussed later )
Content-Length: 182 Number of bytes in the body. If the transport type is UDP, then the Content-Length header is not mandatory. It is, however, mandatory for TCP.
Blank line marks end of SIP headers and beginning of body.

Response Commands:

SIP/2.0 200 OK
Via: SIP/2.0/UDP site4.server2.com;branch=z9hG4bKnashds8;received=192.0.2.3
Via: SIP/2.0/UDP site3.server1.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
Via: SIP/2.0/UDP pc33.server1.com;branch=z9hG4bK776asdhds;received=192.0.2.1
To: user2 <sip:user2@server2.com>;tag=a6c85cf
From: user1 <sip:user1@server1.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.server1.com
CSeq: 314159 INVITE
Contact: <sip:user2@192.0.2.4>
Content-Type: application/sdp
Content-Length: 131

—- User2 Message Body Not Shown —-

The header fields that follow the status line are similar to those in a request. I will just mention the differences-

Via

There are more than one via field. This is because each element through which the INVITE request has passed has added its identity in the Via field. Three Via fields are added by softphone of user1, server1 the first proxy and server2 the second proxy. The response retraces the path of INVITE using the Via fields. On its way back, each element removes the corresponding Via field before forwarding it back to the caller.

To:

Note that the To field now contains a tag. This tag is used to represent the callee in a dialog.

Contact:

It contains the exact address of user2. So user1 doesn’t need to use the proxy servers to find user2 in the future.

It is a 2xx response. However responses can be different depending on particular situations.

Next  post related to SIP –

Basics of Session Initiation Protocol  (part-5)


Leave a comment

Basics of Session Initiation Protocol (SIP) (part-3)

The previous posts were –

Basics of Session Initiation Protocol (part – 1)

Basics of Session Initiation Protocol  (part-2)

SIP Message Parts:

A SIP Message usually has 3 parts-

Start/First Line.

Header.

Body/Content.

Start Line—Conveys the message type(request or response).

Start Line  = Method for Request or Response Code for Response + Protocol version.

A Request’s Start Line(Request Line) uses the following format:

<Request method><URI><Protocol version>

URI indicates the user/service to which the request is addressed. This address/URI can be re-written by the Proxy Servers.

An Example of Request Line is –

REGISTER sip:arstechnica.com SIP/2.0

A Response’s Start Line (Status Line) uses the following format:

<Protocol  version><Response Code><Reason phrase>

The reason phrase could be any text describing the nature of the response.

An Example of Status Line is –

SIP/2.0 200 OK

 

Header—Conveys the message attributes and modifies the meaning of the message. Very similar to the HTTP Headers.

All headers maintains the format-

<name>:<value>

Headers can span multiple lines. Some SIP headers such as Via, Contact, Route and Request-Route can appear multiple times in a message or, alternatively, can take multiple comma-separated values in a single header occurrence.

An Example of Header is –

Contact: sip:gilad@voxisoft.com;Expires=2000

Contact is the header name, sip:gilad@voxisoft.com is the value, and expires=2000 is a parameter. Other parameters may appear separated by semicolons.

Body(Content)— Describes the Session to be initiated (for example, in a multimedia session this may include audio and video codec types, sampling rates etc.), or alternatively it may be used to contain opaque textual or binary data of any type which relates in some way to the session. Message bodies can appear both in request and in response messages. SIP makes a clear distinction between signaling information, conveyed in the SIP Start Line and headers, and the session description information, which is outside the scope of SIP.

Possible body types include:

ü   SDP—Session Description Protocol (SDP).

ü   Multipurpose Internet Mail Extensions (MIME).

ü  Others—to be defined in the IETF and in specific

Other posts related to SIP –

Basics of Session Initiation Protocol  (part-4)

Basics of Session Initiation Protocol  (part-5)


Leave a comment

Basics of Session Initiation Protocol (SIP) (part-2)

The previous post was –

Basics of Session Initiation Protocol (part – 1)

Components of a SIP

Entities interacting  in SIP scenario are called User Agents (UA).

Each entity has specific functions and participates in SIP communication as a client (initiates requests), as a server (responds to requests), or as both. One “physical device” can have the functionality of more than one logical SIP entity. For example, a network server working as a Proxy server can also function as a Registrar at the same time.

User Agents may operate in two fashions –

  • User Agent Client (UAC) : It generates requests and send those requests to servers.
  • User Agent Server (UAS) : It gets requests, processes those requests and generate responses.

Note: A single UA may function as both.

Clients:

It may be a softphone application running on your PC or a messaging device in your IP phone. It generates a request when you try to call another person over the network and sends the request to a server (generally a proxy server).

Servers:

Servers are in general part of the network. They possess a predefined set of rules to handle the requests sent by clients.
Servers can be of several types –

Proxy Server:  When a request is generated, the exact address of the recipient is not known in advance. So the client sends the request to a proxy server. The server on behalf of the client (as if giving a proxy for it) forwards the request to another proxy server or the recipient itself.

Redirect  Server:  Redirects the request back to the client indicating that the client needs to try a different route to get to the recipient. It generally happens when a recipient has moved from its original position either temporarily or permanently. Unlike Proxy servers the redirect server does not forward requests to other servers.

Registrar  Server:  Users have to register their locations to a Registrar server. Users from time to time refresh their locations by registering (sending a special type of message) to a Register server.

Location Server:  The addresses registered to a Registrar are stored in a Location Server.

Message Types and Commands of a SIP

There are two types of SIP messages:

Requests—sent from the client to the server.

Responses—sent from the server to the client.

Request Commands:

Command/Method

Description

INVITE Invites a user to call
ACK Confirms a final response to a INVITE
BYE Terminates a Call
CANCEL Cancel searching and ringing
OPTION Queries the capabilities of Sever/Other side
REGISTER Register the Location Service
INFO Send the mid-session info that will not modify the Session state

Response Commands: Response Message  contains numeric response codes. There are 2 types of Response  Commands and 6 classes –

2 Types :-

Provisional (1xx class)—provisional responses are used by the server to indicate progress, but they do not terminate SIP transactions.

 Final (2xx, 3xx, 4xx, 5xx, 6xx classes)—final responses terminate SIP transactions.

6 Classes:-

1xx : Provisional,Searcing,Quering,Ringing.

2xx : Success.

3xx : Redirection,Forwarding

4xx : Request Failure(client mistakes).

5xx : Server failure.

6xx : Global failure(busy,refusal,not available anywhere).

Other posts related to SIP –

Basics of Session Initiation Protocol  (part-3)

Basics of Session Initiation Protocol  (part-4)

Basics of Session Initiation Protocol  (part-5)