Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
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 = 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_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 1021 of file res_pjsip_messaging.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1021 of file res_pjsip_messaging.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1021 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:1768

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.
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 *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 test_val * next
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, name, and test_val::next.

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 867 of file res_pjsip_messaging.c.

868{
869 enum pjsip_status_code code;
870 int rc;
871 pjsip_dialog *dlg = session->inv_session->dlg;
872 pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
873 struct ast_msg_data *msg;
874 struct ast_party_caller *caller;
875 pjsip_name_addr *name_addr;
876 size_t from_len;
877 size_t to_len;
878 struct ast_msg_data_attribute attrs[4];
879 int pos = 0;
880 int body_pos;
881
882 if (!session->channel) {
883 send_response(rdata, PJSIP_SC_NOT_FOUND, dlg, tsx);
884 return 0;
885 }
886
887 code = check_content_type_in_dialog(rdata);
888 if (code != PJSIP_SC_OK) {
889 send_response(rdata, code, dlg, tsx);
890 return 0;
891 }
892
893 caller = ast_channel_caller(session->channel);
894
895 name_addr = (pjsip_name_addr *) rdata->msg_info.from->uri;
896 from_len = pj_strlen(&name_addr->display);
897 if (from_len) {
898 attrs[pos].type = AST_MSG_DATA_ATTR_FROM;
899 from_len++;
900 attrs[pos].value = ast_alloca(from_len);
901 ast_copy_pj_str(attrs[pos].value, &name_addr->display, from_len);
902 pos++;
903 } else if (caller->id.name.valid && !ast_strlen_zero(caller->id.name.str)) {
904 attrs[pos].type = AST_MSG_DATA_ATTR_FROM;
905 attrs[pos].value = caller->id.name.str;
906 pos++;
907 }
908
909 name_addr = (pjsip_name_addr *) rdata->msg_info.to->uri;
910 to_len = pj_strlen(&name_addr->display);
911 if (to_len) {
912 attrs[pos].type = AST_MSG_DATA_ATTR_TO;
913 to_len++;
914 attrs[pos].value = ast_alloca(to_len);
915 ast_copy_pj_str(attrs[pos].value, &name_addr->display, to_len);
916 pos++;
917 }
918
919 attrs[pos].type = AST_MSG_DATA_ATTR_CONTENT_TYPE;
920 attrs[pos].value = ast_alloca(rdata->msg_info.msg->body->content_type.type.slen
921 + rdata->msg_info.msg->body->content_type.subtype.slen + 2);
922 sprintf(attrs[pos].value, "%.*s/%.*s",
923 (int)rdata->msg_info.msg->body->content_type.type.slen,
924 rdata->msg_info.msg->body->content_type.type.ptr,
925 (int)rdata->msg_info.msg->body->content_type.subtype.slen,
926 rdata->msg_info.msg->body->content_type.subtype.ptr);
927 pos++;
928
929 body_pos = pos;
930 attrs[pos].type = AST_MSG_DATA_ATTR_BODY;
931 attrs[pos].value = ast_malloc(rdata->msg_info.msg->body->len + 1);
932 if (!attrs[pos].value) {
933 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
934 return 0;
935 }
936 ast_copy_string(attrs[pos].value, rdata->msg_info.msg->body->data, rdata->msg_info.msg->body->len + 1);
937 pos++;
938
940 if (!msg) {
941 ast_free(attrs[body_pos].value);
942 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
943 return 0;
944 }
945
946 ast_debug(1, "Received in-dialog MESSAGE from '%s:%s': %s %s\n",
948 ast_channel_name(session->channel),
951
952 rc = ast_msg_data_queue_frame(session->channel, msg);
953 ast_free(attrs[body_pos].value);
954 ast_free(msg);
955 if (rc != 0) {
956 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, dlg, tsx);
957 } else {
958 send_response(rdata, PJSIP_SC_ACCEPTED, dlg, tsx);
959 }
960
961 return 0;
962}
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:420
struct ast_party_id id
Caller party ID.
Definition channel.h:422
struct ast_party_name name
Subscriber name.
Definition channel.h:342
unsigned char valid
TRUE if the name information is valid/present.
Definition channel.h:281
char * str
Subscriber name (Malloced)
Definition channel.h:266
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:703

References ARRAY_LEN, and name.

Referenced by vars_to_headers().

◆ load_module()

static int load_module ( void  )
static

Definition at line 976 of file res_pjsip_messaging.c.

977{
978 if (ast_sip_register_service(&messaging_module) != PJ_SUCCESS) {
980 }
981
982 if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(),
983 NULL, PJSIP_H_ALLOW, NULL, 1,
984 &pjsip_message_method.name) != PJ_SUCCESS) {
985
988 }
989
993 }
994
996 if (!message_serializer) {
1000 }
1001
1004}
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 817 of file res_pjsip_messaging.c.

818{
819 enum pjsip_status_code code;
820 struct ast_msg *msg;
821
822 /* if not a MESSAGE, don't handle */
823 if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_message_method)) {
824 return PJ_FALSE;
825 }
826
827 code = check_content_type(rdata);
828 if (code != PJSIP_SC_OK) {
829 send_response(rdata, code, NULL, NULL);
830 return PJ_TRUE;
831 }
832
833 msg = ast_msg_alloc();
834 if (!msg) {
835 send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL);
836 return PJ_TRUE;
837 }
838
839 code = rx_data_to_ast_msg(rdata, msg);
840 if (code != PJSIP_SC_OK) {
841 send_response(rdata, code, NULL, NULL);
842 ast_msg_destroy(msg);
843 return PJ_TRUE;
844 }
845
846 if (!ast_msg_has_destination(msg)) {
847 ast_debug(1, "MESSAGE request received, but no handler wanted it\n");
848 send_response(rdata, PJSIP_SC_NOT_FOUND, NULL, NULL);
849 ast_msg_destroy(msg);
850 return PJ_TRUE;
851 }
852
853 /* Send it to the messaging core.
854 *
855 * If we are unable to send a response, the most likely reason is that we
856 * are handling a retransmission of an incoming MESSAGE and were unable to
857 * create a transaction due to a duplicate key. If we are unable to send
858 * a response, we should not queue the message to the dialplan
859 */
860 if (!send_response(rdata, PJSIP_SC_ACCEPTED, NULL, NULL)) {
861 ast_msg_queue(msg);
862 }
863
864 return PJ_TRUE;
865}
struct ast_msg * ast_msg_destroy(struct ast_msg *msg)
Destroy an ast_msg.
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
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.

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 559 of file res_pjsip_messaging.c.

560{
561 struct msg_data *mdata = ao2_alloc(sizeof(*mdata), msg_data_destroy);
562
563 if (!mdata) {
564 return NULL;
565 }
566
567 /* typecast to suppress const warning */
568 mdata->msg = ast_msg_ref((struct ast_msg *) msg);
569
570 /* To starts with 'pjsip:' which needs to be removed. */
571 if (!(destination = strchr(destination, ':'))) {
572 ao2_ref(mdata, -1);
573 return NULL;
574 }
575 ++destination;/* Now skip the ':' */
576
578 mdata->from = ast_strdup(from);
579
580 return mdata;
581}
#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.
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 549 of file res_pjsip_messaging.c.

550{
551 struct msg_data *mdata = obj;
552
553 ast_free(mdata->from);
554 ast_free(mdata->destination);
555
556 ast_msg_destroy(mdata->msg);
557}

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 631 of file res_pjsip_messaging.c.

632{
633 struct msg_data *mdata = data; /* The caller holds a reference */
634
635 struct ast_sip_body body = {
636 .type = "text",
637 .subtype = "plain",
638 .body_text = ast_msg_get_body(mdata->msg)
639 };
640
641 pjsip_tx_data *tdata;
642 RAII_VAR(char *, uri, NULL, ast_free);
643 RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
644
645 ast_debug(3, "mdata From: %s msg From: %s mdata Destination: %s msg To: %s\n",
646 mdata->from, ast_msg_get_from(mdata->msg), mdata->destination, ast_msg_get_to(mdata->msg));
647
648 endpoint = ast_sip_get_endpoint(mdata->destination, 1, &uri);
649 if (!endpoint) {
651 "PJSIP MESSAGE - Could not find endpoint '%s' and no default outbound endpoint configured\n",
652 mdata->destination);
653
654 ast_test_suite_event_notify("MSG_ENDPOINT_URI_FAIL",
655 "MdataFrom: %s\r\n"
656 "MsgFrom: %s\r\n"
657 "MdataDestination: %s\r\n"
658 "MsgTo: %s\r\n",
659 mdata->from,
660 ast_msg_get_from(mdata->msg),
661 mdata->destination,
662 ast_msg_get_to(mdata->msg));
663
664 return -1;
665 }
666
667 ast_debug(3, "Request URI: %s\n", uri);
668
669 if (ast_sip_create_request("MESSAGE", NULL, endpoint, uri, NULL, &tdata)) {
670 ast_log(LOG_WARNING, "PJSIP MESSAGE - Could not create request\n");
671 return -1;
672 }
673
674 /* If there was a To in the actual message, */
675 if (!ast_strlen_zero(ast_msg_get_to(mdata->msg))) {
676 char *msg_to = ast_strdupa(ast_msg_get_to(mdata->msg));
677
678 /*
679 * It's possible that the message To was copied from
680 * an incoming MESSAGE in which case it'll have the
681 * pjsip: tech prepended to it. We need to remove it.
682 */
683 if (ast_begins_with(msg_to, "pjsip:")) {
684 msg_to += 6;
685 }
686 ast_sip_update_to_uri(tdata, msg_to);
687 } else {
688 /*
689 * If there was no To in the message, it's still possible
690 * that there is a display name in the mdata To. If so,
691 * we'll copy the URI display name to the tdata To.
692 */
693 update_to_display_name(tdata, uri);
694 }
695
696 if (!ast_strlen_zero(mdata->from)) {
697 ast_sip_update_from(tdata, mdata->from);
698 } else if (!ast_strlen_zero(ast_msg_get_from(mdata->msg))) {
699 ast_sip_update_from(tdata, (char *)ast_msg_get_from(mdata->msg));
700 }
701
702#ifdef TEST_FRAMEWORK
703 {
704 pjsip_name_addr *tdata_name_addr;
705 pjsip_sip_uri *tdata_sip_uri;
706 char touri[128];
707 char fromuri[128];
708
709 tdata_name_addr = (pjsip_name_addr *) PJSIP_MSG_TO_HDR(tdata->msg)->uri;
710 tdata_sip_uri = pjsip_uri_get_uri(tdata_name_addr->uri);
711 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, touri, sizeof(touri));
712 tdata_name_addr = (pjsip_name_addr *) PJSIP_MSG_FROM_HDR(tdata->msg)->uri;
713 tdata_sip_uri = pjsip_uri_get_uri(tdata_name_addr->uri);
714 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, fromuri, sizeof(fromuri));
715
716 ast_test_suite_event_notify("MSG_FROMTO_URI",
717 "MdataFrom: %s\r\n"
718 "MsgFrom: %s\r\n"
719 "MdataDestination: %s\r\n"
720 "MsgTo: %s\r\n"
721 "Endpoint: %s\r\n"
722 "RequestURI: %s\r\n"
723 "ToURI: %s\r\n"
724 "FromURI: %s\r\n",
725 mdata->from,
726 ast_msg_get_from(mdata->msg),
727 mdata->destination,
728 ast_msg_get_to(mdata->msg),
730 uri,
731 touri,
732 fromuri
733 );
734 }
735#endif
736
737 update_content_type(tdata, mdata->msg, &body);
738
739 if (ast_sip_add_body(tdata, &body)) {
740 pjsip_tx_data_dec_ref(tdata);
741 ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not add body to request\n");
742 return -1;
743 }
744
745 /*
746 * This copies any headers set with MESSAGE_DATA() to the
747 * tdata.
748 */
749 vars_to_headers(mdata->msg, tdata);
750
751 ast_debug(1, "Sending message to '%s' (via endpoint %s) from '%s'\n",
752 uri, ast_sorcery_object_get_id(endpoint), mdata->from);
753
754 if (ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL)) {
755 ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not send request\n");
756 return -1;
757 }
758
759 return 0;
760}
#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.
const char * ast_msg_get_to(const struct ast_msg *msg)
Retrieve the destination of this message.
const char * ast_msg_get_body(const struct ast_msg *msg)
Get the body of a message.
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:2381
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:2444
const char * type
Definition res_pjsip.h:2446
An entity with which Asterisk communicates.
Definition res_pjsip.h:1051
#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:978

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 pjsip_sip_uri *suri;
424 char *display_name;
425 char buf[MAX_BODY_SIZE];
426 const char *field;
427 const char *context;
428 char exten[AST_MAX_EXTENSION];
429 int res = 0;
430 int size;
431
432 if (!ast_sip_is_allowed_uri(ruri)) {
433 return PJSIP_SC_UNSUPPORTED_URI_SCHEME;
434 }
435
437
438 /*
439 * We may want to match in the dialplan without any user
440 * options getting in the way.
441 */
443
444 endpt = ast_pjsip_rdata_get_endpoint(rdata);
445 ast_assert(endpt != NULL);
446
447 context = S_OR(endpt->message_context, endpt->context);
448 res |= ast_msg_set_context(msg, "%s", context);
449 res |= ast_msg_set_exten(msg, "%s", exten);
450
451 /* to header */
452 name_addr = (pjsip_name_addr *)rdata->msg_info.to->uri;
453 size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf) - 1);
454 if (size <= 0) {
455 return PJSIP_SC_INTERNAL_SERVER_ERROR;
456 }
457 buf[size] = '\0';
458 res |= ast_msg_set_to(msg, "%s", sip_to_pjsip(buf, ++size, sizeof(buf) - 1));
459
460 /*
461 * We need to sanitize the from header's display name
462 * by replacing any control characters, including NULLs,
463 * with spaces. Since the display name is a pj_str_t, we
464 * can't modify it in place, so we need to copy it to a
465 * temporary buffer first. The good news is that we can't
466 * accidentally run over the end of the buffer, even if
467 * there's a NULL in the middle, because the display name
468 * is a pj_str_t and we know its length.
469 */
470 name_addr = (pjsip_name_addr *)rdata->msg_info.from->uri;
471 suri = pjsip_uri_get_uri((pjsip_uri *)name_addr);
472 if (name_addr->display.slen > 0) {
473 int i = 0;
474 char *temp_name = ast_alloca(name_addr->display.slen + 1);
475 for (i = 0; i < name_addr->display.slen; i++) {
476 if (name_addr->display.ptr[i] < 32) {
477 temp_name[i] = ' ';
478 } else {
479 temp_name[i] = name_addr->display.ptr[i];
480 }
481 }
482 temp_name[name_addr->display.slen] = '\0';
483 /*
484 * We need space for each double quote, the display name,
485 * the trailing space and the NULL terminator.
486 */
487 display_name = ast_alloca(name_addr->display.slen + 5);
488 size = sprintf(display_name, "\"%s\" ", temp_name); /* Safe */
489 } else {
490 display_name = "";
491 }
492
493 /*
494 * In the end, the string should look like...
495 * "display name" <scheme:user@host>
496 * If there's no display name, it and its double quotes
497 * will be suppressed.
498 * Note that the port is not included.
499 */
501 display_name,
502 PJSTR_PRINTF_VAR(*pjsip_uri_get_scheme(suri)),
503 PJSTR_PRINTF_VAR(*ast_sip_pjsip_uri_get_username((pjsip_uri *)name_addr)),
504 PJSTR_PRINTF_VAR(*ast_sip_pjsip_uri_get_hostname((pjsip_uri *)name_addr)));
505
506 field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf) - 1, 3);
507 res |= ast_msg_set_var(msg, "PJSIP_RECVADDR", field);
508
509 switch (rdata->tp_info.transport->key.type) {
510 case PJSIP_TRANSPORT_UDP:
511 case PJSIP_TRANSPORT_UDP6:
512 field = "udp";
513 break;
514 case PJSIP_TRANSPORT_TCP:
515 case PJSIP_TRANSPORT_TCP6:
516 field = "tcp";
517 break;
518 case PJSIP_TRANSPORT_TLS:
519 case PJSIP_TRANSPORT_TLS6:
520 field = "tls";
521 break;
522 default:
523 field = rdata->tp_info.transport->type_name;
524 }
525 ast_msg_set_var(msg, "PJSIP_TRANSPORT", field);
526
527 if (print_body(rdata, buf, sizeof(buf) - 1) > 0) {
528 res |= ast_msg_set_body(msg, "%s", buf);
529 }
530
531 /* endpoint name */
532 res |= ast_msg_set_tech(msg, "%s", "PJSIP");
533 res |= ast_msg_set_endpoint(msg, "%s", ast_sorcery_object_get_id(endpt));
534 if (endpt->id.self.name.valid) {
535 res |= ast_msg_set_var(msg, "PJSIP_ENDPOINT", endpt->id.self.name.str);
536 }
537
538 res |= headers_to_vars(rdata, msg);
539
540 return !res ? PJSIP_SC_OK : PJSIP_SC_INTERNAL_SERVER_ERROR;
541}
#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.
int ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt,...)
Set the technology's endpoint associated with this message.
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
int ast_msg_set_tech(struct ast_msg *msg, const char *fmt,...)
Set the technology associated with this message.
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the 'body' text of a message (in UTF-8)
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the 'to' URI of a message.
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:3504
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.
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition res_pjsip.c:3496
#define PJSTR_PRINTF_VAR(_v)
Definition res_pjsip.h:72
#define PJSTR_PRINTF_SPEC
Definition res_pjsip.h:71
static int print_body(pjsip_rx_data *rdata, char *buf, int len)
#define MAX_BODY_SIZE
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:776

