Review Board 1.7.16


Support text messages outside of a call

Review Request #1042 - Created Dec. 1, 2010 and submitted

Russell Bryant
trunk
Reviewers
asterisk-dev
Asterisk
This branch contains a proposal for adding protocol independent support for processing text messages into and out of the dialplan, outside of a call.  The file doc/asterisk-messaging.txt contains more details on the proposal.  The introduction of the document is quoted here:

"    Asterisk has some limited support today for messaging.  The support that
exists primarily includes passing text messages in the context of a call.  The
SIP and IAX2 protocols have support for this, but that's it.

    There are a couple of other messaging protocols that are supported: Skype
and XMPP (Jabber).  The support of these is very minimal and not very integrated
into the architecture of Asterisk since these messages are not in the context of
a phone call.  They provide a combination of dialplan and manager interface
interfaces that are specific to each protocol.  There just is no current
architectural concept of dealing with text messages.

    The purpose of this proposal is to introduce text messaging into the
architecture of Asterisk.  For messaging support to exist in the true spirit of
Asterisk architecture, the design needs to achieve the following two goals:

    a) Protocol Independence
    b) Scriptable message routing

    The rest of this document goes through some details about how these goals
will be achieved in a way that is both architecturally compatible with Asterisk
as well as practical to implement."

----------

In addition to the documented proposal, I have made some good progress on implementation.  While the document includes some ideas for future enhancements, what is there so far should be usable.

 - core modifications to allow sending incoming messages through the dialplan
 - core modifications to allow outbound messages from the dialplan
 - modifications to res_jabber to allow inbound and outbound messages in the new architecture
 - changes to chan_sip to support inbound and outbound MESSAGE outside of a call
svn/testsuite/asterisk/team/russell/messaging:
  - This branch of the testsuite contains my tests for this branch, which include:
    - tests/sip/message_disabled
      - Ensure MESSAGE outside of a call is rejected when disabled.
    - tests/sip/message_unauth
      - When enabled, test sending a MESSAGE to Asterisk and send another back out from the dialplan.
    - tests/sip/message_auth
      - Same as the last test, but authenticate MESSAGE both inbound and outbound.
    - tests/sip/message_from_call
      - Set up a normal SIP call and send an out of call MESSAGE from the dialplan processing the call

I have also written some simple apps using the pjsua Python module from pjsip that can send and receive messages sent through Asterisk.

Lastly, I have done some manual testing of XMPP messages in and out of Asterisk using this code.
/trunk/channels/chan_sip.c
Revision 297183 New Change
[20] 260 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
261
#include "asterisk/ast_version.h"
261
#include "asterisk/ast_version.h"
262
#include "asterisk/event.h"
262
#include "asterisk/event.h"
263
#include "asterisk/cel.h"
263
#include "asterisk/cel.h"
264
#include "asterisk/data.h"
264
#include "asterisk/data.h"
265
#include "asterisk/aoc.h"
265
#include "asterisk/aoc.h"

    
   
266
#include "asterisk/message.h"
266
#include "sip/include/sip.h"
267
#include "sip/include/sip.h"
267
#include "sip/include/globals.h"
268
#include "sip/include/globals.h"
268
#include "sip/include/config_parser.h"
269
#include "sip/include/config_parser.h"
269
#include "sip/include/reqresp_parser.h"
270
#include "sip/include/reqresp_parser.h"
270
#include "sip/include/sip_utils.h"
271
#include "sip/include/sip_utils.h"
[+20] [20] 974 lines
[+20] [+] static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
1245
static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init, const char * const explicit_uri);
1246
static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init, const char * const explicit_uri);
1246
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp);
1247
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp);
1247
static int transmit_info_with_aoc(struct sip_pvt *p, struct ast_aoc_decoded *decoded);
1248
static int transmit_info_with_aoc(struct sip_pvt *p, struct ast_aoc_decoded *decoded);
1248
static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
1249
static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
1249
static int transmit_info_with_vidupdate(struct sip_pvt *p);
1250
static int transmit_info_with_vidupdate(struct sip_pvt *p);
1250
static int transmit_message_with_text(struct sip_pvt *p, const char *text);
1251
static int transmit_message_with_text(struct sip_pvt *p, const char *text, int init);
1251
static int transmit_refer(struct sip_pvt *p, const char *dest);
1252
static int transmit_refer(struct sip_pvt *p, const char *dest);
1252
static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten);
1253
static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten);
1253
static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message, int terminate);
1254
static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message, int terminate);
1254
static int transmit_cc_notify(struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state);
1255
static int transmit_cc_notify(struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state);
1255
static int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader);
1256
static int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader);
[+20] [20] 2959 lines
[+20] [+] static int sip_sendtext(struct ast_channel *ast, const char *text)
4215
		ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
