#define CGUSAGE "Usage: changrab [-[bB]] @ [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; }