summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-02-09 09:30:09 +0000
committerBenny Prijono <bennylp@teluu.com>2006-02-09 09:30:09 +0000
commit8b393ca1ada4b881c95a947e65c4bc17b5a998c0 (patch)
tree43ae16b41907f1e0509aaf17082b6a9426d4fcfb
parent5a80ef93b88daf113b1bfb805041342c6be5b6ab (diff)
Setting svn:eol-style attribute
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@167 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/build/pjsua.dsp10
-rw-r--r--pjsip/include/pjsip-ua/sip_regc.h13
-rw-r--r--pjsip/src/pjsip-ua/sip_reg.c83
-rw-r--r--pjsip/src/pjsua/main.c10
-rw-r--r--pjsip/src/pjsua/misc.c485
-rw-r--r--pjsip/src/pjsua/pjsua.h36
-rw-r--r--pjsip/src/pjsua/pjsua_core.c301
-rw-r--r--pjsip/src/pjsua/pjsua_inv.c331
-rw-r--r--pjsip/src/pjsua/pjsua_reg.c14
9 files changed, 475 insertions, 808 deletions
diff --git a/pjsip/build/pjsua.dsp b/pjsip/build/pjsua.dsp
index 73e9df16..b27d2c2e 100644
--- a/pjsip/build/pjsua.dsp
+++ b/pjsip/build/pjsua.dsp
@@ -98,17 +98,11 @@ SOURCE=..\src\pjsua\main.c
# End Source File
# Begin Source File
-SOURCE=..\src\pjsua\main_old.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsua\misc.c
-# PROP Exclude_From_Build 1
+SOURCE=..\src\pjsua\pjsua_core.c
# End Source File
# Begin Source File
-SOURCE=..\src\pjsua\pjsua_core.c
+SOURCE=..\src\pjsua\pjsua_inv.c
# End Source File
# Begin Source File
diff --git a/pjsip/include/pjsip-ua/sip_regc.h b/pjsip/include/pjsip-ua/sip_regc.h
index 99a08a48..12959916 100644
--- a/pjsip/include/pjsip-ua/sip_regc.h
+++ b/pjsip/include/pjsip-ua/sip_regc.h
@@ -141,7 +141,7 @@ PJ_DECL(pj_status_t) pjsip_regc_init(pjsip_regc *regc,
/**
* Set authentication credentials to use by this registration.
*
- * @param dlg The registration structure.
+ * @param regc The registration structure.
* @param count Number of credentials in the array.
* @param cred Array of credentials.
*
@@ -152,6 +152,17 @@ PJ_DECL(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
const pjsip_cred_info cred[] );
/**
+ * Set route set to be used for outgoing requests.
+ *
+ * @param regc The client registration structure.
+ * @param route_set List containing Route headers.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_route_set(pjsip_regc *regc,
+ const pjsip_route_hdr*route_set);
+
+/**
* Create REGISTER request for the specified client registration structure.
*
* After successfull registration, application can inspect the contacts in
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index f3a03543..c94aff25 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -41,33 +41,34 @@
*/
struct pjsip_regc
{
- pj_pool_t *pool;
- pjsip_endpoint *endpt;
- pj_bool_t _delete_flag;
- int pending_tsx;
-
- void *token;
- pjsip_regc_cb *cb;
-
- pj_str_t str_srv_url;
- pjsip_uri *srv_url;
- pjsip_cid_hdr *cid_hdr;
- pjsip_cseq_hdr *cseq_hdr;
- pjsip_from_hdr *from_hdr;
- pjsip_to_hdr *to_hdr;
- char *contact_buf;
+ pj_pool_t *pool;
+ pjsip_endpoint *endpt;
+ pj_bool_t _delete_flag;
+ int pending_tsx;
+
+ void *token;
+ pjsip_regc_cb *cb;
+
+ pj_str_t str_srv_url;
+ pjsip_uri *srv_url;
+ pjsip_cid_hdr *cid_hdr;
+ pjsip_cseq_hdr *cseq_hdr;
+ pjsip_from_hdr *from_hdr;
+ pjsip_to_hdr *to_hdr;
+ char *contact_buf;
pjsip_generic_string_hdr *contact_hdr;
- pjsip_expires_hdr *expires_hdr;
- pjsip_contact_hdr *unreg_contact_hdr;
- pjsip_expires_hdr *unreg_expires_hdr;
- pj_uint32_t expires;
+ pjsip_expires_hdr *expires_hdr;
+ pjsip_contact_hdr *unreg_contact_hdr;
+ pjsip_expires_hdr *unreg_expires_hdr;
+ pj_uint32_t expires;
+ pjsip_route_hdr route_set;
/* Authorization sessions. */
- pjsip_auth_clt_sess auth_sess;
+ pjsip_auth_clt_sess auth_sess;
/* Auto refresh registration. */
- pj_bool_t auto_reg;
- pj_timer_entry timer;
+ pj_bool_t auto_reg;
+ pj_timer_entry timer;
};
@@ -99,6 +100,8 @@ PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token,
if (status != PJ_SUCCESS)
return status;
+ pj_list_init(&regc->route_set);
+
/* Done */
*p_regc = regc;
return PJ_SUCCESS;
@@ -248,6 +251,24 @@ PJ_DEF(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
return pjsip_auth_clt_set_credentials(&regc->auth_sess, count, cred);
}
+PJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc,
+ const pjsip_route_hdr *route_set)
+{
+ const pjsip_route_hdr *chdr;
+
+ PJ_ASSERT_RETURN(regc && route_set, PJ_EINVAL);
+
+ pj_list_init(&regc->route_set);
+
+ chdr = route_set->next;
+ while (chdr != route_set) {
+ pj_list_push_back(&regc->route_set, pjsip_hdr_clone(regc->pool, chdr));
+ chdr = chdr->next;
+ }
+
+ return PJ_SUCCESS;
+}
+
static pj_status_t create_request(pjsip_regc *regc,
pjsip_tx_data **p_tdata)
{
@@ -273,6 +294,24 @@ static pj_status_t create_request(pjsip_regc *regc,
/* Add cached authorization headers. */
pjsip_auth_clt_init_req( &regc->auth_sess, tdata );
+ /* Add Route headers from route set, ideally after Via header */
+ if (!pj_list_empty(&regc->route_set)) {
+ pjsip_hdr *route_pos;
+ const pjsip_route_hdr *route;
+
+ route_pos = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
+ if (!route_pos)
+ route_pos = &tdata->msg->hdr;
+
+ route = regc->route_set.next;
+ while (route != &regc->route_set) {
+ pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, route);
+ pj_list_insert_after(route_pos, new_hdr);
+ route_pos = new_hdr;
+ route = route->next;
+ }
+ }
+
/* Done. */
*p_tdata = tdata;
return PJ_SUCCESS;
diff --git a/pjsip/src/pjsua/main.c b/pjsip/src/pjsua/main.c
index f802799f..287f5624 100644
--- a/pjsip/src/pjsua/main.c
+++ b/pjsip/src/pjsua/main.c
@@ -61,7 +61,7 @@ static void ui_help(void)
{
puts("");
puts("Console keys:");
- puts(" m Make a call");
+ puts(" m Make a call/another call");
puts(" a Answer incoming call");
puts(" h Hangup current call");
puts(" q Quit");
@@ -352,10 +352,10 @@ static void usage(void)
puts(" --use-stun1=host[:port]");
puts(" --use-stun2=host[:port] Use STUN and set host name and port of STUN servers");
puts("");
- puts("SIMPLE options (may be specified more than once):");
- puts(" --add-buddy url Add the specified URL to the buddy list.");
- puts(" --offer-x-ms-msg Offer \"x-ms-message\" in outgoing INVITE");
- puts(" --no-presence Do not subscribe presence of buddies");
+ //puts("SIMPLE options (may be specified more than once):");
+ //puts(" --add-buddy url Add the specified URL to the buddy list.");
+ //puts(" --offer-x-ms-msg Offer \"x-ms-message\" in outgoing INVITE");
+ //puts(" --no-presence Do not subscribe presence of buddies");
puts("");
fflush(stdout);
}
diff --git a/pjsip/src/pjsua/misc.c b/pjsip/src/pjsua/misc.c
deleted file mode 100644
index 5c063fc7..00000000
--- a/pjsip/src/pjsua/misc.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * THIS FILE IS INCLUDED BY main.c.
- * IT WON'T COMPILE BY ITSELF.
- */
-
-#include "getopt.h"
-#include <stdio.h>
-
-
-/*
- * Display program usage
- */
-static void usage()
-{
- puts("Usage:");
- puts(" pjsua [options] [sip-url]");
- puts("");
- puts(" [sip-url] Default URL to invite.");
- puts("");
- puts("General options:");
- puts(" --config-file=file Read the config/arguments from file.");
- puts(" --log-file=fname Log to filename (default stderr)");
- puts(" --log-level=N Set log max level to N (0(none) to 6(trace))");
- puts(" --app-log-level=N Set log max level for stdout display to N");
- puts(" --help Display this help screen");
- puts(" --version Display version info");
- puts("");
- puts("Media options:");
- puts(" --null-audio Use NULL audio device");
- puts("");
- puts("User Agent options:");
- puts(" --auto-answer=sec Auto-answer all incoming calls after sec seconds.");
- puts(" --auto-hangup=sec Auto-hangup all calls after sec seconds.");
- puts("");
- puts("SIP options:");
- puts(" --local-port=port Set TCP/UDP port");
- puts(" --id=url Set the URL of local ID (used in From header)");
- puts(" --contact=url Override the Contact information");
- puts(" --proxy=url Set the URL of proxy server");
- puts(" --outbound=url Set the URL of outbound proxy server");
- puts(" --registrar=url Set the URL of registrar server");
- puts(" --reg-timeout=secs Set registration interval to secs (default 3600)");
- puts("");
- puts("Authentication options:");
- puts(" --realm=string Set realm");
- puts(" --username=string Set authentication username");
- puts(" --password=string Set authentication password");
- puts("");
- puts("STUN options (all must be specified):");
- puts(" --use-stun1=host[:port]");
- puts(" --use-stun2=host[:port] Use STUN and set host name and port of STUN servers");
- puts("");
- puts("SIMPLE options (may be specified more than once):");
- puts(" --add-buddy url Add the specified URL to the buddy list.");
- puts(" --offer-x-ms-msg Offer \"x-ms-message\" in outgoing INVITE");
- puts(" --no-presence Do not subscribe presence of buddies");
- puts("");
- fflush(stdout);
-}
-
-/* Display keystroke help. */
-static void keystroke_help()
-{
- int i;
-
- printf("Advertise status as: %s\n", (global.hide_status ? "Offline" : "Online"));
- puts("");
- puts("Buddy list:");
- puts("-------------------------------------------------------------------------------");
- for (i=0; i<global.buddy_cnt; ++i) {
- printf(" %d\t%s <%s>\n", i+1, global.buddy[i].ptr,
- (global.buddy_status[i]?"Online":"Offline"));
- }
- //printf("-------------------------------------\n");
- puts("");
- //puts("Commands:");
- puts("+=============================================================================+");
- puts("| Call Commands: | IM & Presence: | Misc: |");
- puts("| | | |");
- puts("| m Make new call | i Send IM | o Send OPTIONS |");
- puts("| a Answer call | su Subscribe presence | d Dump status |");
- puts("| h Hangup call | us Unsubscribe presence | d1 Dump detailed |");
- puts("| ] Select next dialog | t Toggle Online status | |");
- puts("| [ Select previous dialog | | |");
- puts("+-----------------------------------------------------------------------------+");
- puts("| q QUIT |");
- puts("+=============================================================================+");
- puts("");
-
-
- fflush(stdout);
-}
-
-/*
- * Verify that valid SIP url is given.
- */
-static pj_status_t verify_sip_url(char *url)
-{
- pjsip_uri *p;
- pj_pool_t *pool;
- int len = (url ? strlen(url) : 0);
-
- if (!len) return -1;
-
- pool = pj_pool_create(global.pf, "check%p", 1024, 0, NULL);
- if (!pool) return -1;
-
- p = pjsip_parse_uri(pool, url, len, 0);
- if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)
- p = NULL;
-
- pj_pool_release(pool);
- return p ? 0 : -1;
-}
-
-/*
- * Read command arguments from config file.
- */
-static int read_config_file(pj_pool_t *pool, const char *filename,
- int *app_argc, char ***app_argv)
-{
- int i;
- FILE *fhnd;
- char line[200];
- int argc = 0;
- char **argv;
- enum { MAX_ARGS = 64 };
-
- /* Allocate MAX_ARGS+1 (argv needs to be terminated with NULL argument) */
- argv = pj_pool_calloc(pool, MAX_ARGS+1, sizeof(char*));
- argv[argc++] = *app_argv[0];
-
- /* Open config file. */
- fhnd = fopen(filename, "rt");
- if (!fhnd) {
- printf("Unable to open config file %s\n", filename);
- return -1;
- }
-
- /* Scan tokens in the file. */
- while (argc < MAX_ARGS && !feof(fhnd)) {
- char *token, *p = line;
-
- if (fgets(line, sizeof(line), fhnd) == NULL) break;
-
- for (token = strtok(p, " \t\r\n"); argc < MAX_ARGS;
- token = strtok(NULL, " \t\r\n"))
- {
- int token_len;
-
- if (!token) break;
- if (*token == '#') break;
-
- token_len = strlen(token);
- if (!token_len)
- continue;
- argv[argc] = pj_pool_alloc(pool, token_len+1);
- pj_memcpy(argv[argc], token, token_len+1);
- ++argc;
- }
- }
-
- /* Copy arguments from command line */
- for (i=1; i<*app_argc && argc < MAX_ARGS; ++i)
- argv[argc++] = (*app_argv)[i];
-
- if (argc == MAX_ARGS && (i!=*app_argc || !feof(fhnd))) {
- printf("Too many arguments specified in cmd line/config file\n");
- fclose(fhnd);
- return -1;
- }
-
- fclose(fhnd);
-
- /* Assign the new command line back to the original command line. */
- *app_argc = argc;
- *app_argv = argv;
- return 0;
-
-}
-
-/*
- * Parse program arguments
- */
-static int parse_args(pj_pool_t *pool, int argc, char *argv[])
-{
- int c;
- int option_index;
- enum { OPT_CONFIG_FILE, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL,
- OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO,
- OPT_LOCAL_PORT, OPT_PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR,
- OPT_REG_TIMEOUT, OPT_ID, OPT_CONTACT,
- OPT_REALM, OPT_USERNAME, OPT_PASSWORD,
- OPT_USE_STUN1, OPT_USE_STUN2,
- OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
- OPT_AUTO_ANSWER, OPT_AUTO_HANGUP};
- struct option long_options[] = {
- { "config-file",1, 0, OPT_CONFIG_FILE},
- { "log-file", 1, 0, OPT_LOG_FILE},
- { "log-level", 1, 0, OPT_LOG_LEVEL},
- { "app-log-level",1,0,OPT_APP_LOG_LEVEL},
- { "help", 0, 0, OPT_HELP},
- { "version", 0, 0, OPT_VERSION},
- { "null-audio", 0, 0, OPT_NULL_AUDIO},
- { "local-port", 1, 0, OPT_LOCAL_PORT},
- { "proxy", 1, 0, OPT_PROXY},
- { "outbound", 1, 0, OPT_OUTBOUND_PROXY},
- { "registrar", 1, 0, OPT_REGISTRAR},
- { "reg-timeout",1, 0, OPT_REG_TIMEOUT},
- { "id", 1, 0, OPT_ID},
- { "contact", 1, 0, OPT_CONTACT},
- { "realm", 1, 0, OPT_REALM},
- { "username", 1, 0, OPT_USERNAME},
- { "password", 1, 0, OPT_PASSWORD},
- { "use-stun1", 1, 0, OPT_USE_STUN1},
- { "use-stun2", 1, 0, OPT_USE_STUN2},
- { "add-buddy", 1, 0, OPT_ADD_BUDDY},
- { "offer-x-ms-msg",0,0,OPT_OFFER_X_MS_MSG},
- { "no-presence", 0, 0, OPT_NO_PRESENCE},
- { "auto-answer",1, 0, OPT_AUTO_ANSWER},
- { "auto-hangup",1, 0, OPT_AUTO_HANGUP},
- { NULL, 0, 0, 0}
- };
- char *config_file = NULL;
-
- /* Run getopt once to see if user specifies config file to read. */
- while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
- switch (c) {
- case 0:
- config_file = optarg;
- break;
- }
- if (config_file)
- break;
- }
-
- if (config_file) {
- if (read_config_file(pool, config_file, &argc, &argv) != 0)
- return -1;
- }
-
- /* Reinitialize and re-run getopt again, possibly with new arguments
- * read from config file.
- */
- optind = 0;
- while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
- char *err, *p;
-
- switch (c) {
- case OPT_LOG_FILE:
- global.log_filename = optarg;
- break;
- case OPT_LOG_LEVEL:
- c = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value 0-6 for --log-level\n");
- return -1;
- }
- pj_log_set_level( c );
- break;
- case OPT_APP_LOG_LEVEL:
- global.app_log_level = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value 0-6 for --app-log-level\n");
- return -1;
- }
- break;
- case OPT_HELP:
- usage();
- return -1;
- case OPT_VERSION: /* version */
- pj_dump_config();
- return -1;
- case OPT_NULL_AUDIO:
- global.null_audio = 1;
- break;
- case OPT_LOCAL_PORT: /* local-port */
- global.sip_port = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value for --local-port\n");
- return -1;
- }
- break;
- case OPT_PROXY: /* proxy */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid SIP URL '%s' in proxy argument\n", optarg);
- return -1;
- }
- global.proxy = pj_str(optarg);
- break;
- case OPT_OUTBOUND_PROXY: /* outbound proxy */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid SIP URL '%s' in outbound proxy argument\n", optarg);
- return -1;
- }
- global.outbound_proxy = pj_str(optarg);
- break;
- case OPT_REGISTRAR: /* registrar */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid SIP URL '%s' in registrar argument\n", optarg);
- return -1;
- }
- global.registrar_uri = pj_str(optarg);
- break;
- case OPT_REG_TIMEOUT: /* reg-timeout */
- global.reg_timeout = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value for --reg-timeout\n");
- return -1;
- }
- break;
- case OPT_ID: /* id */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid SIP URL '%s' in local id argument\n", optarg);
- return -1;
- }
- global.local_uri = pj_str(optarg);
- break;
- case OPT_CONTACT: /* contact */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid SIP URL '%s' in contact argument\n", optarg);
- return -1;
- }
- global.contact = pj_str(optarg);
- break;
- case OPT_USERNAME: /* Default authentication user */
- if (!global.cred_count) global.cred_count = 1;
- global.cred_info[0].username = pj_str(optarg);
- break;
- case OPT_REALM: /* Default authentication realm. */
- if (!global.cred_count) global.cred_count = 1;
- global.cred_info[0].realm = pj_str(optarg);
- break;
- case OPT_PASSWORD: /* authentication password */
- if (!global.cred_count) global.cred_count = 1;
- global.cred_info[0].data_type = 0;
- global.cred_info[0].data = pj_str(optarg);
- break;
- case OPT_USE_STUN1: /* STUN server 1 */
- p = pj_native_strchr(optarg, ':');
- if (p) {
- *p = '\0';
- global.stun_srv1 = pj_str(optarg);
- global.stun_port1 = strtoul(p+1, &err, 10);
- if (*err || global.stun_port1==0) {
- printf("Error: expecting port number with option --use-stun1\n");
- return -1;
- }
- } else {
- global.stun_port1 = 3478;
- global.stun_srv1 = pj_str(optarg);
- }
- break;
- case OPT_USE_STUN2: /* STUN server 2 */
- p = pj_native_strchr(optarg, ':');
- if (p) {
- *p = '\0';
- global.stun_srv2 = pj_str(optarg);
- global.stun_port2 = strtoul(p+1, &err, 10);
- if (*err || global.stun_port2==0) {
- printf("Error: expecting port number with option --use-stun2\n");
- return -1;
- }
- } else {
- global.stun_port2 = 3478;
- global.stun_srv2 = pj_str(optarg);
- }
- break;
- case OPT_ADD_BUDDY: /* Add to buddy list. */
- if (verify_sip_url(optarg) != 0) {
- printf("Error: invalid URL '%s' in --add-buddy option\n", optarg);
- return -1;
- }
- if (global.buddy_cnt == MAX_BUDDIES) {
- printf("Error: too many buddies in buddy list.\n");
- return -1;
- }
- global.buddy[global.buddy_cnt++] = pj_str(optarg);
- break;
- case OPT_OFFER_X_MS_MSG:
- global.offer_x_ms_msg = 1;
- break;
- case OPT_NO_PRESENCE:
- global.no_presence = 1;
- break;
- case OPT_AUTO_ANSWER:
- global.auto_answer = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value for --auto-answer option\n");
- return -1;
- }
- break;
- case OPT_AUTO_HANGUP:
- global.auto_hangup = strtoul(optarg, &err, 10);
- if (*err) {
- printf("Error: expecting integer value for --auto-hangup option\n");
- return -1;
- }
- break;
- }
- }
-
- if (optind != argc) {
- printf("Error: unknown options %s\n", argv[optind]);
- return -1;
- }
-
- if (global.reg_timeout == 0)
- global.reg_timeout = 3600;
-
- return 0;
-}
-
-/* Print dialog. */
-static void print_dialog(pjsip_dlg *dlg)
-{
- if (!dlg) {
- puts("none");
- return;
- }
-
- printf("%s: call-id=%.*s", dlg->obj_name,
- (int)dlg->call_id->id.slen,
- dlg->call_id->id.ptr);
-
- printf(" (%s, %s)\n", pjsip_role_name(dlg->role),
- pjsip_dlg_state_str(dlg->state));
-}
-
-/* Dump media statistic */
-void dump_media_statistic(pjsip_dlg *dlg)
-{
- struct dialog_data *dlg_data = dlg->user_data;
- pj_media_stream_stat stat[2];
- const char *statname[2] = { "TX", "RX" };
- int i;
-
- pj_media_session_get_stat (dlg_data->msession, 0, &stat[0], &stat[1]);
-
- printf("Media statistic:\n");
- for (i=0; i<2; ++i) {
- printf(" %s statistics:\n", statname[i]);
- printf(" Pkt TX=%d RX=%d\n", stat[i].pkt_tx, stat[i].pkt_rx);
- printf(" Octets TX=%d RX=%d\n", stat[i].oct_tx, stat[i].oct_rx);
- printf(" Jitter %d ms\n", stat[i].jitter);
- printf(" Pkt lost %d\n", stat[i].pkt_lost);
- }
- printf("\n");
-}
-
-/* Print all dialogs. */
-static void print_all_dialogs()
-{
- pjsip_dlg *dlg = (pjsip_dlg *)global.user_agent->dlg_list.next;
-
- puts("List all dialogs:");
-
- while (dlg != (pjsip_dlg *) &global.user_agent->dlg_list) {
- printf("%c", (dlg==global.cur_dlg ? '*' : ' '));
- print_dialog(dlg);
- dlg = dlg->next;
- }
-
- puts("");
-}
-
diff --git a/pjsip/src/pjsua/pjsua.h b/pjsip/src/pjsua/pjsua.h
index 37740c3a..810c57b5 100644
--- a/pjsip/src/pjsua/pjsua.h
+++ b/pjsip/src/pjsua/pjsua.h
@@ -128,7 +128,7 @@ struct pjsua_inv_data
/*****************************************************************************
- * PJSUA API.
+ * PJSUA API (defined in pjsua_core.c).
*/
/**
@@ -171,6 +171,10 @@ pj_status_t pjsua_start(void);
pj_status_t pjsua_destroy(void);
+/*****************************************************************************
+ * PJSUA Invite session API (defined in pjsua_inv.c).
+ */
+
/**
* Make outgoing call.
*/
@@ -178,8 +182,35 @@ pj_status_t pjsua_invite(const char *cstr_dest_uri,
pjsip_inv_session **p_inv);
+/**
+ * Handle incoming invite request.
+ */
+pj_bool_t pjsua_inv_on_incoming(pjsip_rx_data *rdata);
+
+
+/**
+ * Callback to be called by session when invite session's state has changed.
+ */
+void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e);
+
+
+/**
+ * Callback to be called by session when outgoing dialog has forked.
+ * This function will create a forked dialog.
+ */
+void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e);
+
+
+/**
+ * Callback to be called when SDP offer/answer negotiation has just completed
+ * in the session. This function will start/update media if negotiation
+ * has succeeded.
+ */
+void pjsua_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status);
+
+
/*****************************************************************************
- * PJSUA Client Registration API.
+ * PJSUA Client Registration API (defined in pjsua_reg.c).
*/
/**
@@ -198,6 +229,7 @@ void pjsua_regc_update(pj_bool_t renew);
/*****************************************************************************
* User Interface API.
+ *
* The UI API specifies functions that will be called by pjsua upon
* occurence of various events.
*/
diff --git a/pjsip/src/pjsua/pjsua_core.c b/pjsip/src/pjsua/pjsua_core.c
index f6de89f5..cc9ae86f 100644
--- a/pjsip/src/pjsua/pjsua_core.c
+++ b/pjsip/src/pjsua/pjsua_core.c
@@ -18,13 +18,23 @@
*/
#include "pjsua.h"
+/*
+ * pjsua_core.c
+ *
+ * Core application functionalities.
+ */
-#define THIS_FILE "pjsua.c"
+#define THIS_FILE "pjsua_core.c"
+
+/*
+ * Global variable.
+ */
struct pjsua pjsua;
+
/*
- * Default local URI, if not specified in cmd-line
+ * Default local URI, if none is specified in cmd-line
*/
#define PJSUA_LOCAL_URI "<sip:user@127.0.0.1>"
@@ -92,106 +102,13 @@ void pjsua_perror(const char *title, pj_status_t status)
*/
static pj_bool_t mod_pjsua_on_rx_request(pjsip_rx_data *rdata)
{
- pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
- pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
- pjsip_msg *msg = rdata->msg_info.msg;
-
- /*
- * Handle incoming INVITE outside dialog.
- */
- if (dlg == NULL && tsx == NULL &&
- msg->line.req.method.id == PJSIP_INVITE_METHOD)
- {
- pj_status_t status;
- pjsip_tx_data *response = NULL;
- unsigned options = 0;
-
- /* Verify that we can handle the request. */
- status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
- pjsua.endpt, &response);
- if (status != PJ_SUCCESS) {
-
- /*
- * No we can't handle the incoming INVITE request.
- */
-
- if (response) {
- pjsip_response_addr res_addr;
-
- pjsip_get_response_addr(response->pool, rdata, &res_addr);
- pjsip_endpt_send_response(pjsua.endpt, &res_addr, response,
- NULL, NULL);
-
- } else {
-
- /* Respond with 500 (Internal Server Error) */
- pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL,
- NULL, NULL);
- }
-
- } else {
- /*
- * Yes we can handle the incoming INVITE request.
- */
- pjsip_inv_session *inv;
- struct pjsua_inv_data *inv_data;
- pjmedia_sdp_session *answer;
-
-
- /* Get media capability from media endpoint: */
-
- status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool,
- 1, &pjsua.med_skinfo, &answer );
- if (status != PJ_SUCCESS) {
-
- pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL,
- NULL, NULL);
- return PJ_TRUE;
- }
-
- /* Create dialog: */
-
- status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
- &pjsua.contact_uri, &dlg);
- if (status != PJ_SUCCESS)
- return PJ_TRUE;
-
-
- /* Create invite session: */
-
- status = pjsip_inv_create_uas( dlg, rdata, answer, 0, &inv);
- if (status != PJ_SUCCESS) {
-
- status = pjsip_dlg_create_response( dlg, rdata, 500, NULL,
- &response);
- if (status == PJ_SUCCESS)
- status = pjsip_dlg_send_response(dlg,
- pjsip_rdata_get_tsx(rdata),
- response);
- return PJ_TRUE;
-
- }
-
-
- /* Create and attach pjsua data to the dialog: */
- inv_data = pj_pool_zalloc(dlg->pool, sizeof(struct pjsua_inv_data));
- dlg->mod_data[pjsua.mod.id] = inv_data;
+ if (rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD) {
+ return pjsua_inv_on_incoming(rdata);
- /* Answer with 100 (using the dialog, not invite): */
-
- status = pjsip_dlg_create_response(dlg, rdata, 100, NULL, &response);
- if (status == PJ_SUCCESS)
- status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), response);
- }
-
- /* This INVITE request has been handled. */
- return PJ_TRUE;
}
-
-
return PJ_FALSE;
}
@@ -214,98 +131,6 @@ static pj_bool_t mod_pjsua_on_rx_response(pjsip_rx_data *rdata)
}
-/*
- * This callback receives notification from invite session when the
- * session state has changed.
- */
-static void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
-{
-
- /* Destroy media session when invite session is disconnected. */
- if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
- struct pjsua_inv_data *inv_data;
-
- inv_data = inv->dlg->mod_data[pjsua.mod.id];
- if (inv_data && inv_data->session) {
- pjmedia_session_destroy(inv_data->session);
- inv_data->session = NULL;
-
- PJ_LOG(3,(THIS_FILE,"Media session is destroyed"));
- }
-
- }
-
- pjsua_ui_inv_on_state_changed(inv, e);
-}
-
-
-/*
- * This callback is called by invite session framework when UAC session
- * has forked.
- */
-static void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
-{
- PJ_UNUSED_ARG(inv);
- PJ_UNUSED_ARG(e);
-
- PJ_TODO(HANDLE_FORKED_DIALOG);
-}
-
-/*
- *
- */
-static void pjsua_inv_on_media_update(pjsip_inv_session *inv,
- pj_status_t status)
-{
- struct pjsua_inv_data *inv_data;
- const pjmedia_sdp_session *local_sdp;
- const pjmedia_sdp_session *remote_sdp;
-
- if (status != PJ_SUCCESS) {
-
- pjsua_perror("SDP negotiation has failed", status);
- return;
-
- }
-
- /* Destroy existing media session, if any. */
-
- inv_data = inv->dlg->mod_data[pjsua.mod.id];
- if (inv_data && inv_data->session) {
- pjmedia_session_destroy(inv_data->session);
- inv_data->session = NULL;
- }
-
- /* Get local and remote SDP */
-
- status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Unable to retrieve currently active local SDP", status);
- return;
- }
-
-
- status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Unable to retrieve currently active remote SDP", status);
- return;
- }
-
-
- /* Create new media session.
- * The media session is active immediately.
- */
-
- status = pjmedia_session_create( pjsua.med_endpt, 1, &pjsua.med_skinfo,
- local_sdp, remote_sdp, &inv_data->session );
- if (status != PJ_SUCCESS) {
- pjsua_perror("Unable to create media session", status);
- return;
- }
-
- PJ_LOG(3,(THIS_FILE,"Media has been started successfully"));
-}
-
/*
* Initialize sockets and optionally get the public address via STUN.
*/
@@ -845,111 +670,17 @@ pj_status_t pjsua_destroy(void)
}
/* Destroy endpoint. */
+
pjsip_endpt_destroy(pjsua.endpt);
pjsua.endpt = NULL;
/* Destroy caching pool. */
- pj_caching_pool_destroy(&pjsua.cp);
-
-
- /* Done. */
-
- return PJ_SUCCESS;
-}
-
-
-/**
- * Make outgoing call.
- */
-pj_status_t pjsua_invite(const char *cstr_dest_uri,
- pjsip_inv_session **p_inv)
-{
- pj_str_t dest_uri;
- pjsip_dialog *dlg;
- pjmedia_sdp_session *offer;
- pjsip_inv_session *inv;
- struct pjsua_inv_data *inv_data;
- pjsip_tx_data *tdata;
- pj_status_t status;
-
- /* Convert cstr_dest_uri to dest_uri */
-
- dest_uri = pj_str((char*)cstr_dest_uri);
-
- /* Create outgoing dialog: */
-
- status = pjsip_dlg_create_uac( pjsip_ua_instance(), &pjsua.local_uri,
- &pjsua.contact_uri, &dest_uri, &dest_uri,
- &dlg);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Dialog creation failed", status);
- return status;
- }
-
- /* Get media capability from media endpoint: */
- status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool,
- 1, &pjsua.med_skinfo, &offer);
- if (status != PJ_SUCCESS) {
- pjsua_perror("pjmedia unable to create SDP", status);
- goto on_error;
- }
-
- /* Create the INVITE session: */
-
- status = pjsip_inv_create_uac( dlg, offer, 0, &inv);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Invite session creation failed", status);
- goto on_error;
- }
-
-
- /* Create and associate our data in the session. */
-
- inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data));
- dlg->mod_data[pjsua.mod.id] = inv_data;
-
-
- /* Set dialog Route-Set: */
-
- if (!pj_list_empty(&pjsua.route_set))
- pjsip_dlg_set_route_set(dlg, &pjsua.route_set);
-
-
- /* Set credentials: */
-
- pjsip_auth_clt_set_credentials( &dlg->auth_sess, pjsua.cred_count,
- pjsua.cred_info);
-
-
- /* Create initial INVITE: */
-
- status = pjsip_inv_invite(inv, &tdata);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Unable to create initial INVITE request", status);
- goto on_error;
- }
-
-
- /* Send initial INVITE: */
-
- status = pjsip_inv_send_msg(inv, tdata, NULL);
- if (status != PJ_SUCCESS) {
- pjsua_perror("Unable to send initial INVITE request", status);
- goto on_error;
- }
+ pj_caching_pool_destroy(&pjsua.cp);
/* Done. */
- *p_inv = inv;
-
return PJ_SUCCESS;
-
-
-on_error:
-
- PJ_TODO(DESTROY_DIALOG_ON_FAIL);
- return status;
}
diff --git a/pjsip/src/pjsua/pjsua_inv.c b/pjsip/src/pjsua/pjsua_inv.c
new file mode 100644
index 00000000..72272c32
--- /dev/null
+++ b/pjsip/src/pjsua/pjsua_inv.c
@@ -0,0 +1,331 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "pjsua.h"
+#include <pj/log.h>
+
+
+/*
+ * pjsua_inv.c
+ *
+ * Invite session specific functionalities.
+ */
+
+#define THIS_FILE "pjsua_inv.c"
+
+
+/**
+ * Make outgoing call.
+ */
+pj_status_t pjsua_invite(const char *cstr_dest_uri,
+ pjsip_inv_session **p_inv)
+{
+ pj_str_t dest_uri;
+ pjsip_dialog *dlg;
+ pjmedia_sdp_session *offer;
+ pjsip_inv_session *inv;
+ struct pjsua_inv_data *inv_data;
+ pjsip_tx_data *tdata;
+ pj_status_t status;
+
+ /* Convert cstr_dest_uri to dest_uri */
+
+ dest_uri = pj_str((char*)cstr_dest_uri);
+
+ /* Create outgoing dialog: */
+
+ status = pjsip_dlg_create_uac( pjsip_ua_instance(), &pjsua.local_uri,
+ &pjsua.contact_uri, &dest_uri, &dest_uri,
+ &dlg);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Dialog creation failed", status);
+ return status;
+ }
+
+ /* Get media capability from media endpoint: */
+
+ status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool,
+ 1, &pjsua.med_skinfo, &offer);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("pjmedia unable to create SDP", status);
+ goto on_error;
+ }
+
+ /* Create the INVITE session: */
+
+ status = pjsip_inv_create_uac( dlg, offer, 0, &inv);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Invite session creation failed", status);
+ goto on_error;
+ }
+
+
+ /* Create and associate our data in the session. */
+
+ inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data));
+ dlg->mod_data[pjsua.mod.id] = inv_data;
+
+
+ /* Set dialog Route-Set: */
+
+ if (!pj_list_empty(&pjsua.route_set))
+ pjsip_dlg_set_route_set(dlg, &pjsua.route_set);
+
+
+ /* Set credentials: */
+
+ pjsip_auth_clt_set_credentials( &dlg->auth_sess, pjsua.cred_count,
+ pjsua.cred_info);
+
+
+ /* Create initial INVITE: */
+
+ status = pjsip_inv_invite(inv, &tdata);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Unable to create initial INVITE request", status);
+ goto on_error;
+ }
+
+
+ /* Send initial INVITE: */
+
+ status = pjsip_inv_send_msg(inv, tdata, NULL);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Unable to send initial INVITE request", status);
+ goto on_error;
+ }
+
+
+ /* Done. */
+
+ *p_inv = inv;
+
+ return PJ_SUCCESS;
+
+
+on_error:
+
+ PJ_TODO(DESTROY_DIALOG_ON_FAIL);
+ return status;
+}
+
+
+/**
+ * Handle incoming INVITE request.
+ */
+pj_bool_t pjsua_inv_on_incoming(pjsip_rx_data *rdata)
+{
+ pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
+ pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+ pjsip_msg *msg = rdata->msg_info.msg;
+
+ /*
+ * Handle incoming INVITE outside dialog.
+ */
+ if (dlg == NULL && tsx == NULL &&
+ msg->line.req.method.id == PJSIP_INVITE_METHOD)
+ {
+ pj_status_t status;
+ pjsip_tx_data *response = NULL;
+ unsigned options = 0;
+
+ /* Verify that we can handle the request. */
+ status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
+ pjsua.endpt, &response);
+ if (status != PJ_SUCCESS) {
+
+ /*
+ * No we can't handle the incoming INVITE request.
+ */
+
+ if (response) {
+ pjsip_response_addr res_addr;
+
+ pjsip_get_response_addr(response->pool, rdata, &res_addr);
+ pjsip_endpt_send_response(pjsua.endpt, &res_addr, response,
+ NULL, NULL);
+
+ } else {
+
+ /* Respond with 500 (Internal Server Error) */
+ pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL,
+ NULL, NULL);
+ }
+
+ } else {
+ /*
+ * Yes we can handle the incoming INVITE request.
+ */
+ pjsip_inv_session *inv;
+ struct pjsua_inv_data *inv_data;
+ pjmedia_sdp_session *answer;
+
+
+ /* Get media capability from media endpoint: */
+
+ status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool,
+ 1, &pjsua.med_skinfo, &answer );
+ if (status != PJ_SUCCESS) {
+
+ pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL,
+ NULL, NULL);
+ return PJ_TRUE;
+ }
+
+ /* Create dialog: */
+
+ status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
+ &pjsua.contact_uri, &dlg);
+ if (status != PJ_SUCCESS)
+ return PJ_TRUE;
+
+
+ /* Create invite session: */
+
+ status = pjsip_inv_create_uas( dlg, rdata, answer, 0, &inv);
+ if (status != PJ_SUCCESS) {
+
+ status = pjsip_dlg_create_response( dlg, rdata, 500, NULL,
+ &response);
+ if (status == PJ_SUCCESS)
+ status = pjsip_dlg_send_response(dlg,
+ pjsip_rdata_get_tsx(rdata),
+ response);
+ return PJ_TRUE;
+
+ }
+
+
+ /* Create and attach pjsua data to the dialog: */
+
+ inv_data = pj_pool_zalloc(dlg->pool, sizeof(struct pjsua_inv_data));
+ dlg->mod_data[pjsua.mod.id] = inv_data;
+
+
+ /* Answer with 100 (using the dialog, not invite): */
+
+ status = pjsip_dlg_create_response(dlg, rdata, 100, NULL, &response);
+ if (status == PJ_SUCCESS)
+ status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), response);
+ }
+
+ /* This INVITE request has been handled. */
+ return PJ_TRUE;
+ }
+
+ return PJ_FALSE;
+}
+
+
+/*
+ * This callback receives notification from invite session when the
+ * session state has changed.
+ */
+void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
+{
+
+ /* Destroy media session when invite session is disconnected. */
+ if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+ struct pjsua_inv_data *inv_data;
+
+ inv_data = inv->dlg->mod_data[pjsua.mod.id];
+ if (inv_data && inv_data->session) {
+ pjmedia_session_destroy(inv_data->session);
+ inv_data->session = NULL;
+
+ PJ_LOG(3,(THIS_FILE,"Media session is destroyed"));
+ }
+
+ }
+
+ pjsua_ui_inv_on_state_changed(inv, e);
+}
+
+
+/*
+ * This callback is called by invite session framework when UAC session
+ * has forked.
+ */
+void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
+{
+ PJ_UNUSED_ARG(inv);
+ PJ_UNUSED_ARG(e);
+
+ PJ_TODO(HANDLE_FORKED_DIALOG);
+}
+
+
+/*
+ * Callback to be called when SDP offer/answer negotiation has just completed
+ * in the session. This function will start/update media if negotiation
+ * has succeeded.
+ */
+void pjsua_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status)
+{
+ struct pjsua_inv_data *inv_data;
+ const pjmedia_sdp_session *local_sdp;
+ const pjmedia_sdp_session *remote_sdp;
+
+ if (status != PJ_SUCCESS) {
+
+ pjsua_perror("SDP negotiation has failed", status);
+ return;
+
+ }
+
+ /* Destroy existing media session, if any. */
+
+ inv_data = inv->dlg->mod_data[pjsua.mod.id];
+ if (inv_data && inv_data->session) {
+ pjmedia_session_destroy(inv_data->session);
+ inv_data->session = NULL;
+ }
+
+ /* Get local and remote SDP */
+
+ status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Unable to retrieve currently active local SDP", status);
+ return;
+ }
+
+
+ status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Unable to retrieve currently active remote SDP", status);
+ return;
+ }
+
+
+ /* Create new media session.
+ * The media session is active immediately.
+ */
+
+ if (!pjsua.null_audio) {
+
+ status = pjmedia_session_create( pjsua.med_endpt, 1, &pjsua.med_skinfo,
+ local_sdp, remote_sdp,
+ &inv_data->session );
+ if (status != PJ_SUCCESS) {
+ pjsua_perror("Unable to create media session", status);
+ return;
+ }
+
+ PJ_LOG(3,(THIS_FILE,"Media has been started successfully"));
+ }
+}
diff --git a/pjsip/src/pjsua/pjsua_reg.c b/pjsip/src/pjsua/pjsua_reg.c
index 2afb48d6..0a76750d 100644
--- a/pjsip/src/pjsua/pjsua_reg.c
+++ b/pjsip/src/pjsua/pjsua_reg.c
@@ -18,8 +18,20 @@
*/
#include "pjsua.h"
+
+/*
+ * pjsua_reg.c
+ *
+ * Client registration handler.
+ */
+
#define THIS_FILE "pjsua_reg.c"
+
+/*
+ * This callback is called by pjsip_regc when outgoing register
+ * request has completed.
+ */
static void regc_cb(struct pjsip_regc_cbparam *param)
{
/*
@@ -97,6 +109,8 @@ pj_status_t pjsua_regc_init(void)
pjsip_regc_set_credentials( pjsua.regc, pjsua.cred_count,
pjsua.cred_info );
+
+ pjsip_regc_set_route_set( pjsua.regc, &pjsua.route_set );
}
return PJ_SUCCESS;