CHAPTER SIX

Document Sample
CHAPTER SIX Powered By Docstoc
					                                        CHAPTER SIX


6.0                         DESIGN AND IMPLEMENTATION


This chapter presents the design decisions, design and implementation of a Bluetooth access point
and a Bluetooth soft phone. A Bluetooth access point is a terminal or device that provides Bluetooth
access and services to more than one Bluetooth devices at a particular time. A soft phone is a soft
ware or computer program for making calls over the internet using a general purpose computer,
rather than a dedicated hard ware. However, in this design, the soft phone would be designed to run
on a Bluetooth enabled mobile phone that supports the Java 2 Micro Edition, such as the Nokia
series 60 phones. This chapter is divided into two major parts. The first part will deal with the
design and design issues while the second part will deal with the implementation. Each part will be
divided into two major sub parts, one for the access point and the other for the soft phone.


6.1                        DESIGN
The design model like many other network deigns is essentially a client-server model with the
access point acting as the server and the Bluetooth enable mobile phones connected to the aces
point acting as clients.
It would be assumed that the reader has knowledge of the Java Programming language’s Thread
application programming interface as this would be widely used in the design of both the client and
the server.


6.1.1                      DESIGN OF THE ACCESS POINT


As already stated in section 6.0 above, an access point is a terminal that provides Bluetooth access
and services to other Bluetooth services that are in range and wish to connect and use the services
offered by the access point. More often, in a piconet, the access point is the master and the
Bluetooth devices connected to it and using its services are the slaves. In this design, the access
point will be a computer that provides access to the internet to client mobile phones wishing to
make VOIP calls. Hence the main service of the access point is to provide internet access to a
maximum of seven (at any particular time) connected slave devices.
In the Bluetooth protocol stack, the Bluetooth Network and Encapsulation Protocol (BNEP)
provides network connectivity to connected Bluetooth devices. Hence using this protocol, one could
easily establish a Bluetooth connection between two devices and provide network services at the
same time. However, most mobile devices in the market today do not yet support BNEP. Hence it
becomes necessary to design a system that can provide the basic services offered by the BNEP. To
make the design as simple as possible, keeping in mind the limited memory and processing speed of
a client mobile device (Bluetooth enabled mobile phone), the following design decisions were
arrived at.


    i.        The access point would be run on a computer and provide Bluetooth connections to
              Bluetooth enabled mobile phones
    ii.       The access point would essentially be a Java program running on a computer.
    iii.      The access point would receive data from mobile devices connected to it and forward the
              received data on to the internet
    iv.       Data received from the internet would also be forwarded to the appropriate device on
              arrival of the data at access point.
    v.        The access point would keep track all the devices connected to it at any particular time,
              keeping in mind the maximum piconet size of seven slaves.
    vi.       The access point would provide resources for internet connectivity for each device
              connected to the access point and releasing the resources when the connected devices
              disconnects from the access point or goes out of the Bluetooth range.
    vii.      The access point should only be concerned about the type of data it receives or send and
              not on the contents of the data. The access point could however, alter the some of the
              contents of the data it handles.
                                              INTERNET


                                Data Flow
                                                                            Mobile Device
                                       Bluetooth Access Point




                          MD1                                            MD4


                                                                MD3
                                            MD2


                    Figure 6.1         Bluetooth Access Point
Figure 6.1 shows the Bluetooth access point with four mobile devices (MD1-MD4) with the green
lines representing the flow of data.


From the information presented in chapters three and four, the main data transported in any VOIP
call are SIP data and RTP data. The SIP data is used for call setup (session setup) while RTP data
essentially carries digital voice data. Hence the access point would provide resources for handling
these two types of data. Since any network device needs at least a port to be able to receive and
send data to the network, the access point would provide two ports to each client connected to it.
One port would be responsible to exchanging SIP data with the internet and the other port would be
responsible for sending RTP data. The access points essentially acts a proxy between the clients and
the internet.
When the access points starts up, it initializes its Bluetooth stack and sets up resources that are to be
used by connecting client. One of the resources set up by the access point is a set of seven ports for
the anticipated maximum of seven client devices in a piconet. Each set of the seven ports contain
two ports, one for handling SIP data and the other for handling RTP data.
When a client connects to the access point, the access point sets up two main threads, one thread
called the sender thread for handling the sending of data to the client and the other thread called the
reader thread for receiving data from the client. The data to be sent or received is encapsulated in a
packet known as a BVpacket (Bluetooth VOIP Packet). This packet has a header for identifying the
type of data it contains. After a client must have successfully set up a Bluetooth connection with the
access point, a set of messages are first exchanged between the client and the access point. These
first set of messages is similar to the three-way handshake mechanism of the TCP/IP protocol.
However, only two messages are sent in this case. On successful establishment of a Bluetooth
connection, the access point receives a HELLO_SIGNAL message from the client. This message is
contained in a BVpacket and has a header type that signifies that the packet contains a
HELLO_SIGNAL message. The HELLO_SIGNAL message contains the name of the client that
sent the message. This name is stored at the access point. On receipt of the HELLO_SIGNAL
message, the access point sends back an ACK_HELLO_SIGNAL message to the client. The
ACK_HELLO_SIGNAL message contains the name of the access point, its IP address the SIP and
RTP ports that the access point has allocated to this client, the IP address and port number of a SIP
Proxy server. In this design, the SIP proxy server runs on the same computer as the access point,
hence the proxy server IP address will be the same as that of the access point. This information
would be used by the client as will be later discussed. Table 6.1 shows the various types of signals
exchanged between the clients and the access point.
Table 6.1         SIGNALS EXHANGED BETWEEN CLIENTS AND ACCESS POINT
MESSAGE_SIGNAL                    VALUE                             JAVA TYPE
HELLO_SIGNAL                      1                                 integer
ACK_HELLO_SIGNAL                  2                                 integer
EXIT_SIGNAL                       3                                 integer
SIP_SIGNAL                        7                                 integer
RTP_SIGNAL                        8                                 integer


