Friday, 31 January 2014

Simple Android Gaming

                                     Gaming in Android

Follow the below steps to create a simple gaming application in Android.

Step1:


Create a XML file .

Step 2:

 
 Add the required images file to path

Step 3:


 Sample Java file for gaming


package com.kilobolt.robotgame;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import android.graphics.Color;
import android.graphics.Paint;

import com.kilobolt.framework.Game;
import com.kilobolt.framework.Graphics;
import com.kilobolt.framework.Image;
import com.kilobolt.framework.Input.TouchEvent;
import com.kilobolt.framework.Screen;

public class GameScreen extends Screen {
enum GameState {
Ready, Running, Paused, GameOver
}

GameState state = GameState.Ready;

// Variable Setup

private static Background bg1, bg2;
private static Robot robot;
public static Heliboy hb, hb2;

private Image currentSprite, character, character2, character3, heliboy,
heliboy2, heliboy3, heliboy4, heliboy5;
private Animation anim, hanim;

private ArrayList<Tile> tilearray = new ArrayList<Tile>();

int livesLeft = 1;
Paint paint, paint2;

public GameScreen(Game game) {
super(game);

// Initialize game objects here

bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);
robot = new Robot();
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);

character = Assets.character;
character2 = Assets.character2;
character3 = Assets.character3;

heliboy = Assets.heliboy;
heliboy2 = Assets.heliboy2;
heliboy3 = Assets.heliboy3;
heliboy4 = Assets.heliboy4;
heliboy5 = Assets.heliboy5;

anim = new Animation();
anim.addFrame(character, 1250);
anim.addFrame(character2, 50);
anim.addFrame(character3, 50);
anim.addFrame(character2, 50);

hanim = new Animation();
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);

currentSprite = anim.getImage();

loadMap();

// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);

paint2 = new Paint();
paint2.setTextSize(100);
paint2.setTextAlign(Paint.Align.CENTER);
paint2.setAntiAlias(true);
paint2.setColor(Color.WHITE);

}

private void loadMap() {
ArrayList lines = new ArrayList();
int width = 0;
int height = 0;

Scanner scanner = new Scanner(SampleGame.map);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();

// no more lines to read
if (line == null) {
break;
}

if (!line.startsWith("!")) {
lines.add(line);
width = Math.max(width, line.length());

}
}
height = lines.size();

for (int j = 0; j < 12; j++) {
String line = (String) lines.get(j);
for (int i = 0; i < width; i++) {

if (i < line.length()) {
char ch = line.charAt(i);
Tile t = new Tile(i, j, Character.getNumericValue(ch));
tilearray.add(t);
}

}
}

}

@Override
public void update(float deltaTime) {
List<TouchEvent> touchEvents = game.getInput().getTouchEvents();

// We have four separate update methods in this example.
// Depending on the state of the game, we call different update methods.
// Refer to Unit 3's code. We did a similar thing without separating the
// update methods.

if (state == GameState.Ready)
updateReady(touchEvents);
if (state == GameState.Running)
updateRunning(touchEvents, deltaTime);
if (state == GameState.Paused)
updatePaused(touchEvents);
if (state == GameState.GameOver)
updateGameOver(touchEvents);
}

private void updateReady(List<TouchEvent> touchEvents) {

// This example starts with a "Ready" screen.
// When the user touches the screen, the game begins.
// state now becomes GameState.Running.
// Now the updateRunning() method will be called!

if (touchEvents.size() > 0)
state = GameState.Running;
}

private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {

// This is identical to the update() method from our Unit 2/3 game.

// 1. All touch input is handled here:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN) {

if (inBounds(event, 0, 285, 65, 65)) {
robot.jump();
currentSprite = anim.getImage();
robot.setDucked(false);
}

else if (inBounds(event, 0, 350, 65, 65)) {

if (robot.isDucked() == false && robot.isJumped() == false
&& robot.isReadyToFire()) {
robot.shoot();
}
}

else if (inBounds(event, 0, 415, 65, 65)
&& robot.isJumped() == false) {
currentSprite = Assets.characterDown;
robot.setDucked(true);
robot.setSpeedX(0);

}

if (event.x > 400) {
// Move right.
robot.moveRight();
robot.setMovingRight(true);

}

}

