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
Diff Revision 2 Diff Revision 3
[20] 780 lines
[+20] [+] AST_MUTEX_DEFINE_STATIC(sip_reload_lock);
781
static pthread_t monitor_thread = AST_PTHREADT_NULL;
781
static pthread_t monitor_thread = AST_PTHREADT_NULL;
782

    
   
782

   
783
static int sip_reloading = FALSE;                       /*!< Flag for avoiding multiple reloads at the same time */
783
static int sip_reloading = FALSE;                       /*!< Flag for avoiding multiple reloads at the same time */
784
static enum channelreloadreason sip_reloadreason;       /*!< Reason for last reload/load of configuration */
784
static enum channelreloadreason sip_reloadreason;       /*!< Reason for last reload/load of configuration */
785

    
   
785

   
786
struct sched_context *sched;     /*!< The scheduling context */
786
struct ast_sched_context *sched;     /*!< The scheduling context */
787
static struct io_context *io;           /*!< The IO context */
787
static struct io_context *io;           /*!< The IO context */
788
static int *sipsock_read_id;            /*!< ID of IO entry for sipsock FD */
788
static int *sipsock_read_id;            /*!< ID of IO entry for sipsock FD */
789
struct sip_pkt;
789
struct sip_pkt;
790
static AST_LIST_HEAD_STATIC(domain_list, domain);    /*!< The SIP domain list */
790
static AST_LIST_HEAD_STATIC(domain_list, domain);    /*!< The SIP domain list */
791

    
   
791

   
[+20] [20] 3437 lines
[+20] [+] static int sip_sendtext(struct ast_channel *ast, const char *text)
4229
	table to facilitate multi-server setups.
4229
	table to facilitate multi-server setups.
