/**
* File Name : BaseStation.java
*
* The University of Texas at Arlington
* Software Engineering Center for Telecommunications
* Object Oriented Testing Project
*
* (c) Copyright 2000 University of Texas at Arlington
* ALL RIGHTS RESERVED
*
* Input : Different channels used in a wireless system are simulated using different ports
* 20101 - Reverse control channel for sending controls to the Base Station
* 20001 - Forward control channel for receiving controls from the Base Station
* 20111 - Reverse data channel for sending data to Base Station
* 20011 - Forward data channel for receiving data from Base Station
* The Handset sends controls to Base Station in the following format: PhoneNum MesgType
* The MesgType has the following values
* 4 for registration
* 10 for callinitiation
* 0 for acknowledgement
* 12 for ringback
* 16 for connect
* Output : The BaseStation connects to the Mobile Switching Center on the following ports
* 7777 - for sending controls to MSC
* 6666 - for receiving controls from MSC
* 8888 - for sending data to MSC
* 9999 - for receiving data to MSC
* Supported Requirements : This code handles call requests from
* (1) A handset to another handset in the same Base Station
* (2) A handset to another handset in a different Base Station
* (3) Many handsets in the same Base Station
* (4) Many handsets in different Base Stations
*
* Classes in this file : BaseStation, BaseStationController, BaseStationControllerData,
* BaseStationData, BaseStationForwardCrtl,BaseStationForwardData,
* BaseStationTranceiverControl, ConnectionHandler, DataHandler,
* HandsetSocket, Status, Storage
*
* Update History:
*
* Date Author Changes
* ------------------------------------------------------------------------------
* 04/27/00 Susheela Smitha Kommaraju Initial code which handles
* call requests in the same Base Station
*
* 05/01/00 Susheela Smitha Kommaraju Initiating connections between Handsets
* in different Base Stations
*
* 05/04/00 Susheela Smitha Kommaraju Transfering data between different
* Handsets in different Base Stations
* and Satish Jonnalgedda
*
* Functional Description : This code handles call requests from any number of handsets.
* Connection between handsets is established and handsets can
* exchange messages
* Error Messages : Null pointer exceptions result when the assumptions are not met.
* Otherwise there are no error messages
* Constraints : This code works under normal conditions i.e., when the handsets
* are connected to both the Control channels.
*
* Assumptions : It is assumed that the Handset is never busy and is always ready to receive messages.
*
*
**/
import java.io.*;
import java.net.*;
import java.util.*;
public class BaseStation
{
public static void main(String args[])
{
try
{
ServerSocket rc = new ServerSocket(20101); // receives controls from Handset
ServerSocket fc = new ServerSocket(20001); // writes controls to Handset
ServerSocket rd = new ServerSocket(20111); // receives data from Handset
ServerSocket fd = new ServerSocket(20011); // writes data to Handset
Storage stm = new Storage(); // Storage is a class which stores phone numbers
// and IP address using hash tables
Status sta = new Status(); // Status is a class which stores phone numbers
// and if they are connected to a Handset
// in the same basestation or different base station
HandsetSocket hs = new HandsetSocket(); // stores the sockets at which the Handsets are listerns for controls
HandsetSocket datas = new HandsetSocket(); // stores the sockets at which the Base Station
// can send data to Handset
HandsetSocket datar = new HandsetSocket(); // stores the sockets at which the Handsets send data
new BaseStationController(hs,stm, sta).start(); // class BSC does forwarding and
// receiving of messages and data to and from MSC
new BaseStationControllerData(datas, datar,stm, sta).start();
new BaseStationTransceiverControl(hs,rc,stm, sta).start(); // class BTSC does connecting of handsets
new BaseStationForwardCrtl(hs,fc).start();
new BaseStationForwardData(datas,fd).start();
new BaseStationData(datas,datar,rd,stm, sta).start();// class BTSD handles conversation between handsets
}
catch(Exception e)
{ System.out.println(e); }
}
}
// This class accepts connections from handset sockets where control messages are sent from Base Station
class BaseStationForwardCrtl extends Thread
{ private ServerSocket fControl;
private int num = 1;
public HandsetSocket haso = new HandsetSocket();
public BaseStationForwardCrtl (HandsetSocket hs,ServerSocket fc)
{
haso = hs;
fControl = fc;
}
public void run()
{
try
{
for(;;)
{ Socket forwardControl = fControl.accept();
InetAddress iAddr = forwardControl.getInetAddress();
haso.takeSocket(iAddr, forwardControl);
System.out.println("No. of Handsets accessing Forward Control Channels " + num);
num++;
}
}
catch(Exception e)
{ System.out.println(e);
}
}
}
// This class accepts connections from handset sockets where data are sent to Handset
class BaseStationForwardData extends Thread
{ private ServerSocket fData;
private int num = 1;
public HandsetSocket daso = new HandsetSocket();
public BaseStationForwardData(HandsetSocket ds, ServerSocket fd)
{
fData = fd;
daso = ds;
}
public void run()
{
try
{
for(;;)
{
Socket forwardData = fData.accept();
InetAddress iAddr = forwardData.getInetAddress();
daso.takeSocket(iAddr, forwardData);
System.out.println("No. of Handsets accessing Forward Data Channels " + num);
num++;
}
}
catch(IOException e)
{ System.out.println(e);
}
}
}
// This class accepts connections from handset sockets where control messages are received from Handset
class BaseStationTransceiverControl extends Thread
{ private ServerSocket sControl;
private int num = 1;
public Storage x;
public Status y;
public HandsetSocket hs;
public BaseStationTransceiverControl(HandsetSocket haso,ServerSocket rc,Storage stm, Status sta)
{
hs = haso;
sControl = rc;
x = stm;
y = sta;
}
public void run()
{
try
{
for(;;)
{ Socket revControl = sControl.accept();
new ConnectionHandler(revControl, x, y, hs).start();
System.out.println("No. of Handsets accessing Reverse Control Channels " + num);
num++;
}
}
catch(Exception e)
{ System.out.println(e);
}
}
}
// This class accepts connections from handset sockets where data are received from Handset
class BaseStationData extends Thread
{ private ServerSocket rData;
private int num = 1;
public Storage x;
public Status y;
public HandsetSocket hs;
public HandsetSocket hr;
public BaseStationData(HandsetSocket datas,HandsetSocket datar,ServerSocket rd,Storage stm, Status sta)
{
hs = datas;
hr = datar;
rData = rd;
x = stm;
y = sta;
}
public void run()
{
try
{
for(;;)
{ Socket revData = rData.accept();
InetAddress iAddr = revData.getInetAddress();
hr.takeSocket(iAddr,revData);
new DataHandler(revData, x, y, hs, hr).start();
System.out.println("No. of Handsets accessing Reverse Data Channels " + num);
num++;
}
}
catch(Exception e)
{ System.out.println(e);
}
}
}
// This class handles connections between handsets
class ConnectionHandler extends Thread
{ private Socket incoming;
private Storage storageobj;
private Status statusobj;
public HandsetSocket hs;
public ConnectionHandler(Socket i, Storage x, Status y, HandsetSocket h)
{ incoming = i;
storageobj = x;
statusobj = y;
hs = h;
}
public void run()
{
try
{ BufferedReader in = new BufferedReader
(new InputStreamReader(incoming.getInputStream()));
for(;;)
{
String str = in.readLine();
System.out.println("BS receives " + str + " from Handset");
StringTokenizer t = new StringTokenizer(str," ");
String sourcePhoneNum = t.nextToken();
String mesgType = t.nextToken();
if (mesgType.equals("4"))
{
InetAddress iAddr = incoming.getInetAddress();
storageobj.takeAddress(sourcePhoneNum,iAddr);
// BaseStationController.sendToMSC(str);
}
else if (mesgType.equals("10"))
{
BaseStationController.sendToMSC(str);
storageobj.sendToHandset(hs, sourcePhoneNum, sourcePhoneNum + " 0");
}
else if (mesgType.equals("0"))
{ if ((statusobj.getBSType(sourcePhoneNum)).equals("Same"))
{
System.out.println("HS is in the same BS");
String otherHS = statusobj.getOtherHandset(sourcePhoneNum);
String mesg = otherHS + " 12";
storageobj.sendToHandset(hs, otherHS, mesg);
}
else
{
statusobj.bsType.put(sourcePhoneNum, "Different");
BaseStationController.sendToMSC(str);
}
}
else if (mesgType.equals("16"))
{
String bsType = statusobj.getBSType(sourcePhoneNum);
if (bsType.equals("Same"))
{
String destHandset = statusobj.getOtherHandset(sourcePhoneNum);
String connectMesg = destHandset + " 16";
storageobj.sendToHandset(hs,destHandset, connectMesg);
}
else
{
BaseStationController.sendToMSC(str);
}
}
}
}
catch(Exception e)
{ System.out.println(e);
}
}
}
// This class handles data transfer between handsets
class DataHandler extends Thread
{
HandsetSocket hSend;
HandsetSocket hRec;
private Socket incoming;
private Storage storageobj;
private Status statusobj;
public DataHandler(Socket i, Storage x, Status y, HandsetSocket hs, HandsetSocket hr)
{
incoming = i;
storageobj = x;
statusobj = y;
hSend = hs;
hRec = hr;
}
public void run()
{
try
{
BufferedReader in = new BufferedReader
(new InputStreamReader(incoming.getInputStream()));
for(;;)
{
String str = in.readLine();
InetAddress iAddr = incoming.getInetAddress();
System.out.println("BS receives " + str + " from Handset");
String scrNum = (String)(storageobj.inetToPhone.get(iAddr));
String bstype = statusobj.getBSType(scrNum);
if (bstype.equals("Same"))
{
String destNum = statusobj.getOtherHandset(scrNum);
storageobj.sendToHandset(hSend, destNum, str);
if (str.equals("."))
{
statusobj.updateTablesSame(scrNum,hSend,hRec,storageobj);
}
}
else if (bstype.equals("Different"))
{
String msend = scrNum + " " + str;
BaseStationController.sendDataToMSC(msend);
if (str.equals("."))
{
statusobj.updateTablesDifferent(scrNum,hSend,hRec,storageobj); }
}
}
}
catch(Exception e)
{ System.out.println("Call terminated");
}
}
}
// This class the sockets at which the handsets are connected so that the Base Station
// knows which handset to send the message to
class HandsetSocket
{
Hashtable hsock = new Hashtable();
public synchronized void takeSocket(InetAddress i, Socket s)
{
//System.out.println("Before Adding" + hsock.size());
hsock.put(i,s);
//System.out.println("After Adding" + hsock.size());
}
public synchronized Socket giveSocket(InetAddress i)
{
return ((Socket)(hsock.get(i)));
}
public synchronized void updateTable(InetAddress i1)
{
try
{
(giveSocket(i1)).close();
hsock.remove(i1);
// System.out.println("Removed an entry ");
}
catch(Exception e)
{ System.out.println(e);
}
}
}
// This class stores the information regarding the handset and sends the data as required
class Storage
{
Hashtable inetToPhone = new Hashtable();
Hashtable allAddr = new Hashtable();
public Storage()
{ }
public synchronized void takeAddress(String s, InetAddress i)
{
// System.out.println("Size of the hash table 1 before adding " + allAddr.size());
allAddr.put(s, i);
inetToPhone.put(i,s);
// System.out.println("For the key " + s+" the element in the hash table 1 is "+((InetAddress)(allAddr.get(s))));
// System.out.println("Size of the hash table after adding " + allAddr.size());
}
public synchronized void broadcast(String s, HandsetSocket h)
{
Enumeration en = allAddr.elements();
while (en.hasMoreElements())
{
try
{
InetAddress i = (InetAddress)(en.nextElement());
Socket x = h.giveSocket(i);
PrintWriter outPage = new PrintWriter(x.getOutputStream(),true);
outPage.println(s);
}
catch(Exception e)
{
System.out.println(e);
}
}
System.out.println("Message " + s + " has been broadcast to all the handsets connected to BS");
notifyAll();
}
public synchronized void sendToHandset(HandsetSocket h, String s, String m)
{
try
{
InetAddress i = (InetAddress)(allAddr.get(s));
Socket x = h.giveSocket(i);
PrintWriter outMesg = new PrintWriter(x.getOutputStream(),true);
outMesg.println(m);
System.out.println("BS sends message " + m + " to Handset");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
// This class keeps track of which handsets are connected to which handsets
class Status
{
Hashtable bsType = new Hashtable();
Hashtable connectedTo = new Hashtable();
public Status()
{ }
public synchronized void addbsTypeSame(String h1, String h2, String b)
{
// System.out.println("size of hashtable bsType of status before adding " + bsType.size());
// System.out.println("size of hashtable connectedTo of status before adding " + connectedTo.size());
bsType.put(h1, b);
bsType.put(h2, b);
connectedTo.put(h1,h2);
connectedTo.put(h2,h1);
// System.out.println("size of hashtable bsType of status after adding " + bsType.size());
// System.out.println("size of hashtable connectedTo of status after adding " + connectedTo.size());
}
public synchronized void addbsTypeDifferent(String h1, String b)
{
// System.out.println("size of hashtable bsType of status before adding " + bsType.size());
bsType.put(h1, b);
// System.out.println("size of hashtable bsType of status after adding " + bsType.size());
}
public synchronized String getOtherHandset(String s)
{
return ((String)(connectedTo.get(s)));
}
public synchronized String getBSType(String s)
{
return ((String)(bsType.get(s)));
}
public synchronized void updateTablesSame(String s,HandsetSocket hs, HandsetSocket hr,Storage g)
{
String connectedHS = getOtherHandset(s);
bsType.remove(s);
bsType.remove(connectedHS);
connectedTo.remove(s);
connectedTo.remove(connectedHS);
InetAddress i1 = (InetAddress)(g.allAddr.get(s));
InetAddress i2 =(InetAddress)(g.allAddr.get(connectedHS));
hs.updateTable(i1);
hs.updateTable(i2);
hr.updateTable(i1);
hr.updateTable(i2);
}
public synchronized void updateTablesDifferent(String s,HandsetSocket hs, HandsetSocket hr,Storage g)
{
bsType.remove(s);
InetAddress i1 = (InetAddress)(g.allAddr.get(s));
hs.updateTable(i1);
hr.updateTable(i1);
}
}
// This class handles sending of control messages and data messages to MSC
class BaseStationController extends Thread
{
Storage sgobj;
Status stobj;
Socket outgoing;
static PrintWriter out;
static PrintWriter out2;
BufferedReader in;
Socket incoming;
Socket dout;
HandsetSocket hs;
public BaseStationController(HandsetSocket h, Storage x, Status y)
{ try
{
outgoing = new Socket("129.107.56.23",7777); // for writing controls to MSC
out = new PrintWriter(outgoing.getOutputStream(), true);
incoming = new Socket("129.107.56.23",6666); // for reading controls from MSC
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
dout = new Socket("129.107.56.23",8888); // for writing data to MSC
out2 = new PrintWriter(dout.getOutputStream(), true);
sgobj = x;
stobj = y;
hs = h;
}
catch(Exception e)
{ System.out.println(e);
}
}
public static void sendToMSC(String str)
{
String id = "1 ";
try
{
String bsStr = id + str;
out.println(bsStr);
System.out.println("BSC writes " + bsStr + " to MSC");
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void sendDataToMSC(String s)
{
String id = "1 ";
try
{
String bsStr = id + s;
out2.println(bsStr);
System.out.println("BSC writes " + bsStr + " to MSC");
}
catch(Exception e) { System.out.println(e); }
}
public void run()
{ try
{
for(;;)
{
String strMSC = in.readLine();
System.out.println("BSC reads " + strMSC + " from MSC");
StringTokenizer st = new StringTokenizer(strMSC, " ");
if (st.countTokens() == 2)
{
String phoneNum = st.nextToken();
String mesgType = st.nextToken();
if (mesgType.equals("5"))
{
sgobj.broadcast(strMSC,hs);
stobj.bsType.put(phoneNum,"Different");
}
else if (mesgType.equals("0"))
{
String cMesg = phoneNum + " 12";
sgobj.sendToHandset(hs,phoneNum,cMesg);
}
else if (mesgType.equals("16"))
{
sgobj.sendToHandset(hs, phoneNum, strMSC);
}
}
else if (st.countTokens() == 4)
{
System.out.println("Entered the approved message ");
String approval = st.nextToken();
String bstype = st.nextToken();
String sourceNum = st.nextToken();
String destNum = st.nextToken();
if (bstype.equals("Same"))
{
String bMesg = destNum + " 5";
sgobj.broadcast(bMesg,hs);
stobj.addbsTypeSame(sourceNum, destNum, bstype);
}
else if (bstype.equals("Different"))
{
stobj.addbsTypeDifferent(sourceNum, bstype);
}
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
// This class receives data from MSC
class BaseStationControllerData extends Thread
{
Socket din;
BufferedReader in2;
HandsetSocket hSend;
HandsetSocket hRec;
Storage stmobj;
Status staobj;
public BaseStationControllerData(HandsetSocket hs, HandsetSocket hr, Storage stm, Status sta)
{ try
{
din = new Socket("129.107.56.23",9999); // for reading data from MSC
in2 = new BufferedReader(new InputStreamReader(din.getInputStream()));
hSend = hs;
hRec = hr;
stmobj = stm;
staobj = sta;
}
catch(Exception e)
{ System.out.println(e);
}
}
public void run()
{
for(;;)
{
try
{
String data = in2.readLine();
System.out.println("BSC reads " + data + " from MSC");
int x = data.indexOf(" ");
String destNum = data.substring(0,x);
String s2 = data.substring(x+1);
int y = s2.indexOf(";");
String s3 = s2.substring(0,y);
String mesg = s3.trim();
stmobj.sendToHandset(hSend, destNum, mesg);
if (mesg.equals("."))
staobj.updateTablesDifferent(destNum,hSend,hRec,stmobj);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
}
               (
geocities.com/vienna/7079/src)                   (
geocities.com/vienna/7079)                   (
geocities.com/vienna)