if (event.type == TouchEvent.TOUCH_UP) {

if (inBounds(event, 0, 415, 65, 65)) {
currentSprite = anim.getImage();
robot.setDucked(false);

}

if (inBounds(event, 0, 0, 35, 35)) {
pause();

}

if (event.x > 400) {
// Move right.
robot.stopRight();
}
}

}

// 2. Check miscellaneous events like death:

if (livesLeft == 0) {
state = GameState.GameOver;
}

// 3. Call individual update() methods here.
// This is where all the game updates happen.
// For example, robot.update();
robot.update();
if (robot.isJumped()) {
currentSprite = Assets.characterJump;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}

updateTiles();
hb.update();
hb2.update();
bg1.update();
bg2.update();
animate();

if (robot.getCenterY() > 500) {
state = GameState.GameOver;
}
}

private boolean inBounds(TouchEvent event, int x, int y, int width,
int height) {
if (event.x > x && event.x < x + width - 1 && event.y > y
&& event.y < y + height - 1)
return true;
else
return false;
}

private void updatePaused(List<TouchEvent> touchEvents) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_UP) {
if (inBounds(event, 0, 0, 800, 240)) {

if (!inBounds(event, 0, 0, 35, 35)) {
resume();
}
}

if (inBounds(event, 0, 240, 800, 240)) {
nullify();
goToMenu();
}
}
}
}

private void updateGameOver(List<TouchEvent> touchEvents) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN) {
if (inBounds(event, 0, 0, 800, 480)) {
nullify();
game.setScreen(new MainMenuScreen(game));
return;
}
}
}

}

private void updateTiles() {

for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
t.update();
}

}

@Override
public void paint(float deltaTime) {
Graphics g = game.getGraphics();

g.drawImage(Assets.background, bg1.getBgX(), bg1.getBgY());
g.drawImage(Assets.background, bg2.getBgX(), bg2.getBgY());
paintTiles(g);

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
g.drawRect(p.getX(), p.getY(), 10, 5, Color.YELLOW);
}
// First draw the game elements.

g.drawImage(currentSprite, robot.getCenterX() - 61,
robot.getCenterY() - 63);
g.drawImage(hanim.getImage(), hb.getCenterX() - 48,
hb.getCenterY() - 48);
g.drawImage(hanim.getImage(), hb2.getCenterX() - 48,
hb2.getCenterY() - 48);

// Example:
// g.drawImage(Assets.background, 0, 0);
// g.drawImage(Assets.character, characterX, characterY);

// Secondly, draw the UI above the game elements.
if (state == GameState.Ready)
drawReadyUI();
if (state == GameState.Running)
drawRunningUI();
if (state == GameState.Paused)
drawPausedUI();
if (state == GameState.GameOver)
drawGameOverUI();

}

private void paintTiles(Graphics g) {
for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
if (t.type != 0) {
g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY());
}
}
}

public void animate() {
anim.update(10);
hanim.update(50);
}

private void nullify() {

// Set all variables to null. You will be recreating them in the
// constructor.
paint = null;
bg1 = null;
bg2 = null;
robot = null;
hb = null;
hb2 = null;
currentSprite = null;
character = null;
character2 = null;
character3 = null;
heliboy = null;
heliboy2 = null;
heliboy3 = null;
heliboy4 = null;
heliboy5 = null;
anim = null;
hanim = null;

// Call garbage collector to clean up memory.
System.gc();

}

private void drawReadyUI() {
Graphics g = game.getGraphics();

g.drawARGB(155, 0, 0, 0);
g.drawString("Tap to Start.", 400, 240, paint);

}

private void drawRunningUI() {
Graphics g = game.getGraphics();
g.drawImage(Assets.button, 0, 285, 0, 0, 65, 65);
g.drawImage(Assets.button, 0, 350, 0, 65, 65, 65);
g.drawImage(Assets.button, 0, 415, 0, 130, 65, 65);
g.drawImage(Assets.button, 0, 0, 0, 195, 35, 35);

}

private void drawPausedUI() {
Graphics g = game.getGraphics();
// Darken the entire screen so you can display the Paused screen.
g.drawARGB(155, 0, 0, 0);
g.drawString("Resume", 400, 165, paint2);
g.drawString("Menu", 400, 360, paint2);

}

