ciscocisco-jtapi

Cisco JTAPI phone register/unregister status


I am using the below code to check the phone status(if phone is up or down). When phone is down sends an alarm. However this doesn't show when 8800 series phones are down. Is there any other method to check the Phone register/unregister status?

@Override public void terminalChangedEvent(TermEv[] eventList) {
        if ( eventList != null ) {
            for (TermEv eventList1 : eventList) {
                 if (eventList1 instanceof CiscoTermInServiceEv){
                    if(terminalInService.test()==true){
                        LogSQL.removeLog(terminal.getName());
                     }
                    System.out.println(terminal.getName());
                    terminalInService.set();
                    return;
                } else if (eventList1 instanceof CiscoTermOutOfServiceEv && 
                    terminalInService.test()==true) {
                    offline();
                }
            }
         }
       }

Second Question, I was not able to find the methods or documentation about "com.cisco.cti.util.Condition" class. What does Condition.set() and Condition.test() methods do?


Solution

  • Looks like you have the right general idea - JTAPI should work fine for 88xx models, assuming you have the correct device->user association, and user permissions (Standard CTI Enabled, and Standard CTI Allow Control of Phones supporting Connected Xfer and conf needed for 88xx).

    Here is my version working on CUCM 11.5:

    package com.mycompany.app;
    
    import com.cisco.jtapi.extensions.*;
    import java.util.*;
    import javax.telephony.*;
    import javax.telephony.events.*;
    import javax.telephony.callcontrol.*;
    import javax.telephony.callcontrol.events.*;
    import com.cisco.cti.util.Condition;
    
    public class DataTerm implements ProviderObserver, TerminalObserver {
    
        public static final int OUT_OF_SERVICE = 0;
        public static final int IN_SERVICE = 1;
        private Address destAddress;
        private CiscoTerminal observedTerminal;
        private boolean addressInService;
        private boolean terminalInService;
        protected int state = OUT_OF_SERVICE;
        Condition conditionInService = new Condition();
        Provider provider;
    
        public DataTerm(String[] args) {
            try {
                System.out.println("Initializing Jtapi");
                String providerName = "ds-ucm115-1.cisco.com";
                String login = "dstaudt";
                String passwd = "password";
                String dest = "2999";
                JtapiPeer peer = JtapiPeerFactory.getJtapiPeer(null);
                String providerString = providerName + ";login=" + login + ";passwd=" + passwd;
                System.out.println("Opening " + providerString + "...\n");
                provider = peer.getProvider(providerString);
                provider.addObserver(this);
                conditionInService.waitTrue();
                this.destAddress = provider.getAddress(dest);
                this.observedTerminal = (CiscoTerminal) destAddress.getTerminals()[0];
                try {
                    if (destAddress != null) {
                        System.out.println("Adding Terminal Observer to Terminal" + observedTerminal.getName());
                        observedTerminal.addObserver(this);
                    }
                } catch (Exception e) {
                }
            } catch (Exception e) {
                System.out.println("Caught exception " + e);
            }
        }
    
        public void terminalChangedEvent(TermEv[] events) {
            for (int i = 0; i < events.length; i++) {
                Terminal terminal = events[i].getTerminal();
                switch (events[i].getID()) {
                case CiscoTermInServiceEv.ID:
                    System.out.println("Received " + events[i] + "for " + terminal.getName());
                    terminalInService = true;
                    break;
                case CiscoTermOutOfServiceEv.ID:
                    System.out.println("Received " + events[i] + "for " + terminal.getName());
                    terminalInService = false;
                    if (state != OUT_OF_SERVICE) { // you only want to notify when you had notified earlier that you are IN_SERVICE
                        state = OUT_OF_SERVICE;
                    }
                    break;
                }
            }
        }
    
        public void providerChangedEvent(ProvEv[] eventList) {
            if (eventList != null) {
                for (int i = 0; i < eventList.length; i++) {
                    if (eventList[i] instanceof ProvInServiceEv) {
                        conditionInService.set();
                    }
                }
            }
        }
    
    }
    

    The "com.cisco.cti.util.Condition" seems to be based on this pattern:

    public interface Condition

    Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.

    Conditions (also known as condition queues or condition variables) provide a means for one thread to suspend execution (to "wait") until notified by another thread that some state condition may now be true. Because access to this shared state information occurs in different threads, it must be protected, so a lock of some form is associated with the condition. The key property that waiting for a condition provides is that it atomically releases the associated lock and suspends the current thread, just like Object.wait.

    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html