4216
		ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
4216
		return(0);
4217
		return(0);
4217
	}
4218
	}
4218
	if (debug)
4219
	if (debug)
4219
		ast_verbose("Sending text %s on %s\n", text, ast->name);
4220
		ast_verbose("Sending text %s on %s\n", text, ast->name);
4220
	transmit_message_with_text(dialog, text);
4221
	transmit_message_with_text(dialog, text, 0);
4221
	return 0;	
4222
	return 0;	
4222
}
4223
}
4223

    
   
4224

   
4224
/*! \brief Update peer object in realtime storage
4225
/*! \brief Update peer object in realtime storage
4225
	If the Asterisk system name is set in asterisk.conf, we will use
4226
	If the Asterisk system name is set in asterisk.conf, we will use
[+20] [20] 8381 lines
[+20] [+] static int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
12607
	dialog_unref(p, "p is finished here at the end of transmit_register");
12608
	dialog_unref(p, "p is finished here at the end of transmit_register");
12608
	return res;
12609
	return res;
12609
}
12610
}
12610

    
   
12611

   
12611
/*! \brief Transmit text with SIP MESSAGE method */
12612
/*! \brief Transmit text with SIP MESSAGE method */
12612
static int transmit_message_with_text(struct sip_pvt *p, const char *text)
12613
static int transmit_message_with_text(struct sip_pvt *p, const char *text, int init)
12613
{
12614
{
12614
	struct sip_request req;
12615
	struct sip_request req;
12615
	
12616

   

    
   
12617
	if (init) {

    
   
12618
		initreqprep(&req, p, SIP_MESSAGE, NULL);

    
   
12619
	} else {
12616
	reqprep(&req, p, SIP_MESSAGE, 0, 1);
12620
		reqprep(&req, p, SIP_MESSAGE, 0, 1);

    
   
12621
	}
12617
	add_text(&req, text);
12622
	add_text(&req, text);
12618
	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12623
	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12619
}
12624
}
12620

    
   
12625

   
12621
/*! \brief Allocate SIP refer structure */
12626
/*! \brief Allocate SIP refer structure */
[+20] [20] 2723 lines
[+20] [+] static int get_msg_text(char *buf, int len, struct sip_request *req, int addnewline)
15345
			strcat(buf, "\n"); /* safe */
15350
			strcat(buf, "\n"); /* safe */
15346
	}
15351
	}
15347
	return 0;
15352
	return 0;
15348
}
15353
}
15349

    
   
15354

   

    
   
15355
static int get_msg_text2(struct ast_str **buf, struct sip_request *req, int addnewline)

    
   
15356
{

    
   
15357
	int i, res = 0;

    
   
15358

   

    
   
15359
	ast_str_reset(*buf);

    
   
15360

   

    
   
15361
	for (i = 0; res >= 0 && i < req->lines; i++) {

    
   
15362
		const char *line = REQ_OFFSET_TO_STR(req, line[i]);

    
   
15363
		int res;

    
   
15364

   

    
   
15365
		res = ast_str_append(buf, 0, "%s%s", line, addnewline ? "\n" : "");

    
   
15366
	}

    
   
15367

   

    
   
15368
	return res < 0 ? -1 : 0;

    
   
15369
}

    
   
