Q:

How to send instant message via SIP

I have a windows desktop application, made by my mobile network provider, that does all kind of things with SIP: call, send message, etc. Screenshot of how does this app successfully send MESSAGE (the last 4 lines):

MESSAGE request, from desktop application, is sent as (4th line from behind) :
MESSAGE sip:FROM@DOMAIN SIP/2.0
Via: SIP/2.0/UDP LOCALIP:2112;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport
Max-Forwards: 70
To: "TO"<sip:TO@DOMAIN>
From: "FROM"<sip:USERNAME@DOMAIN>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: text/plain
Content-Length: 4

test

and successfull response for that is:
SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/UDP LOCALIP:2112;received=EXTERNALIP;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport=2112
To: "TO"<sip:TO@DOMAIN>;tag=c005f0e30133ec730add76fc91f4bea
From: "FROM"<sip:USERNAME@DOMAIN>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Content-Length: 0
Proxy-Authenticate: Digest nonce="3F178051B97E1F52000123000A3C53D4B",realm="DOMAIN",algorithm=MD5,qop="auth"

Then I try to send identical (and n-variations) request from PHP, but I always receive SIP/2.0 403 Forbidden instead of SIP/2.0 407 Proxy Authentication Required:
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP LOCALIP;received=EXTERNALIP
To: "TO"<sip:TO@DOMAIN>;tag=aprqngfrt-f7ccjj0000020
From: "FROM"<sip:USERNAME@DOMAIN>;tag=8f7be81d
Call-ID: 526576901edcc@localhost
CSeq: 1 MESSAGE
Reason: Q.850;cause=55;text="Call Terminated"
Content-Length: 0

The funny part is, that if I send REGISTER request it works, and I successfully receive SIP/2.0 401 Unauthorized header with WWW-Authenticate. I recalculate authorization, and resend it. Then I receive SIP/2.0 200 OK. Which is how it should work with MESSAGE.
What could be wrong? What did I miss? Does MESSAGE request need some other request before that (I have already tried REGISTER before)?I have read RFC 3428 up and down, tried all the examples possible, but without success.

A:

If you look into received 403 response, you'll notice a Reason header. The Q.850 string at the beginning indicates that this would be a cause code defined by ITU-T Recomendation. 
Specifically, provided cause code 55 is related to ISDN and literary means "Incoming calls barred within Closed User Group" (you can check it in RFC 3398) and, usually, means that, within a group of members, call reception is restricted.
On the other hand, cause 55 also denotes a problem within the request, specially in relation to a user (sender or receiver). Following diagram shows a normal MESSAGE exchange between SIP users:
      A             Server             B
      |    REGISTER    |               |
      |--------------->|               |
      |     200 OK     |               |
      |<---------------|               |
      |                |    REGISTER   |
      |                |<--------------|          
      |                |     200 OK    |
      |                |-------------->|
      |    MESSAGE     |               |
      |--------------->|    MESSAGE    |
      |                |-------------->|
      |                |     200 OK    |
      |                |<--------------|
      |     200 OK     |               |
      |<---------------|               |

Actually, been strict, REGISTER from user A is not needed but most systems (like IMS) uses it as an authentication mechanism. Then, in REGISTER request, special headers are:
Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT>
Expires: REGISTRATION_DURATION

Keep in mind that, 200 OK answers to a REGISTER, can contain an Expires: header or an expires parameter inside Contact: header that indicates accepted expiration time. For example:
SIP/2.0 200 OK
...
Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT>; expires=60 
...

In this situation, you should re-REGISTER before this expiration time (60 seconds in the example).
Keeping in mind that you're trying to send an SMS to a mobile phone, reception point is directly managed by your network provider's MGCF, so this leaves sender's registration or MESSAGE request.
About your original MESSAGE proposal, request URI (message's first line), should be:
 MESSAGE sip:TO@DOMAIN SIP/2.0

Because it refers to MESSAGE reception entity.
Hope this helps.

