Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
res_pjsip_messaging.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include "asterisk/message.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/uri.h"
Include dependency graph for res_pjsip_messaging.c:

Go to the source code of this file.

Data Structures

struct  msg_data
 

Macros

#define MAX_BODY_SIZE   1024
 
#define MAX_HDR_SIZE   512
 
#define MAX_USER_SIZE   128
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static enum pjsip_status_code check_content_type (const pjsip_rx_data *rdata)
 
static enum pjsip_status_code check_content_type_in_dialog (const pjsip_rx_data *rdata)
 
static int headers_to_vars (const pjsip_rx_data *rdata, struct ast_msg *msg)
 
static int incoming_in_dialog_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static int is_msg_var_blocked (const char *name)
 
static int load_module (void)
 
static pj_bool_t module_on_rx_request (pjsip_rx_data *rdata)
 
static struct msg_datamsg_data_create (const struct ast_msg *msg, const char *destination, const char *from)
 
static void msg_data_destroy (void *obj)
 
static int msg_send (void *data)
 
static int print_body (pjsip_rx_data *rdata, char *buf, int len)
 
static enum pjsip_status_code rx_data_to_ast_msg (pjsip_rx_data *rdata, struct ast_msg *msg)
 
static pj_status_t send_response (pjsip_rx_data *rdata, enum pjsip_status_code code, pjsip_dialog *dlg, pjsip_transaction *tsx)
 
static int sip_msg_send (const struct ast_msg *msg, const char *destination, const char *from)
 
static char * sip_to_pjsip (char *buf, int size, int capacity)
 
static int unload_module (void)
 
static void update_content_type (pjsip_tx_data *tdata, struct ast_msg *msg, struct ast_sip_body *body)
 
static int update_to_display_name (pjsip_tx_data *tdata, char *to)
 
static enum pjsip_status_code vars_to_headers (const struct ast_msg *msg, pjsip_tx_data *tdata)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Messaging 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 = 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_taskprocessormessage_serializer
 
static pjsip_module messaging_module
 
static struct ast_sip_session_supplement messaging_supplement
 
static const struct ast_msg_tech msg_tech
 
const pjsip_method pjsip_message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} }
 

Macro Definition Documentation

◆ MAX_BODY_SIZE

#define MAX_BODY_SIZE   1024

Definition at line 137 of file res_pjsip_messaging.c.

◆ MAX_HDR_SIZE

#define MAX_HDR_SIZE   512

Definition at line 136 of file res_pjsip_messaging.c.

◆ MAX_USER_SIZE

#define MAX_USER_SIZE   128

Definition at line 138 of file res_pjsip_messaging.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 992 of file res_pjsip_messaging.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 992 of file res_pjsip_messaging.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 992 of file res_pjsip_messaging.c.

◆ check_content_type()

static enum pjsip_status_code check_content_type ( const pjsip_rx_data *  rdata)
static

Definition at line 151 of file res_pjsip_messaging.c.

152{
153 int res;
154 if (rdata->msg_info.msg->body && rdata->msg_info.msg->body->len) {
156 &rdata->msg_info.msg->body->content_type, "text", "plain");
157 } else {
158 res = rdata->msg_info.ctype &&
160 &rdata->msg_info.ctype->media, "text", "plain");
161 }
162
163 return res ? PJSIP_SC_OK : PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;
164}
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
Checks if the given content type matches type/subtype.
Definition: res_pjsip.c:2248

References ast_sip_is_content_type().

Referenced by module_on_rx_request().

◆ check_content_type_in_dialog()

static enum pjsip_status_code check_content_type_in_dialog ( const pjsip_rx_data *  rdata)
static

Definition at line 175 of file res_pjsip_messaging.c.

176{
177 int res = PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;
178 static const pj_str_t text = { "text", 4};
179 static const pj_str_t application = { "application", 11};
180
181 if (!(rdata->msg_info.msg->body && rdata->msg_info.msg->body->len > 0)) {
182 return res;
183 }
184
185 /* We'll accept any text/ or application/ content type */
186 if (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0
187 || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0) {
188 res = PJSIP_SC_OK;
189 } else if (rdata->msg_info.ctype
190 && (pj_stricmp(&rdata->msg_info.ctype->media.type, &text) == 0
191 || pj_stricmp(&rdata->msg_info.ctype->media.type, &application) == 0)) {
192 res = PJSIP_SC_OK;
193 }
194
195 return res;
196}
char * text
Definition: app_queue.c:1639

References text.

Referenced by incoming_in_dialog_request().

◆ headers_to_vars()

static int headers_to_vars ( const pjsip_rx_data *  rdata,
struct ast_msg msg 
)
static

Definition at line 310 of file res_pjsip_messaging.c.

