Hi All, I was trying to make work the latest asterisk (13.2.0) with the latest pjproject (2.3) both compiled from sources. They work pretty well, but when calling to/from softphones (in particular the latest Linphone v.3.7.0) the INVITE messages from asterisk are rejected due to the specification violation. Here are more people having the same problem: http://comments.gmane.org/gmane.comp.telephony.pbx.asterisk.user/281228 and http://lists.digium.com/pipermail/asterisk-dev/2003-July/001114.html. Linphone has a debug option: linphone.exe --logfile "c:\Temp\logs.txt" and in the generated logfile one can see something like: [error] Missing mandatory header [Max-Forwards] for message [INVITE] And this is what pjsip at asterisk sends to it: INVITE sip:6002 at 192.168.56.102 SIP/2.0 Via: SIP/2.0/UDP 192.168.56.3:5060;rport;branch=z9hG4bKPjbf53c93c-a424-4b9e-9e6a-b50d0e606965 From: <sip:6001@192.168.56.3>;tag=deeff9b9-50ab-410e-b683-94fdeb9f87b3 To: <sip:6002 at 192.168.56.102> Contact: <sip:9426fd27-7ccd-4e1e-ab7a-e6c27fc59a5c at 192.168.56.3:5060> Call-ID: 5b517cda-634b-4036-bb81-95a43379c09d CSeq: 6848 INVITE Allow: OPTIONS, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, REGISTER, MESSAGE, REFER Supported: 100rel, timer, replaces, norefersub Session-Expires: 1800 Min-SE: 90 Content-Type: application/sdp Content-Length:?? 254 So indeed, there is no "Max-Forwards" header send with the INVITE requests, but, according to the SIP RFC 3261: "A valid SIP request formulated by a UAC MUST, at a minimum, contain the following header fields: To, From, CSeq, Call-ID, Max-Forwards, and Via; all of these header fields are mandatory in all SIP requests." After researching a bit the source code of pjsip, I found that actually almost all messages originating from it don't have Max-Forwards fields. As a proof-of-concept, here is a patch that adds this header to the INVITE and ACK packets and with it the softphones work almost well. Almost, because there are more types of packets involved in a communication (like hanging up that doesn't work) and I've just patched 2 of them. Also, this patch doesn't decrease the value of the header as it should to when the message is relayed (Max-Forwards in SIP is like TTL field in IP), it's just a proof-of-concept. IMO, the better way would be to modify accordingly the functions like pjsip_endpt_create_request_from_hdr where the messages are created initially and where other mandatory fields are set, but it requires a better understanding of the project's code and SIP protocol in general than mine is (it's almost 0). As a side note, it would be great to have the initial Max-Forwards value configurable with the (already existing, but ignored) max_forwards option in [general] section. This problem is actually a show-stopper when there are softphones among the endpoints; so as for me for example, I have to stay with the old asterisk sip driver until this issue is solved. Regards, Anatoli A *demo* patch: --- pjproject-2.3/pjsip/src/pjsip-ua/sip_inv.c.orig? 2014-08-21 04:20:34.000000000 -0300 +++ pjproject-2.3/pjsip/src/pjsip-ua/sip_inv.c????? 2015-02-16 14:55:29.683566529 -0300 @@ -1679,6 +1679,15 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pj ??????? } ???? } + + +?????? // PATCH +?????? if (!pjsip_msg_find_hdr(tdata->msg, PJSIP_H_MAX_FORWARDS, NULL)) +?????????????? pjsip_msg_add_hdr(tdata->msg, pjsip_max_fwd_hdr_create(tdata->pool, 70)); +?????? // PATCH + + + ???? /* See if we have SDP to send. */ ???? if (inv->neg) { ??????? pjmedia_sdp_neg_state neg_state; @@ -2986,6 +2995,12 @@ PJ_DEF(pj_status_t) pjsip_inv_create_ack ??????? return status; ???? } + +?????? // PATCH +?????? pjsip_msg_add_hdr(inv->last_ack->msg, pjsip_max_fwd_hdr_create(inv->last_ack->pool, 70)); +?????? // PATCH + + ???? /* See if we have pending SDP answer to send */ ???? sdp = inv_has_pending_answer(inv, inv->invite_tsx); ???? if (sdp) { STEPS TO REPRODUCE: extensions.conf: [general] language=en static=yes writeprotect=no autofallthrough=yes [internal] exten => 6001,1,Answer() same => 2,Dial(PJSIP/6001,20) same => 3,Hangup() exten => 6002,1,Answer() same => 2,Dial(PJSIP/6002,20) same => 3,Hangup() pjsip.conf: [transport-udp] type=transport protocol=udp bind=192.168.56.3 [6001] type=endpoint transport=transport-udp context=internal allow=ulaw allow=gsm auth=6001 aors=6001 device_state_busy_at=1 allow_subscribe=yes sub_min_expiry=30 [6001] type=auth auth_type=userpass password=6001 username=6001 [6001] type=aor max_contacts=1 contact=sip:6001 at 192.168.56.101 [6002] type=endpoint transport=transport-udp context=internal allow=ulaw allow=gsm auth=6002 aors=6002 device_state_busy_at=1 allow_subscribe=yes sub_min_expiry=30 [6002] type=auth auth_type=userpass password=6002 username=6002 [6002] type=aor max_contacts=1 contact=sip:6002 at 192.168.56.102 Start asterisk: # /usr/sbin/asterisk Then configure the extensions in 2 Linphones (in wizard: user/pass = 600x/600x and domain: 192.168.56.3) and try to make a call from one Linphone to another.