15370

   

    
   
15371
AST_THREADSTORAGE(sip_msg_buf);
15350

    
   
15372

   
15351
/*! \brief  Receive SIP MESSAGE method messages
15373
/*! \brief  Receive SIP MESSAGE method messages
15352
\note	We only handle messages within current calls currently
15374
\note	We only handle messages within current calls currently
15353
	Reference: RFC 3428 */
15375
	Reference: RFC 3428 */
15354
static void receive_message(struct sip_pvt *p, struct sip_request *req)
15376
static void receive_message(struct sip_pvt *p, struct sip_request *req)
15355
{
15377
{
15356
	char buf[1400];	
15378
	struct ast_str *buf;
15357
	struct ast_frame f;
15379
	struct ast_frame f;
15358
	const char *content_type = get_header(req, "Content-Type");
15380
	const char *content_type = get_header(req, "Content-Type");

    
   
15381
	struct ast_msg *msg;

    
   
15382
	int res;

    
   
15383
	char *from, *to;
15359

    
   
15384

   
15360
	if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
15385
	if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
15361
		transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
15386
		transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
15362
		if (!p->owner)
15387
		if (!p->owner)
15363
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15388
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15364
		return;
15389
		return;
15365
	}
15390
	}
15366

    
   
15391

   
15367
	if (get_msg_text(buf, sizeof(buf), req, FALSE)) {
15392
	if (!(buf = ast_str_thread_get(&sip_msg_buf, 128))) {

    
   
15393
		transmit_response(p, "500 Internal Server Error", req);

    
   
15394
		if (!p->owner) {

    
   
15395
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

    
   
15396
		}

    
   
15397
		return;

    
   
15398
	}

    
   
15399

   

    
   
15400
	if (get_msg_text2(&buf, req, FALSE)) {
15368
		ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
15401
		ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
15369
		transmit_response(p, "202 Accepted", req);
15402
		transmit_response(p, "202 Accepted", req);
15370
		if (!p->owner)
15403
		if (!p->owner)
15371
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15404
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15372
		return;
15405
		return;
15373
	}
15406
	}
15374

    
   
15407

   
15375
	if (p->owner) {
15408
	if (p->owner) {
15376
		if (sip_debug_test_pvt(p))
15409
		if (sip_debug_test_pvt(p))
15377
			ast_verbose("SIP Text message received: '%s'\n", buf);
15410
			ast_verbose("SIP Text message received: '%s'\n", ast_str_buffer(buf));
15378
		memset(&f, 0, sizeof(f));
15411
		memset(&f, 0, sizeof(f));
15379
		f.frametype = AST_FRAME_TEXT;
15412
		f.frametype = AST_FRAME_TEXT;
15380
		f.subclass.integer = 0;
15413
		f.subclass.integer = 0;
15381
		f.offset = 0;
15414
		f.offset = 0;
15382
		f.data.ptr = buf;
15415
		f.data.ptr = ast_str_buffer(buf);
15383
		f.datalen = strlen(buf);
15416
		f.datalen = ast_str_strlen(buf);
15384
		ast_queue_frame(p->owner, &f);
15417
		ast_queue_frame(p->owner, &f);
15385
		transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
15418
		transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
15386
		return;
15419
		return;
15387
	}
15420
	}
15388

    
   
15421

   

    
   
15422
#if 0
15389
	/* Message outside of a call, we do not support that */
15423
	/* Message outside of a call, we do not support that */
15390
	ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);

   
15391
	transmit_response(p, "405 Method Not Allowed", req);
15424
	transmit_response(p, "405 Method Not Allowed", req);
15392
	sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15425
	sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

    
   
