diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 297c578c1e..0eb9bab93e 100755 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -15,6 +15,7 @@ * the GNU General Public License */ +#include #include #include #include @@ -55,16 +56,11 @@ static struct timeval lasttime; static int usecnt; -static int needanswer = 0; -static int needringing = 0; -static int needhangup = 0; static int silencesuppression = 0; static int silencethreshold = 1000; -static char digits[80] = ""; -static char text2send[80] = ""; -static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER; static char *type = "Console"; static char *desc = "OSS Console Channel Driver"; @@ -75,9 +71,6 @@ static char context[AST_MAX_EXTENSION] = "default"; static char language[MAX_LANGUAGE] = ""; static char exten[AST_MAX_EXTENSION] = "s"; -/* Command pipe */ -static int cmd[2]; - int hookstate=0; static short silence[FRAME_SIZE] = {0, }; @@ -433,13 +426,18 @@ static int oss_text(struct ast_channel *c, char *text) static int oss_call(struct ast_channel *c, char *dest, int timeout) { int res = 3; + struct ast_frame f = { 0, }; ast_verbose( " << Call placed to '%s' on console >> \n", dest); if (autoanswer) { ast_verbose( " << Auto-answered >> \n" ); - needanswer = 1; + f.frametype = AST_FRAME_CONTROL; + f.subclass = AST_CONTROL_ANSWER; + ast_queue_frame(c, &f, 0); } else { ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n"); - needringing = 1; + f.frametype = AST_FRAME_CONTROL; + f.subclass = AST_CONTROL_RINGING; + ast_queue_frame(c, &f, 0); write(sndcmd[1], &res, sizeof(res)); } return 0; @@ -465,7 +463,7 @@ static int oss_answer(struct ast_channel *c) static int oss_hangup(struct ast_channel *c) { - int res; + int res = 0; cursound = -1; c->pvt->pvt = NULL; oss.owner = NULL; @@ -473,8 +471,6 @@ static int oss_hangup(struct ast_channel *c) ast_pthread_mutex_lock(&usecnt_lock); usecnt--; ast_pthread_mutex_unlock(&usecnt_lock); - needhangup = 0; - needanswer = 0; if (hookstate) { if (autoanswer) { /* Assume auto-hangup too */ @@ -535,7 +531,7 @@ static int oss_write(struct ast_channel *chan, struct ast_frame *f) return 0; /* Stop any currently playing sound */ cursound = -1; - if (!full_duplex && (strlen(digits) || needhangup || needanswer)) { + if (!full_duplex) { /* If we're half duplex, we have to switch to read mode to honor immediate needs if necessary */ res = soundcard_setinput(1); @@ -578,18 +574,11 @@ static struct ast_frame *oss_read(struct ast_channel *chan) static char buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET]; static int readpos = 0; int res; - int b; - int nonull=0; #if 0 ast_log(LOG_DEBUG, "oss_read()\n"); #endif - - /* Acknowledge any pending cmd */ - res = read(cmd[0], &b, sizeof(b)); - if (res > 0) - nonull = 1; - + f.frametype = AST_FRAME_NULL; f.subclass = 0; f.timelen = 0; @@ -599,44 +588,6 @@ static struct ast_frame *oss_read(struct ast_channel *chan) f.src = type; f.mallocd = 0; - if (needringing) { - f.frametype = AST_FRAME_CONTROL; - f.subclass = AST_CONTROL_RINGING; - needringing = 0; - return &f; - } - - if (needhangup) { - needhangup = 0; - return NULL; - } - if (strlen(text2send)) { - f.frametype = AST_FRAME_TEXT; - f.subclass = 0; - f.data = text2send; - f.datalen = strlen(text2send); - strcpy(text2send,""); - return &f; - } - if (strlen(digits)) { - f.frametype = AST_FRAME_DTMF; - f.subclass = digits[0]; - for (res=0;resstate = AST_STATE_UP; - return &f; - } - - if (nonull) - return &f; - res = soundcard_setinput(0); if (res < 0) { ast_log(LOG_WARNING, "Unable to set input mode\n"); @@ -715,12 +666,11 @@ static int oss_indicate(struct ast_channel *chan, int cond) static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state) { struct ast_channel *tmp; - tmp = ast_channel_alloc(); + tmp = ast_channel_alloc(1); if (tmp) { snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5); tmp->type = type; tmp->fds[0] = sounddev; - tmp->fds[1] = cmd[0]; tmp->nativeformats = AST_FORMAT_SLINEAR; tmp->pvt->pvt = p; tmp->pvt->send_digit = oss_digit; @@ -819,6 +769,7 @@ static char autoanswer_usage[] = static int console_answer(int fd, int argc, char *argv[]) { + struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; if (argc != 1) return RESULT_SHOWUSAGE; if (!oss.owner) { @@ -827,7 +778,7 @@ static int console_answer(int fd, int argc, char *argv[]) } hookstate = 1; cursound = -1; - needanswer++; + ast_queue_frame(oss.owner, &f, 1); answer_sound(); return RESULT_SUCCESS; } @@ -839,6 +790,8 @@ static char sendtext_usage[] = static int console_sendtext(int fd, int argc, char *argv[]) { int tmparg = 1; + char text2send[256]; + struct ast_frame f = { 0, }; if (argc < 1) return RESULT_SHOWUSAGE; if (!oss.owner) { @@ -852,7 +805,13 @@ static int console_sendtext(int fd, int argc, char *argv[]) strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send)); strncat(text2send, " ", sizeof(text2send) - strlen(text2send)); } - needanswer++; + if (strlen(text2send)) { + f.frametype = AST_FRAME_TEXT; + f.subclass = 0; + f.data = text2send; + f.datalen = strlen(text2send); + ast_queue_frame(oss.owner, &f, 1); + } return RESULT_SUCCESS; } @@ -870,8 +829,9 @@ static int console_hangup(int fd, int argc, char *argv[]) return RESULT_FAILURE; } hookstate = 0; - if (oss.owner) - needhangup++; + if (oss.owner) { + ast_queue_hangup(oss.owner, 1); + } return RESULT_SUCCESS; } @@ -884,14 +844,16 @@ static int console_dial(int fd, int argc, char *argv[]) { char tmp[256], *tmp2; char *mye, *myc; - int b = 0; + int x; + struct ast_frame f = { AST_FRAME_DTMF, 0 }; if ((argc != 1) && (argc != 2)) return RESULT_SHOWUSAGE; if (oss.owner) { if (argc == 2) { - strncat(digits, argv[1], sizeof(digits) - strlen(digits)); - /* Wake up the polling thread */ - write(cmd[1], &b, sizeof(b)); + for (x=0;x 1) { ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n"); ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding 'noload=chan_oss.so' in /etc/asterisk/modules.conf\n"); @@ -999,10 +953,6 @@ int unload_module() for (x=0;x 0) { - close(cmd[0]); - close(cmd[1]); - } if (sndcmd[0] > 0) { close(sndcmd[0]); close(sndcmd[1]); diff --git a/io.c b/io.c index 91aec690b4..dd4acf628a 100755 --- a/io.c +++ b/io.c @@ -196,7 +196,7 @@ static int io_shrink(struct io_context *ioc, int which) int ast_io_remove(struct io_context *ioc, int *id) { if (ioc->current_ioc == *id) { - ast_log(LOG_NOTICE, "Callback for %d tried to remove itself\n", *id); + ast_log(LOG_NOTICE, "Callback for %d tried to remove itself (%p)\n", *id, id); } else if (*id < ioc->fdcnt) { @@ -225,6 +225,7 @@ int ast_io_wait(struct io_context *ioc, int howlong) for(x=0;xfdcnt;x++) { if (ioc->fds[x].revents) { /* There's an event waiting */ + ioc->current_ioc = *ioc->ior[x].id; if (!ioc->ior[x].callback(ioc->ior[x].id, ioc->fds[x].fd, ioc->fds[x].revents, ioc->ior[x].data)) { /* Time to delete them since they returned a 0 */ diff --git a/res/res_parking.c b/res/res_parking.c index 034efa0f17..f61b253065 100755 --- a/res/res_parking.c +++ b/res/res_parking.c @@ -11,6 +11,7 @@ * the GNU General Public License */ +#include #include #include #include @@ -21,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -74,7 +77,7 @@ struct parkeduser { static struct parkeduser *parkinglot; -static pthread_mutex_t parking_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t parking_lock = AST_MUTEX_INITIALIZER; static pthread_t parking_thread; @@ -108,6 +111,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer) } if (x <= parking_stop) { pu->chan = chan; + ast_moh_start(pu->chan, NULL); gettimeofday(&pu->start, NULL); pu->parkingnum = x; /* Remember what had been dialed, so that if the parking @@ -123,6 +127,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer) if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d\n", pu->chan->name, pu->parkingnum); ast_say_digits(peer, pu->parkingnum, "", peer->language); + /* Start music on hold */ return 0; } else { ast_log(LOG_WARNING, "No more parking spaces\n"); @@ -142,7 +147,7 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer) struct ast_channel *chan; struct ast_frame *f; /* Make a new, fake channel that we'll use to masquerade in the real one */ - chan = ast_channel_alloc(); + chan = ast_channel_alloc(0); if (chan) { /* Let us keep track of the channel name */ snprintf(chan->name, sizeof (chan->name), "Parked/%s",rchan->name); @@ -317,6 +322,8 @@ static void *do_parking_thread(void *ignore) strncpy(pu->chan->exten, pu->exten, sizeof(pu->chan->exten)-1); strncpy(pu->chan->context, pu->context, sizeof(pu->chan->context)-1); pu->chan->priority = pu->priority; + /* Stop music on hold */ + ast_moh_stop(pu->chan); /* Start up the PBX, or hang them up */ if (ast_pbx_start(pu->chan)) { ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name); @@ -420,6 +427,7 @@ static int park_exec(struct ast_channel *chan, void *data) free(pu); } if (peer) { + ast_moh_stop(peer); res = ast_channel_make_compatible(chan, peer); if (res < 0) { ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name); @@ -449,8 +457,31 @@ 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; + cfg = ast_load("parking.conf"); + if (cfg) { + var = ast_variable_browse(cfg, "general"); + while(var) { + if (!strcasecmp(var->name, "parkext")) { + strncpy(parking_ext, var->value, sizeof(parking_ext) - 1); + } else if (!strcasecmp(var->name, "context")) { + strncpy(parking_con, var->value, sizeof(parking_con) - 1); + } else if (!strcasecmp(var->name, "parkpos")) { + if (sscanf(var->value, "%i-%i", &start, &end) != 2) { + ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of parking.conf\n", var->lineno); + } else { + parking_start = start; + parking_stop = end; + } + } + var = var->next; + } + ast_destroy(cfg); + } con = ast_context_find(parking_con); if (!con) { con = ast_context_create(parking_con, registrar);