311{
312 char *c;
313 char name[MAX_HDR_SIZE];
314 char buf[MAX_HDR_SIZE];
315 int res = 0;
316 pjsip_hdr *h = rdata->msg_info.msg->hdr.next;
317 pjsip_hdr *end= &rdata->msg_info.msg->hdr;
318
319 while (h != end) {
320 if ((res = pjsip_hdr_print_on(h, buf, sizeof(buf)-1)) > 0) {
321 buf[res] = '\0';
322 if ((c = strchr(buf, ':'))) {
323 ast_copy_string(buf, ast_skip_blanks(c + 1), sizeof(buf));
324 }
325
326 ast_copy_pj_str(name, &h->name, sizeof(name));
327 if ((res = ast_msg_set_var(msg, name, buf)) != 0) {
328 break;
329 }
330 }
331 h = h->next;
332 }
333 return 0;
334}
char * end
Definition: eagi_proxy.c:73
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static const char name[]
Definition: format_mp3.c:68
int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message going to the dialplan.
Definition: main/message.c:629
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 MAX_HDR_SIZE
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
static struct test_val c

References ast_copy_pj_str(), ast_copy_string(), ast_msg_set_var(), ast_skip_blanks(), buf, c, end, MAX_HDR_SIZE, and name.

Referenced by rx_data_to_ast_msg().

◆ incoming_in_dialog_request()

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

Definition at line 838 of file res_pjsip_messaging.c.

839{
840 enum pjsip_status_code code;
841 int rc;
842 pjsip_dialog *dlg = session->inv_session->dlg;
843 pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
844 struct ast_msg_data *msg;
845 struct ast_party_caller *caller;
846 pjsip_name_addr *name_addr;
847 size_t from_len;
848 size_t to_len;
849 struct ast_msg_data_attribute attrs[4];
850 int pos = 0;
851 int body_pos;
852
853 if (!session->channel) {
854 send_response(rdata, PJSIP_SC_NOT_FOUND, dlg, tsx);
855 return 0;
856 }
857
858 code = check_content_type_in_dialog(rdata);
859 if (code != PJSIP_SC_OK) {
860 send_response(rdata, code, dlg, tsx);
861 return 0;
862 }
863
864 caller = ast_channel_caller(session->channel);
865
866 name_addr = (pjsip_name_addr *) rdata->msg_info.from->uri;
867 from_len = pj_strlen(&name_addr->display);
868 if (from_len) {
869 attrs[pos].type = AST_MSG_DATA_ATTR_FROM;
870 from_len++;
871 attrs[pos].value = ast_alloca(from_len);
872 ast_copy_pj_str(attrs[pos].value, &name_addr->display, from_len);
873 pos++;
874 } else if (caller->id.name.valid && !ast_strlen_zero(caller->id.name.str)) {
875 attrs[pos].type = AST_MSG_DATA_ATTR_FROM;
876 attrs[pos].value = caller->id.name.str;
877 pos++;
878 }
879
880 name_addr = (pjsip_name_addr *) rdata->msg_info.to->uri;
881 to_len = pj_strlen(&name_addr->display);
882 if (to_len) {
883 attrs[pos].type = AST_MSG_DATA_ATTR_TO;
884 to_len++;
885 attrs[pos].value = ast_alloca(to_len);
886 ast_copy_pj_str(attrs[pos].value, &name_addr->display, to_len);
887 pos++;
888 }
889
890 attrs[pos].type = AST_MSG_DATA_ATTR_CONTENT_TYPE;
891 attrs[pos].value = ast_alloca(rdata->msg_info.msg->body->content_type.type.slen
892 + rdata->msg_info.msg->body->content_type.subtype.slen + 2);
893 sprintf(attrs[pos].value, "%.*s/%.*s",
894 (int)rdata->msg_info.msg->body->content_type.type.slen,
895 rdata->msg_info.msg->body->content_type.type.ptr,
896 (int)rdata->msg_info.msg->body->content_type.subtype.slen,
897 rdata->msg_info.msg->body->content_type.subtype.ptr);
898 pos++;
899
900 body_pos = pos;
901 attrs[pos].type = AST_MSG_DATA_ATTR_BODY;
902 attrs[pos].value = ast_malloc(rdata->msg_info.msg->body->len + 1);
903 if (!attrs[pos].value) {
904 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
905 return 0;
906 }
907 ast_copy_string(attrs[pos].value, rdata->msg_info.msg->body->data, rdata->msg_info.msg->body->len + 1);
908 pos++;
909
911 if (!msg) {
912 ast_free(attrs[body_pos].value);
913 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
914 return 0;
915 }
916
917 ast_debug(1, "Received in-dialog MESSAGE from '%s:%s': %s %s\n",
919 ast_channel_name(session->channel),
922
923 rc = ast_msg_data_queue_frame(session->channel, msg);
924 ast_free(attrs[body_pos].value);
925 ast_free(msg);
926 if (rc != 0) {
927 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
928 } else {
929 send_response(rdata, PJSIP_SC_ACCEPTED, dlg, tsx);
930 }
931
932 return 0;
933}
static struct ast_mansession session
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
int ast_msg_data_queue_frame(struct ast_channel *channel, struct ast_msg_data *msg)
Queue an AST_FRAME_TEXT_DATA frame containing an ast_msg_data structure.
@ AST_MSG_DATA_ATTR_BODY
Definition: message.h:458
@ AST_MSG_DATA_ATTR_TO
Definition: message.h:455
@ AST_MSG_DATA_ATTR_FROM
Definition: message.h:456
@ AST_MSG_DATA_ATTR_CONTENT_TYPE
Definition: message.h:457
@ AST_MSG_DATA_SOURCE_TYPE_IN_DIALOG
Definition: message.h:449
#define ast_debug(level,...)
Log a DEBUG message.
static enum pjsip_status_code check_content_type_in_dialog(const pjsip_rx_data *rdata)
static pj_status_t send_response(pjsip_rx_data *rdata, enum pjsip_status_code code, pjsip_dialog *dlg, pjsip_transaction *tsx)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure used to transport a message through the frame core.
Caller Party information.
Definition: channel.h:418
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
char * str
Subscriber name (Malloced)
Definition: channel.h:264
int value
Definition: syslog.c:37

References ast_alloca, ast_channel_caller(), ast_channel_name(), ast_copy_pj_str(), ast_copy_string(), ast_debug, ast_free, ast_malloc, ast_msg_data_alloc(), AST_MSG_DATA_ATTR_BODY, AST_MSG_DATA_ATTR_CONTENT_TYPE, AST_MSG_DATA_ATTR_FROM, AST_MSG_DATA_ATTR_TO, ast_msg_data_get_attribute(), ast_msg_data_queue_frame(), AST_MSG_DATA_SOURCE_TYPE_IN_DIALOG, ast_strlen_zero(), check_content_type_in_dialog(), ast_party_caller::id, ast_party_id::name, send_response(), session, ast_party_name::str, ast_msg_data_attribute::type, ast_party_name::valid, ast_msg_data_attribute::value, and value.

◆ is_msg_var_blocked()

static int is_msg_var_blocked ( const char *  name)
static

Definition at line 240 of file res_pjsip_messaging.c.

241{
242 int i;
243
244 /* Don't block the Max-Forwards header because the user can override it */
245 static const char *hdr[] = {
246 "To",
247 "From",
248 "Via",
249 "Route",
250 "Contact",
251 "Call-ID",
252 "CSeq",
253 "Allow",
254 "Content-Length",
255 "Content-Type",
256 "Request-URI",
257 };
258
259 for (i = 0; i < ARRAY_LEN(hdr); ++i) {
260 if (!strcasecmp(name, hdr[i])) {
261 /* Block addition of this header. */
262 return 1;
263 }
264 }
265 return 0;
266}
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, and name.

Referenced by vars_to_headers().

◆ load_module()

static int load_module ( void  )
static

Definition at line 947 of file res_pjsip_messaging.c.

948{
949 if (ast_sip_register_service(&messaging_module) != PJ_SUCCESS) {
951 }
952
953 if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(),
954 NULL, PJSIP_H_ALLOW, NULL, 1,
955 &pjsip_message_method.name) != PJ_SUCCESS) {
956
959 }
960
964 }
965
967 if (!message_serializer) {
971 }
972
975}
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
Definition: res_pjsip.c:2094
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
int ast_msg_tech_register(const struct ast_msg_tech *tech)
Register a message technology.
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:133
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:117
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:520
static struct ast_sip_session_supplement messaging_supplement
static pjsip_module messaging_module
static struct ast_taskprocessor * message_serializer
static const struct ast_msg_tech msg_tech
const pjsip_method pjsip_message_method
#define ast_sip_session_register_supplement(supplement)
#define NULL
Definition: resample.c:96

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_msg_tech_register(), ast_msg_tech_unregister(), ast_sip_create_serializer(), ast_sip_get_pjsip_endpoint(), ast_sip_register_service(), ast_sip_session_register_supplement, ast_sip_unregister_service(), message_serializer, messaging_module, messaging_supplement, msg_tech, NULL, and pjsip_message_method.