References ao2_cleanup, ast_alloca, 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_hostname(), ast_sip_pjsip_uri_get_username(), AST_SIP_USER_OPTIONS_TRUNCATE_CHECK, ast_sorcery_object_get_id(), buf, headers_to_vars(), MAX_BODY_SIZE, NULL, PJSTR_PRINTF_SPEC, PJSTR_PRINTF_VAR, print_body(), RAII_VAR, and S_OR.

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 788 of file res_pjsip_messaging.c.

790{
791 pjsip_tx_data *tdata;
792 pj_status_t status;
793
794 status = ast_sip_create_response(rdata, code, NULL, &tdata);
795 if (status != PJ_SUCCESS) {
796 ast_log(LOG_ERROR, "Unable to create response (%d)\n", status);
797 return status;
798 }
799
800 if (dlg && tsx) {
801 status = pjsip_dlg_send_response(dlg, tsx, tdata);
802 } else {
803 struct ast_sip_endpoint *endpoint;
804
805 endpoint = ast_pjsip_rdata_get_endpoint(rdata);
806 status = ast_sip_send_stateful_response(rdata, tdata, endpoint);
807 ao2_cleanup(endpoint);
808 }
809
810 if (status != PJ_SUCCESS) {
811 ast_log(LOG_ERROR, "Unable to send response (%d)\n", status);
812 }
813
814 return status;
815}
jack_status_t status
Definition app_jack.c:149
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 762 of file res_pjsip_messaging.c.

