Beispiel #1
0
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;
}
Beispiel #2
0
static void *cw_bridge_call_thread(void *data) 
{
	struct cw_bridge_thread_obj *tobj = data;
	tobj->chan->appl = "Redirected Call";
	tobj->peer->appl = "Redirected Call";
	if (tobj->chan->cdr) {
		cw_cdr_reset(tobj->chan->cdr,0);
		cw_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
	}
	if (tobj->peer->cdr) {
		cw_cdr_reset(tobj->peer->cdr,0);
		cw_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
	}


	cw_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
	cw_hangup(tobj->chan);
	cw_hangup(tobj->peer);
	tobj->chan = tobj->peer = NULL;
	free(tobj);
	tobj=NULL;
	return NULL;
}
Beispiel #3
0
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;
}
Beispiel #4
0
void * sccp_pbx_startchannel(void *data) {
	struct cw_channel * chan = data;
	sccp_channel_t * c;
	sccp_line_t * l;
	sccp_device_t * d;
	uint8_t res_exten = 0, res_wait = 0, res_timeout = 0;

	c = CS_CW_CHANNEL_PVT(chan);
	if ( !c || !(l = c->line) || !(d = c->device) ) {
		cw_hangup(chan);
		return NULL;
	}

	sccp_log(1)( VERBOSE_PREFIX_3 "%s: New call on line %s\n", d->id, l->name);

	cw_mutex_lock(&c->lock);
	c->calltype = SKINNY_CALLTYPE_OUTBOUND;
	c->hangupok = 0;
	cw_mutex_unlock(&c->lock);
	
	sccp_channel_set_callingparty(c, l->cid_name, l->cid_num);

	if (!cw_strlen_zero(c->dialedNumber)) {
		/* we have a number to dial. Let's do it */
		sccp_log(10)( VERBOSE_PREFIX_3 "%s: Dialing %s on channel %s-%d\n", l->device->id, c->dialedNumber, l->name, c->callid);
		sccp_channel_set_calledparty(c, c->dialedNumber, c->dialedNumber);
		sccp_indicate_lock(c, SCCP_CHANNELSTATE_DIALING);
		goto dial;
	}

	/* we have to collect the number */
	/* the phone is on TsOffHook state */
	sccp_log(10)( VERBOSE_PREFIX_3 "%s: Waiting for the number to dial on channel %s-%d\n", l->device->id, l->name, c->callid);
	/* let's use the keypad to collect digits */
	cw_mutex_lock(&c->lock);
	c->digittimeout = time(0)+GLOB(firstdigittimeout);
	cw_mutex_unlock(&c->lock);

	res_exten = 1;

	do {
		pthread_testcancel();
		usleep(100);
		cw_mutex_lock(&c->lock);
		if (!cw_strlen_zero(c->dialedNumber)) {
			res_exten = (c->dialedNumber[0] == '*' || cw_matchmore_extension(chan, chan->context, c->dialedNumber, 1, l->cid_num));
		}
		if (! (res_wait = ( c->state == SCCP_CHANNELSTATE_DOWN || chan->_state == CW_STATE_DOWN
							|| chan->_softhangup || c->calltype == SKINNY_CALLTYPE_INBOUND)) ) {
			if (CS_CW_CHANNEL_PVT(chan)) {
				res_timeout = (time(0) < c->digittimeout);
			} else
				res_timeout = 0;
		}
		cw_mutex_unlock(&c->lock);
	} while ( (res_wait == 0) && res_exten &&  res_timeout);

	if (res_wait != 0) {
		/* CW_STATE_DOWN or softhangup */
		sccp_log(10)(VERBOSE_PREFIX_3 "%s: return from the startchannel for DOWN, HANGUP or PICKUP cause\n", l->device->id);
		cw_mutex_lock(&c->lock);
		c->hangupok = 1;
		cw_mutex_unlock(&c->lock);
		return NULL;
	}

dial:

	cw_mutex_lock(&c->lock);
	cw_copy_string(chan->exten, c->dialedNumber, sizeof(chan->exten));
	cw_copy_string(d->lastNumber, c->dialedNumber, sizeof(d->lastNumber));
	sccp_channel_set_calledparty(c, c->dialedNumber, c->dialedNumber);
	/* proceed call state is needed to display the called number.
	The phone will not display callinfo in offhook state */
	sccp_channel_set_callstate(c, SKINNY_CALLSTATE_PROCEED);
	sccp_channel_send_callinfo(c);
	sccp_dev_clearprompt(d,c->line->instance, c->callid);
	sccp_dev_displayprompt(d, c->line->instance, c->callid, SKINNY_DISP_CALL_PROCEED, 0);
	c->hangupok = 1;
	cw_mutex_unlock(&c->lock);

	if ( !cw_strlen_zero(c->dialedNumber)
			&& cw_exists_extension(chan, chan->context, c->dialedNumber, 1, l->cid_num) ) {
		/* found an extension, let's dial it */
		sccp_log(10)(VERBOSE_PREFIX_3 "%s: channel %s-%d is dialing number %s\n", l->device->id, l->name, c->callid, c->dialedNumber);
		/* Answer dialplan command works only when in RINGING OR RING cw_state */
		sccp_cw_setstate(c, CW_STATE_RING);
		if (cw_pbx_run(chan)) {
			sccp_indicate_lock(c, SCCP_CHANNELSTATE_INVALIDNUMBER);
		}
	} else {
		/* timeout and no extension match */
		sccp_indicate_lock(c, SCCP_CHANNELSTATE_INVALIDNUMBER);
	}
	sccp_log(10)(VERBOSE_PREFIX_3 "%s: return from the startchannel on exit\n", l->device->id);
	return NULL;
}