From 61eb387b5e2f924141691bb8e447eb58de5a6d8b Mon Sep 17 00:00:00 2001 From: M6KVM Date: Thu, 2 Oct 2014 15:13:51 +0100 Subject: [PATCH 1/7] SP-258: Patch to deal with compilation issues in SIPUnit which appear to be to do with the type of a 'Timestamp' Tested with java version "1.7.0_67" Java(TM) SE Runtime Environment (build 1.7.0_67-b01) Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode) --- src/main/java/org/cafesip/sipunit/PresenceSubscriber.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cafesip/sipunit/PresenceSubscriber.java b/src/main/java/org/cafesip/sipunit/PresenceSubscriber.java index 738406ea0a..26af3eac65 100644 --- a/src/main/java/org/cafesip/sipunit/PresenceSubscriber.java +++ b/src/main/java/org/cafesip/sipunit/PresenceSubscriber.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.Calendar; import javax.sip.header.AcceptHeader; import javax.sip.header.ContentTypeHeader; @@ -33,6 +34,7 @@ import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; +import javax.xml.datatype.XMLGregorianCalendar; import org.cafesip.sipunit.presenceparser.pidf.Contact; import org.cafesip.sipunit.presenceparser.pidf.Note; @@ -210,9 +212,11 @@ public boolean handleEvent(ValidationEvent arg0) while (i.hasNext()) { Tuple t = (Tuple) i.next(); + XMLGregorianCalendar gregCal = t.getTimestamp(); + Calendar cvtTs = gregCal.toGregorianCalendar(); PresenceDeviceInfo dev = new PresenceDeviceInfo(); - dev.setBasicStatus(t.getStatus().getBasic()); + dev.setBasicStatus(t.getStatus().getBasic().toString()); Contact contact = t.getContact(); if (contact != null) @@ -228,7 +232,7 @@ public boolean handleEvent(ValidationEvent arg0) dev.setDeviceExtensions(t.getAny()); dev.setId(t.getId()); dev.setStatusExtensions(t.getStatus().getAny()); - dev.setTimestamp(t.getTimestamp()); + dev.setTimestamp(cvtTs); ArrayList notes = new ArrayList(); if (t.getNote() != null) From 3ce47ab824852d5d8a95b1d8d321ec665e1e7c17 Mon Sep 17 00:00:00 2001 From: M6KVM Date: Thu, 9 Oct 2014 16:20:56 +0100 Subject: [PATCH 2/7] SP-258: Experimental waitForDisconnectResponse logic Based on the following thread: https://sourceforge.net/p/cafesip/discussion/467762/thread/fbf155f6 --- .../java/org/cafesip/sipunit/SipCall.java | 101 ++++++++++++++++-- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/cafesip/sipunit/SipCall.java b/src/main/java/org/cafesip/sipunit/SipCall.java index b9b12106d5..a780c1ef9b 100644 --- a/src/main/java/org/cafesip/sipunit/SipCall.java +++ b/src/main/java/org/cafesip/sipunit/SipCall.java @@ -2850,6 +2850,14 @@ public boolean waitReinviteResponse(SipTransaction siptrans, long timeout) return true; } + public boolean disconnect() + { + if (sendDisconnect() == null) { + return false; + } + return true; + } + /** * This method sends a basic BYE message. It incorporates required * authorization headers that have previously been accumulated during the @@ -2858,9 +2866,9 @@ public boolean waitReinviteResponse(SipTransaction siptrans, long timeout) * * @return true if the message was successfully sent, false otherwise. */ - public boolean disconnect() + public SipTransaction sendDisconnect() { - return disconnect(null, null, null); + return sendDisconnect(null, null, null); } /** @@ -2895,7 +2903,7 @@ public boolean disconnect() * for this body to be included in the message. Use null for no * body bytes. */ - public boolean disconnect(ArrayList
additionalHeaders, + public SipTransaction sendDisconnect(ArrayList
additionalHeaders, ArrayList
replaceHeaders, String body) { initErrorInfo(); @@ -2907,7 +2915,7 @@ public boolean disconnect(ArrayList
additionalHeaders, .get(new Integer(returnCode)) + " - dialog hasn't been established"; - return false; + return null; } try @@ -2924,14 +2932,14 @@ public boolean disconnect(ArrayList
additionalHeaders, if (transaction != null) { - return true; + return transaction; } setReturnCode(parent.getReturnCode()); setErrorMessage(parent.getErrorMessage()); setException(parent.getException()); - return false; + return null; } catch (Exception ex) @@ -2941,7 +2949,7 @@ public boolean disconnect(ArrayList
additionalHeaders, setErrorMessage("Exception: " + ex.getClass().getName() + ": " + ex.getMessage()); - return false; + return null; } } @@ -2993,13 +3001,14 @@ public boolean disconnect(ArrayList
additionalHeaders, * null for no replacement of message headers. * */ - public boolean disconnect(String body, String contentType, + public SipTransaction sendDisconnect(String body, String contentType, String contentSubType, ArrayList additionalHeaders, ArrayList replaceHeaders) { + SipTransaction ret = null; try { - return disconnect(parent.toHeader(additionalHeaders, contentType, + ret = sendDisconnect(parent.toHeader(additionalHeaders, contentType, contentSubType), parent.toHeader(replaceHeaders), body); } catch (Exception ex) @@ -3008,8 +3017,8 @@ public boolean disconnect(String body, String contentType, setErrorMessage("Exception: " + ex.getClass().getName() + ": " + ex.getMessage()); setReturnCode(SipSession.EXCEPTION_ENCOUNTERED); - return false; } + return ret; } /** @@ -4278,6 +4287,76 @@ public boolean waitForCancelResponse(SipTransaction siptrans, long timeout) return true; } + /** + * The waitForDisconnectResponse() method waits for a response to be received + * from the network for a sent BYE. Call this method after calling + * sendDisconnect(). + *

+ * This method blocks until one of the following occurs: 1) A response + * message has been received. In this case, a value of true is returned. + * Call the getLastReceivedResponse() method to get the response details. 2) + * A timeout occurs. A false value is returned in this case. 3) An error + * occurs. False is returned in this case. + *

+ * Regardless of the outcome, getReturnCode() can be called after this + * method returns to get the status code: IE, the SIP response code received + * from the network (defined in SipResponse, along with the corresponding + * textual equivalent) or a SipUnit internal status/error code (defined in + * SipSession, along with the corresponding textual equivalent). SipUnit + * internal codes are in a specially designated range + * (SipSession.SIPUNIT_INTERNAL_RETURNCODE_MIN and upward). + *

+ * + * @param siptrans + * This is the object that was returned by method sendDisconnect(). + * It identifies a specific Disconnect transaction. + * @param timeout + * The maximum amount of time to wait, in milliseconds. Use a + * value of 0 to wait indefinitely. + * @return true if a response was received - in that case, call + * getReturnCode() to get the status code that was contained in the + * received response, and/or call getLastReceivedResponse() to see + * the response details. Returns false if timeout or error. + */ + public boolean waitForDisconnectResponse(SipTransaction siptrans, long timeout) + { + initErrorInfo(); + + if (siptrans == null) + { + returnCode = SipSession.INVALID_OPERATION; + errorMessage = (String) SipSession.statusCodeDescription + .get(new Integer(returnCode)) + + " - no transaction object given"; + return false; + } + + EventObject response_event = parent.waitResponse(siptrans, timeout); + + if (response_event == null) + { + setErrorMessage(parent.getErrorMessage()); + setException(parent.getException()); + setReturnCode(parent.getReturnCode()); + return false; + } + + if (response_event instanceof TimeoutEvent == true) + { + setReturnCode(SipPhone.TIMEOUT_OCCURRED); + setErrorMessage("A Timeout Event was received"); + return false; + } + + Response resp = ((ResponseEvent) response_event).getResponse(); + receivedResponses.add(new SipResponse((ResponseEvent) response_event)); + SipStack.trace("Gradwell BYE response received: " + resp.toString()); + + setReturnCode(resp.getStatusCode()); + + return true; + } + /** * Gets the SIP Call ID for this incoming or outgoing call. * @@ -4292,4 +4371,4 @@ public String getCallId() return callId.getCallId(); } -} \ No newline at end of file +} From d15d6de05431e2ec976d9f407d5fc946d3e80123 Mon Sep 17 00:00:00 2001 From: M6KVM Date: Thu, 9 Oct 2014 16:34:25 +0100 Subject: [PATCH 3/7] AST-706: Change target to destdir in Maven config. target is now a version number. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1b384b6a1..9dde5b0962 100644 --- a/pom.xml +++ b/pom.xml @@ -279,7 +279,7 @@ From a844e0d5efc4c27f232b9d5b60792bfca61bb10c Mon Sep 17 00:00:00 2001 From: M6KVM Date: Thu, 9 Oct 2014 16:39:50 +0100 Subject: [PATCH 4/7] AST-706: Missing disconnect() wrapper --- src/main/java/org/cafesip/sipunit/SipCall.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cafesip/sipunit/SipCall.java b/src/main/java/org/cafesip/sipunit/SipCall.java index a780c1ef9b..8a65083c12 100644 --- a/src/main/java/org/cafesip/sipunit/SipCall.java +++ b/src/main/java/org/cafesip/sipunit/SipCall.java @@ -2952,7 +2952,21 @@ public SipTransaction sendDisconnect(ArrayList

additionalHeaders, return null; } } - + + public boolean disconnect(String body, String contentType, + String contentSubType, ArrayList additionalHeaders, + ArrayList replaceHeaders) + { + SipTransaction siptrans = sendDisconnect(body, contentType, contentSubType, + additionalHeaders, replaceHeaders); + + if (siptrans == null) { + return false; + } + + return true; + } + /** * This method is the same as the basic disconnect() method except that it * allows the caller to specify a message body and/or additional message From fc6aa26bd722500c0f2c17de8a99f698457406fa Mon Sep 17 00:00:00 2001 From: M6KVM Date: Thu, 9 Oct 2014 17:12:36 +0100 Subject: [PATCH 5/7] AST-706: Pass internal trace messages on to a version of log4j with trace support. Support user-defined log4j compatible logger - We needed to bump the log4j dependency on a bit for this support. --- pom.xml | 2 +- .../java/org/cafesip/sipunit/SipStack.java | 22 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 9dde5b0962..f71c4f1c37 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ log4j log4j - 1.2.8 + 1.2.17 diff --git a/src/main/java/org/cafesip/sipunit/SipStack.java b/src/main/java/org/cafesip/sipunit/SipStack.java index 0306525da5..025f97b005 100644 --- a/src/main/java/org/cafesip/sipunit/SipStack.java +++ b/src/main/java/org/cafesip/sipunit/SipStack.java @@ -47,6 +47,8 @@ import javax.sip.header.RouteHeader; import javax.sip.message.MessageFactory; +import org.apache.log4j.Logger; + /** * This class is the starting point for a SipUnit test. Before establishing any * SIP sessions, the test program must instantiate this class. Each SipStack @@ -63,6 +65,8 @@ */ public class SipStack implements SipListener { + static Logger log = null; + private static boolean traceEnabled = false; private static SipFactory sipFactory = null; @@ -135,6 +139,16 @@ public class SipStack implements SipListener public static final String DEFAULT_PROTOCOL = PROTOCOL_UDP; + /** + * This constructor is a wrapper around the usual constructor, + * which allows an additional logging object to be passed. + */ + public SipStack(String proto, int port, Properties props, Logger log) throws Exception + { + this(proto, port, props); + SipStack.log = log; + } + /** * A constructor for this class. Before establishing any SIP sessions, * instantiate this class. You may provide the parameters for SIP protocol @@ -529,8 +543,12 @@ public synchronized static void trace(String msg) // grossly simplified { if (traceEnabled) { - System.out.println("SIPUNIT TRACE: " + System.currentTimeMillis() + if (log == null) { + System.out.println("SIPUNIT TRACE: " + System.currentTimeMillis() + " " + msg); + } else { + log.trace("SIPUNIT TRACE\t" + msg); + } } } @@ -606,4 +624,4 @@ public void processDialogTerminated(DialogTerminatedEvent arg0) public int getRetransmissions() { return retransmissions; } -} \ No newline at end of file +} From 320c8126d886c4931b00c5d28fadc8811b44db09 Mon Sep 17 00:00:00 2001 From: M6KVM Date: Fri, 10 Oct 2014 10:11:45 +0100 Subject: [PATCH 6/7] AST-706: Problem processing some events, such as BYE We're not entirely sure about this logic, but it prevented us seeing BYE requests between agents. The BYE was received, but waitForDisconnect() timed out. This change appears to correct it. --- src/main/java/org/cafesip/sipunit/SipSession.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/cafesip/sipunit/SipSession.java b/src/main/java/org/cafesip/sipunit/SipSession.java index 2f3975e2ce..fb683b79e7 100644 --- a/src/main/java/org/cafesip/sipunit/SipSession.java +++ b/src/main/java/org/cafesip/sipunit/SipSession.java @@ -448,13 +448,14 @@ public void processRequest(RequestEvent request) { SipStack .trace(" skipping 'To' check, we're not loopback (see setLoopback())"); - return; } - - // check 'To' for a match - if (to.getAddress().getURI().toString().equals(me) == false) + else { - return; + // check 'To' for a match + if (to.getAddress().getURI().toString().equals(me) == false) + { + return; + } } } @@ -2460,4 +2461,4 @@ public void processDialogTerminated(DialogTerminatedEvent arg0) // TODO Auto-generated method stub } -} \ No newline at end of file +} From 0a034cc8bcd98b063a1f8a8f7121fdafaa80f1ef Mon Sep 17 00:00:00 2001 From: M6KVM Date: Fri, 10 Oct 2014 11:01:55 +0100 Subject: [PATCH 7/7] AST-706: Reference to submitting firm was left in as debug only. --- src/main/java/org/cafesip/sipunit/SipCall.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cafesip/sipunit/SipCall.java b/src/main/java/org/cafesip/sipunit/SipCall.java index 8a65083c12..511abe6995 100644 --- a/src/main/java/org/cafesip/sipunit/SipCall.java +++ b/src/main/java/org/cafesip/sipunit/SipCall.java @@ -4364,7 +4364,7 @@ public boolean waitForDisconnectResponse(SipTransaction siptrans, long timeout) Response resp = ((ResponseEvent) response_event).getResponse(); receivedResponses.add(new SipResponse((ResponseEvent) response_event)); - SipStack.trace("Gradwell BYE response received: " + resp.toString()); + SipStack.trace("BYE response received: " + resp.toString()); setReturnCode(resp.getStatusCode());