When the client has successfully received an ACK_HELLO_SIGNAL from the access point, it can
begin sending data packets (ultimately BVPackets), always defining what type of data packet is
being sent.
As stated earlier, for each client connection to the access point, there are corresponding sender and
reader threads. In addition to these two threads, there are two servers. One server for handling SIP
messages, called SIP server and the other for handling RTP messages called the RTP Server. Each
of these servers contains two threads. The SIP Server contains a thread for reading SIP messages
from the network, called the SIPPacketReader, and the other for sending SIP messages to the
network (the SIPPacketSender). The RTP Server also contains two threads, one for reading RTP
messages (data) from the network, called the RTPPacketReader, and the other for sending RTP
messages to the network (the RTPPacketSender). The SIP Server knows about the sender and the
reader threads that handle Bluetooth packets from the client. Immediately a client connects to the
access point and all its needed resources have been set up, the sender and receiver threads
corresponding to this client are started. Also started at this time, are the SIPPacketSender and
SIPPacketReader threads for this client. These threads are started through the SIP server that
corresponds to this client. The SIP related threads are stared immediately because it is assumed that
a call setup must first be established via SIP before any RTP packets can be exchanged. If the RTP
related threads had been started immediately and the called party did not answer the call, then no
RTP data would have been sent, resulting in loss of valuable memory and CPU resources.
Whenever the access point receives a message from the client, through the reader thread, it checks
the type of the message received. If it is a SIP message, the message is placed in an outgoing SIP
message queue and the SIPPacketSender thread notified that there is a message to be sent to the
network. The SIPPacketSender then picks up the queued message and sends it out to the network,
using the IP address and the SIP port that was allocated to this client. When a message arrives at the
SIP port allocated to a client, the client’s SIPPacketReader thread reads the message, adds the
appropriate header (SIP_SIGNAL), builds a BVPacket and places the packet in a BVPacket out
going queue. The SIPPacketReader thread then notifies the sender thread that corresponds to this
client that there is a BVPacket to be sent over Bluetooth to the client. The sender thread then sends
out the BVPacket via Bluetooth to the client.
After a successful setup of a call session, the client will send out its first RTP packet. Once this
packet is received at the access point, the reader thread allocated this client places the packet in an
RTP out going queue and an RTP server for this client is started. The RTP server, just like the SIP
server contains two threads, the RTPPacketSender and the RTPPacketReader threads, that are
started when the RTP server is started. These threads perform the same functions as the
SIPPacketSender and SIPPacketReader threads, but this time around, the RTPPacketSender reads
data from an out going RTP message queue and writes the sends the data to the internet via the RTP
port allocated to this client. Likewise the RTPPacketReader thread reads incoming data from the
RTP port allocated to this client, adds the appropriate RTP SIGNAL header, builds a BVPacket,
places the BVPacket in the BVPacket out going queue and notifies the sender thread allocated to
this client that there is a BVPacket to be sent over Bluetooth to the client.
When a client wishes to stop using the services of the access point, it sends out an EXIT message
via Bluetooth to the access point. On receipt of this message at the access point by the reader thread
assigned to the client, the access point releases all the resources allocated to this client. The access
point releases the SIP and RTP ports assigned to this client making them available again for other
clients that may join the piconet. The SIPPacketReader, SIPPacketSender, RTPPacketSender and
RTPPacketReader threads for this client are terminated and then the reader and sender threads for
this client are finally terminated.




               Figure 6.2 Internal Structure of the Access Point
Figure 6.2 shows the internal structure of the access point. It shows how the various threads interact
with the appropriate queues as described above. The dotted lines represent the various threads
running in the access point, though the threads responsible to the initial Bluetooth connection setup
have been left out. It should however be noted that the dotted lines denoted as ‘HELLO,
ACK_HELLO EXIT Messages’, ‘SIP Data’ and ‘RTP Data’ are not actual threads but represent the
type of data that is handled by the Reader thread. All these lines are essentially the Reader thread,
but carry different types of data. The box named ‘RFCOMM connection’ signifies the type of
Bluetooth data connection used in this design. It was stated in chapter five that there are two types
of Bluetooth connections, RFCOMM and L2CAP. The choice of the RFCOMM connection over
the L2CAP connection will be discussed later in this chapter.




6.1.2            DESIGN OF SOFT PHONE (ON MOBILE DEVICE)
This section will be sub-divided into four sub sections to handle the major parts in the design of the
soft phone on the Bluetooth enabled device. The first section would discuss the way the Bluetooth
connection has been setup. The second section will deal with SIP setup design, the third section will
deal with RTP setup design while the fourth section would discuss media capture and play back.


6.1.2.1          BLUETOOTH CONNECTION SETUP
To setup a Bluetooth connection, the soft phone application first initializes its Bluetooth protocol
stack. This is handled by the operating system of the device. The application then searches for
available Bluetooth devices in the environment (device discovery). After devices have been found,
the application then searches for the particular Bluetooth VOIP service on the discovered devices.
This service is defined by a Universal Unique Identidier (UUID) as described in chapter five. The
UUID for this service is known both to the application and the access point, hence the application
on the soft phone searches only for this service. Once this service is found on the device (access
point in this case), two threads that handle the Bluetooth connection are started. These threads are
known as the BVPacketSender and BVPacketReader threads. The BVPacketSender thread is
responsible for sending any data to the established Bluetooth link while the BVPacketReader thread
is responsible for reading any data from the Bluetooth link. These threads are located in the lowest
layer of the application, otherwise known as the network layer. All transactions through the
Bluetooth link must pass through this layer. The network layer also contains an outgoing buffer.
When the application wishes to send data to via Bluetooth to the access point, it must encapsulate
the data in an appropriate BVPacket, inserting an appropriate header as described in section 6.1.1
above and then place the resulting BVPacket in the out going buffer. Any thread or top layer
process that places data in the out going buffer must notify the BVPacketSender thread that there is
a BVPacket to be sent. The BVPacketSender thread in turn picks up the packet and sends it out to
the Bluetooth link. However, there is no incoming data queue. All data received by the
BVPacketReader thread is immediately inspected (by reader the packet header) and sent to the
appropriate top layer application or process, through event listeners, for handling.
Figure 6.2 Internal Structure of the Network layer


