Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes

pbx.PBXClient Class Reference

Encapsulates rudimentary functionality of a PBX to list and invite users (peers) to secure calls. More...

Collaboration diagram for pbx.PBXClient:
Collaboration graph
[legend]

List of all members.

Classes

interface  Context
 Provides a call-back context for the instance of PBXClient. More...
class  ControlMessage
 PBX signaling message sent via call-back to the upper layer. More...

Public Types

enum  CMType {
  _INVALID_, INVITE, RING, ACCEPT,
  BYE, INSTANTMESSAGE, LIST, ALIVE
}
 

PBX Signaling Messages' Types.

More...

Public Member Functions

 PBXClient (String host, int port, Context context)
 Creates new instance of PBXClient that posts messages to specified Context.
String getLocalAddress ()
 Returns local IP address.
void start ()
 Starts the thread.
void send (String message)
 Sends message (appended with new-line) to chat server.
void send (String message, String userId)
 Sends message (appended with new-line) to chat server prefixed with userId.
void close ()
 Closes the connection gracefully.
void sendInvite (String remoteUserId, String localIpAddress, int localUdpPort, String publicKey)
 Broadcasts INVITE message.
void sendRing (String remoteUserId, String localIpAddress, int localUdpPort, String publicKey)
 Broadcasts RING message.
void sendAccept (String remoteUserId, String localIpAddress, int localUdpPort, String publicKey)
 Broadcasts ACCEPT message.
void sendBye (String remoteUserId, String localIpAddress, int localUdpPort)
 Broadcasts BYE message.
void sendInstantMessage (String remoteUserId, String encryptedMessage)
 Broadcasts IMSG message.
void sendListPeers (String regex)
 Broadcasts LIST message (to list potential peers)
void run ()
 Connects socket, then reads messages from server while running flag is enabled.

Private Member Functions

void report (String style, String str)
 Reports a system message to log.
void reportIncomingTextMessage (String userId, String message)
 Reports incoming message.
void parseInputMessage (String message)
 Parses input message.
void parseControlMessage (String remoteUserId, String[] args, String original)
 Parses control messages.

Private Attributes

String host = null
 Host name or IP address of the remote chat server.
int port = -1
 TCP port where to connect to on remote chat server.
String myID
 Chat client ID when presented to user (== host + ":" + port)
PrintWriter out = null
 Output stream to remote server.
Socket socket = null
 Instance of the TCP socket to chat server.
volatile boolean running = false
 Indicates/enables the thread to be running.
Context context = null
 Event (call-back) context for this instance of the PBXClient.

Static Private Attributes

static final String WARN = "logWarn"
 HTML CSS class for warning and error messages.
static final String INFO = "logInfo"
 HTML CSS class for info messages.

Detailed Description

Encapsulates rudimentary functionality of a PBX to list and invite users (peers) to secure calls.