15426
#endif

    
   
15427

   

    
   
15428
	/*

    
   
15429
	 * XXX Need to optionally authenticate MESSAGE.  Also, make passing MESSAGE up to

    
   
15430
	 * the dialplan configurable.

    
   
15431
	 */

    
   
15432

   

    
   
15433
	if (!(msg = ast_msg_alloc())) {

    
   
15434
		transmit_response(p, "500 Internal Server Error", req);

    
   
15435
		if (!p->owner) {

    
   
15436
			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

    
   
15437
		}
15393
	return;
15438
		return;
15394
}
15439
	}
15395

    
   
15440

   

    
   
15441
	to = ast_strdupa(REQ_OFFSET_TO_STR(req, rlPart2));

    
   
15442
	from = ast_strdupa(get_header(req, "From"));

    
   
15443

   

    
   
15444
	res = ast_msg_set_to(msg, "%s", to);

    
   
15445
	res |= ast_msg_set_from(msg, "%s", get_in_brackets(from));

    
   
15446
	res |= ast_msg_set_body(msg, "%s", ast_str_buffer(buf));

    
   
15447
	/* XXX set configurable context */

    
   
15448

   

    
   
15449
	if (res) {

    
   
15450
		ao2_ref(msg, -1);

    
   
15451
	} else {

    
   
15452
		ast_msg_queue(msg);

    
   
15453
	}

    
   
15454

   

    
   
15455
	transmit_response(p, "202 Accepted", req);

    
   
15456
	sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

    
   
15457
}

    
   
15458

   
15396
/*! \brief  CLI Command to show calls within limits set by call_limit */
15459
/*! \brief  CLI Command to show calls within limits set by call_limit */
15397
static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15460
static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15398
{
15461
{
15399
#define FORMAT "%-25.25s %-15.15s %-15.15s \n"
15462
#define FORMAT "%-25.25s %-15.15s %-15.15s \n"
15400
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
15463
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
[+20] [20] 4881 lines
[+20] [+] static void *sip_park_thread(void *stuff)
20282
	res = ast_park_call(transferee, transferer, 0, d->parkexten, &ext);
20345
	res = ast_park_call(transferee, transferer, 0, d->parkexten, &ext);
20283
	
20346
	
20284

    
   
20347

   
20285
#ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
20348
#ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
20286
	if (!res) {
20349
	if (!res) {
20287
		transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
20350
		transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n", 0);
20288
	} else {
20351
	} else {
20289
		/* Then tell the transferer what happened */
20352
		/* Then tell the transferer what happened */
20290
		sprintf(buf, "Call parked on extension '%d'", ext);
20353
		sprintf(buf, "Call parked on extension '%d'", ext);
20291
		transmit_message_with_text(transferer->tech_pvt, buf);
20354
		transmit_message_with_text(transferer->tech_pvt, buf, 0);
20292
	}
20355
	}
20293
#endif
20356
#endif
20294

    
   
20357

   
20295
	/* Any way back to the current call??? */
20358
	/* Any way back to the current call??? */
20296
	/* Transmit response to the REFER request */
20359
	/* Transmit response to the REFER request */
[+20] [20] 2412 lines
[+20] [+] static int handle_request_message(struct sip_pvt *p, struct sip_request *req)
22709
	} else
22772
	} else
22710
		transmit_response(p, "202 Accepted", req);
22773
		transmit_response(p, "202 Accepted", req);
22711
	return 1;
22774
	return 1;
22712
}
22775
}
22713

    
   
22776

   

    
   
22777
static int sip_msg_send(const struct ast_msg *msg, const char *to, const char *from);

    
   
22778

   

    
   
22779
static const struct ast_msg_tech sip_msg_tech = {

    
   
22780
	.name = "sip",

    
   
22781
	.msg_send = sip_msg_send,

    
   
22782
};

    
   
22783

   

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

    
   