◆ module_on_rx_request()

static pj_bool_t module_on_rx_request ( pjsip_rx_data *  rdata)
static

Definition at line 788 of file res_pjsip_messaging.c.

789{
790 enum pjsip_status_code code;
791 struct ast_msg *msg;
792
793 /* if not a MESSAGE, don't handle */
794 if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_message_method)) {
795 return PJ_FALSE;
796 }
797
798 code = check_content_type(rdata);
799 if (code != PJSIP_SC_OK) {
800 send_response(rdata, code, NULL, NULL);
801 return PJ_TRUE;
802 }
803
804 msg = ast_msg_alloc();
805 if (!msg) {
806 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL);
807 return PJ_TRUE;
808 }
809
810 code = rx_data_to_ast_msg(rdata, msg);
811 if (code != PJSIP_SC_OK) {
812 send_response(rdata, code, NULL, NULL);
813 ast_msg_destroy(msg);
814 return PJ_TRUE;
815 }
816
817 if (!ast_msg_has_destination(msg)) {
818 ast_debug(1, "MESSAGE request received, but no handler wanted it\n");
819 send_response(rdata, PJSIP_SC_NOT_FOUND, NULL, NULL);
820 ast_msg_destroy(msg);
821 return PJ_TRUE;
822 }
823
824 /* Send it to the messaging core.
825 *
826 * If we are unable to send a response, the most likely reason is that we
827 * are handling a retransmission of an incoming MESSAGE and were unable to
828 * create a transaction due to a duplicate key. If we are unable to send
829 * a response, we should not queue the message to the dialplan
830 */
831 if (!send_response(rdata, PJSIP_SC_ACCEPTED, NULL, NULL)) {
832 ast_msg_queue(msg);
833 }
834
835 return PJ_TRUE;
836}
struct ast_msg * ast_msg_destroy(struct ast_msg *msg)
Destroy an ast_msg.
Definition: main/message.c:462
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
Definition: main/message.c:951
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: main/message.c:432
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: main/message.c:972
static enum pjsip_status_code check_content_type(const pjsip_rx_data *rdata)
static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct ast_msg *msg)
A message.
Definition: main/message.c:247