The instances of PBXClient class expect to be connected to plain public chat server that distributes (broadcasts their messages (terminated by the new-line) to all other connected users (possible kryptofon peers).

Communication with the upper layer (which owns instance of the PBXClient) is done using call-backs over the PBXClient.Context interface.

Author:
Mikica B Kocic

Definition at line 31 of file PBXClient.java.


Member Enumeration Documentation

PBX Signaling Messages' Types.

Enumerator:
_INVALID_ 

Invalid CMType.

INVITE 

The message sent to remote peer to start the call.

RING 

The message sent back from remote peer informing about remote alerting status.

ACCEPT 

The message sent back from the remote peer indicating accepted call.

BYE 

Indicates call clear down -- either normal or abrupt (like call reject).

INSTANTMESSAGE 

Instant message exchanged between users with encrypted messages.

LIST 

Query all peers.

ALIVE 

Respond to Query all pears.

Definition at line 36 of file PBXClient.java.

    {
        /** Invalid CMType */
        _INVALID_,

        /** The message sent to remote peer to start the call */
        INVITE, 
        
        /** The message sent back from remote peer informing about remote alerting status */
        RING, 
        
        /** The message sent back from the remote peer indicating accepted call */
        ACCEPT,
        
        /** Indicates call clear down -- either normal or abrupt (like call reject). */
        BYE, 
        
        /** Instant message exchanged between users with encrypted messages */
        INSTANTMESSAGE,
        
        /** Query all peers */
        LIST,
        
        /** Respond to Query all pears */
        ALIVE
    }

Constructor & Destructor Documentation

pbx.PBXClient.PBXClient ( String  host,
int  port,
Context  context 
)

Creates new instance of PBXClient that posts messages to specified Context.

Parameters:
hosthost name or IP address of the chat server
portTCP port
contextwhere to log messages (also error and info messages)

Definition at line 206 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.host, pbx.PBXClient.myID, and pbx.PBXClient.port.

    {
        super( "Chat-" + host + ":" + port );

        this.host        = host;
        this.port        = port;
        this.context     = context;
        
        this.myID = host + ":" + port; 
    }

Member Function Documentation

void pbx.PBXClient.close (  )

Closes the connection gracefully.

Definition at line 277 of file PBXClient.java.

References pbx.PBXClient.running, and pbx.PBXClient.socket.

Referenced by CryptoPhoneApp.executeCommand(), and CryptoPhoneApp.formWindowClosing().

    {
        synchronized( this )
        {
            running = false;

            if ( socket != null && ! socket.isClosed () ) {
                try {
                    socket.close ();
                } catch( IOException e ) {
                    /* ignore */
                }
            }
        }
    }
String pbx.PBXClient.getLocalAddress (  )

Returns local IP address.

Definition at line 220 of file PBXClient.java.

References pbx.PBXClient.socket.

Referenced by CryptoPhoneApp.acceptIncomingCall(), CryptoPhoneApp.deferredOnInvite(), and CryptoPhoneApp.executeCommand().

    {
        return socket.getLocalAddress ().getHostAddress ();
    }
void pbx.PBXClient.parseControlMessage ( String  remoteUserId,
String[]  args,
String  original 
) [private]

Parses control messages.

TODO Format messages in XML instead. (It would be too much to do for IP1 course.)

Syntax:

     [$] INVITE    local-name   remote-ip-address   remote-udp-port  [ public-key ]   
     [$] RING      local-name   remote-ip-address   remote-udp-port  [ public-key ]
     [$] ACCEPT    local-name   remote-ip-address   remote-udp-port  [ secret-key ]
     [$] BYE       local-name [ remote-ip-address [ remote-udp-port ] ]
     [$] IMSG      local-name   encrypted-message
     [$] LIST    [ username-regex ]
     [$] ALIVE
  

Definition at line 377 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), pbx.PBXClient.host, pbx.PBXClient.INFO, pbx.PBXClient.Context.onAccept(), pbx.PBXClient.Context.onBye(), pbx.PBXClient.Context.onInstantMessage(), pbx.PBXClient.Context.onInvite(), pbx.PBXClient.Context.onRing(), pbx.PBXClient.port, pbx.PBXClient.report(), and pbx.PBXClient.send().

