summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-06-06 18:40:40 +0000
committerBenny Prijono <bennylp@teluu.com>2006-06-06 18:40:40 +0000
commit8db4ef281d67eee2ebeac22a31bc1961e96d78b2 (patch)
treeb910ef526c864da15ab3d05840fc78ff8c6c7608 /pjsip
parent40d75a0cb404fc0bafa20934e992befd0eab673b (diff)
Another huge chunks of modifications in PJSUA API, too many things to mention!
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@492 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h175
-rw-r--r--pjsip/include/pjsua-lib/pjsua_console_app.h2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c98
-rw-r--r--pjsip/src/pjsua-lib/pjsua_console_app.c148
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c187
-rw-r--r--pjsip/src/pjsua-lib/pjsua_im.c34
-rw-r--r--pjsip/src/pjsua-lib/pjsua_imp.h25
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c67
-rw-r--r--pjsip/src/pjsua-lib/pjsua_reg.c61
-rw-r--r--pjsip/src/pjsua-lib/pjsua_settings.c151
10 files changed, 665 insertions, 283 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 622991f6..dba8560c 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -68,6 +68,13 @@ PJ_BEGIN_DECL
#endif
+typedef int pjsua_acc_id;
+typedef int pjsua_buddy_id;
+typedef int pjsua_player_id;
+typedef int pjsua_recorder_id;
+typedef int pjsua_conf_port_id;
+
+
/**
* Account configuration.
*/
@@ -135,6 +142,11 @@ struct pjsua_config
*/
unsigned start_rtp_port;
+ /**
+ * Enable incoming and outgoing message logging (default: 1).
+ */
+ pj_bool_t msg_logging;
+
/** Maximum calls to support (default: 4) */
unsigned max_calls;
@@ -223,9 +235,6 @@ struct pjsua_config
/** Outbound proxy (default: none) */
pj_str_t outbound_proxy;
- /** URI to call. */
- pj_str_t uri_to_call;
-
/** Number of SIP accounts */
unsigned acc_cnt;
@@ -272,6 +281,12 @@ struct pjsua_callback
void (*on_call_state)(int call_index, pjsip_event *e);
/**
+ * Notify application on incoming call.
+ */
+ void (*on_incoming_call)(pjsua_acc_id acc_id, int call_index,
+ pjsip_rx_data *rdata);
+
+ /**
* Notify application on call being transfered.
* Application can decide to accept/reject transfer request
* by setting the code (default is 200). When this callback
@@ -287,13 +302,13 @@ struct pjsua_callback
* Application may then query the account info to get the
* registration details.
*/
- void (*on_reg_state)(int acc_index);
+ void (*on_reg_state)(pjsua_acc_id acc_id);
/**
* Notify application when the buddy state has changed.
* Application may then query the buddy into to get the details.
*/
- void (*on_buddy_state)(int buddy_index);
+ void (*on_buddy_state)(pjsua_buddy_id buddy_id);
/**
* Notify application on incoming pager (i.e. MESSAGE request).
@@ -329,12 +344,12 @@ struct pjsua_call_info
pj_str_t remote_info;
pjsip_inv_state state;
pj_str_t state_text;
+ pjsip_status_code last_status;
+ pj_str_t last_status_text;
pj_time_val connect_duration;
pj_time_val total_duration;
- pjsip_status_code cause;
- pj_str_t cause_text;
pj_bool_t has_media;
- unsigned conf_slot;
+ pjsua_conf_port_id conf_slot;
};
typedef struct pjsua_call_info pjsua_call_info;
@@ -355,7 +370,7 @@ typedef enum pjsua_buddy_status pjsua_buddy_status;
*/
struct pjsua_buddy_info
{
- unsigned index;
+ pjsua_buddy_id index;
pj_bool_t is_valid;
pj_str_t name;
pj_str_t display_name;
@@ -365,7 +380,6 @@ struct pjsua_buddy_info
pjsua_buddy_status status;
pj_str_t status_text;
pj_bool_t monitor;
- int acc_index;
};
typedef struct pjsua_buddy_info pjsua_buddy_info;
@@ -376,7 +390,7 @@ typedef struct pjsua_buddy_info pjsua_buddy_info;
*/
struct pjsua_acc_info
{
- unsigned index;
+ pjsua_acc_id index;
pj_str_t acc_id;
pj_bool_t has_registration;
int expires;
@@ -389,9 +403,23 @@ struct pjsua_acc_info
typedef struct pjsua_acc_info pjsua_acc_info;
-typedef int pjsua_player_id;
-typedef int pjsua_recorder_id;
+/**
+ * Conference port info.
+ */
+struct pjsua_conf_port_info
+{
+ pjsua_conf_port_id slot_id;
+ pj_str_t name;
+ unsigned clock_rate;
+ unsigned channel_count;
+ unsigned samples_per_frame;
+ unsigned bits_per_sample;
+ unsigned listener_cnt;
+ pjsua_conf_port_id listeners[256];
+};
+
+typedef struct pjsua_conf_port_info pjsua_conf_port_info;
/*****************************************************************************
@@ -478,12 +506,12 @@ PJ_DECL(pj_status_t) pjsua_set_call_media_transport(unsigned call_index,
/**
* Get maximum number of calls configured in pjsua.
*/
-PJ_DECL(unsigned) pjsua_get_max_calls(void);
+PJ_DECL(unsigned) pjsua_call_get_max_count(void);
/**
* Get current number of active calls.
*/
-PJ_DECL(unsigned) pjsua_get_call_count(void);
+PJ_DECL(unsigned) pjsua_call_get_count(void);
/**
* Check if the specified call has active INVITE session and the INVITE
@@ -501,14 +529,14 @@ PJ_DECL(pj_bool_t) pjsua_call_has_media(unsigned call_index);
/**
* Get call info.
*/
-PJ_DECL(pj_status_t) pjsua_get_call_info(unsigned call_index,
+PJ_DECL(pj_status_t) pjsua_call_get_info(unsigned call_index,
pjsua_call_info *info);
/**
* Duplicate call info.
*/
-PJ_DECL(void) pjsua_dup_call_info(pj_pool_t *pool,
+PJ_DECL(void) pjsua_call_info_dup(pj_pool_t *pool,
pjsua_call_info *dst_info,
const pjsua_call_info *src_info);
@@ -516,15 +544,15 @@ PJ_DECL(void) pjsua_dup_call_info(pj_pool_t *pool,
/**
* Make outgoing call.
*/
-PJ_DECL(pj_status_t) pjsua_make_call(unsigned acc_index,
- const pj_str_t *dst_uri,
- int *p_call_index);
+PJ_DECL(pj_status_t) pjsua_call_make_call(unsigned acc_id,
+ const pj_str_t *dst_uri,
+ int *p_call_index);
/**
* Answer call.
*/
-PJ_DECL(void) pjsua_call_answer(int call_index, int code);
+PJ_DECL(pj_status_t) pjsua_call_answer(int call_index, int code);
/**
* Hangup call.
@@ -535,19 +563,19 @@ PJ_DECL(void) pjsua_call_hangup(int call_index);
/**
* Put call on-hold.
*/
-PJ_DECL(void) pjsua_call_set_hold(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_set_hold(int call_index);
/**
* Send re-INVITE (to release hold).
*/
-PJ_DECL(void) pjsua_call_reinvite(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_reinvite(int call_index);
/**
* Transfer call.
*/
-PJ_DECL(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
+PJ_DECL(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
/**
* Dial DTMF.
@@ -559,13 +587,14 @@ PJ_DECL(pj_status_t) pjsua_call_dial_dtmf(unsigned call_index,
/**
* Send instant messaging inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *text);
+PJ_DECL(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *text);
/**
* Send IM typing indication inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing);
+PJ_DECL(pj_status_t) pjsua_call_send_typing_ind(int call_index,
+ pj_bool_t is_typing);
/**
* Terminate all calls.
@@ -576,7 +605,7 @@ PJ_DECL(void) pjsua_call_hangup_all(void);
/**
* Dump call and media statistics to string.
*/
-PJ_DECL(void) pjsua_dump_call(int call_index, int with_media,
+PJ_DECL(void) pjsua_call_dump(int call_index, int with_media,
char *buffer, unsigned maxlen,
const char *indent);
@@ -594,9 +623,34 @@ PJ_DECL(unsigned) pjsua_get_acc_count(void);
/**
* Get account info.
*/
-PJ_DECL(pj_status_t) pjsua_acc_get_info(unsigned acc_index,
+PJ_DECL(pj_status_t) pjsua_acc_get_info(pjsua_acc_id acc_id,
pjsua_acc_info *info);
+
+/**
+ * Enum accounts id.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+ unsigned *count );
+
+
+/**
+ * Enum accounts info.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+ unsigned *count );
+
+
+/**
+ * Find account for outgoing request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url);
+
+/**
+ * Find account for incoming request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata);
+
/**
* Add a new account.
* This function should be called after pjsua_init().
@@ -604,14 +658,18 @@ PJ_DECL(pj_status_t) pjsua_acc_get_info(unsigned acc_index,
* registration for this account.
*/
PJ_DECL(pj_status_t) pjsua_acc_add(const pjsua_acc_config *cfg,
- int *acc_index);
+ pjsua_acc_id *acc_id);
+
+/**
+ * Delete account.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id);
/**
* Set account's presence status.
- * Must call pjsua_pres_refresh() after this.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
+PJ_DECL(pj_status_t) pjsua_acc_set_online_status(pjsua_acc_id acc_id,
pj_bool_t is_online);
@@ -619,7 +677,8 @@ PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
* Update registration or perform unregistration. If renew argument is zero,
* this will start unregistration process.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew);
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_id,
+ pj_bool_t renew);
@@ -637,28 +696,28 @@ PJ_DECL(unsigned) pjsua_get_buddy_count(void);
/**
* Get buddy info.
*/
-PJ_DECL(pj_status_t) pjsua_buddy_get_info(unsigned buddy_index,
+PJ_DECL(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id buddy_index,
pjsua_buddy_info *info);
/**
* Add new buddy.
*/
PJ_DECL(pj_status_t) pjsua_buddy_add(const pj_str_t *uri,
- int *buddy_index);
+ pjsua_buddy_id *buddy_index);
/**
- * Enable/disable buddy's presence monitoring.
- * Must call pjsua_pres_refresh() after this.
+ * Delete buddy.
*/
-PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(unsigned buddy_index,
- pj_bool_t monitor);
+PJ_DECL(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_index);
/**
- * Refresh both presence client and server subscriptions.
+ * Enable/disable buddy's presence monitoring.
*/
-PJ_DECL(void) pjsua_pres_refresh(void);
+PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(pjsua_buddy_id buddy_index,
+ pj_bool_t monitor);
+
/**
* Dump presence subscriptions.
@@ -680,14 +739,14 @@ extern const pjsip_method pjsip_message_method;
/**
* Send IM outside dialog.
*/
-PJ_DECL(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri,
+PJ_DECL(pj_status_t) pjsua_im_send(int acc_id, const pj_str_t *dst_uri,
const pj_str_t *text);
/**
* Send typing indication outside dialog.
*/
-PJ_DECL(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
+PJ_DECL(pj_status_t) pjsua_im_typing(int acc_id, const pj_str_t *dst_uri,
pj_bool_t is_typing);
@@ -705,22 +764,29 @@ PJ_DECL(unsigned) pjsua_conf_max_ports(void);
/**
* Enum all conference ports.
*/
-PJ_DECL(pj_status_t) pjsua_conf_enum_ports(unsigned *count,
- pjmedia_conf_port_info info[]);
+PJ_DECL(pj_status_t) pjsua_conf_enum_port_ids(pjsua_conf_port_id id[],
+ unsigned *count);
+
+
+/**
+ * Get information about the specified conference port
+ */
+PJ_DECL(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+ pjsua_conf_port_info *info);
/**
* Connect conference port.
*/
-PJ_DECL(pj_status_t) pjsua_conf_connect(unsigned src_port,
- unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_connect(pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port);
/**
* Connect conference port connection.
*/
-PJ_DECL(pj_status_t) pjsua_conf_disconnect(unsigned src_port,
- unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_disconnect(pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port);
/**
@@ -733,7 +799,7 @@ PJ_DECL(pj_status_t) pjsua_player_create(const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DECL(int) pjsua_player_get_conf_port(pjsua_player_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id);
/**
@@ -760,7 +826,7 @@ PJ_DECL(pj_status_t) pjsua_recorder_create(const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DECL(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
/**
@@ -797,18 +863,21 @@ extern const char *pjsua_inv_state_names[];
* Parse arguments (pjsua_opt.c).
*/
PJ_DECL(pj_status_t) pjsua_parse_args(int argc, char *argv[],
- pjsua_config *cfg);
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call);
/**
* Load settings from a file.
*/
PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
- pjsua_config *cfg);
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call);
/**
* Get pjsua running config.
*/
-PJ_DECL(const pjsua_config*) pjsua_get_config(void);
+PJ_DECL(void) pjsua_get_config(pj_pool_t *pool,
+ pjsua_config *config);
/**
diff --git a/pjsip/include/pjsua-lib/pjsua_console_app.h b/pjsip/include/pjsua-lib/pjsua_console_app.h
index ee7213ed..8be93714 100644
--- a/pjsip/include/pjsua-lib/pjsua_console_app.h
+++ b/pjsip/include/pjsua-lib/pjsua_console_app.h
@@ -20,7 +20,7 @@
#define __PJSUA_CONSOLE_APP_H__
-void pjsua_console_app_main(void);
+void pjsua_console_app_main(const pj_str_t *uri_to_call);
extern pjsip_module pjsua_console_app_msg_logger;
extern pjsua_callback console_callback;
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 70d9a088..507e3c93 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -127,7 +127,7 @@ static pj_status_t call_destroy_media(int call_index)
/**
* Get maximum number of calls configured in pjsua.
*/
-PJ_DEF(unsigned) pjsua_get_max_calls(void)
+PJ_DEF(unsigned) pjsua_call_get_max_count(void)
{
return pjsua.config.max_calls;
}
@@ -136,7 +136,7 @@ PJ_DEF(unsigned) pjsua_get_max_calls(void)
/**
* Get current number of active calls.
*/
-PJ_DEF(unsigned) pjsua_get_call_count(void)
+PJ_DEF(unsigned) pjsua_call_get_count(void)
{
return pjsua.call_cnt;
}
@@ -166,7 +166,7 @@ PJ_DEF(pj_bool_t) pjsua_call_has_media(unsigned call_index)
/**
* Get call info.
*/
-PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
+PJ_DEF(pj_status_t) pjsua_call_get_info( unsigned call_index,
pjsua_call_info *info)
{
pjsua_call *call;
@@ -212,8 +212,8 @@ PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
}
- info->cause = call->inv->cause;
- info->cause_text = *pjsip_get_status_text(info->cause);
+ info->last_status = call->last_code;
+ info->last_status_text = *pjsip_get_status_text(info->last_status);
info->has_media = (call->session != NULL);
info->conf_slot = call->conf_slot;
@@ -225,7 +225,7 @@ PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
/**
* Duplicate call info.
*/
-PJ_DEF(void) pjsua_dup_call_info( pj_pool_t *pool,
+PJ_DEF(void) pjsua_call_info_dup( pj_pool_t *pool,
pjsua_call_info *dst_info,
const pjsua_call_info *src_info)
{
@@ -245,9 +245,9 @@ PJ_DEF(void) pjsua_dup_call_info( pj_pool_t *pool,
/**
* Make outgoing call.
*/
-PJ_DEF(pj_status_t) pjsua_make_call(unsigned acc_index,
- const pj_str_t *dest_uri,
- int *p_call_index)
+PJ_DEF(pj_status_t) pjsua_call_make_call(unsigned acc_index,
+ const pj_str_t *dest_uri,
+ int *p_call_index)
{
pjsip_dialog *dlg = NULL;
pjmedia_sdp_session *offer;
@@ -384,18 +384,18 @@ on_error:
/**
* Answer call.
*/
-PJ_DEF(void) pjsua_call_answer(int call_index, int code)
+PJ_DEF(pj_status_t) pjsua_call_answer(int call_index, int code)
{
pjsip_tx_data *tdata;
pj_status_t status;
- PJ_ASSERT_ON_FAIL(call_index >= 0 &&
+ PJ_ASSERT_RETURN( call_index >= 0 &&
call_index < (int)pjsua.config.max_calls,
- return);
+ PJ_EINVAL);
if (pjsua.calls[call_index].inv == NULL) {
PJ_LOG(3,(THIS_FILE, "Call %d already disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
status = pjsip_inv_answer(pjsua.calls[call_index].inv,
@@ -408,6 +408,7 @@ PJ_DEF(void) pjsua_call_answer(int call_index, int code)
pjsua_perror(THIS_FILE, "Unable to create/send response",
status);
+ return status;
}
@@ -612,6 +613,11 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
pjsua.config.uas_duration);
}
+ /* Notify application */
+ if (pjsua.cb.on_incoming_call)
+ pjsua.cb.on_incoming_call(acc_index, call_index, rdata);
+
+
/* This INVITE request has been handled. */
return PJ_TRUE;
}
@@ -635,17 +641,19 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
case PJSIP_INV_STATE_CONNECTING:
if (call->res_time.sec == 0)
pj_gettimeofday(&call->res_time);
+ call->last_code = e->body.tsx_state.tsx->status_code;
break;
case PJSIP_INV_STATE_CONFIRMED:
pj_gettimeofday(&call->conn_time);
break;
case PJSIP_INV_STATE_DISCONNECTED:
pj_gettimeofday(&call->dis_time);
+ if (e->body.tsx_state.tsx->status_code > call->last_code) {
+ call->last_code = e->body.tsx_state.tsx->status_code;
+ }
break;
default:
- /* Nothing to do. Just to keep gcc from complaining about
- * unused enums.
- */
+ call->last_code = e->body.tsx_state.tsx->status_code;
break;
}
@@ -682,7 +690,7 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
break;
- default:
+ case PJSIP_INV_STATE_INCOMING:
/* Nothing to do. Just to keep gcc from complaining about
* unused enums.
*/
@@ -853,7 +861,7 @@ static void on_call_transfered( pjsip_inv_session *inv,
/* Now make the outgoing call. */
tmp = pj_str(uri);
- status = pjsua_make_call(existing_call->acc_index, &tmp, &new_call);
+ status = pjsua_call_make_call(existing_call->acc_index, &tmp, &new_call);
if (status != PJ_SUCCESS) {
/* Notify xferer about the error */
@@ -1354,7 +1362,7 @@ PJ_DEF(void) pjsua_call_hangup(int call_index)
/*
* Put call on-Hold.
*/
-PJ_DEF(void) pjsua_call_set_hold(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_set_hold(int call_index)
{
pjmedia_sdp_session *sdp;
pjsua_call *call;
@@ -1365,37 +1373,39 @@ PJ_DEF(void) pjsua_call_set_hold(int call_index)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
- return;
+ return PJSIP_ESESSIONSTATE;
}
status = create_inactive_sdp(call, &sdp);
if (status != PJ_SUCCESS)
- return;
+ return status;
/* Send re-INVITE with new offer */
status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
- return;
+ return status;
}
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
- return;
+ return status;
}
+
+ return PJ_SUCCESS;
}
/*
* re-INVITE.
*/
-PJ_DEF(void) pjsua_call_reinvite(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_reinvite(int call_index)
{
pjmedia_sdp_session *sdp;
pjsip_tx_data *tdata;
@@ -1406,13 +1416,13 @@ PJ_DEF(void) pjsua_call_reinvite(int call_index)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
- return;
+ return PJSIP_ESESSIONSTATE;
}
/* Create SDP */
@@ -1421,28 +1431,30 @@ PJ_DEF(void) pjsua_call_reinvite(int call_index)
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
status);
- return;
+ return status;
}
/* Send re-INVITE with new offer */
status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
- return;
+ return status;
}
status = pjsip_inv_send_msg( call->inv, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
- return;
+ return status;
}
+
+ return PJ_SUCCESS;
}
/*
* Transfer call.
*/
-PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
+PJ_DEF(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
{
pjsip_evsub *sub;
pjsip_tx_data *tdata;
@@ -1454,7 +1466,7 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Create xfer client subscription.
@@ -1464,7 +1476,7 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
status = pjsip_xfer_create_uac(call->inv->dlg, NULL, &sub);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create xfer", status);
- return;
+ return status;
}
/*
@@ -1473,20 +1485,22 @@ PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
status = pjsip_xfer_initiate(sub, dest, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
- return;
+ return status;
}
/* Send. */
status = pjsip_xfer_send_request(sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
- return;
+ return status;
}
/* For simplicity (that's what this program is intended to be!),
* leave the original invite session as it is. More advanced application
* may want to hold the INVITE, or terminate the invite, or whatever.
*/
+
+ return PJ_SUCCESS;
}
@@ -1512,7 +1526,7 @@ PJ_DEF(pj_status_t) pjsua_call_dial_dtmf( unsigned call_index,
/**
* Send instant messaging inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
+PJ_DEF(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *str)
{
pjsua_call *call;
const pj_str_t mime_text = pj_str("text");
@@ -1524,7 +1538,7 @@ PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Lock dialog. */
@@ -1560,13 +1574,15 @@ PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
on_return:
pjsip_dlg_dec_lock(call->inv->dlg);
+ return status;
}
/**
* Send IM typing indication inside INVITE session.
*/
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
+PJ_DEF(pj_status_t) pjsua_call_send_typing_ind(int call_index,
+ pj_bool_t is_typing)
{
pjsua_call *call;
pjsip_tx_data *tdata;
@@ -1576,7 +1592,7 @@ PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
if (!call->inv) {
PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
- return;
+ return PJSIP_ESESSIONTERMINATED;
}
/* Lock dialog. */
@@ -1602,7 +1618,9 @@ PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
}
on_return:
- pjsip_dlg_dec_lock(call->inv->dlg);}
+ pjsip_dlg_dec_lock(call->inv->dlg);
+ return status;
+}
/*
diff --git a/pjsip/src/pjsua-lib/pjsua_console_app.c b/pjsip/src/pjsua-lib/pjsua_console_app.c
index 58f64c7f..a54dd689 100644
--- a/pjsip/src/pjsua-lib/pjsua_console_app.c
+++ b/pjsip/src/pjsua-lib/pjsua_console_app.c
@@ -36,7 +36,7 @@ static pj_bool_t find_next_call(void)
{
int i, max;
- max = pjsua_get_max_calls();
+ max = pjsua_call_get_max_count();
for (i=current_call+1; i<max; ++i) {
if (pjsua_call_is_active(i)) {
current_call = i;
@@ -63,7 +63,7 @@ static pj_bool_t find_prev_call(void)
{
int i, max;
- max = pjsua_get_max_calls();
+ max = pjsua_call_get_max_count();
for (i=current_call-1; i>=0; --i) {
if (pjsua_call_is_active(i)) {
current_call = i;
@@ -93,14 +93,14 @@ static void console_on_call_state(int call_index, pjsip_event *e)
PJ_UNUSED_ARG(e);
- pjsua_get_call_info(call_index, &call_info);
+ pjsua_call_get_info(call_index, &call_info);
if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {
PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]",
call_index,
- call_info.cause,
- call_info.cause_text.ptr));
+ call_info.last_status,
+ call_info.last_status_text.ptr));
if ((int)call_index == current_call) {
find_next_call();
@@ -385,31 +385,32 @@ static void ui_input_url(const char *title, char *buf, int len,
static void conf_list(void)
{
unsigned i, count;
- pjmedia_conf_port_info info[PJSUA_MAX_CALLS];
+ pjsua_conf_port_id id[PJSUA_MAX_CALLS];
printf("Conference ports:\n");
- count = PJ_ARRAY_SIZE(info);
- pjsua_conf_enum_ports(&count, info);
+ count = PJ_ARRAY_SIZE(id);
+ pjsua_conf_enum_port_ids(id, &count);
+
for (i=0; i<count; ++i) {
char txlist[PJSUA_MAX_CALLS*4+10];
- int j;
- pjmedia_conf_port_info *port_info = &info[i];
-
+ unsigned j;
+ pjsua_conf_port_info info;
+
+ pjsua_conf_get_port_info(id[i], &info);
+
txlist[0] = '\0';
- for (j=0; j<(int)count; ++j) {
+ for (j=0; j<info.listener_cnt; ++j) {
char s[10];
- if (port_info->listener[j]) {
- pj_ansi_sprintf(s, "#%d ", j);
- pj_ansi_strcat(txlist, s);
- }
+ pj_ansi_sprintf(s, "#%d ", info.listeners[j]);
+ pj_ansi_strcat(txlist, s);
}
printf("Port #%02d[%2dKHz/%dms] %20.*s transmitting to: %s\n",
- port_info->slot,
- port_info->clock_rate/1000,
- port_info->samples_per_frame * 1000 / port_info->clock_rate,
- (int)port_info->name.slen,
- port_info->name.ptr,
+ info.slot_id,
+ info.clock_rate/1000,
+ info.samples_per_frame * 1000 / info.clock_rate,
+ (int)info.name.slen,
+ info.name.ptr,
txlist);
}
@@ -417,7 +418,7 @@ static void conf_list(void)
}
-void pjsua_console_app_main(void)
+void pjsua_console_app_main(const pj_str_t *uri_to_call)
{
char menuin[10];
char buf[128];
@@ -431,9 +432,8 @@ void pjsua_console_app_main(void)
/* If user specifies URI to call, then call the URI */
- if (pjsua_get_config()->uri_to_call.slen) {
- pjsua_make_call( current_acc, &pjsua_get_config()->uri_to_call,
- NULL);
+ if (uri_to_call->slen) {
+ pjsua_call_make_call( current_acc, uri_to_call, NULL);
}
keystroke_help();
@@ -449,7 +449,8 @@ void pjsua_console_app_main(void)
case 'm':
/* Make call! : */
- printf("(You currently have %d calls)\n", pjsua_get_call_count());
+ printf("(You currently have %d calls)\n",
+ pjsua_call_get_count());
uri = NULL;
ui_input_url("Make call", buf, sizeof(buf), &result);
@@ -469,12 +470,13 @@ void pjsua_console_app_main(void)
}
tmp = pj_str(uri);
- pjsua_make_call( current_acc, &tmp, NULL);
+ pjsua_call_make_call( current_acc, &tmp, NULL);
break;
case 'M':
/* Make multiple calls! : */
- printf("(You currently have %d calls)\n", pjsua_get_call_count());
+ printf("(You currently have %d calls)\n",
+ pjsua_call_get_count());
if (!simple_input("Number of calls", menuin, sizeof(menuin)))
continue;
@@ -500,7 +502,7 @@ void pjsua_console_app_main(void)
pj_status_t status;
tmp = pj_str(uri);
- status = pjsua_make_call(current_acc, &tmp, NULL);
+ status = pjsua_call_make_call(current_acc, &tmp, NULL);
if (status != PJ_SUCCESS)
break;
}
@@ -540,7 +542,7 @@ void pjsua_console_app_main(void)
/* Send typing indication. */
if (i != -1)
- pjsua_call_typing(i, PJ_TRUE);
+ pjsua_call_send_typing_ind(i, PJ_TRUE);
else {
pj_str_t tmp_uri = pj_str(uri);
pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE);
@@ -553,7 +555,7 @@ void pjsua_console_app_main(void)
* Send typing notification too, saying we're not typing.
*/
if (i != -1)
- pjsua_call_typing(i, PJ_FALSE);
+ pjsua_call_send_typing_ind(i, PJ_FALSE);
else {
pj_str_t tmp_uri = pj_str(uri);
pjsua_im_typing(current_acc, &tmp_uri, PJ_FALSE);
@@ -576,7 +578,7 @@ void pjsua_console_app_main(void)
case 'a':
if (current_call != -1) {
- pjsua_get_call_info(current_call, &call_info);
+ pjsua_call_get_info(current_call, &call_info);
} else {
/* Make compiler happy */
call_info.active = 0;
@@ -650,7 +652,7 @@ void pjsua_console_app_main(void)
if (current_call != -1) {
- pjsua_get_call_info(current_call, &call_info);
+ pjsua_call_get_info(current_call, &call_info);
PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s",
(int)call_info.remote_info.slen,
call_info.remote_info.ptr));
@@ -781,8 +783,6 @@ void pjsua_console_app_main(void)
pjsua_buddy_subscribe_pres(result.nb_result-1, (menuin[0]=='s'));
}
- pjsua_pres_refresh();
-
} else if (result.uri_result) {
puts("Sorry, can only subscribe to buddy's presence, "
"not arbitrary URL (for now)");
@@ -814,7 +814,6 @@ void pjsua_console_app_main(void)
printf("Setting %s online status to %s\n",
acc_info.acc_id.ptr,
(acc_info.online_status?"online":"offline"));
- pjsua_pres_refresh();
break;
case 'c':
@@ -897,80 +896,6 @@ on_exit:
/*****************************************************************************
- * This is a very simple PJSIP module, whose sole purpose is to display
- * incoming and outgoing messages to log. This module will have priority
- * higher than transport layer, which means:
- *
- * - incoming messages will come to this module first before reaching
- * transaction layer.
- *
- * - outgoing messages will come to this module last, after the message
- * has been 'printed' to contiguous buffer by transport layer and
- * appropriate transport instance has been decided for this message.
- *
- */
-
-/* Notification on incoming messages */
-static pj_bool_t console_on_rx_msg(pjsip_rx_data *rdata)
-{
- PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
- "%s\n"
- "--end msg--",
- rdata->msg_info.len,
- pjsip_rx_data_get_info(rdata),
- rdata->pkt_info.src_name,
- rdata->pkt_info.src_port,
- rdata->msg_info.msg_buf));
-
- /* Always return false, otherwise messages will not get processed! */
- return PJ_FALSE;
-}
-
-/* Notification on outgoing messages */
-static pj_status_t console_on_tx_msg(pjsip_tx_data *tdata)
-{
-
- /* Important note:
- * tp_info field is only valid after outgoing messages has passed
- * transport layer. So don't try to access tp_info when the module
- * has lower priority than transport layer.
- */
-
- PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
- "%s\n"
- "--end msg--",
- (tdata->buf.cur - tdata->buf.start),
- pjsip_tx_data_get_info(tdata),
- tdata->tp_info.dst_name,
- tdata->tp_info.dst_port,
- tdata->buf.start));
-
- /* Always return success, otherwise message will not get sent! */
- return PJ_SUCCESS;
-}
-
-/* The module instance. */
-pjsip_module pjsua_console_app_msg_logger =
-{
- NULL, NULL, /* prev, next. */
- { "mod-pjsua-log", 13 }, /* Name. */
- -1, /* Id */
- PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
- NULL, /* load() */
- NULL, /* start() */
- NULL, /* stop() */
- NULL, /* unload() */
- &console_on_rx_msg, /* on_rx_request() */
- &console_on_rx_msg, /* on_rx_response() */
- &console_on_tx_msg, /* on_tx_request. */
- &console_on_tx_msg, /* on_tx_response() */
- NULL, /* on_tsx_state() */
-
-};
-
-
-
-/*****************************************************************************
* Error display:
*/
@@ -992,7 +917,8 @@ void pjsua_perror(const char *sender, const char *title,
pjsua_callback console_callback =
{
&console_on_call_state,
- NULL, /* default accept transfer */
+ NULL, /* on_incoming_call */
+ NULL, /* default accept transfer */
&console_on_reg_state,
&console_on_buddy_state,
&console_on_pager,
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 3f63ce8f..01b6c8c4 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -55,6 +55,7 @@ PJ_DEF(void) pjsua_default_config(pjsua_config *cfg)
cfg->media_thread_cnt = 1;
cfg->udp_port = 5060;
cfg->start_rtp_port = 4000;
+ cfg->msg_logging = PJ_TRUE;
cfg->max_calls = 4;
cfg->conf_ports = 0;
@@ -721,6 +722,8 @@ static void copy_acc_config(pj_pool_t *pool,
{
unsigned j;
+ pj_memcpy(dst_acc, src_acc, sizeof(pjsua_acc_config));
+
pj_strdup_with_null(pool, &dst_acc->id, &src_acc->id);
pj_strdup_with_null(pool, &dst_acc->reg_uri, &src_acc->reg_uri);
pj_strdup_with_null(pool, &dst_acc->contact, &src_acc->contact);
@@ -742,7 +745,7 @@ static void copy_acc_config(pj_pool_t *pool,
/*
* Copy configuration.
*/
-static void copy_config(pj_pool_t *pool, pjsua_config *dst,
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst,
const pjsua_config *src)
{
unsigned i;
@@ -761,7 +764,7 @@ static void copy_config(pj_pool_t *pool, pjsua_config *dst,
}
pj_strdup_with_null(pool, &dst->outbound_proxy, &src->outbound_proxy);
- pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
+ //pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
for (i=0; i<src->acc_cnt; ++i) {
pjsua_acc_config *dst_acc = &dst->acc_config[i];
@@ -813,6 +816,10 @@ static pj_status_t logging_init()
}
}
+ /* Enable SIP message logging */
+ if (pjsua.config.msg_logging)
+ pjsip_endpt_register_module(pjsua.endpt, &pjsua_msg_logger);
+
return PJ_SUCCESS;
}
@@ -863,7 +870,7 @@ PJ_DECL(pj_status_t) pjsua_init(const pjsua_config *cfg,
}
/* Copy configuration */
- copy_config(pjsua.pool, &pjsua.config, cfg);
+ pjsua_copy_config(pjsua.pool, &pjsua.config, cfg);
/* Copy callback */
pj_memcpy(&pjsua.cb, cb, sizeof(pjsua_callback));
@@ -1026,7 +1033,7 @@ on_error:
/*
* Find account for incoming request.
*/
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
{
pjsip_uri *uri;
pjsip_sip_uri *sip_uri;
@@ -1034,11 +1041,11 @@ int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
uri = rdata->msg_info.to->uri;
- /* Just return last account if To URI is not SIP: */
+ /* Just return default account if To URI is not SIP: */
if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
!PJSIP_URI_SCHEME_IS_SIPS(uri))
{
- return pjsua.config.acc_cnt;
+ return pjsua.default_acc;
}
@@ -1068,20 +1075,60 @@ int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
}
}
- /* Still no match, just return last account */
- return pjsua.config.acc_cnt;
+ /* Still no match, use default account */
+ return pjsua.default_acc;
}
/*
* Find account for outgoing request.
*/
-int pjsua_find_account_for_outgoing(const pj_str_t *url)
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *str_url)
{
- PJ_UNUSED_ARG(url);
+ pj_str_t tmp;
+ pjsip_uri *uri;
+ pjsip_sip_uri *sip_uri;
+ unsigned i;
- /* Just use account #0 */
- return 0;
+ pj_strdup_with_null(pjsua.pool, &tmp, str_url);
+
+ uri = pjsip_parse_uri(pjsua.pool, tmp.ptr, tmp.slen, 0);
+ if (!uri)
+ return pjsua.config.acc_cnt-1;
+
+ if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
+ !PJSIP_URI_SCHEME_IS_SIPS(uri))
+ {
+ /* Return the first account with proxy */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ if (pjsua.config.acc_config[i].proxy.slen)
+ break;
+ }
+
+ if (i != PJ_ARRAY_SIZE(pjsua.acc))
+ return i;
+
+ /* Not found, use default account */
+ return pjsua.default_acc;
+ }
+
+ sip_uri = pjsip_uri_get_uri(uri);
+
+ /* Find matching domain */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ if (pj_stricmp(&pjsua.acc[i].host_part, &sip_uri->host)==0)
+ break;
+ }
+
+ if (i != PJ_ARRAY_SIZE(pjsua.acc))
+ return i;
+
+ /* Just use default account */
+ return pjsua.default_acc;
}
@@ -1192,6 +1239,10 @@ static pj_status_t init_acc(unsigned acc_index)
pj_list_push_back(&acc->route_set, r);
}
+ /* Mark account as valid */
+ pjsua.acc[acc_index].valid = PJ_TRUE;
+
+
return PJ_SUCCESS;
}
@@ -1199,23 +1250,34 @@ static pj_status_t init_acc(unsigned acc_index)
* Add a new account.
*/
PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg,
- int *acc_index)
+ pjsua_acc_id *acc_index)
{
+ unsigned index;
pj_status_t status;
- PJ_ASSERT_RETURN(pjsua.config.acc_cnt<PJ_ARRAY_SIZE(pjsua.config.acc_config),
+ PJ_ASSERT_RETURN(pjsua.config.acc_cnt <
+ PJ_ARRAY_SIZE(pjsua.config.acc_config),
PJ_ETOOMANY);
- copy_acc_config(pjsua.pool, &pjsua.config.acc_config[pjsua.config.acc_cnt], cfg);
+ /* Find empty account index. */
+ for (index=0; index < PJ_ARRAY_SIZE(pjsua.acc); ++index) {
+ if (pjsua.acc[index].valid == PJ_FALSE)
+ break;
+ }
+
+ /* Expect to find a slot */
+ PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.acc), PJ_EBUG);
+
+ copy_acc_config(pjsua.pool, &pjsua.config.acc_config[index], cfg);
- status = init_acc(pjsua.config.acc_cnt);
+ status = init_acc(index);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding account", status);
return status;
}
if (acc_index)
- *acc_index = pjsua.config.acc_cnt;
+ *acc_index = index;
pjsua.config.acc_cnt++;
@@ -1223,6 +1285,25 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg,
}
+/*
+ * Delete account.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_index)
+{
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+ /* Delete registration */
+ if (pjsua.acc[acc_index].regc != NULL)
+ pjsua_acc_set_registration(acc_index, PJ_FALSE);
+
+ /* Invalidate */
+ pjsua.acc[acc_index].valid = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
+
/*
* Start pjsua stack.
@@ -1266,7 +1347,7 @@ PJ_DEF(pj_status_t) pjsua_start(void)
pj_str_t tmp, id;
tmp.ptr = buf;
- tmp.slen = pj_ansi_sprintf(tmp.ptr, "<sip:%s:%d>",
+ tmp.slen = pj_ansi_sprintf(tmp.ptr, "Local <sip:%s:%d>",
pjsua.config.sip_host.ptr,
pjsua.config.sip_port);
pj_strdup_with_null( pjsua.pool, &id, &tmp);
@@ -1283,6 +1364,17 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
+ /* Add another account as the last one.
+ * This account corresponds to local endpoint, and is user-less.
+ * This is also the default account.
+ */
+ if (pjsua.config.acc_cnt < PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+ pjsua.default_acc = pjsua.config.acc_cnt;
+ pjsua.acc[pjsua.default_acc].auto_gen = 1;
+ pjsua.config.acc_cnt++;
+ }
+
+
/* Initialize accounts: */
for (i=0; i<(int)pjsua.config.acc_cnt; ++i) {
status = init_acc(i);
@@ -1293,7 +1385,6 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
-
/* Create worker thread(s), if required: */
for (i=0; i<(int)pjsua.config.thread_cnt; ++i) {
@@ -1333,6 +1424,9 @@ PJ_DEF(pj_status_t) pjsua_start(void)
}
+ /* Refresh presence */
+ pjsua_pres_refresh();
+
PJ_LOG(3,(THIS_FILE, "PJSUA version %s started", PJ_VERSION));
return PJ_SUCCESS;
@@ -1368,22 +1462,55 @@ PJ_DEF(unsigned) pjsua_conf_max_ports(void)
/**
- * Enum all conference ports.
+ * Enum all conference port ID.
*/
-PJ_DEF(pj_status_t) pjsua_conf_enum_ports( unsigned *count,
- pjmedia_conf_port_info info[])
+PJ_DEF(pj_status_t) pjsua_conf_enum_port_ids( pjsua_conf_port_id id[],
+ unsigned *count)
{
- return pjmedia_conf_get_ports_info(pjsua.mconf, count, info);
+ return pjmedia_conf_enum_ports( pjsua.mconf, (unsigned*)id, count);
}
+/**
+ * Get information about the specified conference port
+ */
+PJ_DEF(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+ pjsua_conf_port_info *info)
+{
+ pjmedia_conf_port_info cinfo;
+ unsigned i, count;
+ pj_status_t status;
+
+ status = pjmedia_conf_get_port_info( pjsua.mconf, id, &cinfo);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_memset(info, 0, sizeof(*info));
+ info->slot_id = id;
+ info->name = cinfo.name;
+ info->clock_rate = cinfo.clock_rate;
+ info->channel_count = cinfo.channel_count;
+ info->samples_per_frame = cinfo.samples_per_frame;
+ info->bits_per_sample = cinfo.bits_per_sample;
+
+ /* Build array of listeners */
+ count = pjsua.config.conf_ports;
+ for (i=0; i<count; ++i) {
+ if (cinfo.listener[i]) {
+ info->listeners[info->listener_cnt++] = i;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
/**
* Connect conference port.
*/
-PJ_DEF(pj_status_t) pjsua_conf_connect( unsigned src_port,
- unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port)
{
return pjmedia_conf_connect_port(pjsua.mconf, src_port, dst_port, 0);
}
@@ -1392,8 +1519,8 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( unsigned src_port,
/**
* Connect conference port connection.
*/
-PJ_DEF(pj_status_t) pjsua_conf_disconnect( unsigned src_port,
- unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id src_port,
+ pjsua_conf_port_id dst_port)
{
return pjmedia_conf_disconnect_port(pjsua.mconf, src_port, dst_port);
}
@@ -1434,7 +1561,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
pjsua.player[pjsua.player_cnt].port = port;
pjsua.player[pjsua.player_cnt].slot = slot;
- if (*id)
+ if (id)
*id = pjsua.player_cnt;
++pjsua.player_cnt;
@@ -1446,7 +1573,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DEF(int) pjsua_player_get_conf_port(pjsua_player_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.player), PJ_EINVAL);
return pjsua.player[id].slot;
@@ -1530,7 +1657,7 @@ PJ_DEF(pj_status_t) pjsua_recorder_create( const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DEF(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.recorder), PJ_EINVAL);
return pjsua.recorder[id].slot;
diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c
index efd8cbf6..807f2fac 100644
--- a/pjsip/src/pjsua-lib/pjsua_im.c
+++ b/pjsip/src/pjsua-lib/pjsua_im.c
@@ -185,6 +185,7 @@ static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata)
{
pj_str_t from, to;
pjsip_accept_hdr *accept_hdr;
+ pjsip_contact_hdr *contact_hdr;
pjsip_msg *msg;
pj_status_t status;
@@ -221,11 +222,23 @@ static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata)
status = pjsip_endpt_respond( pjsua.endpt, NULL, rdata, 200, NULL,
NULL, NULL, NULL);
- /* Build the From text. */
+ /* For the source URI, we use Contact header if present, since
+ * Contact header contains the port number information. If this is
+ * not available, then use From header.
+ */
from.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
- from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
- rdata->msg_info.from->uri,
- from.ptr, PJSIP_MAX_URL_SIZE);
+ contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg,
+ PJSIP_H_CONTACT, NULL);
+ if (contact_hdr) {
+ from.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
+ contact_hdr->uri,
+ from.ptr, PJSIP_MAX_URL_SIZE);
+ } else {
+ from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
+ rdata->msg_info.from->uri,
+ from.ptr, PJSIP_MAX_URL_SIZE);
+ }
+
if (from.slen < 1)
from = pj_str("<--URI is too long-->");
@@ -336,6 +349,7 @@ PJ_DEF(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri,
PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
pj_bool_t is_typing)
{
+ const pj_str_t STR_CONTACT = { "Contact", 7 };
pjsip_tx_data *tdata;
pj_status_t status;
@@ -350,6 +364,18 @@ PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,
}
+ /* Add accept header. */
+ pjsip_msg_add_hdr( tdata->msg,
+ (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
+
+
+ /* Add contact. */
+ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
+ pjsip_generic_string_hdr_create(tdata->pool,
+ &STR_CONTACT,
+ &pjsua.config.acc_config[acc_index].contact));
+
+
/* Create "application/im-iscomposing+xml" msg body. */
tdata->msg->body = pjsip_iscomposing_create_body( tdata->pool, is_typing,
NULL, NULL, -1);
diff --git a/pjsip/src/pjsua-lib/pjsua_imp.h b/pjsip/src/pjsua-lib/pjsua_imp.h
index ec1918d3..117a2d12 100644
--- a/pjsip/src/pjsua-lib/pjsua_imp.h
+++ b/pjsip/src/pjsua-lib/pjsua_imp.h
@@ -32,6 +32,7 @@ struct pjsua_call
{
unsigned index; /**< Index in pjsua array. */
pjsip_inv_session *inv; /**< The invite session. */
+ pjsip_status_code last_code; /**<Last status code seen. */
pj_time_val start_time;/**< First INVITE sent/received. */
pj_time_val res_time; /**< First response sent/received. */
pj_time_val conn_time; /**< Connected/confirmed time. */
@@ -61,7 +62,6 @@ struct pjsua_buddy
pj_str_t display; /**< Buddy display name. */
pj_str_t host; /**< Buddy host. */
unsigned port; /**< Buddy port. */
- int acc_index; /**< Which account to use. */
pj_bool_t monitor; /**< Should we monitor? */
pjsip_evsub *sub; /**< Buddy presence subscription */
pjsip_pres_status status; /**< Buddy presence status. */
@@ -89,6 +89,8 @@ typedef struct pjsua_srv_pres pjsua_srv_pres;
*/
struct pjsua_acc
{
+ pj_bool_t valid; /**< Is this account valid? */
+ pj_bool_t auto_gen; /**< Is this account generated. */
int index; /**< Index in accounts array. */
pj_str_t user_part; /**< User part of local URI. */
pj_str_t host_part; /**< Host part of local URI. */
@@ -159,6 +161,7 @@ struct pjsua
} recorder[32];
/* Account: */
+ int default_acc; /**< Default account to use. */
pjsua_acc acc[PJSUA_MAX_ACC]; /** Client regs array. */
@@ -175,7 +178,6 @@ struct pjsua
unsigned call_cnt; /**< Number of calls. */
pjsua_call calls[PJSUA_MAX_CALLS]; /** Calls array. */
-
/* SIMPLE and buddy status: */
pjsua_buddy buddies[PJSUA_MAX_BUDDIES];
};
@@ -185,17 +187,8 @@ struct pjsua
extern struct pjsua pjsua;
-
-/**
- * Find account for incoming request.
- */
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata);
-
-
-/**
- * Find account for outgoing request.
- */
-int pjsua_find_account_for_outgoing(const pj_str_t *url);
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst,
+ const pjsua_config *src);
/**
@@ -225,6 +218,11 @@ pj_status_t pjsua_pres_init();
/**
+ * Refresh both presence client and server subscriptions.
+ */
+void pjsua_pres_refresh(void);
+
+/**
* Terminate all subscriptions
*/
void pjsua_pres_shutdown(void);
@@ -255,6 +253,7 @@ void pjsua_im_process_pager(int call_id, const pj_str_t *from,
const pj_str_t *to, pjsip_rx_data *rdata);
+extern pjsip_module pjsua_msg_logger;
#endif /* __PJSUA_IMP_H__ */
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index c76d3cbb..b24ffd3c 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -97,7 +97,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata)
/* Incoming SUBSCRIBE: */
/* Find which account for the incoming request. */
- acc_index = pjsua_find_account_for_incoming(rdata);
+ acc_index = pjsua_acc_find_for_incoming(rdata);
acc_config = &pjsua.config.acc_config[acc_index];
/* Create UAS dialog: */
@@ -310,7 +310,8 @@ static void subscribe_buddy_presence(unsigned index)
pjsip_tx_data *tdata;
pj_status_t status;
- acc_index = pjsua.buddies[index].acc_index;
+ acc_index = pjsua_acc_find_for_outgoing(&pjsua.config.buddy_uri[index]);
+
acc_config = &pjsua.config.acc_config[acc_index];
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
@@ -439,12 +440,13 @@ PJ_DEF(unsigned) pjsua_get_buddy_count(void)
/**
* Get buddy info.
*/
-PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
+PJ_DEF(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id index,
pjsua_buddy_info *info)
{
pjsua_buddy *buddy;
- PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
pj_memset(info, 0, sizeof(pjsua_buddy_info));
@@ -471,7 +473,6 @@ PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
info->status_text = pj_str("Offline");
}
- info->acc_index = buddy->acc_index;
return PJ_SUCCESS;
}
@@ -480,17 +481,27 @@ PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
* Add new buddy.
*/
PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
- int *buddy_index)
+ pjsua_buddy_id *buddy_index)
{
pjsip_name_addr *url;
pjsip_sip_uri *sip_uri;
int index;
pj_str_t tmp;
- PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <= PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <=
+ PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_ETOOMANY);
+
+ /* Find empty slot */
+ for (index=0; index<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++index) {
+ if (pjsua.config.buddy_uri[index].slen == 0)
+ break;
+ }
+
+ /* Expect to find an empty slot */
+ PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
PJ_ETOOMANY);
- index = pjsua.config.buddy_cnt;
/* Get name and display name for buddy */
pj_strdup_with_null(pjsua.pool, &tmp, uri);
@@ -511,10 +522,6 @@ PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
if (pjsua.buddies[index].port == 0)
pjsua.buddies[index].port = 5060;
- /* Find account for outgoing preence subscription */
- pjsua.buddies[index].acc_index =
- pjsua_find_account_for_outgoing(&pjsua.config.buddy_uri[index]);
-
if (buddy_index)
*buddy_index = index;
@@ -525,24 +532,52 @@ PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
-PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( unsigned index,
+/**
+ * Delete buddy.
+ */
+PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id index)
+{
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
+
+ if (pjsua.config.buddy_uri[index].slen == 0)
+ return PJ_SUCCESS;
+
+ /* Unsubscribe presence */
+ pjsua_buddy_subscribe_pres(index, PJ_FALSE);
+
+ /* Remove buddy */
+ pjsua.config.buddy_uri[index].slen = 0;
+ pjsua.config.buddy_cnt--;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id index,
pj_bool_t monitor)
{
pjsua_buddy *buddy;
- PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+ PJ_EINVAL);
buddy = &pjsua.buddies[index];
buddy->monitor = monitor;
+ pjsua_pres_refresh();
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pjsua_acc_set_online_status( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_set_online_status( pjsua_acc_id acc_index,
pj_bool_t is_online)
{
- PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(acc_index < (int)PJ_ARRAY_SIZE(pjsua.acc),
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
pjsua.acc[acc_index].online_status = is_online;
+ pjsua_pres_refresh();
return PJ_SUCCESS;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_reg.c b/pjsip/src/pjsua-lib/pjsua_reg.c
index f85bcd77..54dbcbd2 100644
--- a/pjsip/src/pjsua-lib/pjsua_reg.c
+++ b/pjsip/src/pjsua-lib/pjsua_reg.c
@@ -95,16 +95,21 @@ PJ_DEF(unsigned) pjsua_get_acc_count(void)
/**
* Get account info.
*/
-PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_index,
pjsua_acc_info *info)
{
pjsua_acc *acc = &pjsua.acc[acc_index];
pjsua_acc_config *acc_cfg = &pjsua.config.acc_config[acc_index];
- PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
-
+ PJ_ASSERT_RETURN(info != NULL, PJ_EINVAL);
+
pj_memset(info, 0, sizeof(pjsua_acc_info));
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+
info->index = acc_index;
info->acc_id = acc_cfg->id;
info->has_registration = (acc->regc != NULL);
@@ -114,9 +119,12 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
info->status = acc->reg_last_err;
pj_strerror(acc->reg_last_err, info->buf, sizeof(info->buf));
info->status_text = pj_str(info->buf);
- } else {
+ } else if (acc->reg_last_code) {
info->status = acc->reg_last_code;
info->status_text = *pjsip_get_status_text(acc->reg_last_code);
+ } else {
+ info->status = 0;
+ info->status_text = pj_str("In Progress");
}
if (acc->regc) {
@@ -129,14 +137,57 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
}
+PJ_DEF(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+ unsigned *count )
+{
+ unsigned i, c;
+
+ for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+
+ pjsua_acc_get_info(i, &info[c]);
+ ++c;
+ }
+
+ *count = c;
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Enum accounts id.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+ unsigned *count )
+{
+ unsigned i, c;
+
+ for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+ if (!pjsua.acc[i].valid)
+ continue;
+ ids[c] = i;
+ ++c;
+ }
+
+ *count = c;
+ return PJ_SUCCESS;
+}
+
+
/*
* Update registration. If renew is false, then unregistration will be performed.
*/
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_index,
+ pj_bool_t renew)
{
pj_status_t status = 0;
pjsip_tx_data *tdata = 0;
+ PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
if (renew) {
if (pjsua.acc[acc_index].regc == NULL) {
status = pjsua_regc_init(acc_index);
diff --git a/pjsip/src/pjsua-lib/pjsua_settings.c b/pjsip/src/pjsua-lib/pjsua_settings.c
index be615359..db30312d 100644
--- a/pjsip/src/pjsua-lib/pjsua_settings.c
+++ b/pjsip/src/pjsua-lib/pjsua_settings.c
@@ -211,7 +211,8 @@ static int my_atoi(const char *cs)
/* Parse arguments. */
PJ_DEF(pj_status_t) pjsua_parse_args(int argc, char *argv[],
- pjsua_config *cfg)
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call)
{
int c;
int option_index;
@@ -595,22 +596,29 @@ PJ_DEF(pj_status_t) pjsua_parse_args(int argc, char *argv[],
}
if (pj_optind != argc) {
+ pj_str_t uri_arg;
if (pjsua_verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
return -1;
}
- cfg->uri_to_call = pj_str(argv[pj_optind]);
+ uri_arg = pj_str(argv[pj_optind]);
+ if (uri_to_call)
+ *uri_to_call = uri_arg;
pj_optind++;
/* Add URI to call to buddy list if it's not already there */
for (i=0; i<cfg->buddy_cnt; ++i) {
- if (pj_stricmp(&cfg->buddy_uri[i], &cfg->uri_to_call)==0)
+ if (pj_stricmp(&cfg->buddy_uri[i], &uri_arg)==0)
break;
}
if (i == cfg->buddy_cnt && cfg->buddy_cnt < PJSUA_MAX_BUDDIES) {
- cfg->buddy_uri[cfg->buddy_cnt++] = cfg->uri_to_call;
+ cfg->buddy_uri[cfg->buddy_cnt++] = uri_arg;
}
+
+ } else {
+ if (uri_to_call)
+ uri_to_call->slen = 0;
}
if (pj_optind != argc) {
@@ -869,7 +877,7 @@ static void dump_media_session(const char *indent,
}
}
-PJ_DEF(void) pjsua_dump_call(int call_index, int with_media,
+PJ_DEF(void) pjsua_call_dump(int call_index, int with_media,
char *buffer, unsigned maxlen,
const char *indent)
{
@@ -975,7 +983,7 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
for (i=0; i<pjsua.config.max_calls; ++i) {
if (pjsua.calls[i].inv) {
- pjsua_dump_call(i, detail, buf, sizeof(buf), " ");
+ pjsua_call_dump(i, detail, buf, sizeof(buf), " ");
PJ_LOG(3,(THIS_FILE, "%s", buf));
}
}
@@ -993,13 +1001,14 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
* Load settings.
*/
PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
- pjsua_config *cfg)
+ pjsua_config *cfg,
+ pj_str_t *uri_to_call)
{
int argc = 3;
char *argv[4] = { "pjsua", "--config-file", NULL, NULL};
argv[2] = (char*)filename;
- return pjsua_parse_args(argc, argv, cfg);
+ return pjsua_parse_args(argc, argv, cfg, uri_to_call);
}
@@ -1297,8 +1306,130 @@ PJ_DEF(pj_status_t) pjsua_save_settings(const char *filename,
/**
* Get pjsua running config.
*/
-PJ_DEF(const pjsua_config*) pjsua_get_config(void)
+PJ_DEF(void) pjsua_get_config(pj_pool_t *pool,
+ pjsua_config *cfg)
{
- return &pjsua.config;
+ unsigned i;
+
+ pjsua_copy_config(pool, cfg, &pjsua.config);
+
+ /* Compact buddy uris. */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.buddy_uri)-1; ++i) {
+ if (pjsua.config.buddy_uri[i].slen == 0) {
+ unsigned j;
+
+ for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++j) {
+ if (pjsua.config.buddy_uri[j].slen != 0)
+ break;
+ }
+
+ if (j == PJ_ARRAY_SIZE(pjsua.config.buddy_uri))
+ break;
+ else
+ pjsua.config.buddy_uri[i] = pjsua.config.buddy_uri[j];
+ }
+ }
+
+ /* Compact accounts. */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config)-1; ++i) {
+
+ if (pjsua.acc[i].valid == PJ_FALSE || pjsua.acc[i].auto_gen) {
+ unsigned j;
+
+ for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++j) {
+ if (pjsua.acc[j].valid && !pjsua.acc[j].auto_gen)
+ break;
+ }
+
+ if (j == PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+ break;
+ } else {
+ pj_memcpy(&pjsua.config.acc_config[i] ,
+ &pjsua.config.acc_config[j],
+ sizeof(pjsua_acc_config));
+ }
+ }
+
+ }
+
+ /* Remove auto generated account from config */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++i) {
+ if (pjsua.acc[i].auto_gen)
+ --cfg->acc_cnt;
+ }
}
+
+
+/*****************************************************************************
+ * This is a very simple PJSIP module, whose sole purpose is to display
+ * incoming and outgoing messages to log. This module will have priority
+ * higher than transport layer, which means:
+ *
+ * - incoming messages will come to this module first before reaching
+ * transaction layer.
+ *
+ * - outgoing messages will come to this module last, after the message
+ * has been 'printed' to contiguous buffer by transport layer and
+ * appropriate transport instance has been decided for this message.
+ *
+ */
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+ PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
+ "%s\n"
+ "--end msg--",
+ rdata->msg_info.len,
+ pjsip_rx_data_get_info(rdata),
+ rdata->pkt_info.src_name,
+ rdata->pkt_info.src_port,
+ rdata->msg_info.msg_buf));
+
+ /* Always return false, otherwise messages will not get processed! */
+ return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+
+ /* Important note:
+ * tp_info field is only valid after outgoing messages has passed
+ * transport layer. So don't try to access tp_info when the module
+ * has lower priority than transport layer.
+ */
+
+ PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
+ "%s\n"
+ "--end msg--",
+ (tdata->buf.cur - tdata->buf.start),
+ pjsip_tx_data_get_info(tdata),
+ tdata->tp_info.dst_name,
+ tdata->tp_info.dst_port,
+ tdata->buf.start));
+
+ /* Always return success, otherwise message will not get sent! */
+ return PJ_SUCCESS;
+}
+
+/* The module instance. */
+pjsip_module pjsua_msg_logger =
+{
+ NULL, NULL, /* prev, next. */
+ { "mod-pjsua-log", 13 }, /* Name. */
+ -1, /* Id */
+ PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
+ NULL, /* load() */
+ NULL, /* start() */
+ NULL, /* stop() */
+ NULL, /* unload() */
+ &logging_on_rx_msg, /* on_rx_request() */
+ &logging_on_rx_msg, /* on_rx_response() */
+ &logging_on_tx_msg, /* on_tx_request. */
+ &logging_on_tx_msg, /* on_tx_response() */
+ NULL, /* on_tsx_state() */
+
+};
+