References ast_debug, ast_msg_alloc(), ast_msg_destroy(), ast_msg_has_destination(), ast_msg_queue(), check_content_type(), NULL, pjsip_message_method, rx_data_to_ast_msg(), and send_response().

◆ msg_data_create()

static struct msg_data * msg_data_create ( const struct ast_msg msg,
const char *  destination,
const char *  from 
)
static

Definition at line 520 of file res_pjsip_messaging.c.

521{
522 char *uri_params;
523 struct msg_data *mdata = ao2_alloc(sizeof(*mdata), msg_data_destroy);
524
525 if (!mdata) {
526 return NULL;
527 }
528
529 /* typecast to suppress const warning */
530 mdata->msg = ast_msg_ref((struct ast_msg *) msg);
531
532 /* To starts with 'pjsip:' which needs to be removed. */
533 if (!(destination = strchr(destination, ':'))) {
534 ao2_ref(mdata, -1);
535 return NULL;
536 }
537 ++destination;/* Now skip the ':' */
538
540 mdata->from = ast_strdup(from);
541
542 /*
543 * Sometimes from URI can contain URI parameters, so remove them.
544 *
545 * sip:user;user-options@domain;uri-parameters
546 */
547 uri_params = strchr(mdata->from, '@');
548 if (uri_params && (uri_params = strchr(mdata->from, ';'))) {
549 *uri_params = '\0';
550 }
551 return mdata;
552}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
struct ast_msg * ast_msg_ref(struct ast_msg *msg)
Bump a msg's ref count.
Definition: main/message.c:456
static void msg_data_destroy(void *obj)
struct ast_msg * msg

References ao2_alloc, ao2_ref, ast_msg_ref(), ast_strdup, msg_data::destination, msg_data::from, msg_data::msg, msg_data_destroy(), and NULL.

Referenced by sip_msg_send().

◆ msg_data_destroy()

static void msg_data_destroy ( void *  obj)
static

Definition at line 510 of file res_pjsip_messaging.c.

511{
512 struct msg_data *mdata = obj;
513
514 ast_free(mdata->from);
515 ast_free(mdata->destination);
516
517 ast_msg_destroy(mdata->msg);
518}

References ast_free, ast_msg_destroy(), msg_data::destination, msg_data::from, and msg_data::msg.

Referenced by msg_data_create().

◆ msg_send()

static int msg_send ( void *  data)
static

Definition at line 602 of file res_pjsip_messaging.c.