4230
*/
4230
*/
4231
static void realtime_update_peer(const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
4231
static void realtime_update_peer(const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
4232
{
4232
{
4233
	char port[10];
4233
	char port[10];
4234
	char ipaddr[INET_ADDRSTRLEN];
4234
	char ipaddr[INET6_ADDRSTRLEN];
4235
	char regseconds[20];
4235
	char regseconds[20];
4236
	char *tablename = NULL;
4236
	char *tablename = NULL;
4237
	char str_lastms[20];
4237
	char str_lastms[20];
4238

    
   
4238

   
4239
	const char *sysname = ast_config_AST_SYSTEM_NAME;
4239
	const char *sysname = ast_config_AST_SYSTEM_NAME;
[+20] [20] 196 lines
[+20] [+] static struct sip_peer *realtime_peer(const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects)
4436
	struct sip_peer *peer;
4436
	struct sip_peer *peer;
4437
	struct ast_variable *var = NULL;
4437
	struct ast_variable *var = NULL;
4438
	struct ast_variable *varregs = NULL;
4438
	struct ast_variable *varregs = NULL;
4439
	struct ast_variable *tmp;
4439
	struct ast_variable *tmp;
4440
	struct ast_config *peerlist = NULL;
4440
	struct ast_config *peerlist = NULL;
4441
	char ipaddr[INET_ADDRSTRLEN];
4441
	char ipaddr[INET6_ADDRSTRLEN];
4442
	char portstring[6]; /*up to 5 digits plus null terminator*/
4442
	char portstring[6]; /*up to 5 digits plus null terminator*/
4443
	char *cat = NULL;
4443
	char *cat = NULL;
4444
	int realtimeregs = ast_check_realtime("sipregs");
4444
	int realtimeregs = ast_check_realtime("sipregs");
4445

    
   
4445

   
4446
	/* First check on peer name */
4446
	/* First check on peer name */
[+20] [20] 3273 lines
[+20] [+] static int sip_register(const char *value, int lineno)
7720
{
7720
{
7721
	struct sip_subscription_mwi *mwi;
7721
	struct sip_subscription_mwi *mwi;
7722
	int portnum = 0;
7722
	int portnum = 0;
7723
	enum sip_transport transport = SIP_TRANSPORT_UDP;
7723
	enum sip_transport transport = SIP_TRANSPORT_UDP;
7724
	char buf[256] = "";
7724
	char buf[256] = "";
7725
	char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
7725
	char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL;
7726
	
7726

   
7727
	if (!value) {
7727
	if (!value) {
7728
		return -1;
7728
		return -1;
7729
	}
7729
	}
7730
	
7730

   
7731
	ast_copy_string(buf, value, sizeof(buf));
7731
	ast_copy_string(buf, value, sizeof(buf));
7732

    
   
7732

   
7733
	sip_parse_host(buf, lineno, &username, &portnum, &transport);
7733
	if (!(at = strstr(buf, "@"))) {
7734
	
7734
		return -1;
7735
	if ((hostname = strrchr(username, '@'))) {
7735
	}

    
   
7736

   

    
   
7737
	if ((hostname = strrchr(buf, '@'))) {
7736
		*hostname++ = '\0';
7738
		*hostname++ = '\0';

    
   
7739
		username = buf;
7737
	}
7740
	}
7738
	
7741

   
7739
	if ((secret = strchr(username, ':'))) {
7742
	if ((secret = strchr(username, ':'))) {
7740
		*secret++ = '\0';
7743
		*secret++ = '\0';
7741
		if ((authuser = strchr(secret, ':'))) {
7744
		if ((authuser = strchr(secret, ':'))) {
7742
			*authuser++ = '\0';
7745
			*authuser++ = '\0';
7743
		}
7746
		}
7744
	}
7747
	}
7745
	
7748

   
7746
	if ((mailbox = strchr(hostname, '/'))) {
7749
	if ((mailbox = strchr(hostname, '/'))) {
7747
		*mailbox++ = '\0';
7750
		*mailbox++ = '\0';
7748
	}
7751
	}
7749

    
   
7752

   
7750
	if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
7753
	if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
7751
		ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port][/mailbox] at line %d\n", lineno);
7754
		ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
7752
		return -1;
7755
		return -1;
7753
	}
7756
	}
7754
	
7757

   
7755
	if ((porta = strchr(hostname, ':'))) {
7758
	if ((porta = strchr(hostname, ':'))) {
7756
		*porta++ = '\0';
7759
		*porta++ = '\0';
7757
		if (!(portnum = atoi(porta))) {
7760
		if (!(portnum = atoi(porta))) {
7758
			ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
7761
			ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
7759
			return -1;
7762
			return -1;
7760
		}
7763
		}
7761
	}
7764
	}
7762
	
7765

   
7763
	if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
7766
	if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
7764
		return -1;
7767
		return -1;
7765
	}
7768
	}
7766
	
7769

   
7767
	ASTOBJ_INIT(mwi);
7770
	ASTOBJ_INIT(mwi);
7768
	ast_string_field_set(mwi, username, username);
7771
	ast_string_field_set(mwi, username, username);
7769
	if (secret) {
7772
	if (secret) {
7770
		ast_string_field_set(mwi, secret, secret);
7773
		ast_string_field_set(mwi, secret, secret);
7771
	}
7774
	}
7772
	if (authuser) {
7775
	if (authuser) {
7773
		ast_string_field_set(mwi, authuser, authuser);
7776
		ast_string_field_set(mwi, authuser, authuser);
7774
	}
7777
	}
7775
	ast_string_field_set(mwi, hostname, hostname);
7778
	ast_string_field_set(mwi, hostname, hostname);
7776
	ast_string_field_set(mwi, mailbox, mailbox);
7779
	ast_string_field_set(mwi, mailbox, mailbox);
7777
	mwi->resub = -1;
7780
	mwi->resub = -1;
7778
	mwi->portno = portnum;
7781
	mwi->portno = portnum;
7779
	mwi->transport = transport;
7782
	mwi->transport = transport;
7780
	
7783

   
7781
	ASTOBJ_CONTAINER_LINK(&submwil, mwi);
7784
	ASTOBJ_CONTAINER_LINK(&submwil, mwi);
7782
	ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
7785
	ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
7783
	
7786

   
7784
	return 0;
7787
	return 0;
7785
}
7788
}
7786

    
   