Referenced by pbx.PBXClient.parseInputMessage().

    {
        assert args.length >= 1 && args[0].equals( "[$]" );

        /* Parse args[1] as CMType 
         */
        CMType cmType = CMType._INVALID_;
        
        if ( args[1].equalsIgnoreCase( "invite" ) ) {
            cmType = CMType.INVITE;
        } else if ( args[1].equalsIgnoreCase( "ring" ) ) {
            cmType = CMType.RING;
        } else if ( args[1].equalsIgnoreCase( "accept" ) ) {
            cmType = CMType.ACCEPT;
        } else if ( args[1].equalsIgnoreCase( "bye" ) ) {
            cmType = CMType.BYE;
        } else if ( args[1].equalsIgnoreCase( "imsg" ) ) {
            cmType = CMType.INSTANTMESSAGE;
        } else if ( args[1].equalsIgnoreCase( "list" ) ) {
            cmType = CMType.LIST;
        } else if ( args[1].equalsIgnoreCase( "alive" ) ) {
            cmType = CMType.ALIVE;
        } else {
            return; // ignore unknown types
        }
        
        String destinationUserId = null;
        
        /* Parse destination user id, then ignore loop messages and 
         * messages that are not explicitly for us.
         */
        if ( cmType != CMType.LIST && cmType != CMType.ALIVE && args.length >= 3 ) 
        {
            destinationUserId = args[2];

            if ( remoteUserId.equalsIgnoreCase( destinationUserId ) ) {
                return;
            } else if ( ! destinationUserId.equalsIgnoreCase( context.getUserId () ) ) { 
                return;
            }
        }

        //////////////////////////////////////////////////////////////////////////////////
        /* [$]  INVITE  local-name remote-ip-address remote-udp-port [ public-key ]
         *  0     1         2           3              4                  5 opt.      
         */
        if ( args.length >= 5  && args[1].equalsIgnoreCase( "invite" ) )
        {
            String publicKey = args.length >= 6 ? args[5] : null;

            try
            {
                int port = Integer.parseInt( args[4] ); // remote port

                context.onInvite( new ControlMessage( CMType.INVITE,
                        remoteUserId, destinationUserId, args[3], port, publicKey ) );
            }
            catch( NumberFormatException e )
            {
                /* ignore message */
            }
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]  RING   local-name remote-ip-address remote-udp-port  [ public-key ]
         *  0     1         2           3              4                   5
         */
        else if ( args.length >= 5 && args[1].equalsIgnoreCase( "ring" ) ) 
        {
            String publicKey = args.length >= 6 ? args[5] : null;

            try
            {
                int port = Integer.parseInt( args[4] ); // remote port

                context.onRing( new ControlMessage( CMType.RING,
                        remoteUserId, destinationUserId, args[3], port, publicKey ) );
            }
            catch( NumberFormatException e )
            {
                /* ignore message if port is not integer */
            }
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]  ACCEPT  local-name remote-ip-address remote-udp-port [ secret-key ]
         *  0     1         2           3                  4               5        
         */
        else if ( args.length >= 5 && args[1].equalsIgnoreCase( "accept" ) ) 
        {
            String secretKey = args.length >= 6 ? args[5] : null;

            try
            {
                int port = Integer.parseInt( args[4] ); // remote port
                
                context.onAccept( new ControlMessage( CMType.ACCEPT, 
                        remoteUserId, destinationUserId, args[3], port, secretKey ) );
            }
            catch( NumberFormatException e )
            {
                /* ignore message if port is not integer */
            }
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]   BYE   local-name [ remote-ip-address [ remote-udp-port ] ]
         *  0     1         2            3                   4      
         */
        else if ( args.length >= 3 && args[1].equalsIgnoreCase( "bye" ) ) 
        {
            try
            {
                String host = args.length >= 4 ? args[3] : "";
                int port = args.length >= 5 ? Integer.parseInt( args[4] ) : 0;

                context.onBye( new ControlMessage( CMType.BYE,
                        remoteUserId, destinationUserId, host, port, null ) );
            }
            catch( NumberFormatException e )
            {
                /* ignore message if port is not integer */
            }
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]   IMSG   local-name  encrypted-message
         *  0     1         2              3      
         */
        else if ( args.length >= 4 && args[1].equalsIgnoreCase( "imsg" ) ) 
        {
            context.onInstantMessage( new ControlMessage( CMType.INSTANTMESSAGE,
                    remoteUserId, destinationUserId, "", 0, args[3] ) );
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]  LIST   [ username-regex ]
         *  0     1          2 opt.
         */
        else if ( args.length >= 2 && args[1].equalsIgnoreCase( "list" ) )
        {
            String myUserId = context.getUserId ();

            report( INFO, "Listing users..." );
            
            if ( ! myUserId.isEmpty () )
            {
                if ( args.length < 3 ) // query all users (without regex)
                { 
                    /* Respond back to query
                     */
                    send( "[$] ALIVE", myUserId );
                }
                else  // case-insensitive query with regex
                {
                    Pattern p = null;
                    try {
                        p = Pattern.compile( args[2], Pattern.CASE_INSENSITIVE );
                    } catch ( Throwable e ) {
                        /* ignored */
                    }
                    if ( p != null && p.matcher( myUserId ).find () )
                    {
                        /* Respond back to query
                         */
                        send( "[$] ALIVE", myUserId );
                    }
                }
            }
        }
        //////////////////////////////////////////////////////////////////////////////////
        /* [$]  ALIVE
         *  0     1   
         */
        else if ( args.length >= 2 
                && args[1].equalsIgnoreCase( "alive" ) )
        {
            report( INFO, "-- User '" + remoteUserId + "' is alive." );
            // TODO this might as well update some list of possible peers?
            // -- but that requires little more functionality on the PBX (chat) server
            // side.
        }
    }