603{
604 struct msg_data *mdata = data; /* The caller holds a reference */
605
606 struct ast_sip_body body = {
607 .type = "text",
608 .subtype = "plain",
609 .body_text = ast_msg_get_body(mdata->msg)
610 };
611
612 pjsip_tx_data *tdata;
613 RAII_VAR(char *, uri, NULL, ast_free);
614 RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
615
616 ast_debug(3, "mdata From: %s msg From: %s mdata Destination: %s msg To: %s\n",
617 mdata->from, ast_msg_get_from(mdata->msg), mdata->destination, ast_msg_get_to(mdata->msg));
618
619 endpoint = ast_sip_get_endpoint(mdata->destination, 1, &uri);
620 if (!endpoint) {
622 "PJSIP MESSAGE - Could not find endpoint '%s' and no default outbound endpoint configured\n",
623 mdata->destination);
624
625 ast_test_suite_event_notify("MSG_ENDPOINT_URI_FAIL",
626 "MdataFrom: %s\r\n"
627 "MsgFrom: %s\r\n"
628 "MdataDestination: %s\r\n"
629 "MsgTo: %s\r\n",
630 mdata->from,
631 ast_msg_get_from(mdata->msg),
632 mdata->destination,
633 ast_msg_get_to(mdata->msg));
634
635 return -1;
636 }
637
638 ast_debug(3, "Request URI: %s\n", uri);
639
640 if (ast_sip_create_request("MESSAGE", NULL, endpoint, uri, NULL, &tdata)) {
641 ast_log(LOG_WARNING, "PJSIP MESSAGE - Could not create request\n");
642 return -1;
643 }
644
645 /* If there was a To in the actual message, */
646 if (!ast_strlen_zero(ast_msg_get_to(mdata->msg))) {
647 char *msg_to = ast_strdupa(ast_msg_get_to(mdata->msg));
648
649 /*
650 * It's possible that the message To was copied from
651 * an incoming MESSAGE in which case it'll have the
652 * pjsip: tech prepended to it. We need to remove it.
653 */
654 if (ast_begins_with(msg_to, "pjsip:")) {
655 msg_to += 6;
656 }
657 ast_sip_update_to_uri(tdata, msg_to);
658 } else {
659 /*
660 * If there was no To in the message, it's still possible
661 * that there is a display name in the mdata To. If so,
662 * we'll copy the URI display name to the tdata To.
663 */
664 update_to_display_name(tdata, uri);
665 }
666
667 if (!ast_strlen_zero(mdata->from)) {
668 ast_sip_update_from(tdata, mdata->from);
669 } else if (!ast_strlen_zero(ast_msg_get_from(mdata->msg))) {
670 ast_sip_update_from(tdata, (char *)ast_msg_get_from(mdata->msg));
671 }
672
673#ifdef TEST_FRAMEWORK
674 {
675 pjsip_name_addr *tdata_name_addr;
676 pjsip_sip_uri *tdata_sip_uri;
677 char touri[128];
678 char fromuri[128];
679
680 tdata_name_addr = (pjsip_name_addr *) PJSIP_MSG_TO_HDR(tdata->msg)->uri;
681 tdata_sip_uri = pjsip_uri_get_uri(tdata_name_addr->uri);
682 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, touri, sizeof(touri));
683 tdata_name_addr = (pjsip_name_addr *) PJSIP_MSG_FROM_HDR(tdata->msg)->uri;
684 tdata_sip_uri = pjsip_uri_get_uri(tdata_name_addr->uri);
685 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, fromuri, sizeof(fromuri));
686
687 ast_test_suite_event_notify("MSG_FROMTO_URI",
688 "MdataFrom: %s\r\n"
689 "MsgFrom: %s\r\n"
690 "MdataDestination: %s\r\n"
691 "MsgTo: %s\r\n"
692 "Endpoint: %s\r\n"
693 "RequestURI: %s\r\n"
694 "ToURI: %s\r\n"
695 "FromURI: %s\r\n",
696 mdata->from,
697 ast_msg_get_from(mdata->msg),
698 mdata->destination,
699 ast_msg_get_to(mdata->msg),
701 uri,
702 touri,
703 fromuri
704 );
705 }
706#endif
707
708 update_content_type(tdata, mdata->msg, &body);
709
710 if (ast_sip_add_body(tdata, &body)) {
711 pjsip_tx_data_dec_ref(tdata);
712 ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not add body to request\n");
713 return -1;
714 }
715
716 /*
717 * This copies any headers set with MESSAGE_DATA() to the
718 * tdata.
719 */
720 vars_to_headers(mdata->msg, tdata);
721
722 ast_debug(1, "Sending message to '%s' (via endpoint %s) from '%s'\n",
723 uri, ast_sorcery_object_get_id(endpoint), mdata->from);
724
725 if (ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL)) {
726 ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not send request\n");
727 return -1;
728 }
729
730 return 0;
731}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define LOG_ERROR
#define LOG_WARNING
const char * ast_msg_get_from(const struct ast_msg *msg)
Retrieve the source of this message.
Definition: main/message.c:550
const char * ast_msg_get_to(const struct ast_msg *msg)
Retrieve the destination of this message.
Definition: main/message.c:555
const char * ast_msg_get_body(const struct ast_msg *msg)
Get the body of a message.
Definition: main/message.c:545
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.
Definition: res_pjsip.c:3249
int ast_sip_update_from(pjsip_tx_data *tdata, char *from)
Overwrite fields in the outbound 'From' header.
Definition: res_pjsip.c:3383
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.
Definition: res_pjsip.c:1979
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition: res_pjsip.c:2052
int ast_sip_update_to_uri(pjsip_tx_data *tdata, const char *to)
Replace the To URI in the tdata with the supplied one.
Definition: res_pjsip.c:3323
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition: res_pjsip.c:1435
static enum pjsip_status_code vars_to_headers(const struct ast_msg *msg, pjsip_tx_data *tdata)
static void update_content_type(pjsip_tx_data *tdata, struct ast_msg *msg, struct ast_sip_body *body)
static int update_to_display_name(pjsip_tx_data *tdata, char *to)
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
SIP body description.
Definition: res_pjsip.h:2325
const char * type
Definition: res_pjsip.h:2327
An entity with which Asterisk communicates.
Definition: res_pjsip.h:963
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#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_begins_with(), ast_debug, ast_free, ast_log, ast_msg_get_body(), ast_msg_get_from(), ast_msg_get_to(), ast_sip_add_body(), ast_sip_create_request(), ast_sip_get_endpoint(), ast_sip_send_request(), ast_sip_update_from(), ast_sip_update_to_uri(), ast_sorcery_object_get_id(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, msg_data::destination, msg_data::from, LOG_ERROR, LOG_WARNING, msg_data::msg, NULL, RAII_VAR, ast_sip_body::type, update_content_type(), update_to_display_name(), and vars_to_headers().

Referenced by sip_msg_send().

◆ print_body()

static int print_body ( pjsip_rx_data *  rdata,
char *  buf,
int  len 
)
static

Definition at line 347 of file res_pjsip_messaging.c.

348{
349 int res;
350
351 if (!rdata->msg_info.msg->body || !rdata->msg_info.msg->body->len) {
352 return 0;
353 }
354
355 if ((res = rdata->msg_info.msg->body->print_body(
356 rdata->msg_info.msg->body, buf, len)) < 0) {
357 return res;
358 }
359
360 /* remove any trailing carriage return/line feeds */
361 while (res > 0 && ((buf[--res] == '\r') || (buf[res] == '\n')));
362
363 buf[++res] = '\0';
364
365 return res;
366}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References buf, and len().

Referenced by rx_data_to_ast_msg().

◆ rx_data_to_ast_msg()

static enum pjsip_status_code rx_data_to_ast_msg ( pjsip_rx_data *  rdata,
struct ast_msg msg 
)
static

Definition at line 418 of file res_pjsip_messaging.c.

419{
420 RAII_VAR(struct ast_sip_endpoint *, endpt, NULL, ao2_cleanup);
421 pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
422 pjsip_name_addr *name_addr;
423 char buf[MAX_BODY_SIZE];
424 const char *field;
425 const char *context;
426 char exten[AST_MAX_EXTENSION];
427 int res = 0;
428 int size;
429
430 if (!ast_sip_is_allowed_uri(ruri)) {
431 return PJSIP_SC_UNSUPPORTED_URI_SCHEME;
432 }
433
435
436 /*
437 * We may want to match in the dialplan without any user
438 * options getting in the way.
439 */
441
442 endpt = ast_pjsip_rdata_get_endpoint(rdata);
443 ast_assert(endpt != NULL);
444
445 context = S_OR(endpt->message_context, endpt->context);
446 res |= ast_msg_set_context(msg, "%s", context);
447 res |= ast_msg_set_exten(msg, "%s", exten);
448
449 /* to header */
450 name_addr = (pjsip_name_addr *)rdata->msg_info.to->uri;
451 size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf) - 1);
452 if (size <= 0) {
453 return PJSIP_SC_INTERNAL_SERVER_ERROR;
454 }
455 buf[size] = '\0';
456 res |= ast_msg_set_to(msg, "%s", sip_to_pjsip(buf, ++size, sizeof(buf) - 1));
457
458 /* from header */
459 name_addr = (pjsip_name_addr *)rdata->msg_info.from->uri;
460 size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf) - 1);
461 if (size <= 0) {
462 return PJSIP_SC_INTERNAL_SERVER_ERROR;
463 }
464 buf[size] = '\0';
465 res |= ast_msg_set_from(msg, "%s", buf);
466
467 field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf) - 1, 3);
468 res |= ast_msg_set_var(msg, "PJSIP_RECVADDR", field);
469
470 switch (rdata->tp_info.transport->key.type) {
471 case PJSIP_TRANSPORT_UDP:
472 case PJSIP_TRANSPORT_UDP6:
473 field = "udp";
474 break;
475 case PJSIP_TRANSPORT_TCP:
476 case PJSIP_TRANSPORT_TCP6:
477 field = "tcp";
478 break;
479 case PJSIP_TRANSPORT_TLS:
480 case PJSIP_TRANSPORT_TLS6:
481 field = "tls";
482 break;
483 default:
484 field = rdata->tp_info.transport->type_name;
485 }
486 ast_msg_set_var(msg, "PJSIP_TRANSPORT", field);
487
488 if (print_body(rdata, buf, sizeof(buf) - 1) > 0) {
489 res |= ast_msg_set_body(msg, "%s", buf);
490 }
491
492 /* endpoint name */
493 res |= ast_msg_set_tech(msg, "%s", "PJSIP");
494 res |= ast_msg_set_endpoint(msg, "%s", ast_sorcery_object_get_id(endpt));
495 if (endpt->id.self.name.valid) {
496 res |= ast_msg_set_var(msg, "PJSIP_ENDPOINT", endpt->id.self.name.str);
497 }
498
499 res |= headers_to_vars(rdata, msg);
500
501 return !res ? PJSIP_SC_OK : PJSIP_SC_INTERNAL_SERVER_ERROR;
502}
#define AST_MAX_EXTENSION
Definition: channel.h:134
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the 'from' URI of a message.
Definition: main/message.c:479
int ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt,...)
Set the technology's endpoint associated with this message.
Definition: main/message.c:534
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: main/message.c:512
int ast_msg_set_tech(struct ast_msg *msg, const char *fmt,...)
Set the technology associated with this message.
Definition: main/message.c:523
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: main/message.c:501
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the 'body' text of a message (in UTF-8)
Definition: main/message.c:490
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the 'to' URI of a message.
Definition: main/message.c:468
const pj_str_t * ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
Get the user portion of the pjsip_uri.
Definition: res_pjsip.c:3477
int ast_sip_is_allowed_uri(pjsip_uri *uri)
Check whether a pjsip_uri is allowed or not.
Definition: res_pjsip.c:3472
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
Definition: res_pjsip.h:3351
struct ast_sip_endpoint * ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
Get the looked-up endpoint on an out-of dialog request or response.
static int print_body(pjsip_rx_data *rdata, char *buf, int len)
#define MAX_BODY_SIZE
static char * sip_to_pjsip(char *buf, int size, int capacity)
static int headers_to_vars(const pjsip_rx_data *rdata, struct ast_msg *msg)
#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
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_assert, ast_copy_pj_str(), AST_MAX_EXTENSION, ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_endpoint(), ast_msg_set_exten(), ast_msg_set_from(), ast_msg_set_tech(), ast_msg_set_to(), ast_msg_set_var(), ast_pjsip_rdata_get_endpoint(), ast_sip_is_allowed_uri(), ast_sip_pjsip_uri_get_username(), AST_SIP_USER_OPTIONS_TRUNCATE_CHECK, ast_sorcery_object_get_id(), buf, voicemailpwcheck::context, headers_to_vars(), MAX_BODY_SIZE, NULL, print_body(), RAII_VAR, S_OR, and sip_to_pjsip().

