Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Functions | Variables
res_pjsip_rfc3326.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/module.h"
#include "asterisk/causes.h"
#include "asterisk/threadpool.h"
Include dependency graph for res_pjsip_rfc3326.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void rfc3326_add_reason_header (struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 
static int rfc3326_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static void rfc3326_incoming_response (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static void rfc3326_outgoing_request (struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 
static void rfc3326_outgoing_response (struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 
static void rfc3326_use_reason_header (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP RFC3326 Support" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip,res_pjsip_session", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_session_supplement rfc3326_supplement
 

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 187 of file res_pjsip_rfc3326.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 187 of file res_pjsip_rfc3326.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 187 of file res_pjsip_rfc3326.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 169 of file res_pjsip_rfc3326.c.

170{
173}
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
static struct ast_sip_session_supplement rfc3326_supplement
#define ast_sip_session_register_supplement(supplement)

References AST_MODULE_LOAD_SUCCESS, ast_sip_session_register_supplement, and rfc3326_supplement.

◆ rfc3326_add_reason_header()

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

Definition at line 113 of file res_pjsip_rfc3326.c.

114{
115 char buf[20];
116
118 ast_sip_add_header(tdata, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
119 }
120
121 if (session->endpoint && session->endpoint->suppress_q850_reason_headers) {
122 ast_debug(1, "A Q.850 '%s'(%i) Reason header was suppressed for endpoint '%s'\n",
124 (ast_channel_hangupcause(session->channel) & 0x7f),
126 } else {
127 snprintf(buf, sizeof(buf), "Q.850;cause=%i", ast_channel_hangupcause(session->channel) & 0x7f);
128 ast_sip_add_header(tdata, "Reason", buf);
129 }
130}
static struct ast_mansession session
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition causes.h:114
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition channel.c:612
char buf[BUFSIZE]
Definition eagi_proxy.c:66
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition res_pjsip.c:2008
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381

References ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_hangupcause(), ast_debug, ast_sip_add_header(), ast_sorcery_object_get_id(), buf, and session.

Referenced by rfc3326_outgoing_request(), and rfc3326_outgoing_response().

◆ rfc3326_incoming_request()

static int rfc3326_incoming_request ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
)
static

Definition at line 89 of file res_pjsip_rfc3326.c.

90{
91 if ((pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_bye_method) &&
92 pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method)) ||
93 !session->channel) {
94 return 0;
95 }
96
98
99 return 0;
100}
static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)

References rfc3326_use_reason_header(), and session.

◆ rfc3326_incoming_response()

static void rfc3326_incoming_response ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
)
static

Definition at line 102 of file res_pjsip_rfc3326.c.

103{
104 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
105
106 if ((status.code < 300) || !session->channel) {
107 return;
108 }
109
111}
jack_status_t status
Definition app_jack.c:149

References rfc3326_use_reason_header(), session, and status.

◆ rfc3326_outgoing_request()

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

Definition at line 132 of file res_pjsip_rfc3326.c.

133{
134 if ((pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_bye_method)
135 && pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method))
136 || !session->channel
137 /*
138 * The session->channel has been seen to go away on us between
139 * checks so we must also be running under the call's serializer
140 * thread.
141 */
143 return;
144 }
145
147}
static void rfc3326_add_reason_header(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
struct ast_taskprocessor * ast_threadpool_serializer_get_current(void)
Get the threadpool serializer currently associated with this thread.

References ast_threadpool_serializer_get_current(), rfc3326_add_reason_header(), and session.

◆ rfc3326_outgoing_response()

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

Definition at line 149 of file res_pjsip_rfc3326.c.

150{
151 struct pjsip_status_line status = tdata->msg->line.status;
152
153 if (status.code < 300
154 || !session->channel
156 return;
157 }
158
160}

References ast_threadpool_serializer_get_current(), rfc3326_add_reason_header(), session, and status.

◆ rfc3326_use_reason_header()

static void rfc3326_use_reason_header ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
)
static

Definition at line 37 of file res_pjsip_rfc3326.c.

38{
39 static const pj_str_t str_reason = { "Reason", 6 };
40 pjsip_generic_string_hdr *header;
41 char buf[128];
42 char *cause;
43 int code_q850 = 0, code_sip = 0;
44
45 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, NULL);
46 for (; header;
47 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, header->next)) {
48 int cause_q850, cause_sip;
49 struct ast_control_pvt_cause_code *cause_code;
50 int data_size = sizeof(*cause_code);
51
52 ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
53 cause = ast_skip_blanks(buf);
54 cause_q850 = !strncasecmp(cause, "Q.850", 5);
55 cause_sip = !strncasecmp(cause, "SIP", 3);
56 if ((cause_q850 || cause_sip) && (cause = strstr(cause, "cause="))) {
57 int *code = cause_q850 ? &code_q850 : &code_sip;
58 if (sscanf(cause, "cause=%30d", code) != 1) {
59 *code = 0;
60 }
61
62 /* Safe */
63 /* Build and send the tech-specific cause information */
64 /* size of the string making up the cause code is "SIP " + reason length */
65 data_size += 4 + strlen(cause) + 1;
66 cause_code = ast_alloca(data_size);
67 memset(cause_code, 0, data_size);
69 snprintf(cause_code->code, data_size, "SIP %s", cause);
70
71 cause_code->cause_extended = 1;
72 if (code_q850) {
73 cause_code->ast_cause = *code & 0x7;
74 } else if (code_sip) {
76 }
77 ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
78 ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
79 }
80 }
81
82 if (code_q850) {
83 ast_channel_hangupcause_set(session->channel, code_q850 & 0x7f);
84 } else if (code_sip) {
86 }
87}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
const char * ast_channel_name(const struct ast_channel *chan)
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition channel.c:1295
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.
Definition channel.c:4340
#define AST_CHANNEL_NAME
Definition channel.h:173
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
@ AST_CONTROL_PVT_CAUSE_CODE
const int ast_sip_hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition res_pjsip.c:3531
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.
Definition res_pjsip.c:2201
#define NULL
Definition resample.c:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition strings.h:161
struct header * next

References ast_alloca, ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), ast_channel_hangupcause_set(), AST_CHANNEL_NAME, ast_channel_name(), AST_CONTROL_PVT_CAUSE_CODE, ast_copy_pj_str(), ast_copy_string(), ast_queue_control_data(), ast_sip_hangup_sip2cause(), ast_skip_blanks(), buf, ast_control_pvt_cause_code::cause_extended, ast_control_pvt_cause_code::chan_name, ast_control_pvt_cause_code::code, header::next, NULL, and session.

Referenced by rfc3326_incoming_request(), and rfc3326_incoming_response().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 175 of file res_pjsip_rfc3326.c.

176{
178 return 0;
179}
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.

References ast_sip_session_unregister_supplement(), and rfc3326_supplement.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP RFC3326 Support" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip,res_pjsip_session", }
static

Definition at line 187 of file res_pjsip_rfc3326.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 187 of file res_pjsip_rfc3326.c.

◆ rfc3326_supplement

struct ast_sip_session_supplement rfc3326_supplement
static

Definition at line 162 of file res_pjsip_rfc3326.c.

162 {
163 .incoming_request = rfc3326_incoming_request,
164 .incoming_response = rfc3326_incoming_response,
165 .outgoing_request = rfc3326_outgoing_request,
166 .outgoing_response = rfc3326_outgoing_response,
167};
static void rfc3326_outgoing_response(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static void rfc3326_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static void rfc3326_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static int rfc3326_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)

Referenced by load_module(), and unload_module().