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