void pbx.PBXClient.parseInputMessage ( String  message ) [private]

Parses input message.

Syntax:

      [ [ <userId> ] : ] <text-or-control>
  

where default userId is [Anonymous].

If the text-or-control begins with "[$]" it represents control message and it will not be displayed to the user.

Definition at line 321 of file PBXClient.java.

References pbx.PBXClient.parseControlMessage(), and pbx.PBXClient.reportIncomingTextMessage().

Referenced by pbx.PBXClient.run().

    {
        /* Parse input with syntax: [ [ <userId> ] ":: " ] <message>
         * where default userId is [Anonymous].
         */
        String[] parts = message.split( ":: ", 2 );
        String userId = "[Anonymous]";
        
        if ( message.startsWith( "WWHHOO: " ) ) {
            userId = "WWHHOO";
            message = message.substring( 8 );
        } else if ( parts.length == 0 ) {
            message = parts[0];
        } else if ( parts[0].trim().length () == 0 && parts.length >= 2 ) {
            message = parts[1];
        } else if ( parts.length >= 2 ) {
            userId  = parts[0].trim ();
            message = parts[1];
        } else {
            message = parts[0];
        }

        /* Now, check if we have a control message beginning with token [$]
         * but not comming from the anonymous user.
         */
        parts = message.trim().split( "\\s{1,}" );

        if ( ! userId.equals( "[Anonymous]" ) 
                && parts.length >= 1 
                && parts[0].equals( "[$]" ) )
        {
            parseControlMessage( userId, parts, message );
        }
        else
        {
            reportIncomingTextMessage( userId, message );
        }
    }
void pbx.PBXClient.report ( String  style,
String  str 
) [private]

Reports a system message to log.

Definition at line 296 of file PBXClient.java.

References pbx.PBXClient.context, and pbx.PBXClient.Context.report().

Referenced by pbx.PBXClient.parseControlMessage(), and pbx.PBXClient.run().

    {
        context.report( style, str );
    }
void pbx.PBXClient.reportIncomingTextMessage ( String  userId,
String  message 
) [private]

Reports incoming message.

Definition at line 304 of file PBXClient.java.

References pbx.PBXClient.context, and pbx.PBXClient.Context.reportIncomingTextMessage().

Referenced by pbx.PBXClient.parseInputMessage().

    {
        context.reportIncomingTextMessage( "chatMessage", userId, message );
    }
void pbx.PBXClient.run (  )

Connects socket, then reads messages from server while running flag is enabled.

Finally, closes connection in graceful manner.

Incoming messages are dispatched to the owner via the call-back context (see PBXClient.Context).

Definition at line 629 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.host, pbx.PBXClient.INFO, pbx.PBXClient.myID, pbx.PBXClient.out, pbx.PBXClient.parseInputMessage(), pbx.PBXClient.port, pbx.PBXClient.report(), pbx.PBXClient.running, pbx.PBXClient.Context.setPbxStatus(), pbx.PBXClient.socket, and pbx.PBXClient.WARN.

    {
        Log.trace( "Thread started" );

        //////////////////////////////////////////////////////////////////////////////////
        /* Open connection
         */
        report( INFO, "Connecting to " + myID + "..." );
        context.setPbxStatus( "Connecting to " + myID + "..." );

        try
        {
            synchronized( this ) {
                socket = new Socket( host, port );
            }
        }
        catch( UnknownHostException e )
        {
            report( WARN, "'Unknown host' exception while creating socket" );
            report( WARN, e.toString () );
            running = false;
        }
        catch( IOException e )
        {
            report( WARN, "I/O exception while connecting" );
            report( WARN, e.toString () );
            running = false;
        }

        //////////////////////////////////////////////////////////////////////////////////
        /* Get input stream. Consider input characters UTF-8 encoded.
         * TODO: It would be nice to have this as a parameter.
         */
        InputStreamReader reader = null;
        try
        {
            if ( socket != null ) {
                reader = new InputStreamReader( socket.getInputStream (), "utf-8" );
            }
        }
        catch( IOException e )
        {
            report( WARN, "I/O exception while getting input stream" );
            report( WARN, e.toString () );
            running = false;
            reader = null;
        }
        
        //////////////////////////////////////////////////////////////////////////////////
        /* Get output stream. Encode our character strings as UTF-8.
         */
        try 
        {
            if ( socket != null ) {
                out = new PrintWriter(
                        new OutputStreamWriter( socket.getOutputStream(), "utf-8" ),
                        /*autoflush*/ true );
            }
        }
        catch( IOException e )
        {
            report( WARN, "I/O exception while getting output stream" );
            report( WARN, e.toString () );
            running = false;
            out = null;
        }

        //////////////////////////////////////////////////////////////////////////////////
        /* Finally connected... (if running == true survived until here)
         */
        BufferedReader in = null;
        if ( running )
        {
            context.setPbxStatus( "Connected to " + myID );
            report( "logOk", "Connected to " + myID + ". Ready to communicate..." );
            
            in = new BufferedReader( reader );
        }
        
        //////////////////////////////////////////////////////////////////////////////////
        /* Read messages from the socket and dump them on log area
         */
        while( running )
        {
            try
            {
                parseInputMessage( in.readLine () );
            }
            catch( IOException e )
            {
                report( WARN, "Connection lost!" );
                report( WARN, e.toString () );
                running = false;
            }
        }

        report( INFO, "Closing connection " + myID + "..." );

        //////////////////////////////////////////////////////////////////////////////////
        /* Close connection gracefully
         */
        try
        {
            if ( out != null ) {
                out.close ();
            }
            if ( in != null ) {
                in.close ();
            }
            synchronized( this )
            {
                if ( socket != null && ! socket.isClosed () ) {
                    socket.close ();
                }
            }
        }
        catch( IOException e )
        {
            report( WARN, "I/O exception while closing connection" );
            report( WARN, e.toString () );
        }
        
        report( INFO, "... connection closed " + myID );
        Log.trace( "Thread completed" );
    }
void pbx.PBXClient.send ( String  message,
String  userId 
)

Sends message (appended with new-line) to chat server prefixed with userId.

Parameters:
messagemessage to be sent
userIduser identifier

Definition at line 263 of file PBXClient.java.

References pbx.PBXClient.send().

    {
        /* Discard spaces from the userId first
         */
        userId = userId.trim().replaceAll( "\\s{1,}", "-" ); 
        
        /* Send message with userId as a prefix
         */
        send( userId + " :: " + message );
    }
void pbx.PBXClient.send ( String  message )

Sends message (appended with new-line) to chat server.

Parameters:
messagemessage to be sent

Definition at line 244 of file PBXClient.java.

References pbx.PBXClient.out.

Referenced by CryptoPhoneApp.executeCommand(), pbx.PBXClient.parseControlMessage(), CryptoPhoneApp.parseInputMessage(), pbx.PBXClient.send(), pbx.PBXClient.sendAccept(), pbx.PBXClient.sendBye(), pbx.PBXClient.sendInstantMessage(), CryptoPhoneApp.sendInstantMessage(), pbx.PBXClient.sendInvite(), pbx.PBXClient.sendListPeers(), and pbx.PBXClient.sendRing().

    {
        synchronized( this )
        {
            if ( out == null || message == null ) {
                return;
            }
            
            out.println( message );
            out.flush ();
        }
    }
void pbx.PBXClient.sendAccept ( String  remoteUserId,
String  localIpAddress,
int  localUdpPort,
String  publicKey 
)

Broadcasts ACCEPT message.

Definition at line 583 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.acceptIncomingCall().

    {
        this.send( "[$] ACCEPT " + remoteUserId + " " 
                + localIpAddress + " "  + localUdpPort 
                + ( publicKey != null ? " " + publicKey : "" ),
                context.getUserId () );
    }
void pbx.PBXClient.sendBye ( String  remoteUserId,
String  localIpAddress,
int  localUdpPort 
)

Broadcasts BYE message.

Definition at line 595 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.deferredOnInvite(), and CryptoPhoneApp.executeCommand().

    {
        this.send( "[$] BYE " + remoteUserId + " " 
                + localIpAddress + " "  + localUdpPort, 
                context.getUserId () );
    }
