moha-abdi / PySIP

An open-source Python library for easy VoIP call integration using SIP and SDP protocols. Simplify real-time communication and audio handling in your applications.
MIT License
3 stars 1 forks source link

SIP Registration Successful but Call Not Initiating #38

Open shakir-snakescript opened 1 month ago

shakir-snakescript commented 1 month ago

Hi @moha-abdi

I am working on a project involving SIP registration and call handling using the PySIP library. The SIP registration appears to be successful; however, when attempting to initiate a call to a test number, nothing happens. No function is triggered, and no call is placed.

import asyncio
import logging
from PySIP.sip_account import SipAccount
from scripts.appointment_booking_bot import appointment_booking_bot
from dotenv import load_dotenv

load_dotenv()
logger = logging.getLogger(__name__)

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger.debug("Environment variables loaded.")

# Monkey patch the SipCore class to handle None realm and nonce
from PySIP.sip_core import SipCore

original_generate_response = SipCore.generate_response

def patched_generate_response(self, method, nonce, realm, uri):
    if realm is None:
        realm = "tel-test-hk.callnovo.cn"
        logger.debug("Realm was None, set to default: tel-test-hk.callnovo.cn")
    if nonce is None:
        nonce = ""  # Use an empty string as a default nonce
        logger.debug("Nonce was None, set to default: empty string")
    return original_generate_response(self, method, nonce, realm, uri)

SipCore.generate_response = patched_generate_response
logger.info("SipCore.generate_response has been patched.")

# Initialize SipAccount
account = SipAccount(
    username="my_username",
    password="my_password",
    hostname="tel-test-hk.callnovo.cn:5080",
    connection_type="TCP"
)
logger.info("SipAccount initialized with username 'my_username'.")

async def main():
    logger.info("Starting main function.")
    try:
        # Register the SIP account
        logger.info("Registering SIP account.")
        await account.register()
        logger.info("SIP account registered successfully.")

        logger.info("Making a call to +11234567890.")
        call = account.make_call("1234567890")  # Using the provided test number
        call_task = asyncio.create_task(call.start())
        logger.debug("Call task created.")

        # Run the appointment booking bot
        logger.info("Running the appointment booking bot.")
        await appointment_booking_bot(call.call_handler, customer_name="John")

        # Wait for the call to complete
        logger.info("Waiting for the call to complete.")
        await call_task
        logger.info("Call completed.")

    except Exception as e:
        logger.error(f"An error occurred: {e}")
    finally:
        # Unregister the SIP account upon completion or error
        logger.info("Unregistering SIP account.")
        await account.unregister()
        logger.info("SIP account unregistered.")

if __name__ == "__main__":
    logger.info("Starting asyncio event loop.")
    asyncio.run(main())

Expected Behavior: After successfully registering the SIP account, when I make call to +11234567890. Any function should get triggered, for example: appointment_booking_bot. I would know that my call is now connected and I can do futher operations with it.

Actual Behavior: The SIP registration succeeds, but when attempting to place the call, nothing happens. No functions seem to be triggered after the account.make_call() method is invoked.

Additional Information:

I am using PySIP to manage SIP accounts and handle calls. Logging has been added, and no errors are logged during the call attempt. I’ve patched the SipCore.generate_response method to handle cases where the realm or nonce are None. Please let me know if further details are required. Any guidance on resolving this issue would be greatly appreciated!

Code output for your reference:

DEBUG:__main__:Environment variables loaded.
INFO:__main__:SipCore.generate_response has been patched.
INFO:__main__:SipAccount initialized with username '1003'.
INFO:__main__:Starting asyncio event loop.
DEBUG:asyncio:Using selector: EpollSelector
INFO:__main__:Starting main function.
INFO:__main__:Registering SIP account.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api64.ipify.org:443
DEBUG:urllib3.connectionpool:https://api64.ipify.org:443 "GET /?format=json HTTP/11" 200 22
2024-09-30 13:01:46,939 - PySIP.utils.logger - INFO - Sip Account: 1003 registered to the server.
INFO:PySIP.utils.logger:Sip Account: 1003 registered to the server.
INFO:__main__:SIP account registered successfully.
INFO:__main__:Making a call to +14087062613.
DEBUG:__main__:Call task created.
INFO:__main__:Running the appointment booking bot.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api64.ipify.org:443
DEBUG:urllib3.connectionpool:https://api64.ipify.org:443 "GET /?format=json HTTP/11" 200 22
2024-09-30 13:01:47,173 - PySIP.utils.logger - INFO - CallHandler has been initialized..
INFO:PySIP.utils.logger:CallHandler has been initialized..
DEBUG:__main__:Realm was None, set to default: tel-test-hk.callnovo.cn
DEBUG:__main__:Nonce was None, set to default: empty string
DEBUG:PySIP.utils.logger:Register message has been sent to the server
DEBUG:pydub.converter:subprocess.call(['ffmpeg', '-y', '-f', 'mp3', '-read_ahead_limit', '-1', '-i', 'cache:pipe:0', '-acodec', 'pcm_s16le', '-vn', '-f', 'wav', '-'])
DEBUG:PySIP.utils.logger:Started stream now - id (c37f01d2-8766-4f5e-ac2f-d6aaa73fbe53)
DEBUG:PySIP.utils.logger:Done preparing all frames in AudioStream
DEBUG:pydub.converter:subprocess.call(['ffmpeg', '-y', '-f', 'mp3', '-read_ahead_limit', '-1', '-i', 'cache:pipe:0', '-acodec', 'pcm_s16le', '-vn', '-f', 'wav', '-'])
DEBUG:PySIP.utils.logger:Started stream now - id (ec962f53-05ea-48af-92a6-ad671d97b725)
DEBUG:PySIP.utils.logger:Done preparing all frames in AudioStream
moha-abdi commented 1 month ago

Hello, from the logs I see that no rtp session was established, it could be because of the sdp session negotiation failure but normally this would have been logged. Can you please confirm if you received the call on the other end for example ringing or a missed call if not, the issue is most likely with the sdp negotiation and we will then go further of logging this and confirming then I will fix any issues and add any appropriate codecs missing. Thank you for your contriburion.

shakir-snakescript commented 1 month ago

I received no call on the other end. So, let me know how we can go further to diagnose the issue.

However, I would like to mention that my actual use case: When someone calls on my SIP test number, I want them to be transferred to my another number(AI voice agent). There is a library called PyVoIP in which I was successfully able to register the SIP and I dialled my test number from my mobile phone, a callback function actually got triggered but they didn't had call forwarding/transfer option.

So, in your case we want to register the SIP and then when someone makes the call on our number from their respective phones, our program will pick the call and will transfer to a desired phone number.

shakir-snakescript commented 1 month ago

Hi @moha-abdi

I'm curious about one thing, does your library supports the handling of incoming calls?

moha-abdi commented 1 month ago

I received no call on the other end. So, let me know how we can go further to diagnose the issue.

However, I would like to mention that my actual use case: When someone calls on my SIP test number, I want them to be transferred to my another number(AI voice agent). There is a library called PyVoIP in which I was successfully able to register the SIP and I dialled my test number from my mobile phone, a callback function actually got triggered but they didn't had call forwarding/transfer option.

So, in your case we want to register the SIP and then when someone makes the call on our number from their respective phones, our program will pick the call and will transfer to a desired phone number.

Good then the issue is with the sdp negotiation, it seems like your server is expecting some codecs that are not supported as the library only supports PCMA, PCMU codecs, but most sip servers support those two so we can further explore this. I would like to see the response of the OPTIONS request to the sip server if possible.

moha-abdi commented 1 month ago

Hi @moha-abdi

I'm curious about one thing, does your library supports the handling of incoming calls?

The current release doesn't fully support it. But the new release 1.8.0 supports handling incoming calls and its also integrated in the call handler, but currently I have to add some final touches to it before pushing the new release. Although i am curreny busy with other projects I will try to make time and add this ASAP. Stay tuned for the next few days as it will be released.