diff options
-rwxr-xr-x | CHANGES | 7 | ||||
-rwxr-xr-x | HARDWARE | 6 | ||||
-rwxr-xr-x | apps/app_meetme.c | 28 | ||||
-rwxr-xr-x | asterisk.c | 4 | ||||
-rwxr-xr-x | channels/chan_mgcp.c | 8 | ||||
-rwxr-xr-x | muted.c | 12 | ||||
-rwxr-xr-x | pbx.c | 12 | ||||
-rwxr-xr-x | res/res_features.c | 108 | ||||
-rwxr-xr-x | sounds/fpm-sunshine.mp3 | bin | 0 -> 2584668 bytes |
9 files changed, 158 insertions, 27 deletions
@@ -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 @@ -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) { @@ -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); } @@ -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 Binary files differnew file mode 100755 index 000000000..f572cf344 --- /dev/null +++ b/sounds/fpm-sunshine.mp3 |