private void drawGameOverUI() {
Graphics g = game.getGraphics();
g.drawRect(0, 0, 1281, 801, Color.BLACK);
g.drawString("GAME OVER.", 400, 240, paint2);
g.drawString("Tap to return.", 400, 290, paint);

}

@Override
public void pause() {
if (state == GameState.Running)
state = GameState.Paused;

}

@Override
public void resume() {
if (state == GameState.Paused)
state = GameState.Running;
}

@Override
public void dispose() {

}

@Override
public void backButton() {
pause();
}

private void goToMenu() {
// TODO Auto-generated method stub
game.setScreen(new MainMenuScreen(game));

}

public static Background getBg1() {
// TODO Auto-generated method stub
return bg1;
}

public static Background getBg2() {
// TODO Auto-generated method stub
return bg2;
}

public static Robot getRobot() {
// TODO Auto-generated method stub
return robot;
}

}


Step 5:


   Add Permissions in Manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kilobolt.robotgame"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:icon="@drawable/icon"
        android:label="RobotGame" >
        <activity
            android:name=".SampleGame"
            android:configChanges="keyboard|keyboardHidden|orientation"
            android:label="RobotGame"
            android:screenOrientation="landscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Step 6:


    Run Application in Android Emulator

The  Sample Output images,,





Bandwidth Measurement in NS2 using pathChirp Tool

  •  You should already have the ns-2 simulator installed. You can obtain ns-2 code here. In the following NS-2-DIR refers to your ns-2.* directory (example: ns-2.27)
  • Save current files: Before untarring the code below, save a few ns files that will be overwritten so that you can revert to the original easily. 1) cd NS-2-DIR
    2) tar -cvf original.tar Makefile.in FILES tcl/lib/ns-default.tcl tcl/lib/ns-packet.tcl common/packet.h


    In case you need to revert to the original code:

    1) cd NS-2-DIR
    2) tar -xvf original.tar
    3) make clean
    4) ./configure
    5) make depend
    6) make

  • Download Code: pathchirp_ns_2.27.tar (for ns_2.27), pathchirp_ns_2.26.tar (for ns_2.26)

    To add the pathChirp code to ns-2, copy the pathChirp_ns_2.27.tar (or pathChirp_ns_2.26.tar) file to NS-2-DIR and run the following commands.

    1) cd NS-2-DIR
    2) tar -xvf pathchirp_ns_2.*tar

    If you have not already saved your current files, go to the "Save current files" instructions above. Otherwise follow the instructions in the README_PATHCHIRP file OR proceed as follows.

    3) tar -xvf pathchirp_code.tar
    4) make clean
    5) ./configure
    6) make depend
    7) make

    To run an experiment using pathChirp read the README_PATHCHIRP file.

Thursday, 30 January 2014

Download and Installation of Redhat, fedora, Ubunthu and Vmware AND ns2


  NS2.34

·        Use following link in your browser (ctrl+click following link)

·        After  page was loaded it will directly download (in some browser download dialogue box will open)
==========================================

Utorrent  download

·        Use following link in your browser (ctrl+click following link)

      After loaded the page click on “Download Now“ for µTorrent Stable (3.3.1 build 29812) 
        It will Start Download.

        Install the downloaded file
==================================================

     VMware Workstation download
        Use following link in your browser (ctrl+click following link)
        

·        It will start download torrent file. After finished downloading double click on it.
·        Next window will be open as below Click  “OK”  as shown below, Torrent will start download the VMware Workstation9

·        After Finishing download start Install
===============================
:
    Redhat Linux 32bit Download
·        Use following link in your browser (ctrl+click following link)
·     
·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file.
=============================================

    Redhat Linux 64bit Download
·        Use following link in your browser (ctrl+click following link)
·   

·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file
=======================================
    Ubuntu Linux 32bit Download
·        Use following link in your browser (ctrl+click following link)
·      
·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file

    Ubuntu Linux 64bit Download
·        Use following link in your browser (ctrl+click following link)
·        
·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file
==============================================

    CentOS Linux 32bit Download