22785
{

    
   
22786
	struct sip_pvt *pvt;

    
   
22787
	int res;

    
   
22788
	char *peer;

    
   
22789

   

    
   
22790
	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL))) {

    
   
22791
		return -1;

    
   
22792
	}

    
   
22793

   

    
   
22794
	peer = ast_strdupa(to);

    
   
22795
	if (strchr(peer, '@')) {

    
   
22796
		strsep(&peer, "@");

    
   
22797
	} else {

    
   
22798
		strsep(&peer, ":");

    
   
22799
	}

    
   
22800
	if (ast_strlen_zero(peer)) {

    
   
22801
		ast_log(LOG_WARNING, "MESSAGE(to) is invalid for SIP - '%s'\n", to);

    
   
22802
		return -1;

    
   
22803
	}

    
   
22804

   

    
   
22805
	sip_pvt_lock(pvt);

    
   
22806

   

    
   
22807
	if (create_addr(pvt, peer, NULL, TRUE, NULL)) {

    
   
22808
		sip_pvt_unlock(pvt);

    
   
22809
		dialog_unlink_all(pvt, TRUE, TRUE);

    
   
22810
		dialog_unref(pvt, "create_addr failed sending a MESSAGE");

    
   
22811
		return -1;

    
   
22812
	}

    
   
22813
	ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);

    
   
22814
	ast_set_flag(&pvt->flags[0], SIP_OUTGOING);

    
   
22815

   

    
   
22816
	/* XXX Does pvt->expiry need to be set? */

    
   
22817

   

    
   
22818
	res = transmit_message_with_text(pvt, ast_msg_get_body(msg), 1);

    
   
22819

   

    
   
22820
	sip_pvt_unlock(pvt);

    
   
22821
	sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT);

    
   
22822
	dialog_unref(pvt, "sent a MESSAGE");

    
   
22823

   

    
   
22824
	return res;

    
   
22825
}

    
   