7789

   
7787
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
7790
static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
7788
{
7791
{
[+20] [20] 7729 lines
[+20] [+] static void receive_message(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
15518
	res |= ast_msg_set_from(msg, "%s", get_in_brackets(from));
15521
	res |= ast_msg_set_from(msg, "%s", get_in_brackets(from));
15519
	res |= ast_msg_set_body(msg, "%s", ast_str_buffer(buf));
15522
	res |= ast_msg_set_body(msg, "%s", ast_str_buffer(buf));
15520
	res |= ast_msg_set_context(msg, "%s", p->context);
15523
	res |= ast_msg_set_context(msg, "%s", p->context);
15521

    
   
15524

   
15522
	if (res) {
15525
	if (res) {
15523
		ao2_ref(msg, -1);
15526
		ast_msg_destroy(msg);
15524
	} else {
15527
	} else {
15525
		ast_msg_queue(msg);
15528
		ast_msg_queue(msg);
15526
	}
15529
	}
15527

    
   
15530

   
15528
	transmit_response(p, "202 Accepted", req);
15531
	transmit_response(p, "202 Accepted", req);
[+20] [20] 5342 lines
[+20] [+] static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e)
20871
			transmit_response(p, "489 Bad event", req);
20874
			transmit_response(p, "489 Bad event", req);
20872
			res = -1;
20875
			res = -1;
20873
		}
20876
		}
20874
	} else if (!strcmp(event, "keep-alive")) {
20877
	} else if (!strcmp(event, "keep-alive")) {
20875
		 /* Used by Sipura/Linksys for NAT pinhole,
20878
		 /* Used by Sipura/Linksys for NAT pinhole,
20876
		  * just confirm that we recieved the packet. */
20879
		  * just confirm that we received the packet. */
20877
		transmit_response(p, "200 OK", req);
20880
		transmit_response(p, "200 OK", req);
20878
	} else if (!strcmp(event, "call-completion")) {
20881
	} else if (!strcmp(event, "call-completion")) {
20879
		res = handle_cc_notify(p, req);
20882
		res = handle_cc_notify(p, req);
20880
	} else {
20883
	} else {
20881
		/* We don't understand this event. */
20884
		/* We don't understand this event. */
[+20] [20] 1969 lines
[+20] [+] static void handle_response_message(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
22851
	}
22854
	}
22852

    
   
22855

   
22853
	if ((p->authtries == MAX_AUTHTRIES)) {
22856
	if ((p->authtries == MAX_AUTHTRIES)) {
22854
		ast_log(LOG_NOTICE, "Failed to authenticate on MESSAGE to '%s'\n", get_header(&p->initreq, "From"));
22857
		ast_log(LOG_NOTICE, "Failed to authenticate on MESSAGE to '%s'\n", get_header(&p->initreq, "From"));
22855
		pvt_set_needdestroy(p, "MESSAGE authentication failed");
22858
		pvt_set_needdestroy(p, "MESSAGE authentication failed");

    
   
22859
		return;
22856
	}
22860
	}
22857

    
   
22861

   
22858
	p->authtries++;
22862
	p->authtries++;
22859
	auth_headers((resp == 401 ? WWW_AUTH : PROXY_AUTH), &header, &respheader);
22863
	auth_headers((resp == 401 ? WWW_AUTH : PROXY_AUTH), &header, &respheader);
22860
	memset(digest, 0, sizeof(digest));
22864
	memset(digest, 0, sizeof(digest));
[+20] [20] 5846 lines
[+20] [+] static void sip_unregister_tests(void)
28707
	sip_request_parser_unregister_tests();
28711
	sip_request_parser_unregister_tests();
28708
	sip_dialplan_function_unregister_tests();
28712
	sip_dialplan_function_unregister_tests();
28709
}
28713
}
28710

    
   