Figure 6.2 shows the internal structure of the network layer. As in figure 6.1, the dotted lines
represent the various threads in the Network layer. However, the lines named ‘Application Specific
Data’, ‘Out Going BVPackets’ and ‘HELLO, EXIT messages’ are essentially threads but have been
named this way to describe the types of data carried in these threads. The lines named ‘Application
Specific Data’, and ‘HELLO, EXIT messages’ are types of data carried in the BVPacketReader
thread while the threads that carry the ‘Out Going BVPackets’ are application specific. Hence one
would expect that any application that needs to send out data to the Bluetooth link must have access
to the out going BVPacket queue.
Once the BVPacketSender and BVPacketReader threads are started, the soft phone application
sends out a ‘HELLO’ message to the access point. On receipt of this ‘HELLO’ message, the access
point registers the connected client and performs all the resource allocations to this client as stated
in section 6.1.1 above. The access point then replies to the client with an ‘ACK_HELLO’ message
containing the name of the access point, its IP address the SIP and RTP ports that the access point
has allocated to this client, the IP address and port number of a SIP Proxy server. The mobile client
on receipt of the ‘ACK_HELLO’ message has an IP address, SIP and RTP port numbers that it can
use in building up SIP messages and RTP packets and subsequently UDP packets as described in
chapters three and four.


6.1.2.2       SIP SETUP
The set up of a SIP stack turned out to be a major challenge in this design. A SIP stack is just a
software implementation of the Session Initiation Protocol. Three options were available.
   i.      To build and implement a complete or a simple SIP stack.
   ii.     To utilize the already existing SIP API for J2ME from Nokia that is available to some
           modern mobile phones.
   iii.    To utilize an open source SIP stack that exposes the internal structure of all the methods
           available in the API.
The first option was quickly dropped since it would have taken a lot of time to design and
implement such a stack and this project is not about the design and implementation of a SIP stack.
The second option looked quite promising since one would just call the necessary methods and
everything would work just fine and easy. However, the Nokia SIP stack library is based solely on
use of Internet Access Providers. These Internet Access Providers are available on Nokia phones in
the system-wide storage for communication-related settings and refer to the GSM network interface
for an IP address. Without providing specific Internet Access Provider, the Nokia SIP stack never
receives a valid IP address. The main part of the Nokia SIP library is unfortunately closed hence
overriding the methods that handle transport in the Nokia SIP stack so that these methods utilize a
different transport mechanism is not possible. In addition, the present implementation of the SIP
API assumes that the data would be sent the network either via UDP or TCP. No provision has been
made for the transfer of data via Bluetooth. One short cut would have been to implement a server
within the soft phone application. Such a server would receive SIP data from a local UDP socket
and then send the data out via the Bluetooth link. However, with the limited resources available on
Connected Limited Device Configuration (CLDC) devices, this option would be a waste of valuable
resources. In addition, not many phones in the market presently support SIP and hence this option
was dropped.
The third option was the left to be explored and utilized. After considerable search on the internet,
an open source SIP stack known as MJSIP (www.mjsip.org). This open source stack is a complete
java-based implementation of a SIP stack. This stack natively works on both J2SE and
J2ME/CDC/Personal Profile 1.0. However, also available for usage on a J2ME/CLDC/MIDP-2.0
platform is an adapted version known as MjSip2ME. The MjSip2ME differs from the standard
MjSip implementation in that it has very classes but offers the same functionality. This stack was
chosen because, being open source and the codes for the classes readily available, it was possible to
adapt the classes responsible for sending out data to the network to utilize a Bluetooth link.
A detailed description of all the classes present in the API would not be given in this thesis. The
reader,   if   interested   could   obtain   such   information     from   the    API’s   website   at
www.mjsip.org/mjsipMe.html.
The MjSip API implements a layered architecture as shown in figure 6.3.
                     Figure 6.3 MjSip API’s Layered Architecture
Figure 6.3 shows the two main layers in the MjSip Model; the Lower Provider Layer and the Upper
layer. The upper layer contains various classes not directly involved in communication with the
network (that is sending and receiving of data), while the lower layer contains classes that receive
data from the upper layers and send the data to the network as well as receive data from data from
the network and in turn send the data to the appropriate upper layer processes via appropriate
callback methods. In figure 6.3 only a sub set of the classes present in the lower layer has been
shown, since these are the classes of interest in this project.
The API contains a number of classes. Of interest in this design is the SipProvider Class. This is the
main class that implements a SIP transport layer. The SIP Transport layer is responsible for sending
and receiving SIP messages. Messages are received by callback functions defined in an interface
known as the SipProviderListener. Since the SipProvider is responsible for sending and receiving
SIP messages, it through this class that one can channel messages though a Bluetooth link. In the
MjSip2ME API, there are four transport protocols that could be used to send out data, two of which
are TCP and UDP. The class responsible for sending out data using UDP is known as
‘UdpProvider’. This class contains methods that send data to and receive data from a UDP socket.
In this design, a reference to the out going BVPacket queue is passed to a UdpProvider class object.
This reference is hence available to the send() method of the UdpProvider class. Within this
method, instead for the data to be sent to a UDP socket as is normally the case, a BVPacket
containing the data be sent is built, placed in the out going BVPacket queue and the
SIPPacketSender thread notified that there is packet to be sent. The UdpProvider class also listens
for events generated in the Network Layer. When SIP data is received by the BVPacketReader
thread in the network layer as described above, the UdpProvider class object is notified and the data
picked up and handled. Within the event handler method of the UdpProvider class are call back
methods of the SipProvider class. Through these methods, the received data is sent to the
appropriate processes (in the upper layer).
With this design, the upper layer processes would never know the exact underlying protocol that is
being used to send out the data. In this scenario, the upper layer processes still think that they are
using UDP as their transport protocol, when in fact it is the Bluetooth protocol that is being used.


