diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-02-09 00:13:40 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-02-09 00:13:40 +0000 |
commit | 1a7571f62112ae25317663cba5df39c8ff1690c7 (patch) | |
tree | 4bb56c9bc0d9a941ef274a2545c83a5243821465 /pjsip | |
parent | 86871987528c71dfa0e666e663ed66f5eb776342 (diff) |
Integration of pjmedia and pjsip error subsystem to pjlib
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@162 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsip/sip_errno.h | 18 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 61 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_endpoint.c | 29 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_resolve.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 20 | ||||
-rw-r--r-- | pjsip/src/pjsua/pjsua.h | 44 | ||||
-rw-r--r-- | pjsip/src/pjsua/pjsua_core.c | 180 |
7 files changed, 260 insertions, 96 deletions
diff --git a/pjsip/include/pjsip/sip_errno.h b/pjsip/include/pjsip/sip_errno.h index f7dc18cc..d5000955 100644 --- a/pjsip/include/pjsip/sip_errno.h +++ b/pjsip/include/pjsip/sip_errno.h @@ -23,11 +23,6 @@ PJ_BEGIN_DECL -/** - * Guidelines on error message length. - */ -#define PJSIP_ERR_MSG_SIZE 64 - /* * PJSIP error codes occupies 170000 - 219000, and mapped as follows: * - 170100 - 170799: mapped to SIP status code in response msg. @@ -35,19 +30,6 @@ PJ_BEGIN_DECL */ /** - * Get error message for the specified error code. - * - * @param status The error code. - * @param buffer The buffer where to put the error message. - * @param bufsize Size of the buffer. - * - * @return The error message as NULL terminated string, - * wrapped with pj_str_t. - */ -PJ_DECL(pj_str_t) pjsip_strerror( pj_status_t status, char *buffer, - pj_size_t bufsize); - -/** * Start of error code relative to PJ_ERRNO_START_USER. */ #define PJSIP_ERRNO_START (PJ_ERRNO_START_USER) diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 2a5e14ae..28a8bd62 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -23,6 +23,7 @@ #include <pjsip/sip_transaction.h> #include <pjmedia/sdp.h> #include <pjmedia/sdp_neg.h> +#include <pjmedia/errno.h> #include <pj/string.h> #include <pj/pool.h> #include <pj/assert.h> @@ -760,9 +761,7 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg, status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, local_sdp, &inv->neg); } else { - pj_assert(!"UAS dialog without remote and local offer is not supported!"); - PJ_TODO(IMPLEMENT_DELAYED_UAS_OFFER); - status = PJ_ENOTSUP; + status = PJ_SUCCESS; } if (status != PJ_SUCCESS) @@ -875,6 +874,25 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv, /* + * Negotiate SDP. + */ +static pj_status_t inv_negotiate_sdp( pjsip_inv_session *inv ) +{ + pj_status_t status; + + PJ_ASSERT_RETURN(pjmedia_sdp_neg_get_state(inv->neg) == + PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, + PJMEDIA_SDPNEG_EINSTATE); + + status = pjmedia_sdp_neg_negotiate(inv->pool, inv->neg, 0); + + if (mod_inv.cb.on_media_update) + (*mod_inv.cb.on_media_update)(inv, status); + + return status; +} + +/* * Answer initial INVITE. */ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv, @@ -898,12 +916,23 @@ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv, /* If local_sdp is specified, then we MUST NOT have answered the * offer before. */ - PJ_ASSERT_RETURN(!local_sdp || - (pjmedia_sdp_neg_get_state(inv->neg)==PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER), - PJ_EINVALIDOP); if (local_sdp) { - status = pjmedia_sdp_neg_set_local_answer(inv->pool, inv->neg, - local_sdp); + + if (inv->neg == NULL) { + status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, local_sdp, + &inv->neg); + } else if (pjmedia_sdp_neg_get_state(inv->neg)== + PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER) + { + status = pjmedia_sdp_neg_set_local_answer(inv->pool, inv->neg, + local_sdp); + } else { + + /* Can not specify local SDP at this state. */ + pj_assert(0); + status = PJMEDIA_SDPNEG_EINSTATE; + } + if (status != PJ_SUCCESS) return status; } @@ -915,18 +944,26 @@ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv, if (status != PJ_SUCCESS) return status; - /* Include SDP for 18x and 2xx response. */ + /* Include SDP for 18x and 2xx response. + * Also if SDP negotiator is ready, start negotiation. + */ if (st_code/10 == 18 || st_code/10 == 20) { const pjmedia_sdp_session *local; status = pjmedia_sdp_neg_get_neg_local(inv->neg, &local); if (status == PJ_SUCCESS) last_res->msg->body = create_sdp_body(last_res->pool, local); - ; + + /* Start negotiation, if ready. */ + if (pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) { + status = inv_negotiate_sdp(inv); + if (status != PJ_SUCCESS) { + pjsip_tx_data_dec_ref(last_res); + return status; + } + } } - /* Do we need to increment tdata'inv reference counter? */ - PJ_TODO(INV_ANSWER_MAY_HAVE_TO_INCREMENT_REF_COUNTER); *p_tdata = last_res; diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index 0cc8b270..df4c5ccb 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -106,6 +106,28 @@ pj_status_t pjsip_tel_uri_subsys_init(void); /* Defined in sip_util_statefull.c */ extern pjsip_module mod_stateful_util; + +/* Specifies whether error subsystem has been registered to pjlib. */ +static int error_subsys_initialized; + +/** + * Defined in sip_errno.c + * + * Get error message for the specified error code. This can only get + * PJSIP specific error message. To get all types of error message, + * use pj_strerror() instead. + * + * @param status The error code. + * @param buffer The buffer where to put the error message. + * @param bufsize Size of the buffer. + * + * @return The error message as NULL terminated string, + * wrapped with pj_str_t. + */ +PJ_DECL(pj_str_t) pjsip_strerror( pj_status_t status, char *buffer, + pj_size_t bufsize); + + /* * This is the global handler for memory allocation failure, for pools that * are created by the endpoint (by default, all pools ARE allocated by @@ -394,6 +416,13 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf, pjsip_max_fwd_hdr *mf_hdr; pj_lock_t *lock = NULL; + + if (!error_subsys_initialized) { + pj_register_strerror(PJSIP_ERRNO_START, PJ_ERRNO_SPACE_SIZE, + &pjsip_strerror); + error_subsys_initialized = 1; + } + PJ_LOG(5, (THIS_FILE, "Creating endpoint instance...")); *p_endpt = NULL; diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c index 4712b7f7..5b920be5 100644 --- a/pjsip/src/pjsip/sip_resolve.c +++ b/pjsip/src/pjsip/sip_resolve.c @@ -129,12 +129,12 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, } if (status != PJ_SUCCESS) { - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; PJ_LOG(4,(THIS_FILE, "Failed to resolve '%.*s'. Err=%d (%s)", target->addr.host.slen, target->addr.host.ptr, status, - pjsip_strerror(status,errmsg,sizeof(errmsg)).ptr)); + pj_strerror(status,errmsg,sizeof(errmsg)).ptr)); (*cb)(status, token, &svr_addr); return; } diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index 6dae0370..dcb09131 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -1442,12 +1442,12 @@ static void send_msg_callback( pjsip_send_state *send_state, } if (!*cont) { - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; PJ_LOG(4,(tsx->obj_name, "Failed to send %s! err=%d (%s)", pjsip_tx_data_get_info(send_state->tdata), -sent, - pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); /* Clear pending transport flag. */ tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); @@ -1465,13 +1465,13 @@ static void send_msg_callback( pjsip_send_state *send_state, } } else { - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; PJ_LOG(4,(tsx->obj_name, "Temporary failure in sending %s, " "will try next server. Err=%d (%s)", pjsip_tx_data_get_info(send_state->tdata), -sent, - pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); } } @@ -1486,11 +1486,11 @@ static void transport_callback(void *token, pjsip_tx_data *tdata, if (sent < 0) { pjsip_transaction *tsx = token; struct tsx_lock_data lck; - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; PJ_LOG(4,(tsx->obj_name, "Transport failed to send %s! Err=%d (%s)", pjsip_tx_data_get_info(tdata), -sent, - pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); lock_tsx(tsx, &lck); @@ -1534,12 +1534,12 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, status = PJ_SUCCESS; if (status != PJ_SUCCESS) { - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; PJ_LOG(4,(tsx->obj_name, "Error sending %s: Err=%d (%s)", pjsip_tx_data_get_info(tdata), status, - pjsip_strerror(status, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(status, errmsg, sizeof(errmsg)).ptr)); /* On error, release transport to force using full transport * resolution procedure. @@ -1568,7 +1568,7 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, */ if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) { - char errmsg[PJSIP_ERR_MSG_SIZE]; + char errmsg[PJ_ERR_MSG_SIZE]; if (status == PJ_SUCCESS) { pj_assert(!"Unexpected status!"); @@ -1582,7 +1582,7 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, "Transport error, terminating transaction. " "Err=%d (%s)", status, - pjsip_strerror(status, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(status, errmsg, sizeof(errmsg)).ptr)); tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, diff --git a/pjsip/src/pjsua/pjsua.h b/pjsip/src/pjsua/pjsua.h index 53b46e58..37740c3a 100644 --- a/pjsip/src/pjsua/pjsua.h +++ b/pjsip/src/pjsua/pjsua.h @@ -38,16 +38,22 @@ PJ_BEGIN_DECL /* PJSUA application variables. */ -struct pjsua_t +struct pjsua { /* Control: */ - pj_caching_pool cp; /**< Global pool factory. */ - pjsip_endpoint *endpt; /**< Global endpoint. */ - pj_pool_t *pool; /**< pjsua's private pool. */ - pjsip_module mod; /**< pjsua's PJSIP module. */ + pj_caching_pool cp; /**< Global pool factory. */ + pjsip_endpoint *endpt; /**< Global endpoint. */ + pj_pool_t *pool; /**< pjsua's private pool. */ + pjsip_module mod; /**< pjsua's PJSIP module. */ + /* Media: */ + + pjmedia_endpt *med_endpt; /**< Media endpoint. */ + pj_bool_t null_audio; + pjmedia_sock_info med_skinfo; + /* User info: */ pj_str_t local_uri; /**< Uri in From: header. */ @@ -57,6 +63,8 @@ struct pjsua_t pj_str_t proxy; pj_str_t outbound_proxy; + pjsip_route_hdr route_set; + /* Registration: */ @@ -83,10 +91,6 @@ struct pjsua_t pj_uint16_t sip_port; /**< SIP signaling port. */ pj_sock_t sip_sock; /**< SIP UDP socket. */ pj_sockaddr_in sip_sock_name; /**< Public/STUN UDP socket addr. */ - pj_sock_t rtp_sock; /**< RTP socket. */ - pj_sockaddr_in rtp_sock_name; /**< Public/STUN UDP socket addr. */ - pj_sock_t rtcp_sock; /**< RTCP socket. */ - pj_sockaddr_in rtcp_sock_name;/**< Public/STUN UDP socket addr. */ @@ -98,12 +102,6 @@ struct pjsua_t int stun_port2; - /* Media stack: */ - - pj_bool_t null_audio; - pj_med_mgr_t *mmgr; - - /* Misc: */ int log_level; /**< Logging verbosity. */ @@ -113,7 +111,21 @@ struct pjsua_t }; -extern struct pjsua_t pjsua; + +/** PJSUA instance. */ +extern struct pjsua pjsua; + + +/** + * Structure to be attached to all dialog. + * Given a dialog "dlg", application can retrieve this structure + * by accessing dlg->mod_data[pjsua.mod.id]. + */ +struct pjsua_inv_data +{ + pjmedia_session *session; +}; + /***************************************************************************** * PJSUA API. diff --git a/pjsip/src/pjsua/pjsua_core.c b/pjsip/src/pjsua/pjsua_core.c index 46f7fde7..272339f1 100644 --- a/pjsip/src/pjsua/pjsua_core.c +++ b/pjsip/src/pjsua/pjsua_core.c @@ -21,27 +21,14 @@ #define THIS_FILE "pjsua.c" -struct pjsua_t pjsua; +struct pjsua pjsua; +/* + * Default local URI, if not specified in cmd-line + */ #define PJSUA_LOCAL_URI "<sip:user@127.0.0.1>" -static char *PJSUA_DUMMY_SDP_OFFER = - "v=0\r\n" - "o=offer 2890844526 2890844526 IN IP4 127.0.0.1\r\n" - "s= \r\n" - "c=IN IP4 127.0.0.1\r\n" - "t=0 0\r\n" - "m=audio 49170 RTP/AVP 0\r\n" - "a=rtpmap:0 PCMU/8000\r\n"; - -static char *PJSUA_DUMMY_SDP_ANSWER = - "v=0\r\n" - "o=answer 2890844730 2890844730 IN IP4 127.0.0.1\r\n" - "s= \r\n" - "c=IN IP4 127.0.0.1\r\n" - "t=0 0\r\n" - "m=audio 49920 RTP/AVP 0\r\n" - "a=rtpmap:0 PCMU/8000\r\n"; + /* * Init default application parameters. @@ -74,6 +61,10 @@ void pjsua_default(void) /* Default URIs: */ pjsua.local_uri = pj_str(PJSUA_LOCAL_URI); + + /* Init route set list: */ + + pj_list_init(&pjsua.route_set); } @@ -143,14 +134,14 @@ static pj_bool_t mod_pjsua_on_rx_request(pjsip_rx_data *rdata) * Yes we can handle the incoming INVITE request. */ pjsip_inv_session *inv; + struct pjsua_inv_data *inv_data; pjmedia_sdp_session *answer; - /* Create dummy SDP answer: */ + /* Get media capability from media endpoint: */ - status = pjmedia_sdp_parse(pjsua.pool, PJSUA_DUMMY_SDP_ANSWER, - pj_native_strlen(PJSUA_DUMMY_SDP_ANSWER), - &answer); + 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, @@ -181,6 +172,13 @@ static pj_bool_t mod_pjsua_on_rx_request(pjsip_rx_data *rdata) } + + /* 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); @@ -222,6 +220,19 @@ static pj_bool_t mod_pjsua_on_rx_response(pjsip_rx_data *rdata) */ 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; + } + + } + pjsua_ui_inv_on_state_changed(inv, e); } @@ -238,6 +249,60 @@ static void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *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; + } + +} + /* * Initialize sockets and optionally get the public address via STUN. */ @@ -363,20 +428,24 @@ static pj_status_t init_sockets() pjsua.sip_sock = sock[SIP_SOCK]; pj_memcpy(&pjsua.sip_sock_name, &mapped_addr[SIP_SOCK], sizeof(pj_sockaddr_in)); - pjsua.rtp_sock = sock[RTP_SOCK]; - pj_memcpy(&pjsua.rtp_sock_name, &mapped_addr[RTP_SOCK], sizeof(pj_sockaddr_in)); - pjsua.rtcp_sock = sock[RTCP_SOCK]; - pj_memcpy(&pjsua.rtcp_sock_name, &mapped_addr[RTCP_SOCK], sizeof(pj_sockaddr_in)); + + pjsua.med_skinfo.rtp_sock = sock[RTP_SOCK]; + pj_memcpy(&pjsua.med_skinfo.rtp_addr_name, + &mapped_addr[RTP_SOCK], sizeof(pj_sockaddr_in)); + + pjsua.med_skinfo.rtcp_sock = sock[RTCP_SOCK]; + pj_memcpy(&pjsua.med_skinfo.rtcp_addr_name, + &mapped_addr[RTCP_SOCK], sizeof(pj_sockaddr_in)); PJ_LOG(4,(THIS_FILE, "SIP UDP socket reachable at %s:%d", pj_inet_ntoa(pjsua.sip_sock_name.sin_addr), pj_ntohs(pjsua.sip_sock_name.sin_port))); PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s:%d", - pj_inet_ntoa(pjsua.rtp_sock_name.sin_addr), - pj_ntohs(pjsua.rtp_sock_name.sin_port))); + pj_inet_ntoa(pjsua.med_skinfo.rtp_addr_name.sin_addr), + pj_ntohs(pjsua.med_skinfo.rtp_addr_name.sin_port))); PJ_LOG(4,(THIS_FILE, "RTCP UDP socket reachable at %s:%d", - pj_inet_ntoa(pjsua.rtcp_sock_name.sin_addr), - pj_ntohs(pjsua.rtcp_sock_name.sin_port))); + pj_inet_ntoa(pjsua.med_skinfo.rtcp_addr_name.sin_addr), + pj_ntohs(pjsua.med_skinfo.rtcp_addr_name.sin_port))); return PJ_SUCCESS; @@ -478,6 +547,7 @@ static pj_status_t init_stack(void) pj_memset(&inv_cb, 0, sizeof(inv_cb)); inv_cb.on_state_changed = &pjsua_inv_on_state_changed; inv_cb.on_new_session = &pjsua_inv_on_new_session; + inv_cb.on_media_update = &pjsua_inv_on_media_update; /* Initialize invite session module: */ status = pjsip_inv_usage_init(pjsua.endpt, &pjsua.mod, &inv_cb); @@ -554,6 +624,16 @@ pj_status_t pjsua_init(void) return status; } + + /* Init media endpoint: */ + + status = pjmedia_endpt_create(&pjsua.cp.factory, &pjsua.med_endpt); + if (status != PJ_SUCCESS) { + pj_caching_pool_destroy(&pjsua.cp); + pjsua_perror("Media stack initialization has returned error", status); + return status; + } + /* Done. */ return PJ_SUCCESS; } @@ -676,9 +756,25 @@ pj_status_t pjsua_start(void) } - /* Initialize global route_set: */ + /* If outbound_proxy is specified, put it in the route_set: */ + + if (pjsua.outbound_proxy.slen) { - PJ_TODO(INIT_GLOBAL_ROUTE_SET); + pjsip_route_hdr *route; + const pj_str_t hname = { "Route", 5 }; + int parsed_len; + + route = pjsip_parse_hdr( pjsua.pool, &hname, + pjsua.outbound_proxy.ptr, + pjsua.outbound_proxy.slen, + &parsed_len); + if (route == NULL) { + pjsua_perror("Invalid outbound proxy URL", PJSIP_EINVALIDURI); + return PJSIP_EINVALIDURI; + } + + pj_list_push_back(&pjsua.route_set, route); + } /* Create worker thread(s), if required: */ @@ -769,6 +865,7 @@ pj_status_t pjsua_invite(const char *cstr_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; @@ -786,13 +883,12 @@ pj_status_t pjsua_invite(const char *cstr_dest_uri, return status; } - /* Create dummy SDP for offer: */ + /* Get media capability from media endpoint: */ - status = pjmedia_sdp_parse(dlg->pool, PJSUA_DUMMY_SDP_OFFER, - pj_native_strlen(PJSUA_DUMMY_SDP_OFFER), - &offer); + status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool, + 1, &pjsua.med_skinfo, &offer); if (status != PJ_SUCCESS) { - pjsua_perror("Dummy SDP offer parsing failed", status); + pjsua_perror("pjmedia unable to create SDP", status); goto on_error; } @@ -805,9 +901,17 @@ pj_status_t pjsua_invite(const char *cstr_dest_uri, } + /* Create and associate our data in the session. */ + + inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data)); + dlg->mod_data[pjsua.mod.id] = inv_data; + + /* Set dialog Route-Set: */ - PJ_TODO(INIT_DIALOG_ROUTE_SET); + if (!pj_list_empty(&pjsua.route_set)) + pjsip_dlg_set_route_set(dlg, &pjsua.route_set); + /* Set credentials: */ |