diff --git a/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/extensions.conf b/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/extensions.conf
new file mode 100644
index 000000000..ec5f926af
--- /dev/null
+++ b/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/extensions.conf
@@ -0,0 +1,3 @@
+[default]
+exten => s,1,NoOp()
+ same => n,Hangup()
diff --git a/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/pjsip.conf b/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/pjsip.conf
new file mode 100644
index 000000000..2d27cc232
--- /dev/null
+++ b/tests/channels/pjsip/message/message_no_redirect_method/configs/ast1/pjsip.conf
@@ -0,0 +1,17 @@
+[local]
+type=transport
+protocol=udp
+bind=0.0.0.0
+
+[first_dest]
+type=aor
+contact=sip:first@127.0.0.1:5061
+max_contacts=1
+
+[first_dest]
+type=endpoint
+context=default
+aors=first_dest
+direct_media=no
+disallow=all
+allow=ulaw
diff --git a/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_message_expected.xml b/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_message_expected.xml
new file mode 100644
index 000000000..4aad41476
--- /dev/null
+++ b/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_message_expected.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ ;tag=[pid]SIPpTag00[call_number]
+ To: sip:127.0.0.1
+ Call-ID: [call_id]
+ CSeq: 1 OPTIONS
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_redirect_305.xml b/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_redirect_305.xml
new file mode 100644
index 000000000..ea3fb2c41
--- /dev/null
+++ b/tests/channels/pjsip/message/message_no_redirect_method/sipp/no_redirect_305.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+ Content-Length: 0
+
+ ]]>
+
+
+
diff --git a/tests/channels/pjsip/message/message_no_redirect_method/test-config.yaml b/tests/channels/pjsip/message/message_no_redirect_method/test-config.yaml
new file mode 100644
index 000000000..dd97f6590
--- /dev/null
+++ b/tests/channels/pjsip/message/message_no_redirect_method/test-config.yaml
@@ -0,0 +1,53 @@
+testinfo:
+ summary: 'Test MESSAGE does NOT redirect when redirect_method is not set'
+ description: |
+ 'This test verifies that when an outgoing SIP MESSAGE receives a 305
+ redirect response, Asterisk does NOT follow the redirect when the
+ endpoint is configured without redirect_method (default behavior).
+
+ Test flow:
+ 1. AMI MessageSend action triggers MESSAGE to first_dest endpoint
+ 2. SIPp scenario at port 5061 responds with 305 Use Proxy
+ 3. 305 response contains Contact header pointing to port 5062
+ 4. SIPp scenario at port 5062 sends OPTIONS and waits 5 seconds
+ 5. Asterisk should NOT send a MESSAGE to port 5062 (no redirect)
+ 6. If unexpected MESSAGE received on 5062, SIPp fails the test
+ 7. Test passes if both scenarios complete without unexpected messages'
+
+properties:
+ dependencies:
+ - app: 'sipp'
+ - asterisk: 'res_pjsip'
+ - asterisk: 'res_pjsip_messaging'
+ tags:
+ - pjsip
+
+test-modules:
+ test-object:
+ config-section: test-object-config
+ typename: 'sipp.SIPpTestCase'
+ modules:
+ -
+ config-section: ami-config
+ typename: 'pluggable_modules.EventActionModule'
+
+test-object-config:
+ reactor-timeout: 15
+ connect-ami: true
+ stop-after-scenarios: true
+ test-iterations:
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'no_redirect_305.xml', '-p': '5061', '-m': '1'}}
+ - {'key-args': {'scenario': 'no_message_expected.xml', '-p': '5062', '-m': '1', '-default_behaviors': 'abortunexp'}}
+
+ami-config:
+ -
+ ami-start:
+ ami-actions:
+ delay: 1
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender@asterisk'
+ Body: 'Test message that should not be redirected'
diff --git a/tests/channels/pjsip/message/message_redirect/configs/ast1/extensions.conf b/tests/channels/pjsip/message/message_redirect/configs/ast1/extensions.conf
new file mode 100644
index 000000000..ec5f926af
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect/configs/ast1/extensions.conf
@@ -0,0 +1,3 @@
+[default]
+exten => s,1,NoOp()
+ same => n,Hangup()
diff --git a/tests/channels/pjsip/message/message_redirect/configs/ast1/pjsip.conf b/tests/channels/pjsip/message/message_redirect/configs/ast1/pjsip.conf
new file mode 100644
index 000000000..e22760ac3
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect/configs/ast1/pjsip.conf
@@ -0,0 +1,18 @@
+[local]
+type=transport
+protocol=udp
+bind=0.0.0.0
+
+[first_dest]
+type=aor
+contact=sip:first@127.0.0.1:5061
+max_contacts=1
+
+[first_dest]
+type=endpoint
+context=default
+aors=first_dest
+direct_media=no
+disallow=all
+allow=ulaw
+redirect_method=uri_pjsip
diff --git a/tests/channels/pjsip/message/message_redirect/sipp/final_destination.xml b/tests/channels/pjsip/message/message_redirect/sipp/final_destination.xml
new file mode 100644
index 000000000..af8690c33
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect/sipp/final_destination.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect/sipp/redirect_305.xml b/tests/channels/pjsip/message/message_redirect/sipp/redirect_305.xml
new file mode 100644
index 000000000..c1be62315
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect/sipp/redirect_305.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect/test-config.yaml b/tests/channels/pjsip/message/message_redirect/test-config.yaml
new file mode 100644
index 000000000..c17071eb4
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect/test-config.yaml
@@ -0,0 +1,51 @@
+testinfo:
+ summary: 'Test MESSAGE redirect with 305 Use Proxy'
+ description: |
+ 'This test verifies that when an outgoing SIP MESSAGE receives a 305
+ redirect response, Asterisk properly follows the redirect to the URI
+ specified in the Contact header. The endpoint is configured with
+ redirect_method=uri_pjsip.
+
+ Test flow:
+ 1. AMI MessageSend action triggers MESSAGE to first_dest endpoint
+ 2. SIPp scenario at port 5061 responds with 305 Use Proxy
+ 3. 305 response contains Contact header with redirected destination
+ 4. Asterisk sends new MESSAGE to the redirected URI
+ 5. SIPp scenario at port 5062 receives redirected MESSAGE and responds 202'
+
+properties:
+ dependencies:
+ - app: 'sipp'
+ - asterisk: 'res_pjsip'
+ - asterisk: 'res_pjsip_messaging'
+ tags:
+ - pjsip
+
+test-modules:
+ test-object:
+ config-section: test-object-config
+ typename: 'sipp.SIPpTestCase'
+ modules:
+ -
+ config-section: ami-config
+ typename: 'pluggable_modules.EventActionModule'
+
+test-object-config:
+ reactor-timeout: 15
+ connect-ami: true
+ stop-after-scenarios: true
+ test-iterations:
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'redirect_305.xml', '-p': '5061'}}
+ - {'key-args': {'scenario': 'final_destination.xml', '-p': '5062'}}
+
+ami-config:
+ -
+ ami-start:
+ ami-actions:
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender@asterisk'
+ Body: 'My test redirect message'
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/extensions.conf b/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/extensions.conf
new file mode 100644
index 000000000..ec5f926af
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/extensions.conf
@@ -0,0 +1,3 @@
+[default]
+exten => s,1,NoOp()
+ same => n,Hangup()
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/pjsip.conf b/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/pjsip.conf
new file mode 100644
index 000000000..e22760ac3
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/configs/ast1/pjsip.conf
@@ -0,0 +1,18 @@
+[local]
+type=transport
+protocol=udp
+bind=0.0.0.0
+
+[first_dest]
+type=aor
+contact=sip:first@127.0.0.1:5061
+max_contacts=1
+
+[first_dest]
+type=endpoint
+context=default
+aors=first_dest
+direct_media=no
+disallow=all
+allow=ulaw
+redirect_method=uri_pjsip
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_accept.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_accept.xml
new file mode 100644
index 000000000..c913fb6ba
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_accept.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_redirect_loop.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_redirect_loop.xml
new file mode 100644
index 000000000..0e443deb9
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_redirect_loop.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_reject.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_reject.xml
new file mode 100644
index 000000000..da467d6cf
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact1_reject.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_accept.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_accept.xml
new file mode 100644
index 000000000..77bf7d229
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_accept.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_redirect_loop.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_redirect_loop.xml
new file mode 100644
index 000000000..175a76b22
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_redirect_loop.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_reject.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_reject.xml
new file mode 100644
index 000000000..ebae68032
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact2_reject.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact3_reject.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact3_reject.xml
new file mode 100644
index 000000000..4287f451c
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/contact3_reject.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/no_message_expected.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/no_message_expected.xml
new file mode 100644
index 000000000..25ff4af06
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/no_message_expected.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ ;tag=[pid]SIPpTag00[call_number]
+ To: sip:127.0.0.1
+ Call-ID: [call_id]
+ CSeq: 1 OPTIONS
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/sipp/redirect_305_three_contacts.xml b/tests/channels/pjsip/message/message_redirect_multiple/sipp/redirect_305_three_contacts.xml
new file mode 100644
index 000000000..0578ff11e
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/sipp/redirect_305_three_contacts.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ;q=1.0
+ Contact: ;q=0.5
+ Contact: ;q=0.1
+ Content-Length: 0
+
+ ]]>
+
+
+
+
+
diff --git a/tests/channels/pjsip/message/message_redirect_multiple/test-config.yaml b/tests/channels/pjsip/message/message_redirect_multiple/test-config.yaml
new file mode 100644
index 000000000..24a060d16
--- /dev/null
+++ b/tests/channels/pjsip/message/message_redirect_multiple/test-config.yaml
@@ -0,0 +1,102 @@
+testinfo:
+ summary: 'Test MESSAGE redirect with 305 Use Proxy - multiple Contact headers'
+ description: |
+ 'This test verifies that when an outgoing SIP MESSAGE receives a 305
+ redirect response with multiple Contact headers having different q-values,
+ Asterisk properly follows the redirect to the URIs in order of q-value
+ priority. The endpoint is configured with redirect_method=uri_pjsip.
+
+ Test iterations:
+ 1. First contact (q=1.0) accepts - verify only highest priority is tried
+ 2. First contact rejects, second accepts - verify failover to next q-value
+ 3. All contacts reject - verify all contacts are tried in q-value order
+ 4. Loop prevention - verify redirect loops are detected and stopped'
+
+properties:
+ dependencies:
+ - app: 'sipp'
+ - asterisk: 'res_pjsip'
+ - asterisk: 'res_pjsip_messaging'
+ tags:
+ - pjsip
+
+test-modules:
+ test-object:
+ config-section: test-object-config
+ typename: 'sipp.SIPpTestCase'
+ modules:
+ -
+ config-section: ami-config
+ typename: 'pluggable_modules.EventActionModule'
+
+test-object-config:
+ reactor-timeout: 20
+ connect-ami: true
+ stop-after-scenarios: true
+ test-iterations:
+ # Iteration 1: First contact (q=1.0) accepts
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'redirect_305_three_contacts.xml', '-p': '5061'}}
+ - {'key-args': {'scenario': 'contact1_accept.xml', '-p': '5062'}}
+ - {'key-args': {'scenario': 'no_message_expected.xml', '-p': '5063', '-default_behaviors': 'abortunexp'}}
+ - {'key-args': {'scenario': 'no_message_expected.xml', '-p': '5064', '-default_behaviors': 'abortunexp'}}
+ # Iteration 2: First contact rejects (4xx), second accepts
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'redirect_305_three_contacts.xml', '-p': '5061'}}
+ - {'key-args': {'scenario': 'contact1_reject.xml', '-p': '5062'}}
+ - {'key-args': {'scenario': 'contact2_accept.xml', '-p': '5063'}}
+ - {'key-args': {'scenario': 'no_message_expected.xml', '-p': '5064', '-default_behaviors': 'abortunexp'}}
+ # Iteration 3: All contacts reject (4xx)
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'redirect_305_three_contacts.xml', '-p': '5061'}}
+ - {'key-args': {'scenario': 'contact1_reject.xml', '-p': '5062'}}
+ - {'key-args': {'scenario': 'contact2_reject.xml', '-p': '5063'}}
+ - {'key-args': {'scenario': 'contact3_reject.xml', '-p': '5064'}}
+ # Iteration 4: Loop prevention - contact1 redirects to contact2, which redirects back to contact1
+ -
+ scenarios:
+ - {'key-args': {'scenario': 'redirect_305_three_contacts.xml', '-p': '5061'}}
+ - {'key-args': {'scenario': 'contact1_redirect_loop.xml', '-p': '5062'}}
+ - {'key-args': {'scenario': 'contact2_redirect_loop.xml', '-p': '5063'}}
+ - {'key-args': {'scenario': 'no_message_expected.xml', '-p': '5064', '-default_behaviors': 'abortunexp'}}
+
+ami-config:
+ -
+ ami-start:
+ ami-actions:
+ -
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender-iter1@asterisk'
+ Body: 'Iteration 1: first contact accepts'
+ -
+ ami-start:
+ ami-actions:
+ -
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender-iter2@asterisk'
+ Body: 'Iteration 2: first rejects, second accepts'
+ -
+ ami-start:
+ ami-actions:
+ -
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender-iter3@asterisk'
+ Body: 'Iteration 3: all contacts reject'
+ -
+ ami-start:
+ ami-actions:
+ -
+ action:
+ Action: 'MessageSend'
+ To: 'pjsip:first_dest'
+ From: 'sip:sender-iter4@asterisk'
+ Body: 'Iteration 4: loop prevention test'
diff --git a/tests/channels/pjsip/message/tests.yaml b/tests/channels/pjsip/message/tests.yaml
index bc99fa04c..1dc789675 100644
--- a/tests/channels/pjsip/message/tests.yaml
+++ b/tests/channels/pjsip/message/tests.yaml
@@ -7,6 +7,9 @@ tests:
- test: 'message_from'
- test: 'message_in_dialog'
- test: 'message_retrans'
+ - test: 'message_redirect'
+ - test: 'message_no_redirect_method'
+ - test: 'message_redirect_multiple'
- test: 'message_send_ami'
- test: 'message_to_uri'
- test: 'message_confbridge'