예제 #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;
}
예제 #2
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;
}
예제 #3
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;
}