diff options
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsip-ua/sip_inv.h | 5 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_ua_layer.h | 5 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_dialog.c | 8 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 5 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_ua_layer.c | 70 | ||||
-rw-r--r-- | pjsip/src/pjsua/main.c | 150 | ||||
-rw-r--r-- | pjsip/src/pjsua/pjsua.h | 29 | ||||
-rw-r--r-- | pjsip/src/pjsua/pjsua_core.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsua/pjsua_inv.c | 16 |
10 files changed, 268 insertions, 25 deletions
diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h index b0dab63c..a8276bb5 100644 --- a/pjsip/include/pjsip-ua/sip_inv.h +++ b/pjsip/include/pjsip-ua/sip_inv.h @@ -200,6 +200,11 @@ PJ_DECL(pj_status_t) pjsip_inv_usage_init(pjsip_endpoint *endpt, PJ_DECL(pjsip_module*) pjsip_inv_usage_instance(void); +/** + * Dump user agent contents (e.g. all dialogs). + */ +PJ_DECL(void) pjsip_inv_usage_dump(void); + /** * Create UAC invite session for the specified dialog in dlg. diff --git a/pjsip/include/pjsip/sip_ua_layer.h b/pjsip/include/pjsip/sip_ua_layer.h index 02f94579..012628a5 100644 --- a/pjsip/include/pjsip/sip_ua_layer.h +++ b/pjsip/include/pjsip/sip_ua_layer.h @@ -73,6 +73,11 @@ PJ_DECL(pjsip_user_agent*) pjsip_ua_instance(void); PJ_DECL(pj_status_t) pjsip_ua_destroy(void); /** + * Dump user agent contents (e.g. all dialogs). + */ +PJ_DEF(void) pjsip_ua_dump(void); + +/** * Get the endpoint instance of a user agent module. * * @param ua The user agent instance. diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 65e46431..a655c86f 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -320,6 +320,7 @@ PJ_DEF(pjsip_module*) pjsip_inv_usage_instance(void) } + /* * Return the invite session for the specified dialog. */ diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c index f41b5d53..9f0434a4 100644 --- a/pjsip/src/pjsip/sip_dialog.c +++ b/pjsip/src/pjsip/sip_dialog.c @@ -929,6 +929,9 @@ static void dlg_beautify_response(pjsip_dialog *dlg, pj_assert(to != NULL); to->tag = dlg->local.info->tag; + + if (dlg->state == PJSIP_DIALOG_STATE_NULL) + dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED; } } @@ -1097,7 +1100,9 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata ) dlg->remote.cseq = rdata->msg_info.cseq->cseq; /* Create UAS transaction for this request. */ - if (pjsip_rdata_get_tsx(rdata) == NULL) { + if (pjsip_rdata_get_tsx(rdata) == NULL && + rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) + { status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx); PJ_ASSERT_ON_FAIL(status==PJ_SUCCESS,{goto on_return;}); @@ -1280,4 +1285,3 @@ void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg, } } - diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 2531ae22..fb247b18 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -1044,6 +1044,11 @@ PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr) pj_lock_acquire(mgr->lock); +#if defined(PJ_DEBUG) && PJ_DEBUG!=0 + PJ_LOG(3,(THIS_FILE, " Outstanding transmit buffers: %d", + pj_atomic_get(mgr->tdata_counter))); +#endif + itr = pj_hash_first(mgr->table, &itr_val); if (itr) { PJ_LOG(3, (THIS_FILE, " Dumping transports:")); diff --git a/pjsip/src/pjsip/sip_ua_layer.c b/pjsip/src/pjsip/sip_ua_layer.c index ada14ad2..c1fd6332 100644 --- a/pjsip/src/pjsip/sip_ua_layer.c +++ b/pjsip/src/pjsip/sip_ua_layer.c @@ -720,3 +720,73 @@ static pj_bool_t mod_ua_on_rx_response(pjsip_rx_data *rdata) } +#if PJ_LOG_MAX_LEVEL >= 3 +static void print_dialog( const char *title, + pjsip_dialog *dlg, char *buf, pj_size_t size) +{ + int len; + char userinfo[128]; + + len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo)); + if (len < 1) + pj_native_strcpy(userinfo, "<--uri too long-->"); + else + userinfo[len] = '\0'; + + len = pj_snprintf(buf, size, "%s[%s] %s", + title, + (dlg->state==PJSIP_DIALOG_STATE_NULL ? " - " : + "est"), + userinfo); + if (len < 1 || len >= (int)size) { + pj_native_strcpy(buf, "<--uri too long-->"); + } else + buf[len] = '\0'; +} +#endif + +/* + * Dump user agent contents (e.g. all dialogs). + */ +PJ_DEF(void) pjsip_ua_dump(void) +{ +#if PJ_LOG_MAX_LEVEL >= 3 + pj_hash_iterator_t itbuf, *it; + char dlginfo[128]; + + pj_mutex_lock(mod_ua.mutex); + + PJ_LOG(3, (THIS_FILE, "Number of dialog sets: %u", pj_hash_count(mod_ua.dlg_table))); + PJ_LOG(3, (THIS_FILE, "Dumping dialog sets:")); + + it = pj_hash_first(mod_ua.dlg_table, &itbuf); + for (; it != NULL; it = pj_hash_next(mod_ua.dlg_table, it)) { + struct dlg_set *dlg_set; + pjsip_dialog *dlg; + const char *title; + + dlg_set = pj_hash_this(mod_ua.dlg_table, it); + if (!dlg_set || pj_list_empty(&dlg_set->dlg_list)) continue; + + /* First dialog in dialog set. */ + dlg = dlg_set->dlg_list.next; + if (dlg->role == PJSIP_ROLE_UAC) + title = " [out] "; + else + title = " [in] "; + + print_dialog(title, dlg, dlginfo, sizeof(dlginfo)); + PJ_LOG(3,(THIS_FILE, "%s", dlginfo)); + + /* Next dialog in dialog set (forked) */ + dlg = dlg->next; + while (dlg != (pjsip_dialog*) &dlg_set->dlg_list) { + print_dialog(" [forked] ", dlg, dlginfo, sizeof(dlginfo)); + dlg = dlg->next; + } + } + + pj_mutex_unlock(mod_ua.mutex); +#endif +} + diff --git a/pjsip/src/pjsua/main.c b/pjsip/src/pjsua/main.c index 287f5624..6b85bfaf 100644 --- a/pjsip/src/pjsua/main.c +++ b/pjsip/src/pjsua/main.c @@ -25,26 +25,27 @@ static pjsip_inv_session *inv_session; +static const char *inv_state_names[] = +{ + "NULL ", + "CALLING ", + "INCOMING ", + "EARLY ", + "CONNECTING", + "CONFIRMED ", + "DISCONNCTD", + "TERMINATED", +}; + /* * Notify UI when invite state has changed. */ void pjsua_ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) { - const char *state_names[] = - { - "NULL", - "CALLING", - "INCOMING", - "EARLY", - "CONNECTING", - "CONFIRMED", - "DISCONNECTED", - "TERMINATED", - }; - PJ_UNUSED_ARG(e); - PJ_LOG(3,(THIS_FILE, "INVITE session state changed to %s", state_names[inv->state])); + PJ_LOG(3,(THIS_FILE, "INVITE session state changed to %s", + inv_state_names[inv->state])); if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { if (inv == inv_session) @@ -57,11 +58,130 @@ void pjsua_ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) } } + +static void print_invite_session(const char *title, + struct pjsua_inv_data *inv_data, + char *buf, pj_size_t size) +{ + int len; + pjsip_inv_session *inv = inv_data->inv; + pjsip_dialog *dlg = inv->dlg; + char userinfo[128]; + + /* Dump invite sesion info. */ + + len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo)); + if (len < 1) + pj_native_strcpy(userinfo, "<--uri too long-->"); + else + userinfo[len] = '\0'; + + len = pj_snprintf(buf, size, "%s[%s] %s", + title, + inv_state_names[inv->state], + userinfo); + if (len < 1 || len >= (int)size) { + pj_native_strcpy(buf, "<--uri too long-->"); + len = 18; + } else + buf[len] = '\0'; +} + +static void dump_media_session(pjmedia_session *session) +{ + unsigned i; + pjmedia_session_info info; + + pjmedia_session_get_info(session, &info); + + for (i=0; i<info.stream_cnt; ++i) { + pjmedia_stream_stat strm_stat; + const char *rem_addr; + int rem_port; + const char *dir; + + pjmedia_session_get_stream_stat(session, i, &strm_stat); + rem_addr = pj_inet_ntoa(info.stream_info[i].rem_addr.sin_addr); + rem_port = pj_ntohs(info.stream_info[i].rem_addr.sin_port); + + if (info.stream_info[i].dir == PJMEDIA_DIR_ENCODING) + dir = "sendonly"; + else if (info.stream_info[i].dir == PJMEDIA_DIR_DECODING) + dir = "recvonly"; + else if (info.stream_info[i].dir == PJMEDIA_DIR_ENCODING_DECODING) + dir = "sendrecv"; + else + dir = "inactive"; + + + PJ_LOG(3,(THIS_FILE, + "%s[Media strm#%d] %.*s, %s, peer=%s:%d", + " ", + i, + info.stream_info[i].fmt.encoding_name.slen, + info.stream_info[i].fmt.encoding_name.ptr, + dir, + rem_addr, rem_port)); + PJ_LOG(3,(THIS_FILE, + "%s tx {pkt=%u, bytes=%u} rx {pkt=%u, bytes=%u}", + " ", + strm_stat.enc.pkt, strm_stat.enc.bytes, + strm_stat.dec.pkt, strm_stat.dec.bytes)); + + } +} + +/* + * Dump application states. + */ +static void pjsua_dump(void) +{ + struct pjsua_inv_data *inv_data; + char buf[128]; + unsigned log_decor; + + log_decor = pj_log_get_decor(); + pj_log_set_decor(PJ_LOG_HAS_NEWLINE); + + pjsip_endpt_dump(pjsua.endpt, 1); + pjsip_ua_dump(); + + /* Dump all invite sessions: */ + PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:")); + + if (pj_list_empty(&pjsua.inv_list)) { + + PJ_LOG(3,(THIS_FILE, " - no sessions -")); + + } else { + + inv_data = pjsua.inv_list.next; + + while (inv_data != &pjsua.inv_list) { + + print_invite_session(" ", inv_data, buf, sizeof(buf)); + PJ_LOG(3,(THIS_FILE, "%s", buf)); + + if (inv_data->session) + dump_media_session(inv_data->session); + + inv_data = inv_data->next; + } + } + + pj_log_set_decor(log_decor); +} + + +/* + * Show a bit of help. + */ static void ui_help(void) { puts(""); puts("Console keys:"); puts(" m Make a call/another call"); + puts(" d Dump application states"); puts(" a Answer incoming call"); puts(" h Hangup current call"); puts(" q Quit"); @@ -122,6 +242,10 @@ static void ui_console_main(void) break; + case 'd': + pjsua_dump(); + break; + case 'a': if (inv_session == NULL || inv_session->role != PJSIP_ROLE_UAS || diff --git a/pjsip/src/pjsua/pjsua.h b/pjsip/src/pjsua/pjsua.h index 810c57b5..f882e873 100644 --- a/pjsip/src/pjsua/pjsua.h +++ b/pjsip/src/pjsua/pjsua.h @@ -37,6 +37,22 @@ PJ_BEGIN_DECL + +/** + * Structure to be attached to all dialog. + * Given a dialog "dlg", application can retrieve this structure + * by accessing dlg->mod_data[pjsua.mod.id]. + */ +struct pjsua_inv_data +{ + PJ_DECL_LIST_MEMBER(struct pjsua_inv_data); + + pjsip_inv_session *inv; + pjmedia_session *session; +}; + + + /* PJSUA application variables. */ struct pjsua { @@ -109,6 +125,9 @@ struct pjsua unsigned log_decor; /**< Log decoration. */ char *log_filename; /**< Log filename. */ + /* List of invite sessions: */ + + struct pjsua_inv_data inv_list; }; @@ -116,16 +135,6 @@ struct pjsua extern struct pjsua pjsua; -/** - * Structure to be attached to all dialog. - * Given a dialog "dlg", application can retrieve this structure - * by accessing dlg->mod_data[pjsua.mod.id]. - */ -struct pjsua_inv_data -{ - pjmedia_session *session; -}; - /***************************************************************************** * PJSUA API (defined in pjsua_core.c). diff --git a/pjsip/src/pjsua/pjsua_core.c b/pjsip/src/pjsua/pjsua_core.c index cc9ae86f..7eb414bc 100644 --- a/pjsip/src/pjsua/pjsua_core.c +++ b/pjsip/src/pjsua/pjsua_core.c @@ -75,6 +75,10 @@ void pjsua_default(void) /* Init route set list: */ pj_list_init(&pjsua.route_set); + + /* Init invite session list: */ + + pj_list_init(&pjsua.inv_list); } diff --git a/pjsip/src/pjsua/pjsua_inv.c b/pjsip/src/pjsua/pjsua_inv.c index 72272c32..7c6dbf26 100644 --- a/pjsip/src/pjsua/pjsua_inv.c +++ b/pjsip/src/pjsua/pjsua_inv.c @@ -78,6 +78,7 @@ pj_status_t pjsua_invite(const char *cstr_dest_uri, /* Create and associate our data in the session. */ inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data)); + inv_data->inv = inv; dlg->mod_data[pjsua.mod.id] = inv_data; @@ -110,6 +111,10 @@ pj_status_t pjsua_invite(const char *cstr_dest_uri, goto on_error; } + /* Add invite session to the list. */ + + pj_list_push_back(&pjsua.inv_list, inv_data); + /* Done. */ @@ -214,8 +219,11 @@ pj_bool_t pjsua_inv_on_incoming(pjsip_rx_data *rdata) /* Create and attach pjsua data to the dialog: */ inv_data = pj_pool_zalloc(dlg->pool, sizeof(struct pjsua_inv_data)); + inv_data->inv = inv; dlg->mod_data[pjsua.mod.id] = inv_data; + pj_list_push_back(&pjsua.inv_list, inv_data); + /* Answer with 100 (using the dialog, not invite): */ @@ -244,6 +252,9 @@ void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) struct pjsua_inv_data *inv_data; inv_data = inv->dlg->mod_data[pjsua.mod.id]; + + pj_assert(inv_data != NULL); + if (inv_data && inv_data->session) { pjmedia_session_destroy(inv_data->session); inv_data->session = NULL; @@ -251,6 +262,11 @@ void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) PJ_LOG(3,(THIS_FILE,"Media session is destroyed")); } + if (inv_data) { + + pj_list_erase(inv_data); + + } } pjsua_ui_inv_on_state_changed(inv, e); |