aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xCHANGES7
-rwxr-xr-xHARDWARE6
-rwxr-xr-xapps/app_meetme.c28
-rwxr-xr-xasterisk.c4
-rwxr-xr-xchannels/chan_mgcp.c8
-rwxr-xr-xmuted.c12
-rwxr-xr-xpbx.c12
-rwxr-xr-xres/res_features.c108
-rwxr-xr-xsounds/fpm-sunshine.mp3bin0 -> 2584668 bytes
9 files changed, 158 insertions, 27 deletions
diff --git a/CHANGES b/CHANGES
index cf21e7222..b4ea88b15 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+ -- Additional CDR backends
+ -- Allow muted to reconnect
+ -- Call parking improvements (including SIP parking support)
+ -- Added licensed hold music from FreePlayMusic
+ -- GR-303 and Zap improvements
+ -- More bug fixes from the bug tracker
+ -- Improved FreeBSD/OpenBSD/MacOS X support
Asterisk 1.0-RC1
-- Innumerable bug fixes and features from the bug tracker
-- Added Open Settlement Protocol (OSP) support
diff --git a/HARDWARE b/HARDWARE
index 990d054e8..86b28bef7 100755
--- a/HARDWARE
+++ b/HARDWARE
@@ -16,11 +16,11 @@ Zaptel compatible hardware
* Wildcard X100P - Single FXO interface connects to Loopstart phone
line
- * Wildcard T400P - Quad T1 interface connects to four T1/PRI
+ * Wildcard T400P (obsolete) - Quad T1 interface connects to four T1/PRI
interfaces. Supports RBS and PRI voice and PPP, FR, and HDLC data.
- * Wildcard E400P - Quad E1 interface connects to four E1/PRI (or PRA)
- interfaces. Supports PRA/PRI, EuroISDN voice and PPP, FR, HDLC data.
+ * Wildcard E400P (obsolete)- Quad E1 interface connects to four E1/PRI
+ (or PRA) interfaces. Supports PRA/PRI, EuroISDN voice and data.
* Wildcard T100P - Single T1 interface connects to a single T1/PRI
interface. Supports RBS and PRI voice and PPP, FR, and HDLC data.
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index bb7aa8e30..6b03b97de 100755
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -59,6 +59,9 @@ static char *descrip =
" 'm' -- set monitor only mode (Listen only, no talking)\n"
" 't' -- set talk only mode. (Talk only, no listening)\n"
" 'p' -- allow user to exit the conference by pressing '#'\n"
+" 'X' -- allow user to exit the conference by entering a valid single\n"
+" digit extension ${MEETME_EXIT_CONTEXT} or the current context\n"
+" if that variable is not defined.\n"
" 'd' -- dynamically add conference\n"
" 'D' -- dynamically add conference, prompting for a PIN\n"
" 'e' -- select an empty conference\n"
@@ -148,6 +151,7 @@ static int admin_exec(struct ast_channel *chan, void *data);
#define CONFFLAG_MOH (1 << 9) /* Set to have music on hold when user is alone in conference */
#define CONFFLAG_ADMINEXIT (1 << 10) /* If set the MeetMe will return if all marked with this flag left */
#define CONFFLAG_WAITMARKED (1 << 11) /* If set, the MeetMe will wait until a marked user enters */
+#define CONFFLAG_EXIT_CONTEXT (1 << 12) /* If set, the MeetMe will wait until a marked user enters */
static int careful_write(int fd, unsigned char *data, int len)
@@ -504,6 +508,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
char *agifile;
char *agifiledefault = "conf-background.agi";
char meetmesecs[30] = "";
+ char exitcontext[AST_MAX_EXTENSION] = "";
ZT_BUFFERINFO bi;
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
@@ -560,6 +565,14 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
user->adminflags = 0;
ast_mutex_unlock(&conflock);
origquiet = confflags & CONFFLAG_QUIET;
+ if (confflags & CONFFLAG_EXIT_CONTEXT) {
+ if ((agifile = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT")))
+ strncpy(exitcontext, agifile, sizeof(exitcontext) - 1);
+ else if (!ast_strlen_zero(chan->macrocontext))
+ strncpy(exitcontext, chan->macrocontext, sizeof(exitcontext) - 1);
+ else
+ strncpy(exitcontext, chan->context, sizeof(exitcontext) - 1);
+ }
while((confflags & CONFFLAG_WAITMARKED) && (conf->markedusers < 0)) {
confflags &= ~CONFFLAG_QUIET;
confflags |= origquiet;
@@ -806,7 +819,18 @@ zapretry:
f = ast_read(c);
if (!f)
break;
- if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#') && (confflags & CONFFLAG_POUNDEXIT)) {
+ if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
+ char tmp[2];
+ tmp[0] = f->subclass;
+ tmp[1] = '\0';
+ if (ast_exists_extension(chan, exitcontext, tmp, 1, chan->callerid)) {
+ strncpy(chan->context, exitcontext, sizeof(chan->context) - 1);
+ strncpy(chan->exten, tmp, sizeof(chan->exten) - 1);
+ chan->priority = 0;
+ ret = 0;
+ break;
+ }
+ } else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#') && (confflags & CONFFLAG_POUNDEXIT)) {
ret = 0;
break;
} else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*') && (confflags & CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_active)) {
@@ -1187,6 +1211,8 @@ static int conf_exec(struct ast_channel *chan, void *data)
confflags |= CONFFLAG_MOH;
if (strchr(inflags, 'x'))
confflags |= CONFFLAG_ADMINEXIT;
+ if (strchr(inflags, 'X'))
+ confflags |= CONFFLAG_EXIT_CONTEXT;
if (strchr(inflags, 'b'))
confflags |= CONFFLAG_AGI;
if (strchr(inflags, 'w'))
diff --git a/asterisk.c b/asterisk.c
index 575ddbcb1..62b01c159 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -689,7 +689,7 @@ static int remoteconsolehandler(char *s)
{
int ret = 0;
/* Called when readline data is available */
- if (s && !ast_strlen_zero(s))
+ if (s && !ast_all_zeros(s))
ast_el_add_history(s);
/* Give the console access to the shell */
if (s) {
@@ -1341,6 +1341,8 @@ static int ast_el_read_history(char *filename)
fgets(buf, sizeof(buf), f);
if (!strcmp(buf, "_HiStOrY_V2_\n"))
continue;
+ if (ast_all_zeros(buf))
+ continue;
if ((ret = ast_el_add_history(buf)) == -1)
break;
}
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 8adeede3c..f30e4ab4a 100755
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -2808,9 +2808,9 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
}
} else {
if (p->hookstate == MGCP_OFFHOOK) {
- ast_log(LOG_WARNING, "Off hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
+ ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name);
} else {
- ast_log(LOG_WARNING, "On hook, but alreaedy have owner on %s@%s\n", p->name, p->parent->name);
+ ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?");
}
if (sub->owner->bridge) {
@@ -2921,8 +2921,8 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
/* Thanks to point on IRC for pointing this out */
return -1;
}
- /* do not let * confrnce two down channels */
- if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) return -1;
+ /* do not let * confrnce two down channels */
+ if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) return -1;
if (p->callwaiting || p->transfer || p->threewaycalling) {
if (option_verbose > 2) {
diff --git a/muted.c b/muted.c
index a039fb451..ac8d5d957 100755
--- a/muted.c
+++ b/muted.c
@@ -535,8 +535,16 @@ int main(int argc, char *argv[])
if (needfork)
daemon(0,0);
for(;;) {
- if (wait_event())
- exit(1);
+ if (wait_event()) {
+ fclose(astf);
+ while(connect_asterisk()) {
+ sleep(5);
+ }
+ if (login_asterisk()) {
+ fclose(astf);
+ exit(1);
+ }
+ }
}
exit(0);
}
diff --git a/pbx.c b/pbx.c
index 1a18208fd..c39d7e104 100755
--- a/pbx.c
+++ b/pbx.c
@@ -1,4 +1,4 @@
-/*
+ /*
* Asterisk -- A telephony toolkit for Linux.
*
* Core PBX routines.
@@ -2044,7 +2044,7 @@ int ast_context_remove_include2(struct ast_context *con, char *include, char *re
while (i) {
/* find our include */
if (!strcmp(i->name, include) &&
- (!strcmp(i->registrar, registrar) || !registrar)) {
+ (!registrar || !strcmp(i->registrar, registrar))) {
/* remove from list */
if (pi)
pi->next = i->next;
@@ -2116,7 +2116,7 @@ int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, ch
while (i) {
/* find our switch */
if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
- (!strcmp(i->registrar, registrar) || !registrar)) {
+ (!registrar || !strcmp(i->registrar, registrar))) {
/* remove from list */
if (pi)
pi->next = i->next;
@@ -2189,7 +2189,7 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
/* look for right extension */
if (!strcmp(exten->exten, extension) &&
- (!strcmp(exten->registrar, registrar) || !registrar)) {
+ (!registrar || !strcmp(exten->registrar, registrar))) {
struct ast_exten *peer;
/* should we free all peers in this extension? (priority == 0)? */
@@ -2224,7 +2224,7 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
while (peer) {
/* is this our extension? */
if (peer->priority == priority &&
- (!strcmp(peer->registrar, registrar) || !registrar)) {
+ (!registrar || !strcmp(peer->registrar, registrar) )) {
/* we are first priority extension? */
if (!previous_peer) {
/* exists previous extension here? */
@@ -3459,7 +3459,7 @@ int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char
ip = con->ignorepats;
while (ip) {
if (!strcmp(ip->pattern, ignorepat) &&
- (registrar == ip->registrar || !registrar)) {
+ (!registrar || (registrar == ip->registrar))) {
if (ipl) {
ipl->next = ip->next;
free(ip);
diff --git a/res/res_features.c b/res/res_features.c
index f6b4dfcda..b8639f614 100755
--- a/res/res_features.c
+++ b/res/res_features.c
@@ -62,7 +62,7 @@ static int parking_stop = 750;
static int transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
/* Registrar for operations */
-static char *registrar = "res_parking";
+static char *registrar = "res_features";
static char *synopsis = "Answer a parked call";
@@ -72,6 +72,18 @@ static char *descrip = "ParkedCall(exten):"
"into the dialplan, although you should include the 'parkedcalls'\n"
"context.\n";
+
+static char *parkcall = "Park";
+
+static char *synopsis2 = "Park yourself";
+
+static char *descrip2 = "Park(exten):"
+"Used to park yourself (typically in combination with a supervised\n"
+"transfer to know the parking space. This Application is always\n"
+"registered internally and does not need to be explicitly added\n"
+"into the dialplan, although you should include the 'parkedcalls'\n"
+"context.\n";
+
struct parkeduser {
struct ast_channel *chan;
struct timeval start;
@@ -81,6 +93,7 @@ struct parkeduser {
char exten[AST_MAX_EXTENSION];
int priority;
int parkingtime;
+ int notquiteyet;
struct parkeduser *next;
};
@@ -110,6 +123,8 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
after these channels too */
struct parkeduser *pu, *cur;
int x;
+ char exten[AST_MAX_EXTENSION];
+ struct ast_context *con;
pu = malloc(sizeof(struct parkeduser));
if (pu) {
ast_mutex_lock(&parking_lock);
@@ -129,7 +144,8 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu->chan = chan;
/* Start music on hold */
- ast_moh_start(pu->chan, NULL);
+ if (chan != peer)
+ ast_moh_start(pu->chan, NULL);
gettimeofday(&pu->start, NULL);
pu->parkingnum = x;
if (timeout > 0)
@@ -154,6 +170,9 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu->priority = chan->priority;
pu->next = parkinglot;
parkinglot = pu;
+ /* If parking a channel directly, don't quiet yet get parking running on it */
+ if (peer == chan)
+ pu->notquiteyet = 1;
ast_mutex_unlock(&parking_lock);
/* Wake up the (presumably select()ing) thread */
pthread_kill(parking_thread, SIGURG);
@@ -171,8 +190,26 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
,(pu->chan->callerid ? pu->chan->callerid : "")
);
- if (peer)
+ if (peer) {
ast_say_digits(peer, pu->parkingnum, "", peer->language);
+ if (pu->notquiteyet) {
+ /* Wake up parking thread if we're really done */
+ ast_moh_start(pu->chan, NULL);
+ pu->notquiteyet = 0;
+ pthread_kill(parking_thread, SIGURG);
+ }
+ }
+ con = ast_context_find(parking_con);
+ if (!con) {
+ con = ast_context_create(NULL,parking_con, registrar);
+ if (!con) {
+ ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
+ }
+ }
+ if (con) {
+ snprintf(exten, sizeof(exten), "%d", x);
+ ast_add_extension2(con, 1, exten, 1, NULL, parkedcall, strdup(exten), free, registrar);
+ }
return 0;
} else {
ast_log(LOG_WARNING, "No more parking spaces\n");
@@ -441,6 +478,8 @@ static void *do_parking_thread(void *ignore)
struct parkeduser *pu, *pl, *pt = NULL;
struct timeval tv;
struct ast_frame *f;
+ char exten[AST_MAX_EXTENSION];
+ struct ast_context *con;
int x;
fd_set rfds, efds;
fd_set nrfds, nefds;
@@ -456,6 +495,12 @@ static void *do_parking_thread(void *ignore)
FD_ZERO(&nrfds);
FD_ZERO(&nefds);
while(pu) {
+ if (pu->notquiteyet) {
+ /* Pretend this one isn't here yet */
+ pl = pu;
+ pu = pu->next;
+ continue;
+ }
tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000;
if (tms > pu->parkingtime) {
/* They've been waiting too long, send them back to where they came. Theoretically they
@@ -477,6 +522,13 @@ static void *do_parking_thread(void *ignore)
parkinglot = pu->next;
pt = pu;
pu = pu->next;
+ con = ast_context_find(parking_con);
+ if (con) {
+ snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
+ if (ast_context_remove_extension2(con, exten, 1, NULL))
+ ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ } else
+ ast_log(LOG_WARNING, "Whoa, no parking context?\n");
free(pt);
} else {
for (x=0;x<AST_MAX_FDS;x++) {
@@ -498,6 +550,13 @@ static void *do_parking_thread(void *ignore)
parkinglot = pu->next;
pt = pu;
pu = pu->next;
+ con = ast_context_find(parking_con);
+ if (con) {
+ snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
+ if (ast_context_remove_extension2(con, exten, 1, NULL))
+ ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ } else
+ ast_log(LOG_WARNING, "Whoa, no parking context?\n");
free(pt);
break;
} else {
@@ -537,12 +596,37 @@ std: for (x=0;x<AST_MAX_FDS;x++) {
return NULL; /* Never reached */
}
+static int park_call_exec(struct ast_channel *chan, void *data)
+{
+ /* Data is unused at the moment but could contain a parking
+ lot context eventually */
+ int res=0;
+ struct localuser *u;
+ LOCAL_USER_ADD(u);
+ /* Setup the exten/priority to be s/1 since we don't know
+ where this call should return */
+ strcpy(chan->exten, "s");
+ chan->priority = 1;
+ if (chan->_state != AST_STATE_UP)
+ res = ast_answer(chan);
+ if (!res)
+ res = ast_safe_sleep(chan, 1000);
+ if (!res)
+ res = ast_park_call(chan, chan, 0, NULL);
+ LOCAL_USER_REMOVE(u);
+ if (!res)
+ res = AST_PBX_KEEPALIVE;
+ return res;
+}
+
static int park_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *peer=NULL;
struct parkeduser *pu, *pl=NULL;
+ char exten[AST_MAX_EXTENSION];
+ struct ast_context *con;
int park;
int dres;
struct ast_bridge_config config;
@@ -569,6 +653,13 @@ static int park_exec(struct ast_channel *chan, void *data)
ast_mutex_unlock(&parking_lock);
if (pu) {
peer = pu->chan;
+ con = ast_context_find(parking_con);
+ if (con) {
+ snprintf(exten, sizeof(exten), "%d", pu->parkingnum);
+ if (ast_context_remove_extension2(con, exten, 1, NULL))
+ ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ } else
+ ast_log(LOG_WARNING, "Whoa, no parking context?\n");
free(pu);
}
/* JK02: it helps to answer the channel if not already up */
@@ -696,10 +787,8 @@ static int manager_parking_status( struct mansession *s, struct message *m )
int load_module(void)
{
int res;
- int x;
int start, end;
struct ast_context *con;
- char exten[AST_MAX_EXTENSION];
struct ast_config *cfg;
struct ast_variable *var;
@@ -750,12 +839,11 @@ int load_module(void)
return -1;
}
}
- for(x=parking_start; x<=parking_stop;x++) {
- snprintf(exten, sizeof(exten), "%d", x);
- ast_add_extension2(con, 1, exten, 1, NULL, parkedcall, strdup(exten), free, registrar);
- }
+ ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, parkcall, strdup(""),free, registrar);
pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
+ if (!res)
+ res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
if (!res) {
ast_manager_register( "ParkedCalls", 0, manager_parking_status, "List parked calls" );
}
@@ -802,7 +890,7 @@ int unload_module(void)
ast_manager_unregister( "ParkedCalls" );
ast_cli_unregister(&showparked);
-
+ ast_unregister_application(parkcall);
return ast_unregister_application(parkedcall);
}
diff --git a/sounds/fpm-sunshine.mp3 b/sounds/fpm-sunshine.mp3
new file mode 100755
index 000000000..f572cf344
--- /dev/null
+++ b/sounds/fpm-sunshine.mp3
Binary files differ