summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-02-18 23:49:14 +0000
committerBenny Prijono <bennylp@teluu.com>2007-02-18 23:49:14 +0000
commit8485138ec283f3c890f31c1c8768900985d2d836 (patch)
tree3930232c7429de6f914b505b6742357b03b2fdf5
parentd8ab4d8bb8154f00cf13a6d3196fd6ecc026728b (diff)
Fixed various bugs in Python module
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@972 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/py_pjsua/pjsua_app.py113
-rw-r--r--pjsip-apps/src/py_pjsua/py_pjsua.c220
2 files changed, 233 insertions, 100 deletions
diff --git a/pjsip-apps/src/py_pjsua/pjsua_app.py b/pjsip-apps/src/py_pjsua/pjsua_app.py
index 8b54dfa7..7e47c8d4 100644
--- a/pjsip-apps/src/py_pjsua/pjsua_app.py
+++ b/pjsip-apps/src/py_pjsua/pjsua_app.py
@@ -36,6 +36,23 @@ g_rec_file = ""
g_rec_id = 0
g_rec_port = 0
+# Utility: display PJ error and exit
+#
+def err_exit(title, rc):
+ py_pjsua.perror(THIS_FILE, title, rc)
+ exit(1)
+
+
+# Logging function (also callback, called by pjsua-lib)
+#
+def log_cb(level, str, len):
+ if level <= C_LOG_LEVEL:
+ print str,
+
+def write_log(level, str):
+ log_cb(level, str + "\n", 0)
+
+
# Utility to get call info
#
def call_name(call_id):
@@ -84,10 +101,14 @@ def on_call_media_state(call_id):
#
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 (un)registration failed: rc=" + `acc_info.status` + " " + acc_info.status_text)
+ write_log(3, "Account " + cmd + " failed: rc=" + `acc_info.status` + " " + acc_info.status_text)
else:
- write_log(3, "Account successfully (un)registered")
+ write_log(3, "Account " + cmd + " success")
# Callback when buddy's presence state has changed
@@ -122,7 +143,7 @@ def on_typing(call_id, strfrom, to, contact, is_typing):
str_t = "has stopped typing"
write_log(3, "IM indication: " + strfrom + " " + str_t)
-# on call transfer status
+# Received the status of previous call transfer request
#
def on_call_transfer_status(call_id,status_code,status_text,final,p_cont):
strfinal = ""
@@ -136,28 +157,11 @@ def on_call_transfer_status(call_id,status_code,status_text,final,p_cont):
status = py_pjsua.call_hangup(call_id, 410, None, None)
p_cont = 0
-# on call transfer request
+# 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`)
-# Utility: display PJ error and exit
-#
-def err_exit(title, rc):
- py_pjsua.perror(THIS_FILE, title, rc)
- exit(1)
-
-
-# Logging function (also callback, called by pjsua-lib)
-#
-def log_cb(level, str, len):
- if level <= C_LOG_LEVEL:
- print str,
-
-def write_log(level, str):
- log_cb(level, str + "\n", 0)
-
-
#
# Initialize pjsua.
#
@@ -329,13 +333,8 @@ def add_recorder():
write_log(3, "File recorder " + file_name + " added")
def conf_list():
-
-
ports = None
-
print "Conference ports : "
-
-
ports = py_pjsua.enum_conf_ports()
for port in ports:
@@ -400,7 +399,7 @@ def dump_call_quality():
write_log(3, "\n" + buf)
else:
write_log(3, "No current call")
-
+
def xfer_call():
global g_current_call
@@ -506,9 +505,46 @@ def app_start():
print "PJSUA Started!!"
+# Print account and buddy list
+def print_acc_buddy_list():
+ global g_acc_id
+
+ acc_ids = py_pjsua.enum_accs()
+ print "Account list:"
+ for acc_id in acc_ids:
+ acc_info = py_pjsua.acc_get_info(acc_id)
+ if acc_info.has_registration == 0:
+ acc_status = acc_info.status_text
+ else:
+ acc_status = `acc_info.status` + "/" + acc_info.status_text + " (expires=" + `acc_info.expires` + ")"
+
+ if acc_id == g_acc_id:
+ print " *",
+ else:
+ print " ",
+
+ print "[" + `acc_id` + "] " + acc_info.acc_uri + ": " + acc_status
+ print " Presence status: ",
+ if acc_info.online_status != 0:
+ print "Online"
+ else:
+ print "Invisible"
+
+ if py_pjsua.get_buddy_count() > 0:
+ print ""
+ print "Buddy list:"
+ buddy_ids = py_pjsua.enum_buddies()
+ for buddy_id in buddy_ids:
+ bi = py_pjsua.buddy_get_info(buddy_id)
+ print " [" + `buddy_id` + "] " + bi.status_text + " " + bi.uri
+
+
# Print application menu
#
def print_menu():
+ print ""
+ print ">>>"
+ print_acc_buddy_list()
print """
+============================================================================+
| Call Commands : | Buddy, IM & Presence: | Account: |
@@ -524,14 +560,14 @@ def print_menu():
| x Xfer call | Media Commands: | Status: |
| X Xfer with Replaces | | |
| | cl List ports | d Dump status |
-| | cc Connect port | |
+| | cc Connect port | dd Dump detail |
| | cd Disconnect port | |
| | +p Add file player | |
|------------------------------+ +r Add file recorder | |
| q Quit application | | |
-+============================================================================+
- """
- print "Choice: ",
++============================================================================+"""
+ print "You have " + `py_pjsua.call_get_count()` + " active call(s)"
+ print ">>>",
# Menu
#
@@ -591,6 +627,7 @@ def app_menu():
if bc.uri == "\n":
continue
+ bc.uri = bc.uri.replace("\n", "")
bc.subscribe = 1
status, buddy_id = py_pjsua.buddy_add(bc)
if status != 0:
@@ -713,19 +750,7 @@ def app_menu():
elif choice[1] == "u":
py_pjsua.acc_set_registration(g_acc_id, 0)
elif choice[0] == "d":
-
- write_log(3, "Start dumping application states : ")
- write_log(3, "Dumping invite sessions : ")
-
- if py_pjsua.call_get_count() == 0:
- write_log(3, " - no sessions -")
- else:
- for i in range(0, g_ua_cfg.max_calls):
- if py_pjsua.call_is_active(i):
- buf = py_pjsua.call_dump(i, 1, 1024, " ")
- write_log(3, buf)
- py_pjsua.pres_dump(1)
- write_log(3, "Dump complete")
+ py_pjsua.dump(choice[1] == "d")
elif choice[0] == "a":
if g_current_call != py_pjsua.PJSUA_INVALID_ID:
diff --git a/pjsip-apps/src/py_pjsua/py_pjsua.c b/pjsip-apps/src/py_pjsua/py_pjsua.c
index e5cb6caf..c4e3e819 100644
--- a/pjsip-apps/src/py_pjsua/py_pjsua.c
+++ b/pjsip-apps/src/py_pjsua/py_pjsua.c
@@ -27,46 +27,35 @@
/* LIB BASE */
-static PyObject* obj_reconfigure_logging;
-static PyObject* obj_logging_init;
+static PyObject* obj_log_cb;
static long thread_id;
+#define ENTER_PYTHON() PyGILState_STATE state = PyGILState_Ensure()
+#define LEAVE_PYTHON() PyGILState_Release(state)
+
/*
- * cb_reconfigure_logging
+ * cb_log_cb
* declares method for reconfiguring logging process for callback struct
*/
-static void cb_reconfigure_logging(int level, const char *data, pj_size_t len)
+static void cb_log_cb(int level, const char *data, pj_size_t len)
{
- if (PyCallable_Check(obj_reconfigure_logging))
- {
- PyObject_CallFunctionObjArgs(
- obj_reconfigure_logging, Py_BuildValue("i",level),
- PyString_FromString(data), Py_BuildValue("i",len), NULL
- );
- }
-}
-
-
-/*
- * cb_logging_init
- * declares method logging_init for callback struct
- */
-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))
+ if (PyCallable_Check(obj_log_cb))
{
-
+ ENTER_PYTHON();
+
PyObject_CallFunctionObjArgs(
- obj_logging_init, Py_BuildValue("i",level),
+ obj_log_cb, Py_BuildValue("i",level),
PyString_FromString(data), Py_BuildValue("i",len), NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -195,17 +184,19 @@ static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
if (PyCallable_Check(g_obj_callback->on_call_state))
{
pjsip_event_Object * obj;
-
- obj =
- (pjsip_event_Object *)PyType_GenericNew(&pjsip_event_Type,
- NULL, NULL);
+
+ ENTER_PYTHON();
+
+ obj = (pjsip_event_Object *)PyType_GenericNew(&pjsip_event_Type,
+ NULL, NULL);
obj->event = e;
PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
);
-
+
+ LEAVE_PYTHON();
}
}
@@ -219,8 +210,11 @@ static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
{
if (PyCallable_Check(g_obj_callback->on_incoming_call))
{
- pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *)
- PyType_GenericNew(&pjsip_rx_data_Type,
+ pjsip_rx_data_Object * obj;
+
+ ENTER_PYTHON();
+
+ obj = (pjsip_rx_data_Object *)PyType_GenericNew(&pjsip_rx_data_Type,
NULL, NULL);
obj->rdata = rdata;
@@ -231,6 +225,8 @@ static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
obj,
NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -243,7 +239,11 @@ static void cb_on_call_media_state(pjsua_call_id call_id)
{
if (PyCallable_Check(g_obj_callback->on_call_media_state))
{
+ ENTER_PYTHON();
+
PyObject_CallFunction(g_obj_callback->on_call_media_state,"i",call_id);
+
+ LEAVE_PYTHON();
}
}
@@ -256,10 +256,13 @@ static void cb_on_call_transfer_request(pjsua_call_id call_id,
const pj_str_t *dst,
pjsip_status_code *code)
{
- PyObject * ret;
- int cd;
if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
{
+ PyObject * ret;
+ int cd;
+
+ ENTER_PYTHON();
+
ret = PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_transfer_request,
Py_BuildValue("i",call_id),
@@ -274,6 +277,8 @@ static void cb_on_call_transfer_request(pjsua_call_id call_id,
}
}
}
+
+ LEAVE_PYTHON();
}
}
@@ -291,10 +296,13 @@ static void cb_on_call_transfer_status( pjsua_call_id call_id,
pj_bool_t final,
pj_bool_t *p_cont)
{
- PyObject * ret;
- int cnt;
if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
{
+ PyObject * ret;
+ int cnt;
+
+ ENTER_PYTHON();
+
ret = PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_transfer_status,
Py_BuildValue("i",call_id),
@@ -311,6 +319,8 @@ static void cb_on_call_transfer_status( pjsua_call_id call_id,
}
}
}
+
+ LEAVE_PYTHON();
}
}
@@ -325,13 +335,16 @@ static void cb_on_call_replace_request( pjsua_call_id call_id,
int *st_code,
pj_str_t *st_text)
{
- PyObject * ret;
- PyObject * txt;
- int cd;
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,
+ PyObject * ret;
+ PyObject * txt;
+ int cd;
+ pjsip_rx_data_Object * obj;
+
+ ENTER_PYTHON();
+
+ obj = (pjsip_rx_data_Object *)PyType_GenericNew(&pjsip_rx_data_Type,
NULL, NULL);
obj->rdata = rdata;
@@ -352,6 +365,8 @@ static void cb_on_call_replace_request( pjsua_call_id call_id,
}
}
}
+
+ LEAVE_PYTHON();
}
}
@@ -366,12 +381,16 @@ static void cb_on_call_replaced(pjsua_call_id old_call_id,
{
if (PyCallable_Check(g_obj_callback->on_call_replaced))
{
+ ENTER_PYTHON();
+
PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_replaced,
Py_BuildValue("i",old_call_id),
Py_BuildValue("i",old_call_id),
NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -384,7 +403,11 @@ static void cb_on_reg_state(pjsua_acc_id acc_id)
{
if (PyCallable_Check(g_obj_callback->on_reg_state))
{
+ ENTER_PYTHON();
+
PyObject_CallFunction(g_obj_callback->on_reg_state,"i",acc_id);
+
+ LEAVE_PYTHON();
}
}
@@ -397,7 +420,11 @@ static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
{
if (PyCallable_Check(g_obj_callback->on_buddy_state))
{
+ ENTER_PYTHON();
+
PyObject_CallFunction(g_obj_callback->on_buddy_state,"i",buddy_id);
+
+ LEAVE_PYTHON();
}
}
@@ -411,6 +438,8 @@ static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
{
if (PyCallable_Check(g_obj_callback->on_pager))
{
+ ENTER_PYTHON();
+
PyObject_CallFunctionObjArgs(
g_obj_callback->on_pager,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
@@ -419,6 +448,8 @@ static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
PyString_FromStringAndSize(mime_type->ptr, mime_type->slen),
PyString_FromStringAndSize(body->ptr, body->slen), NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -432,17 +463,26 @@ static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
pjsip_status_code status,
const pj_str_t *reason)
{
-
- PyObject * obj = PyType_GenericNew(user_data, NULL, NULL);
if (PyCallable_Check(g_obj_callback->on_pager))
{
+ PyObject * obj_user_data;
+
+ ENTER_PYTHON();
+
+ obj_user_data = Py_BuildValue("i", user_data);
+
PyObject_CallFunctionObjArgs(
- g_obj_callback->on_pager,Py_BuildValue("i",call_id),
+ g_obj_callback->on_pager_status,
+ 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,
- reason->slen),NULL
+ PyString_FromStringAndSize(body->ptr, body->slen),
+ obj_user_data,
+ Py_BuildValue("i",status),
+ PyString_FromStringAndSize(reason->ptr,reason->slen),
+ NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -457,6 +497,8 @@ static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
{
if (PyCallable_Check(g_obj_callback->on_typing))
{
+ ENTER_PYTHON();
+
PyObject_CallFunctionObjArgs(
g_obj_callback->on_typing,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
@@ -464,6 +506,8 @@ static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
PyString_FromStringAndSize(contact->ptr, contact->slen),
Py_BuildValue("i",is_typing),NULL
);
+
+ LEAVE_PYTHON();
}
}
@@ -1299,10 +1343,10 @@ static PyTypeObject msg_data_Type =
*/
void translate_hdr(pj_pool_t *pool, pjsip_hdr *hdr, PyObject *py_hdr_list)
{
- int i;
+ pj_list_init(hdr);
if (PyList_Check(py_hdr_list)) {
- pj_list_init(hdr);
+ int i;
for (i = 0; i < PyList_Size(py_hdr_list); i++)
{
@@ -1866,10 +1910,10 @@ static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf, PyObject *pArgs)
cfg.decor = log->decor;
cfg.log_filename.ptr = PyString_AsString(log->log_filename);
cfg.log_filename.slen = strlen(cfg.log_filename.ptr);
- Py_XDECREF(obj_reconfigure_logging);
- obj_reconfigure_logging = log->cb;
- Py_INCREF(obj_reconfigure_logging);
- cfg.cb = &cb_reconfigure_logging;
+ Py_XDECREF(obj_log_cb);
+ obj_log_cb = log->cb;
+ Py_INCREF(obj_log_cb);
+ cfg.cb = &cb_log_cb;
status = pjsua_reconfigure_logging(&cfg);
} else {
status = pjsua_reconfigure_logging(NULL);
@@ -2086,10 +2130,10 @@ static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
cfg_log.decor = log_cfg->decor;
cfg_log.log_filename.ptr = PyString_AsString(log_cfg->log_filename);
cfg_log.log_filename.slen = strlen(cfg_log.log_filename.ptr);
- Py_XDECREF(obj_logging_init);
- obj_logging_init = log_cfg->cb;
- Py_INCREF(obj_logging_init);
- cfg_log.cb = &cb_logging_init;
+ Py_XDECREF(obj_log_cb);
+ obj_log_cb = log_cfg->cb;
+ Py_INCREF(obj_log_cb);
+ cfg_log.cb = &cb_log_cb;
p_cfg_log = &cfg_log;
} else {
p_cfg_log = NULL;
@@ -7862,6 +7906,66 @@ static PyObject *py_pjsua_call_dump
return Py_BuildValue("O", sb);
}
+
+/*
+ * py_pjsua_dump
+ * Dump application states.
+ */
+static PyObject *py_pjsua_dump(PyObject *pSelf, PyObject *pArgs)
+{
+ unsigned old_decor;
+ char buf[1024];
+ int detail;
+
+ if (!PyArg_ParseTuple(pArgs, "i", &detail))
+ {
+ return NULL;
+ }
+
+ PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));
+
+ old_decor = pj_log_get_decor();
+ pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));
+
+ if (detail)
+ pj_dump_config();
+
+ pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail);
+ pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());
+ pjsip_tsx_layer_dump(detail);
+ pjsip_ua_dump(detail);
+
+
+ /* Dump all invite sessions: */
+ PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:"));
+
+ if (pjsua_call_get_count() == 0) {
+
+ PJ_LOG(3,(THIS_FILE, " - no sessions -"));
+
+ } else {
+ unsigned i, max;
+
+ max = pjsua_call_get_max_count();
+ for (i=0; i<max; ++i) {
+ if (pjsua_call_is_active(i)) {
+ pjsua_call_dump(i, detail, buf, sizeof(buf), " ");
+ PJ_LOG(3,(THIS_FILE, "%s", buf));
+ }
+ }
+ }
+
+ /* Dump presence status */
+ pjsua_pres_dump(detail);
+
+ pj_log_set_decor(old_decor);
+ PJ_LOG(3,(THIS_FILE, "Dump complete"));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
static char pjsua_call_get_max_count_doc[] =
"int py_pjsua.call_get_max_count () "
"Get maximum number of calls configured in pjsua.";
@@ -8355,7 +8459,9 @@ static PyMethodDef py_pjsua_methods[] =
"call_dump", py_pjsua_call_dump, METH_VARARGS,
pjsua_call_dump_doc
},
-
+ {
+ "dump", py_pjsua_dump, METH_VARARGS, "Dump application state"
+ },
{NULL, NULL} /* end of function list */
@@ -8373,6 +8479,8 @@ initpy_pjsua(void)
#define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
+ PyEval_InitThreads();
+
if (PyType_Ready(&callback_Type) < 0)
return;
if (PyType_Ready(&config_Type) < 0)