Referenced by module_on_rx_request().

◆ send_response()

static pj_status_t send_response ( pjsip_rx_data *  rdata,
enum pjsip_status_code  code,
pjsip_dialog *  dlg,
pjsip_transaction *  tsx 
)
static

Definition at line 759 of file res_pjsip_messaging.c.

761{
762 pjsip_tx_data *tdata;
763 pj_status_t status;
764
765 status = ast_sip_create_response(rdata, code, NULL, &tdata);
766 if (status != PJ_SUCCESS) {
767 ast_log(LOG_ERROR, "Unable to create response (%d)\n", status);
768 return status;
769 }
770
771 if (dlg && tsx) {
772 status = pjsip_dlg_send_response(dlg, tsx, tdata);
773 } else {
774 struct ast_sip_endpoint *endpoint;
775
776 endpoint = ast_pjsip_rdata_get_endpoint(rdata);
777 status = ast_sip_send_stateful_response(rdata, tdata, endpoint);
778 ao2_cleanup(endpoint);
779 }
780
781 if (status != PJ_SUCCESS) {
782 ast_log(LOG_ERROR, "Unable to send response (%d)\n", status);
783 }
784
785 return status;
786}
jack_status_t status
Definition: app_jack.c:146
int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code, struct ast_sip_contact *contact, pjsip_tx_data **p_tdata)
General purpose method for creating a SIP response.
Definition: res_pjsip.c:2468
int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Send a stateful response to an out of dialog request.
Definition: res_pjsip.c:2424

References ao2_cleanup, ast_log, ast_pjsip_rdata_get_endpoint(), ast_sip_create_response(), ast_sip_send_stateful_response(), LOG_ERROR, NULL, and status.

Referenced by incoming_in_dialog_request(), and module_on_rx_request().

◆ sip_msg_send()

static int sip_msg_send ( const struct ast_msg msg,
const char *  destination,
const char *  from 
)
static

Definition at line 733 of file res_pjsip_messaging.c.

734{
735 struct msg_data *mdata;
736 int res;
737
739 ast_log(LOG_ERROR, "SIP MESSAGE - a 'To' URI must be specified\n");
740 return -1;
741 }
742
744 if (!mdata) {
745 return -1;
746 }
747
749 ao2_ref(mdata, -1);
750
751 return res;
752}
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.
Definition: res_pjsip.c:2179
static int msg_send(void *data)
static struct msg_data * msg_data_create(const struct ast_msg *msg, const char *destination, const char *from)

References ao2_ref, ast_log, ast_sip_push_task_wait_serializer(), ast_strlen_zero(), msg_data::destination, msg_data::from, LOG_ERROR, message_serializer, msg_data::msg, msg_data_create(), and msg_send().

◆ sip_to_pjsip()

static char * sip_to_pjsip ( char *  buf,
int  size,
int  capacity 
)
static

Definition at line 377 of file res_pjsip_messaging.c.

378{
379 int count;
380 const char *scheme;
381 char *res = buf;
382
383 /* remove any wrapping brackets */
384 if (*buf == '<') {
385 ++buf;
386 --size;
387 }
388
389 scheme = strncmp(buf, "sip", 3) ? "pjsip:" : "pj";
390 count = strlen(scheme);
391 if (count + size >= capacity) {
392 ast_log(LOG_WARNING, "Unable to handle MESSAGE- incoming uri "
393 "too large for given buffer\n");
394 return NULL;
395 }
396
397 memmove(res + count, buf, size);
398 memcpy(res, scheme, count);
399
400 buf += size - 1;
401 if (*buf == '>') {
402 *buf = '\0';
403 }
404
405 return res;
406}

References ast_log, buf, LOG_WARNING, and NULL.

Referenced by rx_data_to_ast_msg().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 977 of file res_pjsip_messaging.c.

978{
983 return 0;
984}
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
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.

References ast_msg_tech_unregister(), ast_sip_session_unregister_supplement(), ast_sip_unregister_service(), ast_taskprocessor_unreference(), message_serializer, messaging_module, messaging_supplement, and msg_tech.

◆ update_content_type()

static void update_content_type ( pjsip_tx_data *  tdata,
struct ast_msg msg,
struct ast_sip_body body 
)
static

Definition at line 554 of file res_pjsip_messaging.c.