void pbx.PBXClient.sendInstantMessage ( String  remoteUserId,
String  encryptedMessage 
)

Broadcasts IMSG message.

Definition at line 606 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.sendInstantMessage().

    {
        this.send( "[$] IMSG " + remoteUserId + " " + encryptedMessage, 
                context.getUserId () );
    }
void pbx.PBXClient.sendInvite ( String  remoteUserId,
String  localIpAddress,
int  localUdpPort,
String  publicKey 
)

Broadcasts INVITE message.

Definition at line 559 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.executeCommand().

    {
        this.send( "[$] INVITE " + remoteUserId + " " 
                + localIpAddress + " "  + localUdpPort 
                + ( publicKey != null ? " " + publicKey : "" ),
                context.getUserId () );
    }
void pbx.PBXClient.sendListPeers ( String  regex )

Broadcasts LIST message (to list potential peers)

Definition at line 615 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.executeCommand().

    {
        this.send( "[$] LIST" + ( regex != null ? " " + regex : "" ),
                context.getUserId () );
    }
void pbx.PBXClient.sendRing ( String  remoteUserId,
String  localIpAddress,
int  localUdpPort,
String  publicKey 
)

Broadcasts RING message.

Definition at line 571 of file PBXClient.java.

References pbx.PBXClient.context, pbx.PBXClient.Context.getUserId(), and pbx.PBXClient.send().

Referenced by CryptoPhoneApp.deferredOnInvite().

    {
        this.send( "[$] RING " + remoteUserId + " " 
                + localIpAddress + " "  + localUdpPort 
                + ( publicKey != null ? " " + publicKey : "" ),
                context.getUserId () );
    }
void pbx.PBXClient.start (  )

Starts the thread.

Definition at line 229 of file PBXClient.java.

References pbx.PBXClient.running.

Referenced by CryptoPhoneApp.CryptoPhoneApp(), CryptoPhoneApp.executeCommand(), and CryptoPhoneApp.mainTimerEvent().

    {
        if ( isAlive () || running ) {
            return;  // Allow only one thread per instance
        }

        running = true;
        super.start ();
    }

Member Data Documentation

Context pbx.PBXClient.context = null [private]
String pbx.PBXClient.host = null [private]

Host name or IP address of the remote chat server.

Definition at line 164 of file PBXClient.java.

Referenced by pbx.PBXClient.parseControlMessage(), pbx.PBXClient.PBXClient(), and pbx.PBXClient.run().

final String pbx.PBXClient.INFO = "logInfo" [static, private]

HTML CSS class for info messages.

Definition at line 159 of file PBXClient.java.

Referenced by pbx.PBXClient.parseControlMessage(), and pbx.PBXClient.run().

String pbx.PBXClient.myID [private]

Chat client ID when presented to user (== host + ":" + port)

Definition at line 174 of file PBXClient.java.

Referenced by pbx.PBXClient.PBXClient(), and pbx.PBXClient.run().

PrintWriter pbx.PBXClient.out = null [private]

Output stream to remote server.

Definition at line 179 of file PBXClient.java.

Referenced by pbx.PBXClient.run(), and pbx.PBXClient.send().

int pbx.PBXClient.port = -1 [private]

TCP port where to connect to on remote chat server.

Definition at line 169 of file PBXClient.java.

Referenced by pbx.PBXClient.parseControlMessage(), pbx.PBXClient.PBXClient(), and pbx.PBXClient.run().

volatile boolean pbx.PBXClient.running = false [private]

Indicates/enables the thread to be running.

Definition at line 189 of file PBXClient.java.

Referenced by pbx.PBXClient.close(), pbx.PBXClient.run(), and pbx.PBXClient.start().

Socket pbx.PBXClient.socket = null [private]

Instance of the TCP socket to chat server.

Definition at line 184 of file PBXClient.java.

Referenced by pbx.PBXClient.close(), pbx.PBXClient.getLocalAddress(), and pbx.PBXClient.run().

final String pbx.PBXClient.WARN = "logWarn" [static, private]

HTML CSS class for warning and error messages.

Definition at line 154 of file PBXClient.java.

Referenced by pbx.PBXClient.run().


The documentation for this class was generated from the following file: