summaryrefslogtreecommitdiff
path: root/pjsip-apps/src/py_pjsua
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-01-29 18:36:38 +0000
committerBenny Prijono <bennylp@teluu.com>2007-01-29 18:36:38 +0000
commit46a065a2a8ab12f09a4b116dc7da86067d924078 (patch)
treeac113a674a8387dd49438b87dfc066502687439c /pjsip-apps/src/py_pjsua
parentd35d3d1ff385ea2411940b536126025f8dcd6e7c (diff)
Some simple call testing to py_pjsua and bug fixes
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@916 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip-apps/src/py_pjsua')
-rw-r--r--pjsip-apps/src/py_pjsua/pjsua_app.py421
-rw-r--r--pjsip-apps/src/py_pjsua/py_pjsua.c178
2 files changed, 397 insertions, 202 deletions
diff --git a/pjsip-apps/src/py_pjsua/pjsua_app.py b/pjsip-apps/src/py_pjsua/pjsua_app.py
index 74817d32..5c8e6ed9 100644
--- a/pjsip-apps/src/py_pjsua/pjsua_app.py
+++ b/pjsip-apps/src/py_pjsua/pjsua_app.py
@@ -5,152 +5,328 @@ import thread
#
# Configurations
#
-APP = "pjsua_app.py"
+THIS_FILE = "pjsua_app.py"
C_QUIT = 0
-C_LOG_LEVEL = 3
+C_LOG_LEVEL = 4
-C_SIP_PORT = 5060
+# STUN config.
+# Set C_STUN_SRV to the address of the STUN server to enable STUN
+#
C_STUN_SRV = ""
+C_SIP_PORT = 5060
C_STUN_PORT = 3478
-C_ACC_REGISTRAR = ""
-#C_ACC_REGISTRAR = "sip:iptel.org"
-C_ACC_ID = "sip:bulukucing1@iptel.org"
-C_ACC_REALM = "iptel.org"
-C_ACC_USERNAME = "bulukucing1"
-C_ACC_PASSWORD = "netura"
-# Display PJ error and exit
+# Globals
+#
+g_acc_id = py_pjsua.PJSUA_INVALID_ID
+g_current_call = py_pjsua.PJSUA_INVALID_ID
+
+
+# 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 + "]"
+
+# Handler when invite 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 == 6:
+ g_current_call = py_pjsua.PJSUA_INVALID_ID
+
+# Handler 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:
+ py_pjsua.call_answer(call_id, 486, "", None)
+ return
+ g_current_call = call_id
+ ci = py_pjsua.call_get_info(call_id)
+ write_log(3, "Incoming call: " + call_name(call_id))
+ py_pjsua.call_answer(call_id, 200, "", None)
+
+
+# Handler 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 == 1:
+ 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")
+
+
+# Handler when account registration state has changed
+#
+def on_reg_state(acc_id):
+ acc_info = py_pjsua.acc_get_info(acc_id)
+ if acc_info.status != 0 and acc_info.status != 200:
+ write_log(3, "Account (un)registration failed: rc=" + `acc_info.status` + " " + acc_info.status_text)
+ else:
+ write_log(3, "Account successfully (un)registered")
+
+
+# Utility: display PJ error and exit
+#
def err_exit(title, rc):
- py_pjsua.perror(APP, title, rc)
+ py_pjsua.perror(THIS_FILE, title, rc)
exit(1)
-# Logging callback
+
+# Logging function (also callback, called by pjsua-lib)
+#
def log_cb(level, str, len):
- if level >= C_LOG_LEVEL:
+ if level <= C_LOG_LEVEL:
print str,
-# Initialize pjsua
+def write_log(level, str):
+ log_cb(level, str + "\n", 0)
+
+
+#
+# Initialize pjsua.
+#
def app_init():
- # 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
- ua_cfg = py_pjsua.config_default()
- ua_cfg.thread_cnt = 0
- ua_cfg.user_agent = "PJSUA/Python 0.1"
-
- # 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 STUN config
- stun_cfg = py_pjsua.stun_config_default()
- stun_cfg.stun_srv1 = C_STUN_SRV
- stun_cfg.stun_srv2 = C_STUN_SRV
- stun_cfg.stun_port1 = C_STUN_PORT
- stun_cfg.stun_port2 = C_STUN_PORT
-
- # Configure UDP transport config
- transport_cfg = py_pjsua.transport_config_default()
- transport_cfg.port = C_SIP_PORT
- transport_cfg.stun_config = stun_cfg
- if C_STUN_SRV != "":
- transport_cfg.use_stun = 1
-
- # Create UDP transport
- # Note: transport_id is supposed to be integer
- status, transport_id = py_pjsua.transport_create(1, transport_cfg)
- if status != 0:
- py_pjsua.destroy()
- err_exit("Error creating UDP transport", status)
-
-
- # Configure account configuration
- acc_cfg = py_pjsua.acc_config_default()
- acc_cfg.id = C_ACC_ID
- acc_cfg.reg_uri = C_ACC_REGISTRAR
- acc_cfg.cred_count = 1
- acc_cfg.cred_info[0].realm = C_ACC_REALM
- acc_cfg.cred_info[0].scheme = "digest"
- acc_cfg.cred_info[0].username = C_ACC_USERNAME
- acc_cfg.cred_info[0].data_type = 0
- acc_cfg.cred_info[0].data = C_ACC_PASSWORD
-
- # Add new SIP account
- # Note: acc_id is supposed to be integer
- status, acc_id = py_pjsua.acc_add(acc_cfg, 1)
- if status != 0:
- py_pjsua.destroy()
- err_exit("Error adding SIP account", status)
-
-
-# Worker thread function
+ global g_acc_id
+
+ # 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
+
+ # 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 STUN config
+ stun_cfg = py_pjsua.stun_config_default()
+ stun_cfg.stun_srv1 = C_STUN_SRV
+ stun_cfg.stun_srv2 = C_STUN_SRV
+ stun_cfg.stun_port1 = C_STUN_PORT
+ stun_cfg.stun_port2 = C_STUN_PORT
+
+ # Configure UDP transport config
+ transport_cfg = py_pjsua.transport_config_default()
+ transport_cfg.port = C_SIP_PORT
+ transport_cfg.stun_config = stun_cfg
+ if C_STUN_SRV != "":
+ transport_cfg.use_stun = 1
+
+ # Create UDP transport
+ status, transport_id = py_pjsua.transport_create(1, transport_cfg)
+ if status != 0:
+ py_pjsua.destroy()
+ 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:
+ py_pjsua.destroy()
+ err_exit("Error creating account", status)
+
+ g_acc_id = acc_id
+
+# Add SIP account interractively
+#
+def add_account():
+ global g_acc_id
+
+ acc_domain = ""
+ acc_username = ""
+ acc_passwd =""
+ confirm = ""
+
+ # Input account configs
+ print "Your SIP domain (e.g. myprovider.com): ",
+ acc_domain = sys.stdin.readline()
+ if acc_domain == "\n":
+ return
+ acc_domain = acc_domain.replace("\n", "")
+
+ print "Your username (e.g. alice): ",
+ acc_username = sys.stdin.readline()
+ if acc_username == "\n":
+ return
+ acc_username = acc_username.replace("\n", "")
+
+ print "Your password (e.g. secret): ",
+ acc_passwd = sys.stdin.readline()
+ if acc_passwd == "\n":
+ return
+ acc_passwd = acc_passwd.replace("\n", "")
+
+ # 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
+ acc_cfg.cred_count = 1
+ acc_cfg.cred_info[0].realm = acc_domain
+ acc_cfg.cred_info[0].scheme = "digest"
+ acc_cfg.cred_info[0].username = acc_username
+ acc_cfg.cred_info[0].data_type = 0
+ acc_cfg.cred_info[0].data = acc_passwd
+
+ # 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")
+
+
+#
+# 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):
- thread_desc = 0;
- status = py_pjsua.thread_register("worker thread", thread_desc)
- if status != 0:
- py_pjsua.perror(APP, "Error registering thread", status)
- else:
- while C_QUIT == 0:
- py_pjsua.handle_events(50)
+ 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:
- py_pjsua.destroy()
- err_exit("Error starting pjsua!", status)
-
- # Start worker thread
- thr = thread.start_new(worker_thread_main, (0,))
+ # Done with initialization, start pjsua!!
+ #
+ status = py_pjsua.start()
+ if status != 0:
+ py_pjsua.destroy()
+ err_exit("Error starting pjsua!", status)
+
+ # Start worker thread
+ thr = thread.start_new(worker_thread_main, (0,))
- print "PJSUA Started!!"
+ print "PJSUA Started!!"
# Print application menu
+#
def print_menu():
- print "Menu:"
- print " q Quit application"
- print " s Add buddy"
- print "Choice: ",
+ print """
+Menu:
+ q Quit application
+ +a Add account
+ +b Add buddy
+ m Make call
+ h Hangup current call (if any)
+ i Send instant message
+ """
+ print "Choice: ",
-
# Menu
+#
def app_menu():
- quit = 0
- while quit == 0:
- print_menu()
- choice = sys.stdin.readline()
- if choice[0] == "q":
- quit = 1
- elif choice[0] == "s":
- bc = py_pjsua.Buddy_Config()
- print "Buddy URI: ",
- bc.uri = sys.stdin.readline()
- if bc.uri == "":
- continue
+ global g_acc_id
+ global g_current_call
+
+ quit = 0
+ while quit == 0:
+ print_menu()
+ choice = sys.stdin.readline()
+
+ if choice[0] == "q":
+ quit = 1
+
+ elif choice[0] == "i":
+ # Sending IM
+ print "Send IM to SIP URL: ",
+ url = sys.stdin.readline()
+ if url == "\n":
+ continue
+
+ # Send typing indication
+ py_pjsua.im_typing(g_acc_id, url, 1, None)
+
+ print "The content: ",
+ message = sys.stdin.readline()
+ if message == "\n":
+ py_pjsua.im_typing(g_acc_id, url, 0, None)
+ continue
+
+ # Send the IM!
+ py_pjsua.im_send(g_acc_id, url, "", message, None, 0)
+
+ elif choice[0] == "m":
+ # Make call
+ print "Using account ", g_acc_id
+ print "Make call to SIP URL: ",
+ url = sys.stdin.readline()
+ url = url.replace("\n", "")
+ if url == "":
+ continue
+
+ # Initiate the call!
+ status, call_id = py_pjsua.call_make_call(g_acc_id, url, 0, 0, None)
+
+ if status != 0:
+ py_pjsua.perror(THIS_FILE, "Error making call", status)
+ else:
+ g_current_call = call_id
+
+ elif choice[0] == "+" and choice[1] == "b":
+ # Add new buddy
+ bc = py_pjsua.Buddy_Config()
+ print "Buddy URL: ",
+ bc.uri = sys.stdin.readline()
+ if bc.uri == "\n":
+ continue
- bc.subscribe = 1
- status = py_pjsua.buddy_add(bc)
- if status != 0:
- py_pjsua.perror(APP, "Error adding buddy", status)
+ bc.subscribe = 1
+ status, buddy_id = py_pjsua.buddy_add(bc)
+ if status != 0:
+ py_pjsua.perror(THIS_FILE, "Error adding buddy", status)
+
+ elif choice[0] == "+" and choice[1] == "a":
+ # Add account
+ add_account()
+
+ elif choice[0] == "h":
+ if g_current_call != py_pjsua.PJSUA_INVALID_ID:
+ py_pjsua.call_hangup(g_current_call, 603, "", None)
+ else:
+ print "No current call"
#
@@ -165,5 +341,10 @@ app_menu()
#
print "PJSUA shutting down.."
C_QUIT = 1
+# Give the worker thread chance to quit itself
+while C_QUIT != 2:
+ py_pjsua.handle_events(50)
+
+print "PJSUA destroying.."
py_pjsua.destroy()
diff --git a/pjsip-apps/src/py_pjsua/py_pjsua.c b/pjsip-apps/src/py_pjsua/py_pjsua.c
index b1a47726..15908d69 100644
--- a/pjsip-apps/src/py_pjsua/py_pjsua.c
+++ b/pjsip-apps/src/py_pjsua/py_pjsua.c
@@ -26,6 +26,7 @@
static PyObject* obj_reconfigure_logging;
static PyObject* obj_logging_init;
+static long thread_id;
/*
* cb_reconfigure_logging
@@ -50,7 +51,12 @@ static void cb_reconfigure_logging(int level, const char *data, pj_size_t len)
*/
static void cb_logging_init(int level, const char *data, pj_size_t len)
{
-
+ /* Ignore if this callback is called from alien thread context,
+ * or otherwise it will crash Python.
+ */
+ if (pj_thread_local_get(thread_id) == 0)
+ return;
+
if (PyCallable_Check(obj_logging_init))
{
//PyObject_CallFunction(obj_logging_init,"iSi",level,data,len);
@@ -175,7 +181,7 @@ typedef struct
/*
* The global callback object.
*/
-static callback_Object * obj_callback;
+static callback_Object * g_obj_callback;
/*
@@ -184,9 +190,7 @@ static callback_Object * obj_callback;
*/
static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
-
- printf("on_call_state called\n");
- if (PyCallable_Check(obj_callback->on_call_state))
+ if (PyCallable_Check(g_obj_callback->on_call_state))
{
pjsip_event_Object * obj;
@@ -197,7 +201,7 @@ static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
obj->event = e;
PyObject_CallFunctionObjArgs(
- obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
+ g_obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
);
}
@@ -211,8 +215,7 @@ static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
pjsip_rx_data *rdata)
{
- printf("on_incoming_call called\n");
- if (PyCallable_Check(obj_callback->on_incoming_call))
+ if (PyCallable_Check(g_obj_callback->on_incoming_call))
{
pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *)
PyType_GenericNew(&pjsip_rx_data_Type,
@@ -220,7 +223,7 @@ static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
obj->rdata = rdata;
PyObject_CallFunctionObjArgs(
- obj_callback->on_incoming_call,
+ g_obj_callback->on_incoming_call,
Py_BuildValue("i",acc_id),
Py_BuildValue("i",call_id),
obj,
@@ -236,10 +239,9 @@ static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
*/
static void cb_on_call_media_state(pjsua_call_id call_id)
{
- printf("on_call_media_state called\n");
- if (PyCallable_Check(obj_callback->on_call_media_state))
+ if (PyCallable_Check(g_obj_callback->on_call_media_state))
{
- PyObject_CallFunction(obj_callback->on_call_media_state,"i",call_id);
+ PyObject_CallFunction(g_obj_callback->on_call_media_state,"i",call_id);
}
}
@@ -254,11 +256,10 @@ static void cb_on_call_transfer_request(pjsua_call_id call_id,
{
PyObject * ret;
int cd;
- printf("on_call_transfer_request called\n");
- if (PyCallable_Check(obj_callback->on_call_transfer_request))
+ if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
{
ret = PyObject_CallFunctionObjArgs(
- obj_callback->on_call_transfer_request,
+ g_obj_callback->on_call_transfer_request,
Py_BuildValue("i",call_id),
PyString_FromStringAndSize(dst->ptr, dst->slen),
Py_BuildValue("i",*code),
@@ -290,11 +291,10 @@ static void cb_on_call_transfer_status( pjsua_call_id call_id,
{
PyObject * ret;
int cnt;
- printf("on_call_transfer_status called\n");
- if (PyCallable_Check(obj_callback->on_call_transfer_status))
+ if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
{
ret = PyObject_CallFunctionObjArgs(
- obj_callback->on_call_transfer_status,
+ g_obj_callback->on_call_transfer_status,
Py_BuildValue("i",call_id),
Py_BuildValue("i",status_code),
PyString_FromStringAndSize(status_text->ptr, status_text->slen),
@@ -326,8 +326,7 @@ static void cb_on_call_replace_request( pjsua_call_id call_id,
PyObject * ret;
PyObject * txt;
int cd;
- printf("on_call_replace_request called\n");
- if (PyCallable_Check(obj_callback->on_call_replace_request))
+ if (PyCallable_Check(g_obj_callback->on_call_replace_request))
{
pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *)
PyType_GenericNew(&pjsip_rx_data_Type,
@@ -335,7 +334,7 @@ static void cb_on_call_replace_request( pjsua_call_id call_id,
obj->rdata = rdata;
ret = PyObject_CallFunctionObjArgs(
- obj_callback->on_call_replace_request,
+ g_obj_callback->on_call_replace_request,
Py_BuildValue("i",call_id),
obj,
Py_BuildValue("i",*st_code),
@@ -363,11 +362,10 @@ static void cb_on_call_replace_request( pjsua_call_id call_id,
static void cb_on_call_replaced(pjsua_call_id old_call_id,
pjsua_call_id new_call_id)
{
- printf("on_call_replaced\n");
- if (PyCallable_Check(obj_callback->on_call_replaced))
+ if (PyCallable_Check(g_obj_callback->on_call_replaced))
{
PyObject_CallFunctionObjArgs(
- obj_callback->on_call_replaced,
+ g_obj_callback->on_call_replaced,
Py_BuildValue("i",old_call_id),
Py_BuildValue("i",old_call_id),
NULL
@@ -382,10 +380,9 @@ static void cb_on_call_replaced(pjsua_call_id old_call_id,
*/
static void cb_on_reg_state(pjsua_acc_id acc_id)
{
- printf("on_reg_state\n");
- if (PyCallable_Check(obj_callback->on_reg_state))
+ if (PyCallable_Check(g_obj_callback->on_reg_state))
{
- PyObject_CallFunction(obj_callback->on_reg_state,"i",acc_id);
+ PyObject_CallFunction(g_obj_callback->on_reg_state,"i",acc_id);
}
}
@@ -396,10 +393,9 @@ static void cb_on_reg_state(pjsua_acc_id acc_id)
*/
static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
{
- printf("on_buddy_state called\n");
- if (PyCallable_Check(obj_callback->on_buddy_state))
+ if (PyCallable_Check(g_obj_callback->on_buddy_state))
{
- PyObject_CallFunction(obj_callback->on_buddy_state,"i",buddy_id);
+ PyObject_CallFunction(g_obj_callback->on_buddy_state,"i",buddy_id);
}
}
@@ -411,11 +407,10 @@ static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
const pj_str_t *mime_type, const pj_str_t *body)
{
- printf("on_pager called\n");
- if (PyCallable_Check(obj_callback->on_pager))
+ if (PyCallable_Check(g_obj_callback->on_pager))
{
PyObject_CallFunctionObjArgs(
- obj_callback->on_pager,Py_BuildValue("i",call_id),
+ g_obj_callback->on_pager,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(contact->ptr, contact->slen),
@@ -437,11 +432,10 @@ static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
{
PyObject * obj = PyType_GenericNew(user_data, NULL, NULL);
- printf("on_pager_status called\n");
- if (PyCallable_Check(obj_callback->on_pager))
+ if (PyCallable_Check(g_obj_callback->on_pager))
{
PyObject_CallFunctionObjArgs(
- obj_callback->on_pager,Py_BuildValue("i",call_id),
+ g_obj_callback->on_pager,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(body->ptr, body->slen),obj,
Py_BuildValue("i",status),PyString_FromStringAndSize(reason->ptr,
@@ -459,11 +453,10 @@ static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
pj_bool_t is_typing)
{
- printf("on_typing called\n");
- if (PyCallable_Check(obj_callback->on_typing))
+ if (PyCallable_Check(g_obj_callback->on_typing))
{
PyObject_CallFunctionObjArgs(
- obj_callback->on_typing,Py_BuildValue("i",call_id),
+ g_obj_callback->on_typing,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(contact->ptr, contact->slen),
@@ -1725,6 +1718,9 @@ static PyObject *py_pjsua_thread_register(PyObject *pSelf, PyObject
thread_desc = malloc(sizeof(pj_thread_desc));
#endif
status = pj_thread_register(name, thread_desc, &thread);
+
+ if (status == PJ_SUCCESS)
+ status = pj_thread_local_set(thread_id, (void*)1);
return Py_BuildValue("i",status);
}
@@ -1991,7 +1987,13 @@ static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs)
return NULL;
}
status = pjsua_create();
- //printf("status %d\n",status);
+
+ if (status == PJ_SUCCESS) {
+ status = pj_thread_local_alloc(&thread_id);
+ if (status == PJ_SUCCESS)
+ status = pj_thread_local_set(thread_id, (void*)1);
+ }
+
return Py_BuildValue("i",status);
}
@@ -2027,40 +2029,44 @@ static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
pjsua_media_config_default(&cfg_media);
if (ua_cfgObj != Py_None) {
- ua_cfg = (config_Object *)ua_cfgObj;
+ ua_cfg = (config_Object *)ua_cfgObj;
cfg_ua.cred_count = ua_cfg->cred_count;
for (i = 0; i < 4; i++)
- {
+ {
cfg_ua.cred_info[i] = ua_cfg->cred_info[i];
- }
+ }
cfg_ua.max_calls = ua_cfg->max_calls;
for (i = 0; i < PJSUA_ACC_MAX_PROXIES; i++)
- {
+ {
cfg_ua.outbound_proxy[i] = ua_cfg->outbound_proxy[i];
- }
+ }
+
+ g_obj_callback = ua_cfg->cb;
+ Py_INCREF(g_obj_callback);
+
+ cfg_ua.cb.on_call_state = &cb_on_call_state;
+ cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
+ cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
+ cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
+ cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
+ cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
+ cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
+ cfg_ua.cb.on_reg_state = &cb_on_reg_state;
+ cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
+ cfg_ua.cb.on_pager = &cb_on_pager;
+ cfg_ua.cb.on_pager_status = &cb_on_pager_status;
+ cfg_ua.cb.on_typing = &cb_on_typing;
cfg_ua.outbound_proxy_cnt = ua_cfg->outbound_proxy_cnt;
cfg_ua.thread_cnt = ua_cfg->thread_cnt;
cfg_ua.user_agent.ptr = PyString_AsString(ua_cfg->user_agent);
cfg_ua.user_agent.slen = strlen(cfg_ua.user_agent.ptr);
- obj_callback = ua_cfg->cb;
- cfg_ua.cb.on_call_state = &cb_on_call_state;
- cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
- cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
- cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
- cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
- cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
- cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
- cfg_ua.cb.on_reg_state = &cb_on_reg_state;
- cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
- cfg_ua.cb.on_pager = &cb_on_pager;
- cfg_ua.cb.on_pager_status = &cb_on_pager_status;
- cfg_ua.cb.on_typing = &cb_on_typing;
p_cfg_ua = &cfg_ua;
} else {
p_cfg_ua = NULL;
- }
+ }
+
if (log_cfgObj != Py_None) {
log_cfg = (logging_config_Object *)log_cfgObj;
cfg_log.msg_logging = log_cfg->msg_logging;
@@ -2076,7 +2082,8 @@ static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
p_cfg_log = &cfg_log;
} else {
p_cfg_log = NULL;
- }
+ }
+
if (media_cfgObj != Py_None) {
media_cfg = (media_config_Object *)media_cfgObj;
cfg_media.clock_rate = media_cfg->clock_rate;
@@ -2092,9 +2099,10 @@ static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
cfg_media.thread_cnt = media_cfg->thread_cnt;
cfg_media.tx_drop_pct = media_cfg->tx_drop_pct;
p_cfg_media = &cfg_media;
- } else {
+ } else {
p_cfg_media = NULL;
- }
+ }
+
status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
return Py_BuildValue("i",status);
}
@@ -3959,12 +3967,14 @@ static PyObject *py_pjsua_acc_add
{
return NULL;
}
+
+ pjsua_acc_config_default(&cfg);
if (acObj != Py_None)
{
ac = (acc_config_Object *)acObj;
cfg.cred_count = ac->cred_count;
for (i = 0; i < 8; i++)
- {
+ {
/*cfg.cred_info[i] = ac->cred_info[i];*/
pjsip_cred_info_Object * ci = (pjsip_cred_info_Object *)
PyList_GetItem((PyObject *)ac->cred_info,i);
@@ -3979,7 +3989,7 @@ static PyObject *py_pjsua_acc_add
cfg.cred_info[i].username.slen = strlen
(PyString_AsString(ci->username));
cfg.cred_info[i].data_type = ci->data_type;
- }
+ }
cfg.force_contact.ptr = PyString_AsString(ac->force_contact);
cfg.force_contact.slen = strlen(PyString_AsString(ac->force_contact));
cfg.id.ptr = PyString_AsString(ac->id);
@@ -3989,7 +3999,7 @@ static PyObject *py_pjsua_acc_add
/*cfg.proxy[i] = ac->proxy[i];*/
cfg.proxy[i].ptr = PyString_AsString
(PyList_GetItem((PyObject *)ac->proxy,i));
- }
+ }
cfg.proxy_cnt = ac->proxy_cnt;
cfg.publish_enabled = ac->publish_enabled;
cfg.reg_timeout = ac->reg_timeout;
@@ -7162,7 +7172,7 @@ static PyObject *py_pjsua_call_make_call
dst_uri.ptr = PyString_AsString(sd);
dst_uri.slen = strlen(PyString_AsString(sd));
if (omdObj != Py_None) {
- omd = (msg_data_Object *)omdObj;
+ omd = (msg_data_Object *)omdObj;
msg_data.content_type.ptr = PyString_AsString(omd->content_type);
msg_data.content_type.slen = strlen
(PyString_AsString(omd->content_type));
@@ -7173,10 +7183,11 @@ static PyObject *py_pjsua_call_make_call
status = pjsua_call_make_call(acc_id, &dst_uri,
options, &user_data, &msg_data, &call_id);
pj_pool_release(pool);
- } else {
+ } else {
status = pjsua_call_make_call(acc_id, &dst_uri,
options, &user_data, NULL, &call_id);
- }
+ }
+
return Py_BuildValue("ii",status, call_id);
}
@@ -7253,7 +7264,6 @@ static PyObject *py_pjsua_call_get_info
int status;
call_info_Object * oi;
pjsua_call_info info;
- int i;
if (!PyArg_ParseTuple(pArgs, "i", &call_id))
@@ -7267,15 +7277,19 @@ static PyObject *py_pjsua_call_get_info
{
oi = (call_info_Object *)call_info_new(&call_info_Type, NULL, NULL);
oi->acc_id = info.acc_id;
- for (i = 0; i < 128; i++)
- {
- oi->buf_.call_id[i] = info.buf_.call_id[i];
- oi->buf_.last_status_text[i] = info.buf_.last_status_text[i];
- oi->buf_.local_contact[i] = info.buf_.local_contact[i];
- oi->buf_.local_info[i] = info.buf_.local_info[i];
- oi->buf_.remote_contact[i] = info.buf_.remote_contact[i];
- oi->buf_.remote_info[i] = info.buf_.remote_info[i];
- }
+ pj_ansi_snprintf(oi->buf_.call_id, sizeof(oi->buf_.call_id),
+ "%.*s", (int)info.call_id.slen, info.call_id.ptr);
+ pj_ansi_snprintf(oi->buf_.last_status_text, sizeof(oi->buf_.last_status_text),
+ "%.*s", (int)info.last_status_text.slen, info.last_status_text.ptr);
+ pj_ansi_snprintf(oi->buf_.local_contact, sizeof(oi->buf_.local_contact),
+ "%.*s", (int)info.local_contact.slen, info.local_contact.ptr);
+ pj_ansi_snprintf(oi->buf_.local_info, sizeof(oi->buf_.local_info),
+ "%.*s", (int)info.local_info.slen, info.local_info.ptr);
+ pj_ansi_snprintf(oi->buf_.remote_contact, sizeof(oi->buf_.remote_contact),
+ "%.*s", (int)info.remote_contact.slen, info.remote_contact.ptr);
+ pj_ansi_snprintf(oi->buf_.remote_info, sizeof(oi->buf_.remote_info),
+ "%.*s", (int)info.remote_info.slen, info.remote_info.ptr);
+
oi->call_id = PyString_FromStringAndSize(info.call_id.ptr,
info.call_id.slen);
oi->conf_slot = info.conf_slot;
@@ -7371,7 +7385,7 @@ static PyObject *py_pjsua_call_answer
{
return NULL;
}
-
+
reason.ptr = PyString_AsString(sr);
reason.slen = strlen(PyString_AsString(sr));
if (omdObj != Py_None) {
@@ -7408,7 +7422,7 @@ static PyObject *py_pjsua_call_hangup
pjsua_msg_data msg_data;
PyObject * omdObj;
msg_data_Object * omd;
- pj_pool_t * pool;
+ pj_pool_t * pool = NULL;
if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
{
@@ -7428,9 +7442,9 @@ static PyObject *py_pjsua_call_hangup
translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
status = pjsua_call_hangup(call_id, code, &reason, &msg_data);
pj_pool_release(pool);
- } else {
+ } else {
status = pjsua_call_hangup(call_id, code, &reason, NULL);
- }
+ }
return Py_BuildValue("i",status);
}