Клиент PyVoIP не отвечает на SIP OPTIONS, отправленные SIP-сервером.

Вопрос или проблема

Я пытаюсь создать SIP-клиент, который записывает все входящие звонки. Я использую Python и библиотеку pyVoIP, вот код:

from pyVoIP.VoIP import VoIPPhone, CallState, PhoneStatus, InvalidStateError
import time
import datetime

def answer(call): # Это функция обратного вызова, которая срабатывает при получении телефонного звонка

   try:
     print(call.state)
     anum = call.request.headers["From"]["number"]
     print(',' + datetime.datetime.now().strftime("%Y%m%d") + ', ' + datetime.datetime.now().strftime("%X") + ', ' + datetime.datetime.now().strftime("%f") + ',,,,,,,' + anum + ',0662279775,,,')
     open('tmp.csv', 'w+')
     f.write(',' + datetime.datetime.now().strftime("%Y%m%d") + ', ' + datetime.datetime.now().strftime("%X") + ', ' + datetime.datetime.now().strftime("%f") + ',,,,,,,' + anum + ',0662279775,,,')
     print(anum)
     call.answer()
     call.hangup()
   except InvalidStateError:
     print(InvalidStateError)
     pass

if __name__ == "__main__":
   vp = VoIPPhone('79.98.45.133', 5060, '0662279775', '065+eMl6Ttd6$T', callCallback=answer)
   print('VOIP PHONE ИНИЦИАЛИЗИРОВАН: статус="' + str(vp._status))
   vp.start()
   print("VoIP PHONE ЗАПУЩЕН: статус=" + str(vp._status))
   while(vp._status == PhoneStatus.REGISTERING or vp._status == PhoneStatus.INACTIVE):
     continue
   print("STATUS ЦИКЛА WHILE ЗАВЕРШЕН: статус=" + str(vp._status))
   input("Нажмите ENTER, чтобы остановить")
   time.sleep(5)
   vp.stop()
   print('VOIP PHONE ОСТАНОВЛЕН: статус="' + str(vp._status))
   time.sleep(5)

Фаза регистрации проходит успешно, клиент может зарегистрироваться на SIP-сервере, и я получаю:

STATUS ЦИКЛА WHILE ЗАВЕРШЕН: статус = PhoneStatus.REGISTERED

Когда я перезваниваю на номер, связанный с SIP-аккаунтом, иногда звонок принимается клиентом, а иногда нет. Я сделал трассировку SIP-пакета, полученного клиентом, и вижу, что SIP-сервер отправляет сообщения OPTIONS клиенту, но клиент не отвечает на них. Я предполагаю, что в этом проблема: сервер не получает ответа на сообщения OPTIONS, поэтому считает, что клиент неактивен и не перенаправляет звонок клиенту.

Есть ли способ настроить pyVoIP для ответа на сообщения OPTIONS?

Ответ или решение

Ваша проблема действительно может быть связана с тем, что клиент PyVoIP не отвечает на SIP OPTIONS сообщения, отправляемые SIP-сервером. Это может вызвать проблемы с поддержанием статуса регистрации клиента, в результате чего сервер может считать клиента недоступным, не перенаправляя вызовы. Рассмотрим, как можно решить эту проблему.

1. Обработка SIP OPTIONS

В библиотеке PyVoIP не всегда непосредственно предусмотрена обработка SIP OPTIONS, поэтому вам нужно убедиться, что клиент отвечает на эти сообщения. Можно добавить собственную обработку сообщений, в том числе для OPTIONS. Вам нужно будет создать метод для обработки входящих SIP-сообщений и определить, как реагировать на OPTIONS.

Вот пример кода, который показывает, как можно обработать SIP OPTIONS:

from pyVoIP.VoIP import VoIPPhone, CallState, PhoneStatus, InvalidStateError
import time
import datetime

def handle_incoming_message(message):
    if message.method == 'OPTIONS':
        # Отправляем ответ на OPTIONS
        response = message.create_response(200, "OK")
        message.send_response(response)

def answer(call):
    try:
        print(call.state)
        anum = call.request.headers["From"]["number"]
        print(',' + datetime.datetime.now().strftime("%Y%m%d") + ', ' + datetime.datetime.now().strftime("%X") + ', ' + datetime.datetime.now().strftime("%f") + ',,,,,,,' + anum + ',0662279775,,,')
        with open('tmp.csv', 'a') as f:
            f.write(',' + datetime.datetime.now().strftime("%Y%m%d") + ', ' + datetime.datetime.now().strftime("%X") + ', ' + datetime.datetime.now().strftime("%f") + ',,,,,,,' + anum + ',0662279775,,,\n')
        print(anum)
        call.answer()
        call.hangup()
    except InvalidStateError as e:
        print(e)
        pass

if __name__ == "__main__":
    vp = VoIPPhone('79.98.45.133', 5060, '0662279775', '065+eMl6Ttd6$T',
                   callCallback=answer, messageCallback=handle_incoming_message)
    print('VOIP PHONE INITIALIZED: status=' + str(vp._status))
    vp.start()
    print("VoIP PHONE STARTED: status=" + str(vp._status))

    while (vp._status == PhoneStatus.REGISTERING or vp._status == PhoneStatus.INACTIVE):
        continue

    print("WHILE LOOP STATUS ENDED: status=" + str(vp._status))
    input("Press ENTER to stop")
    time.sleep(5)
    vp.stop()
    print('STOPPED VOIP PHONE: status=' + str(vp._status))
    time.sleep(5)

2. Обратите внимание на следующее:

  • Использование create_response: В коде вы должны создать ответ на OPTIONS с помощью метода create_response, передав корректные код и текст ответа.
  • Логика обработки сообщений: Убедитесь, что сообщения, которые ваш клиент принимает, проверяются на предмет метода OPTIONS. Это предположение может быть дополнительно уточнено в зависимости от специфики библиотеки.
  • Отключение из register: Не забудьте запускать метод vp.stop() корректно, чтобы не вызвать потенциальные утечки ресурсов.

3. Рекомендации

  • Документация
    Поскольку библиотека PyVoIP не является широко распространенной, обязательно обращайтесь к ее документации для получения информации о возможностях и примерах использования.

  • Отладка:
    Используйте пакетный анализатор, такой как Wireshark, чтобы убедиться, что ваш клиент действительно не отвечает на OPTIONS и отслеживать весь SIP-трафик для дальнейших шагов отладки.

Следуя приведенным рекомендациям, вы сможете убедиться, что ваш SIP-клиент отвечает на OPTIONS сообщения и решает вашу проблему с недоступностью.

Оцените материал
Добавить комментарий

Капча загружается...