Asterisk - The Open Source Telephony Project  18.5.0
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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 168 of file res_pjsip_rfc3326.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 168 of file res_pjsip_rfc3326.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 168 of file res_pjsip_rfc3326.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 150 of file res_pjsip_rfc3326.c.

References AST_MODULE_LOAD_SUCCESS, and ast_sip_session_register_supplement.

Referenced by unload_module().

151 {
154 }
static struct ast_sip_session_supplement rfc3326_supplement
#define ast_sip_session_register_supplement(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 94 of file res_pjsip_rfc3326.c.

References ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_hangupcause(), ast_debug, ast_sip_add_header(), ast_sorcery_object_get_id(), buf, ast_sip_session::channel, ast_sip_session::endpoint, and ast_sip_endpoint::suppress_q850_reason_headers.

Referenced by rfc3326_outgoing_request(), and rfc3326_outgoing_response().

95 {
96  char buf[20];
97 
99  ast_sip_add_header(tdata, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
100  }
101 
102  if (session->endpoint && session->endpoint->suppress_q850_reason_headers) {
103  ast_debug(1, "A Q.850 '%s'(%i) Reason header was suppresed for endpoint '%s'\n",
104  ast_cause2str((ast_channel_hangupcause(session->channel) & 0x7f)),
105  (ast_channel_hangupcause(session->channel) & 0x7f),
107  } else {
108  snprintf(buf, sizeof(buf), "Q.850;cause=%i", ast_channel_hangupcause(session->channel) & 0x7f);
109  ast_sip_add_header(tdata, "Reason", buf);
110  }
111 }
struct ast_sip_endpoint * endpoint
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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:5063
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_channel * channel
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
int ast_channel_hangupcause(const struct ast_channel *chan)
unsigned int suppress_q850_reason_headers
Definition: res_pjsip.h:899

◆ rfc3326_incoming_request()

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

Definition at line 70 of file res_pjsip_rfc3326.c.

References ast_sip_session::channel, and rfc3326_use_reason_header().

71 {
72  if ((pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_bye_method) &&
73  pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method)) ||
74  !session->channel) {
75  return 0;
76  }
77 
78  rfc3326_use_reason_header(session, rdata);
79 
80  return 0;
81 }
struct ast_channel * channel
static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)

◆ rfc3326_incoming_response()

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

Definition at line 83 of file res_pjsip_rfc3326.c.

References ast_sip_session::channel, and rfc3326_use_reason_header().

84 {
85  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
86 
87  if ((status.code < 300) || !session->channel) {
88  return;
89  }
90 
91  rfc3326_use_reason_header(session, rdata);
92 }
struct ast_channel * channel
static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
jack_status_t status
Definition: app_jack.c:146

◆ rfc3326_outgoing_request()

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

Definition at line 113 of file res_pjsip_rfc3326.c.

References ast_threadpool_serializer_get_current(), ast_sip_session::channel, rfc3326_add_reason_header(), and ast_sip_session::serializer.

114 {
115  if ((pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_bye_method)
116  && pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method))
117  || !session->channel
118  /*
119  * The session->channel has been seen to go away on us between
120  * checks so we must also be running under the call's serializer
121  * thread.
122  */
124  return;
125  }
126 
127  rfc3326_add_reason_header(session, tdata);
128 }
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.
Definition: threadpool.c:1397
struct ast_channel * channel
struct ast_taskprocessor * serializer

◆ rfc3326_outgoing_response()

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

Definition at line 130 of file res_pjsip_rfc3326.c.

References ast_threadpool_serializer_get_current(), ast_sip_session::channel, rfc3326_add_reason_header(), and ast_sip_session::serializer.

131 {
132  struct pjsip_status_line status = tdata->msg->line.status;
133 
134  if (status.code < 300
135  || !session->channel
137  return;
138  }
139 
140  rfc3326_add_reason_header(session, tdata);
141 }
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.
Definition: threadpool.c:1397
struct ast_channel * channel
struct ast_taskprocessor * serializer
jack_status_t status
Definition: app_jack.c:146

◆ 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.

References ast_channel_hangupcause_set(), ast_copy_pj_str(), ast_skip_blanks(), buf, ast_sip_session::channel, NULL, and text.

Referenced by rfc3326_incoming_request(), and rfc3326_incoming_response().

38 {
39  static const pj_str_t str_reason = { "Reason", 6 };
40  pjsip_generic_string_hdr *header;
41  char buf[20];
42  char *cause;
43  char *text;
44  int code;
45 
46  header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, NULL);
47  for (; header;
48  header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, header->next)) {
49  ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
50  cause = ast_skip_blanks(buf);
51 
52  if (strncasecmp(cause, "Q.850", 5) || !(cause = strstr(cause, "cause="))) {
53  continue;
54  }
55 
56  /* If text is present get rid of it */
57  if ((text = strstr(cause, ";"))) {
58  *text = '\0';
59  }
60 
61  if (sscanf(cause, "cause=%30d", &code) != 1) {
62  continue;
63  }
64 
65  ast_channel_hangupcause_set(session->channel, code & 0x7f);
66  break;
67  }
68 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
char * text
Definition: app_queue.c:1508
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:5240
#define NULL
Definition: resample.c:96
struct ast_channel * channel
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 156 of file res_pjsip_rfc3326.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_sip_session_unregister_supplement(), ASTERISK_GPL_KEY, and load_module().

157 {
159  return 0;
160 }
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
static struct ast_sip_session_supplement 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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 168 of file res_pjsip_rfc3326.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 168 of file res_pjsip_rfc3326.c.

◆ rfc3326_supplement

struct ast_sip_session_supplement rfc3326_supplement
static

Definition at line 143 of file res_pjsip_rfc3326.c.