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 int changrab_cli(int fd, int argc, char *argv[]) { char *chan_name_1, *chan_name_2 = NULL, *context,*exten,*flags=NULL; char *pria = NULL; struct cw_channel *xferchan_1, *xferchan_2; int pri=0,x=1; if(argc < 3) { cw_cli(fd,CGUSAGE); return -1; } chan_name_1 = argv[x++]; if(chan_name_1[0] == '-') { flags = cw_strdupa(chan_name_1); if (strchr(flags,'h')) { chan_name_1 = argv[x++]; if((xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1))) { cw_mutex_unlock(&xferchan_1->lock); cw_hangup(xferchan_1); cw_verbose("OK, good luck!\n"); return 0; } else return -1; } else if (strchr(flags,'m') || strchr(flags,'M')) { chan_name_1 = argv[x++]; if((xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1))) { cw_mutex_unlock(&xferchan_1->lock); strchr(flags,'m') ? cw_moh_start(xferchan_1,NULL) : cw_moh_stop(xferchan_1); } else return 1; return 0; } if(argc < 4) { cw_cli(fd,CGUSAGE); return -1; } chan_name_1 = argv[x++]; } exten = cw_strdupa(argv[x++]); if((context = strchr(exten,'@'))) { *context = 0; context++; if(!(context && exten)) { cw_cli(fd,CGUSAGE); return -1; } if((pria = strchr(context,':'))) { *pria = '\0'; pria++; pri = atoi(pria); } else { pri = argv[x] ? atoi(argv[x++]) : 1; } if(!pri) pri = 1; } else if (strchr(exten,'/')) { chan_name_2 = exten; } xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1); if(!xferchan_1) { cw_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_1); return -1; } cw_mutex_unlock(&xferchan_1->lock); if(flags && strchr(flags,'b')) { if(cw_bridged_channel(xferchan_1)) { xferchan_1 = cw_bridged_channel(xferchan_1); } } if(chan_name_2) { struct cw_frame *f; struct cw_channel *newchan_1, *newchan_2; if (!(newchan_1 = cw_channel_alloc(0))) { cw_log(LOG_WARNING, "Memory Error!\n"); cw_hangup(newchan_1); return -1; } else { snprintf(newchan_1->name, sizeof (newchan_1->name), "ChanGrab/%s", xferchan_1->name); newchan_1->readformat = xferchan_1->readformat; newchan_1->writeformat = xferchan_1->writeformat; cw_channel_masquerade(newchan_1, xferchan_1); if ((f = cw_read(newchan_1))) { cw_fr_free(f); } else { cw_hangup(newchan_1); return -1; } } if(!(xferchan_2 = my_cw_get_channel_by_name_locked(chan_name_2))) { cw_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_2); cw_hangup(newchan_1); return -1; } cw_mutex_unlock(&xferchan_2->lock); if(flags && strchr(flags, 'B')) { if(cw_bridged_channel(xferchan_2)) { xferchan_2 = cw_bridged_channel(xferchan_2); } } if(!(newchan_2 = cw_channel_alloc(0))) { cw_log(LOG_WARNING, "Memory Error!\n"); cw_hangup(newchan_1); return -1; } else { snprintf(newchan_2->name, sizeof (newchan_2->name), "ChanGrab/%s", xferchan_2->name); newchan_2->readformat = xferchan_2->readformat; newchan_2->writeformat = xferchan_2->writeformat; cw_channel_masquerade(newchan_2, xferchan_2); if ((f = cw_read(newchan_2))) { cw_fr_free(f); } else { cw_hangup(newchan_1); cw_hangup(newchan_2); return -1; } } cw_bridge_call_thread_launch(newchan_1, newchan_2); } else { cw_verbose("Transferring_to context %s, extension %s, priority %d\n", context, exten, pri); cw_async_goto(xferchan_1, context, exten, pri); if(xferchan_1) cw_mutex_unlock(&xferchan_1->lock); } return 0; }
uint8_t sccp_pbx_channel_allocate(sccp_channel_t * c) { sccp_device_t * d = c->device; struct cw_channel * tmp; sccp_line_t * l = c->line; int fmt; if (!l || !d || !d->session) { cw_log(LOG_ERROR, "SCCP: Unable to allocate asterisk channel\n"); return 0; } tmp = cw_channel_alloc(1); if (!tmp) { cw_log(LOG_ERROR, "%s: Unable to allocate callweaver channel on line %s\n", d->id, l->name); return 0; } /* need to reset the exten, otherwise it would be set to s */ memset(&tmp->exten,0,sizeof(tmp->exten)); /* let's connect the CW channel to the sccp channel */ cw_mutex_lock(&c->lock); c->owner = tmp; cw_mutex_unlock(&c->lock); sccp_log(10)(VERBOSE_PREFIX_3 "%s: Global Capabilities: %d\n", d->id, GLOB(global_capability)); cw_mutex_lock(&l->lock); cw_mutex_lock(&d->lock); tmp->nativeformats = (d->capability ? d->capability : GLOB(global_capability)); if (tmp->nativeformats & c->format) { fmt = c->format; } else { fmt = cw_codec_choose(&d->codecs, tmp->nativeformats, 1); c->format = fmt; } cw_mutex_unlock(&l->lock); cw_mutex_unlock(&d->lock); sccp_log(2)(VERBOSE_PREFIX_3 "%s: format request: %d/%d\n", d->id, tmp->nativeformats, c->format); snprintf(tmp->name, sizeof(tmp->name), "SCCP/%s-%08x", l->name, c->callid); if (GLOB(debug) > 2) { const unsigned slen=512; char s1[slen]; char s2[slen]; sccp_log(2)(VERBOSE_PREFIX_3 "%s: Channel %s, capabilities: DEVICE %s NATIVE %s BEST %d (%s)\n", d->id, c->owner->name, cw_getformatname_multiple(s1, slen, d->capability), cw_getformatname_multiple(s2, slen, tmp->nativeformats), fmt, cw_getformatname(fmt)); } tmp->type = "SCCP"; tmp->nativeformats = fmt; tmp->writeformat = fmt; tmp->readformat = fmt; tmp->tech = &sccp_tech; tmp->tech_pvt = c; tmp->adsicpe = CW_ADSI_UNAVAILABLE; // XXX: Bridge? // XXX: Transfer? cw_mutex_lock(&GLOB(usecnt_lock)); GLOB(usecnt)++; cw_mutex_unlock(&GLOB(usecnt_lock)); cw_update_use_count(); if (l->cid_num) tmp->cid.cid_num = strdup(l->cid_num); if (l->cid_name) tmp->cid.cid_name = strdup(l->cid_name); cw_copy_string(tmp->context, l->context, sizeof(tmp->context)); if (!cw_strlen_zero(l->language)) cw_copy_string(tmp->language, l->language, sizeof(tmp->language)); if (!cw_strlen_zero(l->accountcode)) cw_copy_string(tmp->accountcode, l->accountcode, sizeof(tmp->accountcode)); if (!cw_strlen_zero(l->musicclass)) cw_copy_string(tmp->musicclass, l->musicclass, sizeof(tmp->musicclass)); tmp->amaflags = l->amaflags; tmp->callgroup = l->callgroup; #ifdef CS_SCCP_PICKUP tmp->pickupgroup = l->pickupgroup; #endif tmp->priority = 1; sccp_log(10)(VERBOSE_PREFIX_3 "%s: Allocated callweaver channel %s-%d\n", d->id, l->name, c->callid); return 1; }