23 #include <pjsip_simple.h> 24 #include <pjsip/sip_transaction.h> 27 #include <pjmedia/errno.h> 3178 #define MOD_DATA_CONTACT "contact" 3181 #define SERIALIZER_POOL_SIZE 8 3204 pjsip_module **module = data;
3206 ast_log(
LOG_ERROR,
"There is no PJSIP endpoint. Unable to register services\n");
3210 ast_log(
LOG_ERROR,
"Unable to register module %.*s\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3213 ast_debug(1,
"Registered SIP service %.*s (%p)\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
3224 pjsip_module **module = data;
3229 ast_debug(1,
"Unregistered SIP service %.*s\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3242 if (registered_authenticator) {
3243 ast_log(
LOG_WARNING,
"Authenticator %p is already registered. Cannot register a new one\n", registered_authenticator);
3246 registered_authenticator = auth;
3247 ast_debug(1,
"Registered SIP authenticator module %p\n", auth);
3254 if (registered_authenticator != auth) {
3255 ast_log(
LOG_WARNING,
"Trying to unregister authenticator %p but authenticator %p registered\n",
3256 auth, registered_authenticator);
3259 registered_authenticator =
NULL;
3260 ast_debug(1,
"Unregistered SIP authenticator %p\n", auth);
3265 if (!registered_authenticator) {
3266 ast_log(
LOG_WARNING,
"No SIP authenticator registered. Assuming authentication is not required\n");
3274 pjsip_rx_data *rdata, pjsip_tx_data *tdata)
3276 if (!registered_authenticator) {
3277 ast_log(
LOG_WARNING,
"No SIP authenticator registered. Assuming authentication is successful\n");
3287 if (registered_outbound_authenticator) {
3288 ast_log(
LOG_WARNING,
"Outbound authenticator %p is already registered. Cannot register a new one\n", registered_outbound_authenticator);
3291 registered_outbound_authenticator = auth;
3292 ast_debug(1,
"Registered SIP outbound authenticator module %p\n", auth);
3299 if (registered_outbound_authenticator != auth) {
3300 ast_log(
LOG_WARNING,
"Trying to unregister outbound authenticator %p but outbound authenticator %p registered\n",
3301 auth, registered_outbound_authenticator);
3304 registered_outbound_authenticator =
NULL;
3305 ast_debug(1,
"Unregistered SIP outbound authenticator %p\n", auth);
3309 pjsip_tx_data *old_request, pjsip_tx_data **new_request)
3311 if (!registered_outbound_authenticator) {
3312 ast_log(
LOG_WARNING,
"No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
3330 char *prev, *current, *identifier_order;
3334 id_list_item =
ast_calloc(1,
sizeof(*id_list_item));
3335 if (!id_list_item) {
3342 ast_debug(1,
"Register endpoint identifier %s(%p)\n", name ?:
"", identifier);
3361 while ((current = strchr(current,
','))) {
3363 if (!strncmp(prev, name, current - prev)
3364 && strlen(name) == current - prev) {
3372 if (!strcmp(prev, name)) {
3417 ast_debug(1,
"Unregistered endpoint identifier %p\n", identifier);
3441 pjsip_generic_string_hdr *hdr;
3444 hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str,
NULL);
3449 pj_strdup_with_null(rdata->tp_info.pool, &hdr_val, &hdr->hvalue);
3470 e->
command =
"pjsip dump endpt [details]";
3472 "Usage: pjsip dump endpt [details]\n" 3473 " Dump the res_pjsip endpt internals.\n" 3475 "Warning: PJPROJECT documents that the function used by this\n" 3476 "CLI command may cause a crash when asking for details because\n" 3477 "it tries to access all active memory pools.\n";
3485 e->
command =
"pjsip dump endpt";
3487 "Usage: pjsip dump endpt\n" 3488 " Dump the res_pjsip endpt internals.\n";
3496 || (a->
argc == 4 && strcasecmp(a->
argv[3],
"details"))) {
3507 #define ENDPOINT_IDENTIFIER_FORMAT "%-20.20s\n" 3512 e->
command =
"pjsip show identifiers";
3513 e->
usage =
"Usage: pjsip show identifiers\n" 3514 " List all registered endpoint identifiers\n";
3529 iter->
name ? iter->
name :
"name not specified");
3533 #undef ENDPOINT_IDENTIFIER_FORMAT 3542 e->
command =
"pjsip show settings";
3543 e->
usage =
"Usage: pjsip show settings\n" 3544 " Show global and system configuration options\n";
3552 ast_cli(a->
fd,
"Could not allocate output buffer.\n");
3558 ast_cli(a->
fd,
"Error retrieving settings.\n");
3620 pjsip_rx_data *rdata)
3626 if (uri->port == rdata->pkt_info.src_port
3627 && !pj_strcmp(&uri->host,
3628 pj_cstr(&host_name, rdata->pkt_info.src_name))
3630 && PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport)) {
3634 if (!strcasecmp(
"WSS", rdata->tp_info.transport->type_name)) {
3636 pj_cstr(&type_name,
"ws");
3638 pj_cstr(&type_name, rdata->tp_info.transport->type_name);
3641 if (!pj_stricmp(&uri->transport_param, &type_name)
3644 || !pj_stricmp(&uri->transport_param,
3645 pj_cstr(&type_name,
"ws")))) {
3659 pjsip_sip_uri *sip_uri,
char *
buf,
size_t buf_len)
3663 pjsip_param *x_transport;
3670 x_transport = pjsip_param_find(&sip_uri->other_param, &x_name);
3688 pjsip_tpselector *selector)
3691 pjsip_tpselector sel = { .type = PJSIP_TPSELECTOR_NONE, };
3693 uri = pjsip_uri_get_uri(dlg->target);
3700 pjsip_dlg_set_transport(dlg, selector);
3702 if (selector == &sel) {
3710 const char *
domain,
const pj_str_t *target, pjsip_tpselector *selector)
3712 pj_str_t
tmp, local_addr;
3714 pjsip_sip_uri *sip_uri;
3715 pjsip_transport_type_e
type;
3717 char default_user[PJSIP_MAX_URL_SIZE];
3721 user = default_user;
3725 pj_strdup_with_null(pool, &tmp, target);
3727 if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
3728 (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3732 sip_uri = pjsip_uri_get_uri(uri);
3735 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
3736 if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
3737 if (type == PJSIP_TRANSPORT_UNSPECIFIED
3738 || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
3739 type = PJSIP_TRANSPORT_TLS;
3741 }
else if (!sip_uri->transport_param.slen) {
3742 type = PJSIP_TRANSPORT_UDP;
3743 }
else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
3748 if (pj_strchr(&sip_uri->host,
':')) {
3749 type |= PJSIP_TRANSPORT_IPV6;
3753 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3754 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3758 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
3759 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
3765 &local_addr, &local_port) != PJ_SUCCESS) {
3768 pj_strdup(pool, &local_addr, pj_gethostname());
3769 local_port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP);
3773 if (pj_strchr(&local_addr,
':')) {
3774 type |= PJSIP_TRANSPORT_IPV6;
3777 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3778 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3779 "<sip:%s@%s%.*s%s:%d%s%s>",
3781 (type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
3782 (
int)local_addr.slen,
3784 (type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
3786 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
3787 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
3798 if (!transport_state) {
3805 if (transport_state->
flow) {
3810 selector->type = PJSIP_TPSELECTOR_TRANSPORT;
3811 selector->u.transport = transport_state->
transport;
3812 pjsip_transport_add_ref(selector->u.transport);
3813 }
else if (transport_state->
factory) {
3814 selector->type = PJSIP_TPSELECTOR_LISTENER;
3815 selector->u.listener = transport_state->
factory;
3821 }
else if (transport->
flow) {
3823 #ifdef HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE 3824 selector->disable_connection_reuse = PJ_TRUE;
3826 ast_log(
LOG_WARNING,
"Connection reuse could not be disabled on transport '%s' as support is not available\n",
3833 if (transport_state->
flow) {
3861 pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
3863 char transport_name[128];
3874 if (selector->type == PJSIP_TPSELECTOR_TRANSPORT && selector->u.transport) {
3875 pjsip_transport_dec_ref(selector->u.transport);
3881 pjsip_sip_uri *sip_uri;
3883 static const pj_str_t STR_PHONE = {
"phone", 5 };
3885 if (!endpoint || !endpoint->
usereqphone || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3889 sip_uri = pjsip_uri_get_uri(uri);
3891 if (!pj_strlen(&sip_uri->user)) {
3895 if (pj_strbuf(&sip_uri->user)[0] ==
'+') {
3900 for (; i < pj_strlen(&sip_uri->user); i++) {
3906 if (i < pj_strlen(&sip_uri->user)) {
3910 sip_uri->user_param = STR_PHONE;
3914 const char *uri,
const char *request_user)
3916 char enclosed_uri[PJSIP_MAX_URL_SIZE];
3917 pj_str_t local_uri = {
"sip:temp@temp", 13 }, remote_uri, target_uri;
3919 pjsip_dialog *dlg =
NULL;
3921 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
3922 static const pj_str_t HCONTACT = {
"Contact", 7 };
3924 snprintf(enclosed_uri,
sizeof(enclosed_uri),
"<%s>", uri);
3925 pj_cstr(&remote_uri, enclosed_uri);
3927 pj_cstr(&target_uri, uri);
3929 res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri,
NULL, &remote_uri, &target_uri, &dlg);
3930 if (res == PJ_SUCCESS && !(PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
3933 res = PJSIP_EINVALIDURI;
3934 pjsip_dlg_terminate(dlg);
3936 if (res != PJ_SUCCESS) {
3937 if (res == PJSIP_EINVALIDURI) {
3939 "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered and reachable?\n",
3952 pjsip_dlg_terminate(dlg);
3960 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
3961 dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
3962 if (!dlg->local.info->uri) {
3964 "Could not parse URI '%s' for endpoint '%s'\n",
3967 pjsip_dlg_terminate(dlg);
3971 dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen,
NULL);
3974 pjsip_sip_uri *sip_uri;
3976 sip_uri = pjsip_uri_get_uri(dlg->local.contact->uri);
3977 pj_strdup2(dlg->pool, &sip_uri->user, endpoint->
contact_user);
3982 pjsip_sip_uri *sip_uri;
3984 if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target)) {
3985 sip_uri = pjsip_uri_get_uri(dlg->target);
3986 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
3988 if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) || PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri)) {
3989 sip_uri = pjsip_uri_get_uri(dlg->remote.info->uri);
3990 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
3999 pjsip_route_hdr route_set, *route;
4000 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
4003 pj_list_init(&route_set);
4005 pj_strdup2_with_null(dlg->pool, &tmp, outbound_proxy);
4006 if (!(route = pjsip_parse_hdr(dlg->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen,
NULL))) {
4007 ast_log(
LOG_ERROR,
"Could not create dialog to endpoint '%s' as outbound proxy URI '%s' is not valid\n",
4010 pjsip_dlg_terminate(dlg);
4013 pj_list_insert_nodes_before(&route_set, route);
4015 pjsip_dlg_set_route_set(dlg, &route_set);
4035 pjsip_rr_hdr *record_route;
4037 if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri)) {
4041 record_route = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE,
NULL);
4043 if (PJSIP_URI_SCHEME_IS_SIPS(&record_route->name_addr)) {
4049 contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4051 if (PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
4060 const pj_str_t *
contact, pjsip_dialog **p_dlg);
4067 pjsip_transport_type_e
type = rdata->tp_info.transport->key.type;
4068 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4070 pjsip_contact_hdr *contact_hdr;
4074 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4080 transport = rdata->tp_info.transport;
4081 if (selector.type == PJSIP_TPSELECTOR_TRANSPORT) {
4082 transport = selector.u.transport;
4084 type = transport->key.type;
4086 contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
4087 contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE,
4088 "<%s:%s%.*s%s:%d%s%s>",
4090 (type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
4091 (
int)transport->local_name.host.slen,
4092 transport->local_name.host.ptr,
4093 (type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
4094 transport->local_name.port,
4095 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
4096 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
4098 *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
4099 if (*status != PJ_SUCCESS) {
4100 char err[PJ_ERR_MSG_SIZE];
4102 pj_strerror(*status, err,
sizeof(err));
4110 pjsip_dlg_set_transport(dlg, &selector);
4120 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 4123 dlg =
create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4125 pjsip_dlg_dec_lock(dlg);
4135 pjsip_rx_data *rdata, pj_status_t *
status)
4137 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 4138 return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4149 pjsip_dlg_inc_lock(dlg);
4157 char *transport_type,
const char *local_name,
int local_port,
const char *
contact)
4165 pj_list_init(&rdata->msg_info.parse_err);
4167 rdata->tp_info.transport = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, pjsip_transport);
4168 if (!rdata->tp_info.transport) {
4172 ast_copy_string(rdata->pkt_info.packet, packet,
sizeof(rdata->pkt_info.packet));
4173 ast_copy_string(rdata->pkt_info.src_name, src_name,
sizeof(rdata->pkt_info.src_name));
4174 rdata->pkt_info.src_port = src_port;
4175 pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&tmp, src_name), &rdata->pkt_info.src_addr);
4176 pj_sockaddr_set_port(&rdata->pkt_info.src_addr, src_port);
4178 pjsip_parse_rdata(packet, strlen(packet), rdata);
4179 if (!rdata->msg_info.msg || !pj_list_empty(&rdata->msg_info.parse_err)) {
4184 pjsip_contact_hdr *contact_hdr;
4186 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4188 contact_hdr->uri = pjsip_parse_uri(rdata->tp_info.pool, (
char *)contact,
4189 strlen(contact), PJSIP_PARSE_URI_AS_NAMEADDR);
4190 if (!contact_hdr->uri) {
4197 pj_strdup2(rdata->tp_info.pool, &rdata->msg_info.via->recvd_param, rdata->pkt_info.src_name);
4198 rdata->msg_info.via->rport_param = -1;
4200 rdata->tp_info.transport->key.type = pjsip_transport_get_type_from_name(pj_cstr(&tmp, transport_type));
4201 rdata->tp_info.transport->type_name = transport_type;
4202 pj_strdup2(rdata->tp_info.pool, &rdata->tp_info.transport->local_name.host, local_name);
4203 rdata->tp_info.transport->local_name.port = local_port;
4209 char *transport_type,
const char *local_name,
int local_port)
4212 local_name, local_port,
NULL);
4216 static const pjsip_method
info_method = {PJSIP_OTHER_METHOD, {
"INFO", 4} };
4223 {
"INVITE", &pjsip_invite_method },
4224 {
"CANCEL", &pjsip_cancel_method },
4225 {
"ACK", &pjsip_ack_method },
4226 {
"BYE", &pjsip_bye_method },
4227 {
"REGISTER", &pjsip_register_method },
4228 {
"OPTIONS", &pjsip_options_method },
4229 {
"SUBSCRIBE", &pjsip_subscribe_method },
4230 {
"NOTIFY", &pjsip_notify_method },
4240 if (!strcmp(method,
methods[i].method)) {
4249 if (pjsip_dlg_create_request(dlg, method, -1, tdata) != PJ_SUCCESS) {
4259 .name = {
"Out of dialog supplement hook", 29 },
4261 .priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
4266 const char *uri,
struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
4269 pj_str_t remote_uri;
4272 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4274 const char *fromuser;
4291 pj_cstr(&remote_uri,
contact->uri);
4293 pj_cstr(&remote_uri, uri);
4303 sip_uri = pjsip_parse_uri(pool, remote_uri.ptr, remote_uri.slen, 0);
4304 if (!sip_uri || (!PJSIP_URI_SCHEME_IS_SIP(sip_uri) && !PJSIP_URI_SCHEME_IS_SIPS(sip_uri))) {
4305 ast_log(
LOG_ERROR,
"Unable to create outbound %.*s request to endpoint %s as URI '%s' is not valid\n",
4306 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4308 pj_strbuf(&remote_uri));
4317 endpoint ? endpoint->
fromdomain :
NULL, &remote_uri, &selector)) {
4318 ast_log(
LOG_ERROR,
"Unable to create From header for %.*s request to endpoint %s\n",
4319 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4327 &from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
4328 ast_log(
LOG_ERROR,
"Unable to create outbound %.*s request to endpoint %s\n",
4329 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4336 pjsip_tx_data_set_transport(*tdata, &selector);
4341 pjsip_contact_hdr *contact_hdr;
4342 pjsip_sip_uri *contact_uri;
4343 static const pj_str_t HCONTACT = {
"Contact", 7 };
4344 static const pj_str_t HCONTACTSHORT = {
"m", 1 };
4346 contact_hdr = pjsip_msg_find_hdr_by_names((*tdata)->msg, &HCONTACT, &HCONTACTSHORT, NULL);
4348 contact_uri = pjsip_uri_get_uri(contact_hdr->uri);
4349 pj_strdup2((*tdata)->pool, &contact_uri->user, endpoint->
contact_user);
4359 ast_log(
LOG_ERROR,
"Unable to apply outbound proxy on request %.*s to endpoint %s as outbound proxy URI '%s' is not valid\n",
4422 if (supplement == iter) {
4432 if (pjsip_dlg_send_request(dlg, tdata, -1,
NULL) != PJ_SUCCESS) {
4447 pj_cstr(&method, supplement_method);
4449 return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
4452 #define TIMER_INACTIVE 0 4453 #define TIMEOUT_TIMER2 5 4462 void (*callback)(
void *token, pjsip_event *e);
4496 void (*callback)(
void *token, pjsip_event *e);
4524 if (e->body.tsx_state.type == PJSIP_EVENT_TIMER) {
4525 ast_debug(2,
"%p: PJSIP tsx timer expired\n", req_wrapper);
4529 ast_debug(3,
"%p: Timeout already handled\n", req_wrapper);
4534 ast_debug(2,
"%p: PJSIP tsx response received\n", req_wrapper);
4545 int timers_cancelled = 0;
4547 ast_debug(3,
"%p: Cancelling timer\n", req_wrapper);
4549 timers_cancelled = pj_timer_heap_cancel_if_active(
4552 if (timers_cancelled > 0) {
4556 ast_debug(3,
"%p: Timer cancelled\n", req_wrapper);
4564 ast_debug(3,
"%p: Timer already expired\n", req_wrapper);
4575 if (!cb_called && req_wrapper->
callback) {
4577 ast_debug(2,
"%p: Callbacks executed\n", req_wrapper);
4593 ast_debug(2,
"%p: Internal tsx timer expired after %d msec\n",
4594 req_wrapper, req_wrapper->
timeout);
4603 ast_debug(3,
"%p: Timeout already handled\n", req_wrapper);
4609 ast_debug(3,
"%p: Timer handled here\n", req_wrapper);
4615 if (!cb_called && req_wrapper->
callback) {
4618 PJSIP_EVENT_INIT_TX_MSG(event, req_wrapper->
tdata);
4619 event.body.tsx_state.type = PJSIP_EVENT_TIMER;
4622 ast_debug(2,
"%p: Callbacks executed\n", req_wrapper);
4632 pjsip_tx_data_dec_ref(req_wrapper->
tdata);
4633 ast_debug(2,
"%p: wrapper destroyed\n", req_wrapper);
4637 pjsip_tx_data *
tdata, pj_int32_t
timeout,
void *token, pjsip_endpt_send_callback cb)
4640 pj_status_t ret_val;
4645 pjsip_tx_data_dec_ref(tdata);
4652 pjsip_tx_data_dec_ref(tdata);
4656 ast_debug(2,
"%p: Wrapper created\n", req_wrapper);
4664 pjsip_tx_data_add_ref(tdata);
4667 pj_time_val timeout_timer_val = { timeout / 1000, timeout % 1000 };
4669 req_wrapper->
timeout_timer = PJ_POOL_ALLOC_T(tdata->pool, pj_timer_entry);
4671 ast_debug(2,
"%p: Set timer to %d msec\n", req_wrapper, timeout);
4680 ret_val = pj_timer_heap_schedule(pjsip_endpt_get_timer_heap(endpt),
4682 if (ret_val != PJ_SUCCESS) {
4684 "Failed to set timer. Not sending %.*s request to endpoint %s.\n",
4685 (
int) pj_strlen(&tdata->msg->line.req.method.name),
4686 pj_strbuf(&tdata->msg->line.req.method.name),
4688 ao2_t_ref(req_wrapper, -2,
"Drop timer and routine ref");
4689 pjsip_tx_data_dec_ref(tdata);
4699 if (ret_val != PJ_SUCCESS) {
4700 char errmsg[PJ_ERR_MSG_SIZE];
4708 pj_strerror(ret_val, errmsg,
sizeof(errmsg));
4710 (
int) ret_val, errmsg, (
int) pj_strlen(&tdata->msg->line.req.method.name),
4711 pj_strbuf(&tdata->msg->line.req.method.name),
4715 int timers_cancelled;
4718 timers_cancelled = pj_timer_heap_cancel_if_active(
4719 pjsip_endpt_get_timer_heap(endpt),
4721 if (timers_cancelled > 0) {
4732 ret_val = PJ_SUCCESS;
4748 ret_val = PJ_SUCCESS;
4760 if (!tdata || !tdata->dest_info.addr.count
4761 || (tdata->dest_info.cur_addr == tdata->dest_info.addr.count - 1)) {
4767 ++tdata->dest_info.cur_addr;
4769 via = (pjsip_via_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA,
NULL);
4770 via->branch_param.slen = 0;
4772 pjsip_tx_data_invalidate_msg(tdata);
4782 pjsip_transaction *tsx;
4783 pjsip_tx_data *tdata;
4790 tsx = e->body.tsx_state.tsx;
4792 switch (tsx->status_code) {
4798 e->body.tsx_state.src.rdata, tsx->last_tx, &tdata);
4803 tdata = tsx->last_tx;
4808 pjsip_tx_data_add_ref(tdata);
4815 req_data, send_request_cb) == PJ_SUCCESS;
4828 if (e->type == PJSIP_EVENT_TSX_STATE) {
4829 switch(e->body.tsx_state.type) {
4830 case PJSIP_EVENT_TRANSPORT_ERROR:
4831 case PJSIP_EVENT_TIMER:
4841 case PJSIP_EVENT_RX_MSG:
4842 challenge = e->body.tsx_state.src.rdata;
4880 void (*callback)(
void *token, pjsip_event *e))
4888 pjsip_tx_data_dec_ref(tdata);
4921 void (*callback)(
void *token, pjsip_event *e))
4923 ast_assert(tdata->msg->type == PJSIP_REQUEST_MSG);
4934 pjsip_route_hdr *route;
4935 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
4938 pj_strdup2_with_null(tdata->pool, &tmp, proxy);
4939 if (!(route = pjsip_parse_hdr(tdata->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen,
NULL))) {
4943 pj_list_insert_nodes_before(&tdata->msg->hdr, (pjsip_hdr*)route);
4952 pjsip_generic_string_hdr *hdr;
4954 pj_cstr(&hdr_name, name);
4955 pj_cstr(&hdr_value, value);
4957 hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
4959 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
4969 pj_cstr(&type, body->
type);
4970 pj_cstr(&subtype, body->
subtype);
4973 return pjsip_msg_body_create(pool, &type, &subtype, &body_text);
4979 tdata->msg->body = pjsip_body;
4987 pjsip_msg_body *body = pjsip_multipart_create(tdata->pool,
NULL,
NULL);
4989 for (i = 0; i < num_bodies; ++i) {
4990 pjsip_multipart_part *part = pjsip_multipart_create_part(tdata->pool);
4992 pjsip_multipart_add_part(tdata->pool, body, part);
4995 tdata->msg->body = body;
5001 size_t combined_size = strlen(body_text) + tdata->msg->body->len;
5004 ast_str_set(&body_buffer, 0,
"%.*s%s", (
int) tdata->msg->body->len, (
char *) tdata->msg->body->data, body_text);
5006 tdata->msg->body->data = pj_pool_alloc(tdata->pool, combined_size);
5007 pj_memcpy(tdata->msg->body->data,
ast_str_buffer(body_buffer), combined_size);
5008 tdata->msg->body->len = combined_size;
5066 memset(&std, 0,
sizeof(std));
5069 std.
task = sip_task;
5092 return sip_task(task_data);
5119 return sip_task(task_data);
5127 size_t chars_to_copy =
MIN(size - 1, pj_strlen(src));
5128 memcpy(dest, pj_strbuf(src), chars_to_copy);
5129 dest[chars_to_copy] =
'\0';
5134 int res =
ast_asprintf(dest,
"%.*s", (
int)pj_strlen(src), pj_strbuf(src));
5148 if (!content_type) {
5152 pjsip_media_type_init2(&compare, type, subtype);
5154 return pjsip_media_type_cmp(content_type, &compare, 0) ? 0 : -1;
5164 while (monitor_continue) {
5165 const pj_time_val delay = {0, 10};
5173 monitor_continue = 0;
5174 pj_thread_join(monitor_thread);
5179 #define SIP_SERVANT_ID 0x5E2F1D 5183 pj_thread_desc *
desc;
5185 uint32_t *servant_id;
5189 ast_log(
LOG_ERROR,
"Could not set SIP servant ID in thread-local storage.\n");
5196 ast_log(
LOG_ERROR,
"Could not get thread desc from thread-local storage. Expect awful things to occur\n");
5199 pj_bzero(*desc,
sizeof(*desc));
5201 if (pj_thread_register(
"Asterisk Thread", *desc, &thread) != PJ_SUCCESS) {
5208 uint32_t *servant_id;
5210 if (monitor_thread &&
5211 pthread_self() == *(pthread_t *)pj_thread_get_os_handle(monitor_thread)) {
5225 unsigned int hval = 0;
5231 return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval);
5235 const char *key,
void *
val)
5238 ht = pj_hash_create(pool, 11);
5241 pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
5250 if (pjsip_rdata_get_dlg(rdata)) {
5273 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
NULL);
5298 if (status != PJ_SUCCESS) {
5299 pjsip_tx_data_dec_ref(tdata);
5302 return status == PJ_SUCCESS ? 0 : -1;
5307 pjsip_transaction *tsx;
5309 if (pjsip_tsx_create_uas(
NULL, rdata, &tsx) != PJ_SUCCESS) {
5318 pjsip_tx_data_dec_ref(tdata);
5321 pjsip_tsx_recv_msg(tsx, rdata);
5325 if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
5326 pjsip_tx_data_dec_ref(tdata);
5360 if (af == pj_AF_INET()) {
5362 }
else if (af == pj_AF_INET6()) {
5370 char *
buf,
size_t buf_len)
5402 if (!strcasecmp(dtmf_mode,
"info")) {
5404 }
else if (!strcasecmp(dtmf_mode,
"rfc4733")) {
5406 }
else if (!strcasecmp(dtmf_mode,
"inband")) {
5408 }
else if (!strcasecmp(dtmf_mode,
"none")) {
5410 }
else if (!strcasecmp(dtmf_mode,
"auto")) {
5412 }
else if (!strcasecmp(dtmf_mode,
"auto_info")) {
5423 if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5425 }
else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5426 value =
"local_merge";
5427 }
else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5428 value =
"local_first";
5429 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5431 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5432 value =
"remote_merge";
5433 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5434 value =
"remote_first";
5446 if (strcmp(pref_str,
"local") == 0) {
5448 }
else if (is_outgoing && strcmp(pref_str,
"local_merge") == 0) {
5450 }
else if (strcmp(pref_str,
"local_first") == 0) {
5452 }
else if (strcmp(pref_str,
"remote") == 0) {
5454 }
else if (is_outgoing && strcmp(pref_str,
"remote_merge") == 0) {
5456 }
else if (strcmp(pref_str,
"remote_first") == 0) {
5474 pjsip_name_addr *id_name_addr;
5475 pjsip_sip_uri *id_uri;
5477 id_name_addr = (pjsip_name_addr *) id_hdr->uri;
5478 id_uri = pjsip_uri_get_uri(id_name_addr->uri);
5482 int name_buf_len = strlen(id->
name.
str) * 2 + 1;
5486 pj_strdup2(pool, &id_name_addr->display, name_buf);
5488 pj_strdup2(pool, &id_name_addr->display,
NULL);
5493 pj_strdup2(pool, &id_uri->user, id->
number.
str);
5500 const pjsip_hdr *
request_headers = pjsip_endpt_get_request_headers(endpt);
5501 pjsip_hdr *iter = request_headers->next;
5503 while (iter != request_headers) {
5504 pjsip_hdr *to_erase = iter;
5506 pj_list_erase(to_erase);
5520 #ifdef TEST_FRAMEWORK 5527 info->name =
"xml_sanitization_end_null";
5528 info->category =
"/res/res_pjsip/";
5529 info->summary =
"Ensure XML sanitization works as expected with a long string";
5530 info->description =
"This test sanitizes a string which exceeds the output\n" 5531 "buffer size. Once done the string is confirmed to be NULL terminated.";
5538 if (sanitized[7] !=
'\0') {
5552 info->name =
"xml_sanitization_exceeds_buffer";
5553 info->category =
"/res/res_pjsip/";
5554 info->summary =
"Ensure XML sanitization does not exceed buffer when output won't fit";
5555 info->description =
"This test sanitizes a string which before sanitization would\n" 5556 "fit within the output buffer. After sanitization, however, the string would\n" 5557 "exceed the buffer. Once done the string is confirmed to be NULL terminated.";
5564 if (sanitized[7] !=
'\0') {
5603 if (monitor_thread) {
5605 monitor_thread =
NULL;