6.1.2.3             RTP SETUP
As discussed in chapter four, the Real Time Protocol (RTP) is main protocol used to transport real
time data in most VOIP systems. In addition to the Real Time Protocol is the Real Time Control
Protocol (RTCP) that is used to transfer RTP control packets. RTCP is however, mostly employed
in multi-peer calls, that is in conference VOIP calls and in sessions where more than one type of
media is transported between end users, such as in video calls where both audio and video data are
transported. In this design, however, to make the work as simple as possible, the application can
handle only one call at a time. Hence in any particular session, only one caller and one callee would
be present. In such a scenario, the use of RTCP would not be very necessary and its use in such a
memory and CPU speed restricted environment would be over kill. Hence in this design, only RTP
would be used to transport audio data.
As at the moment of writing this report, there is no RTP stack available for the J2ME platform.
There are however many open source Java RTP implementations. One of these Java RTP
implementations was chosen and adapted for the J2ME platform. The Java RTP implementation
that was used is described in [1, RTP IMPLEMENTATION]
The first thing to do in any Java RTP implementation is the design of an RTP packet. The RTP
packet was designed as a java class known as ‘RTPPacket.java. This class has as variables a
Sequence Number, a TimeStamp, a Synchronization Source (SSRC), a Contributing Source Count
(CSRCCount) and the payload data. However, in the actual transfer of an RTP packet all the fields
in an RTP packet header, as described in chapter four are defined and used. The variables of the
RTPPacket class stated above have chosen because these are the variables that would be widely
within the application to distinguish between various RTP packets.
The main class that handles and controls the flow of the RTP data is known as the ‘Session’ class.
This is the top most class in the RTP implementation. This class encapsulates the RTP setup startup
and shutdown procedures. The Session also acts as the interface which processes that need to send
RTP data utilize.
On successful establishment of a SIP session, during a call setup, the RTP port number of the called
party becomes available to the application. With this information the application starts an RTP
session by creating an object of the Session class. This class contains two threads known as the
RTPPacketSender and the RTPPacketReader. The RTPPacketSender thread handles the sending of
RTP data to the network while the RTPPacketReader handles the data that has been received from
the network. The Session class contains an out going RTP data queue that is filled with real time
data that needs to be sent to the network. Whenever the application needs to send out real time data
to the network, the data is compressed to reduce its size and save to save bandwidth and placed in
the Session’s class out going queue with data. Once the out going queue receives the compressed
data, the RTPPacketSender thread is notified that there is a packet to be sent. The RTPPacketSender
thread then removes the data from the out going queue, fragments the data if need be, adds the
necessary RTP header fields and passes the resulting RTP packet to the Network layer, informing
the Network layer to build an RTP BVPacket. What this means is essentially to sign the BVPacket
as containing an RTP packet by adding the appropriate header as described in section 6.1.1. The
Network layer then builds the RTP BVPacket, places the resulting packet in its out going queue and
informs the Network Layer’s sender thread (BVPacketSender) that there is a packet to be sent. The
sender thread now sends out the packet on to the Bluetooth link. This is illustrated in figure 6.4




                      Figure 6.4         RTP SETUP
On receipt of an RTP BVPacket from the Bluetooth link, the BVPacketReader in the Network layer
notifies an event listener that listens for the arrival of RTP packets. In this case, the even listener is
the Session class. The BVPacketReader thread then strips the RTP message header from the
received RTP BVPacket and sends the resulting packet to the Session class. In the session class, the
RTP packet is validated and an object of the class RTPPacket generated and placed in an incoming
RTP queue. In this design, all the received packets will be unavoidably fragmented packets. Hence
the packets have to be combined together to generate the original voice data. The reason for this
unavoidable fragmentation will be discussed later in this chapter. Since all packets that contain
voice data generated at the same time will have the same timestamp but different sequence
numbers, these two parameters would be used to sort out related fragmented packets. For this
reason, the in coming RTP queue is designed has a hash-table, with the key being the timestamp
and the value a sorted vector. The Sorted Vector was designed as a class that extends java’ Vector
class and the RTPPacket class designed to implement the java.lang.Comparable interface. Objects
of the RTPPacket class are stored in the Sorted Vector and each time a new object is added to a
Sorted Vector, all the elements already in the Sorted Vector object including the newly added
RTPPacket object are sorted according to the sequence numbers of the RTPPacket objects, since all
the objects in a Sorted Vector must have the same timestamp. Hence each time a new RTPPacket is
to be added to the in coming RTP queue, the timestamp of the RTPPacket is obtained used as key to
obtain the corresponding Sorted Vector object in the in coming RTP queue. Once the appropriate
Sorted Vector object is obtained, its addElement() (that has been overridden to take care of sorting)
method is called passing to it the newly arrived RTPPacket. After each RTPPacket is added to the in
coming RTP queue, the RTPPacketReader thread is notified that a new packet has been added. The
RTPPacketReader thread then reads the timestamp of each Sorted Vector in the queue and checks if
the difference between the timestamp and the current session time is greater than some threshold
value. If the difference is greater than or equal to this value, then Sorted Vector is removed from the
queue, all the data in the Sorted Vector combined to form one un-fragmented voice data, the
appropriate headers added and sent to a play out buffer. For simplicity and as a very rough estimate,
this threshold value will be initially set at 300 milliseconds. But it must be stressed here that this is
a very rough and should be used in any commercial application. The value of 300 milliseconds was
arrived at because studies of human perception point to a limit in round-trip time of about 300
milliseconds as the maximum tolerable for interactive use. This limit implies an end-to-end delay of
only 150 milliseconds including network transit time (time take for data to move across the network
from caller to callee) and buffering delay (time taken to store received data before playout). It
should be noted that the data sent to the play out buffer is still compressed. Un-compression and
subsequent addition of an appropriate audio-file header is done just before the audio data is to be
played out in the application. This is to save valuable memory space that is limited in the J2ME
platform.
6.1.2.4 MEDIA CAPTURE AND PLAYOUT.


The capture and play out of audio media turned out and is still the most difficult part in the whole
design process and in fact in the whole thesis work. To understand this difficulty one needs to take a
look at how the Java 2 Micro Edition handles multimedia.