763{
764 struct msg_data *mdata;
765 int res;
766
768 ast_log(LOG_ERROR, "SIP MESSAGE - a 'To' URI must be specified\n");
769 return -1;
770 }
771
773 if (!mdata) {
774 return -1;
775 }
776
778 ao2_ref(mdata, -1);
779
780 return res;
781}
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.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1006 of file res_pjsip_messaging.c.

1007{
1012 return 0;
1013}
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
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 583 of file res_pjsip_messaging.c.

584{
585 static const pj_str_t CONTENT_TYPE = { "Content-Type", sizeof("Content-Type") - 1 };
586
587 const char *content_type = ast_msg_get_var(msg, pj_strbuf(&CONTENT_TYPE));
588 if (content_type) {
589 pj_str_t type, subtype;
590 pjsip_ctype_hdr *parsed;
591
592 /* Let pjsip do the parsing for us */
593 parsed = pjsip_parse_hdr(tdata->pool, &CONTENT_TYPE,
594 ast_strdupa(content_type), strlen(content_type),
595 NULL);
596
597 if (!parsed) {
598 ast_log(LOG_WARNING, "Failed to parse '%s' as a content type. Using text/plain\n",
599 content_type);
600 return;
601 }
602
603 /* We need to turn type and subtype into zero-terminated strings */
604 pj_strdup_with_null(tdata->pool, &type, &parsed->media.type);
605 pj_strdup_with_null(tdata->pool, &subtype, &parsed->media.subtype);
606
607 body->type = pj_strbuf(&type);
608 body->subtype = pj_strbuf(&subtype);
609 }
610}
static const char type[]
const char * ast_msg_get_var(struct ast_msg *msg, const char *name)
Get the specified variable on the message.
const char * subtype
Definition res_pjsip.h:2448

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.
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.
void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
Unref a message var from inside an iterator loop.
struct ast_msg_var_iterator * ast_msg_var_iterator_init(const struct ast_msg *msg)
Create a new message variable iterator.
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
Channel datastore data for max forwards.

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 = 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 1021 of file res_pjsip_messaging.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1021 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 969 of file res_pjsip_messaging.c.

969 {
970 .name = {"Messaging Module", 16},
971 .id = -1,
972 .priority = PJSIP_MOD_PRIORITY_APPLICATION,
973 .on_rx_request = module_on_rx_request,
974};
static pj_bool_t module_on_rx_request(pjsip_rx_data *rdata)

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 964 of file res_pjsip_messaging.c.

964 {
965 .method = "MESSAGE",
966 .incoming_request = incoming_in_dialog_request
967};

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 783 of file res_pjsip_messaging.c.

783 {
784 .name = "pjsip",
785 .msg_send = sip_msg_send,
786};

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.

134{PJSIP_OTHER_METHOD, {"MESSAGE", 7} };

Referenced by load_module(), and module_on_rx_request().