@php $endpoint = $endpoint ?? null; $auth = $auth ?? null; $aor = $aor ?? null; $reg = $reg ?? null; $trunk = $trunk ?? null; $isEdit = $isEdit ?? false; $codecs = $codecs ?? []; if (empty($codecs)) { $codecs = [ 'ulaw' => ['label' => 'G.711 ulaw', 'hz' => '8 kHz', 'preferred' => true], 'alaw' => ['label' => 'G.711 alaw', 'hz' => '8 kHz', 'preferred' => true], 'g729' => ['label' => 'G.729', 'hz' => '8 kHz', 'preferred' => false], 'g722' => ['label' => 'G.722', 'hz' => '16 kHz', 'preferred' => false], 'opus' => ['label' => 'Opus', 'hz' => '48 kHz', 'preferred' => false], 'gsm' => ['label' => 'GSM', 'hz' => '8 kHz', 'preferred' => false], ]; } $v = function ($key, $default = '') use ($endpoint, $auth, $aor, $reg, $trunk) { $map = [ // Endpoint fields 'id' => optional($endpoint)->id, 'description' => optional($endpoint)->description, 'transport' => optional($endpoint)->transport ?: 'transport-udp', 'context' => optional($endpoint)->context ?: 'from-trunk', 'from_user' => optional($endpoint)->from_user ?: optional($trunk)->from_user, 'from_domain' => optional($endpoint)->from_domain ?? optional($trunk)->from_domain, 'outbound_proxy' => optional($endpoint)->outbound_proxy ?? optional($trunk)->outbound_proxy, 'rtp_timeout' => optional($endpoint)->rtp_timeout, 'rtp_timeout_hold' => optional($endpoint)->rtp_timeout_hold, 'identify_by' => optional($endpoint)->identify_by ?: 'username', 'dtmf_mode' => optional($endpoint)->dtmf_mode ?: 'rfc4733', 'direct_media' => (optional($endpoint)->direct_media ?? 'no') === 'yes', 'preferred_codec_only' => (optional($endpoint)->preferred_codec_only ?? 'no') === 'yes', 'rtcp_mux' => (optional($endpoint)->rtcp_mux ?? 'no') === 'yes', 'trust_id_inbound' => (optional($endpoint)->trust_id_inbound ?? 'no') === 'yes', 'trust_id_outbound' => (optional($endpoint)->trust_id_outbound ?? 'no') === 'yes', 'send_pai' => (optional($endpoint)->send_pai ?? 'no') === 'yes', 'send_rpid' => (optional($endpoint)->send_rpid ?? 'no') === 'yes', 'user_eq_phone' => (optional($endpoint)->user_eq_phone ?? 'no') === 'yes', // NAT-safe defaults for a NEW trunk (no $endpoint yet): symmetric RTP // and force_rport prevent one-way / no audio behind NAT, which is the // norm for our on-prem boxes. On edit, the saved value is honoured. 'rtp_symmetric' => (optional($endpoint)->rtp_symmetric ?? ($endpoint ? 'no' : 'yes')) === 'yes', 'rewrite_contact' => (optional($endpoint)->rewrite_contact ?? 'no') === 'yes', 'force_rport' => (optional($endpoint)->force_rport ?? ($endpoint ? 'no' : 'yes')) === 'yes', 'force_outbound_cli' => optional($endpoint)->force_outbound_cli, 'callerid' => optional($endpoint)->callerid ?? optional($trunk)->caller_id, 'per_extension_cli' => (bool) (optional($trunk)->per_extension_cli ?? 0), 'outbound_auth' => optional($endpoint)->outbound_auth, 'auth' => optional($endpoint)->auth, 'inbound_auth' => optional($endpoint)->auth, 'language' => optional($endpoint)->language, 'accountcode' => optional($endpoint)->accountcode, 't38_udptl' => (optional($endpoint)->t38_udptl ?? 'no') === 'yes', 't38_udptl_ec' => optional($endpoint)->t38_udptl_ec, 't38_udptl_nat' => (optional($endpoint)->t38_udptl_nat ?? 'no') === 'yes', 't38_udptl_ipv6' => (optional($endpoint)->t38_udptl_ipv6 ?? 'no') === 'yes', 'timers' => (optional($endpoint)->timers ?? 'no') === 'yes', 'timers_min_se' => optional($endpoint)->timers_min_se ?: 90, 'timers_sess_expires' => optional($endpoint)->timers_sess_expires ?: 1800, '100rel' => (optional($endpoint)->{'100rel'} ?? 'no') === 'yes', 'connected_line_method' => optional($endpoint)->connected_line_method ?: 'invite', 'media_encryption' => optional($endpoint)->media_encryption ?: 'no', 'use_avpf' => (optional($endpoint)->use_avpf ?? 'no') === 'yes', 'use_ptime' => (optional($endpoint)->use_ptime ?? 'no') === 'yes', 'ice_support' => (optional($endpoint)->ice_support ?? 'no') === 'yes', 'acl' => optional($endpoint)->acl, 'allow' => optional($endpoint)->allow, 'callerid_privacy' => optional($endpoint)->callerid_privacy, 'callerid_tag' => optional($endpoint)->callerid_tag, 'call_group' => optional($endpoint)->call_group, 'pickup_group' => optional($endpoint)->pickup_group, 'named_call_group' => optional($endpoint)->named_call_group, 'named_pickup_group' => optional($endpoint)->named_pickup_group, 'device_state_busy_at' => optional($endpoint)->device_state_busy_at, 'disable_direct_media_on_nat' => (optional($endpoint)->disable_direct_media_on_nat ?? 'no') === 'yes', 'direct_media_glare_mitigation' => optional($endpoint)->direct_media_glare_mitigation ?: 'none', 'direct_media_method' => optional($endpoint)->direct_media_method ?: 'invite', 'follow_early_media_fork' => (optional($endpoint)->follow_early_media_fork ?? 'no') === 'yes', 'ignore_183_without_sdp' => (optional($endpoint)->ignore_183_without_sdp ?? 'no') === 'yes', 'inband_progress' => (optional($endpoint)->inband_progress ?? 'no') === 'yes', 'incoming_call_offer_pref' => optional($endpoint)->incoming_call_offer_pref ?: 'local', 'outgoing_call_offer_pref' => optional($endpoint)->outgoing_call_offer_pref ?: 'remote_merge', 'overlap_context' => optional($endpoint)->overlap_context, 'redirect_method' => optional($endpoint)->redirect_method ?: 'user', 'refer_blind_progress' => (optional($endpoint)->refer_blind_progress ?? 'no') === 'yes', 'send_diversion' => (optional($endpoint)->send_diversion ?? 'no') === 'yes', 'send_history_info' => (optional($endpoint)->send_history_info ?? 'no') === 'yes', 'send_connected_line' => (optional($endpoint)->send_connected_line ?? 'no') === 'yes', 'trust_connected_line' => (optional($endpoint)->trust_connected_line ?? 'no') === 'yes', 'rpid_immediate' => (optional($endpoint)->rpid_immediate ?? 'no') === 'yes', 'tone_zone' => optional($endpoint)->tone_zone, 'tos_audio' => optional($endpoint)->tos_audio, 'tos_video' => optional($endpoint)->tos_video, 'cos_audio' => optional($endpoint)->cos_audio, 'cos_video' => optional($endpoint)->cos_video, 'sub_min_expiry' => optional($endpoint)->sub_min_expiry, 'moh_suggest' => optional($endpoint)->moh_suggest, 'voicemail_extension' => optional($endpoint)->voicemail_extension, 'mailboxes' => optional($endpoint)->mailboxes, 'max_audio_streams' => optional($endpoint)->max_audio_streams ?: 10, 'max_video_streams' => optional($endpoint)->max_video_streams ?: 1, 'bundle' => (optional($endpoint)->bundle ?? 'no') === 'yes', 'webrtc' => (optional($endpoint)->webrtc ?? 'no') === 'yes', 'stir_shaken' => (optional($endpoint)->stir_shaken ?? 'no') === 'yes', 'stir_shaken_profile' => optional($endpoint)->stir_shaken_profile, 'dtls_auto_generate_cert' => (optional($endpoint)->dtls_auto_generate_cert ?? 'no') === 'yes', 'dtls_setup' => optional($endpoint)->dtls_setup ?: 'active', 'dtls_verify' => (optional($endpoint)->dtls_verify ?? 'no') === 'yes', 'dtls_rekey' => optional($endpoint)->dtls_rekey, 'dtls_fingerprint' => optional($endpoint)->dtls_fingerprint ?: 'SHA-256', 'dtls_cert_file' => optional($endpoint)->dtls_cert_file, 'dtls_private_key' => optional($endpoint)->dtls_private_key, 'dtls_ca_file' => optional($endpoint)->dtls_ca_file, 'dtls_ca_path' => optional($endpoint)->dtls_ca_path, 'dtls_cipher' => optional($endpoint)->dtls_cipher, 'srtp_tag_32' => (optional($endpoint)->srtp_tag_32 ?? 'no') === 'yes', 'media_address' => optional($endpoint)->media_address, 'media_use_received_transport' => (optional($endpoint)->media_use_received_transport ?? 'no') === 'yes', 'rtp_keepalive' => optional($endpoint)->rtp_keepalive, 'rtp_ipv6' => (optional($endpoint)->rtp_ipv6 ?? 'no') === 'yes', 'rtcp_mux' => (optional($endpoint)->rtcp_mux ?? 'no') === 'yes', 'rtcp_mux' => (optional($endpoint)->rtcp_mux ?? 'no') === 'yes', 'record_on_feature' => optional($endpoint)->record_on_feature, 'record_off_feature' => optional($endpoint)->record_off_feature, 'fax_detect' => (optional($endpoint)->fax_detect ?? 'no') === 'yes', 'fax_detect_timeout' => optional($endpoint)->fax_detect_timeout, 'g726_non_standard' => (optional($endpoint)->g726_non_standard ?? 'no') === 'yes', 'message_context' => optional($endpoint)->message_context, 'aggregate_mwi' => (optional($endpoint)->aggregate_mwi ?? 'no') === 'yes', 'mwi_from_user' => optional($endpoint)->mwi_from_user, 'allow_subscribe' => (optional($endpoint)->allow_subscribe ?? 'no') === 'yes', 'allow_transfer' => (optional($endpoint)->allow_transfer ?? 'no') === 'yes', 'allow_unauthenticated_options' => (optional($endpoint)->allow_unauthenticated_options ?? 'no') === 'yes', 'allow_overlap' => (optional($endpoint)->allow_overlap ?? 'no') === 'yes', 'supress_moh_on_sendonly' => (optional($endpoint)->supress_moh_on_sendonly ?? 'no') === 'yes', 'suppress_q850_reason_headers' => (optional($endpoint)->suppress_q850_reason_headers ?? 'no') === 'yes', 'subscribe_context' => optional($endpoint)->subscribe_context, 'one_touch_recording' => (optional($endpoint)->one_touch_recording ?? 'no') === 'yes', 'sdp_owner' => optional($endpoint)->sdp_owner, 'sdp_session' => optional($endpoint)->sdp_session, 'tos_audio' => optional($endpoint)->tos_audio, 'tos_video' => optional($endpoint)->tos_video, 'cos_audio' => optional($endpoint)->cos_audio, 'cos_video' => optional($endpoint)->cos_video, 'allow' => optional($endpoint)->allow, // Auth fields 'username' => optional($auth)->username ?? optional($trunk)->username, 'password' => optional($auth)->password ?? optional($trunk)->password, 'auth_type' => optional($auth)->auth_type ?? optional($trunk)->auth_type, 'realm' => optional($auth)->realm, // AOR fields 'contact' => optional($aor)->contact, 'max_contacts' => optional($aor)->max_contacts ?? optional($trunk)->max_contacts, 'qualify_frequency' => optional($aor)->qualify_frequency, 'qualify_timeout' => optional($aor)->qualify_timeout, 'remove_existing' => (optional($aor)->remove_existing ?? 'no') === 'yes', 'support_path' => (optional($aor)->support_path ?? 'no') === 'yes', // Registration fields 'reg_server_uri' => optional($reg)->server_uri ?? optional($trunk)->server_uri, 'reg_client_uri' => optional($reg)->client_uri ?? optional($trunk)->client_uri, 'reg_contact_user' => optional($reg)->contact_user ?? optional($trunk)->contact_user, 'retry_interval' => optional($reg)->retry_interval, 'expiration' => optional($reg)->expiration, 'max_retries' => optional($reg)->max_retries, 'forbidden_retry_interval' => optional($reg)->forbidden_retry_interval, 'fatal_retry_interval' => optional($reg)->fatal_retry_interval, 'auth_rejection_permanent' => (optional($reg)->auth_rejection_permanent ?? 'no') === 'yes', 'line' => optional($reg)->line, 'reg_endpoint' => optional($reg)->endpoint, // Trunk (sip_trunks table) fields 'dial_prefix' => optional($trunk)->dial_prefix, 'dial_strip' => optional($trunk)->dial_strip, 'dial_prepend' => optional($trunk)->dial_prepend, 'callerid_name' => optional($trunk)->trunk_cid_name, 'enabled' => !optional($trunk)->disable_trunk, 'notes' => optional($trunk)->notes, ]; return $map[$key] ?? $default; }; @endphp @php $selectedCodecs = old('codecs'); if ($selectedCodecs === null) { $raw = $endpoint->allow ?? ''; $selectedCodecs = $raw ? preg_split('/\s*,\s*/', $raw, -1, PREG_SPLIT_NO_EMPTY) : ['ulaw', 'alaw']; } $selectedCodecs = array_map(fn($c) => strtolower(trim($c)), (array) $selectedCodecs); @endphp
| Description | MSTeams |
| Transport | transport-tls |
| Codecs | ulaw, alaw, gsm |
| DTMF | rfc4733 |
| Username | msteams |
| Contact | sip:sip.pstnhub.microsoft.com |
| From Domain | msteams.nextfour.co.za |
| Identify By | auth_username |
Fills the form with a Microsoft Teams Direct Routing baseline. You can adjust values after applying.
trunks-in so inbound DID routes are always reached.Outbound route associations are configured in Outbound Routes. Assign this trunk there to control which calls are sent through it.