static int changrab_exec(struct cw_channel *chan, int argc, char **argv) { int res=0; struct localuser *u; struct cw_channel *newchan; struct cw_channel *oldchan; struct cw_frame *f; struct cw_bridge_config config; if (argc < 1 || argc > 2) { cw_log(LOG_ERROR, "Syntax: %s\n", changrab_syntax); return -1; } if ((oldchan = my_cw_get_channel_by_name_locked(argv[0]))) { cw_mutex_unlock(&oldchan->lock); } else { cw_log(LOG_WARNING, "No Such Channel: %s\n", argv[0]); return -1; } if (argc > 1) { if (oldchan->_bridge && strchr(argv[1], 'b')) oldchan = oldchan->_bridge; if (strchr(argv[1],'r') && oldchan->_state == CW_STATE_UP) return -1; } LOCAL_USER_ADD(u); newchan = cw_channel_alloc(0); snprintf(newchan->name, sizeof (newchan->name), "ChanGrab/%s",oldchan->name); newchan->readformat = oldchan->readformat; newchan->writeformat = oldchan->writeformat; cw_channel_masquerade(newchan, oldchan); if((f = cw_read(newchan))) { cw_fr_free(f); memset(&config,0,sizeof(struct cw_bridge_config)); cw_set_flag(&(config.features_callee), CW_FEATURE_REDIRECT); cw_set_flag(&(config.features_caller), CW_FEATURE_REDIRECT); if(newchan->_state != CW_STATE_UP) { cw_answer(newchan); } chan->appl = "Bridged Call"; res = cw_bridge_call(chan, newchan, &config); cw_hangup(newchan); } LOCAL_USER_REMOVE(u); return res ? 0 : -1; }
static void *playtones_alloc(struct cw_channel *chan, void *params) { struct playtones_def *pd = params; struct playtones_state *ps; if ((ps = malloc(sizeof(*ps))) == NULL) return NULL; memset(ps, 0, sizeof(*ps)); ps->origwfmt = chan->writeformat; if (cw_set_write_format(chan, CW_FORMAT_SLINEAR)) { cw_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); playtones_release(NULL, ps); ps = NULL; } else { struct playtones_item *pi; ps->vol = pd->vol; ps->reppos = pd->reppos; ps->nitems = pd->nitems; ps->items = pd->items; /* Initialize the tone generator */ pi = &pd->items[0]; tone_setup(ps, pi); } /* Let interrupts interrupt :) */ if (pd->interruptible) cw_set_flag(chan, CW_FLAG_WRITE_INT); else cw_clear_flag(chan, CW_FLAG_WRITE_INT); return ps; }
static void *linear_alloc(struct cw_channel *chan, void *params) { struct linear_state *ls; /* In this case, params is already malloc'd */ if (params) { ls = params; if (ls->allowoverride) cw_set_flag(chan, CW_FLAG_WRITE_INT); else cw_clear_flag(chan, CW_FLAG_WRITE_INT); ls->origwfmt = chan->writeformat; if (cw_set_write_format(chan, CW_FORMAT_SLINEAR)) { cw_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name); free(ls); ls = params = NULL; } } return params; }