The Mobile Media API (MMAPI) 1.1, together with the Mobile Information Device Profile 2.0
offers a range of multimedia capabilities for mobile devices, including playback and recording of
audio and video from a variety or sources. However, not all mobile devices support all the features
offered in the MMAPI. Nevertheless the MIDP 2.0 comes with a subset of the MMAPI which
ensures that if a device does not support MMAPI a scaled down version that supports at least audio
is made available. The MMAPI defines a superset of the multimedia capabilities present in MIDP
2.0 and was started in the Java Specification Request 135 [2 REFERENCE]. The current version is
1.1. The MMAPI is built on a high-level abstraction of all the multimedia devices that are possible
in a resource limited device. This abstraction is manifest in three classes that form the bulk of
operations that can be performed with this API. These classes are the Player and Control interfaces,
and the Manager class. Another class, the DataSource abstract class is used to locate resources, but
is rarely used directly.
The Manager class is used to create Player instances for different media by specifying DataSource
instances. The Player instances thus created are configurable by using Control instances. Once a
Player instance is created, it needs to go through various stages before it can be used. Upon
creation, the player is in an UNREALIZED stated and must be REALIZED and PREFETCHEED
before it can be used. Realization is the process in which the player examines the source or the
destination media resources and has enough information to start acquiring them. Bothe realization
and pre-fetching processes may be time and resource consuming, but performing them before the
player is started ensures that there is no latency when the actual start happens. Once a player is
started, by calling the Player class’s start() method, and is processing data, it may enter the
PREFETCHED state again when the media stops on its own ( because the end of the media may be
been reached). The player can however be stopped by calling the stop() method on the Player
instance or when a pre-defined time is reached. Going from STARTED to PREFETCHED state is
like pausing the player, and calling start() on the Player instance restarts from previous paused
point. A player can go into the CLOSED state if a call is made to its close() method, after which
the Player instance cannot be reused. However, the player could be returned to the REALIZED state
by calling its deallocate() method, which releases all the resources acquired by the player. The
various states in the life cycle of a Player instance and the transitions between them are shown in
figure 6.5




               Figure 6.5 Media player states and their transitions
Apart from the above mentioned state changes, a player also enables control over the properties of
the media that it is playing by using controls. A control is a media processing function that may be
typical for a particular media type.


The capture of audio in the soft phone is performed by a Player instance, in a layer that would be
termed for descriptive processes, the ‘Audio Layer’. The Audio Layer is responsible for capture and
playback of audio media. It receives raw audio data from the play out buffer defined above, and
schedules the media for play out. The Audio Layer also generates audio data and feeds the data to
the out going RTP queue. The raw audio data generated by the Player instance of the MMAPI is
uncompressed 16-bit PCM (Pulse Code Modulation). Pulse Code Modulation (PCM) is a digital
representation of an analog signal where the magnitude of the signal is sampled regularly at uniform
intervals, then quantized (Quantization is the process of approximating a continuous range of
values [or a very large set of possible discrete values] by a relatively-small set of discrete symbols
or integer values) to a series of symbols in a digital (usually binary) code. The uncompressed audio
data is compressed from PCM-16 bit to PCMU (PCM mu-law) 8 bit, resulting a 50% reduction in
size of the audio data. This compression is performed just before the data is fed into the out going
RTP queue.
The advisable size of the payload data in an RTP packet is 20 bytes [RTP BOOK]. Moreover, the
human ear cannot notice any difference in sound if the sound is sampled at less than 200
milliseconds. However, when media is captured with a Player instance for a length of even 100ms
produces an audio media of about 1000bytes. Even at this sample time, the player instance does not
capture any human audible sound and as the sampling time is increased so too is the size of the
audio data generated by the player instance. In addition, the J2ME MMAPI does not support full
duplex audio facilities. That is one cannot utilize the functionality of the microphone and the
speaker at the same time. Each instance of the player uses the resources of both the microphone and
the speaker and these resources cannot be shared at the same time by two speakers. One is therefore
left with two options;
   i.      Design the application to be a push-to-talk system, where one peer in a conversation
           speaks while the other listens and vice versa
   ii.     Mimic a full-duplex scenario by creating to speakers and using a thread to alternate
           between the two players, during a phone conversation.
The first option was very straight forward and not quite challenging while the second option was
more involved. It was decided that the second option would be used, since my research has shown
that this has only been done in proprietary applications.
In the design of the full-duplex scenario, two player instances, running in two different threads,
were created and a lock shared between the two. One of the player instances was used as a
microphone while the other was used as a speaker. On successful setup of a SIP session and audio
communication needs to be started, the instances of the two players are created and the microphone
player thread started first, followed by the speaker player thread. The microphone player then
captures data for a pre-determined length of time, after which it stops and sends the data to the
Session object which subsequently compresses the data and places it in the out going RTP queue.
When the speaker player instance obtains the lock, it checks the play out buffer if there is audio-
data to be played. If there is audio data, it obtains the data, un-compresses it, adds the appropriate
audio media header (in this case the media format is the wave file format) and plays the generated
audio file, after which it releases the lock. If there is no data to be played, the speaker player
instance releases the lock so that the microphone speaker can capture audio data.


Combining all the above design discussions will result in the complete VOIP over Bluetooth
application. However, a SIP proxy server to ensure registration and subsequent communication
between SIP user agents (mobile-phones) is needed. After careful research on the internet, an open
source windows based SIP server, the Brekeke SIP server [3] was chosen and used as the SIP
Server. The main reason why this server was chosen was because, it acted both as a proxy and a SIP
server and it supported the relay of RTP packets (very useful in situations were Network Address
Translation is required). This server also has a graphical user interface whereby one can monitor all
registered SIP user agents and monitor calls between registered user agents. Figure 6.7 shows the
final setup of the VOIP over Bluetooth application and access point.




                          Figure 6.6 Final Design Setup
In figure 6.6, the SIP server has been shown to be out side the access point. This is because the
access point is considered to be a software application running on a computer. In the final setup
however, both the SIP server and the access point run on the same computer. In reality however, the
SIP server and the access point could be on two separate computers.


6.1.3                  CHOICE OF BLUETOOTH CONNECTION
In chapter five, it was shown that there are two possible connection types in the Bluetooth protocol;
RFCOMM and L2CAP. The RFCOMM is a stream based connection while L2CAP is packet based.
One would quickly conclude that the L2CAP connection being packet based would be the best
connection type to be used to transfer UDP packets. However, the choice of the connection type
does not only depend on the type of packets to be transferred but also on the operating system of the
hardware where the access point runs. The hardware on which the designed access point would run
is a windows computer and unfortunately, as at this moment, the windows Bluetooth stack does not
yet support L2CAP connections. This type of connection is only presently supported on linux/unix
computers. However, proprietary Bluetooth stacks such as the Avetana Bluetooth [4] stack does
support L2CAP connections on a windows platform. Because of the limitation to only RFCOMM
connections on windows computers, the RFCOMM connection was used as the main Bluetooth
connection in this design.


6.2                IMPLEMENTATION
As with the design part, the implementation would be divided into two sections; the implementation
of the access point and the implementation of the VOIP over Bluetooth application.


6.2.1                  ACCESS POINT IMPLEMENTATION
The access point consists of 15 Java classes and two Java Interfaces. Each of these classes will be
presented and brief descriptions of what is performed by the class given.


      i.     BVEventListener.java: This event listener interface contains events that are generated
             when ever a message arrives at the Bluetooth link. That is when ever the reader thread
             receives Bluetooth messages. Any class that needs to perform some action that depends
             on what type of message is received at the Bluetooth link will have to implement this
             event Listener class.
      ii.    Persistent.java: This is an interface that contains two methods; persist() which returns a
             byte array, resurrect() which takes a byte array and returns nothing. This class was
             developed because the Java 2 Micro Edition has no support for serialization (the process
             of converting a set of object instances that contain references to each other into a linear
             stream of bytes, which can then be sent through a socket, stored to a file, or simply
             manipulated as a stream of data). Since data objects had to transferred between the
             access point running on J2SE and the VOIP over Bluetooth application running on
             J2ME, this interface was very much necessary for the adequate transfer of data objects.
      iii.   AccessPoint.java: This is the main class for the access point application. It is in this
             class that access point application starts.
      iv.    AvailablePorts.java: This class is called once during the life time of the application. The
             class generates seven pairs of ports. Each pair of ports consists of a SIP port and an RTP
        port. Seven pairs are generated since the maximum number of slaves in a Bluetooth
        piconet is seven.
v.      Ports.java: This class just holds information about a two ports. One port for SIP and
        another for RTP. The AvailablePorts.java class essential generates seven objects of the
        Ports.java class.
vi.     BVProxyServer.java: This class is responsible for setting up the Bluetooth device and
        service discovery. This class makes available the service offered by the access point to
        other Bluetooth devices in the vicinity. The BVProxyServer.java class allocates all the
        resources to a client that has successfully made a Bluetooth connection to the access
        point. The class also starts the sender and reader threads for each connected Bluetooth
        device, passing to these threads all the resources allocated to the class. The class also
        frees up resources of a client when the client disconnects from the access point. It is the
        central server of the access point architecture. It runs as a Java Thread.
vii.    BVClient.java: The BVClient.java class represents a connected client at the access point.
        It holds all the resources allocated to a client. Hence an instance of this class is always
        created immediately after a client has made a successful connection to the access point.
        This class holds references to all the resources allocated to a connected client. This class
        provides methods that build BVPackets that are destined for a client and BVPackets
        received from a client are buffered in this class for further processing.
viii.   BVPacket.java: This class holds information about the type of packet data received from
        or being sent to the Bluetooth link. The class has methods that add headers to any type
        of data (datagram) that has to move across the Bluetooth link. Since the BVPacket.java
        class prepares data for transport across the Bluetooth link it implements the Persistent
        interface. Hence any BVPacket that needs to be sent over the Bluetooth link needs to
        called the persist() method it inherits from the Persistent interface, while when any data
        is received from the Bluetooth link a new instance of the BVPacket is created and its
        resurrect() method called, passing to it the data ( a byte array) received from the
        network.
ix.     BVPacketSender.java: Each client connected to the access point has an instance of this
        class associated with it. This class is responsible of sending and data destined to a client
        associated with it. It is the sender thread in the Network Layer. The class periodically
        checks the out going queue for this client in the BVClient.java class for any packets that
        are to be sent over the Bluetooth link. If it finds a packet from the queue and sends it. It
        should be noted that all the packets sent by this class must be instances of the
        BVPacket.java class that have been persisted (the persist() method called t generate a
        byte array that is sent out over the Bluetooth link). This class holds a reference to the
        BVClient.java class The class runs as a Java Thread
x.      BVPacketReader.java: This class performs almost the same function as the
        BVPacketSender, only that it reads data from a client that is associated with it. The class
        reads data (as a byte array) from the Bluetooth link, and creates an instance of the
        BVPacket and calls its resurrect() method, passing to it the data received from the
        Bluetooth link. This way, all the objects present in the data are re-created. Then
        depending on the header (type) of the BVPacket, it passes the data to the instance of the
        BVClient associated with this client. The method in the BVClient class to which the
        received data is passed depends on the type of BVPacket received. The class runs as a
        Java Thread.
xi.     BVProxyParameters.java. This class only holds attributes of the access point, such as its
        IP address and name, attributes of the SIP and RTP port allocated to a client, and the IP
        address and port of the SIP server. The information held by this class is valuable to any
        client that connects to the access point. This class implements the Persistent interface.
xii.    NetworkSIPServer.java: The NetworkSIPServer.java class acts as an internal server for
        handling SIP requests and responses for a particular client. This class holds references to
        two threads that are responsible for sending SIP request to the internet and receiving SIP
        responses from the internet. The purpose of this class is to create a datagram socket (for
        the transport of UDP datagrams ) and to initialize and terminated these threads.
xiii.   SIPPacketSender.java: This class is responsible for sending SIP packets for a particular
        client to the internet. This class holds a reference to the instance of the
        NetworkSIPServer that created an instance of it (SIPPacketSender). All this class does is
        to check for SIP packets in an out going SIP queue present in the instance of the
        BVClient class. If it finds a packet, it sends it out to the internet. Alternatively when ever
        a packet is placed in the out going SIP queue, this class is notified that there is a SIP
        packet to be sent. It runs as a Java thread.
xiv.    SIPPacketReader.java. This class performs the function of reading SIP responses or
        requests from the internet. This class holds a reference to the instance of the
           NetworkSIPServer that created an instance of it (SIPPacketReader). The class reads data
           from the socket created by the instance of the NetworkSIPServer, builds a BVPacket
           from the received data by adding the appropriate SIP header, places the packet in the out
           going queue and notifies the BVPacketSender thread that there is a BVPacket to be sent.
   xv.     NetworkRTPServer.java.      This   class   performs    the   same   functions    as   the
           NetworkSIPServer, only this time around, it is responsible for RTP packets. Hence the
           datagram socket created by this class uses the RTP port number allocated to client
           assigned to this NetworkRTPServer.
   xvi.    RTPPacketSender.java. This class performs exactly the same functions as the
           SIPPacketSender.java class but for RTP packets.
   xvii.   RTPPacketReader.java: This class performs exactly the same functions as the
           SIPPacketReader.java class but this time around, RTP packets are handled.




           Figure 6.7 Interaction between the Classes at the Access Point
Figure 6.7 shows the way some of the classes interact with each other. The figure look to contract
some of the discussions presented above, however this is not the case. For example, it has been said
that SIPPacketReader receives data from the network, adds the appropriate headers, and sends the
resulting data to the out going queue. However, this is done through the NetworkSIPServer and the
BVClient classes, since the SIPPacketReader needs a reference to the out going queue, which is
present in the BVClient class. The BVClient instance is only available to the SIPPacketReader
through the NetworkSIPServer. The same analogy holds for the functions of the SIPPacketReader,
RTPPacketSender and RTPPacketReader classes. However, for clarity, the BVPacketReader and
BVPacketSender classes have been presented in the diagram as directly communicating with the
BVProxyServer class. This is not the case. In reality, the BVPacketReader and BVPacketSender
classes communicate with the BVProxyServer class through an RFCOMM connection object that
was passed to them through the BVClient class. The representation in figure 6.7 is just for clarity
purposes.
All the above classes have been grouped into one package called blueproxy.


6.2.2                 VOIP OVER BLUETOOTH APPLICATION IMPLEMENTATION
The implementation of the VOIP over Bluetooth has been divided into two sections; the Network
layer and an upper application layer. The network layer handles only networking issues while the
upper application layer is responsible for the generating and handling of access point registration,
SIP and RTP requests and responses.


6.2.2.1               NETWORK LAYER IMPLEMENTATION
The Network Layer consists of seven Java classes and two Java interfaces. These would now be
presented.


   i.        BVEventListener.java: This class is a Java interface and is the same as the
             BVEventlistener class in the access point implementation.
   ii.       Persistent.java: This is also a Java interface and is exactly the same as in the access
             point implementaion
   iii.      Ports.java: This class is also the same as in the access point implementation
   iv.       BVPacket.java: The same as in the access point implementation
   v.        BVProxyParameters.java: The same as in the access point implementation.
   vi.       BVClientProxy.java. This class performs almost the same functions as the
             BVServerProxy class in the access point implementation. However, after a device
             discovery has been performed and a search for the VOIP over Bluetooth service located
             on one device, the service search is terminated on all the other devices. At this point, the
        sender and receiver threads (that handle sending and receiving of Bluetooth packets) are
        started. Only two of these threads are present in a client, unlike at the access point where
        for each connected client, two threads are created. The BVServerProxy class provides
        the Bluetooth connection required by classes in the upper application layer for data
        transport.
vii.    BVPacketSender.java.      This   class   performs    the   same    functionality   as   the
        BVPacketSender class in the access point implementation, however the out going queue
        from which it obtains its data from is located in a class known as the BVServer.java
        (similar to the BVClient in the access point implementation).
viii.   BVPacketReader.java.      This   class   performs    the   same    functionality   as   the
        BVPacketReader class in the access point implementation. However, this time around,
        when data is received from the Bluetooth link, a BVPacket generated and the header in
        the packet obtain, appropriate events are triggered that are handled by appropriate event
        listeners in the upper application layer. These event listeners must have registered to
        receive these events.
ix.     BVServer.java: This class represents the access point to which a client is connected to.
        An instance of this class is created once a successful connection has been established
        with the access point. The class holds instances of the BVPacketReader and
        BVPacketSender classes. It also holds references of all upper layer application classes
        that need to listen to events generated by the BVPacketReader class. The out going
        queue where out going BVPackets are stored is found in this class. Hence the
        BVPacketSender and BVPacketReader classes must hold references to the same instance
        of this class.
               Figure 6.8 Interaction between classes at the Network Layer
   In figure 6.8 the interactions between some of the classes in the Network layer implementation
   is illustrated. The UDP Packets in figure 6.8 are essentially SIP or RTP packets that have been
   encapsulated in UDP Packets while the REG Packets carry information about the client and the
   access point that are transferred when the client connects to the access point. Such information
   may include the client name, the server IP address, the SIP and RTP ports allocated by the
   access point to the client, etc.
   All the above classes are grouped into a package known as blueClientProxy.


