aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c184
-rw-r--r--configs/sip.conf.sample7
2 files changed, 175 insertions, 16 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 0f0c23d25..c5bd08c6f 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -7720,36 +7720,39 @@ static int sip_subscribe_mwi(const char *value, int lineno)
int portnum = 0;
enum sip_transport transport = SIP_TRANSPORT_UDP;
char buf[256] = "";
- char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
-
+ char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL;
+
if (!value) {
return -1;
}
-
+
ast_copy_string(buf, value, sizeof(buf));
- sip_parse_host(buf, lineno, &username, &portnum, &transport);
-
- if ((hostname = strrchr(username, '@'))) {
+ if (!(at = strstr(buf, "@"))) {
+ return -1;
+ }
+
+ if ((hostname = strrchr(buf, '@'))) {
*hostname++ = '\0';
+ username = buf;
}
-
+
if ((secret = strchr(username, ':'))) {
*secret++ = '\0';
if ((authuser = strchr(secret, ':'))) {
*authuser++ = '\0';
}
}
-
+
if ((mailbox = strchr(hostname, '/'))) {
*mailbox++ = '\0';
}
if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
- ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port][/mailbox] at line %d\n", lineno);
+ ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
return -1;
}
-
+
if ((porta = strchr(hostname, ':'))) {
*porta++ = '\0';
if (!(portnum = atoi(porta))) {
@@ -7757,11 +7760,11 @@ static int sip_subscribe_mwi(const char *value, int lineno)
return -1;
}
}
-
+
if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
return -1;
}
-
+
ASTOBJ_INIT(mwi);
ast_string_field_set(mwi, username, username);
if (secret) {
@@ -7775,10 +7778,10 @@ static int sip_subscribe_mwi(const char *value, int lineno)
mwi->resub = -1;
mwi->portno = portnum;
mwi->transport = transport;
-
+
ASTOBJ_CONTAINER_LINK(&submwil, mwi);
ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
-
+
return 0;
}
@@ -28504,6 +28507,157 @@ static void sip_unregister_tests(void)
}
#ifdef TEST_FRAMEWORK
+AST_TEST_DEFINE(test_sip_mwi_subscribe_parse)
+{
+ int found = 0;
+ enum ast_test_result_state res = AST_TEST_PASS;
+ const char *mwi1 = "1234@mysipprovider.com/1234";
+ const char *mwi2 = "1234:password@mysipprovider.com/1234";
+ const char *mwi3 = "1234:password@mysipprovider.com:5061/1234";
+ const char *mwi4 = "1234:password:authuser@mysipprovider.com/1234";
+ const char *mwi5 = "1234:password:authuser@mysipprovider.com:5061/1234";
+ const char *mwi6 = "1234:password";
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "sip_mwi_subscribe_parse_test";
+ info->category = "/channels/chan_sip/";
+ info->summary = "SIP MWI subscribe line parse unit test";
+ info->description =
+ "Tests the parsing of mwi subscription lines (e.g., mwi => from sip.conf)";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (sip_subscribe_mwi(mwi1, 1)) {
+ res = AST_TEST_FAIL;
+ } else {
+ found = 0;
+ res = AST_TEST_FAIL;
+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+ ASTOBJ_WRLOCK(iterator);
+ if (
+ !strcmp(iterator->hostname, "mysipprovider.com") &&
+ !strcmp(iterator->username, "1234") &&
+ !strcmp(iterator->secret, "") &&
+ !strcmp(iterator->authuser, "") &&
+ !strcmp(iterator->mailbox, "1234") &&
+ iterator->portno == 0) {
+ found = 1;
+ res = AST_TEST_PASS;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ if (!found) {
+ ast_test_status_update(test, "sip_subscribe_mwi test 1 failed\n");
+ }
+ }
+
+ if (sip_subscribe_mwi(mwi2, 1)) {
+ res = AST_TEST_FAIL;
+ } else {
+ found = 0;
+ res = AST_TEST_FAIL;
+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+ ASTOBJ_WRLOCK(iterator);
+ if (
+ !strcmp(iterator->hostname, "mysipprovider.com") &&
+ !strcmp(iterator->username, "1234") &&
+ !strcmp(iterator->secret, "password") &&
+ !strcmp(iterator->authuser, "") &&
+ !strcmp(iterator->mailbox, "1234") &&
+ iterator->portno == 0) {
+ found = 1;
+ res = AST_TEST_PASS;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ if (!found) {
+ ast_test_status_update(test, "sip_subscribe_mwi test 2 failed\n");
+ }
+ }
+
+ if (sip_subscribe_mwi(mwi3, 1)) {
+ res = AST_TEST_FAIL;
+ } else {
+ found = 0;
+ res = AST_TEST_FAIL;
+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+ ASTOBJ_WRLOCK(iterator);
+ if (
+ !strcmp(iterator->hostname, "mysipprovider.com") &&
+ !strcmp(iterator->username, "1234") &&
+ !strcmp(iterator->secret, "password") &&
+ !strcmp(iterator->authuser, "") &&
+ !strcmp(iterator->mailbox, "1234") &&
+ iterator->portno == 5061) {
+ found = 1;
+ res = AST_TEST_PASS;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ if (!found) {
+ ast_test_status_update(test, "sip_subscribe_mwi test 3 failed\n");
+ }
+ }
+
+ if (sip_subscribe_mwi(mwi4, 1)) {
+ res = AST_TEST_FAIL;
+ } else {
+ found = 0;
+ res = AST_TEST_FAIL;
+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+ ASTOBJ_WRLOCK(iterator);
+ if (
+ !strcmp(iterator->hostname, "mysipprovider.com") &&
+ !strcmp(iterator->username, "1234") &&
+ !strcmp(iterator->secret, "password") &&
+ !strcmp(iterator->authuser, "authuser") &&
+ !strcmp(iterator->mailbox, "1234") &&
+ iterator->portno == 0) {
+ found = 1;
+ res = AST_TEST_PASS;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ if (!found) {
+ ast_test_status_update(test, "sip_subscribe_mwi test 4 failed\n");
+ }
+ }
+
+ if (sip_subscribe_mwi(mwi5, 1)) {
+ res = AST_TEST_FAIL;
+ } else {
+ found = 0;
+ res = AST_TEST_FAIL;
+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+ ASTOBJ_WRLOCK(iterator);
+ if (
+ !strcmp(iterator->hostname, "mysipprovider.com") &&
+ !strcmp(iterator->username, "1234") &&
+ !strcmp(iterator->secret, "password") &&
+ !strcmp(iterator->authuser, "authuser") &&
+ !strcmp(iterator->mailbox, "1234") &&
+ iterator->portno == 5061) {
+ found = 1;
+ res = AST_TEST_PASS;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ if (!found) {
+ ast_test_status_update(test, "sip_subscribe_mwi test 5 failed\n");
+ }
+ }
+
+ if (sip_subscribe_mwi(mwi6, 1)) {
+ res = AST_TEST_PASS;
+ } else {
+ res = AST_TEST_FAIL;
+ }
+ return res;
+}
+
AST_TEST_DEFINE(test_sip_peers_get)
{
struct sip_peer *peer;
@@ -28782,6 +28936,7 @@ static int load_module(void)
#ifdef TEST_FRAMEWORK
AST_TEST_REGISTER(test_sip_peers_get);
+ AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
#endif
/* Register AstData providers */
@@ -28892,6 +29047,7 @@ static int unload_module(void)
#ifdef TEST_FRAMEWORK
AST_TEST_UNREGISTER(test_sip_peers_get);
+ AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
#endif
/* Unregister all the AstData providers */
ast_data_unregister(NULL);
diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
index 320895669..03008b146 100644
--- a/configs/sip.conf.sample
+++ b/configs/sip.conf.sample
@@ -680,12 +680,15 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;----------------------------------------- OUTBOUND MWI SUBSCRIPTIONS -------------------------
; Asterisk can subscribe to receive the MWI from another SIP server and store it locally for retrieval
-; by other phones.
+; by other phones. At this time, you can only subscribe using UDP as the transport.
; Format for the mwi register statement is:
-; mwi => user[:secret[:authuser]]@host[:port][/mailbox]
+; mwi => user[:secret[:authuser]]@host[:port]/mailbox
;
; Examples:
;mwi => 1234:password@mysipprovider.com/1234
+;mwi => 1234:password@myportprovider.com:6969/1234
+;mwi => 1234:password:authuser@myauthprovider.com/1234
+;mwi => 1234:password:authuser@myauthportprovider.com:6969/1234
;
; MWI received will be stored in the 1234 mailbox of the SIP_Remote context. It can be used by other phones by following the below:
; mailbox=1234@SIP_Remote