86 .name = {
"REFER Progress", 14 },
100 pjsip_evsub_state
state)
149 pjsip_tx_data *tdata;
151 pjsip_dlg_inc_lock(notification->progress->dlg);
154 if (!(
sub = notification->progress->sub)) {
155 ast_debug(3,
"Not sending NOTIFY of response '%d' and state '%u' on progress monitor '%p' as subscription has been terminated\n",
156 notification->response, notification->state, notification->progress);
157 pjsip_dlg_dec_lock(notification->progress->dlg);
162 if (!notification->progress->sent_100) {
163 notification->progress->sent_100 = 1;
164 if (notification->response != 100) {
165 ast_debug(3,
"Sending initial 100 Trying NOTIFY for progress monitor '%p'\n",
166 notification->progress);
167 if (pjsip_xfer_notify(
sub, PJSIP_EVSUB_STATE_ACTIVE, 100,
NULL, &tdata) == PJ_SUCCESS) {
168 pjsip_xfer_send_request(
sub, tdata);
173 ast_debug(3,
"Sending NOTIFY with response '%d' and state '%u' on subscription '%p' and progress monitor '%p'\n",
174 notification->response, notification->state,
sub, notification->progress);
177 if (pjsip_xfer_notify(
sub, notification->state, notification->response,
NULL, &tdata) == PJ_SUCCESS) {
178 pjsip_xfer_send_request(
sub, tdata);
181 pjsip_dlg_dec_lock(notification->progress->dlg);
210 if (!
progress->transfer_data->completed) {
232 ast_debug(3,
"Detaching REFER progress monitoring hook from '%s' as it has joined a bridge\n",
252 if (!
progress->transfer_data->completed) {
287 if (notification->
state == PJSIP_EVSUB_STATE_TERMINATED) {
288 ast_debug(3,
"Detaching REFER progress monitoring hook from '%s' as subscription is being terminated\n",
336 if (
progress && (pjsip_evsub_get_state(
sub) == PJSIP_EVSUB_STATE_TERMINATED)) {
389 const pj_str_t str_refer_sub = {
"Refer-Sub", 9 };
390 pjsip_generic_string_hdr *refer_sub =
NULL;
391 const pj_str_t str_true = {
"true", 4 };
398 refer_sub = pjsip_msg_find_hdr_by_name(
rdata->msg_info.msg, &str_refer_sub,
NULL);
399 if ((refer_sub && pj_strnicmp(&refer_sub->hvalue, &str_true, 4))) {
407 ast_debug(3,
"Created progress monitor '%p' for transfer occurring from channel '%s' and endpoint '%s'\n",
410 (*progress)->refer_blind_progress =
session->endpoint->refer_blind_progress;
412 (*progress)->framehook = -1;
428 (*progress)->dlg =
session->inv_session->dlg;
439 pjsip_hdr *hdr = (pjsip_hdr*)pjsip_generic_string_hdr_create(
session->inv_session->dlg->pool, &str_refer_sub, &str_true);
562 int (*task_cb)(
void *data);
565 ast_debug(3,
"Performing a REFER attended transfer - Transferer #1: %s Transferer #2: %s\n",
573 ast_debug(3,
"Final response for REFER attended transfer - Transferer #1: %s Transferer #2: %s is '%d'\n",
578 ast_debug(3,
"Received REFER request on channel '%s' but other channel has gone.\n",
587 PJSIP_EVSUB_STATE_TERMINATED);
634 pjsip_generic_string_hdr *referred_by;
636 static const pj_str_t str_referred_by = {
"Referred-By", 11 };
637 static const pj_str_t str_referred_by_s = {
"b", 1 };
638 const char *get_xfrdata;
645 PJSIP_EVSUB_STATE_TERMINATED);
659 .disable_inheritance = 1,
665 PJSIP_EVSUB_STATE_TERMINATED);
667 ast_log(
LOG_WARNING,
"Could not copy channel name '%s' during transfer - assuming success\n",
678 ao2_ref(user_data_wrapper, +1);
690 PJSIP_EVSUB_STATE_TERMINATED);
692 ast_log(
LOG_WARNING,
"Could not attach REFER transfer progress monitoring hook to channel '%s' - assuming success\n",
712 PJSIP_EVSUB_STATE_TERMINATED);
714 ast_log(
LOG_WARNING,
"Could not create bridge stasis subscription for monitoring progress on transfer of channel '%s' - assuming success\n",
743 const pjsip_msg * msg = refer->
rdata->msg_info.msg;
744 const struct pjsip_hdr *
end = &msg->hdr;
745 struct pjsip_hdr *hdr =
end->next;
748 const char *
prefix = get_xfrdata;
751 if (!strcmp(
prefix,
"*")) {
755 for (; hdr !=
end; hdr = hdr->next) {
756 if (!pj_strnicmp2(&hdr->name,
prefix, strlen(
prefix))) {
757 const int hdr_name_strlen = pj_strlen(&hdr->name);
758 const int hdr_name_bytes = hdr_name_strlen + 1;
759 char hdr_name[hdr_name_bytes];
764 len = pjsip_hdr_print_on(hdr,
buf,
sizeof(
buf) - 1);
773 value_str = strchr(
buf,
':');
780 ast_str_set(&pbxvar, -1,
"~HASH~TRANSFER_DATA~%.*s~", hdr_name_strlen, hdr_name);
782 ast_debug(5,
"On channel '%s' set TRANSFER_DATA variable '%s' to value '%s' \n",
ast_channel_name(chan), hdr_name, value_str);
791 referred_by = pjsip_msg_find_hdr_by_names(refer->
rdata->msg_info.msg,
792 &str_referred_by, &str_referred_by_s,
NULL);
794 size_t uri_size = pj_strlen(&referred_by->hvalue) + 1;
805 char *replaces_val =
NULL;
808 len = pjsip_hdr_print_on(refer->
replaces, replaces,
sizeof(replaces) - 1);
811 replaces[
len] =
'\0';
812 replaces_val = replaces +
sizeof(
"Replaces:");
820 char refer_to[PJSIP_MAX_URL_SIZE];
822 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, refer->
refer_to, refer_to,
sizeof(refer_to));
837#define DETERMINE_TRANSFER_CONTEXT(context, session) \
839 ast_channel_lock((session)->channel); \
840 context = pbx_builtin_getvar_helper((session)->channel, "TRANSFER_CONTEXT"); \
841 if (ast_strlen_zero(context)) { \
842 context = (session)->endpoint->context; \
844 context = ast_strdupa(context); \
846 ast_channel_unlock((session)->channel); \
909 uri_params = strchr(rdata->
from,
'@');
910 if (uri_params && (uri_params = strchr(uri_params,
';'))) {
937 static const char *hdr[] = {
952 if (!strcasecmp(
name, hdr[i])) {
992 .name = {
"REFER Out-of-dialog Module", 26 },
996 .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 4,
1002 const pj_str_t REFER_TO = {
"Refer-To", 8 };
1003 pjsip_generic_string_hdr *refer_to;
1004 pjsip_uri *parsed_uri;
1006 if (!(refer_to = pjsip_msg_find_hdr_by_name(tdata->msg, &REFER_TO,
NULL))
1007 || !(parsed_uri = pjsip_parse_uri(tdata->pool, refer_to->hvalue.ptr, refer_to->hvalue.slen, 0))
1008 || (!PJSIP_URI_SCHEME_IS_SIP(parsed_uri) && !PJSIP_URI_SCHEME_IS_SIPS(parsed_uri))) {
1017 const pj_str_t REFER_TO = {
"Refer-To", 8 };
1018 pjsip_generic_string_hdr *refer_to_hdr;
1021 pjsip_uri *parsed_uri;
1022 pjsip_sip_uri *refer_to_uri;
1032 || pjsip_msg_find_hdr(tdata->msg, PJSIP_H_AUTHORIZATION,
NULL)
1033 || !(dlg = pjsip_tdata_get_dlg(tdata))
1039 refer_to_uri = pjsip_uri_get_uri(parsed_uri);
1043 refer_to_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &REFER_TO,
NULL);
1044 pj_strdup2(tdata->pool, &refer_to_hdr->hvalue,
ast_str_buffer(refer_to_str));
1088 pjsip_tx_data *tdata;
1105 if (pjsip_evsub_get_state(
sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
1107 pjsip_rx_data *rdata;
1108 pjsip_generic_string_hdr *refer_sub;
1109 const pj_str_t REFER_SUB = {
"Refer-Sub", 9 };
1114 if (
event->type == PJSIP_EVENT_TSX_STATE &&
event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1115 rdata =
event->body.tsx_state.src.rdata;
1118 refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB,
NULL);
1124 if (refer_sub && !pj_stricmp2(&refer_sub->hvalue,
"false")) {
1129 pjsip_evsub_terminate(
sub, PJ_TRUE);
1133 }
else if (pjsip_evsub_get_state(
sub) == PJSIP_EVSUB_STATE_ACTIVE ||
1134 pjsip_evsub_get_state(
sub) == PJSIP_EVSUB_STATE_TERMINATED) {
1137 pjsip_msg_body *body;
1138 pjsip_status_line status_line = { .code = 0 };
1142 if (
event->type == PJSIP_EVENT_TSX_STATE &&
event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1143 pjsip_rx_data *rdata;
1145 pj_cstr(&refer_str,
"REFER");
1147 rdata =
event->body.tsx_state.src.rdata;
1148 msg = rdata->msg_info.msg;
1150 if (msg->type == PJSIP_RESPONSE_MSG
1151 && (
event->body.tsx_state.tsx->status_code == 401
1152 ||
event->body.tsx_state.tsx->status_code == 407)
1153 && pj_stristr(&refer_str, &
event->body.tsx_state.tsx->method.name)
1158 event->body.tsx_state.src.rdata,
event->body.tsx_state.tsx->last_tx, &tdata)) {
1165 if (msg->type == PJSIP_REQUEST_MSG) {
1166 if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
1168 if (body && !pj_stricmp2(&body->content_type.type,
"message")
1169 && !pj_stricmp2(&body->content_type.subtype,
"sipfrag")) {
1170 pjsip_parse_status_line((
char *)body->data, body->len, &status_line);
1174 status_line.code = msg->line.status.code;
1175 status_line.reason = msg->line.status.reason;
1178 status_line.code = 500;
1179 status_line.reason = *pjsip_get_status_text(500);
1182 is_last = (pjsip_evsub_get_state(
sub) == PJSIP_EVSUB_STATE_TERMINATED);
1184 if (status_line.code >= 200 || is_last) {
1187 refer_success = status_line.code >= 200 && status_line.code < 300;
1192 pjsip_tx_data *tdata;
1194 status = pjsip_evsub_initiate(
sub, pjsip_get_subscribe_method(), 0, &tdata);
1195 if (
status == PJ_SUCCESS) {
1196 pjsip_evsub_send_request(
sub, tdata);
1199 ast_debug(3,
"Refer completed: %d %.*s (%s)\n",
1201 (
int)status_line.reason.slen, status_line.reason.ptr,
1202 refer_success ?
"Success" :
"Failure");
1223 pjsip_tx_data *tdata;
1226 char refer_to_str[PJSIP_MAX_URL_SIZE];
1227 char disp_name_escaped[128];
1229 struct pjsip_evsub_user xfer_cb;
1239 "PJSIP REFER - Could not find endpoint '%s' and no default outbound endpoint configured\n",
1247 ast_log(
LOG_WARNING,
"PJSIP REFER - Refer to not a valid resource identifier or SIP URI\n");
1265 pj_bzero(&xfer_cb,
sizeof(xfer_cb));
1267 if (pjsip_xfer_create_uac(refer->
dlg, &xfer_cb, &
sub) != PJ_SUCCESS) {
1276 snprintf(refer_to_str,
sizeof(refer_to_str),
"\"%s\" <%s>", disp_name_escaped, tmp_str);
1278 snprintf(refer_to_str,
sizeof(refer_to_str),
"%s", tmp_str);
1285 if (pjsip_xfer_initiate(
sub, pj_cstr(&
tmp, refer_to_str), &tdata) != PJ_SUCCESS) {
1290 if (refer_to_endpoint && rdata->
to_self) {
1302 ast_debug(1,
"Sending REFER to '%s' (via endpoint %s) from '%s'\n",
1305 if (pjsip_xfer_send_request(
sub, tdata) == PJ_SUCCESS) {
1312 pjsip_evsub_terminate(
sub, PJ_FALSE);
1345 const pj_str_t str_replaces = {
"Replaces", 8 };
1346 pj_str_t replaces_content;
1347 pjsip_replaces_hdr *replaces;
1351 pj_strdup_with_null(rdata->tp_info.pool, &replaces_content, &replaces_param->value);
1354 if (!(replaces = pjsip_parse_hdr(rdata->tp_info.pool, &str_replaces, replaces_content.ptr,
1355 pj_strlen(&replaces_content), &parsed_len))) {
1356 ast_log(
LOG_ERROR,
"Received REFER request on channel '%s' from endpoint '%s' with invalid Replaces header, rejecting\n",
1362 if ((dlg = pjsip_ua_find_dialog(&replaces->call_id, &replaces->to_tag, &replaces->from_tag, PJ_TRUE))) {
1366 pjsip_dlg_dec_lock(dlg);
1368 if (!other_session) {
1369 ast_debug(3,
"Received REFER request on channel '%s' from endpoint '%s' for local dialog but no session exists on it\n",
1376 ast_log(
LOG_ERROR,
"Received REFER request on channel '%s' from endpoint '%s' for local dialog but could not allocate structure to complete, rejecting\n",
1382 ast_log(
LOG_ERROR,
"Received REFER request on channel '%s' from endpoint '%s' for local dialog but could not defer termination, rejecting\n",
1396 ast_debug(3,
"Attended transfer from '%s' pushed to second channel serializer\n",
1408 ast_log(
LOG_ERROR,
"Received REFER for remote session on channel '%s' from endpoint '%s' but 'external_replaces' extension not found in context %s\n",
1421 ast_log(
LOG_ERROR,
"Received REFER for remote session on channel '%s' from endpoint '%s' but could not defer termination, rejecting\n",
1431 if (response != 200) {
1462 ast_debug(3,
"Channel '%s' from endpoint '%s' attempted blind transfer to a target without extension. Target was set to 's@%s'\n",
1467 ast_log(
LOG_ERROR,
"Channel '%s' from endpoint '%s' attempted blind transfer to '%s@%s' but target does not exist\n",
1479 ast_log(
LOG_ERROR,
"Channel '%s' from endpoint '%s' attempted blind transfer but could not defer termination, rejecting\n",
1489 if (response != 200) {
1524 pjsip_dialog *other_dlg =
NULL;
1525 pjsip_tx_data *packet;
1531 if (pjsip_replaces_verify_request(rdata, &other_dlg, PJ_TRUE, &packet) != PJ_SUCCESS) {
1532 response = packet->msg->line.status.code;
1534 pjsip_tx_data_dec_ref(packet);
1535 goto inv_replace_failed;
1544 pjsip_dlg_dec_lock(other_dlg);
1547 if (
session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
1549 goto inv_replace_failed;
1552 if (!other_session) {
1553 ast_debug(3,
"INVITE with Replaces received on channel '%s' from endpoint '%s', but requested session does not exist\n",
1556 goto inv_replace_failed;
1559 invite.
session = other_session;
1564 goto inv_replace_failed;
1572 ast_debug(3,
"INVITE with Replaces being attempted. '%s' --> '%s'\n",
1613 ast_debug(3,
"INVITE with Replaces successfully completed.\n");
1615 ast_debug(3,
"INVITE with Replaces failed on channel '%s', hanging up with cause '%d'\n",
1626 if (
session->inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
1627 ast_debug(3,
"INVITE with Replaces failed on channel '%s', sending response of '%d'\n",
1632 if (pjsip_inv_end_session(
session->inv_session, response,
NULL, &packet) == PJ_SUCCESS
1637 ast_debug(3,
"INVITE with Replaces in-dialog on channel '%s', hanging up\n",
1647 pjsip_generic_string_hdr *refer_to;
1651 pjsip_sip_uri *target_uri;
1653 pjsip_param *replaces;
1656 static const pj_str_t str_refer_to = {
"Refer-To", 8 };
1657 static const pj_str_t str_refer_to_s = {
"r", 1 };
1658 static const pj_str_t str_replaces = {
"Replaces", 8 };
1663 ast_debug(3,
"Received a REFER on a session with no channel from endpoint '%s'.\n",
1668 if (!
session->endpoint->allowtransfer) {
1676 refer_to = pjsip_msg_find_hdr_by_names(rdata->msg_info.msg, &str_refer_to, &str_refer_to_s,
NULL);
1679 ast_debug(3,
"Received a REFER without Refer-To on channel '%s' from endpoint '%s'\n",
1688 uri_size = pj_strlen(&refer_to->hvalue) + 1;
1692 target = pjsip_parse_uri(rdata->tp_info.pool, uri, uri_size - 1, 0);
1695 || (!PJSIP_URI_SCHEME_IS_SIP(target)
1696 && !PJSIP_URI_SCHEME_IS_SIPS(target))) {
1699 ast_debug(3,
"Received a REFER without a parseable Refer-To ('%s') on channel '%s' from endpoint '%s'\n",
1703 target_uri = pjsip_uri_get_uri(target);
1708 ast_debug(3,
"Could not set up subscription for REFER on channel '%s' from endpoint '%s'\n",
1714 if ((replaces = pjsip_param_find(&target_uri->header_param, &str_replaces)) ||
1715 (replaces = pjsip_param_find(&target_uri->other_param, &str_replaces))) {
1723 pjsip_tx_data *tdata;
1724 const pj_str_t str_refer_sub = {
"Refer-Sub", 9 };
1725 const pj_str_t str_false = {
"false", 5 };
1728 ast_debug(3,
"Progress monitoring not requested for REFER on channel '%s' from endpoint '%s', sending immediate response of '%d'\n",
1731 if (pjsip_dlg_create_response(
session->inv_session->dlg, rdata, response,
NULL, &tdata) != PJ_SUCCESS) {
1736 hdr = (pjsip_hdr*)pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub, &str_false);
1737 pjsip_msg_add_hdr(tdata->msg, hdr);
1739 pjsip_dlg_send_response(
session->inv_session->dlg, pjsip_rdata_get_tsx(rdata), tdata);
1740 }
else if (response != 200) {
1757 if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_refer_method())) {
1759 }
else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_invite_method)) {
1782 const char *var_value;
1783 pj_str_t pj_header_name;
1791 pj_cstr(&pj_header_name, header_name);
1792 header = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_header_name,
NULL);
1801 if (pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_invite_method)
1803 ||
session->inv_session->state != PJSIP_INV_STATE_NULL) {
1821 const pj_str_t str_norefersub = {
"norefersub", 10 };
1864 .
requires =
"res_pjsip,res_pjsip_session,res_pjsip_pubsub",
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_alloc(data_size, destructor_fn)
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
@ AST_BRIDGE_TRANSFER_SUCCESS
@ AST_BRIDGE_TRANSFER_INVALID
@ AST_BRIDGE_TRANSFER_FAIL
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Internal Asterisk hangup causes.
#define AST_CAUSE_FAILURE
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
#define ast_channel_lock(chan)
#define ast_channel_ref(c)
Increase channel reference count.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
#define ast_channel_unref(c)
Decrease channel reference count.
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
@ AST_FRAMEHOOK_EVENT_WRITE
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
#define AST_FRAMEHOOK_INTERFACE_VERSION
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
struct ast_sip_endpoint * ast_sip_dialog_get_endpoint(pjsip_dialog *dlg)
Get the endpoint associated with this dialog.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
int ast_sip_thread_is_servant(void)
Determine if the current thread is a SIP servant thread.
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
static char prefix[MAX_PREFIX]
struct ast_frame ast_null_frame
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
Out-of-call refer support.
void ast_refer_var_unref_current(struct ast_refer_var_iterator *iter)
Unref a refer var from inside an iterator loop.
int ast_refer_tech_unregister(const struct ast_refer_tech *tech)
Unregister a refer technology.
const char * ast_refer_get_to(const struct ast_refer *refer)
Retrieve the destination of this refer.
int ast_refer_var_iterator_next(struct ast_refer_var_iterator *iter, const char **name, const char **value)
Get the next variable name and value.
struct ast_refer_var_iterator * ast_refer_var_iterator_init(const struct ast_refer *refer)
Create a new refer variable iterator.
const char * ast_refer_get_from(const struct ast_refer *refer)
Retrieve the source of this refer.
char * ast_refer_get_var_and_unlink(struct ast_refer *refer, const char *name)
Get the specified variable on the refer and unlink it from the container of variables.
struct ast_refer * ast_refer_destroy(struct ast_refer *refer)
Destroy an ast_refer.
const char * ast_refer_get_refer_to(const struct ast_refer *refer)
Get the "refer-to" value of a refer.
int ast_refer_tech_register(const struct ast_refer_tech *tech)
Register a refer technology.
struct ast_refer * ast_refer_ref(struct ast_refer *refer)
Bump a refer's ref count.
int ast_refer_get_to_self(const struct ast_refer *refer)
Retrieve the "to_self" value of this refer.
void ast_refer_var_iterator_destroy(struct ast_refer_var_iterator *iter)
Destroy a refer variable iterator.
struct stasis_forward * sub
struct ast_sip_endpoint * ast_sip_get_endpoint(const char *to, int get_default_outbound, char **uri)
Retrieves an endpoint and URI from the "to" string.
unsigned int ast_sip_get_norefersub(void)
Retrieve the global setting 'norefersub'.
void ast_sip_unregister_service(pjsip_module *module)
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
pjsip_dialog * ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *aor_name, const char *request_user)
General purpose method for creating a UAC dialog with an endpoint.
int ast_sip_rewrite_uri_to_local(pjsip_sip_uri *uri, pjsip_tx_data *tdata)
Replace domain and port of SIP URI to point to (external) signaling address of this Asterisk instance...
int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *tdata, pjsip_tx_data **new_request)
Create a response to an authentication challenge.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
int ast_sip_update_from(pjsip_tx_data *tdata, char *from)
Overwrite fields in the outbound 'From' header.
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
int ast_sip_update_to_uri(pjsip_tx_data *tdata, const char *to)
Replace the To URI in the tdata with the supplied one.
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
#define MAX_RX_CHALLENGES
static int refer_unreference_dialog(void *obj)
static void refer_progress_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
Callback for REFER subscription state changes.
static void add_header_from_channel_var(struct ast_channel *chan, const char *var_name, const char *header_name, pjsip_tx_data *tdata)
Use the value of a channel variable as the value of a SIP header.
static void refer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
static pjsip_module refer_out_of_dialog_module
REFER Out-of-dialog module, used to attach session data structure to subscription.
static struct ast_taskprocessor * refer_serializer
static int xfer_response_code2sip(enum ast_transfer_result xfer_code)
static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static struct refer_data * refer_data_create(const struct ast_refer *refer)
static void refer_progress_notification_destroy(void *obj)
Destructor for REFER Progress notification structure.
static struct refer_progress_notification * refer_progress_notification_alloc(struct refer_progress *progress, int response, pjsip_evsub_state state)
Allocator for REFER Progress notification structure.
static struct ast_sip_session_supplement refer_supplement
static pjsip_module refer_progress_module
REFER Progress module, used to attach REFER progress structure to subscriptions.
static int dlg_releaser_task(void *data)
static enum pjsip_status_code vars_to_headers(const struct ast_refer *refer, pjsip_tx_data *tdata)
static int is_refer_var_blocked(const char *name)
static int refer_incoming_attended_request(struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target_uri, pjsip_param *replaces_param, struct refer_progress *progress)
#define DETERMINE_TRANSFER_CONTEXT(context, session)
static int refer_incoming_blind_request(struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target, struct refer_progress *progress)
static const struct ast_refer_tech refer_tech
static int refer_progress_notify(void *data)
Serialized callback for subscription notification.
static int refer_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static int refer_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
static void refer_blind_callback(struct ast_channel *chan, struct transfer_channel_data *user_data_wrapper, enum ast_transfer_type transfer_type)
Blind transfer callback function.
static int refer_incoming_refer_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static void refer_attended_destroy(void *obj)
Destructor for attended transfer task.
static int sip_refer_send(const struct ast_refer *refer)
static int refer_attended_task(void *data)
Task for attended transfer executed by attended->transferer_second serializer.
static pj_status_t refer_on_tx_request(pjsip_tx_data *tdata)
static void refer_progress_destroy(void *obj)
Destructor for REFER progress sutrcture.
static int refer_send(void *data)
static int defer_termination_cancel_task(void *data)
static int invite_replaces(void *data)
Task for invite replaces.
static void refer_out_of_dialog_destroy(void *obj)
Destructor for REFER out of dialog structure.
static int session_end_if_deferred_task(void *data)
static int load_module(void)
static void refer_progress_framehook_destroy(void *data)
Destroy callback for monitoring framehook.
static int unload_module(void)
static pjsip_uri * get_refer_to_uri(pjsip_tx_data *tdata)
Helper function which returns the name-addr of the Refer-To header or NULL.
static int refer_progress_alloc(struct ast_sip_session *session, pjsip_rx_data *rdata, struct refer_progress **progress)
Internal helper function which sets up a refer progress structure if needed.
static struct ast_frame * refer_progress_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Progress monitoring frame hook - examines frames to determine state of transfer.
static pjsip_evsub_user refer_progress_evsub_cb
Callback structure for subscription.
static void refer_progress_bridge(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct refer_attended * refer_attended_alloc(struct ast_sip_session *transferer, struct ast_sip_session *transferer_second, struct refer_progress *progress)
Allocator for attended transfer task.
static void refer_data_destroy(void *obj)
struct ast_sip_session * ast_sip_dialog_get_session(pjsip_dialog *dlg)
Retrieves a session from a dialog.
void ast_sip_session_defer_termination_cancel(struct ast_sip_session *session)
Cancel a pending deferred termination.
#define ast_sip_session_register_supplement(supplement)
void ast_sip_session_end_if_deferred(struct ast_sip_session *session)
End the session if it had been previously deferred.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
int ast_sip_session_defer_termination(struct ast_sip_session *session)
Defer local termination of a session until remote side terminates, or an amount of time passes.
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
#define stasis_subscribe_pool(topic, callback, data)
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for ast_channel enter bridge blob messages.
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Blob of data associated with a bridge.
struct ast_channel_snapshot * channel
Structure that contains information about a bridge.
const ast_string_field uniqueid
struct ast_channel_snapshot_base * base
Main Channel structure associated with a channel.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
const char *const name
Name of this refer technology.
An entity with which Asterisk communicates.
A supplement to SIP message processing.
enum ast_sip_supplement_priority priority
A structure describing a SIP session.
struct ast_channel * channel
struct ast_taskprocessor * serializer
Support for dynamic strings.
A ast_taskprocessor structure is a singleton by name.
Structure used to retrieve channel from another session.
struct ast_sip_session * session
Session we want the channel from.
struct ast_channel * channel
Channel from the session (with reference)
struct ast_bridge * bridge
Bridge the channel is in.
Structure for attended transfer task.
struct ast_sip_session * transferer
Transferer session.
struct ast_sip_session * transferer_second
Second transferer session.
struct refer_progress * progress
Optional refer progress structure.
struct ast_channel * transferer_chan
Transferer channel.
Structure for blind transfer callback details.
pjsip_replaces_hdr * replaces
Optional Replaces header.
pjsip_rx_data * rdata
REFER message.
struct refer_progress * progress
Optional progress structure.
unsigned int attended
Attended transfer flag.
const char * context
Context being used for transfer.
pjsip_sip_uri * refer_to
Optional Refer-To header.
int authentication_challenge_count
REFER Progress notification structure.
pjsip_evsub_state state
Subscription state.
int response
SIP response code to send.
struct refer_progress * progress
Refer progress structure to send notification on.
REFER Progress structure.
struct transfer_channel_data * transfer_data
Reference to transfer_channel_data related to the refer.
pjsip_rx_data * rdata
Received packet, used to construct final response in case no subscription exists.
unsigned int refer_blind_progress
Whether to notifies all the progress details on blind transfer.
pjsip_evsub * sub
Subscription to provide updates on.
int subclass
Last received subclass in frame hook.
pjsip_dialog * dlg
Dialog for subscription.
struct stasis_subscription * bridge_sub
Stasis subscription for bridge events.
struct ast_taskprocessor * serializer
Serializer for notifications.
int sent_100
Non-zero if the 100 notify has been sent.
char * transferee
Uniqueid of transferee channel.
int framehook
Frame hook for monitoring REFER progress.
AO2 object that wraps data for transfer_channel_cb.
An API for managing task processing threads that can be shared across modules.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.