28714

   
28711
#ifdef TEST_FRAMEWORK
28715
#ifdef TEST_FRAMEWORK

    
   
28716
AST_TEST_DEFINE(test_sip_mwi_subscribe_parse)

    
   
28717
{

    
   
28718
	int found = 0;

    
   
28719
	enum ast_test_result_state res = AST_TEST_PASS;

    
   
28720
	const char *mwi1 = "1234@mysipprovider.com/1234";

    
   
28721
	const char *mwi2 = "1234:password@mysipprovider.com/1234";

    
   
28722
	const char *mwi3 = "1234:password@mysipprovider.com:5061/1234";

    
   
28723
	const char *mwi4 = "1234:password:authuser@mysipprovider.com/1234";

    
   
28724
	const char *mwi5 = "1234:password:authuser@mysipprovider.com:5061/1234";

    
   
28725
	const char *mwi6 = "1234:password";

    
   
28726

   

    
   
28727
	switch (cmd) {

    
   
28728
	case TEST_INIT:

    
   
28729
		info->name = "sip_mwi_subscribe_parse_test";

    
   
28730
		info->category = "/channels/chan_sip/";

    
   
28731
		info->summary = "SIP MWI subscribe line parse unit test";

    
   
28732
		info->description =

    
   
28733
			"Tests the parsing of mwi subscription lines (e.g., mwi => from sip.conf)";

    
   
28734
		return AST_TEST_NOT_RUN;

    
   
28735
	case TEST_EXECUTE:

    
   
28736
		break;

    
   
28737
	}

    
   
28738

   

    
   
28739
	if (sip_subscribe_mwi(mwi1, 1)) {

    
   
28740
		res = AST_TEST_FAIL;

    
   
28741
	} else {

    
   
28742
		found = 0;

    
   
28743
		res = AST_TEST_FAIL;

    
   
28744
		ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {

    
   
28745
			ASTOBJ_WRLOCK(iterator);

    
   
28746
			if (

    
   
28747
				!strcmp(iterator->hostname, "mysipprovider.com") &&

    
   
28748
				!strcmp(iterator->username, "1234") &&

    
   
28749
				!strcmp(iterator->secret, "") &&

    
   
28750
				!strcmp(iterator->authuser, "") &&

    
   
28751
				!strcmp(iterator->mailbox, "1234") &&

    
   
28752
				iterator->portno == 0) {

    
   
28753
				found = 1;

    
   
28754
				res = AST_TEST_PASS;

    
   
28755
			}

    
   
28756
			ASTOBJ_UNLOCK(iterator);

    
   
28757
		} while(0));

    
   
28758
		if (!found) {

    
   
28759
			ast_test_status_update(test, "sip_subscribe_mwi test 1 failed\n");

    
   
28760
		}

    
   
28761
	}

    
   
28762

   

    
   
28763
	if (sip_subscribe_mwi(mwi2, 1)) {

    
   
28764
		res = AST_TEST_FAIL;

    
   
28765
	} else {

    
   
28766
		found = 0;

    
   
28767
		res = AST_TEST_FAIL;

    
   
28768
		ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {

    
   
28769
			ASTOBJ_WRLOCK(iterator);

    
   
28770
			if (

    
   
28771
				!strcmp(iterator->hostname, "mysipprovider.com") &&

    
   
28772
				!strcmp(iterator->username, "1234") &&

    
   
28773
				!strcmp(iterator->secret, "password") &&

    
   
28774
				!strcmp(iterator->authuser, "") &&

    
   
28775
				!strcmp(iterator->mailbox, "1234") &&

    
   
28776
				iterator->portno == 0) {

    
   
28777
				found = 1;

    
   
28778
				res = AST_TEST_PASS;

    
   
28779
			}

    
   
28780
			ASTOBJ_UNLOCK(iterator);

    
   
28781
		} while(0));

    
   
28782
		if (!found) {

    
   
28783
			ast_test_status_update(test, "sip_subscribe_mwi test 2 failed\n");

    
   
28784
		}

    
   
