From 8485138ec283f3c890f31c1c8768900985d2d836 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 18 Feb 2007 23:49:14 +0000 Subject: Fixed various bugs in Python module git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@972 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/src/py_pjsua/pjsua_app.py | 113 +++++++++++------- pjsip-apps/src/py_pjsua/py_pjsua.c | 220 ++++++++++++++++++++++++++--------- 2 files changed, 233 insertions(+), 100 deletions(-) (limited to 'pjsip-apps/src') 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