У меня есть настольное приложение для Windows, сделанное моим провайдером мобильной сети, которое делает все виды с помощью SIP: вызов, отправка сообщения и т. Д. Снимок экрана о том, как это приложение успешно отправляет сообщение MESSAGE
(последние 4 строки):
Запрос MESSAGE
из настольного приложения отправляется как (4-я строка сзади):
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
и успешный ответ для этого:
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"
Затем я пытаюсь отправить идентичный (и n-варианты) запрос с PHP, но я всегда получаю SIP/2.0 403 Forbidden
вместо 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
Самое смешное, что если я отправлю запрос REGISTER
он будет работать, и я успешно получаю SIP/2.0 401 Unauthorized
заголовок с WWW-Authenticate
. Я пересчитываю авторизацию и повторно отправляю ее. Затем я получаю SIP/2.0 200 OK
. Вот как это должно работать с MESSAGE
.
Что может быть неправильным? Что я упустил? Перед запросом MESSAGE
требуется какой-либо другой запрос (я уже пробовал REGISTER
раньше)?
Я прочитал RFC 3428 вверх и вниз, попробовал все возможные примеры, но безуспешно.
Если вы просмотрите полученный ответ 403, вы увидите заголовок Reason. Строка Q.850 в начале указывает, что это будет код причины, определяемый Рекомендацией МСЭ-Т.
В частности, приведенный код причины 55 относится к ISDN и литературным средствам «Входящие вызовы, запрещенные в пределах Закрытой группы пользователей» (вы можете проверить это в RFC 3398 ) и, как правило, означает, что в пределах группы участников прием вызова ограничен.
С другой стороны, причина 55 также указывает на проблему в запросе, особенно в отношении пользователя (отправителя или получателя). На следующей диаграмме показан обычный обмен MESSAGE между пользователями SIP:
A Server B | REGISTER | | |--------------->| | | 200 OK | | |<---------------| | | | REGISTER | | |<--------------| | | 200 OK | | |-------------->| | MESSAGE | | |--------------->| MESSAGE | | |-------------->| | | 200 OK | | |<--------------| | 200 OK | | |<---------------| |
На самом деле, был строгим, REGISTER от пользователя A не требуется, но большинство систем (например, IMS) использует его как механизм аутентификации. Затем, в запросе REGISTER, специальные заголовки:
Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT> Expires: REGISTRATION_DURATION
Имейте в виду, что 200 OK отвечает на РЕГИСТР, может содержать заголовок Expires:
или параметр expires
внутри заголовка Contact:
который указывает принятое время истечения срока действия. Например:
SIP/2.0 200 OK ... Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT>; expires=60 ...
В этой ситуации вы должны повторно зарегистрироваться до истечения этого срока (60 секунд в примере).
Помня о том, что вы пытаетесь отправить SMS на мобильный телефон, точка приема напрямую управляется MGCF вашего сетевого провайдера, поэтому это оставляет регистрацию отправителя или запрос MESSAGE.
О вашем исходном предложении MESSAGE, запросить URI (первая строка сообщения), должно быть:
MESSAGE sip:TO@DOMAIN SIP/2.0
Потому что это относится к сущности приема MESSAGE.
Надеюсь это поможет.
Как я уже говорил вам в комментариях, я не эксперт по SIP, а мой друг. Я спросил его о вашем случае, и вот что он сказал мне:
Протокол SIP является протоколом диалога, означающим, что каждое сообщение представляет собой диалог с уникальным идентификатором диалога (что-то вроде идентификатора сеанса в HTTP). Разница между SIP и HTTP заключается в том, что идентификатор сеанса используется между различными соединениями TPC / IP (HTTP-запросы), в то время как идентификатор диалога используется в одном и том же соединении TPC / IP, но среди разных сообщений.
Мне кажется, что вы пытаетесь сделать здесь несколько похоже на захват сеанса в HTTP. Хотя можно захватить идентификатор сеанса в HTTP и отправить его другому клиенту, то же самое не для SIP. По словам моего друга, SIP-серверы имеют внутреннюю память, с которой идентификатор диалога принадлежит тому соединению, и вы не можете пропустить ваши сообщения в чужой диалог, просто зная их идентификатор диалога.
В вашем вопросе не говорится, действительно ли это то, что вы пытаетесь сделать, но если это так, то я должен сказать, что вы не можете. Тот факт, что вы можете отправить команду REGISTER
показывает, что ваша связь с сервером SIP выполнена. Все, что вам нужно сделать, это инициировать свой собственный диалог и взять его оттуда.