Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Functions | Variables
pjsip_session_reason_header.c File Reference
#include "asterisk.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/utils.h"
#include "pjsip_session.h"
Include dependency graph for pjsip_session_reason_header.c:

Go to the source code of this file.

Data Structures

struct  return_reason_data
 

Macros

#define RETURN_REASON_DATASTORE_NAME   "pjsip_session_return_reason"
 

Functions

int ast_sip_session_add_reason_header (struct ast_sip_session *session, const char *protocol, int code, const char *text)
 Adds a Reason header in the next reponse to an incoming INVITE. More...
 
void pjsip_reason_header_load (void)
 
void pjsip_reason_header_unload (void)
 
static void reason_header_outgoing_response (struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 
static void return_reason_destructor (void *obj)
 

Variables

static const pj_str_t reason_hdr_str = { "Reason", 6}
 
static struct ast_sip_session_supplement reason_header_supplement
 
static struct ast_datastore_info return_reason_info
 

Macro Definition Documentation

◆ RETURN_REASON_DATASTORE_NAME

#define RETURN_REASON_DATASTORE_NAME   "pjsip_session_return_reason"

Definition at line 43 of file pjsip_session_reason_header.c.

Function Documentation

◆ ast_sip_session_add_reason_header()

int ast_sip_session_add_reason_header ( struct ast_sip_session session,
const char *  protocol,
int  code,
const char *  text 
)

Adds a Reason header in the next reponse to an incoming INVITE.

Parameters
sessionThe session
protocolUsually "SIP" but may be "STIR" for stir-shaken
codeSIP response code
textReason string
Return values
0the header is accepted
-1the header is rejected

Definition at line 123 of file pjsip_session_reason_header.c.

125{
126 struct return_reason_data *rr;
127 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
128 const char *tag = ast_sip_session_get_name(session);
129 SCOPE_ENTER(4, "%s: Adding Reason header %s %d %s\n",
130 tag, S_OR(protocol,"<missing protocol>"),
131 code, S_OR(text, "<missing text>"));
132
133 if (ast_strlen_zero(protocol) || !text) {
134 SCOPE_EXIT_RTN_VALUE(-1, "%s: Missing protocol or text\n", tag);
135 }
136 rr = ast_calloc(1, sizeof(*rr));
137 if (!rr) {
138 SCOPE_EXIT_RTN_VALUE(-1, "%s: Failed to allocate datastore\n", tag);
139 }
143 rr->response_code = code;
145 datastore->data = rr;
146 if (ast_sip_session_add_datastore(session, datastore) != 0) {
148 "%s: Failed to add datastore to session\n", tag);
149 }
150
151 SCOPE_EXIT_RTN_VALUE(0, "%s: Done\n", tag);
152}
char * text
Definition: app_queue.c:1668
static struct ast_mansession session
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
static struct ast_datastore_info return_reason_info
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define NULL
Definition: resample.c:96
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_cleanup, ast_calloc, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), ast_strdup, ast_strlen_zero(), NULL, return_reason_data::protocol, RAII_VAR, return_reason_data::response_code, return_reason_data::response_str, return_reason_info, S_OR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, text, and ast_datastore_info::type.

Referenced by process_failure().

◆ pjsip_reason_header_load()

void pjsip_reason_header_load ( void  )

Definition at line 165 of file pjsip_session_reason_header.c.

166{
168}
static struct ast_sip_session_supplement reason_header_supplement
#define ast_sip_session_register_supplement(supplement)

References ast_sip_session_register_supplement, and reason_header_supplement.

Referenced by load_module().

◆ pjsip_reason_header_unload()

void pjsip_reason_header_unload ( void  )

Definition at line 160 of file pjsip_session_reason_header.c.

161{
163}
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63

References ast_sip_session_unregister_supplement(), and reason_header_supplement.

Referenced by unload_module().

◆ reason_header_outgoing_response()

static void reason_header_outgoing_response ( struct ast_sip_session session,
struct pjsip_tx_data *  tdata 
)
static

Definition at line 49 of file pjsip_session_reason_header.c.

