diff --git a/config/golang.m4 b/config/golang.m4 new file mode 100644 index 0000000000..b376909427 --- /dev/null +++ b/config/golang.m4 @@ -0,0 +1,16 @@ +## +## AC macros for using go lang +## + +AC_DEFUN([CHECK_GOLANG],[ + AC_ARG_VAR(GOLANG, [ Go compiler full path ]) + + AC_PATH_PROG([GOLANG],[go],[no]) + if test x$GOLANG != xno; then + found_golang="yes"; + fi + AS_VAR_SET_IF([found_golang], + [], + [AC_MSG_ERROR([Cannot find golang installed. Install go and set GOROOT var])] + ) +]) \ No newline at end of file diff --git a/sipXbridge/src/main/java/org/sipfoundry/sipxbridge/SipUtilities.java b/sipXbridge/src/main/java/org/sipfoundry/sipxbridge/SipUtilities.java index 349dac2c62..2f2d82b8ef 100644 --- a/sipXbridge/src/main/java/org/sipfoundry/sipxbridge/SipUtilities.java +++ b/sipXbridge/src/main/java/org/sipfoundry/sipxbridge/SipUtilities.java @@ -1042,16 +1042,35 @@ static Set getNonTelephoneEventMediaFormats( for (Iterator it = mediaDescriptions.iterator(); it.hasNext();) { MediaDescription mediaDescription = (MediaDescription) it .next(); + int telephoneEvent = -1; if (mediaDescription.getMedia().getMediaType().equals("audio")) { - Vector formats = mediaDescription.getMedia() - .getMediaFormats(true); - for (Iterator it1 = formats.iterator(); it1.hasNext();) { - Object format = it1.next(); - int fmt = new Integer(format.toString()); - if (fmt != 100 && fmt != 101) { - retval.add(fmt); + Vector attributes = mediaDescription.getAttributes(true); + + for (Iterator it1 = attributes.iterator(); it1.hasNext();) { + Attribute attr = (Attribute) it1.next(); + + if (attr.getName().equalsIgnoreCase("rtpmap") || attr.getName().equalsIgnoreCase("fmtp")) { + String attribute = attr.getValue(); + String[] attrs = attribute.split(" "); + if (!attrs[1].startsWith("telephone-event")) { + try{ + telephoneEvent = Integer.parseInt(attrs[0]); + } catch ( NumberFormatException ex) { + logger.warn("could not parse RTP Map " + attrs[0]); + continue; } + } } + } + Vector formats = mediaDescription.getMedia() + .getMediaFormats(true); + for (Iterator it1 = formats.iterator(); it1.hasNext();) { + Object format = it1.next(); + int fmt = new Integer(format.toString()); + if (fmt != telephoneEvent) { + retval.add(fmt); + } + } } } return retval; @@ -1127,27 +1146,8 @@ static SessionDescription cleanSessionDescription( Vector formats = mediaDescription.getMedia().getMediaFormats( true); String mediaType = mediaDescription.getMedia().getMediaType(); - + int telephoneEvent = -1; if ( mediaType.equals("audio")) { - for (Iterator it1 = formats.iterator(); it1.hasNext();) { - Object format = it1.next(); - try { - Integer fmt = new Integer(format.toString()); - if (!codecs.contains(fmt)) { - /* - * Preserve the telephone event lines -- this upsets - * some ITSPs otherwise. AT&T Hack. - */ - if (fmt != 100 && fmt != 101) { - it1.remove(); - } - } - } catch (NumberFormatException ex) { - logger.warn("Could not parse media format " + format); - continue; - } - } - Vector attributes = mediaDescription.getAttributes(true); for (Iterator it1 = attributes.iterator(); it1.hasNext();) { Attribute attr = (Attribute) it1.next(); @@ -1161,17 +1161,18 @@ static SessionDescription cleanSessionDescription( String[] attrs = attribute.split(" "); try { int rtpMapCodec = Integer.parseInt(attrs[0]); - - if (!codecs.contains(rtpMapCodec)) { - /* - * Preserve the telephone event lines -- this upsets - * some ITSPs otherwise. AT&T Hack. - */ - if (rtpMapCodec != 100 && rtpMapCodec != 101) { + /* + * Preserve the telephone event lines -- this upsets + * some ITSPs otherwise. AT&T Hack. + */ + if (!codecs.contains(rtpMapCodec) && rtpMapCodec!=telephoneEvent) { + if (!attrs[1].startsWith("telephone-event")) { if ( logger.isDebugEnabled()) { logger.debug("codecs does not contain " + rtpMapCodec + " removing it "); } it1.remove(); + } else { + telephoneEvent=rtpMapCodec; } } } catch ( NumberFormatException ex) { @@ -1187,6 +1188,23 @@ static SessionDescription cleanSessionDescription( } } + for (Iterator it1 = formats.iterator(); it1.hasNext();) { + Object format = it1.next(); + try { + Integer fmt = new Integer(format.toString()); + /* + * Preserve the telephone event lines -- this upsets + * some ITSPs otherwise. AT&T Hack. + */ + if (!codecs.contains(fmt) && telephoneEvent!=fmt) { + it1.remove(); + } + } catch (NumberFormatException ex) { + logger.warn("Could not parse media format " + format); + continue; + } + } + } } diff --git a/sipXcdr/bin/sipxcdr.in b/sipXcdr/bin/sipxcdr.in index f829f18f63..d303872c2e 100644 --- a/sipXcdr/bin/sipxcdr.in +++ b/sipXcdr/bin/sipxcdr.in @@ -137,8 +137,9 @@ EOF # special patch that upgrades DB version to the latest version - only use once VersionPatch="upgrade_version" -UpgradePatches7="" -UpgradePatches6="cdrremote $VersionPatch" +UpgradePatches8="" +UpgradePatches7="gateway $VersionPatch" +UpgradePatches6="cdrremote $UpgradePatches7" UpgradePatches5="transaction $UpgradePatches6" UpgradePatches4="reference contact calldirection transaction $UpgradePatches5" UpgradePatches3="index_on_time $UpgradePatches4" diff --git a/sipXcdr/etc/Makefile.am b/sipXcdr/etc/Makefile.am index 500523a151..229ddb942b 100644 --- a/sipXcdr/etc/Makefile.am +++ b/sipXcdr/etc/Makefile.am @@ -10,7 +10,8 @@ dist_sql_DATA = \ database/contact.sql \ database/calldirection.sql \ database/cdrremote.sql \ - database/transaction.sql + database/transaction.sql \ + database/gateway.sql cfinputsdir = @SIPX_CFINPUTS@/plugin.d dist_cfinputs_DATA = \ diff --git a/sipXcdr/etc/database/gateway.sql b/sipXcdr/etc/database/gateway.sql new file mode 100644 index 0000000000..10af7e5cc2 --- /dev/null +++ b/sipXcdr/etc/database/gateway.sql @@ -0,0 +1,2 @@ +alter table cdrs add column called_number text ; +alter table cdrs add column gateway int ; diff --git a/sipXcdr/lib/cdr.rb b/sipXcdr/lib/cdr.rb index 197f8f7e5b..0519d09870 100644 --- a/sipXcdr/lib/cdr.rb +++ b/sipXcdr/lib/cdr.rb @@ -153,6 +153,7 @@ def established? private def get_leg(cse) id = CallLeg.leg_id(cse) + puts cse.request_uri,"->", id @legs[id] ||= CallLeg.new(id, @log) end end @@ -207,7 +208,10 @@ def initialize(call_id, log=nil) @failure_status = nil @failure_reason = nil @call_direction = nil - + @called_number = nil + @gateway = nil + @contact_info = {} + @got_original = false @log = log @legs = CallLegs.new(@log) @@ -223,7 +227,8 @@ def initialize(call_id, log=nil) FIELDS = [:call_id, :from_tag, :to_tag, :caller_aor, :callee_aor, :start_time, :connect_time, :end_time, :termination, :failure_status, :failure_reason, - :call_direction, :reference, :caller_contact, :callee_contact, :caller_internal, :callee_route] + :call_direction, :reference, :caller_contact, :callee_contact, :caller_internal, :callee_route, + :called_number, :gateway ] attr_accessor(*FIELDS) @@ -301,8 +306,14 @@ def accept_call_request(cse) original = !cse.to_tag @caller_internal = cse.caller_internal @via_count = cse.via_count if (!@via_count || cse.via_count < @via_count) - @branch_id = cse.branch_id if (!@branch_id || cse.via_count <= @via_count) + @branch_id = cse.branch_id if (!@branch_id || cse.via_count <= @via_count) # bailout if we already have original request and this one is not + + if cse.request_uri.include? "sipxecs-lineid" + called_number = Utils.contact_without_params(cse.request_uri) + gateway = Integer(/.*sipxecs-lineid=(\d+).*/.match(cse.request_uri)[1]) + @contact_info[cse.branch_id] = [called_number, gateway] + end return if(@got_original && !original) # continue if we are original or if we are older @@ -323,6 +334,10 @@ def accept_call_request(cse) end def accept_call_setup(cse) + if @contact_info.has_key? cse.branch_id + @called_number = @contact_info[cse.branch_id][0] + @gateway = @contact_info[cse.branch_id][1] + end if !@start_time # probably a case where we've missed the request. Setup necessary # info as if a request was seen. @@ -370,7 +385,7 @@ def apply_leg(leg) end @failure_reason = leg.failure_reason @failure_status = leg.failure_status - @callee_contact = leg.callee_contact + @callee_contact = leg.callee_contact end # Map termination codes to human-readable strings diff --git a/sipXconfig/etc/ftp.cf b/sipXconfig/etc/ftp.cf index e7288d7fb1..78b844e496 100644 --- a/sipXconfig/etc/ftp.cf +++ b/sipXconfig/etc/ftp.cf @@ -89,7 +89,8 @@ pam_service_name=vsftpd listen=YES chroot_local_user=YES port_enable=YES -log_ftp_protocol=YES"; +log_ftp_protocol=YES +user_config_dir=/etc/vsftpd/user_conf"; "$(sipx.SIPX_CFDATA)/$(sipx.location_id)/vsftp.config.part" insert_type => "file"; } diff --git a/sipXconfig/etc/sipxpbx/commserver/forwardingrules.vm b/sipXconfig/etc/sipxpbx/commserver/forwardingrules.vm index e8e5eca1dc..fd4212280e 100644 --- a/sipXconfig/etc/sipxpbx/commserver/forwardingrules.vm +++ b/sipXconfig/etc/sipxpbx/commserver/forwardingrules.vm @@ -22,32 +22,28 @@ $route #end - SUBSCRIBE -#if( ${statusAddress} ) - - - - message-summary.* - - <${statusAddress.stripProtocol()};transport=tcp> - - +#set($method = $locals.get("subscribe")) +#set($methodDefault = $method.getDefRoute()) +#set($methodName = $method.getName()) + $methodName +#foreach ($field in $method.getFields()) +#if($field.get("name")) + + + $field.get("pattern") + $field.get("routeTo") + +#end #end - - - reg - <${regEventAddress.stripProtocol()};transport=tcp> - - - <${regAddress.stripProtocol()};transport=tcp;x-sipx-routetoreg> + $methodDefault - <${regAddress.stripProtocol()};transport=tcp;x-sipx-routetoreg> + #if(${sbc.enabled}) #if(${exportLocalIpAddress}) @@ -66,6 +62,7 @@ #end + #foreach($auxSbc in $auxSbcs) #if($auxSbc.enabled) @@ -86,6 +83,7 @@ #end #end + Any foreign domain - route via session border. diff --git a/sipXconfig/etc/sipxpbx/dhcp/dhcp.properties b/sipXconfig/etc/sipxpbx/dhcp/dhcp.properties index 9f81538ac2..f6e70c8514 100644 --- a/sipXconfig/etc/sipxpbx/dhcp/dhcp.properties +++ b/sipXconfig/etc/sipxpbx/dhcp/dhcp.properties @@ -12,6 +12,8 @@ dhcpd-config.plcm_https_provisioning.label=Polycom HTTPS provisioning dhcpd-config.plcm_https_provisioning.description=Enable Polycom phones and other devices that utilize DHCP option 160 to use HTTPS provisioning. Please note that the web SSL certificate MUST signed by a well know Cerificate Authority such as Verisign. dhcpd-config.bria_https_provisioning.label=CounterPath Bria HTTPS provisioning dhcpd-config.bria_https_provisioning.description=Enable CounterPath Bria clients and other devices that utilize DHCP option 120 to use HTTPS provisioning. Please note that the web SSL certificate MUST signed by a well know Cerificate such as Verisign. +dhcpd-config.snom_statichttp_provisioning.label=Adding Snom specific class +dhcpd-config.snom_statichttp_provisioning.description=Enable definition of snom class that provides url. dhcpd-config.default_lease_time.label=Default lease time dhcpd-config.default_lease_time.description=Length in seconds that will be assigned to a lease if the client requesting the lease does not ask for a specific expiration time. dhcpd-config.max_lease_time.label=Maximum lease time diff --git a/sipXconfig/etc/sipxpbx/dhcp/dhcp.xml b/sipXconfig/etc/sipxpbx/dhcp/dhcp.xml index d297cf3ef4..e01a812a16 100644 --- a/sipXconfig/etc/sipxpbx/dhcp/dhcp.xml +++ b/sipXconfig/etc/sipxpbx/dhcp/dhcp.xml @@ -2,6 +2,7 @@ + @@ -39,6 +40,12 @@ 0 + + + + + 0 + diff --git a/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.properties b/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.properties index 6f22106e99..0827669725 100644 --- a/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.properties +++ b/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.properties @@ -34,4 +34,11 @@ callresolver.SIP_CALLRESOLVER_CSE_QUEUE_SIZE.label=CSE Queue size callresolver.SIP_CALLRESOLVER_CDR_QUEUE_SIZE.label=CDR Queue size callresolver.SIP_CALLRESOLVER_MAX_CALL_LEN.label=Maximum call length callresolver.SIP_CALLRESOLVER_MAX_RINGING_CALL_LEN.label=Maximum Ringing call length -callresolver.SIP_CALLRESOLVER_MIN_CLEANUP_INTERVAL.label=Minimum cleanup interval \ No newline at end of file +callresolver.SIP_CALLRESOLVER_MIN_CLEANUP_INTERVAL.label=Minimum cleanup interval +callresolver.SIP_CALLRESOLVER_PRIVACY.label=Privacy Extension +callresolver.SIP_CALLRESOLVER_PRIVACY.description=When enabled hides last digits of phone numbers into cdrs to enhance privacy +callresolver.SIP_CALLRESOLVER_PRIVACY_LENGTH.label=Minimum length of extension that must be masquerade +callresolver.SIP_CALLRESOLVER_PRIVACY_LENGTH.description=This value indicate the minimum length of extension that should be covered with * +callresolver.SIP_CALLRESOLVER_PRIVACY_EXCLUDE.label=Prefix excluded from masquerading +callresolver.SIP_CALLRESOLVER_PRIVACY_EXCLUDE.description=This helps to exclude some prefix to be masquerade for extension with length equal to minimum. + diff --git a/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.xml b/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.xml index 65016ce603..0aa62fafe2 100644 --- a/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.xml +++ b/sipXconfig/etc/sipxpbx/sipxcallresolver/sipxcallresolver.xml @@ -116,5 +116,21 @@ + + + DISABLE + + + + + + 5 + + + + + + + diff --git a/sipXconfig/etc/sipxpbx/sipxproxy/sipXproxy-config.vm b/sipXconfig/etc/sipxpbx/sipxproxy/sipXproxy-config.vm index 320723b1b1..ed67ee8a31 100644 --- a/sipXconfig/etc/sipxpbx/sipxproxy/sipXproxy-config.vm +++ b/sipXconfig/etc/sipxpbx/sipxproxy/sipXproxy-config.vm @@ -11,6 +11,9 @@ SIPX_PROXY_STALE_TCP_TIMEOUT : SIPX_PROXY_TLS_PORT : $!{proxyService.secureSipPort} SIPX_PROXY_TCP_PORT : $!{proxyService.sipTCPPort} SIPX_PROXY_UDP_PORT : $!{proxyService.sipUDPPort} +SIPX_PROXY_UDP_RESEND : $!{proxyService.sipUDPResend} +SIPX_PROXY_TCP_RESEND : $!{proxyService.sipTCPResend} + SIPX_PROXY_CALL_STATE : SIPX_PROXY_CALL_STATE_LOG : SIPX_PROXY_CALL_STATE_DB : $callResolverSettings.getSetting('CALLRESOLVER_CALL_STATE_DB').Value diff --git a/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.properties b/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.properties index 2ff3e959dd..7774a9f038 100644 --- a/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.properties +++ b/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.properties @@ -33,6 +33,8 @@ alert-info.ON_EXISTING.description=Phones can be configured to send their own Al type.replaceOrKeep.0=Leave it as it is type.replaceOrKeep.1=Replace it +proxy-configuration.SIPX_PROXY_UDP_RESEND.label=Max resend attempts for UDP +proxy-configuration.SIPX_PROXY_TCP_RESEND.label=Max resend attempts for TCP proxy-configuration.SIPX_PROXY_LOG_LEVEL.label=Log Level proxy-configuration.SIPX_PROXY_TCP_PORT.label=TCP Port proxy-configuration.SIPX_PROXY_TCP_PORT.description= diff --git a/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.xml b/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.xml index bdc22d8e75..39a94f0d0c 100644 --- a/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.xml +++ b/sipXconfig/etc/sipxpbx/sipxproxy/sipxproxy.xml @@ -72,6 +72,18 @@ 5061 + + + + + 4 + + + + + + 4 + diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManager.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManager.java index 15c56bf359..c4e4a2dd86 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManager.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManager.java @@ -13,6 +13,7 @@ public interface ApacheManager { public static final LocationFeature FEATURE = new LocationFeature("apache"); public static final AddressType HTTP_ADDRESS = new AddressType("apacheHttp", 80); + public static final AddressType HTTP_STATIC_ADDRESS = new AddressType("apacheHttpStatic", 8090); public static final AddressType HTTPS_ADDRESS = new AddressType("apacheHttps", "https://%s", 443); public void avoidCheckstyleError(); diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManagerImpl.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManagerImpl.java index 584a429f88..1f88b69f8a 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManagerImpl.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/apache/ApacheManagerImpl.java @@ -70,12 +70,13 @@ public void avoidCheckstyleError() { @Override public Collection getFirewallRules(FirewallManager manager) { - return DefaultFirewallRule.rules(Arrays.asList(HTTP_ADDRESS, HTTPS_ADDRESS), FirewallRule.SystemId.PUBLIC); + return DefaultFirewallRule.rules(Arrays.asList(HTTP_ADDRESS, HTTP_STATIC_ADDRESS, HTTPS_ADDRESS), + FirewallRule.SystemId.PUBLIC); } @Override public Collection
getAvailableAddresses(AddressManager manager, AddressType type, Location requester) { - if (!type.equalsAnyOf(HTTP_ADDRESS, HTTPS_ADDRESS)) { + if (!type.equalsAnyOf(HTTP_ADDRESS, HTTP_STATIC_ADDRESS, HTTPS_ADDRESS)) { return null; } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/Cdr.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/Cdr.java index 957aa67968..2d7aae6411 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/Cdr.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/Cdr.java @@ -82,6 +82,10 @@ public static Termination fromString(String t) { private boolean m_callerInternal; private String m_calleeRoute; + private String m_calledNumberAor; + private String m_calledNumber; + private int m_trunkId; + public String getCalleeAor() { return m_calleeAor; } @@ -95,7 +99,10 @@ public String getCallee() { } public String getRecipient() { - return m_recipient; + if(m_calledNumber!=null) + return m_calledNumber; + else + return m_recipient; } public void setCalleeAor(String calleeAor) { @@ -103,6 +110,28 @@ public void setCalleeAor(String calleeAor) { m_callee = SipUri.extractUser(calleeAor); } + public void setMaskedCalleeAor(String calleeAor, int limit, String excluded) { + m_calleeAor = calleeAor; + m_callee = SipUri.extractUser(calleeAor); + if(m_callee.length() > limit) { + m_callee = m_callee.substring(0, m_callee.length()-3)+"***"; + } else { + if(m_callee.length()==limit) { + String[] exclude = excluded.split(" "); + boolean isExcluded = false; + for(String prefix: exclude) { + if(prefix!="" && m_callee.startsWith(prefix)) { + isExcluded = true; + break; + } + } + if(!isExcluded) { + m_callee = m_callee.substring(0, m_callee.length()-3)+"***"; + } + } + } + } + public void setCalleeContact(String calleeContact) { m_calleeContact = calleeContact; m_recipient = SipUri.extractUser(calleeContact); @@ -129,6 +158,28 @@ public void setCallerAor(String callerAor) { m_caller = SipUri.extractFullUser(callerAor); } + public void setMaskedCallerAor(String callerAor, int limit, String excluded) { + m_callerAor = callerAor; + m_caller = SipUri.extractUser(callerAor); + if(m_caller.length() > limit) { + m_caller = m_caller.substring(0, m_caller.length()-3)+"***"; + }else { + if(m_caller.length()==limit) { + String[] exclude = excluded.split(" "); + boolean isExcluded = false; + for(String prefix: exclude) { + if(prefix!="" && m_caller.startsWith(prefix)) { + isExcluded = true; + break; + } + } + if(!isExcluded) { + m_caller = m_caller.substring(0, m_caller.length()-3)+"***"; + } + } + } + } + public void setCallerContact(String callerContact) { m_callerContact = callerContact; m_originator = SipUri.extractFullUser(callerContact); @@ -291,5 +342,20 @@ public String getCallTypeShortName() { return callType; } + public String getCalledNumber() { + return m_calledNumber; + } + + public void setCalledNumber(String calledNumber) { + m_calledNumberAor = calledNumber; + m_calledNumber = SipUri.extractUser(calledNumber); + } + public int getGateway() { + return m_trunkId; + } + + public void setGateway(int id) { + m_trunkId = id; + } } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrManagerImpl.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrManagerImpl.java index 049bdcb22c..9f62b51db9 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrManagerImpl.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrManagerImpl.java @@ -92,6 +92,8 @@ public class CdrManagerImpl extends JdbcDaoSupport implements CdrManager, Featur static final String CALLEE_ROUTE = "callee_route"; static final String CALLEE_CONTACT = "callee_contact"; static final String CALLER_CONTACT = "caller_contact"; + static final String CALLED_NUMBER = "called_number"; + static final String GATEWAY = "gateway"; private int m_csvLimit; private int m_jsonLimit; @@ -125,9 +127,16 @@ public List getCdrs(Date from, Date to, CdrSearch search, User user) { } public List getCdrs(Date from, Date to, CdrSearch search, User user, int limit, int offset) { - CdrsStatementCreator psc = new SelectAll(from, to, search, user, (user != null) ? (user.getTimezone()) - : m_tz, limit, offset); - CdrsResultReader resultReader = new CdrsResultReader((user != null) ? (user.getTimezone()) : m_tz); + CdrsStatementCreator psc = new SelectAll(from, to, search, user, m_tz, limit, offset); + boolean privacy = false; + int pLimit = 0; + String pExcluded = ""; + if ( user==null ) { + privacy = getSettings().getPrivacyStatus(); + pLimit = getSettings().getPrivacyMinLength(); + pExcluded = getSettings().getPrivacyExcludeList(); + } + CdrsResultReader resultReader = new CdrsResultReader(m_tz, privacy, pLimit, pExcluded); getJdbcTemplate().query(psc, resultReader); return resultReader.getResults(); } @@ -300,6 +309,7 @@ public CdrsStatementCreator(Date from, Date to, CdrSearch search, User user, Tim Set names = user.getAliases(); names.add(user.getName()); m_forUser.setTerm(names.toArray(new String[0])); + m_forUser.setUser(user); } } @@ -371,9 +381,22 @@ static class CdrsResultReader implements RowCallbackHandler { private List m_cdrs = new ArrayList(); private Calendar m_calendar; + private boolean m_privacy; + private int m_privacy_limit; + private String m_privacy_excluded; + + public CdrsResultReader(TimeZone tz, boolean privacy, int limit, String excluded) { + m_calendar = Calendar.getInstance(tz); + m_privacy = privacy; + m_privacy_limit = limit; + m_privacy_excluded = excluded; + } public CdrsResultReader(TimeZone tz) { m_calendar = Calendar.getInstance(tz); + m_privacy = false; + m_privacy_limit = 0; + m_privacy_excluded = ""; } public List getResults() { @@ -382,8 +405,14 @@ public List getResults() { public void processRow(ResultSet rs) throws SQLException { Cdr cdr = new Cdr(); - cdr.setCalleeAor(rs.getString(CALLEE_AOR)); - cdr.setCallerAor(rs.getString(CALLER_AOR)); + if (!m_privacy) { + cdr.setCalleeAor(rs.getString(CALLEE_AOR)); + cdr.setCallerAor(rs.getString(CALLER_AOR)); + } + else { + cdr.setMaskedCalleeAor(rs.getString(CALLEE_AOR), m_privacy_limit, m_privacy_excluded); + cdr.setMaskedCallerAor(rs.getString(CALLER_AOR), m_privacy_limit, m_privacy_excluded); + } cdr.setCallId(rs.getString(CALL_ID)); cdr.setReference(rs.getString(CALL_REFERENCE)); cdr.setCallerInternal(rs.getBoolean(CALLER_INTERNAL)); @@ -400,6 +429,8 @@ public void processRow(ResultSet rs) throws SQLException { cdr.setFailureStatus(rs.getInt(FAILURE_STATUS)); String termination = rs.getString(TERMINATION); cdr.setTermination(Termination.fromString(termination)); + cdr.setCalledNumber(rs.getString(CALLED_NUMBER)); + cdr.setGateway(rs.getInt(GATEWAY)); m_cdrs.add(cdr); } } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSearch.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSearch.java index 44032c3fa5..6a8244b752 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSearch.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSearch.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; +import org.sipfoundry.sipxconfig.common.User; import org.sipfoundry.sipxconfig.dialplan.CallTag; public class CdrSearch { @@ -49,6 +50,7 @@ public enum Mode { }; private String m_order; private boolean m_ascending = true; + private User m_user; public void setMode(Mode mode) { if (mode == null) { @@ -74,6 +76,10 @@ public String[] getTerm() { return m_term; } + public void setUser(User u) { + m_user = u; + } + public void setOrder(String order, boolean ascending) { m_order = order; m_ascending = ascending; @@ -90,16 +96,23 @@ private void appendSearchTermSql(StringBuilder sql, String call) { private void appendCallerSql(StringBuilder sql) { sql.append(OPEN_PARANTHESIS); appendSearchTermSql(sql, CdrManagerImpl.CALLER_AOR); - sql.append(AND); - sql.append(CdrManagerImpl.CALLER_INTERNAL); - sql.append("=true)"); + if(m_user!=null && !m_user.isAdmin()) { + sql.append(AND); + sql.append(CdrManagerImpl.CALLER_INTERNAL); + sql.append("=true)"); + } else { + sql.append(CLOSED_PARANTHESIS); + } + } private void appendCalleeSql(StringBuilder sql) { sql.append(OPEN_PARANTHESIS); appendSearchTermSql(sql, CdrManagerImpl.CALLEE_AOR); - sql.append(AND); - appendCalleeInternalRouteSql(sql); + if(m_user!=null && !m_user.isAdmin()) { + sql.append(AND); + appendCalleeInternalRouteSql(sql); + } sql.append(CLOSED_PARANTHESIS); } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSettings.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSettings.java index d8940db7ee..bc2a842d56 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSettings.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/cdr/CdrSettings.java @@ -30,6 +30,21 @@ public int getAgentPort() { return (Integer) getSettingTypedValue("callresolver/SIP_CALLRESOLVER_AGENT_PORT"); } + public boolean getPrivacyStatus() { + return (Boolean) getSettingTypedValue("callresolver/SIP_CALLRESOLVER_PRIVACY"); + } + + public int getPrivacyMinLength() { + return (Integer) getSettingTypedValue("callresolver/SIP_CALLRESOLVER_PRIVACY_LENGTH"); + } + + public String getPrivacyExcludeList() { + String excludeList = (String) getSettingTypedValue("callresolver/SIP_CALLRESOLVER_PRIVACY_EXCLUDE"); + if( excludeList == null) + excludeList = ""; + return excludeList; + } + @Override protected Setting loadSettings() { return getModelFilesContext().loadModelFile("sipxcallresolver/sipxcallresolver.xml"); diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dhcp/DhcpConfig.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dhcp/DhcpConfig.java index 41ca819f0c..57297baaef 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dhcp/DhcpConfig.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dhcp/DhcpConfig.java @@ -27,6 +27,7 @@ import org.sipfoundry.sipxconfig.address.Address; import org.sipfoundry.sipxconfig.address.AddressManager; import org.sipfoundry.sipxconfig.admin.AdminContext; +import org.sipfoundry.sipxconfig.apache.ApacheManager; import org.sipfoundry.sipxconfig.cfgmgt.ConfigManager; import org.sipfoundry.sipxconfig.cfgmgt.ConfigProvider; import org.sipfoundry.sipxconfig.cfgmgt.ConfigRequest; @@ -49,6 +50,7 @@ public void replicate(ConfigManager manager, ConfigRequest request) throws IOExc AddressManager addressManager = manager.getAddressManager(); Address tftp = addressManager.getSingleAddress(FtpManager.TFTP_ADDRESS); Address admin = addressManager.getSingleAddress(AdminContext.HTTP_ADDRESS); + Address staticHttp = addressManager.getSingleAddress(ApacheManager.HTTP_STATIC_ADDRESS); List
dns = addressManager.getAddresses(DnsManager.DNS_ADDRESS); List
ntp = addressManager.getAddresses(NtpManager.NTP_SERVER); @@ -67,7 +69,7 @@ public void replicate(ConfigManager manager, ConfigRequest request) throws IOExc } Writer w = new FileWriter(new File(dir, "dhcpd.yaml")); try { - writeConfig(w, settings, tftp, admin, dns, ntp); + writeConfig(w, settings, tftp, admin, staticHttp, dns, ntp); } finally { IOUtils.closeQuietly(w); } @@ -75,11 +77,12 @@ public void replicate(ConfigManager manager, ConfigRequest request) throws IOExc } protected void writeConfig(Writer w, DhcpSettings settings, Address tftp, Address admin, - Collection
dns, Collection
ntp) throws IOException { + Address staticHttp, Collection
dns, Collection
ntp) throws IOException { YamlConfiguration c = new YamlConfiguration(w); c.writeSettings(settings.getSettings().getSetting("dhcpd-config")); c.write("tftp", tftp != null ? tftp.getAddress() : ""); c.write("config", admin.stripProtocol()); + c.write("statichttp", staticHttp.addressColonPort() + ":" + staticHttp.getCanonicalPort()); c.writeInlineArray("ntp", CollectionUtils.collect(ntp, Address.GET_IP)); c.writeInlineArray("dns", CollectionUtils.collect(dns, Address.GET_IP)); } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardLocalRuleProvider.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardLocalRuleProvider.java new file mode 100644 index 0000000000..2c02794ce4 --- /dev/null +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardLocalRuleProvider.java @@ -0,0 +1,27 @@ +/** + * + * + * Copyright (c) 2013 Sip2ser.srl. All rights reserved. + * Contributed to SIPfoundry under a Contributor Agreement + * + * This software is free software; you can redistribute it and/or modify it under + * the terms of the Affero General Public License (AGPL) as published by the + * Free Software Foundation; either version 3 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + */ + +package org.sipfoundry.sipxconfig.dialplan.config; + +import java.util.Map; + +public interface ForwardLocalRuleProvider { + + Map getMethodField(); + + boolean isEnabled(); +} diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardingRules.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardingRules.java index 4d6e236cf8..b6be58d76f 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardingRules.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/dialplan/config/ForwardingRules.java @@ -14,10 +14,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.HashMap; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.sipfoundry.sipxconfig.address.AddressManager; +import org.sipfoundry.sipxconfig.address.Address; import org.sipfoundry.sipxconfig.bridge.BridgeSbc; import org.sipfoundry.sipxconfig.dialplan.IDialingRule; import org.sipfoundry.sipxconfig.mwi.Mwi; @@ -27,17 +30,23 @@ import org.sipfoundry.sipxconfig.sbc.SbcDevice; import org.sipfoundry.sipxconfig.sbc.SbcDeviceManager; import org.sipfoundry.sipxconfig.sbc.SbcManager; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + /** * Controls very initial SIP message routing from proxy based on SIP method and potentialy message * content. */ -public class ForwardingRules extends RulesFile { +public class ForwardingRules extends RulesFile implements ApplicationContextAware { + private SbcManager m_sbcManager; private List m_routes; private SbcDeviceManager m_sbcDeviceManager; private AddressManager m_addressManager; private VelocityEngine m_velocityEngine; + private ApplicationContext m_context; + public void setSbcManager(SbcManager sbcManager) { m_sbcManager = sbcManager; @@ -62,6 +71,51 @@ public void generate(IDialingRule rule) { public void end() { } + public class ForwardingMethod{ + public String name; + public List fields; + public String defaultRoute; + + + public ForwardingMethod(String name, String defRoute){ + if (name != null){ + this.name = name; + } + this.fields = new ArrayList(); + if(defRoute!=null){ + this.defaultRoute = defRoute; + } else { + defRoute = ""; + } + } + + public Map getMethodMap(){ + Map methodMap = new HashMap(); + methodMap.put(this.name, this.fields); + return methodMap; + } + + public String getName(){ + return this.name; + } + + public List getFields(){ + return this.fields; + } + + public void addField(Map field){ + Map newField = new HashMap(); + for(String key : field.keySet()){ + newField.put(key,field.get(key)); + } + this.fields.add(newField); + } + + public String getDefRoute(){ + return this.defaultRoute; + } + } + @Override public void write(Writer writer) throws IOException { VelocityContext context = new VelocityContext(); @@ -80,11 +134,56 @@ public void write(Writer writer) throws IOException { // set required sipx services in context context.put("domainName", getDomainName()); context.put("proxyAddress", m_addressManager.getSingleAddress(ProxyManager.TCP_ADDRESS, getLocation())); - context.put("statusAddress", m_addressManager.getSingleAddress(Mwi.SIP_TCP, getLocation())); - context.put("regEventAddress", m_addressManager.getSingleAddress(Registrar.EVENT_ADDRESS, getLocation())); context.put("regAddress", m_addressManager.getSingleAddress(Registrar.TCP_ADDRESS, getLocation())); context.put("location", getLocation()); + + // Defineng the subscribe formarding methods to be place in forwarding rules + ForwardingMethod subscribe = new ForwardingMethod("SUBSCRIBE", + "<"+ m_addressManager.getSingleAddress(Registrar.TCP_ADDRESS, getLocation()).stripProtocol() + + ";transport=tcp;x-sipx-routetoreg>"); + + Address mwiSingleAddress = m_addressManager.getSingleAddress(Mwi.SIP_TCP, getLocation()); + if(null != mwiSingleAddress ) { + Map msgSummary = new HashMap(); + msgSummary.put("name","\"Event\""); + msgSummary.put("pattern","message-summary.*"); + msgSummary.put("routeTo","<"+ mwiSingleAddress.stripProtocol()+";transport=tcp>"); + subscribe.addField(msgSummary); + } + + Address registrarAddress = m_addressManager.getSingleAddress(Registrar.EVENT_ADDRESS, getLocation()); + if(null!=registrarAddress) { + Map reg = new HashMap(); + reg.put("name","\"Event\""); + reg.put("pattern","reg"); + reg.put("routeTo","<"+ registrarAddress.stripProtocol()+";transport=tcp>"); + subscribe.addField(reg); + } + + // List of all method + Map methodsLocalFwd = new HashMap(); + methodsLocalFwd.put("subscribe",subscribe); + + + // write local forwarding rules providers + Map beansLocal = m_context.getBeansOfType(ForwardLocalRuleProvider.class); + if (beansLocal != null) { + for (ForwardLocalRuleProvider beanLocal : beansLocal.values()) { + if (beanLocal.isEnabled()) { + Map newfield = beanLocal.getMethodField(); + String newfieldMethod = ((String)newfield.get("method")).toLowerCase(); + if(methodsLocalFwd.get(newfieldMethod) != null){ + methodsLocalFwd.get(newfieldMethod).addField(newfield); + } + } + } + } + + // Adding methods for local forward to the context + context.put("locals", methodsLocalFwd); + + List bridgeSbcs = new ArrayList(); List sbcDevices = m_sbcDeviceManager.getSbcDevices(); for (SbcDevice device : sbcDevices) { @@ -107,4 +206,9 @@ public void setAddressManager(AddressManager addressManager) { public void setVelocityEngine(VelocityEngine velocityEngine) { m_velocityEngine = velocityEngine; } + + @Override + public void setApplicationContext(ApplicationContext context) { + m_context = context; + } } diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversal.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversal.java index d2eafb29de..5981fca6a0 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversal.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversal.java @@ -18,6 +18,8 @@ public interface NatTraversal { public static final AddressType RELAY_RTP = new AddressType("natRtp", "rtp:%s:%d", 30000, AddressType.Protocol.udp); + public static final AddressType RELAY_RPC = new AddressType("natRpc", 9090); + public NatSettings getSettings(); public void saveSettings(NatSettings settings); diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversalImpl.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversalImpl.java index 7e197d2424..7c08028e6a 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversalImpl.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/nattraversal/NatTraversalImpl.java @@ -92,7 +92,7 @@ public void getBundleFeatures(FeatureManager featureManager, Bundle b) { @Override public Collection
getAvailableAddresses(AddressManager manager, AddressType type, Location requester) { - if (!type.equals(RELAY_RTP)) { + if (!(type.equals(RELAY_RTP) || type.equals(RELAY_RPC))) { return null; } @@ -101,20 +101,29 @@ public Collection
getAvailableAddresses(AddressManager manager, Address return null; } - List
proxy = manager.getAddresses(ProxyManager.TCP_ADDRESS); - List
addresses = new ArrayList
(proxy.size()); - for (Address proxyAddress : proxy) { - Address a = new Address(type, proxyAddress.getAddress(), NatSettings.START_RTP_PORT); - a.setEndPort(NatSettings.END_RTP_PORT); - addresses.add(a); - } - + List locations = manager.getFeatureManager().getLocationsForEnabledFeature(ProxyManager.FEATURE); + List
addresses = new ArrayList
(locations.size()); + + if (type.equals(RELAY_RTP)) { + for (Location location : locations) { + Address a = new Address(type, location.getAddress(), location.getStartRtpPort()); + a.setEndPort(location.getStopRtpPort()); + addresses.add(a); + } + } + if (type.equals(RELAY_RPC)) { + for (Location location : locations) { + Address a = new Address(type, location.getAddress(), getSettings().getXmlRpcPort()); + addresses.add(a); + } + } return addresses; } @Override public Collection getFirewallRules(FirewallManager manager) { - return Arrays.asList(new DefaultFirewallRule(RELAY_RTP, FirewallRule.SystemId.PUBLIC, true)); + return Arrays.asList(new DefaultFirewallRule(RELAY_RTP, FirewallRule.SystemId.PUBLIC, true), + new DefaultFirewallRule(RELAY_RPC, FirewallRule.SystemId.CLUSTER, false)); } @Override diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/vm/AbstractMailboxManager.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/vm/AbstractMailboxManager.java index 3eb72f2a21..8de7831d67 100644 --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/vm/AbstractMailboxManager.java +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/vm/AbstractMailboxManager.java @@ -80,7 +80,7 @@ public List getFolderIds() { // to support custom folders, return these names and any additional // directories here return Arrays.asList(new String[] { - "inbox", "conference", "deleted", "saved" + "inbox", "conference", "deleted", "saved", "recorder" }); } diff --git a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/DhcpConfigTest.java b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/DhcpConfigTest.java index 9168d48ef9..b24a891f53 100644 --- a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/DhcpConfigTest.java +++ b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/DhcpConfigTest.java @@ -38,10 +38,11 @@ public void config() throws IOException { AddressType t = new AddressType("t"); Address tftp = new Address(t, "tftp"); Address admin = new Address(t, "admin"); + Address staticHttp = new Address(t, "static"); List
dns = Arrays.asList(new Address(t, "dns1"), new Address(t, "dns2")); List
ntp = Arrays.asList(new Address(t, "ntp1"), new Address(t, "ntp2")); StringWriter actual = new StringWriter(); - config.writeConfig(actual, settings, tftp, admin, dns, ntp); + config.writeConfig(actual, settings, tftp, admin, staticHttp, dns, ntp); String expected = IOUtils.toString(getClass().getResourceAsStream("expected-dhcpd.conf")); assertEquals(expected, actual.toString()); } diff --git a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/expected-dhcpd.conf b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/expected-dhcpd.conf index 8ae8bbd14d..ce258c9a72 100644 --- a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/expected-dhcpd.conf +++ b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/dhcp/expected-dhcpd.conf @@ -7,7 +7,9 @@ default_lease_time: 43200 max_lease_time: 43200 plcm_https_provisioning: 0 bria_https_provisioning: 0 +snom_statichttp_provisioning: 0 tftp: tftp config: admin +statichttp: static:0 ntp: [ ntp1, ntp2 ] dns: [ dns1, dns2 ] diff --git a/sipXconfig/web/context/WEB-INF/cdr/CdrTable.html b/sipXconfig/web/context/WEB-INF/cdr/CdrTable.html index 11673587bc..a272b07599 100644 --- a/sipXconfig/web/context/WEB-INF/cdr/CdrTable.html +++ b/sipXconfig/web/context/WEB-INF/cdr/CdrTable.html @@ -7,6 +7,11 @@ + + + + + + + + diff --git a/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.jwc b/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.jwc index 58549ac810..027c17dd9f 100644 --- a/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.jwc +++ b/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.jwc @@ -11,7 +11,7 @@ - + diff --git a/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.properties b/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.properties index 5559a3b1f4..ab2d6b0d0d 100644 --- a/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.properties +++ b/sipXconfig/web/context/WEB-INF/gateway/GatewayTable.properties @@ -1,5 +1,6 @@ # 'name' and 'description' translations are in application bundle (sipXconfig-web.properties) address=Address +id=Id model=Model site=Location all=All \ No newline at end of file diff --git a/sipXconfig/web/context/WEB-INF/sipXconfig-web.properties b/sipXconfig/web/context/WEB-INF/sipXconfig-web.properties index d04816bf5b..d8cc90c06d 100644 --- a/sipXconfig/web/context/WEB-INF/sipXconfig-web.properties +++ b/sipXconfig/web/context/WEB-INF/sipXconfig-web.properties @@ -341,6 +341,7 @@ address.mwiHttpApi = MWI RESTful API address.mwiSipTcp = MWI SIP/TCP address.mwiSipUdp = MWI SIP/UDP address.natRtp = Media Relay/NAT RTP +address.natRpc = Media Relay/XML RPC address.openacdRestApi = Contact Center RESTful API address.openacdWebUI = Contact Center Agent Web UI address.openacdSecureWebUI = Contact Center Secure Agent Web UI @@ -376,6 +377,7 @@ address.parkUdp = Park SIP/UDP address.parkRtp = Park RTP address.smtp=SMTP address.apacheHttp = HTTP +address.apacheHttpStatic = HTTP_STATIC (Port 8090) address.apacheHttps = HTTPS address.sipxsqaQueue = Network Queue Pub/Sub address.sipxsqaControl = Network Queue Control diff --git a/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.html b/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.html index f007537e46..d0d38d7d97 100644 --- a/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.html +++ b/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.html @@ -4,7 +4,7 @@
diff --git a/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.properties b/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.properties index ac1809cba9..bf76e1c190 100644 --- a/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.properties +++ b/sipXconfig/web/context/WEB-INF/user_portal/UserPortalNavigation.properties @@ -1,8 +1,8 @@ #Created by JInto - www.guh-software.de #Thu Oct 05 17:46:56 CEST 2006 menu.about=About -menu.voicemail=Voicemail -menu.inbox=Inbox +menu.voicemail=Inbox +menu.inbox=Voicemail menu.distributionLists=Distribution Lists menu.callForwarding=Call Forwarding menu.changePin=Change PIN diff --git a/sipXconfig/web/context/WEB-INF/vm/ManageVoicemail.properties b/sipXconfig/web/context/WEB-INF/vm/ManageVoicemail.properties index 1191d53727..038e7dcb06 100644 --- a/sipXconfig/web/context/WEB-INF/vm/ManageVoicemail.properties +++ b/sipXconfig/web/context/WEB-INF/vm/ManageVoicemail.properties @@ -1,13 +1,14 @@ -title=Voicemail +title=Inbox subject=Subject from=From timestamp=Date duration=Duration play=Play -tab.inbox=Inbox +tab.inbox=Voicemail tab.conference=Conference tab.deleted=Trash tab.saved=Saved +tab.recorder=Recorder confirm.delete=Are you sure you want to delete the selected voicemail(s)? label.moveTo=Move to warning.noVoicemailPermissionNotice=You do not have permission to receive voicemail. diff --git a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceCommandsResource.java b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceCommandsResource.java index 0ede48e44f..0e5a4375d9 100644 --- a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceCommandsResource.java +++ b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceCommandsResource.java @@ -16,6 +16,10 @@ */ package org.sipfoundry.sipxconfig.rest; +import java.io.Serializable; +import com.thoughtworks.xstream.XStream; +import org.sipfoundry.sipxconfig.common.BeanWithId; + import org.apache.commons.lang.StringUtils; import org.restlet.Context; import org.restlet.data.MediaType; @@ -47,6 +51,7 @@ public void init(Context context, Request request, Response response) { String argumentList = (String) getRequest().getAttributes().get("command"); m_arguments = StringUtils.split(argumentList, '&'); getVariants().add(new Variant(MediaType.TEXT_ALL)); + getVariants().add(new Variant(MediaType.TEXT_XML)); } @Override @@ -80,6 +85,142 @@ public Representation represent(Variant variant) throws ResourceException { return new StringRepresentation(response); } + + @Override + public void storeRepresentation( Representation entity) throws ResourceException { + Conference conference = m_conferenceBridgeContext.findConferenceByName(m_confName); + if (conference == null) { + throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND, "conference not found"); + } + if (!(conference.hasOwner() && StringUtils.equals(conference.getOwner().getName(), getUser().getName())) && + !getUser().isAdmin()) { + throw new ResourceException(Status.CLIENT_ERROR_FORBIDDEN, "User is not owner of this conference "); + } + if (m_arguments == null || m_arguments.length == 0) { + throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "No conference command specified"); + } + if (entity == null) { + throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "No data defined"); + } + if (StringUtils.equals(m_arguments[0], "change")) { + ConferenceRepresentation conferenceRep = new ConferenceRepresentation(entity); + Representable confValue = conferenceRep.getObject(); + + conference.setEnabled(confValue.isEnabled()); + + if (StringUtils.isNotBlank(confValue.getName())) { + conference.setName(confValue.getName()); + } + if (StringUtils.isNotBlank(confValue.getDescription())) { + conference.setDescription(confValue.getDescription()); + } + if (StringUtils.isNotBlank(confValue.getExtension())) { + conference.setExtension(confValue.getExtension()); + } + if (StringUtils.isNotBlank(confValue.getParticipantAccessCode())) { + conference.setSettingValue(Conference.PARTICIPANT_CODE, + confValue.getParticipantAccessCode()); + } + if (StringUtils.isNotBlank(confValue.getOrganizerAccessCode())) { + conference.setSettingValue(Conference.ORGANIZER_CODE, + confValue.getOrganizerAccessCode()); + } + + if (StringUtils.isNotBlank(confValue.getMaxLegs())) { + conference.setSettingValue(Conference.MAX_LEGS, + confValue.getMaxLegs()); + } + m_conferenceBridgeContext.saveConference(conference); + getResponse().setStatus(Status.SUCCESS_OK, "changed done"); + } + } + + @SuppressWarnings("serial") + static class Representable implements Serializable { + @SuppressWarnings("unused") + private boolean m_enabled; + @SuppressWarnings("unused") + private String m_name; + @SuppressWarnings("unused") + private String m_description; + @SuppressWarnings("unused") + private String m_extension; + @SuppressWarnings("unused") + private String m_participantAccessCode; + @SuppressWarnings("unused") + private String m_organizerAccessCode; + @SuppressWarnings("unused") + private String m_maxLegs; + + public Representable(Conference conference) { + m_enabled = conference.isEnabled(); + m_name = conference.getName(); + m_description = conference.getDescription(); + m_extension = conference.getExtension(); + m_participantAccessCode = conference.getParticipantAccessCode(); + m_organizerAccessCode = conference.getOrganizerAccessCode(); + m_maxLegs = conference.getSettingValue(Conference.MAX_LEGS); + } + + public Boolean isEnabled() { + return m_enabled; + } + + public String getName() { + return m_name; + } + + public String getDescription() { + return m_description; + } + + public String getExtension() { + return m_extension; + } + + public String getParticipantAccessCode() { + return m_participantAccessCode; + } + + public String getOrganizerAccessCode() { + return m_organizerAccessCode; + } + + public String getMaxLegs() { + return m_maxLegs; + } + } + + + static class ConferenceRepresentation extends XStreamRepresentation { + private static final String ID = "m_id"; + private static final String ENABLED = "enabled"; + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String EXTENSION = "extension"; + private static final String PARTICIPANT_AC = "participantAccessCode"; + private static final String ORGANIZER_AC = "organizerAccessCode"; + private static final String MAX_LEGS = "maxLegs"; + + public ConferenceRepresentation(Representation representation) { + super(representation); + } + + @Override + protected void configureXStream(XStream xstream) { + xstream.omitField(BeanWithId.class, ID); + xstream.alias("conference", Representable.class); + xstream.aliasField(ENABLED, Representable.class, ENABLED); + xstream.aliasField(NAME, Representable.class, NAME); + xstream.aliasField(DESCRIPTION, Representable.class, DESCRIPTION); + xstream.aliasField(EXTENSION, Representable.class, EXTENSION); + xstream.aliasField(PARTICIPANT_AC, Representable.class, PARTICIPANT_AC); + xstream.aliasField(ORGANIZER_AC, Representable.class, ORGANIZER_AC); + xstream.aliasField(MAX_LEGS, Representable.class, MAX_LEGS); + xstream.omitField(Representable.class, ID); + } + } + @Required public void setConferenceBridgeContext(ConferenceBridgeContext conferenceBridgeContext) { m_conferenceBridgeContext = conferenceBridgeContext; @@ -93,4 +234,5 @@ public void setActiveConferenceContext(ActiveConferenceContext activeConferenceC public String[] getArguments() { return m_arguments; } + } diff --git a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceResource.java b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceResource.java index ee5a590b37..8ecc7f14c2 100644 --- a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceResource.java +++ b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/UserConferenceResource.java @@ -75,13 +75,22 @@ static class Representable implements Serializable { private String m_extension; @SuppressWarnings("unused") private String m_accessCode; - - public Representable(Conference conference) { + @SuppressWarnings("unused") + private String m_participantAccessCode; + @SuppressWarnings("unused") + private String m_organizerAccessCode; + @SuppressWarnings("unused") + private String m_maxLegs; + + public Representable(Conference conference) { m_enabled = conference.isEnabled(); m_name = conference.getName(); m_description = conference.getDescription(); m_extension = conference.getExtension(); m_accessCode = conference.getParticipantAccessCode(); + m_participantAccessCode = conference.getParticipantAccessCode(); + m_organizerAccessCode = conference.getOrganizerAccessCode(); + m_maxLegs = conference.getSettingValue(Conference.MAX_LEGS); } } @@ -91,6 +100,9 @@ static class ConferenceRepresentation extends XStreamRepresentation object) { super(mediaType, object); @@ -110,6 +122,9 @@ protected void configureXStream(XStream xstream) { xstream.aliasField(DESCRIPTION, Representable.class, DESCRIPTION); xstream.aliasField(EXTENSION, Representable.class, EXTENSION); xstream.aliasField("accessCode", Representable.class, "participantAccessCode"); + xstream.aliasField(PARTICIPANT_AC, Representable.class, PARTICIPANT_AC); + xstream.aliasField(ORGANIZER_AC, Representable.class, ORGANIZER_AC); + xstream.aliasField(MAX_LEGS, Representable.class, MAX_LEGS); xstream.omitField(Representable.class, ID); } } diff --git a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/rest.beans.xml b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/rest.beans.xml index aca9bbfedc..6ab009d202 100644 --- a/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/rest.beans.xml +++ b/sipXconfig/web/src/org/sipfoundry/sipxconfig/rest/rest.beans.xml @@ -191,7 +191,7 @@ - + @@ -199,7 +199,7 @@ - + diff --git a/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/ActiveCallsPanel.java b/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/ActiveCallsPanel.java index c4f2f9a17d..896d4f85c8 100644 --- a/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/ActiveCallsPanel.java +++ b/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/ActiveCallsPanel.java @@ -61,5 +61,4 @@ public List getSource() { } return activeCalls; } - } diff --git a/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/CdrTable.java b/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/CdrTable.java index 6a10bba495..bdac5a541d 100644 --- a/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/CdrTable.java +++ b/sipXconfig/web/src/org/sipfoundry/sipxconfig/site/cdr/CdrTable.java @@ -11,6 +11,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.Date; +import java.util.Calendar; +import java.text.SimpleDateFormat; import org.apache.tapestry.BaseComponent; import org.apache.tapestry.IAsset; @@ -21,6 +24,8 @@ import org.apache.tapestry.annotations.Parameter; import org.apache.tapestry.contrib.table.model.ITableColumn; import org.apache.tapestry.services.ExpressionEvaluator; +import org.sipfoundry.sipxconfig.feature.FeatureManager; +import org.sipfoundry.sipxconfig.feature.LocationFeature; import org.sipfoundry.sipxconfig.cdr.Cdr; import org.sipfoundry.sipxconfig.common.CoreContext; import org.sipfoundry.sipxconfig.common.SipUri; @@ -43,6 +48,8 @@ public abstract class CdrTable extends BaseComponent { private static final Pattern AOR_RE = Pattern.compile(AOR); private static final Pattern FULL_USER_RE = Pattern.compile("(?:\\w+ *)+ - (\\d+)"); + private static final String HOMER_LINK = "/webhomer/index.php?component=search&task=result&callid=%s&location[]=1&from_date=%s&to_date=%s"; + @InjectObject(value = "service:tapestry.ognl.ExpressionEvaluator") public abstract ExpressionEvaluator getExpressionEvaluator(); @@ -65,6 +72,9 @@ public ITableColumn getStartTimeColumn() { @InjectObject(value = "spring:coreContext") public abstract CoreContext getCoreContext(); + @InjectObject(value = "spring:featureManager") + public abstract FeatureManager getFeatureManager(); + @InjectState(value = "userSession") public abstract UserSession getUserSession(); @@ -107,6 +117,9 @@ public ITableColumn getStartTimeColumn() { @Asset("/images/retrievepark.png") public abstract IAsset getRetrieveParkIcon(); + @Asset("/images/go.png") + public abstract IAsset getLink(); + /** * Implements click to call link * @@ -129,6 +142,11 @@ public User getUser() { return getUserSession().getUser(getCoreContext()); } + public boolean isHomerEnabled() { + LocationFeature HomerWeb = new LocationFeature("homer_web"); + return getFeatureManager().isFeatureEnabled(HomerWeb); + } + public IAsset getRecipientTypeIcon() { IAsset recipientIcon = null; String rowCalleeRoute = null; @@ -223,4 +241,23 @@ public boolean isSelfCallCondition(String calleeOrCallerAor, String userUri) { } return false; } + + public String getHomerLink() { + String callid = getRow().getCallId(); + SimpleDateFormat ft = new SimpleDateFormat ("dd-MM-yyyy"); + Date start = getRow().getStartTime(); + Date end = getRow().getEndTime(); + Calendar cal = Calendar.getInstance(); + if(end!=null) + cal.setTime(end); + else { + end = new Date(); + cal.setTime(end); + } + cal.add(Calendar.DATE, 1); + end = cal.getTime(); + return String.format(HOMER_LINK, callid, + ft.format(start), + ft.format(end)); + } } diff --git a/sipXexample/config-plugin/Makefile.am b/sipXexample/config-plugin/Makefile.am index d9b5d58e39..d6ba0acdb2 100644 --- a/sipXexample/config-plugin/Makefile.am +++ b/sipXexample/config-plugin/Makefile.am @@ -20,6 +20,7 @@ example_RESOURCES = \ example_PKGS = \ sipxconfig-neoconf \ + sipxconfig-web \ tapestry-annotations \ tapestry-framework \ hivemind diff --git a/sipXexample/config-plugin/plugin/PluginTestPage.properties b/sipXexample/config-plugin/plugin/PluginTestPage.properties index 11d8a6d4f9..fc2dd1b452 100644 --- a/sipXexample/config-plugin/plugin/PluginTestPage.properties +++ b/sipXexample/config-plugin/plugin/PluginTestPage.properties @@ -5,3 +5,4 @@ test.serialno=Serial test No test.quick.help=This is a plugin page. Classes should go under org.sipfoundry.sipxconfig.web.plugin \ package, .html, .page and .properties files under /plugin msg.plugintest.hello = {0} you have {1} users in your system +title=Example \ No newline at end of file diff --git a/sipXexample/config-plugin/src/org/sipfoundry/sipxconfig/web/plugin/PluginTestPage.java b/sipXexample/config-plugin/src/org/sipfoundry/sipxconfig/web/plugin/PluginTestPage.java index b9a355aa4a..cdd61c76f8 100644 --- a/sipXexample/config-plugin/src/org/sipfoundry/sipxconfig/web/plugin/PluginTestPage.java +++ b/sipXexample/config-plugin/src/org/sipfoundry/sipxconfig/web/plugin/PluginTestPage.java @@ -7,13 +7,14 @@ package org.sipfoundry.sipxconfig.web.plugin; import org.apache.tapestry.annotations.InjectObject; +import org.sipfoundry.sipxconfig.components.SipxBasePage; import org.apache.tapestry.html.BasePage; import org.sipfoundry.Example; /** * Tapestry 4 page to do whatever you want. */ -public abstract class PluginTestPage extends BasePage { +public abstract class PluginTestPage extends SipxBasePage { /** * inject your service into the page to perform operations, read/write data, etc. Tapestry integration diff --git a/sipXimbot/src/org/sipfoundry/sipximbot/IMUser.java b/sipXimbot/src/org/sipfoundry/sipximbot/IMUser.java index 3dfd6fe54b..c00c81f0c9 100644 --- a/sipXimbot/src/org/sipfoundry/sipximbot/IMUser.java +++ b/sipXimbot/src/org/sipfoundry/sipximbot/IMUser.java @@ -680,8 +680,12 @@ private String doListen() { Socket socket = new Socket("localhost", 8021); + String uri = m_user.getIdentity(); + if ( !"".equals(m_user.getCellNum())){ + uri = m_user.getCellNum()+"@"+config.getSipxchangeDomainName(); + } if (fses.connect(socket, "ClueCon")) { - ListenIn listenIn = new ListenIn(fses, m_user.getIdentity(), + ListenIn listenIn = new ListenIn(fses, uri, uuid, config.getSipxchangeDomainName()); listenIn.go(); } diff --git a/sipXivr/src/org/sipfoundry/voicemail/Deposit.java b/sipXivr/src/org/sipfoundry/voicemail/Deposit.java index 57c7773112..59f0441705 100644 --- a/sipXivr/src/org/sipfoundry/voicemail/Deposit.java +++ b/sipXivr/src/org/sipfoundry/voicemail/Deposit.java @@ -71,8 +71,15 @@ public String runAction() { LOG.info("depositVoicemail Collected digits=" + digits); if (digits.equals("i")) { - play("please_hold", ""); - transfer(user.getUri(), true, true); + //play("please_hold", ""); + String uri = user.getUri(); + if ( !"".equals(user.getCellNum())){ + if ( uri.contains("sip:")) + uri = uri.replaceAll(":(.+)@", ":"+user.getCellNum()+"@"); + else + uri = uri.replaceAll("(.+)@", user.getCellNum()+"@"); + } + transfer(uri, true, true); return null; } @@ -121,8 +128,16 @@ public String runAction() { if (digit != null && digit.equals("i")) { tempMessage.setIsToBeStored(true); - play("please_hold", ""); - transfer(user.getUri(), true, true); + //play("please_hold", ""); + String uri = user.getUri(); + if ( !"".equals(user.getCellNum())){ + LOG.error(uri); + if ( uri.contains("sip:")) + uri = uri.replaceAll(":(.+)@", ":"+user.getCellNum()+"@"); + else + uri = uri.replaceAll("(.+)@", user.getCellNum()+"@"); + } + transfer(uri, true, true); return null; } diff --git a/sipXivr/src/org/sipfoundry/voicemail/MailboxServlet.java b/sipXivr/src/org/sipfoundry/voicemail/MailboxServlet.java index 7e27cbedee..876ad272be 100644 --- a/sipXivr/src/org/sipfoundry/voicemail/MailboxServlet.java +++ b/sipXivr/src/org/sipfoundry/voicemail/MailboxServlet.java @@ -226,11 +226,13 @@ public void doIt(HttpServletRequest request, HttpServletResponse response) throw pw.write("\n"); List inboxMessages = mailboxManager.getMessages(user.getUserName(), Folder.INBOX); List savedMessages = mailboxManager.getMessages(user.getUserName(), Folder.SAVED); + List recorderMessages = mailboxManager.getMessages(user.getUserName(), Folder.RECORDER); List deletedMessages = mailboxManager.getMessages(user.getUserName(), Folder.DELETED); listMessages(inboxMessages, "inbox", pw); listMessages(savedMessages, "saved", pw); listMessages(deletedMessages, "deleted", pw); + listMessages(recorderMessages, "recorder", pw); pw.write(""); } else { response.sendError(405); @@ -256,7 +258,28 @@ public void doIt(HttpServletRequest request, HttpServletResponse response) throw } else { response.sendError(405); } - } else if (context.equals("saved")) { + } else if (context.equals("recorder")) { + if (method.equals(METHOD_GET)) { + response.setContentType("text/xml"); + pw.write("\n"); + pw.write("\n"); + if (subDirs.length >= 4) { + String messageId = subDirs[3]; + try { + listFullMessage(mailboxManager.getVmMessage(user.getUserName(), Folder.RECORDER, + messageId, false), "recorder", pw); + } catch (MessageNotFoundException ex) { + response.sendError(404, "messageId not found"); + } + } else { + listFullMessages(mailboxManager.getMessages(user.getUserName(), Folder.RECORDER), "recorder", + pw); + } + pw.write(""); + } else { + response.sendError(405); + } + } else if (context.equals("saved")) { if (method.equals(METHOD_GET)) { response.setContentType("text/xml"); pw.write("\n"); diff --git a/sipXivr/src/org/sipfoundry/voicemail/mailbox/AbstractMailboxManager.java b/sipXivr/src/org/sipfoundry/voicemail/mailbox/AbstractMailboxManager.java index 2851148599..162372e45f 100644 --- a/sipXivr/src/org/sipfoundry/voicemail/mailbox/AbstractMailboxManager.java +++ b/sipXivr/src/org/sipfoundry/voicemail/mailbox/AbstractMailboxManager.java @@ -281,6 +281,9 @@ protected Folder getFolderFromName(String name) { if (Folder.CONFERENCE.toString().equals(name)) { return Folder.CONFERENCE; } + if (Folder.RECORDER.toString().equals(name)) { + return Folder.RECORDER; + } return null; } diff --git a/sipXivr/src/org/sipfoundry/voicemail/mailbox/FilesystemMailboxManager.java b/sipXivr/src/org/sipfoundry/voicemail/mailbox/FilesystemMailboxManager.java index 67eb105084..e36e8abf33 100644 --- a/sipXivr/src/org/sipfoundry/voicemail/mailbox/FilesystemMailboxManager.java +++ b/sipXivr/src/org/sipfoundry/voicemail/mailbox/FilesystemMailboxManager.java @@ -60,6 +60,7 @@ public MailboxDetails getMailboxDetails(String username) { List savedMessages = extractMessages(getFolder(username, Folder.SAVED).listFiles(filter)); List deletedMessages = extractMessages(getFolder(username, Folder.DELETED).listFiles(filter)); List conferenceMessages = extractMessages(getFolder(username, Folder.CONFERENCE).listFiles(filter)); + List recorderMessages = extractMessages(getFolder(username, Folder.RECORDER).listFiles(filter)); FilenameFilter unheardFilter = new RegexFileFilter(STATUS_REGEX); List unheardMessages = extractMessages(getFolder(username, Folder.INBOX).listFiles(unheardFilter)); @@ -266,7 +267,7 @@ public void deleteMessage(User user, VmMessage message) { for (File messageFile : messageFiles) { FileUtils.deleteQuietly(messageFile); } - } else if (messageFolder == Folder.INBOX || messageFolder == Folder.SAVED) { + } else if (messageFolder == Folder.INBOX || messageFolder == Folder.SAVED || messageFolder == Folder.RECORDER) { File deletedFolder = getFolder(message.getUserName(), Folder.DELETED); for (File file : messageFiles) { String fileName = file.getName(); @@ -502,6 +503,10 @@ private File[] findFilesInUserDirectory(String username, FilenameFilter filter) if (files != null) { return files; } + files = findFilesInFolder(getFolder(username, Folder.RECORDER), filter); + if (files != null) { + return files; + } throw new MessageNotFoundException(); } diff --git a/sipXivr/src/org/sipfoundry/voicemail/mailbox/Folder.java b/sipXivr/src/org/sipfoundry/voicemail/mailbox/Folder.java index b134241310..18cc9cf983 100644 --- a/sipXivr/src/org/sipfoundry/voicemail/mailbox/Folder.java +++ b/sipXivr/src/org/sipfoundry/voicemail/mailbox/Folder.java @@ -39,5 +39,11 @@ public String toString() { public String toString() { return "conference"; } + }, + + RECORDER { + public String toString() { + return "recorder"; + } } } \ No newline at end of file diff --git a/sipXportLib/src/test/os/OsSocketTest.cpp b/sipXportLib/src/test/os/OsSocketTest.cpp index be6de4e1ef..1de6c72b22 100644 --- a/sipXportLib/src/test/os/OsSocketTest.cpp +++ b/sipXportLib/src/test/os/OsSocketTest.cpp @@ -28,7 +28,16 @@ class SocketsTest : public CppUnit::TestCase CPPUNIT_TEST_SUITE_END(); + int m_port; + public: + + void setUp() { + int port = PORT_NONE; + OsServerSocket s(50); + m_port = s.getLocalHostPort(); + s.close(); + } /** * Test accept with various timeouts @@ -38,7 +47,7 @@ class SocketsTest : public CppUnit::TestCase OsTime before; OsTime after; - OsServerSocket* server = new OsServerSocket(50, 8021); + OsServerSocket* server = new OsServerSocket(50, m_port); OsDateTime::getCurTime(before); OsSocket* serverClient = server->accept(50); @@ -88,12 +97,11 @@ class SocketsTest : public CppUnit::TestCase void testWriteAndAcceptMsg() { // Create/Verify Sockets - OsServerSocket* server = new OsServerSocket(50, 8021); - KNOWN_BUG("This can fail if there is a port conflict on the test system", "XECS-1924"); + OsServerSocket* server = new OsServerSocket(50, m_port); CPPUNIT_ASSERT_MESSAGE("server socket failure", server->isOk()); - OsSocket* client = new OsConnectionSocket(8021, "localhost"); + OsSocket* client = new OsConnectionSocket(m_port, "localhost"); CPPUNIT_ASSERT_MESSAGE("client socket failure", client->isOk()); diff --git a/sipXproxy/lib/authplugins/CallDestination.cpp b/sipXproxy/lib/authplugins/CallDestination.cpp index a0272f6262..76983cb98f 100755 --- a/sipXproxy/lib/authplugins/CallDestination.cpp +++ b/sipXproxy/lib/authplugins/CallDestination.cpp @@ -103,7 +103,8 @@ CallDestination::moveCallDestToRecordRoute( SipMessage& request ) // Parameter doesn't exist. Add it. recordrouteUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, headercalldest.data()); } - request.setRecordRouteField(recordrouteUri.toString().data(), 0); + if (recordrouteUri.isValid()) + request.setRecordRouteField(recordrouteUri.toString().data(), 0); bRemoved = true; } return bRemoved; diff --git a/sipXproxy/src/CallStateEventBuilder.cpp b/sipXproxy/src/CallStateEventBuilder.cpp index 622b4915c0..c1b1d488ee 100755 --- a/sipXproxy/src/CallStateEventBuilder.cpp +++ b/sipXproxy/src/CallStateEventBuilder.cpp @@ -178,6 +178,7 @@ void CallStateEventBuilder::observerEvent(int sequenceNumber, ///< for ObserverR */ void CallStateEventBuilder::callRequestEvent(int sequenceNumber, const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, const UtlString& contact, const UtlString& references, const UtlString& branch_id, diff --git a/sipXproxy/src/CallStateEventBuilder.h b/sipXproxy/src/CallStateEventBuilder.h index 3d6a44120c..d928940d52 100755 --- a/sipXproxy/src/CallStateEventBuilder.h +++ b/sipXproxy/src/CallStateEventBuilder.h @@ -79,6 +79,7 @@ class CallStateEventBuilder */ virtual void callRequestEvent(int sequenceNumber, const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, const UtlString& contact, const UtlString& references, const UtlString& branch_id, diff --git a/sipXproxy/src/CallStateEventBuilder_DB.cpp b/sipXproxy/src/CallStateEventBuilder_DB.cpp index 3f02466c32..0ddc23c6b0 100755 --- a/sipXproxy/src/CallStateEventBuilder_DB.cpp +++ b/sipXproxy/src/CallStateEventBuilder_DB.cpp @@ -139,13 +139,14 @@ void CallStateEventBuilder_DB::observerEvent(int sequenceNumber, ///< for Observ * - completeCallEvent */ void CallStateEventBuilder_DB::callRequestEvent(int sequenceNumber, - const OsTime& timestamp, ///< obtain using getCurTime(OsTime) - const UtlString& contact, - const UtlString& references, - const UtlString& branch_id, - int via_count, - const bool callerInternal - ) + const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, + const UtlString& contact, + const UtlString& references, + const UtlString& branch_id, + int via_count, + const bool callerInternal + ) { if (builderStateIsOk(CallRequestEvent)) { @@ -170,6 +171,10 @@ void CallStateEventBuilder_DB::callRequestEvent(int sequenceNumber, replaceSingleQuotes(branch_id, nbranchId); mBranchId = "\'" + nbranchId + "\',"; + UtlString nrequestUri; + replaceSingleQuotes(requestUri, nrequestUri); + mRequestUri = "\'" + nrequestUri + "\',"; + char buffer[10]; snprintf(buffer, 10, "%d", via_count); mViaCount = buffer; @@ -193,11 +198,11 @@ void CallStateEventBuilder_DB::callRequestEvent(int sequenceNumber, * - completeCallEvent */ void CallStateEventBuilder_DB::callSetupEvent(int sequenceNumber, - const OsTime& timestamp, ///< obtain using getCurTime(OsTime) - const UtlString& contact, - const UtlString& calleeRoute, - const UtlString& branch_id, - int via_count + const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& contact, + const UtlString& calleeRoute, + const UtlString& branch_id, + int via_count ) { if (builderStateIsOk(CallSetupEvent)) diff --git a/sipXproxy/src/CallStateEventBuilder_DB.h b/sipXproxy/src/CallStateEventBuilder_DB.h index e1a405c547..db65b08d00 100755 --- a/sipXproxy/src/CallStateEventBuilder_DB.h +++ b/sipXproxy/src/CallStateEventBuilder_DB.h @@ -55,6 +55,7 @@ class CallStateEventBuilder_DB : public CallStateEventBuilder /// Begin a Call Request Event - an INVITE without a to tag has been observed void callRequestEvent(int sequenceNumber, const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, const UtlString& contact, const UtlString& references, const UtlString& branch_id, diff --git a/sipXproxy/src/CallStateEventBuilder_XML.cpp b/sipXproxy/src/CallStateEventBuilder_XML.cpp index c6ab270de4..db5d1cb9db 100755 --- a/sipXproxy/src/CallStateEventBuilder_XML.cpp +++ b/sipXproxy/src/CallStateEventBuilder_XML.cpp @@ -244,6 +244,7 @@ void CallStateEventBuilder_XML::observerEvent(int sequenceNumber, ///< for Obser */ void CallStateEventBuilder_XML::callRequestEvent(int sequenceNumber, const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, const UtlString& contact, const UtlString& references, const UtlString& branch_id, diff --git a/sipXproxy/src/CallStateEventBuilder_XML.h b/sipXproxy/src/CallStateEventBuilder_XML.h index 3d2f557a61..5925fe98e1 100755 --- a/sipXproxy/src/CallStateEventBuilder_XML.h +++ b/sipXproxy/src/CallStateEventBuilder_XML.h @@ -55,6 +55,7 @@ class CallStateEventBuilder_XML : public CallStateEventBuilder /// Begin a Call Request Event - an INVITE without a to tag has been observed void callRequestEvent(int sequenceNumber, const OsTime& timestamp, ///< obtain using getCurTime(OsTime) + const UtlString& requestUri, const UtlString& contact, const UtlString& references, const UtlString& branch_id, diff --git a/sipXproxy/src/SipXProxyCseObserver.cpp b/sipXproxy/src/SipXProxyCseObserver.cpp index 717d3bab9f..a92fe18748 100755 --- a/sipXproxy/src/SipXProxyCseObserver.cpp +++ b/sipXproxy/src/SipXProxyCseObserver.cpp @@ -541,8 +541,10 @@ UtlBoolean SipXProxyCseObserver::handleMessage(OsMsg& eventMessage) callIdBranchIdTime->setPaiPresent(&paiPresent); } else { - mCallTransMutex.release(); - return(TRUE); + if ( not requestUri.contains("sipxecs-lineid") ) { + mCallTransMutex.release(); + return(TRUE); + } } } else { @@ -552,7 +554,8 @@ UtlBoolean SipXProxyCseObserver::handleMessage(OsMsg& eventMessage) } mCallTransMutex.release(); } - mpBuilder->callRequestEvent(mSequenceNumber, timeNow, contact, references, branchId, viaCount, paiPresent); + + mpBuilder->callRequestEvent(mSequenceNumber, timeNow, requestUri, contact, references, branchId, viaCount, paiPresent); break; case aCallSetup: @@ -570,7 +573,7 @@ UtlBoolean SipXProxyCseObserver::handleMessage(OsMsg& eventMessage) { // CallId/BranchId are either not found or doesn't match. Not a final response. mCallTransMutex.release(); - return(TRUE); + //return(TRUE); } for (int rrNum = 0; (!routeFound && sipMsg->getRecordRouteUri(rrNum, &recordRoute)); diff --git a/sipXproxy/src/sipXproxymain.cpp b/sipXproxy/src/sipXproxymain.cpp index aaa33236d9..90912807ee 100755 --- a/sipXproxy/src/sipXproxymain.cpp +++ b/sipXproxy/src/sipXproxymain.cpp @@ -221,6 +221,8 @@ int proxy() int proxyTcpPort; int proxyUdpPort; int proxyTlsPort; + int proxyUdpResend; + int proxyTcpResend; UtlString bindIp; int maxForwards; UtlString domainName; @@ -282,6 +284,18 @@ int proxy() proxyTlsPort = 5061; } Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_TLS_PORT : %d", proxyTlsPort); + proxyUdpResend = configDb.getPort("SIPX_PROXY_UDP_RESEND") ; + if (proxyUdpResend<0) + { + proxyUdpResend = 4; + } + Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_UDP_RESEND : %d", proxyUdpResend); + proxyTcpResend = configDb.getPort("SIPX_PROXY_TCP_RESEND") ; + if (proxyTcpResend<0) + { + proxyTcpResend = 4; + } + Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_TCP_RESEND : %d", proxyTcpResend); configDb.get("SIPX_PROXY_MAX_FORWARDS", maxForwards); if(maxForwards <= 0) maxForwards = SIP_DEFAULT_MAX_FORWARDS; @@ -610,7 +624,9 @@ int proxy() FALSE, // Use Next Available Port TRUE, // Perform message checks TRUE, // Use symmetric signaling - SipUserAgent::HANDLE_OPTIONS_AUTOMATICALLY); + SipUserAgent::HANDLE_OPTIONS_AUTOMATICALLY, + proxyUdpResend, // we need to get this from config + proxyTcpResend); // this one too if (!pSipUserAgent->isOk()) diff --git a/sipXsnom/etc/snom/line.xml b/sipXsnom/etc/snom/line.xml index 422bc811cb..967ec52a9c 100644 --- a/sipXsnom/etc/snom/line.xml +++ b/sipXsnom/etc/snom/line.xml @@ -63,6 +63,7 @@ + user_ringer$ Ringer1 @@ -232,7 +233,7 @@ - off + on diff --git a/sipXsnom/etc/snom/phone.properties b/sipXsnom/etc/snom/phone.properties index 134d797a63..df9dd1f116 100644 --- a/sipXsnom/etc/snom/phone.properties +++ b/sipXsnom/etc/snom/phone.properties @@ -730,6 +730,9 @@ Ringer_Settings.alert_info_playback.label=Alert Info Playback Ringer_Settings.alert_info_playback.description=If enabled, the phone replays audio system messages and shows \ them on the display. +Ringer_settings.alert_external_ring_sound.label=External Ring Sound +Ringer_Settings.alert_external_ring_sound.description=Generic extarnal calls ringer. Selection of the ring tone style that signals incoming external calls + Action_URLs.label=Action URL Action_URLs.description=An Action URL triggers external URL in response to various events. \ For instance, on an incoming call, the "Incoming Call" URL is triggered. diff --git a/sipXsnom/etc/snom/phone.xml b/sipXsnom/etc/snom/phone.xml index a2fd9bfb5c..95d27b01bf 100644 --- a/sipXsnom/etc/snom/phone.xml +++ b/sipXsnom/etc/snom/phone.xml @@ -298,7 +298,7 @@ use_backlight$ - on + off @@ -1387,6 +1387,10 @@ Ringer1 + + + Ringer1 + diff --git a/sipXsnom/etc/snom/snom-7_3_X.vm b/sipXsnom/etc/snom/snom-7_3_X.vm new file mode 100644 index 0000000000..73fc6ffbaf --- /dev/null +++ b/sipXsnom/etc/snom/snom-7_3_X.vm @@ -0,0 +1,115 @@ +## calculates setting permission based on its name +#macro( perm $setting ) +#set ($pn = $!{setting.ProfileName}) +#if ($pn.endsWith('$')) +perm="RW"#elseif ($pn.endsWith('!')) +perm="!"#else +perm="R"#end +#end + + + + + +#foreach ($group in $phone.Settings.Values) +#if ($group.Name != 'fkeys') +#foreach ($setting in $group.Values) + <${setting.name} #perm( $setting )>$!{setting.Value} +#end +#end +#end + on +#set ($supported_models = ["Snom 320", "Snom 360", "Snom 370"]) +#set ($pr_usr = "") +#foreach ($line in $phone.ProfileLines) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) +#if ($pr_usr == "" && $setting.name == "user_name") +#set ($pr_usr = $setting.Value) +#end +#end +#end +#end +#foreach ($model in $supported_models) +#if ($phone.Model.Label == $model && $pr_usr != "") + recorder ~~pr~$pr_usr +#end +#end + speed 101 + + +#foreach ($number in $speedDial) +#set ($i = $velocityCount - 1) + $number +#end + +#foreach ($line in $phone.ProfileLines) +#set ($i = $velocityCount) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) + <${setting.name} idx="${i}" #perm( $setting )>$!{setting.Value} +#end +#end +#end + + + + +#foreach ($entry in $phoneBook) +#set ($i = $velocityCount - 1) +#set ($fullName = "$!{entry.FirstName} $!{entry.LastName}") +#set ($fullName = $fullName.trim()) + + $esc.xml($!fullName) + $!{entry.Number} + + +#end + + + + +#foreach ($key in $phone.Settings.getSetting('fkeys').Values) +#set ($number = "") +#set ($context = $key.getSetting('context').Value) +#set ($type = $key.getSetting('type').Value) +#set ($number = $key.getSetting('number').Value) +#set ($i = $velocityCount - 1) +#if ($phone.Model.Label=="Snom 300" && $i>=2 && $i<=4 && $number=="" && $context=="active" && $type=="line" ) +#set ($context = "active") +#set ($type = "keyevent") +#if ($i==2) +#set ($number = "F_REDIAL") +#end +#if ($i==3) +#set ($number = "F_ADR_BOOK") +#end +#if ($i==4) +#set ($number = "F_TRANSFER") +#end +#if ($i==5) +#set ($number = "F_MUTE") +#end +#end +#set ($fkeyValue = "$!type $!number") +#set ($fkeyValue = $fkeyValue.trim()) + $!fkeyValue +#end + + +#set ($ip = $phone.PhoneContext.PhoneDefaults.TftpServer) + + +#foreach ($file in $webLang) + +#end + + + + +#foreach ($file in $guiLang) + +#end + + + diff --git a/sipXsnom/etc/snom/snom-8_4_X.vm b/sipXsnom/etc/snom/snom-8_4_X.vm new file mode 100644 index 0000000000..f755d0cb69 --- /dev/null +++ b/sipXsnom/etc/snom/snom-8_4_X.vm @@ -0,0 +1,116 @@ +## calculates setting permission based on its name +#macro( perm $setting ) +#set ($pn = $!{setting.ProfileName}) +#if ($pn.endsWith('$')) +perm="RW"#elseif ($pn.endsWith('!')) +perm="!"#else +perm="R"#end +#end + + + + + +#foreach ($group in $phone.Settings.Values) +#if ($group.Name != 'fkeys') +#foreach ($setting in $group.Values) + <${setting.name} #perm( $setting )>$!{setting.Value} +#end +#end +#end + on +#set ($supported_models = ["Snom 320", "Snom 360", "Snom 370"]) +#set ($pr_usr = "") +#foreach ($line in $phone.ProfileLines) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) +#if ($pr_usr == "" && $setting.name == "user_name") +#set ($pr_usr = $setting.Value) +#end +#end +#end +#end +#foreach ($model in $supported_models) +#if ($phone.Model.Label == $model && $pr_usr != "") + recorder ~~pr~$pr_usr +#end +#end + + speed 101 + + +#foreach ($number in $speedDial) +#set ($i = $velocityCount - 1) + $number +#end + +#foreach ($line in $phone.ProfileLines) +#set ($i = $velocityCount) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) + <${setting.name} idx="${i}" #perm( $setting )>$!{setting.Value} +#end +#end +#end + + + + +#foreach ($entry in $phoneBook) +#set ($i = $velocityCount - 1) +#set ($fullName = "$!{entry.FirstName} $!{entry.LastName}") +#set ($fullName = $fullName.trim()) + + $esc.xml($!fullName) + $!{entry.Number} + + +#end + + + + +#foreach ($key in $phone.Settings.getSetting('fkeys').Values) +#set ($number = "") +#set ($context = $key.getSetting('context').Value) +#set ($type = $key.getSetting('type').Value) +#set ($number = $key.getSetting('number').Value) +#set ($i = $velocityCount - 1) +#if ($phone.Model.Label=="Snom 300" && $i>=2 && $i<=4 && $number=="" && $context=="active" && $type=="line" ) +#set ($context = "active") +#set ($type = "keyevent") +#if ($i==2) +#set ($number = "F_REDIAL") +#end +#if ($i==3) +#set ($number = "F_ADR_BOOK") +#end +#if ($i==4) +#set ($number = "F_TRANSFER") +#end +#if ($i==5) +#set ($number = "F_MUTE") +#end +#end +#set ($fkeyValue = "$!type $!number") +#set ($fkeyValue = $fkeyValue.trim()) + $!fkeyValue +#end + + +#set ($ip = $phone.PhoneContext.PhoneDefaults.TftpServer) + + +#foreach ($file in $webLang) + +#end + + + + +#foreach ($file in $guiLang) + +#end + + + diff --git a/sipXsnom/etc/snom/snom-8_7_X.vm b/sipXsnom/etc/snom/snom-8_7_X.vm new file mode 100644 index 0000000000..349c8b8479 --- /dev/null +++ b/sipXsnom/etc/snom/snom-8_7_X.vm @@ -0,0 +1,115 @@ +## calculates setting permission based on its name +#macro( perm $setting ) +#set ($pn = $!{setting.ProfileName}) +#if ($pn.endsWith('$')) +perm="RW"#elseif ($pn.endsWith('!')) +perm="!"#else +perm="R"#end +#end + + + + + +#foreach ($group in $phone.Settings.Values) +#if ($group.Name != 'fkeys') +#foreach ($setting in $group.Values) + <${setting.name} #perm( $setting )>$!{setting.Value} +#end +#end +#end + on +#set ($supported_models = ["Snom 320", "Snom 360", "Snom 370"]) +#set ($pr_usr = "") +#foreach ($line in $phone.ProfileLines) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) +#if ($pr_usr == "" && $setting.name == "user_name") +#set ($pr_usr = $setting.Value) +#end +#end +#end +#end +#foreach ($model in $supported_models) +#if ($phone.Model.Label == $model && $pr_usr != "") + recorder ~~pr~$pr_usr +#end +#end + speed 101 + + +#foreach ($number in $speedDial) +#set ($i = $velocityCount - 1) + $number +#end + +#foreach ($line in $phone.ProfileLines) +#set ($i = $velocityCount) +#foreach ($group in $line.Values) +#foreach ($setting in $group.Values) + <${setting.name} idx="${i}" #perm( $setting )>$!{setting.Value} +#end +#end +#end + + + + +#foreach ($entry in $phoneBook) +#set ($i = $velocityCount - 1) +#set ($fullName = "$!{entry.FirstName} $!{entry.LastName}") +#set ($fullName = $fullName.trim()) + + $esc.xml($!fullName) + $!{entry.Number} + + +#end + + + + +#foreach ($key in $phone.Settings.getSetting('fkeys').Values) +#set ($number = "") +#set ($context = $key.getSetting('context').Value) +#set ($type = $key.getSetting('type').Value) +#set ($number = $key.getSetting('number').Value) +#set ($i = $velocityCount - 1) +#if ($phone.Model.Label=="Snom 300" && $i>=2 && $i<=4 && $number=="" && $context=="active" && $type=="line" ) +#set ($context = "active") +#set ($type = "keyevent") +#if ($i==2) +#set ($number = "F_REDIAL") +#end +#if ($i==3) +#set ($number = "F_ADR_BOOK") +#end +#if ($i==4) +#set ($number = "F_TRANSFER") +#end +#if ($i==5) +#set ($number = "F_MUTE") +#end +#end +#set ($fkeyValue = "$!type $!number") +#set ($fkeyValue = $fkeyValue.trim()) + $!fkeyValue +#end + + +#set ($ip = $phone.PhoneContext.PhoneDefaults.TftpServer) + + +#foreach ($file in $webLang) + +#end + + + + +#foreach ($file in $guiLang) + +#end + + + diff --git a/sipXsnom/etc/snom/snom.vm b/sipXsnom/etc/snom/snom.vm index ee44341197..0d46e7ebb8 100644 --- a/sipXsnom/etc/snom/snom.vm +++ b/sipXsnom/etc/snom/snom.vm @@ -18,6 +18,7 @@ perm="R"#end #end #end #end + on speed 101 @@ -30,7 +31,7 @@ perm="R"#end #set ($i = $velocityCount) #foreach ($group in $line.Values) #foreach ($setting in $group.Values) - <${setting.ProfileName} idx="${i}" #perm( $setting )>$!{setting.Value} + <${setting.name} idx="${i}" #perm( $setting )>$!{setting.Value} #end #end #end @@ -40,7 +41,7 @@ perm="R"#end #foreach ($entry in $phoneBook) #set ($i = $velocityCount - 1) -#set ($fullName = "$!{entry.FirstName} $!{entry.LastName}") +#set ($fullName = "$!{entry.LastName} $!{entry.FirstName}") #set ($fullName = $fullName.trim()) $esc.xml($!fullName) @@ -57,10 +58,42 @@ perm="R"#end #set ($context = $key.getSetting('context').Value) #set ($type = $key.getSetting('type').Value) #set ($number = $key.getSetting('number').Value) +#set ($i = $velocityCount - 1) +#if ($phone.Model.Label=="Snom 300" && $i>=2 && $i<=4 && $number=="" && $context=="active" && $type=="line" ) +#set ($context = "active") +#set ($type = "keyevent") +#if ($i==2) +#set ($number = "F_REDIAL") +#end +#if ($i==3) +#set ($number = "F_ADR_BOOK") +#end +#if ($i==4) +#set ($number = "F_TRANSFER") +#end +#if ($i==5) +#set ($number = "F_MUTE") +#end +#end #set ($fkeyValue = "$!type $!number") #set ($fkeyValue = $fkeyValue.trim()) -#set ($i = $velocityCount - 1) $!fkeyValue #end + +#set ($ip = $phone.PhoneContext.PhoneDefaults.TftpServer) + + +#foreach ($file in $webLang) + +#end + + + + +#foreach ($file in $guiLang) + +#end + + diff --git a/sipXsnom/etc/snom/types.xml b/sipXsnom/etc/snom/types.xml index 1c7725e1ec..e1fe53871d 100644 --- a/sipXsnom/etc/snom/types.xml +++ b/sipXsnom/etc/snom/types.xml @@ -282,3 +282,11 @@ + + + + + + + + diff --git a/sipXsnom/etc/snom/upload.xml b/sipXsnom/etc/snom/upload.xml new file mode 100644 index 0000000000..b638a5589e --- /dev/null +++ b/sipXsnom/etc/snom/upload.xml @@ -0,0 +1,76 @@ + + + + + + application/zip + + + + + application/binary + + + + + + + application/xml + + + + + + + + + + + Web + + + + + + + + + + + + + + + + + + + + + + + + + Italiano + + + + + + + + + + 7.3.X + + + + diff --git a/sipXsnom/src/common.am b/sipXsnom/src/common.am index 5a02d02470..9bcdd2a2a3 100644 --- a/sipXsnom/src/common.am +++ b/sipXsnom/src/common.am @@ -3,6 +3,7 @@ snom_PKGS = \ commons-lang \ commons-io \ commons-collections \ + commons-logging \ org.springframework.beans \ sipxcommons \ sipxconfig-neoconf \ diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/LangUploadListener.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/LangUploadListener.java new file mode 100644 index 0000000000..921bb24a7f --- /dev/null +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/LangUploadListener.java @@ -0,0 +1,33 @@ +/* + * + * + * Copyright (C) 2007 Sip2ser Srl., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + */ +package org.sipfoundry.sipxconfig.phone.snom; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sipfoundry.sipxconfig.common.event.DaoEventListener; +import org.sipfoundry.sipxconfig.phone.PhoneContext; + + +public class LangUploadListener implements DaoEventListener { + private static final Log LOG = LogFactory.getLog(LangUploadListener.class); + private static final String GROUP_LANG_VERSION = "group.version/localization.version"; + private PhoneContext m_phoneContext; + + public void setPhoneContext(PhoneContext phoneContext) { + m_phoneContext = phoneContext; + } + + @Override + public void onDelete(Object entity) { + } + + @Override + public void onSave(Object entity) { + } +} diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomLanguageFile.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomLanguageFile.java new file mode 100644 index 0000000000..186f6d4e53 --- /dev/null +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomLanguageFile.java @@ -0,0 +1,52 @@ +/* + * + * + * Copyright (C) 2013 Pingtel Corp., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + */ + +package org.sipfoundry.sipxconfig.phone.snom; + +public class SnomLanguageFile { + private String m_type; + private String m_fileName; + private String m_langCode; + private String m_version; + + public SnomLanguageFile(String type, String file, String lang, String version) { + m_type = type; + m_fileName = file; + m_langCode = lang; + m_version = version; + } + + public void setType(String type) { + m_type = type; + } + public String getType() { + return m_type; + } + + public void setFileName(String file) { + m_fileName = file; + } + public String getFileName() { + return m_fileName; + } + + public void setLangCode(String lang) { + m_langCode = lang; + } + public String getLangCode() { + return m_langCode; + } + + public void setVersion(String version) { + m_version = version; + } + public String getVersion() { + return m_version; + } +} diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomModel.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomModel.java new file mode 100644 index 0000000000..5fa51288a7 --- /dev/null +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomModel.java @@ -0,0 +1,36 @@ +/* + * + * + * Copyright (C) 2013 Sip2ser Srl., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + */ + +package org.sipfoundry.sipxconfig.phone.snom; + +import org.sipfoundry.sipxconfig.device.DeviceVersion; +import org.sipfoundry.sipxconfig.phone.PhoneModel; + + +public final class SnomModel extends PhoneModel { + + public static final DeviceVersion VER_7_3_X = new DeviceVersion(SnomPhone.BEAN_ID, "7.3.X"); + public static final DeviceVersion VER_8_4_X = new DeviceVersion(SnomPhone.BEAN_ID, "8.4.X"); + public static final DeviceVersion VER_8_7_X = new DeviceVersion(SnomPhone.BEAN_ID, "8.7.X"); + public static final DeviceVersion[] SUPPORTED_VERSIONS = new DeviceVersion[]{VER_7_3_X, VER_8_4_X, VER_8_7_X}; + + public SnomModel() { + super(SnomPhone.BEAN_ID); + setEmergencyConfigurable(true); + } + + public static DeviceVersion getPhoneDeviceVersion(String version) { + for (DeviceVersion deviceVersion : SUPPORTED_VERSIONS) { + if (deviceVersion.getName().contains(version)) { + return deviceVersion; + } + } + return VER_7_3_X; + } +} diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomPhone.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomPhone.java index cf69458441..fb7fbe68b8 100644 --- a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomPhone.java +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomPhone.java @@ -13,6 +13,7 @@ import java.util.Iterator; import java.util.List; +import org.sipfoundry.sipxconfig.upload.UploadManager; import org.sipfoundry.sipxconfig.device.ProfileContext; import org.sipfoundry.sipxconfig.phone.Line; import org.sipfoundry.sipxconfig.phone.LineInfo; @@ -27,6 +28,7 @@ public class SnomPhone extends Phone { public static final String BEAN_ID = "snom"; private SpeedDialManager m_speedDialManager; + private UploadManager m_uploadManager; public SnomPhone() { } @@ -36,6 +38,10 @@ public void setSpeedDialManager(SpeedDialManager speedDialManager) { m_speedDialManager = speedDialManager; } + public void setUploadManager(UploadManager uploadManager) { + m_uploadManager = uploadManager; + } + @Override public void initialize() { SnomDefaults defaults = new SnomDefaults(getPhoneContext().getPhoneDefaults(), this); @@ -57,7 +63,20 @@ public void initializeLine(Line line) { protected ProfileContext createContext() { SpeedDial speedDial = getPhoneContext().getSpeedDial(this); Collection phoneBook = getPhoneContext().getPhonebookEntries(this); - return new SnomProfileContext(this, speedDial, phoneBook, getModel().getProfileTemplate()); + if (getDeviceVersion() == SnomModel.VER_7_3_X) { + return new SnomProfileContext(this, speedDial, phoneBook, "snom/snom-7_3_X.vm", + m_uploadManager); + } + if (getDeviceVersion() == SnomModel.VER_8_4_X) { + return new SnomProfileContext(this, speedDial, phoneBook, "snom/snom-8_4_X.vm", + m_uploadManager); + } + if (getDeviceVersion() == SnomModel.VER_8_7_X) { + return new SnomProfileContext(this, speedDial, phoneBook, "snom/snom-8_7_X.vm", + m_uploadManager); + } + return new SnomProfileContext(this, speedDial, phoneBook, getModel().getProfileTemplate(), + m_uploadManager); } @Override diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomProfileContext.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomProfileContext.java index dacb592ec6..7d3bb6ca59 100644 --- a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomProfileContext.java +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomProfileContext.java @@ -12,11 +12,15 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.ArrayList; import java.util.Map; +import org.sipfoundry.sipxconfig.upload.UploadManager; +import org.sipfoundry.sipxconfig.upload.Upload; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; import org.apache.velocity.tools.generic.EscapeTool; import org.sipfoundry.sipxconfig.device.ProfileContext; import org.sipfoundry.sipxconfig.phonebook.PhonebookEntry; @@ -27,15 +31,21 @@ public class SnomProfileContext extends ProfileContext { private static final int PHONEBOOK_MAX = 100; private static final int SPEEDDIAL_MAX = 33; - + private static final String SNOM_FILE_TYPE = "snomLanguage"; + private static final String SNOM_CONTEXT_LABEL = "localization/context"; + private static final String SNOM_FILE_LABEL = "localization/file"; + private static final String SNOM_LANGUAGE_LABEL = "localization/language"; + private static final String SNOM_VERSION_LABEL = "localization/version"; private final SpeedDial m_speedDial; private final Collection m_phoneBook; + private UploadManager m_uploadManager; public SnomProfileContext(SnomPhone device, SpeedDial speedDial, Collection phoneBook, - String profileTemplate) { + String profileTemplate, UploadManager uploadManager) { super(device, profileTemplate); m_speedDial = speedDial; m_phoneBook = trim(phoneBook); + m_uploadManager = uploadManager; } @Override @@ -43,6 +53,8 @@ public Map getContext() { Map context = super.getContext(); context.put("speedDial", getNumbers()); context.put("phoneBook", m_phoneBook); + context.put("webLang", getWebLangFiles()); + context.put("guiLang", getGuiLangFiles()); context.put("esc", new EscapeTool()); return context; } @@ -82,4 +94,40 @@ String[] getNumbers() { } return numbers; } + + /** + * Create SNOM localization file url + * + */ + SnomLanguageFile[] getWebLangFiles() { + List files = new ArrayList(); + if (m_uploadManager != null) { + for (Upload upload : m_uploadManager.getUpload()) { + if (upload.isDeployed() && StringUtils.equals(upload.getSpecificationId(), SNOM_FILE_TYPE) + && StringUtils.equals(upload.getSettingValue(SNOM_CONTEXT_LABEL), "Web")) { + files.add(new SnomLanguageFile(upload.getSettingValue(SNOM_CONTEXT_LABEL), + upload.getSettingValue(SNOM_FILE_LABEL), + upload.getSettingValue(SNOM_LANGUAGE_LABEL), + upload.getSettingValue(SNOM_VERSION_LABEL))); + } + } + } + return (SnomLanguageFile[]) files.toArray(new SnomLanguageFile[files.size()]); + } + + SnomLanguageFile[] getGuiLangFiles() { + List files = new ArrayList(); + if (m_uploadManager != null) { + for (Upload upload : m_uploadManager.getUpload()) { + if (upload.isDeployed() && StringUtils.equals(upload.getSpecificationId(), SNOM_FILE_TYPE) + && StringUtils.equals(upload.getSettingValue(SNOM_CONTEXT_LABEL), "Gui")) { + files.add(new SnomLanguageFile(upload.getSettingValue(SNOM_CONTEXT_LABEL), + upload.getSettingValue(SNOM_FILE_LABEL), + upload.getSettingValue(SNOM_LANGUAGE_LABEL), + upload.getSettingValue(SNOM_VERSION_LABEL))); + } + } + } + return (SnomLanguageFile[]) files.toArray(new SnomLanguageFile[files.size()]); + } } diff --git a/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomUpload.java b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomUpload.java new file mode 100644 index 0000000000..868045bb86 --- /dev/null +++ b/sipXsnom/src/org/sipfoundry/sipxconfig/phone/snom/SnomUpload.java @@ -0,0 +1,29 @@ +/* + * + * + * Copyright (C) 2013 Sip2ser Srl., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + */ +package org.sipfoundry.sipxconfig.phone.snom; + +import org.sipfoundry.sipxconfig.upload.Upload; + +public class SnomUpload extends Upload { + private static final String SNOMLANG_DIR = "/snomlang/"; + private static final String VERSION = "localization/version"; + + @Override + public void deploy() { + super.setDestinationDirectory(getDestinationDirectory() + SNOMLANG_DIR + getSettingValue(VERSION)); + super.deploy(); + } + + @Override + public void undeploy() { + super.setDestinationDirectory(getDestinationDirectory() + SNOMLANG_DIR + getSettingValue(VERSION)); + super.undeploy(); + } + +} diff --git a/sipXsnom/src/sipxplugin.beans.xml b/sipXsnom/src/sipxplugin.beans.xml index a308106a85..ca5a5f854e 100644 --- a/sipXsnom/src/sipxplugin.beans.xml +++ b/sipXsnom/src/sipxplugin.beans.xml @@ -1,13 +1,26 @@ - + + + + + + + + + + + @@ -49,6 +62,7 @@ + @@ -70,5 +84,19 @@ + + + + + + + + ${sysdir.phone}/profile/docroot/ + + + + + diff --git a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/SnomTest.java b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/SnomTest.java index a79861e1b7..4c8152bbfc 100644 --- a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/SnomTest.java +++ b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/SnomTest.java @@ -226,7 +226,7 @@ public void testGetProfileName() { public void testSnomContextEmpty() { SnomPhone phone = new SnomPhone(); - SnomProfileContext sc = new SnomProfileContext(phone, null, m_emptyPhonebook, null); + SnomProfileContext sc = new SnomProfileContext(phone, null, m_emptyPhonebook, null, null); String[] numbers = (String[]) sc.getContext().get("speedDial"); assertEquals(0, numbers.length); @@ -238,14 +238,14 @@ public void testSnomContext() { SnomPhone phone = new SnomPhone(); - SnomProfileContext sc = new SnomProfileContext(phone, smallSd, m_emptyPhonebook, null); + SnomProfileContext sc = new SnomProfileContext(phone, smallSd, m_emptyPhonebook, null, null); String[] numbers = (String[]) sc.getContext().get("speedDial"); assertEquals(5, numbers.length); for (int i = 0; i < numbers.length; i++) { assertEquals(Integer.toString(i), numbers[i]); } - sc = new SnomProfileContext(phone, largeSd, m_emptyPhonebook, null); + sc = new SnomProfileContext(phone, largeSd, m_emptyPhonebook, null, null); numbers = (String[]) sc.getContext().get("speedDial"); assertEquals(33, numbers.length); for (int i = 0; i < numbers.length; i++) { @@ -260,7 +260,7 @@ public void testSnomContextLargePhonebook() { } SnomPhone phone = new SnomPhone(); - SnomProfileContext sc = new SnomProfileContext(phone, null, phonebook, null); + SnomProfileContext sc = new SnomProfileContext(phone, null, phonebook, null, null); Collection< ? > trimmed = (Collection< ? >) sc.getContext().get("phoneBook"); assertEquals(100, trimmed.size()); } diff --git a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-320.xml b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-320.xml index a9d3070da8..1514e5a08b 100644 --- a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-320.xml +++ b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-320.xml @@ -22,7 +22,7 @@ off 15 on - on + off 4 off on @@ -68,7 +68,7 @@ USA-5 - ntp.example.org + testdriver.example.org 3600 @@ -82,7 +82,7 @@ 161 - 10.4.5.2 + testdriver.example.org on nothing auto @@ -125,6 +125,7 @@ Ringer1 Ringer1 Ringer1 + Ringer1 Ringer1 60 @@ -176,6 +177,7 @@ off on + on speed 101 @@ -190,7 +192,7 @@ none juser juser - Ringer1 + Ringer1 @@ -218,7 +220,7 @@ off nortel - off + on 3600 off off @@ -250,7 +252,7 @@ none - Ringer1 + Ringer1 @@ -278,7 +280,7 @@ off nortel - off + on 3600 off off @@ -310,7 +312,7 @@ none - Ringer1 + Ringer1 @@ -338,7 +340,7 @@ off nortel - off + on 3600 off off @@ -370,7 +372,7 @@ none - Ringer1 + Ringer1 @@ -398,7 +400,7 @@ off nortel - off + on 3600 off off @@ -441,4 +443,13 @@ line line + + + + + + + + + diff --git a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-360.xml b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-360.xml index c0573ea6fc..42d779d457 100644 --- a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-360.xml +++ b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-360.xml @@ -22,7 +22,7 @@ off 15 on - on + off 4 off on @@ -68,7 +68,7 @@ USA-5 - ntp.example.org + testdriver.example.org 3600 @@ -82,7 +82,7 @@ 161 - 10.4.5.2 + testdriver.example.org on nothing auto @@ -125,6 +125,7 @@ Ringer1 Ringer1 Ringer1 + Ringer1 Ringer1 60 @@ -176,6 +177,7 @@ off on + on speed 101 @@ -190,7 +192,7 @@ none juser juser - Ringer1 + Ringer1 @@ -218,7 +220,7 @@ off nortel - off + on 3600 off off @@ -250,7 +252,7 @@ none - Ringer1 + Ringer1 @@ -278,7 +280,7 @@ off nortel - off + on 3600 off off @@ -310,7 +312,7 @@ none - Ringer1 + Ringer1 @@ -338,7 +340,7 @@ off nortel - off + on 3600 off off @@ -370,7 +372,7 @@ none - Ringer1 + Ringer1 @@ -398,7 +400,7 @@ off nortel - off + on 3600 off off @@ -441,4 +443,13 @@ line line + + + + + + + + + diff --git a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-m3.cfg b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-m3.cfg index 8af7adc12c..1a5f6c482c 100644 --- a/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-m3.cfg +++ b/sipXsnom/test/org/sipfoundry/sipxconfig/phone/snom/expected-snom-m3.cfg @@ -33,7 +33,7 @@ // management %MANAGEMENT_TRANSFER_PROTOCOL%:0 // time -%NETWORK_SNTP_SERVER%:"ntp.example.org" +%NETWORK_SNTP_SERVER%:"testdriver.example.org" %NETWORK_SNTP_SERVER_UPDATE_TIME%:255 // tone_scheme %COUNTRY_VARIANT_ID%:18 diff --git a/sipXsupervisor/bin/sipxecs-setup.in b/sipXsupervisor/bin/sipxecs-setup.in index 32c8718b44..9f2fcc7996 100644 --- a/sipXsupervisor/bin/sipxecs-setup.in +++ b/sipXsupervisor/bin/sipxecs-setup.in @@ -276,7 +276,11 @@ def network_settings net = get_network(true) puts "\e[0;31mNetwork settings:\e[m" puts "IP address : #{net.ip}" - reprompt = prompt_confirm("Would you like to configure your system\'s \e[0;31m network settings\e[m?") unless $prompt[:noui] + if net.net_defined + reprompt = prompt_confirm("Would you like to configure your system\'s \e[0;31m network settings\e[m?") unless $prompt[:noui] + else + reprompt = true + end if reprompt change = true system("/usr/sbin/system-config-network-tui") @@ -331,14 +335,20 @@ def get_network(force = false) end class Network - attr_accessor :ip, :host, :domain + attr_accessor :ip, :host, :domain, :net_defined def initialize - orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true - UDPSocket.open { |s| - s.connect '8.8.8.8', 1 - @ip = s.addr.last - } + begin + orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true + UDPSocket.open { |s| + s.connect '8.8.8.8', 1 + @ip = s.addr.last + @net_defined = true + } + rescue + @ip="" + @net_defined = false + end # hostname call is not reliable, check hosts file for more accurate answer # the network config tool system-config-network-tui does not create a clean diff --git a/sipXsupervisor/etc/dhcpd.erb b/sipXsupervisor/etc/dhcpd.erb index 25391795f9..fb9324f37d 100644 --- a/sipXsupervisor/etc/dhcpd.erb +++ b/sipXsupervisor/etc/dhcpd.erb @@ -16,3 +16,11 @@ subnet <%= subnet %> netmask <%= netmask %> { option domain-name-servers <%= dns.join(', ') %>; option ntp-servers <%= ntp.join(', ') %>; } + +<% if snom_statichttp_provisioning == 1 %> + class "Snom" { + match if substring (hardware, 1, 3) = 00:04:13; + option tftp-server-name "http://<%= statichttp %>"; + option bootfile-name "/phone/profile/docroot/{mac}.xml"; + } +<% end %> diff --git a/sipXtackLib/include/net/SipTransaction.h b/sipXtackLib/include/net/SipTransaction.h index 2bb25e51b2..e5e6fbfb19 100644 --- a/sipXtackLib/include/net/SipTransaction.h +++ b/sipXtackLib/include/net/SipTransaction.h @@ -112,8 +112,11 @@ class SipTransaction : public UtlString { SipTransaction(SipMessage* initialMsg = NULL, ///< message whose state this tracks UtlBoolean isOutgoing = TRUE, ///< direction UtlBoolean userAgentTransaction = TRUE,///< local initiated - BranchId* parentBranch = NULL ///< for use in loop detection - ); + BranchId* parentBranch = NULL, ///< for use in loop detection + int maxUdpResend = 4, + int maxTcpResend = 4 + ); + /**< * When this is an out going request, this is a client * transaction. The via header field MUST be added before @@ -464,6 +467,8 @@ class SipTransaction : public UtlString { UtlBoolean mProvisionalSdp; ///< early media UtlSList mTimers; /**< A list of all outstanding timers * started by this transaction. */ + const int mMaxUdpResend; + const int mMaxTcpResend; /**< SipTransaction Timer Usage * In this comment, "transaction" refers to the SipTransaction object in the code, not an RFC3261 transaction. * Timer objects contain the corresponding SipMessage to be used when events are processed. diff --git a/sipXtackLib/include/net/SipUserAgent.h b/sipXtackLib/include/net/SipUserAgent.h index 693eee4e2b..6975d6d835 100644 --- a/sipXtackLib/include/net/SipUserAgent.h +++ b/sipXtackLib/include/net/SipUserAgent.h @@ -265,8 +265,10 @@ class SipUserAgent : public SipUserAgentBase UtlBoolean bUseNextAvailablePort = FALSE, UtlBoolean doUaMessageChecks = TRUE, UtlBoolean forceSymmetricSignaling = TRUE, - OptionsRequestHandlePref howTohandleOptionsRequest = HANDLE_OPTIONS_AUTOMATICALLY - ); + OptionsRequestHandlePref howTohandleOptionsRequest = HANDLE_OPTIONS_AUTOMATICALLY, + int maxUdpResend = 4, + int maxTcpResend = 4 + ); //! Destructor virtual @@ -837,6 +839,8 @@ class SipUserAgent : public SipUserAgentBase bool mbIncludePlatformInUserAgentName; // whether or not the platform name should // be appended to the user agent name + const int mMaxUdpResend; + const int mMaxTcpResend; /** check the acceptability of method, extensions, and encoding. * The default is TRUE; it may be set to false in applications such as a redirect server * that will never actually send a 2xx response, so the checks might cause errors that diff --git a/sipXtackLib/include/net/Url.h b/sipXtackLib/include/net/Url.h index 3faab51003..e2876cf732 100644 --- a/sipXtackLib/include/net/Url.h +++ b/sipXtackLib/include/net/Url.h @@ -546,6 +546,8 @@ class Url */ static UtlBoolean isDigitString(const char* dialedCharacters); + UtlBoolean isValid() const; + /// Compare two URLs to see if the have the same user, host and port UtlBoolean isUserHostPortEqual(const Url& uri, int impliedPort = PORT_NONE diff --git a/sipXtackLib/src/net/SipTransaction.cpp b/sipXtackLib/src/net/SipTransaction.cpp index 6a1b54f9be..6ef728f956 100644 --- a/sipXtackLib/src/net/SipTransaction.cpp +++ b/sipXtackLib/src/net/SipTransaction.cpp @@ -30,8 +30,6 @@ // EXTERNAL FUNCTIONS // EXTERNAL VARIABLES // CONSTANTS -#define SIP_UDP_RESEND_TIMES 4 // Maximum number of times to send/resend messages via UDP -#define SIP_TCP_RESEND_TIMES 4 // Maximum number of times to send/resend messages via TCP #define MIN_Q_DELTA_SQUARE 0.0000000001 // Smallest Q difference is 0.00001 #define UDP_LARGE_MSG_LIMIT 1200 // spec says 1300, but we may have to add another via @@ -52,7 +50,9 @@ UtlBoolean SipTransaction::SendTryingForNist = TRUE; SipTransaction::SipTransaction(SipMessage* initialMsg, UtlBoolean isOutgoing, UtlBoolean userAgentTransaction, - BranchId* parentBranch + BranchId* parentBranch, + int mUdpRe, + int mTcpRe ) : mpBranchId(NULL) , mRequestMethod("") @@ -80,6 +80,8 @@ SipTransaction::SipTransaction(SipMessage* initialMsg, , mProvoExtendsTimer(FALSE) , mWaitingList(NULL) , _markedForDeletion(false) + , mMaxUdpResend(mUdpRe) + , mMaxTcpResend(mTcpRe) { # ifdef ROUTE_DEBUG @@ -2828,7 +2830,9 @@ UtlBoolean SipTransaction::recurseDnsSrvChildren(SipUserAgent& userAgent, mIsUaTransaction, ( mpParentTransaction ? mpParentTransaction->mpBranchId - : NULL ) + : NULL ), + mMaxUdpResend, + mMaxTcpResend ); // same as parent mpDnsDestinations[numSrvRecords]. @@ -3118,7 +3122,9 @@ UtlBoolean SipTransaction::recurseChildren(SipUserAgent& userAgent, childTransaction = new SipTransaction(mpRequest, TRUE, // outgoing FALSE, - mpBranchId + mpBranchId, + mMaxUdpResend, + mMaxTcpResend ); // proxy transaction # ifdef LOG_FORKING @@ -3832,7 +3838,7 @@ UtlBoolean SipTransaction::doResend(SipMessage& resendMessage, if (protocol == OsSocket::UDP) { - if (numTries < SIP_UDP_RESEND_TIMES) + if (numTries < mMaxUdpResend) { // Try UDP again if (userAgent.sendUdp(&resendMessage, sendAddress.data(), sendPort)) @@ -3858,7 +3864,7 @@ UtlBoolean SipTransaction::doResend(SipMessage& resendMessage, #endif ) { - if (numTries < SIP_TCP_RESEND_TIMES) + if (numTries < mMaxTcpResend) { bool r = !SipTransaction::enableTcpResend; // Try sending again. diff --git a/sipXtackLib/src/net/SipUserAgent.cpp b/sipXtackLib/src/net/SipUserAgent.cpp index dafc594b37..011f9e974b 100644 --- a/sipXtackLib/src/net/SipUserAgent.cpp +++ b/sipXtackLib/src/net/SipUserAgent.cpp @@ -118,7 +118,9 @@ SipUserAgent::SipUserAgent(int sipTcpPort, UtlBoolean bUseNextAvailablePort, UtlBoolean doUaMessageChecks, UtlBoolean bForceSymmetricSignaling, - OptionsRequestHandlePref howTohandleOptionsRequest + OptionsRequestHandlePref howTohandleOptionsRequest, + int mudpr, + int mtcpr ) : SipUserAgentBase(sipTcpPort, sipUdpPort, sipTlsPort, queueSize) , mSipTcpServer(NULL) @@ -137,6 +139,8 @@ SipUserAgent::SipUserAgent(int sipTcpPort, , mbForceSymmetricSignaling(bForceSymmetricSignaling) , mbShuttingDown(FALSE) , mbShutdownDone(FALSE) + , mMaxUdpResend(mudpr) + , mMaxTcpResend(mtcpr) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipUserAgent[%s]::_ sipTcpPort = %d, sipUdpPort = %d, " @@ -999,7 +1003,8 @@ UtlBoolean SipUserAgent::send(SipMessage& message, // Create a new transactions // This should only be for requests // so it should not be a server transaction - transaction = new SipTransaction(&message, TRUE /* outgoing */, isUaTransaction); + transaction = new SipTransaction(&message, TRUE /* outgoing */, isUaTransaction, NULL, + mMaxUdpResend, mMaxTcpResend); transaction->markBusy(); mSipTransactions.addTransaction(transaction); @@ -1763,7 +1768,8 @@ void SipUserAgent::dispatch(SipMessage* message, int messageType) else { // Should create a server transaction - transaction = new SipTransaction(message, FALSE /* incoming */, isUaTransaction); + transaction = new SipTransaction(message, FALSE /* incoming */, isUaTransaction, NULL, + mMaxUdpResend, mMaxTcpResend); // Add the new transaction to the list transaction->markBusy(); diff --git a/sipXtackLib/src/net/Url.cpp b/sipXtackLib/src/net/Url.cpp index 2a5c1a9ca9..f6c393d47a 100644 --- a/sipXtackLib/src/net/Url.cpp +++ b/sipXtackLib/src/net/Url.cpp @@ -1401,6 +1401,11 @@ UtlBoolean Url::isIncludeAngleBracketsSet() const return mAngleBracketsIncluded ; } +UtlBoolean Url::isValid() const +{ + return !mHostAddress.isNull(); +} + /* //////////////////////////// PROTECTED ///////////////////////////////// */ // Special value used inside Url::parseString() to indicate that no