• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import android.net.Uri;
20 import android.os.Bundle;
21 import android.os.SystemClock;
22 import android.telecom.ConferenceParticipant;
23 import android.telephony.Rlog;
24 import android.util.Log;
25 
26 import java.lang.Override;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.concurrent.CopyOnWriteArraySet;
31 
32 /**
33  * {@hide}
34  */
35 public abstract class Connection {
36     public interface PostDialListener {
onPostDialWait()37         void onPostDialWait();
onPostDialChar(char c)38         void onPostDialChar(char c);
39     }
40 
41     /**
42      * Listener interface for events related to the connection which should be reported to the
43      * {@link android.telecom.Connection}.
44      */
45     public interface Listener {
onVideoStateChanged(int videoState)46         public void onVideoStateChanged(int videoState);
onLocalVideoCapabilityChanged(boolean capable)47         public void onLocalVideoCapabilityChanged(boolean capable);
onRemoteVideoCapabilityChanged(boolean capable)48         public void onRemoteVideoCapabilityChanged(boolean capable);
onWifiChanged(boolean isWifi)49         public void onWifiChanged(boolean isWifi);
onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)50         public void onVideoProviderChanged(
51                 android.telecom.Connection.VideoProvider videoProvider);
onAudioQualityChanged(int audioQuality)52         public void onAudioQualityChanged(int audioQuality);
onConferenceParticipantsChanged(List<ConferenceParticipant> participants)53         public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants);
onCallSubstateChanged(int callSubstate)54         public void onCallSubstateChanged(int callSubstate);
onMultipartyStateChanged(boolean isMultiParty)55         public void onMultipartyStateChanged(boolean isMultiParty);
onConferenceMergedFailed()56         public void onConferenceMergedFailed();
onExtrasChanged(Bundle extras)57         public void onExtrasChanged(Bundle extras);
58     }
59 
60     /**
61      * Base listener implementation.
62      */
63     public abstract static class ListenerBase implements Listener {
64         @Override
onVideoStateChanged(int videoState)65         public void onVideoStateChanged(int videoState) {}
66         @Override
onLocalVideoCapabilityChanged(boolean capable)67         public void onLocalVideoCapabilityChanged(boolean capable) {}
68         @Override
onRemoteVideoCapabilityChanged(boolean capable)69         public void onRemoteVideoCapabilityChanged(boolean capable) {}
70         @Override
onWifiChanged(boolean isWifi)71         public void onWifiChanged(boolean isWifi) {}
72         @Override
onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)73         public void onVideoProviderChanged(
74                 android.telecom.Connection.VideoProvider videoProvider) {}
75         @Override
onAudioQualityChanged(int audioQuality)76         public void onAudioQualityChanged(int audioQuality) {}
77         @Override
onConferenceParticipantsChanged(List<ConferenceParticipant> participants)78         public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {}
79         @Override
onCallSubstateChanged(int callSubstate)80         public void onCallSubstateChanged(int callSubstate) {}
81         @Override
onMultipartyStateChanged(boolean isMultiParty)82         public void onMultipartyStateChanged(boolean isMultiParty) {}
83         @Override
onConferenceMergedFailed()84         public void onConferenceMergedFailed() {}
85         @Override
onExtrasChanged(Bundle extras)86         public void onExtrasChanged(Bundle extras) {}
87     }
88 
89     public static final int AUDIO_QUALITY_STANDARD = 1;
90     public static final int AUDIO_QUALITY_HIGH_DEFINITION = 2;
91 
92     //Caller Name Display
93     protected String mCnapName;
94     protected int mCnapNamePresentation  = PhoneConstants.PRESENTATION_ALLOWED;
95     protected String mAddress;     // MAY BE NULL!!!
96     protected String mDialString;          // outgoing calls only
97     protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED;
98     protected boolean mIsIncoming;
99     /*
100      * These time/timespan values are based on System.currentTimeMillis(),
101      * i.e., "wall clock" time.
102      */
103     protected long mCreateTime;
104     protected long mConnectTime;
105     /*
106      * These time/timespan values are based on SystemClock.elapsedRealTime(),
107      * i.e., time since boot.  They are appropriate for comparison and
108      * calculating deltas.
109      */
110     protected long mConnectTimeReal;
111     protected long mDuration;
112     protected long mHoldingStartTime;  // The time when the Connection last transitioned
113                             // into HOLDING
114     protected Connection mOrigConnection;
115     private List<PostDialListener> mPostDialListeners = new ArrayList<>();
116     public Set<Listener> mListeners = new CopyOnWriteArraySet<>();
117 
118     protected boolean mNumberConverted = false;
119     protected String mConvertedNumber;
120 
121     private static String LOG_TAG = "Connection";
122 
123     Object mUserData;
124     private int mVideoState;
125     private boolean mLocalVideoCapable;
126     private boolean mRemoteVideoCapable;
127     private boolean mIsWifi;
128     private int mAudioQuality;
129     private int mCallSubstate;
130     private android.telecom.Connection.VideoProvider mVideoProvider;
131     public Call.State mPreHandoverState = Call.State.IDLE;
132     private Bundle mExtras;
133 
134     /* Instance Methods */
135 
136     /**
137      * Gets address (e.g. phone number) associated with connection.
138      * TODO: distinguish reasons for unavailability
139      *
140      * @return address or null if unavailable
141      */
142 
getAddress()143     public String getAddress() {
144         return mAddress;
145     }
146 
147     /**
148      * Gets CNAP name associated with connection.
149      * @return cnap name or null if unavailable
150      */
getCnapName()151     public String getCnapName() {
152         return mCnapName;
153     }
154 
155     /**
156      * Get original dial string.
157      * @return original dial string or null if unavailable
158      */
getOrigDialString()159     public String getOrigDialString(){
160         return null;
161     }
162 
163     /**
164      * Gets CNAP presentation associated with connection.
165      * @return cnap name or null if unavailable
166      */
167 
getCnapNamePresentation()168     public int getCnapNamePresentation() {
169        return mCnapNamePresentation;
170     }
171 
172     /**
173      * @return Call that owns this Connection, or null if none
174      */
getCall()175     public abstract Call getCall();
176 
177     /**
178      * Connection create time in currentTimeMillis() format
179      * Basically, set when object is created.
180      * Effectively, when an incoming call starts ringing or an
181      * outgoing call starts dialing
182      */
getCreateTime()183     public long getCreateTime() {
184         return mCreateTime;
185     }
186 
187     /**
188      * Connection connect time in currentTimeMillis() format.
189      * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition.
190      * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition.
191      * Returns 0 before then.
192      */
getConnectTime()193     public long getConnectTime() {
194         return mConnectTime;
195     }
196 
197     /**
198      * Sets the Connection connect time in currentTimeMillis() format.
199      *
200      * @param connectTime the new connect time.
201      */
setConnectTime(long connectTime)202     public void setConnectTime(long connectTime) {
203         mConnectTime = connectTime;
204     }
205 
206     /**
207      * Connection connect time in elapsedRealtime() format.
208      * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition.
209      * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition.
210      * Returns 0 before then.
211      */
getConnectTimeReal()212     public long getConnectTimeReal() {
213         return mConnectTimeReal;
214     }
215 
216     /**
217      * Disconnect time in currentTimeMillis() format.
218      * The time when this Connection makes a transition into ENDED or FAIL.
219      * Returns 0 before then.
220      */
getDisconnectTime()221     public abstract long getDisconnectTime();
222 
223     /**
224      * Returns the number of milliseconds the call has been connected,
225      * or 0 if the call has never connected.
226      * If the call is still connected, then returns the elapsed
227      * time since connect.
228      */
getDurationMillis()229     public long getDurationMillis() {
230         if (mConnectTimeReal == 0) {
231             return 0;
232         } else if (mDuration == 0) {
233             return SystemClock.elapsedRealtime() - mConnectTimeReal;
234         } else {
235             return mDuration;
236         }
237     }
238 
239     /**
240      * The time when this Connection last transitioned into HOLDING
241      * in elapsedRealtime() format.
242      * Returns 0, if it has never made a transition into HOLDING.
243      */
getHoldingStartTime()244     public long getHoldingStartTime() {
245         return mHoldingStartTime;
246     }
247 
248     /**
249      * If this connection is HOLDING, return the number of milliseconds
250      * that it has been on hold for (approximately).
251      * If this connection is in any other state, return 0.
252      */
253 
getHoldDurationMillis()254     public abstract long getHoldDurationMillis();
255 
256     /**
257      * Returns call disconnect cause. Values are defined in
258      * {@link android.telephony.DisconnectCause}. If the call is not yet
259      * disconnected, NOT_DISCONNECTED is returned.
260      */
getDisconnectCause()261     public abstract int getDisconnectCause();
262 
263     /**
264      * Returns a string disconnect cause which is from vendor.
265      * Vendors may use this string to explain the underline causes of failed calls.
266      * There is no guarantee that it is non-null nor it'll have meaningful stable values.
267      * Only use it when getDisconnectCause() returns a value that is not specific enough, like
268      * ERROR_UNSPECIFIED.
269      */
getVendorDisconnectCause()270     public abstract String getVendorDisconnectCause();
271 
272     /**
273      * Returns true of this connection originated elsewhere
274      * ("MT" or mobile terminated; another party called this terminal)
275      * or false if this call originated here (MO or mobile originated).
276      */
isIncoming()277     public boolean isIncoming() {
278         return mIsIncoming;
279     }
280 
281     /**
282      * If this Connection is connected, then it is associated with
283      * a Call.
284      *
285      * Returns getCall().getState() or Call.State.IDLE if not
286      * connected
287      */
getState()288     public Call.State getState() {
289         Call c;
290 
291         c = getCall();
292 
293         if (c == null) {
294             return Call.State.IDLE;
295         } else {
296             return c.getState();
297         }
298     }
299 
300     /**
301      * If this connection went through handover return the state of the
302      * call that contained this connection before handover.
303      */
getStateBeforeHandover()304     public Call.State getStateBeforeHandover() {
305         return mPreHandoverState;
306    }
307 
308     /**
309      * Get the details of conference participants. Expected to be
310      * overwritten by the Connection subclasses.
311      */
getConferenceParticipants()312     public List<ConferenceParticipant> getConferenceParticipants() {
313         Call c;
314 
315         c = getCall();
316 
317         if (c == null) {
318             return null;
319         } else {
320             return c.getConferenceParticipants();
321         }
322     }
323 
324     /**
325      * isAlive()
326      *
327      * @return true if the connection isn't disconnected
328      * (could be active, holding, ringing, dialing, etc)
329      */
330     public boolean
isAlive()331     isAlive() {
332         return getState().isAlive();
333     }
334 
335     /**
336      * Returns true if Connection is connected and is INCOMING or WAITING
337      */
338     public boolean
isRinging()339     isRinging() {
340         return getState().isRinging();
341     }
342 
343     /**
344      *
345      * @return the userdata set in setUserData()
346      */
getUserData()347     public Object getUserData() {
348         return mUserData;
349     }
350 
351     /**
352      *
353      * @param userdata user can store an any userdata in the Connection object.
354      */
setUserData(Object userdata)355     public void setUserData(Object userdata) {
356         mUserData = userdata;
357     }
358 
359     /**
360      * Hangup individual Connection
361      */
hangup()362     public abstract void hangup() throws CallStateException;
363 
364     /**
365      * Separate this call from its owner Call and assigns it to a new Call
366      * (eg if it is currently part of a Conference call
367      * TODO: Throw exception? Does GSM require error display on failure here?
368      */
separate()369     public abstract void separate() throws CallStateException;
370 
371     public enum PostDialState {
372         NOT_STARTED,    /* The post dial string playback hasn't
373                            been started, or this call is not yet
374                            connected, or this is an incoming call */
375         STARTED,        /* The post dial string playback has begun */
376         WAIT,           /* The post dial string playback is waiting for a
377                            call to proceedAfterWaitChar() */
378         WILD,           /* The post dial string playback is waiting for a
379                            call to proceedAfterWildChar() */
380         COMPLETE,       /* The post dial string playback is complete */
381         CANCELLED,       /* The post dial string playback was cancelled
382                            with cancelPostDial() */
383         PAUSE           /* The post dial string playback is pausing for a
384                            call to processNextPostDialChar*/
385     }
386 
clearUserData()387     public void clearUserData(){
388         mUserData = null;
389     }
390 
addPostDialListener(PostDialListener listener)391     public final void addPostDialListener(PostDialListener listener) {
392         if (!mPostDialListeners.contains(listener)) {
393             mPostDialListeners.add(listener);
394         }
395     }
396 
removePostDialListener(PostDialListener listener)397     public final void removePostDialListener(PostDialListener listener) {
398         mPostDialListeners.remove(listener);
399     }
400 
clearPostDialListeners()401     protected final void clearPostDialListeners() {
402         mPostDialListeners.clear();
403     }
404 
notifyPostDialListeners()405     protected final void notifyPostDialListeners() {
406         if (getPostDialState() == PostDialState.WAIT) {
407             for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) {
408                 listener.onPostDialWait();
409             }
410         }
411     }
412 
notifyPostDialListenersNextChar(char c)413     protected final void notifyPostDialListenersNextChar(char c) {
414         for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) {
415             listener.onPostDialChar(c);
416         }
417     }
418 
getPostDialState()419     public abstract PostDialState getPostDialState();
420 
421     /**
422      * Returns the portion of the post dial string that has not
423      * yet been dialed, or "" if none
424      */
getRemainingPostDialString()425     public abstract String getRemainingPostDialString();
426 
427     /**
428      * See Phone.setOnPostDialWaitCharacter()
429      */
430 
proceedAfterWaitChar()431     public abstract void proceedAfterWaitChar();
432 
433     /**
434      * See Phone.setOnPostDialWildCharacter()
435      */
proceedAfterWildChar(String str)436     public abstract void proceedAfterWildChar(String str);
437     /**
438      * Cancel any post
439      */
cancelPostDial()440     public abstract void cancelPostDial();
441 
442     /**
443      * Returns the caller id presentation type for incoming and waiting calls
444      * @return one of PRESENTATION_*
445      */
getNumberPresentation()446     public abstract int getNumberPresentation();
447 
448     /**
449      * Returns the User to User Signaling (UUS) information associated with
450      * incoming and waiting calls
451      * @return UUSInfo containing the UUS userdata.
452      */
getUUSInfo()453     public abstract UUSInfo getUUSInfo();
454 
455     /**
456      * Returns the CallFail reason provided by the RIL with the result of
457      * RIL_REQUEST_LAST_CALL_FAIL_CAUSE
458      */
getPreciseDisconnectCause()459     public abstract int getPreciseDisconnectCause();
460 
461     /**
462      * Returns the original Connection instance associated with
463      * this Connection
464      */
getOrigConnection()465     public Connection getOrigConnection() {
466         return mOrigConnection;
467     }
468 
469     /**
470      * Returns whether the original ImsPhoneConnection was a member
471      * of a conference call
472      * @return valid only when getOrigConnection() is not null
473      */
isMultiparty()474     public abstract boolean isMultiparty();
475 
migrateFrom(Connection c)476     public void migrateFrom(Connection c) {
477         if (c == null) return;
478         mListeners = c.mListeners;
479         mDialString = c.getOrigDialString();
480         mCreateTime = c.getCreateTime();
481         mConnectTime = c.getConnectTime();
482         mConnectTimeReal = c.getConnectTimeReal();
483         mHoldingStartTime = c.getHoldingStartTime();
484         mOrigConnection = c.getOrigConnection();
485     }
486 
487     /**
488      * Assign a listener to be notified of state changes.
489      *
490      * @param listener A listener.
491      */
addListener(Listener listener)492     public final void addListener(Listener listener) {
493         mListeners.add(listener);
494     }
495 
496     /**
497      * Removes a listener.
498      *
499      * @param listener A listener.
500      */
removeListener(Listener listener)501     public final void removeListener(Listener listener) {
502         mListeners.remove(listener);
503     }
504 
505     /**
506      * Returns the current video state of the connection.
507      *
508      * @return The video state of the connection.
509      */
getVideoState()510     public int getVideoState() {
511         return mVideoState;
512     }
513 
514     /**
515      * Returns the local video capability state for the connection.
516      *
517      * @return {@code True} if the connection has local video capabilities.
518      */
isLocalVideoCapable()519     public boolean isLocalVideoCapable() {
520         return mLocalVideoCapable;
521     }
522 
523     /**
524      * Returns the remote video capability state for the connection.
525      *
526      * @return {@code True} if the connection has remote video capabilities.
527      */
isRemoteVideoCapable()528     public boolean isRemoteVideoCapable() {
529         return mRemoteVideoCapable;
530     }
531 
532     /**
533      * Returns whether the connection is using a wifi network.
534      *
535      * @return {@code True} if the connection is using a wifi network.
536      */
isWifi()537     public boolean isWifi() {
538         return mIsWifi;
539     }
540 
541     /**
542      * Returns the {@link android.telecom.Connection.VideoProvider} for the connection.
543      *
544      * @return The {@link android.telecom.Connection.VideoProvider}.
545      */
getVideoProvider()546     public android.telecom.Connection.VideoProvider getVideoProvider() {
547         return mVideoProvider;
548     }
549 
550     /**
551      * Returns the audio-quality for the connection.
552      *
553      * @return The audio quality for the connection.
554      */
getAudioQuality()555     public int getAudioQuality() {
556         return mAudioQuality;
557     }
558 
559 
560     /**
561      * Returns the current call substate of the connection.
562      *
563      * @return The call substate of the connection.
564      */
getCallSubstate()565     public int getCallSubstate() {
566         return mCallSubstate;
567     }
568 
569 
570     /**
571      * Sets the videoState for the current connection and reports the changes to all listeners.
572      * Valid video states are defined in {@link android.telecom.VideoProfile}.
573      *
574      * @return The video state.
575      */
setVideoState(int videoState)576     public void setVideoState(int videoState) {
577         mVideoState = videoState;
578         for (Listener l : mListeners) {
579             l.onVideoStateChanged(mVideoState);
580         }
581     }
582 
583     /**
584      * Sets whether video capability is present locally.
585      *
586      * @param capable {@code True} if video capable.
587      */
setLocalVideoCapable(boolean capable)588     public void setLocalVideoCapable(boolean capable) {
589         mLocalVideoCapable = capable;
590         for (Listener l : mListeners) {
591             l.onLocalVideoCapabilityChanged(mLocalVideoCapable);
592         }
593     }
594 
595     /**
596      * Sets whether video capability is present remotely.
597      *
598      * @param capable {@code True} if video capable.
599      */
setRemoteVideoCapable(boolean capable)600     public void setRemoteVideoCapable(boolean capable) {
601         mRemoteVideoCapable = capable;
602         for (Listener l : mListeners) {
603             l.onRemoteVideoCapabilityChanged(mRemoteVideoCapable);
604         }
605     }
606 
607     /**
608      * Sets whether a wifi network is used for the connection.
609      *
610      * @param isWifi {@code True} if wifi is being used.
611      */
setWifi(boolean isWifi)612     public void setWifi(boolean isWifi) {
613         mIsWifi = isWifi;
614         for (Listener l : mListeners) {
615             l.onWifiChanged(mIsWifi);
616         }
617     }
618 
619     /**
620      * Set the audio quality for the connection.
621      *
622      * @param audioQuality The audio quality.
623      */
setAudioQuality(int audioQuality)624     public void setAudioQuality(int audioQuality) {
625         mAudioQuality = audioQuality;
626         for (Listener l : mListeners) {
627             l.onAudioQualityChanged(mAudioQuality);
628         }
629     }
630 
631     /**
632      * Notifies listeners that connection extras has changed.
633      * @param extras New connection extras.
634      */
setConnectionExtras(Bundle extras)635     public void setConnectionExtras(Bundle extras) {
636         mExtras = extras;
637         for (Listener l : mListeners) {
638             l.onExtrasChanged(extras);
639         }
640     }
641 
642     /**
643      * Retrieves the current connection extras.
644      * @return the connection extras.
645      */
getConnectionExtras()646     public Bundle getConnectionExtras() {
647         return mExtras;
648     }
649 
650     /**
651      * Sets the call substate for the current connection and reports the changes to all listeners.
652      * Valid call substates are defined in {@link android.telecom.Connection}.
653      *
654      * @return The call substate.
655      */
setCallSubstate(int callSubstate)656     public void setCallSubstate(int callSubstate) {
657         mCallSubstate = callSubstate;
658         for (Listener l : mListeners) {
659             l.onCallSubstateChanged(mCallSubstate);
660         }
661     }
662 
663     /**
664      * Sets the {@link android.telecom.Connection.VideoProvider} for the connection.
665      *
666      * @param videoProvider The video call provider.
667      */
setVideoProvider(android.telecom.Connection.VideoProvider videoProvider)668     public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) {
669         mVideoProvider = videoProvider;
670         for (Listener l : mListeners) {
671             l.onVideoProviderChanged(mVideoProvider);
672         }
673     }
674 
setConverted(String oriNumber)675     public void setConverted(String oriNumber) {
676         mNumberConverted = true;
677         mConvertedNumber = mAddress;
678         mAddress = oriNumber;
679         mDialString = oriNumber;
680     }
681 
682     /**
683      * Notifies listeners of a change to conference participant(s).
684      *
685      * @param conferenceParticipants The participant(s).
686      */
updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants)687     public void updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants) {
688         for (Listener l : mListeners) {
689             l.onConferenceParticipantsChanged(conferenceParticipants);
690         }
691     }
692 
693     /**
694      * Notifies listeners of a change to the multiparty state of the connection.
695      *
696      * @param isMultiparty The participant(s).
697      */
updateMultipartyState(boolean isMultiparty)698     public void updateMultipartyState(boolean isMultiparty) {
699         for (Listener l : mListeners) {
700             l.onMultipartyStateChanged(isMultiparty);
701         }
702     }
703 
704     /**
705      * Notifies listeners of a failure in merging this connection with the background connection.
706      */
onConferenceMergeFailed()707     public void onConferenceMergeFailed() {
708         for (Listener l : mListeners) {
709             l.onConferenceMergedFailed();
710         }
711     }
712 
713     /**
714      * Notifies this Connection of a request to disconnect a participant of the conference managed
715      * by the connection.
716      *
717      * @param endpoint the {@link Uri} of the participant to disconnect.
718      */
onDisconnectConferenceParticipant(Uri endpoint)719     public void onDisconnectConferenceParticipant(Uri endpoint) {
720     }
721 
722     /**
723      * Build a human representation of a connection instance, suitable for debugging.
724      * Don't log personal stuff unless in debug mode.
725      * @return a string representing the internal state of this connection.
726      */
toString()727     public String toString() {
728         StringBuilder str = new StringBuilder(128);
729 
730         if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) {
731             str.append("addr: " + getAddress())
732                     .append(" pres.: " + getNumberPresentation())
733                     .append(" dial: " + getOrigDialString())
734                     .append(" postdial: " + getRemainingPostDialString())
735                     .append(" cnap name: " + getCnapName())
736                     .append("(" + getCnapNamePresentation() + ")");
737         }
738         str.append(" incoming: " + isIncoming())
739                 .append(" state: " + getState())
740                 .append(" post dial state: " + getPostDialState());
741         return str.toString();
742     }
743 }
744