51{
52 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
53 pjsip_generic_string_hdr *reason_hdr;
54 pj_str_t reason_val;
55 RAII_VAR(char *, reason_str, NULL, ast_free);
56 struct return_reason_data *rr = NULL;
57 int rc = 0;
58 struct pjsip_status_line status = tdata->msg->line.status;
59 const char *tag = ast_sip_session_get_name(session);
60 SCOPE_ENTER(3, "%s: Response Code: %d\n", tag,
61 status.code);
62
63 /*
64 * Include the Reason header if this is a provisional
65 * response other than a 100 OR it's a 200.
66 */
67 if (!((PJSIP_IS_STATUS_IN_CLASS(status.code, 100) && status.code != 100) || status.code == 200)) {
68 SCOPE_EXIT_RTN("%s: RC %d not eligible for Reason header\n", tag, status.code);
69 }
70
72 if (!datastore) {
73 SCOPE_EXIT_RTN("%s: No datastore on session. Nothing to do\n", tag);
74 }
75 rr = datastore->data;
76
77 rc = ast_asprintf(&reason_str, "%s; cause=%d; text=\"%s\"",
78 rr->protocol, rr->response_code, rr->response_str);
79 if (rc < 0) {
81 SCOPE_EXIT_RTN("%s: Failed to create reason string\n", tag);
82 }
83 reason_val = pj_str(reason_str);
84
85 /*
86 * pjproject re-uses the tdata for a transaction so if we've
87 * already sent the Reason header, it'll get sent again unless
88 * we remove it. It's possible something else is sending a Reason
89 * header so we need to ensure we only remove our own.
90 */
91 if (rr->already_sent) {
92 ast_trace(3, "%s: Reason already sent\n", tag);
93 reason_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &reason_hdr_str, NULL);
94 while (reason_hdr) {
95 ast_trace(3, "%s: Checking old reason: <" PJSTR_PRINTF_SPEC "> - <" PJSTR_PRINTF_SPEC "> \n",
96 tag,
97 PJSTR_PRINTF_VAR(reason_hdr->hvalue), PJSTR_PRINTF_VAR(reason_val));
98 if (pj_strcmp(&reason_hdr->hvalue, &reason_val) == 0) {
99 ast_trace(3, "%s: MATCH. Cleaning up old reason\n", tag);
100 pj_list_erase(reason_hdr);
101 break;
102 }
103 reason_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &reason_hdr_str, reason_hdr->next);
104 }
106 SCOPE_EXIT_RTN("%s: Done\n", tag);
107 }
108
109 reason_hdr = pjsip_generic_string_hdr_create(tdata->pool, &reason_hdr_str, &reason_val);
110 if (reason_hdr) {
111 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)reason_hdr);
112 rr->already_sent = 1;
113 ast_trace(1, "%s: Created reason header: Reason: %s\n",
114 tag, reason_str);
115 } else {
116 ast_trace(1, "%s: Failed to create reason header: Reason: %s\n",
117 tag, reason_str);
118 }
119
120 SCOPE_EXIT_RTN("%s: Done\n", tag);
121}
jack_status_t status
Definition: app_jack.c:146
#define ast_free(a)
Definition: astmm.h:180
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define SCOPE_EXIT_RTN(...)
#define ast_trace(level,...)
static const pj_str_t reason_hdr_str
#define RETURN_REASON_DATASTORE_NAME
#define PJSTR_PRINTF_VAR(_v)
Definition: res_pjsip.h:72
#define PJSTR_PRINTF_SPEC
Definition: res_pjsip.h:71
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.

References return_reason_data::already_sent, ao2_cleanup, ast_asprintf, ast_free, ast_sip_session_get_datastore(), ast_sip_session_get_name(), ast_sip_session_remove_datastore(), ast_trace, NULL, PJSTR_PRINTF_SPEC, PJSTR_PRINTF_VAR, return_reason_data::protocol, RAII_VAR, reason_hdr_str, return_reason_data::response_code, return_reason_data::response_str, RETURN_REASON_DATASTORE_NAME, SCOPE_ENTER, SCOPE_EXIT_RTN, session, and status.

◆ return_reason_destructor()

static void return_reason_destructor ( void *  obj)
static

Definition at line 33 of file pjsip_session_reason_header.c.

34{
35 struct return_reason_data *rr = obj;
36 SCOPE_ENTER(3, "Destroying RR");
37 ast_free(rr->protocol);
39 ast_free(rr);
40 SCOPE_EXIT("Done");
41}
#define SCOPE_EXIT(...)

References ast_free, return_reason_data::protocol, return_reason_data::response_str, SCOPE_ENTER, and SCOPE_EXIT.

Variable Documentation

◆ reason_hdr_str

const pj_str_t reason_hdr_str = { "Reason", 6}
static

Definition at line 24 of file pjsip_session_reason_header.c.

Referenced by reason_header_outgoing_response().

◆ reason_header_supplement

struct ast_sip_session_supplement reason_header_supplement
static
Initial value:
= {
.method = "INVITE",
.outgoing_response = reason_header_outgoing_response,
}
static void reason_header_outgoing_response(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition: res_pjsip.h:3185

Definition at line 154 of file pjsip_session_reason_header.c.

Referenced by pjsip_reason_header_load(), and pjsip_reason_header_unload().

◆ return_reason_info

struct ast_datastore_info return_reason_info
static
Initial value:
= {
}
static void return_reason_destructor(void *obj)

Definition at line 44 of file pjsip_session_reason_header.c.

Referenced by ast_sip_session_add_reason_header().