6.2.2.2              UPPER APPLICATION LAYER IMPLEMENTATION
The upper application layer classes form the core classes in the implementation of the VOIP over
Bluetooth application. Most of the classes used in this implementation were obtained from the
MjSiP2ME stack [5]. Hence these classes would not be described here. The interested reader should
consult a mini tutorial that describes all the classes at [6]. However, some of the classes that were
adapted to this implementation would be briefly presented.
The MjSiP2ME stack is presented in five major packages. These packages would now be briefly
described.
   i.        org.zoolu.sdp: This package contains all the classes that provide functionality for the
             generation of Session Description Protocol (SDP).
   ii.       org.zoolu.sip: This package contains all the classes that provide functionality for the
             generation of SIP request and responses. It also contains classes that provide networking
             facilities to a SIP user agent.
   iii.      org.zoolu.tools: This package contains classes that provide certain tools needed in the
             generation of SIP requests and responses. For example classes that generate message
             digest when security and encryption are needed in a SIP request are present in this
             package. Classes that provide logging facilities for debugging purposes are also present
             in this package.
   iv.       j2me.local.media: This package contains classes for handling audio and video media.
             However, these classes require that the Java Media Framework (JMF) should be
             installed in the system. Hence classes in this package were not used in this work
   v.        j2me.net: This package contains classes that provide communication facilities to all the
             classes in the MjSip2ME packages. The classes in this package make direct
             communication with network sockets. It is in this package that some classes were
             adapted to provide Bluetooth networking facilities to the classes in the other packages
             that needed to communicate with the network.


             The classes that were adapted include
             1. j2me.net.UdpSocket.java: This class in its original implementation was responsible
                 for transporting UDP datagrams from and to a UDP socket. However, in this
                 implementation, an instance of the BVServer.java class was added to this class.
                 Through this instance object, any UDP datagram to be sent is just added an
                 appropriate header and placed in the out going BVPacket queue in the BVServer
                 instance, from were is picked up by the BVPacket sender thread and sent via the
                 Bluetooth link.
             2. j2me.net.UdpProvider.java: This class in its original implementation was indirectly,
                 through the j2me.net.UdpSocket.java class, responsible of receiving data from a
                 UDP socket. However, in this implementation, this class implements the
              BVEventListener interface. When an instance of this is created, it registers itself with
              the BVServer as a listener to events generated by the BVPacketReader thread. Hence
              whenever the BVPacketReader thread reads data from the Bluetooth link, generates a
              BVPacket and inspects the header, it triggers an appropriate event depending on the
              inspected header. If this event corresponds to the event registered by the
              j2me.net.UdpProvider.java instance object, the data read by the BVPacketReader
              thread is passed to the instance object and subsequently to the upper layer process
              that requires the data.
   vi.    j2me.local.ua: This package contains classes that perform call, registration and presence
          functionality for a user agent. These classes include the following;
          1. CallAgent.java: This class provides functionality for making setup a SIP session
          2. RegisterAgent.java: This class provides functionality for performing registration
              with a SIP Registrar server
          3. PresenceAgent.java: This class provides functionality for performing SIP
              subscription to a service or presentity as described in chapter three. That is it
              generates SUBCRIBE SIP requests and handles their corresponding responses.
          4. CallAgentListener.java. This class is an interface that provides methods that are
              listened to by a CallAgent instance object.
          5. PresenceAgentListener.java: This class is an interface that provides methods that are
              listened to by a PresenceAgent instance object.
          6. RegisterAgentListener.java. This class is an interface that provides methods that are
              listened to by a RegisterAgent instance object.
          7. myUserAgent.java: This class performs all the activities that are performed by a SIP
              user agent. These activities include registration, subscription session setup and
              termination and call handling. Hence this class has instances of the CallAgent,
              PresenceAgent and RegisterAgent classes. This is a new class that was added to the
              original MjSip2ME package. The class implements the RegisterAgentListener,
              PresenceAgentListener and CallAgentListener interfaces.


Apart from the classes from the MjSip2ME packages, various classes have also been used in the
implementation of the VOIP over Bluetooth application. From simplicity, these classes have been
added to some of the existing packages in the MjSIP2ME group of packages. The following classes
have been added.
   i.     j2me.loca.ua.Session.java: This class handles the flow of RTP packets as described in
          the design section 6.1.2.2 (RTP setup). It is through this class the audio packets
          generated by a J2ME MMAPI player instance is transformed into RTP packets for
          subsequent transport to the Network Layer. It is also through this class that RTP packets
          from the Bluetooth link are transformed into audio packets for play out by the player
          instance.
   ii.    j2me.local.ua.RTPPacketSender.java: This class as explained in section 6.1.2.2 provides
          functionality for the transfer of RTP packets to the Network Layer. It performs the
          fragmentation of compressed audio data, generating RTP packets from the data, and
          sends the RTP packet to an instance of the BVServer class, informing it to generate a
          BVPacket packet with an RTP signal header (as described in Table 6.1)
   iii.   j2me.local.ua.RTPPacketReader.java: This functionality of this class has also been
          explained in section 6.1.2.2 (RTP SETUP). This class is responsible for picking up
          packets from the incoming RTP queue, stripping off the RTP headers and scheduling the
          payload for play out by placing the data in the play out buffer.
The following two packages were create and added to the group of MjSip2ME packages.
   i.     j2me.local.util: This package contains utility classes that provide certain requirements to
          the application. These classes include;
          1. MuLawDecoder.java. This class performs the conversion of audio data from PCMU
              (Pulse Code Modulation µ-law (mu-law)) (8-bits) to PCM-signed (16-bits). It
              decompresses compressed audio data.
          2. MuLawDecoder.java. This class performs the conversion of uncompressed 16-bit
              PCM audio data to compressed 8-bits PCMU audio data.
          3. WavBuilder.java: This class generates a wave file from raw data. It adds the
              appropriate wav file headers to a decompressed array of audio bytes.
          4. SortedVector.java: This class inherits from the java.util.Vector class and has the
              added functionality in that when ever a new object is added to an instance of this
              class all the objects already in the vector are sorted according to some criteria that is
              defined in the class of the objects. Hence all objects added to a sorted vector must
              implement the java.lang.Comparable interface.
ii.   j2me.net.rtp: This packet contains classes that describe an RTP packet. The classes
      include;
      1. RTPPacket.java: This class as described in section 6.1.2.2 (RTP SETUP) describes
         an RTP packet. As discussed in section 6.1.2.2, the class does not hold information
         of all the components in an RTP packet only certain components that are useful to
         the application. This class implements the java.util.Comparable interface, so that
         RTP packets with the same timestamp placed in a sorted vector can be arranged
         according to their sequence numbers.
      2. PacketUtils.java: This class provides functionality for building RTP packets. It is
         through this that the all the necessary RTP packet headers are added to any RTP
         payload data

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:14
posted:5/13/2011
language:English
pages:29