register thread in python

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

 



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

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 ?

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)



[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