register thread in python

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 9, 2008 at 8:16 PM, Krzysztof Adamczak <kradamcz at gmail.com>
wrote:

> Hi,
>
> I have a problem with registering threads (via method
> py_pjsua.thread_register()). I attached a complete code below. The
> interesting part is at the bottom in the "for" loop (rest is taken from
> Python example from site). When I make call from the same thread
> everything is ok (actual code). When i uncomment first line in the loop
> (and comment second) i have error:
> Assertion failed: !"Calling pjlib from unknown/external thread. You must
> " "register external threads with pj_thread_register() " "before calling
> any pjlib functions.", file ../src/pj/os_core_win32.c, line 521
>


Actually just few lines above your func() you can see how to register a
Python thread ( the worker_thread_main() function).


>
> My question is - where should i put thread registration code ? What
> about function app_init() and add_account() - should i call this methods
> in each thread ?
>

Creating a thread for every function doesn't sound like a good idea.

Cheers
 Benny



>
> Any help is appreciated.
>
> Chris
>
>
> import py_pjsua
> import sys
> import thread
>
> # Globals
> #
> g_ua_cfg = None
> g_acc_id = py_pjsua.PJSUA_INVALID_ID
> g_current_call = py_pjsua.PJSUA_INVALID_ID
> g_wav_files = []
> g_wav_id = 0
> g_wav_port = 0
> g_rec_file = ""
> g_rec_id = 0
> g_rec_port = 0
>
> #
> # Configurations
> #
> THIS_FILE = "SIPSender.py"
> C_QUIT = 0
> C_LOG_LEVEL = 4
>
> # STUN config.
> # Set C_STUN_HOST to the address:port of the STUN server to enable STUN
> #
> C_STUN_HOST = ""
> #C_STUN_HOST = "192.168.0.2"
> #C_STUN_HOST = "stun.iptel.org:3478"
>
> # SIP port
> C_SIP_PORT = 5061
>
> # Utility: display PJ error and exit
> #
> def err_exit(title, rc):
>    py_pjsua.perror(THIS_FILE, title, rc)
>    py_pjsua.destroy()
>    exit(1)
>
>
> # Logging function (also callback, called by pjsua-lib)
> #
> def log_cb(level, str, len):
>    print(str)
>
> def write_log(level, str):
>    log_cb(level, "LOGGER " + str + "\n", 0)
>
>
> # Utility to get call info
> #
> def call_name(call_id):
>    ci = py_pjsua.call_get_info(call_id)
>    return "[Call " + `call_id` + " " + ci.remote_info + "]"
>
> # Callback when call state has changed.
> #
> def on_call_state(call_id, e):
>    global g_current_call
>    ci = py_pjsua.call_get_info(call_id)
>    write_log(3, call_name(call_id) + " state = " + `ci.state_text`)
>    if ci.state == py_pjsua.PJSIP_INV_STATE_DISCONNECTED:
>        g_current_call = py_pjsua.PJSUA_INVALID_ID
>
> # Callback for incoming call
> #
> def on_incoming_call(acc_id, call_id, rdata):
>    global g_current_call
>
>    if g_current_call != py_pjsua.PJSUA_INVALID_ID:
>        # There's call in progress - answer Busy
>        py_pjsua.call_answer(call_id, 486, None, None)
>        return
>
>    g_current_call = call_id
>    ci = py_pjsua.call_get_info(call_id)
>    write_log(3, "*** Incoming call: " + call_name(call_id) + "***")
>    write_log(3, "*** Press a to answer or h to hangup  ***")
>
>
>
> # Callback when media state has changed (e.g. established or terminated)
> #
> def on_call_media_state(call_id):
>    ci = py_pjsua.call_get_info(call_id)
>    if ci.media_status == py_pjsua.PJSUA_CALL_MEDIA_ACTIVE:
>        py_pjsua.conf_connect(ci.conf_slot, 0)
>        py_pjsua.conf_connect(0, ci.conf_slot)
>        write_log(3, call_name(call_id) + ": media is active")
>    else:
>        write_log(3, call_name(call_id) + ": media is inactive")
>
>
> # Callback when account registration state has changed
> #
> def on_reg_state(acc_id):
>    acc_info = py_pjsua.acc_get_info(acc_id)
>    if acc_info.has_registration != 0:
>        cmd = "registration"
>    else:
>        cmd = "unregistration"
>    if acc_info.status != 0 and acc_info.status != 200:
>        write_log(3, "Account " + cmd + " failed: rc=" +
> `acc_info.status` + " " + acc_info.status_text)
>    else:
>        write_log(3, "Account " + cmd + " success")
>
>
> # Received the status of previous call transfer request
> #
> def on_call_transfer_status(call_id, status_code, status_text, final,
> p_cont):
>    strfinal = ""
>    if final == 1:
>        strfinal = "[final]"
>
>    write_log(3, "Call " + `call_id` + ": transfer status= " +
> `status_code` + " " + status_text+ " " + strfinal)
>
>    if status_code/100 == 2:
>        write_log(3, "Call " + `call_id` + " : call transfered
> successfully, disconnecting call")
>        status = py_pjsua.call_hangup(call_id, 410, None, None)
>        p_cont = 0
>
> # Callback on incoming call transfer request
> #
> def on_call_transfer_request(call_id, dst, code):
>    write_log(3, "Call transfer request from " + `call_id` + " to " +
> dst + " with code " + `code`)
>
> #
> # Initialize pjsua.
> #
> def app_init():
>    global g_acc_id, g_ua_cfg
>
>    # Create pjsua before anything else
>    status = py_pjsua.create()
>    if status != 0:
>        err_exit("pjsua create() error", status)
>
>    # Create and initialize logging config
>    log_cfg = py_pjsua.logging_config_default()
>    log_cfg.level = C_LOG_LEVEL
>    log_cfg.cb = log_cb
>
>    # Create and initialize pjsua config
>    # Note: for this Python module, thread_cnt must be 0 since Python
>    #       doesn't like to be called from alien thread (pjsua's thread
>    #       in this case)
>    ua_cfg = py_pjsua.config_default()
>    ua_cfg.thread_cnt = 0
>    ua_cfg.user_agent = "PJSUA/Python 0.1"
>    ua_cfg.cb.on_incoming_call = on_incoming_call
>    ua_cfg.cb.on_call_media_state = on_call_media_state
>    ua_cfg.cb.on_reg_state = on_reg_state
>    ua_cfg.cb.on_call_state = on_call_state
>    ua_cfg.cb.on_call_transfer_status = on_call_transfer_status
>    ua_cfg.cb.on_call_transfer_request = on_call_transfer_request
>
>    # Configure STUN setting
>    if C_STUN_HOST != "":
>        ua_cfg.stun_host = C_STUN_HOST;
>
>    # Create and initialize media config
>    med_cfg = py_pjsua.media_config_default()
>    med_cfg.ec_tail_len = 0
>
>    #
>    # Initialize pjsua!!
>    #
>    status = py_pjsua.init(ua_cfg, log_cfg, med_cfg)
>    if status != 0:
>        err_exit("pjsua init() error", status)
>
>    # Configure UDP transport config
>    transport_cfg = py_pjsua.transport_config_default()
>    transport_cfg.port = C_SIP_PORT
>
>    # Create UDP transport
>    status, transport_id = \
>        py_pjsua.transport_create(py_pjsua.PJSIP_TRANSPORT_UDP,
> transport_cfg)
>    if status != 0:
>        err_exit("Error creating UDP transport", status)
>
>
>    # Create initial default account
>    status, acc_id = py_pjsua.acc_add_local(transport_id, 1)
>    if status != 0:
>        err_exit("Error creating account", status)
>
>    g_acc_id = acc_id
>    g_ua_cfg = ua_cfg
>    print g_acc_id
>
> # Add SIP account interractively
> #
> def add_account():
>    global g_acc_id
>
>    acc_domain = "localhost"
>    acc_username = "1000"
>    acc_passwd ="1234"
>    confirm = ""
>
>    # Configure account configuration
>    acc_cfg = py_pjsua.acc_config_default()
>    acc_cfg.id = "sip:" + acc_username + "@" + acc_domain
>    acc_cfg.reg_uri = "sip:" + acc_domain
>
>    cred_info = py_pjsua.Pjsip_Cred_Info()
>    cred_info.realm = "*"
>    cred_info.scheme = "digest"
>    cred_info.username = acc_username
>    cred_info.data_type = 0
>    cred_info.data = acc_passwd
>
>    acc_cfg.cred_info.append(1)
>    acc_cfg.cred_info[0] = cred_info
>
>    # Add new SIP account
>    status, acc_id = py_pjsua.acc_add(acc_cfg, 1)
>    if status != 0:
>        py_pjsua.perror(THIS_FILE, "Error adding SIP account", status)
>    else:
>        g_acc_id = acc_id
>        write_log(3, "Account " + acc_cfg.id + " added")
>
>    return
>
> #
> # Worker thread function.
> # Python doesn't like it when it's called from an alien thread
> # (pjsua's worker thread, in this case), so for Python we must
> # disable worker thread in pjsua and poll pjsua from Python instead.
> #
> def worker_thread_main(arg):
>    global C_QUIT
>    thread_desc = 0;
>    status = py_pjsua.thread_register("python worker", thread_desc)
>    if status != 0:
>        py_pjsua.perror(THIS_FILE, "Error registering thread", status)
>    else:
>        while C_QUIT == 0:
>            py_pjsua.handle_events(50)
>        print "Worker thread quitting.."
>        C_QUIT = 2
>
>
> # Start pjsua
> #
> def app_start():
>    # Done with initialization, start pjsua!!
>    #
>    status = py_pjsua.start()
>    if status != 0:
>       err_exit("Error starting pjsua!", status)
>
>    # Start worker thread
>    thr = thread.start_new(worker_thread_main, (0,))
>
>    print "PJSUA Started!!"
>
> def func(arg):
>    print str(thread.get_ident()) + " calls " + str(arg)
>    status, call_id = py_pjsua.call_make_call(g_acc_id, "sip:" +
> str(arg) + "@192.168.169.99", 0, 0, None)
>
>    if status != 0:
>        py_pjsua.perror(THIS_FILE, "Error making call", status)
>    else:
>        g_current_call = call_id
>
>    time.sleep(5)
>    py_pjsua.call_hangup(g_current_call, 603, None, None)
>
>
> # Main thread
> app_init()
> add_account()
> app_start()
>
> for i in range(1001,1002):
>    #thread.start_new_thread(func, (i, ))
>    status, call_id = py_pjsua.call_make_call(g_acc_id, "sip:" + str(i)
> + "@213.134.170.23", 0, 0, None)
>
> import time
> time.sleep(10)
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20080709/93117443/attachment-0001.html 


[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux