rendered paste body#define CGUSAGE "Usage: changrab [-[bB]] <channel> <exten>@<context> [pri]\n"
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 opbx_channel *xferchan_1, *xferchan_2;
int pri=0,x=1;
if(argc < 3) {
opbx_cli(fd,CGUSAGE);
return -1;
}
chan_name_1 = argv[x++];
if(chan_name_1[0] == '-') {
flags = opbx_strdupa(chan_name_1);
if(flags && (strchr(flags,'h'))) {
chan_name_1 = argv[x++];
if((xferchan_1 = my_opbx_get_channel_by_name_locked(chan_name_1))) {
opbx_mutex_unlock(&xferchan_1->lock);
opbx_hangup(xferchan_1);
opbx_verbose("OK, good luck!\n");
return 0;
} else
return -1;
} else if(flags && (strchr(flags,'m') || strchr(flags,'M'))) {
chan_name_1 = argv[x++];
if((xferchan_1 = my_opbx_get_channel_by_name_locked(chan_name_1))) {
opbx_mutex_unlock(&xferchan_1->lock);
strchr(flags,'m') ? opbx_moh_start(xferchan_1,NULL) : opbx_moh_stop(xferchan_1);
} else
return 1;
return 0;
}
if(argc < 4) {
opbx_cli(fd,CGUSAGE);
return -1;
}
chan_name_1 = argv[x++];
}
exten = opbx_strdupa(argv[x++]);
if((context = strchr(exten,'@'))) {
*context = 0;
context++;
if(!(context && exten)) {
opbx_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_opbx_get_channel_by_name_locked(chan_name_1);
if(!xferchan_1) {
opbx_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_1);
return -1;
}
opbx_mutex_unlock(&xferchan_1->lock);
if(flags && strchr(flags,'b')) {
if(opbx_bridged_channel(xferchan_1)) {
xferchan_1 = opbx_bridged_channel(xferchan_1);
}
}
if(chan_name_2) {
struct opbx_frame *f;
struct opbx_channel *newchan_1, *newchan_2;
if (!(newchan_1 = opbx_channel_alloc(0))) {
opbx_log(LOG_WARNING, "Memory Error!\n");
opbx_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;
opbx_channel_masquerade(newchan_1, xferchan_1);
if ((f = opbx_read(newchan_1))) {
opbx_frfree(f);
} else {
opbx_hangup(newchan_1);
return -1;
}
}
if(!(xferchan_2 = my_opbx_get_channel_by_name_locked(chan_name_2))) {
opbx_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_2);
opbx_hangup(newchan_1);
return -1;
}
opbx_mutex_unlock(&xferchan_2->lock);
if(flags && strchr(flags, 'B')) {
if(opbx_bridged_channel(xferchan_2)) {
xferchan_2 = opbx_bridged_channel(xferchan_2);
}
}
if(!(newchan_2 = opbx_channel_alloc(0))) {
opbx_log(LOG_WARNING, "Memory Error!\n");
opbx_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;
opbx_channel_masquerade(newchan_2, xferchan_2);
if ((f = opbx_read(newchan_2))) {
opbx_frfree(f);
} else {
opbx_hangup(newchan_1);
opbx_hangup(newchan_2);
return -1;
}
}
opbx_bridge_call_thread_launch(newchan_1, newchan_2);
} else {
opbx_verbose("Transferring_to context %s, extension %s, priority %d\n", context, exten, pri);
opbx_async_goto(xferchan_1, context, exten, pri);
if(xferchan_1)
opbx_mutex_unlock(&xferchan_1->lock);
}
return 0;
}