28785
	}

    
   
28786

   

    
   
28787
	if (sip_subscribe_mwi(mwi3, 1)) {

    
   
28788
		res = AST_TEST_FAIL;

    
   
28789
	} else {

    
   
28790
		found = 0;

    
   
28791
		res = AST_TEST_FAIL;

    
   
28792
		ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {

    
   
28793
			ASTOBJ_WRLOCK(iterator);

    
   
28794
			if (

    
   
28795
				!strcmp(iterator->hostname, "mysipprovider.com") &&

    
   
28796
				!strcmp(iterator->username, "1234") &&

    
   
28797
				!strcmp(iterator->secret, "password") &&

    
   
28798
				!strcmp(iterator->authuser, "") &&

    
   
28799
				!strcmp(iterator->mailbox, "1234") &&

    
   
28800
				iterator->portno == 5061) {

    
   
28801
				found = 1;

    
   
28802
				res = AST_TEST_PASS;

    
   
28803
			}

    
   
28804
			ASTOBJ_UNLOCK(iterator);

    
   
28805
		} while(0));

    
   
28806
		if (!found) {

    
   
28807
			ast_test_status_update(test, "sip_subscribe_mwi test 3 failed\n");

    
   
28808
		}

    
   
28809
	}

    
   
28810

   

    
   
28811
	if (sip_subscribe_mwi(mwi4, 1)) {

    
   
28812
		res = AST_TEST_FAIL;

    
   
28813
	} else {

    
   
28814
		found = 0;

    
   
28815
		res = AST_TEST_FAIL;

    
   
28816
		ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {

    
   
28817
			ASTOBJ_WRLOCK(iterator);

    
   
28818
			if (

    
   
28819
				!strcmp(iterator->hostname, "mysipprovider.com") &&

    
   
28820
				!strcmp(iterator->username, "1234") &&

    
   
28821
				!strcmp(iterator->secret, "password") &&

    
   
28822
				!strcmp(iterator->authuser, "authuser") &&

    
   
28823
				!strcmp(iterator->mailbox, "1234") &&

    
   
28824
				iterator->portno == 0) {

    
   
28825
				found = 1;

    
   
28826
				res = AST_TEST_PASS;

    
   
28827
			}

    
   
28828
			ASTOBJ_UNLOCK(iterator);

    
   
28829
		} while(0));

    
   
28830
		if (!found) {

    
   
28831
			ast_test_status_update(test, "sip_subscribe_mwi test 4 failed\n");

    
   
28832
		}

    
   
28833
	}

    
   
28834

   

    
   
28835
	if (sip_subscribe_mwi(mwi5, 1)) {

    
   
28836
		res = AST_TEST_FAIL;

    
   
28837
	} else {

    
   
28838
		found = 0;

    
   
28839
		res = AST_TEST_FAIL;

    
   
28840
		ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {

    
   
28841
			ASTOBJ_WRLOCK(iterator);

    
   
28842
			if (

    
   
28843
				!strcmp(iterator->hostname, "mysipprovider.com") &&

    
   
28844
				!strcmp(iterator->username, "1234") &&

    
   
28845
				!strcmp(iterator->secret, "password") &&

    
   
28846
				!strcmp(iterator->authuser, "authuser") &&

    
   
28847
				!strcmp(iterator->mailbox, "1234") &&

    
   
28848
				iterator->portno == 5061) {

    
   
28849
				found = 1;

    
   
28850
				res = AST_TEST_PASS;

    
   
28851
			}

    
   
28852
			ASTOBJ_UNLOCK(iterator);

    
   
28853
		} while(0));

    
   
28854
		if (!found) {

    
   
28855
			ast_test_status_update(test, "sip_subscribe_mwi test 5 failed\n");

    
   
28856
		}

    
   
28857
	}

    
   
28858
	

    
   