·        Use following link in your browser (ctrl+click following link)

·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file
=============================================


    CentOS Linux 64bit Download
·        Use following link in your browser (ctrl+click following link)

·        It will start download the torrent link. After downloaded double click on link
·        It will start download the file
=============================================


    Fedora Linux 32bit Download
·        Use following link in your browser (ctrl+click following link)
·                It will start download the torrent link. After downloaded double click on link
·        It will start download the file
===============================================


    Fedora Linux 64bit Download
·        Use following link in your browser (ctrl+click following link)

· It will start download the torrent link. After downloaded double click on link
·        It will start download the file
======================================

Add New Queue in NS2

Add New Queue




  • Objective
  • To build a simple drop-tail router output queue that uses a round-robin dequeue scheduling for priority 15 packets (from a "MmApp" over "UDPmm") and the other packets in the queue. That is, while priority 15 packets and other packets coexist in the queue, it dequeues the oldest packets of each type one by one in turn.


  • Design
  • The queue has two logical FIFO queues, say LQ1 and LQ2, of which the total size is equal to the size of physical queue (PQ), i.e. LQ1 + LQ2 = PQ. To implement a normal drop-tail enqueue behavior, when a packet is to be enqueued, the enqueue manager checks if size of LQ1 + LQ2 is less than maximum allowed PQ size. If so, the packet will be enqueued to an appropriate logical queue. To implement the round-robin dequeue scheduling, the dequeue manager tries to dequeue one packet from a logical queue and the next one from the other logical queue in turn. I.e. packets in the two logical queues are dequeued at 1:1 ratio if both queues have packets.


  • Implementation
  • We named the C++ name for this queue object "DtRrQueue" (Drop-Tail Round-Robin Queue) that is derived from "Queue" class. The matching OTcl name is "Queue/DTRR". When the "recv" member function that is implemented in the "Queue" class (in "queue.cc") receives a packet, it invokes the "enqueue" member function of the queue object and invokes "dequeue" if the link object is not blocked. When the link came from a blocked state, it also calls the "dequeue" member function of its queue object. Therefore, we needed to write "enqueue" and "dequeue" member functions of the "DtRrQueue" object class. Figure 30 shows the "DtRrQueue" class definition and its "enqueue" and "dequeue" member functions. For the complete implementation, refer to "dtrr-queue.h" and "dtrr-queue.cc" files. Since the codes are really easy to understand, no further explanation is given.



    Figure 30. "DtRrQueue" class implementation





  • Test Simulation
  • We used the simulation script used for testing "MmApp" over "UDPmm" in the previous section with changing the RED queue to DTRR queue for the link r1-r2. The changes to the script are show in Figure 31. Download this script and test your newly added queue components.

    ex-dtrr-queue.tcl

    Figure 31. "DtRrQueue" test simulation script

    Web Server and Clients in NS2

    Web Server Example




    This section contains a pointer to an example Web Server simulation script and shows its network topology. Download "ex-web.tcl" and "dumbbell.tcl" files and examine them yourself. This example is from the 5th VINT/NS Simulator Tutorial/Workshop. Note that you should change the path for "http-mod.tcl" at the begining of the script to an appropriate one to make it run on your machine.



    Figure 34. Web server simulation network topology

    Add New Agents in NS2

    Add New Application and Agent


  • Objective
  • We want to build a multimedia application that runs over a UDP connection, which simulates the behavior of an imaginary multimedia application that implements "five rate media scaling" that can respond to network congestion to some extent by changing encoding and transmission policy pairs associated with scale parameter values.

  • Application Description
  • In this implementation, it is assumed that when a connection is established, the sender and the receiver agree on 5 different sets of encoding and transmission policy pairs, and associate them with 5 scale values (0-4). For simplicity reasons, it is also assumed that a constant transmission rate is determined for each of the encoding and transmission policy pairs, and every pair uses packets of the same size regardless of the encoding scheme.
    Basically, "five rate media scaling" works as follow. The sender starts with transmission rate associated with scale 0, and changes transmission rates according to the scale value that the receiver notifies. The receiver is responsible for monitoring network congestion and determining the scale factor. For congestion monitoring, a simple periodical (for every RTT second) packet loss monitoring is used, and even a single packet loss for each period is regarded as network congestion. If congestion is detected, the receiver reduces the scale parameter value to half and notifies the sender of this value. If no packet loss is detected, the receiver increases the value by one and notifies the sender.

  • Problem Analysis
  • Before implementing this application, the UDP agent implementation is examined and one major problem is found. Since a UDP agent allocates and sends network packets, all the information needed for application level communication should be handed to the UDP agent as a data stream. However, the UDP implementation allocates packets that only have a header stack. Therefore, we need to modify the UDP implementation to add a mechanism to send the data received from the application. It is also noted that we might want to use this application for further research on IP router queue management mechanisms. Therefore, we need a way to distinguish this type of multimedia stream from other types of streams. That is, we also need to modify UDP agent to record data type in one of IP header fields that is currently not used.

  • Note on NS Versions
  • The locations of C++ source files in NS version 2.1b9a are slightly changed from 2.1b8a. In ns-2.1b9a, C++ source files are categorized and placed in sub-directories under the main ns-2 directory. For example, "packet.h" to "common/packet.h", "agent.h" to "common/agent.h" and "app.h" is moved to "apps/app.h". However, the locations of OTcl files are same as before ("tcl/lib/ns-packet.tcl", "tcl/lib/ns-default.tcl" and etc.)
  • Design and Implementation
  • For the application, we decided to take the CBR implementation and modify it to have the "five level media scaling" feature. We examined the C++ class hierarchy, and decided to name the class of this application as "MmApp" and implement as a child class of "Application". The matching OTcl hierarchy name is "Application/MmApp". The sender and receiver behavior of the application is implemented together in "MmApp". For the modified UDP agent that supports "MmApp", we decided to name it "UdpMmAgent" and implement it as a child class of "UdpAgent". The matching OTcl hierarchy name is "Agent/UDP/UDPmm"
    • MmApp Header: For the application level communication, we decided to define a header of which the structure named in C++ "hdr_mm". Whenever the application has information to transmit, it will hand it to "UdpMmAgent" in the "hdr_mm" structure format. Then, "UdpMmAgent" allocates one or more packets (depending on the simulated data packet size) and writes the data to the multimedia header of each packet. Figure 23 shows the header definition, in which a structure for the header and a header class object, "MultimediaHeaderClass" that should be derived from "PacketHeaderCalss" is defined. In defining this class, the OTcl name for the header ("PacketHeader/Multimedia") and the size of the header structure defined are presented. Notice that bind_offset() must be called in the constructor of this class.

      Figure 23. MM Header Structure & Class (in "udp-mm.h" & "udp-mm.cc")


      Figure 24 (a). Add to the "packet.h" file (C++)

      Figure 24 (b). Add to the "ns-packet.tcl" file (Otcl)
      We also add lines to packet.h and ns-packet.tcl as shown in Figure 24 (a) and (b) to add our "Mulltimedia" header to the header stack. At this point, the header creation process is finished, and "UdpMmAgent" will access the new header via hdr_mm::access() member function. Please refer to NS Manual for detailed information on header creation and access methods. For the rest of the application and the modified UDP agent description, refer directly to "mm-app.h", "mm-app.cc", "udp-mm.h" and "udp-mm.cc" files as needed.
       
    • MmApp Sender: The sender uses a timer for scheduling the next application data packet transmission. We defined the "SendTimer" class derived from the "TimerHandler" class, and wrote its "expire()" member function to call "send_mm_pkt()" member function of the "MmApp" object. Then, we included an instance of this object as a private member of "MmApp" object referred to as "snd_timer_". Figure 25 shows the "SendTimer" implementation.

      Figure 25. SendTimer Implementation.
      Before setting this timer, "MmApp" re-calculates the next transmission time using the transmission rate associated with the current scale value and the size of application data packet that is given in the input simulation script (or use the default size). The "MmApp" sender, when an ACK application packet arrives from the receiver side, updates the scale parameter.
       
    • MmApp Receiver: The receiver uses a timer, named "ack_timer_", to schedule the next application ACK packet transmission of which the interval is equal to the mean RTT. When receiving an application data packet from the sender, the receiver counts the number of received packets and also counts the number of lost packets using the packet sequence number. When the "ack_timer_" expires, it invokes the "send_ack_pkt" member function of "MmApp", which adjusts the scale value looking at the received and lost packet accounting information, resets the received and lost count to 0, and sends an ACK packet with the adjusted scale value. Note that the receiver doesn't have any connection establishment or closing methods. Therefore, starting from the first packet arrival, the receiver periodically sends ACK packets and never stops (this is a bug).
       
    • UdpMmAgent: The "UdpMmAgent" is modified from the "UdpAgent" to have the following additional features: (1) writing to the sending data packet MM header the information received from a "MmApp" (or reading information from the received data packet MM header and handing it to the "MmApp"), (2) segmentation and re-assembly ("UdpAgent" only implements segmentation), and (3) setting the priority bit (IPv6) to 15 (max priority) for the "MmApp" packets.
       
    • Modify "agent.h": To make the new application and agent running with your NS distribution, you should add two methods to "Agent" class as public. In the "command" member function of the "MmApp" class, there defined an "attach-agent" OTcl command. When this command is received from OTcl, "MmApp" tries to attach itself to the underlying agent. Before the attachment, it invokes the "supportMM()" member function of the underlying agent to check if the underlying agent support for multimedia transmission (i.e. can it carry data from application to application), and invokes "enableMM()" if it does. Even though these two member functions are defined in the "UdpMmAgnet" class, it is not defined in its base ancestor "Agent" class, and the two member functions of the general "Agent" class are called. Therefore, when trying to compile the code, it will give an error message. Inserting the two methods as public member functions of the "Agent" class (in "agent.h") as follows will solve this problem.

      Figure 26 (a). Add two member functions to "Agent" class.
    • Modify "app.h": You also need to add an additional member function "recv_msg(int nbytes, const char *msg)" to "Application" class as shown in Figure 26 (b). This member function, which was included in the "Application" class in the old versions of NS (ns-2.1b4a for sure), is removed from the class in the latest versions (ns-2.1b8a for sure). Our multimedia application was initially written for the ns-2.1.b4a, and therefore requires "Application::recv_msg()" member function for ns-2.1b8a or later versions.

      Figure 26 (b). Add a member function to "Application" class.
    • Set default values for new parameter in the "ns-default.tcl": After implementing all the parts of the application and agent, the last thing to do is to set default values for the newly introduced configurable parameters in the "ns-default.tcl" file. Figure 26 shows an example of setting the default values for configurable parameters introduced by "MmApp".

      Figure 27. Default parameter value settings

  • Download and Compile
  • Here is a checklist that should be done before recompiling your NS.
    1. Download "mm-app.h", "mm-app.cc", "udp-mm.h" and "udp-mm.cc") to the "ns-2" directory.
    2. Make sure you registered the new application header by modifying "packet.h" and "ns-packet.tcl" as shown in Figure 24 (a) and (b).
    3. Add supportMM() and enableMM() methods to the "Agent" class in "agent.h" as shown in Figure 26 (a).
    4. Add recv_msg() method to the "Application" class in "app.h" as shown in Figure 26 (b).
    5. Set default values for the newly introduced configurable parameters in "ns-default.tcl" as described in Figure 27. Be SURE to complete this last step. Otherwise, all five-scale rates are initialized to zero unless specified in the input simulation script (i.e., the test simulation script given below will not transmit any frames).
    Be SURE to complete the last (5th) step. Otherwise, all five-scale rates are initialized to zero unless specifically given in the input simulation script (i.e., the test simulation script given below will not transmit any frames).

    After you've done all things in the checklist, modify your "Makefile" as needed (include "mm-app.o" and "udp-mm.o" in the object file list) and re-compile your NS. Be SURE to run "make clean" and "make depend" before you re-compile your modified NS, otherwise the new application may not transmit any packets. It is generally a good practice to do "make depend" after you make changes in "Makefile" before a re-compile.

  • Test Simulation
  • Figure 28 shows a simulation topology and scenario that is used to test "MmApp", and Figure 29 shows the test simulation script. Download this script and test the newly added components.

    Figure 28. Test Simulation Topology and Scenario

    ex-mm-app.tcl

    Figure 29. "MmApp" Test Simulation Script