diff --git a/applications/callflow/src/cf_route_req.erl b/applications/callflow/src/cf_route_req.erl index ab86b53325b..c8bac82d37c 100644 --- a/applications/callflow/src/cf_route_req.erl +++ b/applications/callflow/src/cf_route_req.erl @@ -216,7 +216,9 @@ response_ccvs(Call, _Id, _Type) -> default_response_ccvs(Call). response_ccvs_from_device(Call, {'ok', DeviceJObj}) -> - kz_json:set_values([{<<"Presence-ID">>, kzd_devices:calculate_presence_id(DeviceJObj)}] + kz_json:set_values([{<<"Presence-ID">>, kzd_devices:calculate_presence_id(DeviceJObj)} + ,{<<"DTMF-Type">>, kzd_devices:sip_dtmf_type(DeviceJObj)} + ] ,default_response_ccvs(Call) ); response_ccvs_from_device(Call, _E) -> diff --git a/applications/crossbar/doc/devices.md b/applications/crossbar/doc/devices.md index ccdd579994f..eba1ec88342 100644 --- a/applications/crossbar/doc/devices.md +++ b/applications/crossbar/doc/devices.md @@ -72,6 +72,7 @@ Key | Description | Type | Default | Required | Support Level `sip.custom_sip_headers.out` | Custom SIP Headers to be applied to calls outbound from Kazoo to the endpoint | [#/definitions/custom_sip_headers](#custom_sip_headers) | | `false` | `sip.custom_sip_headers.^[a-zA-z0-9_\-]+$` | The SIP header to add | `string()` | | `false` | `sip.custom_sip_headers` | A property list of SIP headers | `object()` | | `false` | +`sip.dtmf_type` | The SIP request DTMF format | `string('none' | 'rfc2833' | 'info')` | | `false` | `sip.expire_seconds` | The time, in seconds, sent to the provisioner for the registration period that the device should be configured with. | `integer()` | `300` | `false` | `supported` `sip.ignore_completed_elsewhere` | When set to false the phone should not consider ring group calls answered elsewhere as missed | `boolean()` | | `false` | `sip.invite_format` | The SIP request URI invite format | `string('username' | 'npan' | '1npan' | 'e164' | 'route' | 'contact')` | `contact` | `false` | `supported` diff --git a/applications/crossbar/doc/ref/devices.md b/applications/crossbar/doc/ref/devices.md index 8d8b618b587..82fd4620878 100644 --- a/applications/crossbar/doc/ref/devices.md +++ b/applications/crossbar/doc/ref/devices.md @@ -69,6 +69,7 @@ Key | Description | Type | Default | Required | Support Level `sip.custom_sip_headers.out` | Custom SIP Headers to be applied to calls outbound from Kazoo to the endpoint | [#/definitions/custom_sip_headers](#custom_sip_headers) | | `false` | `sip.custom_sip_headers.^[a-zA-z0-9_\-]+$` | The SIP header to add | `string()` | | `false` | `sip.custom_sip_headers` | A property list of SIP headers | `object()` | | `false` | +`sip.dtmf_type` | The SIP request DTMF format | `string('none' | 'rfc2833' | 'info')` | | `false` | `sip.expire_seconds` | The time, in seconds, sent to the provisioner for the registration period that the device should be configured with. | `integer()` | `300` | `false` | `supported` `sip.ignore_completed_elsewhere` | When set to false the phone should not consider ring group calls answered elsewhere as missed | `boolean()` | | `false` | `sip.invite_format` | The SIP request URI invite format | `string('username' | 'npan' | '1npan' | 'e164' | 'route' | 'contact')` | `contact` | `false` | `supported` diff --git a/applications/crossbar/priv/api/swagger.json b/applications/crossbar/priv/api/swagger.json index f7d200f5744..5c52a26343a 100644 --- a/applications/crossbar/priv/api/swagger.json +++ b/applications/crossbar/priv/api/swagger.json @@ -5651,6 +5651,15 @@ "description": "A property list of SIP headers", "type": "object" }, + "dtmf_type": { + "description": "The SIP request DTMF format", + "enum": [ + "none", + "rfc2833", + "info" + ], + "type": "string" + }, "expire_seconds": { "default": 300, "description": "The time, in seconds, sent to the provisioner for the registration period that the device should be configured with.", @@ -12584,6 +12593,9 @@ "Custom-SIP-Headers": { "type": "object" }, + "DTMF-Type": { + "type": "string" + }, "Enable-T38-Fax": { "type": "string" }, @@ -22839,6 +22851,9 @@ "Custom-SIP-Headers": { "type": "object" }, + "DTMF-Type": { + "type": "string" + }, "Enable-T38-Fax": { "type": "string" }, diff --git a/applications/crossbar/priv/couchdb/schemas/devices.json b/applications/crossbar/priv/couchdb/schemas/devices.json index 82061ad42d8..869161a08c3 100644 --- a/applications/crossbar/priv/couchdb/schemas/devices.json +++ b/applications/crossbar/priv/couchdb/schemas/devices.json @@ -347,6 +347,15 @@ "description": "A property list of SIP headers", "type": "object" }, + "dtmf_type": { + "description": "The SIP request DTMF format", + "enum": [ + "none", + "rfc2833", + "info" + ], + "type": "string" + }, "expire_seconds": { "default": 300, "description": "The time, in seconds, sent to the provisioner for the registration period that the device should be configured with.", diff --git a/applications/crossbar/priv/couchdb/schemas/kapi.dialplan.bridge_endpoint_headers.json b/applications/crossbar/priv/couchdb/schemas/kapi.dialplan.bridge_endpoint_headers.json index 7c695288605..135dff1d633 100644 --- a/applications/crossbar/priv/couchdb/schemas/kapi.dialplan.bridge_endpoint_headers.json +++ b/applications/crossbar/priv/couchdb/schemas/kapi.dialplan.bridge_endpoint_headers.json @@ -39,6 +39,9 @@ "Custom-SIP-Headers": { "type": "object" }, + "DTMF-Type": { + "type": "string" + }, "Enable-T38-Fax": { "type": "string" }, diff --git a/applications/crossbar/priv/couchdb/schemas/kapi.resource.originate_req_endpoint_headers.json b/applications/crossbar/priv/couchdb/schemas/kapi.resource.originate_req_endpoint_headers.json index cc96de4b267..5db4b24384d 100644 --- a/applications/crossbar/priv/couchdb/schemas/kapi.resource.originate_req_endpoint_headers.json +++ b/applications/crossbar/priv/couchdb/schemas/kapi.resource.originate_req_endpoint_headers.json @@ -39,6 +39,9 @@ "Custom-SIP-Headers": { "type": "object" }, + "DTMF-Type": { + "type": "string" + }, "Enable-T38-Fax": { "type": "string" }, diff --git a/applications/ecallmgr/src/ecallmgr_fs_xml.erl b/applications/ecallmgr/src/ecallmgr_fs_xml.erl index 707a035d323..8046f371458 100644 --- a/applications/ecallmgr/src/ecallmgr_fs_xml.erl +++ b/applications/ecallmgr/src/ecallmgr_fs_xml.erl @@ -310,6 +310,7 @@ route_resp_xml(<<"park">>, _Routes, JObj, Props) -> ,route_resp_transfer_ringback(JObj) ,route_resp_pre_park_action(JObj) ,maybe_start_dtmf_action(Props) + ,maybe_set_dtmf_type(JObj) | route_resp_ccvs(JObj) ++ route_resp_cavs(JObj) ++ unset_custom_sip_headers(Props) @@ -486,6 +487,17 @@ check_dtmf_type(Props) -> _ -> action_el(<<"start_dtmf">>) end. +%%------------------------------------------------------------------------------ +%% @doc Set the FS `dtmf_type' value if `DTMF-Type' is defined in the CCV. +%% @end +%%------------------------------------------------------------------------------ +-spec maybe_set_dtmf_type(kz_json:object()) -> 'undefined' | kz_types:xml_el(). +maybe_set_dtmf_type(JObj) -> + case kz_json:get_binary_value([<<"Custom-Channel-Vars">>, <<"DTMF-Type">>], JObj) of + 'undefined' -> 'undefined'; + DTMFType -> action_el(<<"set">>, <<"dtmf_type=", DTMFType/binary>>) + end. + -spec build_leg_vars(kz_json:object() | kz_term:proplist()) -> kz_term:ne_binaries(). build_leg_vars([]) -> []; build_leg_vars([_|_]=Prop) -> @@ -623,6 +635,9 @@ kazoo_var_to_fs_var({<<"Caller-ID-Type">>, <<"rpid">>}, Vars) -> kazoo_var_to_fs_var({<<"Caller-ID-Type">>, <<"pid">>}, Vars) -> [ <<"sip_cid_type=pid">> | Vars]; +kazoo_var_to_fs_var({<<"DTMF-Type">>, DTMFType}, Vars) -> + [encode_fs_val("dtmf_type", DTMFType) | Vars]; + kazoo_var_to_fs_var({<<"origination_uuid">> = K, UUID}, Vars) -> [encode_fs_val(K, UUID) | Vars]; diff --git a/core/kazoo_amqp/src/api/kapi_dialplan.hrl b/core/kazoo_amqp/src/api/kapi_dialplan.hrl index 2778cc7c02b..2f53b171e51 100644 --- a/core/kazoo_amqp/src/api/kapi_dialplan.hrl +++ b/core/kazoo_amqp/src/api/kapi_dialplan.hrl @@ -120,6 +120,7 @@ ,<<"Custom-Application-Vars">> ,<<"Custom-Channel-Vars">> ,<<"Custom-SIP-Headers">> + ,<<"DTMF-Type">> ,<<"Enable-T38-Fax">> ,<<"Enable-T38-Fax-Request">> ,<<"Enable-T38-Gateway">> diff --git a/core/kazoo_documents/src/kzd_devices.erl b/core/kazoo_documents/src/kzd_devices.erl index 0c77d6e456e..73a2be942ee 100644 --- a/core/kazoo_documents/src/kzd_devices.erl +++ b/core/kazoo_documents/src/kzd_devices.erl @@ -60,6 +60,7 @@ -export([ringtones_internal/1, ringtones_internal/2, set_ringtones_internal/2]). -export([sip/1, sip/2, set_sip/2]). -export([sip_custom_sip_headers/1, sip_custom_sip_headers/2, set_sip_custom_sip_headers/2]). +-export([sip_dtmf_type/1, sip_dtmf_type/2, set_sip_dtmf_type/2]). -export([sip_expire_seconds/1, sip_expire_seconds/2, set_sip_expire_seconds/2]). -export([sip_ignore_completed_elsewhere/1, sip_ignore_completed_elsewhere/2, set_sip_ignore_completed_elsewhere/2]). -export([sip_invite_format/1, sip_invite_format/2, set_sip_invite_format/2]). @@ -808,6 +809,18 @@ sip_custom_sip_headers(Doc, Default) -> set_sip_custom_sip_headers(Doc, SipCustomSipHeaders) -> kz_json:set_value([<<"sip">>, <<"custom_sip_headers">>], SipCustomSipHeaders, Doc). +-spec sip_dtmf_type(doc()) -> kz_term:api_binary(). +sip_dtmf_type(Doc) -> + sip_dtmf_type(Doc, 'undefined'). + +-spec sip_dtmf_type(doc(), Default) -> binary() | Default. +sip_dtmf_type(Doc, Default) -> + kz_json:get_binary_value([<<"sip">>, <<"dtmf_type">>], Doc, Default). + +-spec set_sip_dtmf_type(doc(), binary()) -> doc(). +set_sip_dtmf_type(Doc, SipDtmfType) -> + kz_json:set_value([<<"sip">>, <<"dtmf_type">>], SipDtmfType, Doc). + -spec sip_expire_seconds(doc()) -> integer(). sip_expire_seconds(Doc) -> sip_expire_seconds(Doc, 300). diff --git a/core/kazoo_documents/src/kzd_devices.erl.src b/core/kazoo_documents/src/kzd_devices.erl.src index 928929fe60e..3b37722a8ff 100644 --- a/core/kazoo_documents/src/kzd_devices.erl.src +++ b/core/kazoo_documents/src/kzd_devices.erl.src @@ -62,6 +62,7 @@ -export([ringtones_internal/1, ringtones_internal/2, set_ringtones_internal/2]). -export([sip/1, sip/2, set_sip/2]). -export([sip_custom_sip_headers/1, sip_custom_sip_headers/2, set_sip_custom_sip_headers/2]). +-export([sip_dtmf_type/1, sip_dtmf_type/2, set_sip_dtmf_type/2]). -export([sip_expire_seconds/1, sip_expire_seconds/2, set_sip_expire_seconds/2]). -export([sip_ignore_completed_elsewhere/1, sip_ignore_completed_elsewhere/2, set_sip_ignore_completed_elsewhere/2]). -export([sip_invite_format/1, sip_invite_format/2, set_sip_invite_format/2]). @@ -760,6 +761,18 @@ sip_custom_sip_headers(Doc, Default) -> set_sip_custom_sip_headers(Doc, SipCustomSipHeaders) -> kz_json:set_value([<<"sip">>, <<"custom_sip_headers">>], SipCustomSipHeaders, Doc). +-spec sip_dtmf_type(doc()) -> kz_term:api_binary(). +sip_dtmf_type(Doc) -> + sip_dtmf_type(Doc, 'undefined'). + +-spec sip_dtmf_type(doc(), Default) -> binary() | Default. +sip_dtmf_type(Doc, Default) -> + kz_json:get_binary_value([<<"sip">>, <<"dtmf_type">>], Doc, Default). + +-spec set_sip_dtmf_type(doc(), binary()) -> doc(). +set_sip_dtmf_type(Doc, SipDtmfType) -> + kz_json:set_value([<<"sip">>, <<"dtmf_type">>], SipDtmfType, Doc). + -spec sip_expire_seconds(doc()) -> integer(). sip_expire_seconds(Doc) -> sip_expire_seconds(Doc, 300). diff --git a/core/kazoo_endpoint/src/kz_endpoint.erl b/core/kazoo_endpoint/src/kz_endpoint.erl index c03c21e704d..f5ba7a0baed 100644 --- a/core/kazoo_endpoint/src/kz_endpoint.erl +++ b/core/kazoo_endpoint/src/kz_endpoint.erl @@ -1187,6 +1187,7 @@ create_sip_endpoint(Endpoint, Properties, #clid{}=Clid, Call) -> ,{<<"Route">>, kz_json:get_ne_binary_value(<<"route">>, SIPJObj)} ,{<<"Proxy-IP">>, kz_json:get_ne_binary_value(<<"proxy">>, SIPJObj)} ,{<<"Forward-IP">>, kz_json:get_ne_binary_value(<<"forward">>, SIPJObj)} + ,{<<"DTMF-Type">>, kz_json:get_ne_binary_value(<<"dtmf_type">>, SIPJObj)} ,{<<"Caller-ID-Name">>, Clid#clid.caller_name} ,{<<"Caller-ID-Number">>, Clid#clid.caller_number} ,{<<"Outbound-Caller-ID-Number">>, Clid#clid.caller_number}