22826

   
22714
static enum sip_publish_type determine_sip_publish_type(struct sip_request *req, const char * const event, const char * const etag, const char * const expires, int *expires_int)
22827
static enum sip_publish_type determine_sip_publish_type(struct sip_request *req, const char * const event, const char * const etag, const char * const expires, int *expires_int)
22715
{
22828
{
22716
	int etag_present = !ast_strlen_zero(etag);
22829
	int etag_present = !ast_strlen_zero(etag);
22717
	int body_present = req->lines > 0;
22830
	int body_present = req->lines > 0;
22718

    
   
22831

   
[+20] [20] 6020 lines
[+20] [+] static int load_module(void)
28739
	 * has const fields.
28852
	 * has const fields.
28740
	 */
28853
	 */
28741
	memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
28854
	memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
28742
	memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
28855
	memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
28743

    
   
28856

   

    
   
28857
	if (ast_msg_tech_register(&sip_msg_tech)) {

    
   
28858
		/* LOAD_FAILURE stops Asterisk, so cleanup is a moot point. */

    
   
28859
		return AST_MODULE_LOAD_FAILURE;

    
   
28860
	}

    
   
28861

   
28744
	/* Make sure we can register our sip channel type */
28862
	/* Make sure we can register our sip channel type */
28745
	if (ast_channel_register(&sip_tech)) {
28863
	if (ast_channel_register(&sip_tech)) {
28746
		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
28864
		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
28747
		io_context_destroy(io);
28865
		io_context_destroy(io);
28748
		sched_context_destroy(sched);
28866
		sched_context_destroy(sched);
[+20] [20] 97 lines
[+20] [+] static int unload_module(void)
28846
	ast_sched_dump(sched);
28964
	ast_sched_dump(sched);
28847
	
28965
	
28848
	/* First, take us out of the channel type list */
28966
	/* First, take us out of the channel type list */
28849
	ast_channel_unregister(&sip_tech);
28967
	ast_channel_unregister(&sip_tech);
28850

    
   
28968

   

    
   
28969
	ast_msg_tech_unregister(&sip_msg_tech);

    
   
28970

   
28851
	/* Unregister dial plan functions */
28971
	/* Unregister dial plan functions */
28852
	ast_custom_function_unregister(&sipchaninfo_function);
28972
	ast_custom_function_unregister(&sipchaninfo_function);
28853
	ast_custom_function_unregister(&sippeer_function);
28973
	ast_custom_function_unregister(&sippeer_function);
28854
	ast_custom_function_unregister(&sip_header_function);
28974
	ast_custom_function_unregister(&sip_header_function);
28855
	ast_custom_function_unregister(&checksipdomain_function);
28975
	ast_custom_function_unregister(&checksipdomain_function);
[+20] [20] 134 lines
/trunk/configs/jabber.conf.sample
Revision 297183 New Change
 
/trunk/doc/asterisk-messaging.txt
New File
 
/trunk/include/asterisk/_private.h
Revision 297183 New Change
 
/trunk/include/asterisk/channel.h
Revision 297183 New Change
 
/trunk/include/asterisk/jabber.h
Revision 297183 New Change
 
/trunk/include/asterisk/message.h
New File
 
/trunk/main/asterisk.c
Revision 297183 New Change
 
/trunk/main/channel.c
Revision 297183 New Change
 
/trunk/main/message.c
New File
 
/trunk/res/res_jabber.c
Revision 297183 New Change
 
/trunk/testsuite-tests/message_from_call/run-test
New File
 
/trunk/testsuite-tests/message_from_call/test-config.yaml
New File
 
/trunk/testsuite-tests/message_from_call/configs/ast1/extensions.conf
New File
 
/trunk/testsuite-tests/message_from_call/sipp/call.xml
New File
 
/trunk/testsuite-tests/message_from_call/sipp/message_recv.xml
New File
 
/trunk/testsuite-tests/message_unauth/run-test
New File
 
/trunk/testsuite-tests/message_unauth/test-config.yaml
New File
 
/trunk/testsuite-tests/message_unauth/configs/ast1/extensions.conf
New File
 
/trunk/testsuite-tests/message_unauth/sipp/message.xml
New File
 
/trunk/testsuite-tests/message_unauth/sipp/message_recv.xml
New File
 
  1. /trunk/channels/chan_sip.c: Loading...
  2. /trunk/configs/jabber.conf.sample: Loading...
  3. /trunk/doc/asterisk-messaging.txt: Loading...
  4. /trunk/include/asterisk/_private.h: Loading...
  5. /trunk/include/asterisk/channel.h: Loading...
  6. /trunk/include/asterisk/jabber.h: Loading...
  7. /trunk/include/asterisk/message.h: Loading...
  8. /trunk/main/asterisk.c: Loading...
  9. /trunk/main/channel.c: Loading...
  10. /trunk/main/message.c: Loading...
  11. /trunk/res/res_jabber.c: Loading...
  12. /trunk/testsuite-tests/message_from_call/run-test: Loading...
  13. /trunk/testsuite-tests/message_from_call/test-config.yaml: Loading...
  14. /trunk/testsuite-tests/message_from_call/configs/ast1/extensions.conf: Loading...
  15. /trunk/testsuite-tests/message_from_call/sipp/call.xml: Loading...
  16. /trunk/testsuite-tests/message_from_call/sipp/message_recv.xml: Loading...
  17. /trunk/testsuite-tests/message_unauth/run-test: Loading...
  18. /trunk/testsuite-tests/message_unauth/test-config.yaml: Loading...
  19. /trunk/testsuite-tests/message_unauth/configs/ast1/extensions.conf: Loading...
  20. /trunk/testsuite-tests/message_unauth/sipp/message.xml: Loading...
  21. /trunk/testsuite-tests/message_unauth/sipp/message_recv.xml: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.