555{
556 static const pj_str_t CONTENT_TYPE = { "Content-Type", sizeof("Content-Type") - 1 };
557
558 const char *content_type = ast_msg_get_var(msg, pj_strbuf(&CONTENT_TYPE));
559 if (content_type) {
560 pj_str_t type, subtype;
561 pjsip_ctype_hdr *parsed;
562
563 /* Let pjsip do the parsing for us */
564 parsed = pjsip_parse_hdr(tdata->pool, &CONTENT_TYPE,
565 ast_strdupa(content_type), strlen(content_type),
566 NULL);
567
568 if (!parsed) {
569 ast_log(LOG_WARNING, "Failed to parse '%s' as a content type. Using text/plain\n",
570 content_type);
571 return;
572 }
573
574 /* We need to turn type and subtype into zero-terminated strings */
575 pj_strdup_with_null(tdata->pool, &type, &parsed->media.type);
576 pj_strdup_with_null(tdata->pool, &subtype, &parsed->media.subtype);
577
578 body->type = pj_strbuf(&type);
579 body->subtype = pj_strbuf(&subtype);
580 }
581}
static const char type[]
Definition: chan_ooh323.c:109
const char * ast_msg_get_var(struct ast_msg *msg, const char *name)
Get the specified variable on the message.
Definition: main/message.c:634
const char * subtype
Definition: res_pjsip.h:2329

References ast_log, ast_msg_get_var(), ast_strdupa, LOG_WARNING, msg_data::msg, NULL, ast_sip_body::subtype, type, and ast_sip_body::type.

Referenced by msg_send().

◆ update_to_display_name()

static int update_to_display_name ( pjsip_tx_data *  tdata,
char *  to 
)
static

Definition at line 207 of file res_pjsip_messaging.c.

208{
209 pjsip_name_addr *parsed_name_addr;
210
211 parsed_name_addr = (pjsip_name_addr *) pjsip_parse_uri(tdata->pool, to, strlen(to),
212 PJSIP_PARSE_URI_AS_NAMEADDR);
213
214 if (parsed_name_addr) {
215 if (pj_strlen(&parsed_name_addr->display)) {
216 pjsip_name_addr *name_addr =
217 (pjsip_name_addr *) PJSIP_MSG_TO_HDR(tdata->msg)->uri;
218
219 pj_strdup(tdata->pool, &name_addr->display, &parsed_name_addr->display);
220
221 }
222 return 0;
223 }
224
225 return -1;
226}

Referenced by msg_send().

◆ vars_to_headers()

static enum pjsip_status_code vars_to_headers ( const struct ast_msg msg,
pjsip_tx_data *  tdata 
)
static

Definition at line 275 of file res_pjsip_messaging.c.

276{
277 const char *name;
278 const char *value;
279 int max_forwards;
281
285 if (!strcasecmp(name, "Max-Forwards")) {
286 /* Decrement Max-Forwards for SIP loop prevention. */
287 if (sscanf(value, "%30d", &max_forwards) != 1 || --max_forwards == 0) {
289 ast_log(LOG_NOTICE, "MESSAGE(Max-Forwards) reached zero. MESSAGE not sent.\n");
290 return -1;
291 }
292 sprintf((char *) value, "%d", max_forwards);
294 } else if (!is_msg_var_blocked(name)) {
296 }
297 }
299
300 return PJSIP_SC_OK;
301}
#define LOG_NOTICE
void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *iter)
Destroy a message variable iterator.
Definition: main/message.c:720
int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
Get the next variable name and value that is set for sending outbound.
Definition: main/message.c:703
void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
Unref a message var from inside an iterator loop.
Definition: main/message.c:714
struct ast_msg_var_iterator * ast_msg_var_iterator_init(const struct ast_msg *msg)
Create a new message variable iterator.
Definition: main/message.c:658
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
static int is_msg_var_blocked(const char *name)
struct ao2_iterator iter
Definition: main/message.c:654
Channel datastore data for max forwards.
Definition: max_forwards.c:29

References ast_log, ast_msg_var_iterator_destroy(), ast_msg_var_iterator_init(), ast_msg_var_iterator_next(), ast_msg_var_unref_current(), ast_sip_add_header(), is_msg_var_blocked(), ast_msg_var_iterator::iter, LOG_NOTICE, name, and value.

Referenced by msg_send().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Messaging 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 = 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 992 of file res_pjsip_messaging.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 992 of file res_pjsip_messaging.c.

◆ message_serializer

struct ast_taskprocessor* message_serializer
static

Definition at line 140 of file res_pjsip_messaging.c.

Referenced by load_module(), sip_msg_send(), and unload_module().

◆ messaging_module

pjsip_module messaging_module
static

Definition at line 940 of file res_pjsip_messaging.c.

Referenced by load_module(), and unload_module().

◆ messaging_supplement

struct ast_sip_session_supplement messaging_supplement
static
Initial value:
= {
.method = "MESSAGE",
.incoming_request = incoming_in_dialog_request
}
static int incoming_in_dialog_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)

Definition at line 935 of file res_pjsip_messaging.c.

Referenced by load_module(), and unload_module().

◆ msg_tech

const struct ast_msg_tech msg_tech
static
Initial value:
= {
.name = "pjsip",
.msg_send = sip_msg_send,
}
static int sip_msg_send(const struct ast_msg *msg, const char *destination, const char *from)

Definition at line 754 of file res_pjsip_messaging.c.

Referenced by action_messagesend(), ast_msg_send(), load_module(), msg_send_exec(), and unload_module().

◆ pjsip_message_method

const pjsip_method pjsip_message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} }

Definition at line 134 of file res_pjsip_messaging.c.

Referenced by load_module(), and module_on_rx_request().