28859
	if (sip_subscribe_mwi(mwi6, 1)) {

    
   
28860
		res = AST_TEST_PASS;

    
   
28861
	} else {

    
   
28862
		res = AST_TEST_FAIL;

    
   
28863
	}

    
   
28864
	return res;

    
   
28865
}

    
   
28866

   
28712
AST_TEST_DEFINE(test_sip_peers_get)
28867
AST_TEST_DEFINE(test_sip_peers_get)
28713
{
28868
{
28714
	struct sip_peer *peer;
28869
	struct sip_peer *peer;
28715
	struct ast_data *node;
28870
	struct ast_data *node;
28716
	struct ast_data_query query = {
28871
	struct ast_data_query query = {
[+20] [20] 233 lines
[+20] [+] static int load_module(void)
28950
	threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
29105
	threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
28951
	
29106
	
28952
	ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
29107
	ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
28953
	ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
29108
	ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
28954

    
   
29109

   
28955
	if (!(sched = sched_context_create())) {
29110
	if (!(sched = ast_sched_context_create())) {
28956
		ast_log(LOG_ERROR, "Unable to create scheduler context\n");
29111
		ast_log(LOG_ERROR, "Unable to create scheduler context\n");
28957
		return AST_MODULE_LOAD_FAILURE;
29112
		return AST_MODULE_LOAD_FAILURE;
28958
	}
29113
	}
28959

    
   
29114

   
28960
	if (!(io = io_context_create())) {
29115
	if (!(io = io_context_create())) {
28961
		ast_log(LOG_ERROR, "Unable to create I/O context\n");
29116
		ast_log(LOG_ERROR, "Unable to create I/O context\n");
28962
		sched_context_destroy(sched);
29117
		ast_sched_context_destroy(sched);
28963
		return AST_MODULE_LOAD_FAILURE;
29118
		return AST_MODULE_LOAD_FAILURE;
28964
	}
29119
	}
28965

    
   
29120

   
28966
	sip_reloadreason = CHANNEL_MODULE_LOAD;
29121
	sip_reloadreason = CHANNEL_MODULE_LOAD;
28967

    
   
29122

   
[+20] [20] 16 lines
[+20] static int load_module(void)
28984

    
   
29139

   
28985
	/* Make sure we can register our sip channel type */
29140
	/* Make sure we can register our sip channel type */
28986
	if (ast_channel_register(&sip_tech)) {
29141
	if (ast_channel_register(&sip_tech)) {
28987
		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
29142
		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
28988
		io_context_destroy(io);
29143
		io_context_destroy(io);
28989
		sched_context_destroy(sched);
29144
		ast_sched_context_destroy(sched);
28990
		return AST_MODULE_LOAD_FAILURE;
29145
		return AST_MODULE_LOAD_FAILURE;
28991
	}
29146
	}
28992

    
   
29147

   
28993
#ifdef TEST_FRAMEWORK
29148
#ifdef TEST_FRAMEWORK
28994
	AST_TEST_REGISTER(test_sip_peers_get);
29149
	AST_TEST_REGISTER(test_sip_peers_get);

    
   
29150
	AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
28995
#endif
29151
#endif
28996

    
   
29152

   
28997
	/* Register AstData providers */
29153
	/* Register AstData providers */
28998
	ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
29154
	ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
28999

    
   
29155

   
[+20] [20] 55 lines
[+20] static int load_module(void)
29055
	/* And start the monitor for the first time */
29211
	/* And start the monitor for the first time */
29056
	restart_monitor();
29212
	restart_monitor();
29057

    
   
29213

   
29058
	ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
29214
	ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
29059
		"name", RQ_CHAR, 10,
29215
		"name", RQ_CHAR, 10,
29060
		"ipaddr", RQ_CHAR, 15,
29216
		"ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1,
29061
		"port", RQ_UINTEGER2, 5,
29217
		"port", RQ_UINTEGER2, 5,
29062
		"regseconds", RQ_INTEGER4, 11,
29218
		"regseconds", RQ_INTEGER4, 11,
29063
		"defaultuser", RQ_CHAR, 10,
29219
		"defaultuser", RQ_CHAR, 10,
29064
		"fullcontact", RQ_CHAR, 35,
29220
		"fullcontact", RQ_CHAR, 35,
29065
		"regserver", RQ_CHAR, 20,
29221
		"regserver", RQ_CHAR, 20,
[+20] [20] 36 lines
[+20] [+] static int unload_module(void)
29102
	ast_unregister_application(app_sipaddheader);
29258
	ast_unregister_application(app_sipaddheader);
29103
	ast_unregister_application(app_sipremoveheader);
29259
	ast_unregister_application(app_sipremoveheader);
29104

    
   
29260

   
29105
#ifdef TEST_FRAMEWORK
29261
#ifdef TEST_FRAMEWORK
29106
	AST_TEST_UNREGISTER(test_sip_peers_get);
29262
	AST_TEST_UNREGISTER(test_sip_peers_get);

    
   
29263
	AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
29107
#endif
29264
#endif
29108
	/* Unregister all the AstData providers */
29265
	/* Unregister all the AstData providers */
29109
	ast_data_unregister(NULL);
29266
	ast_data_unregister(NULL);
29110

    
   
29267

   
29111
	/* Unregister CLI commands */
29268
	/* Unregister CLI commands */
[+20] [20] 93 lines
[+20] static int unload_module(void)
29205
	ao2_t_ref(threadt, -1, "unref the thread table");
29362
	ao2_t_ref(threadt, -1, "unref the thread table");
29206

    
   
29363

   
29207
	clear_sip_domains();
29364
	clear_sip_domains();
29208
	ast_free_ha(sip_cfg.contact_ha);
29365
	ast_free_ha(sip_cfg.contact_ha);
29209
	close(sipsock);
29366
	close(sipsock);
29210
	sched_context_destroy(sched);
29367
	ast_sched_context_destroy(sched);
29211
	con = ast_context_find(used_context);
29368
	con = ast_context_find(used_context);
29212
	if (con) {
29369
	if (con) {
29213
		ast_context_destroy(con, "SIP");
29370
		ast_context_destroy(con, "SIP");
29214
	}
29371
	}
29215
	ast_unload_realtime("sipregs");
29372
	ast_unload_realtime("sipregs");
[+20] [20] 17 lines
/trunk/channels/sip/include/sip.h
Diff Revision 2 Diff Revision 3
 
/trunk/configs/jabber.conf.sample
Diff Revision 2 Diff Revision 3
 
/trunk/configs/sip.conf.sample
Diff Revision 2 Diff Revision 3
 
/trunk/include/asterisk/_private.h
Diff Revision 2 Diff Revision 3
 
/trunk/include/asterisk/channel.h
Diff Revision 2 Diff Revision 3
 
/trunk/include/asterisk/jabber.h
Diff Revision 2 Diff Revision 3
 
/trunk/include/asterisk/message.h
Diff Revision 2 Diff Revision 3
 
/trunk/main/asterisk.c
Diff Revision 2 Diff Revision 3
 
/trunk/main/channel.c
Diff Revision 2 Diff Revision 3
 
/trunk/main/message.c
Diff Revision 2 Diff Revision 3
 
/trunk/res/res_jabber.c
Diff Revision 2 Diff Revision 3
 
  1. /trunk/channels/chan_sip.c: Loading...
  2. /trunk/channels/sip/include/sip.h: Loading...
  3. /trunk/configs/jabber.conf.sample: Loading...
  4. /trunk/configs/sip.conf.sample: Loading...
  5. /trunk/include/asterisk/_private.h: Loading...
  6. /trunk/include/asterisk/channel.h: Loading...
  7. /trunk/include/asterisk/jabber.h: Loading...
  8. /trunk/include/asterisk/message.h: Loading...
  9. /trunk/main/asterisk.c: Loading...
  10. /trunk/main/channel.c: Loading...
  11. /trunk/main/message.c: Loading...
  12. /trunk/res/res_jabber.c: 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.