Пример #1
0
static void *attempt_thread(void *data)
{
	struct outgoing *o = (struct outgoing *) data;
	int res, reason;
	if (!cw_strlen_zero(o->app)) {
		if (option_verbose > 2)
			cw_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
		res = cw_pbx_outgoing_app(o->tech, CW_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, NULL);
	} else {
		if (option_verbose > 2)
			cw_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
		res = cw_pbx_outgoing_exten(o->tech, CW_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, NULL);
	}
	if (res) {
		cw_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason);
		if (o->retries >= o->maxretries + 1) {
			/* Max retries exceeded */
			cw_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : "");
			unlink(o->fn);
		} else {
			/* Notate that the call is still active */
			safe_append(o, time(NULL), "EndRetry");
		}
	} else {
		cw_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
		cw_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest);
		unlink(o->fn);
	}
	free_outgoing(o);
	return NULL;
}
Пример #2
0
int unload_module(void)
{
	cw_verbose(VERBOSE_PREFIX_1 "Unloading [Sub]Agent Module\n");

	res_snmp_dont_stop = 0;
	return ((thread != CW_PTHREADT_NULL) ? pthread_join(thread, NULL) : 0);
}
static int settransfercapability_exec(struct cw_channel *chan, int argc, char **argv)
{
	struct localuser *u;
	int x;
	int transfercapability = -1;
	
	LOCAL_USER_ADD(u);
	
	for (x = 0; x < (sizeof(transcaps) / sizeof(transcaps[0])); x++) {
		if (!strcasecmp(transcaps[x].name, argv[0])) {
			transfercapability = transcaps[x].val;
			break;
		}
	}
	if (transfercapability < 0) {
		cw_log(LOG_WARNING, "'%s' is not a valid transfer capability (see 'show application SetTransferCapability')\n", argv[0]);
		LOCAL_USER_REMOVE(u);
		return 0;
	}
		
	chan->transfercapability = (unsigned short)transfercapability;
	
	if (option_verbose > 2)
		cw_verbose(VERBOSE_PREFIX_3 "Setting transfer capability to: 0x%.2x - %s.\n", transfercapability, argv[0]);

	LOCAL_USER_REMOVE(u);

	return 0;
}
Пример #4
0
int icd_module_unload(void)
{
    /*TODO didnt get this far */
    cw_verbose(VERBOSE_PREFIX_3 "Unloaded ICD Module[MatchAgent]!\n");
    return 0;

}
Пример #5
0
/* Configure an customer. data is a config obj. */
icd_status init_icd_customer(icd_customer * that, icd_config * data)
{
    icd_status(*init) (icd_customer * that, icd_config * data);
    char *moh;
    icd_caller *caller = (icd_caller *) that;
    icd_status result;

    assert(that != NULL);

    if (that->allocated != 1)
        ICD_MEMSET_ZERO(that, sizeof(icd_caller));
    /* Initialize base class */
    result = init_icd_caller((icd_caller *) that, data);
    if (result != ICD_SUCCESS) {
        return result;
    }

    icd_caller__add_role((icd_caller *) that, ICD_CUSTOMER_ROLE);
    moh = icd_caller__get_moh((icd_caller *) that);
    if (moh == NULL) {
        icd_caller__set_moh((icd_caller *) that, "default");
    }
    /* Set plugable function pointer for Agent Caller plugable functions */
    icd_caller__set_plugable_fn_ptr(caller, icd_customer_get_plugable_fns);
    /*
     * if we wanted to customized for a specific instance of a agent caller we can add
     * a pointer in the caller->plugable_fns_list for a speific dist use the family
     * of helpers in the plugable_fns_list.c otherwise we set the function ptrs to 
     * the staic struc declared locally here in icd_agent_plugable_fns
     plugable_fns = (icd_plugable_fn *)icd_list__peek((icd_list *)caller->plugable_fns_list);
     icd_list_iterator *iter;

     iter = icd_list__get_iterator((icd_list *)(caller->plugable_fns_list));
     while (icd_list_iterator__has_more(iter)) {
     plugable_fns = (icd_plugable_fn *)icd_list_iterator__next(iter);

     result = icd_plugable__set_state_call_end_fn(plugable_fns, icd_customer__standard_state_call_end, NULL);
     result = icd_plugable__set_cleanup_caller_fn(plugable_fns, icd_customer__standard_cleanup_caller);
     }
     destroy_icd_list_iterator(&iter);

     */

    /* fix me This is supposed to be the agent_init in a loadable module 
     *  icd_config_registry__register_ptr(registry, "customer.init", "myModule",
     *  icd_module__init_agent);
     *  then we run 
     * icd_config__get_any_value(data, "customer.init.", myModule_init_agent_)
     */

    init = (icd_status(*)(icd_customer * that, icd_config * data))
        icd_config__get_value(data, "customers.init");
    if (init != NULL) {
        cw_verbose(VERBOSE_PREFIX_1 "Customer plugable init for [%s] \n", icd_caller__get_name(caller));
        return init(that, data);
    }

    return ICD_SUCCESS;
}
Пример #6
0
static void *icd_distributor__match_agent_run(void *that) 
{ 
	    icd_distributor *dist; 
	    icd_status result; 
 	 
	    assert(that != NULL); 
	    assert(((icd_distributor *)that)->customers != NULL); 
	    assert(((icd_distributor *)that)->agents != NULL); 
	 
	    dist = (icd_distributor *)that; 
	     
	    while (dist->thread_state != ICD_THREAD_STATE_FINISHED) { 
	        if (dist->thread_state == ICD_THREAD_STATE_RUNNING) { 
	            result = icd_distributor__lock(dist); 
	            /* Distribute callers if we can, or pause until some are added */ 
		while(icd_distributor__get_added_callers_number(dist) > 0){
			icd_distributor__reset_added_callers_number(dist);
			if (icd_distributor__customers_pending(dist) && icd_distributor__agents_pending(dist)) { 
				result = icd_distributor__unlock(dist); 
				/* func ptr to the icd_distributor__link_callers_via_?? note may also come from custom 
				* function eg from icd_mod_?? installed using icd_distributor__set_link_callers_fn 
				*/ 
				if (icd_verbose > 4) 
				cw_verbose(VERBOSE_PREFIX_3 "Distributor__run [%s] link_fn[%p]  \n",  
					icd_distributor__get_name(dist), dist->link_fn); 
				result = dist->link_fn(dist, dist->link_fn_extra);   
				result = icd_distributor__lock(dist); 
			}
		} 
		/* All distributor links are now created wait for changes of customer or agent list  */      
		cw_cond_wait(&(dist->wakeup), &(dist->lock)); /* wait until signal received */ 
		result = icd_distributor__unlock(dist); 
		if (icd_verbose > 4) 
			cw_verbose(VERBOSE_PREFIX_3 "Distributor__run [%s] wait  \n",  icd_distributor__get_name(dist));             
		} else { 
	            /* TBD - Make paused thread work better.  
	             *        - Use pthread_cond_wait() 
	             *        - Use same or different condition variable?  
	             */ 
 	        }
	        /* Play nice */ 
	        sched_yield(); 
	    } 
	    /* Do any cleanup here */ 
	    return NULL; 
} 
Пример #7
0
int load_module(void)
{
	if (!load_config())
		return -1;

	cw_verbose(VERBOSE_PREFIX_1 "Loading [Sub]Agent Module\n");

	res_snmp_dont_stop = 1;
	if (res_snmp_enabled)
		return cw_pthread_create(&thread, NULL, agent_thread, NULL);
	return 0;
}
Пример #8
0
int cw_app_has_voicemail(const char *mailbox, const char *folder)
{
	static int warned = 0;
	if (cw_has_voicemail_func)
		return cw_has_voicemail_func(mailbox, folder);

	if ((option_verbose > 2) && !warned) {
		cw_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX");
		warned++;
	}
	return 0;
}
Пример #9
0
int icd_module_load(icd_config_registry * registry)
{

    assert(registry != NULL);
    icd_config_registry__register_ptr(registry, "dist", "matchagent", init_icd_distributor_match_agent);

    icd_config_registry__register_ptr(registry, "dist.link", "popcustmatchagent",
      link_callers_via_pop_customer_match_agent  );

    cw_verbose(VERBOSE_PREFIX_3 "Registered ICD Module[MatchAgent]!\n");

    return 0;
}
Пример #10
0
int icd_module_load(icd_config_registry * registry)
{

    assert(registry != NULL);

    module_id = icd_event_factory__add_module(module_name);
    if (module_id == 0)
        cw_log(LOG_WARNING, "Unable to register Module Name[%s]", module_name);
    else {
        icd_event_factory__add_listener(event_factory, queues, icd_module__event_cwmgr, NULL);
        cw_verbose(VERBOSE_PREFIX_3 "Registered ICD Module[%s]!\n",module_name);
    }
    return 0;
}
Пример #11
0
int reload(void)
{
	cw_verbose(VERBOSE_PREFIX_1 "Reloading [Sub]Agent Module\n");

	res_snmp_dont_stop = 0;
	if (thread != CW_PTHREADT_NULL)
		pthread_join(thread, NULL);
	thread = CW_PTHREADT_NULL;
	load_config();

	res_snmp_dont_stop = 1;
	if (res_snmp_enabled)
		return cw_pthread_create(&thread, NULL, agent_thread, NULL);
	return 0;
}
Пример #12
0
/* Set global indication country */
int cw_set_indication_country(const char *country)
{
	if (country)
    {
		struct tone_zone *z = cw_get_indication_zone(country);
		if (z)
        {
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n",country);
			current_tonezone = z;
			return 0;
		}
	}
	return 1; /* not found */
}
Пример #13
0
static icd_status init_icd_distributor_match_agent(icd_distributor * that, char *name, icd_config * data)
{

    assert(that != NULL);
    assert(data != NULL);
    strncpy(that->name, name, sizeof(that->name));
    icd_distributor__set_config_params(that, data);
    icd_distributor__create_lists(that, data);
    icd_list__set_node_insert_func((icd_list *) that->agents, icd_list__insert_fifo, NULL);
    icd_distributor__set_link_callers_fn(that, link_callers_via_pop_customer_match_agent, NULL);
	icd_distributor__set_run_fn(that, icd_distributor__match_agent_run);  
    icd_distributor__create_thread(that);

    cw_verbose(VERBOSE_PREFIX_3 "Registered ICD Distributor[%s] Initialized !\n", name);
    return ICD_SUCCESS;
}
Пример #14
0
/* remove an existing country and all its indications, country must exist.
 * Also, all countries which are an alias for the specified country are removed. */
int cw_unregister_indication_country(const char *country)
{
	struct tone_zone *tz, *pz = NULL, *tmp;
	int res = -1;

	if (cw_mutex_lock(&tzlock))
    {
		cw_log(LOG_WARNING, "Unable to lock tone_zones list\n");
		return -1;
	}
	tz = tone_zones;
	while (tz)
    {
		if (country == NULL
            ||
		    (strcasecmp(country, tz->country) == 0
            ||
		     strcasecmp(country, tz->alias) == 0))
        {
			/* tone_zone found, remove */
			tmp = tz->next;
			if (pz)
				pz->next = tmp;
			else
				tone_zones = tmp;
			/* if we are unregistering the default country, w'll notice */
			if (tz == current_tonezone) {
				cw_log(LOG_NOTICE,"Removed default indication country '%s'\n",tz->country);
				current_tonezone = NULL;
			}
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
			free_zone(tz);
			if (tone_zones == tz)
				tone_zones = tmp;
			tz = tmp;
			res = 0;
		}
		else {
			/* next zone please */
			pz = tz;
			tz = tz->next;
		}
	}
	cw_mutex_unlock(&tzlock);
	return res;
}
Пример #15
0
int cw_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
{
	static int warned = 0;
	if (newmsgs)
		*newmsgs = 0;
	if (oldmsgs)
		*oldmsgs = 0;
	if (cw_messagecount_func)
		return cw_messagecount_func(mailbox, newmsgs, oldmsgs);

	if (!warned && (option_verbose > 2)) {
		warned++;
		cw_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox);
	}

	return 0;
}
Пример #16
0
static int dumpchan_exec(struct cw_channel *chan, int argc, char **argv)
{
	static char *line = "================================================================================";
	char vars[1024];
	char info[1024];
	struct localuser *u;
	int level;
	
	LOCAL_USER_ADD(u);

	level = (argc > 0 ? atoi(argv[0]) : 0);

	if (option_verbose >= level) {
		cw_serialize_showchan(chan, info, sizeof(info));
		pbx_builtin_serialize_variables(chan, vars, sizeof(vars));
		cw_verbose("\nDumping Info For Channel: %s:\n%s\nInfo:\n%s\nVariables:\n%s%s\n", chan->name, line, info, vars, line);
	}

	LOCAL_USER_REMOVE(u);
	return 0;
}
Пример #17
0
/* add a new country, if country exists, it will be replaced. */
int cw_register_indication_country(struct tone_zone *zone)
{
	struct tone_zone *tz,*pz;

	if (cw_mutex_lock(&tzlock))
    {
		cw_log(LOG_WARNING, "Unable to lock tone_zones list\n");
		return -1;
	}
	for (pz = NULL, tz = tone_zones;  tz;  pz = tz, tz = tz->next)
    {
		if (strcasecmp(zone->country,tz->country) == 0)
        {
			/* tone_zone already there, replace */
			zone->next = tz->next;
			if (pz)
				pz->next = zone;
			else
				tone_zones = zone;
			/* if we are replacing the default zone, re-point it */
			if (tz == current_tonezone)
				current_tonezone = zone;
			/* now free the previous zone */
			free_zone(tz);
			cw_mutex_unlock(&tzlock);
			return 0;
		}
	}
	/* country not there, add */
	zone->next = NULL;
	if (pz)
		pz->next = zone;
	else
		tone_zones = zone;
	cw_mutex_unlock(&tzlock);

	if (option_verbose > 2)
		cw_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n",zone->country);
	return 0;
}
Пример #18
0
static void parse_config(void)
{
    struct cw_config *cfg;
    struct cw_variable *var;
  
    if ((cfg = cw_config_load("codecs.conf")))
    {
        if ((var = cw_variable_browse(cfg, "plc")))
        {
            while (var)
            {
                if (!strcasecmp(var->name, "genericplc"))
                {
                    useplc = cw_true(var->value) ? 1 : 0;
                    if (option_verbose > 2)
                        cw_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n", useplc  ?  ""  :  "not ");
                }
                var = var->next;
            }
        }
        cw_config_destroy(cfg);
    }
}
Пример #19
0
/* Match the customers "identifier" to the agents "identifier".
 * the "identifier" is set to what ever value is required typical use case
 * agent identifier=agent_id and the customer identifier = agent_id
 * exten => 9001,1,icd_customer(identifier=123|name=roundrobin-customer|queue=roundrobin_q|moh=ringing)
 * exten => 8001,1,icd_agent(identifier=123|agent=101|noauth=1|queue=test_q
 * */
icd_status link_callers_via_pop_customer_match_agent(icd_distributor * dist, void *extra)
{
    icd_member *customer = NULL;
    icd_member *agent = NULL;
    icd_caller *customer_caller = NULL;
    icd_caller *agent_caller = NULL;
    char *tmp_str;
    icd_list_iterator *iter;
    icd_status result;
    int LinkFound;

    assert(dist != NULL);
    assert(dist->customers != NULL);
    assert(dist->agents != NULL);
    if (!icd_member_list__has_members(dist->customers)) {
        return ICD_ENOTFOUND;
    }
    if (!icd_member_list__has_members(dist->agents)) {
        return ICD_ENOTFOUND;
    }

    /* Go through all the customers looking for a match */
    /* For each customer on the list, try to find the match agent. 
     * Return after all customer has been pass looked over once */
	while(1){
		LinkFound = 0;
		result = icd_member_list__lock(dist->customers);
		iter = icd_distributor__get_customer_iterator(dist);
		while (icd_list_iterator__has_more_nolock(iter)) {
			customer = (icd_member *) icd_list_iterator__next(iter);
			if (customer != NULL) {
				customer_caller = icd_member__get_caller(customer);
			}    
			if (customer == NULL || customer_caller == NULL) {
				cw_log(LOG_ERROR, "MatchAgent Distributor %s could not retrieve customer from list\n",
				icd_distributor__get_name(dist));
				continue;
			}
	
			tmp_str = icd_caller__get_param(customer_caller, "identifier");
	
			if (tmp_str == NULL) {
				cw_log(LOG_WARNING, "MatchAgent Distributor [%s] reports that customer [%s] has no identifier\n",
				icd_distributor__get_name(dist), icd_caller__get_name(customer_caller));
				continue;
			}
			agent_caller = (icd_caller *) icd_fieldset__get_value(agents, tmp_str);   
			if (agent_caller == NULL) {
				cw_log(LOG_WARNING, "MatchAgent Distributor [%s] reports that agent [%s] is not in ICD\n",
				icd_distributor__get_name(dist), tmp_str);
				continue;
			}
			if(icd_caller__get_state(agent_caller) != ICD_CALLER_STATE_READY){
				continue;
			}       
			icd_member_list__lock(dist->agents);		
			agent = icd_member_list__get_for_caller(dist->agents, agent_caller);
			if (agent == NULL ) {
			/*  cw_log(LOG_WARNING, "MatchAgent Distributor [%s] reports that agent [%s] is not in distributor\n",
                	icd_distributor__get_name(dist), tmp_str);
			*/                
				icd_member_list__unlock(dist->agents);		
				continue;
        		}
			if (icd_member__lock(agent) != ICD_SUCCESS){
				icd_member_list__unlock(dist->agents);		
				continue;
			}
			icd_member_list__unlock(dist->agents);
			result = icd_member__distribute(agent);
			if (result != ICD_SUCCESS) {
				cw_log(LOG_WARNING, "MatchAgent Distributor [%s] reports that cannot distribute agent [%s]\n",
				icd_distributor__get_name(dist), tmp_str);
				icd_member__unlock(agent);
				continue;
			}
			
			if(icd_caller__get_state(customer_caller) == ICD_CALLER_STATE_READY){
				icd_caller__lock(customer_caller);
				if(icd_caller__get_state(customer_caller) == ICD_CALLER_STATE_READY){
				/* Still in READY state - OK */
					result = ICD_SUCCESS;
				}
				else {
					result = ICD_ERESOURCE;
					icd_caller__unlock(customer_caller);
				}
			}
			else {
				result = ICD_ERESOURCE;
			}	
		
			if (result != ICD_SUCCESS) {
				icd_caller__set_state(agent_caller, ICD_CALLER_STATE_READY);   
				icd_member__unlock(agent);
				continue;
			}
			
			result = icd_member__distribute(customer);
			if (result != ICD_SUCCESS) {
				icd_caller__unlock(customer_caller);
				icd_caller__set_state(agent_caller, ICD_CALLER_STATE_READY);
				icd_member__unlock(agent);
				continue;
			}
			LinkFound = 1;
			icd_member_list__unlock(dist->customers);
			result = icd_caller__join_callers(customer_caller, agent_caller);
			if (result != ICD_SUCCESS) {
				icd_caller__set_state(customer_caller, ICD_CALLER_STATE_READY);
				icd_caller__set_state(agent_caller, ICD_CALLER_STATE_READY);
				icd_caller__unlock(customer_caller);
				icd_member__unlock(agent);
			}
			else {

			/* Figure out who the bridger is, and who the bridgee is */
				result = icd_distributor__select_bridger(agent_caller, customer_caller);

				cw_verbose(VERBOSE_PREFIX_3 "MatchAgent Distributor [%s] Link CustomerID[%d] to AgentID[%d]\n",
				icd_distributor__get_name(dist), icd_caller__get_id(customer_caller), icd_caller__get_id(agent_caller));
				if (icd_caller__has_role(customer_caller, ICD_BRIDGER_ROLE)) {
					result = icd_caller__bridge(customer_caller);
				} else if (icd_caller__has_role(agent_caller, ICD_BRIDGER_ROLE)) {
					result = icd_caller__bridge(agent_caller);
				} else {
					cw_log(LOG_ERROR, "MatchAgent Distributor %s found no bridger responsible to bridge call\n",
					icd_distributor__get_name(dist));
					icd_caller__set_state(agent_caller, ICD_CALLER_STATE_READY);
					icd_caller__set_state(customer_caller, ICD_CALLER_STATE_READY);
					icd_caller__unlock(customer_caller);
					icd_member__unlock(agent);
					continue;
				}
			}
			if( LinkFound) {
				icd_caller__unlock(customer_caller);
				icd_member__unlock(agent);
				break;
			}
      		} /*  while (icd_list_iterator__has_more(iter)) */
		if(! LinkFound) {
			result = icd_member_list__unlock(dist->customers);
		}
		destroy_icd_list_iterator(&iter);
		if(! LinkFound) {
			break;
		}    
	}
	return ICD_SUCCESS;
}
Пример #20
0
int icd_module_unload(void)
{
    cw_verbose(VERBOSE_PREFIX_3 "Unloaded ICD Module[%s]!\n", module_name);
    return 0;

}
Пример #21
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;
}
Пример #22
0
static int _while_exec(struct cw_channel *chan, int argc, char **argv, int end)
{
	int res=0;
	struct localuser *u;
	char *while_pri = NULL;
	char *goto_str = NULL, *my_name = NULL;
	char *label = NULL;
	char varname[VAR_SIZE], end_varname[VAR_SIZE];
	const char *prefix = "WHILE";
	size_t size=0;
	int used_index_i = -1, x=0;
	char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0";

	if (!end && argc != 1) {
		cw_log(LOG_ERROR, "Syntax: %s\n", while_syntax);
		return -1;
	}

	if (!chan) {
		/* huh ? */
		return -1;
	}

	LOCAL_USER_ADD(u);

	/* dont want run away loops if the chan isn't even up
	   this is up for debate since it slows things down a tad ......
	*/
	if (cw_waitfordigit(chan,1) < 0)
		ALL_DONE(u,-1);


	for (x=0;;x++) {
		if (get_index(chan, prefix, x)) {
			used_index_i = x;
		} else 
			break;
	}
	
	snprintf(used_index, VAR_SIZE, "%d", used_index_i);
	snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1);
	
	size = strlen(chan->context) + strlen(chan->exten) + 32;
	my_name = alloca(size);
	snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority);
	
	if (cw_strlen_zero(label)) {
		if (end) 
			label = used_index;
		else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) {
			label = new_index;
			pbx_builtin_setvar_helper(chan, my_name, label);
		}
		
	}
	
	snprintf(varname, VAR_SIZE, "%s_%s", prefix, label);
	while_pri = pbx_builtin_getvar_helper(chan, varname);
	
	if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) {
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
	}
	

	if (!end && !cw_true(argv[0])) {
		/* Condition Met (clean up helper vars) */
		pbx_builtin_setvar_helper(chan, varname, NULL);
		pbx_builtin_setvar_helper(chan, my_name, NULL);
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
		if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) {
			pbx_builtin_setvar_helper(chan, end_varname, NULL);
			cw_parseable_goto(chan, goto_str);
		} else {
			int pri = find_matching_endwhile(chan);
			if (pri > 0) {
				if (option_verbose > 2)
					cw_verbose(VERBOSE_PREFIX_3 "Jumping to priority %d\n", pri);
				chan->priority = pri;
			} else {
				cw_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority);
			}
		}
		ALL_DONE(u,res);
	}

	if (!end && !while_pri) {
		size = strlen(chan->context) + strlen(chan->exten) + 32;
		goto_str = alloca(size);
		snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority);
		pbx_builtin_setvar_helper(chan, varname, goto_str);
	} 

	else if (end && while_pri) {
		/* END of loop */
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
		if (! pbx_builtin_getvar_helper(chan, end_varname)) {
			size = strlen(chan->context) + strlen(chan->exten) + 32;
			goto_str = alloca(size);
			snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1);
			pbx_builtin_setvar_helper(chan, end_varname, goto_str);
		}
		cw_parseable_goto(chan, while_pri);
	}
	



	ALL_DONE(u, res);
}
Пример #23
0
int cw_record_review(struct cw_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) 
{
	int silencethreshold = 128; 
	int maxsilence=0;
	int res = 0;
	int cmd = 0;
	int max_attempts = 3;
	int attempts = 0;
	int recorded = 0;
	int message_exists = 0;
	/* Note that urgent and private are for flagging messages as such in the future */

	/* barf if no pointer passed to store duration in */
	if (duration == NULL) {
		cw_log(LOG_WARNING, "Error cw_record_review called without duration pointer\n");
		return -1;
	}

	cmd = '3';	 /* Want to start by recording */

	while ((cmd >= 0) && (cmd != 't')) {
		switch (cmd) {
		case '1':
			if (!message_exists) {
				/* In this case, 1 is to record a message */
				cmd = '3';
				break;
			} else {
				cw_streamfile(chan, "vm-msgsaved", chan->language);
				cw_waitstream(chan, "");
				cmd = 't';
				return res;
			}
		case '2':
			/* Review */
			cw_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
			cw_streamfile(chan, recordfile, chan->language);
			cmd = cw_waitstream(chan, CW_DIGIT_ANY);
			break;
		case '3':
			message_exists = 0;
			/* Record */
			if (recorded == 1)
				cw_verbose(VERBOSE_PREFIX_3 "Re-recording\n");
			else	
				cw_verbose(VERBOSE_PREFIX_3 "Recording\n");
			recorded = 1;
			cmd = cw_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path);
			if (cmd == -1) {
			/* User has hung up, no options to give */
				return cmd;
			}
			if (cmd == '0') {
				break;
			} else if (cmd == '*') {
				break;
			} 
			else {
				/* If all is well, a message exists */
				message_exists = 1;
				cmd = 0;
			}
			break;
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case '*':
		case '#':
			cmd = cw_play_and_wait(chan, "vm-sorry");
			break;
		default:
			if (message_exists) {
				cmd = cw_play_and_wait(chan, "vm-review");
			}
			else {
				cmd = cw_play_and_wait(chan, "vm-torerecord");
				if (!cmd)
					cmd = cw_waitfordigit(chan, 600);
			}
			
			if (!cmd)
				cmd = cw_waitfordigit(chan, 6000);
			if (!cmd) {
				attempts++;
			}
			if (attempts > max_attempts) {
				cmd = 't';
			}
		}
	}
	if (cmd == 't')
		cmd = 0;
	return cmd;
}
Пример #24
0
static int visdn_ppp_exec(struct cw_channel *chan, int argc, char **argv)
{
	struct visdn_chan *visdn_chan;
	const char **nargv;
	struct localuser *u;
	struct cw_frame *f;
	int res=-1;

	LOCAL_USER_ADD(u);

	if (chan->_state != CW_STATE_UP)
		cw_answer(chan);

	cw_mutex_lock(&chan->lock);

	if (strcmp(chan->type, "VISDN")) {
		cw_log(LOG_WARNING,
			"Only VISDN channels may be connected to"
			" this application\n");

		cw_mutex_unlock(&chan->lock);
		return -1;
	}

	visdn_chan = chan->tech_pvt;

	if (!strlen(visdn_chan->visdn_chanid)) {
		cw_log(LOG_WARNING,
			"vISDN crossconnector channel ID not present\n");
		cw_mutex_unlock(&chan->lock);
		return -1;
	}

	nargv = alloca((2 + argc + 3 + 1) * sizeof(nargv[0]));
	nargv[0] = PPP_EXEC;
	nargv[1] = "nodetach";
	memcpy(nargv + 2, argc, argv * sizeof(argv[0]));
	nargv[2 + argc + 0] = "plugin";
	nargv[2 + argc + 1] = "visdn.so";
	nargv[2 + argc + 2] = visdn_chan->visdn_chanid;
	nargv[2 + argc + 3] = NULL;

	cw_mutex_unlock(&chan->lock);

#if 0
	int i;
	for (i=0;i<argc;i++) {
		cw_log(LOG_NOTICE, "Arg %d: %s\n", i, argv[i]);
	}
#endif

	signal(SIGCHLD, SIG_DFL);

	pid_t pid = spawn_ppp(chan, nargv);
	if (pid < 0) {
		cw_log(LOG_WARNING, "Failed to spawn pppd\n");
		return -1;
	}

	while(cw_waitfor(chan, -1) > -1) {

		f = cw_read(chan);
		if (!f) {
			cw_log(LOG_NOTICE,
				"Channel '%s' hungup."
				" Signalling PPP at %d to die...\n",
				chan->name, pid);

			kill(pid, SIGTERM);

			break;
		}

		cw_fr_free(f);

		int status;
		res = wait4(pid, &status, WNOHANG, NULL);
		if (res < 0) {
			cw_log(LOG_WARNING,
				"wait4 returned %d: %s\n",
				res, strerror(errno));

			break;
		} else if (res > 0) {
			if (option_verbose > 2) {
				if (WIFEXITED(status)) {
					cw_verbose(VERBOSE_PREFIX_3
						"PPP on %s terminated with status %d\n",
						chan->name, WEXITSTATUS(status));
				} else if (WIFSIGNALED(status)) {
					cw_verbose(VERBOSE_PREFIX_3
						"PPP on %s terminated with signal %d\n", 
						chan->name, WTERMSIG(status));
				} else {
					cw_verbose(VERBOSE_PREFIX_3
						"PPP on %s terminated weirdly.\n", chan->name);
				}
			}

			break;
		}
	}

	LOCAL_USER_REMOVE(u);
	return res;
}
Пример #25
0
int cw_play_and_record(struct cw_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
{
	int d;
	char *fmts;
	char comment[256];
	int x, fmtcnt=1, res=-1,outmsg=0;
	struct cw_frame *f;
	struct cw_filestream *others[MAX_OTHER_FORMATS];
	char *sfmt[MAX_OTHER_FORMATS];
	char *stringp=NULL;
	time_t start, end;
	struct cw_dsp *sildet=NULL;   	/* silence detector dsp */
	int totalsilence = 0;
	int dspsilence = 0;
	int gotsilence = 0;		/* did we timeout for silence? */
	int rfmt=0;

	if (silencethreshold < 0)
		silencethreshold = global_silence_threshold;

	if (maxsilence < 0)
		maxsilence = global_maxsilence;

	/* barf if no pointer passed to store duration in */
	if (duration == NULL) {
		cw_log(LOG_WARNING, "Error play_and_record called without duration pointer\n");
		return -1;
	}

	cw_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);

	if (playfile) {
		d = cw_play_and_wait(chan, playfile);
		if (d > -1)
			d = cw_streamfile(chan, "beep",chan->language);
		if (!d)
			d = cw_waitstream(chan,"");
		if (d < 0)
			return -1;
	}

	fmts = cw_strdupa(fmt);

	stringp=fmts;
	strsep(&stringp, "|,");
	cw_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);
	sfmt[0] = cw_strdupa(fmts);

	while((fmt = strsep(&stringp, "|,"))) {
		if (fmtcnt > MAX_OTHER_FORMATS - 1) {
			cw_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
			break;
		}
		sfmt[fmtcnt++] = cw_strdupa(fmt);
	}

	time(&start);
	end=start;  /* pre-initialize end to be same as start in case we never get into loop */
	for (x=0;x<fmtcnt;x++) {
		others[x] = cw_writefile(recordfile, sfmt[x], comment, O_TRUNC, 0, 0700);
		cw_verbose( VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, recordfile, sfmt[x], others[x]);

		if (!others[x]) {
			break;
		}
	}

	if (path)
		cw_unlock_path(path);


	
	if (maxsilence > 0) {
		sildet = cw_dsp_new(); /* Create the silence detector */
		if (!sildet) {
			cw_log(LOG_WARNING, "Unable to create silence detector :(\n");
			return -1;
		}
		cw_dsp_set_threshold(sildet, silencethreshold);
		rfmt = chan->readformat;
		res = cw_set_read_format(chan, CW_FORMAT_SLINEAR);
		if (res < 0) {
			cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
			cw_dsp_free(sildet);
			return -1;
		}
	}
	/* Request a video update */
	cw_indicate(chan, CW_CONTROL_VIDUPDATE);

	if (x == fmtcnt) {
	/* Loop forever, writing the packets we read to the writer(s), until
	   we read a # or get a hangup */
		f = NULL;
		for(;;) {
		 	res = cw_waitfor(chan, 2000);
			if (!res) {
				cw_log(LOG_DEBUG, "One waitfor failed, trying another\n");
				/* Try one more time in case of masq */
			 	res = cw_waitfor(chan, 2000);
				if (!res) {
					cw_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
					res = -1;
				}
			}

			if (res < 0) {
				f = NULL;
				break;
			}
			f = cw_read(chan);
			if (!f)
				break;
			if (f->frametype == CW_FRAME_VOICE) {
				/* write each format */
				for (x=0;x<fmtcnt;x++) {
					res = cw_writestream(others[x], f);
				}

				/* Silence Detection */
				if (maxsilence > 0) {
					dspsilence = 0;
					cw_dsp_silence(sildet, f, &dspsilence);
					if (dspsilence)
						totalsilence = dspsilence;
					else
						totalsilence = 0;

					if (totalsilence > maxsilence) {
						/* Ended happily with silence */
						if (option_verbose > 2)
							cw_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
						cw_fr_free(f);
						gotsilence = 1;
						outmsg=2;
						break;
					}
				}
				/* Exit on any error */
				if (res) {
					cw_log(LOG_WARNING, "Error writing frame\n");
					cw_fr_free(f);
					break;
				}
			} else if (f->frametype == CW_FRAME_VIDEO) {
				/* Write only once */
				cw_writestream(others[0], f);
			} else if (f->frametype == CW_FRAME_DTMF) {
				if (f->subclass == '#') {
					if (option_verbose > 2)
						cw_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
					res = '#';
					outmsg = 2;
					cw_fr_free(f);
					break;
				}
				if (f->subclass == '0') {
				/* Check for a '0' during message recording also, in case caller wants operator */
					if (option_verbose > 2)
						cw_verbose(VERBOSE_PREFIX_3 "User cancelled by pressing %c\n", f->subclass);
					res = '0';
					outmsg = 0;
					cw_fr_free(f);
					break;
				}
			}
			if (maxtime) {
				time(&end);
				if (maxtime < (end - start)) {
					if (option_verbose > 2)
						cw_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
					outmsg = 2;
					res = 't';
					cw_fr_free(f);
					break;
				}
			}
			cw_fr_free(f);
		}
		if (end == start) time(&end);
		if (!f) {
			if (option_verbose > 2)
				cw_verbose( VERBOSE_PREFIX_3 "User hung up\n");
			res = -1;
			outmsg=1;
		}
	} else {
		cw_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
	}

	*duration = end - start;

	for (x=0;x<fmtcnt;x++) {
		if (!others[x])
			break;
		if (res > 0) {
			if (totalsilence)
				cw_stream_rewind(others[x], totalsilence-200);
			else
				cw_stream_rewind(others[x], 200);
		}
		cw_truncstream(others[x]);
		cw_closestream(others[x]);
	}
	if (rfmt) {
		if (cw_set_read_format(chan, rfmt)) {
			cw_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", cw_getformatname(rfmt), chan->name);
		}
	}
	if (outmsg > 1) {
		/* Let them know recording is stopped */
		if(!cw_streamfile(chan, "auth-thankyou", chan->language))
			cw_waitstream(chan, "");
	}
	if (sildet)
		cw_dsp_free(sildet);
	return res;
}
Пример #26
0
int cw_play_and_prepend(struct cw_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
{
	int d = 0;
	char *fmts;
	char comment[256];
	int x, fmtcnt=1, res=-1,outmsg=0;
	struct cw_frame *f;
	struct cw_filestream *others[MAX_OTHER_FORMATS];
	struct cw_filestream *realfiles[MAX_OTHER_FORMATS];
	char *sfmt[MAX_OTHER_FORMATS];
	char *stringp=NULL;
	time_t start, end;
	struct cw_dsp *sildet;   	/* silence detector dsp */
	int totalsilence = 0;
	int dspsilence = 0;
	int gotsilence = 0;		/* did we timeout for silence? */
	int rfmt=0;	
	char prependfile[80];
	
	if (silencethreshold < 0)
		silencethreshold = global_silence_threshold;

	if (maxsilence < 0)
		maxsilence = global_maxsilence;

	/* barf if no pointer passed to store duration in */
	if (duration == NULL) {
		cw_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n");
		return -1;
	}

	cw_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);

	if (playfile || beep) {	
		if (!beep)
			d = cw_play_and_wait(chan, playfile);
		if (d > -1)
			d = cw_streamfile(chan, "beep",chan->language);
		if (!d)
			d = cw_waitstream(chan,"");
		if (d < 0)
			return -1;
	}
	cw_copy_string(prependfile, recordfile, sizeof(prependfile));	
	strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
			
	fmts = cw_strdupa(fmt);
	
	stringp=fmts;
	strsep(&stringp, "|,");
	cw_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);	
	sfmt[0] = cw_strdupa(fmts);
	
	while((fmt = strsep(&stringp, "|,"))) {
		if (fmtcnt > MAX_OTHER_FORMATS - 1) {
			cw_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
			break;
		}
		sfmt[fmtcnt++] = cw_strdupa(fmt);
	}

	time(&start);
	end=start;  /* pre-initialize end to be same as start in case we never get into loop */
	for (x=0;x<fmtcnt;x++) {
		others[x] = cw_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700);
		cw_verbose( VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]);
		if (!others[x]) {
			break;
		}
	}
	
	sildet = cw_dsp_new(); /* Create the silence detector */
	if (!sildet) {
		cw_log(LOG_WARNING, "Unable to create silence detector :(\n");
		return -1;
	}
	cw_dsp_set_threshold(sildet, silencethreshold);

	if (maxsilence > 0) {
		rfmt = chan->readformat;
		res = cw_set_read_format(chan, CW_FORMAT_SLINEAR);
		if (res < 0) {
			cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
			return -1;
		}
	}
						
	if (x == fmtcnt) {
	/* Loop forever, writing the packets we read to the writer(s), until
	   we read a # or get a hangup */
		f = NULL;
		for(;;) {
		 	res = cw_waitfor(chan, 2000);
			if (!res) {
				cw_log(LOG_DEBUG, "One waitfor failed, trying another\n");
				/* Try one more time in case of masq */
			 	res = cw_waitfor(chan, 2000);
				if (!res) {
					cw_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
					res = -1;
				}
			}
			
			if (res < 0) {
				f = NULL;
				break;
			}
			f = cw_read(chan);
			if (!f)
				break;
			if (f->frametype == CW_FRAME_VOICE) {
				/* write each format */
				for (x=0;x<fmtcnt;x++) {
					if (!others[x])
						break;
					res = cw_writestream(others[x], f);
				}
				
				/* Silence Detection */
				if (maxsilence > 0) {
					dspsilence = 0;
					cw_dsp_silence(sildet, f, &dspsilence);
					if (dspsilence)
						totalsilence = dspsilence;
					else
						totalsilence = 0;
					
					if (totalsilence > maxsilence) {
					/* Ended happily with silence */
					if (option_verbose > 2) 
						cw_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
					cw_fr_free(f);
					gotsilence = 1;
					outmsg=2;
					break;
					}
				}
				/* Exit on any error */
				if (res) {
					cw_log(LOG_WARNING, "Error writing frame\n");
					cw_fr_free(f);
					break;
				}
			} else if (f->frametype == CW_FRAME_VIDEO) {
				/* Write only once */
				cw_writestream(others[0], f);
			} else if (f->frametype == CW_FRAME_DTMF) {
				/* stop recording with any digit */
				if (option_verbose > 2) 
					cw_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
				res = 't';
				outmsg = 2;
				cw_fr_free(f);
				break;
			}
			if (maxtime) {
				time(&end);
				if (maxtime < (end - start)) {
					if (option_verbose > 2)
						cw_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
					res = 't';
					outmsg=2;
					cw_fr_free(f);
					break;
				}
			}
			cw_fr_free(f);
		}
		if (end == start)
            time(&end);
		if (!f) {
			if (option_verbose > 2) 
				cw_verbose( VERBOSE_PREFIX_3 "User hung up\n");
			res = -1;
			outmsg=1;
#if 0
			/* delete all the prepend files */
			for (x=0;x<fmtcnt;x++) {
				if (!others[x])
					break;
				cw_closestream(others[x]);
				cw_filedelete(prependfile, sfmt[x]);
			}
#endif
		}
	} else {
		cw_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); 
	}
	*duration = end - start;
#if 0
	if (outmsg > 1) {
#else
	if (outmsg) {
#endif
		struct cw_frame *fr;
		for (x=0;x<fmtcnt;x++) {
			snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
			realfiles[x] = cw_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
			if (!others[x] || !realfiles[x])
				break;
			if (totalsilence)
				cw_stream_rewind(others[x], totalsilence-200);
			else
				cw_stream_rewind(others[x], 200);
			cw_truncstream(others[x]);
			/* add the original file too */
			while ((fr = cw_readframe(realfiles[x]))) {
				cw_writestream(others[x],fr);
			}
			cw_closestream(others[x]);
			cw_closestream(realfiles[x]);
			cw_filerename(prependfile, recordfile, sfmt[x]);
#if 0
			cw_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile);
#endif
			cw_filedelete(prependfile, sfmt[x]);
		}
	}
	if (rfmt) {
		if (cw_set_read_format(chan, rfmt)) {
			cw_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", cw_getformatname(rfmt), chan->name);
		}
	}
	if (outmsg) {
		if (outmsg > 1) {
			/* Let them know it worked */
			cw_streamfile(chan, "auth-thankyou", chan->language);
			cw_waitstream(chan, "");
		}
	}	
	return res;
}

/* Channel group core functions */

int cw_app_group_split_group(char *data, char *group, int group_max, char *category, int category_max)
{
	int res=0;
	char tmp[256];
	char *grp=NULL, *cat=NULL;

	if (!cw_strlen_zero(data)) {
		cw_copy_string(tmp, data, sizeof(tmp));
		grp = tmp;
		cat = strchr(tmp, '@');
		if (cat) {
			*cat = '\0';
			cat++;
		}
	}

	if (!cw_strlen_zero(grp))
		cw_copy_string(group, grp, group_max);
	else
		res = -1;

	if (cat)
		snprintf(category, category_max, "%s_%s", GROUP_CATEGORY_PREFIX, cat);
	else
		cw_copy_string(category, GROUP_CATEGORY_PREFIX, category_max);

	return res;
}
Пример #27
0
int ldap_lookup(char *host, int port, int version, int timeout, char *user, char *pass, 
		char *base, char *scope, char *filter, char *attribute, char *result) {
	char *attrs[] = { NULL };
	char **values;
	LDAP *ld;
	LDAPMessage *res, *entry;
	int ret, ldap_scope = LDAP_SCOPE_SUBTREE;

	ld = ldap_init(host, port);
	if (!ld) {
		cw_log(LOG_WARNING, "LDAPget: unable to initialize ldap connection to %s:%d\n", host, port);
		return 0;
	}
	ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timeout);
	ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
	if (user) {
		if (option_verbose > 2)
			cw_verbose(VERBOSE_PREFIX_3 "LDAPget: bind to %s as %s\n", host, user);
		ret = ldap_simple_bind_s(ld, user, pass);
	} else {
		if (option_verbose > 2)
			cw_verbose(VERBOSE_PREFIX_3 "LDAPget: bind to %s anonymously\n", host);
		ret = ldap_simple_bind_s(ld, NULL, NULL);
	}
	if (ret) {
		cw_log(LOG_WARNING, "LDAPget: bind failed: %s\n", ldap_err2string(ret));
		ldap_unbind(ld);
		return 0;
	}

	if (strncmp(scope,"sub",3)==0) {
		ldap_scope = LDAP_SCOPE_SUBTREE;
	} else if (strncmp(scope,"base",4)==0) {
		ldap_scope = LDAP_SCOPE_BASE;
	} else if (strncmp(scope,"one",3)==0) {
		ldap_scope = LDAP_SCOPE_ONELEVEL;
	}

	ret = ldap_search_s(ld, base, ldap_scope, filter, attrs, 0, &res);
	if (ret) {
		cw_log(LOG_DEBUG, "LDAPget: search failed: %s\n", ldap_err2string(ret));
		ldap_msgfree(res);
		ldap_unbind(ld);
		return 0;
	}

	entry = ldap_first_entry(ld, res);
	if (!entry) {
		if (option_verbose > 2)
			cw_verbose (VERBOSE_PREFIX_3 "LDAPget: Value not found in directory.\n");
		ldap_msgfree(res);
		ldap_unbind(ld);
		return 0;
	}

	values = ldap_get_values(ld, entry, attribute);
	if (values && values[0]) {
		memset(result, 0, strlen(values[0]));
		strncpy(result, values[0], strlen(values[0]));
		result[strlen(values[0])] = '\0';
		if (option_verbose > 2)
			cw_verbose(VERBOSE_PREFIX_3 "LDAPget: %s=%s\n", attribute, result);
	} else {
		if (option_verbose > 2)
			cw_verbose (VERBOSE_PREFIX_3 "LDAPget: %s not found.\n", attribute);
		ldap_msgfree(res);
		ldap_unbind(ld);
		return 0;
	}
	ldap_value_free(values);
	ldap_msgfree(res);
	ldap_unbind_s(ld);
	return 1;
}
Пример #28
0
static int ldap_exec(struct cw_channel *chan, int argc, char **argv)
{
	char result[2048];
	struct localuser *u;
	char *varname, *config, *keys = NULL, *key = NULL, *tail = NULL;
	char *result_conv;
	struct cw_config *cfg;

	int port = LDAP_PORT, version = LDAP_VERSION2, timeout = 10;
	char *temp, *host, *user, *pass, *base, *scope, *filter, *_filter, *attribute,
		 *convert_from = NULL, *convert_to = NULL;

	if (argc != 1) {
		cw_log(LOG_ERROR, "Syntax: %s\n", g_syntax);
		pbx_builtin_setvar_helper(chan, "LDAPSTATUS", "FAILURE");
		return 0;
	}

	LOCAL_USER_ADD(u);

	if (strchr(argv[0], '=')) {
		varname = strsep (&argv[0], "=");
		if (strchr(argv[0], '/')) {
			config = strsep(&argv[0], "/");
			keys = strsep(&argv[0], "\0");
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "LDAPget: varname=%s, config-section=%s, keys=%s\n", varname, config, keys);
		} else {
			config = strsep(&argv[0], "\0");
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "LDAPget: varname=%s, config-section=%s\n", varname, config);
		}
		if (!varname || !config) {
			cw_log(LOG_WARNING, "Ignoring; Syntax error in argument\n");
			pbx_builtin_setvar_helper(chan, "LDAPSTATUS", "FAILURE");
			return 0;
		}
	} else {
		cw_log(LOG_WARNING, "Ignoring, no parameters\n");
		pbx_builtin_setvar_helper(chan, "LDAPSTATUS", "FAILURE");
		return 0;
	}

	cfg = cw_config_load(LDAP_CONFIG);

	if (!cfg) {
		cw_log(LOG_WARNING, "No such configuration file %s\n", LDAP_CONFIG);
		return -1;
	}
	if (!(host = cw_variable_retrieve(cfg, config, "host"))) {
		host = "localhost";
	}
	if ((temp = cw_variable_retrieve(cfg, config, "port"))) {
		port = atoi(temp);
	}
	if ((temp = cw_variable_retrieve(cfg, config, "timeout"))) {
		timeout = atoi(temp);
	}
	if ((temp = cw_variable_retrieve(cfg, config, "version"))) {
		version = atoi(temp);
	}
	user = cw_variable_retrieve(cfg, config, "user");
	pass = cw_variable_retrieve(cfg, config, "pass");
	base = cw_variable_retrieve(cfg, config, "base");
	if (!base) base = "";
	base = replace_cw_vars(chan, base);
	if (!(scope = cw_variable_retrieve(cfg, config, "scope"))) {
		scope = "sub";
	}
	if (!(_filter = cw_variable_retrieve(cfg, config, "filter"))) {
		_filter = "(&(objectClass=person)(telephoneNumber=${CALLERIDNUM}))";
	}
	if (!(attribute = cw_variable_retrieve(cfg, config, "attribute"))) {
		attribute = "cn";
	}
	if ((temp = cw_variable_retrieve(cfg, config, "convert"))) {
		if (strchr(temp, ',')) {
			convert_from = strtrim(strsep(&temp, ","));
			convert_to = strtrim(strsep(&temp, "\0"));
		} else {
			cw_log(LOG_WARNING, "syntax error: convert = <source-charset>,<destination charset>\n");
		}
	}

	if (option_verbose > 3)
		cw_verbose (VERBOSE_PREFIX_4 "LDAPget: ldap://%s/%s?%s?%s?%s\n", host, base, attribute, scope, _filter);

	filter = replace_cw_vars(chan, _filter);
	if (option_verbose > 3)
		cw_verbose (VERBOSE_PREFIX_4 "LDAPget: %s\n", filter);

	if (keys && strstr(filter, "%s") != NULL) {
		filter = (char *)realloc(filter, (strlen(filter)+strlen(keys)+1)*sizeof(char));
		while((key = strsep(&keys, "|")) != NULL) {
			if ((tail = strstr(filter, "%s")) != NULL) {
				memmove(tail+strlen(key), tail+2, strlen(tail+2)+1);
				memcpy(tail, key, strlen(key));
			}
		}
	}

	if (option_verbose > 2)
		cw_verbose (VERBOSE_PREFIX_3 "LDAPget: ldap://%s/%s?%s?%s?%s\n", host, base, attribute, scope, filter);

	if (ldap_lookup(host, port, version, timeout, user, pass, base, scope, filter, attribute, result)) {

		if (convert_from) {
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "LDAPget: convert: %s -> %s\n", convert_from, convert_to);
			result_conv = malloc(strlen(result) * 2);
			strconvert(convert_from, convert_to, result, result_conv);
			strcpy(result, result_conv);
			free(result_conv);
		}
		
		if (strcmp("CALLERIDNAME", varname)==0) {
			cw_set_callerid(chan, NULL, result, NULL);
			if (option_verbose > 2)
				cw_verbose (VERBOSE_PREFIX_3 "LDAPget: set CIDNAME to \"%s\"\n", result);
		} else {
			if (option_verbose > 2)
				cw_verbose (VERBOSE_PREFIX_3 "LDAPget: set %s='%s'\n", varname, result);
			pbx_builtin_setvar_helper(chan, varname, result);
		}
		
	} else {
		pbx_builtin_setvar_helper(chan, "LDAPSTATUS", "FAILURE");
		return 0;
	}
	cw_config_destroy(cfg);
	free(filter);
	free(base);
	pbx_builtin_setvar_helper(chan, "LDAPSTATUS", "SUCCESS");

	LOCAL_USER_REMOVE(u);
	return 0;
}
Пример #29
0
static int privacy_exec (struct cw_channel *chan, int argc, char **argv)
{
	char phone[30];
	struct localuser *u;
	struct cw_config *cfg;
	char *s;
	int res=0;
	int retries;
	int maxretries = 3;
	int minlength = 10;
	int x;

	LOCAL_USER_ADD (u);

	if (!cw_strlen_zero(chan->cid.cid_num)) {
		if (option_verbose > 2)
			cw_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
		pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
	} else {
		/*Answer the channel if it is not already*/
		if (chan->_state != CW_STATE_UP) {
			res = cw_answer(chan);
			if (res) {
				pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAIL");
				LOCAL_USER_REMOVE(u);
				return 0;
			}
		}
		/*Read in the config file*/
		cfg = cw_config_load(PRIV_CONFIG);
		
		
		/*Play unidentified call*/
		res = cw_safe_sleep(chan, 1000);
		if (!res)
			res = cw_streamfile(chan, "privacy-unident", chan->language);
		if (!res)
			res = cw_waitstream(chan, "");

        if (cfg && (s = cw_variable_retrieve(cfg, "general", "maxretries"))) {
                if (sscanf(s, "%d", &x) == 1) {
                        maxretries = x;
                } else {
                        cw_log(LOG_WARNING, "Invalid max retries argument\n");
                }
        }
        if (cfg && (s = cw_variable_retrieve(cfg, "general", "minlength"))) {
                if (sscanf(s, "%d", &x) == 1) {
                        minlength = x;
                } else {
                        cw_log(LOG_WARNING, "Invalid min length argument\n");
                }
        }
			
		/*Ask for 10 digit number, give 3 attempts*/
		for (retries = 0; retries < maxretries; retries++) {
			if (!res ) 
				res = cw_app_getdata(chan, "privacy-prompt", phone, sizeof(phone), 0);

			if (res < 0)
				break;

			/*Make sure we get at least our minimum of digits*/
			if (strlen(phone) >= minlength ) 
				break;
			else {
				res = cw_streamfile(chan, "privacy-incorrect", chan->language);
				if (!res)
					res = cw_waitstream(chan, "");
			}
		}
		
		/*Got a number, play sounds and send them on their way*/
		if ((retries < maxretries) && res == 1 ) {
			res = cw_streamfile(chan, "privacy-thankyou", chan->language);
			if (!res)
				res = cw_waitstream(chan, "");
			cw_set_callerid (chan, phone, "Privacy Manager", NULL);
			if (option_verbose > 2)
				cw_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",phone);
			pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
		} else {
			/* Flag Failure  */
			pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAIL");
		}
		if (cfg) 
			cw_config_destroy(cfg);
	}

  LOCAL_USER_REMOVE (u);
  return 0;
}
Пример #30
0
static struct cw_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
{
	int ktype = 0;
	char *c = NULL;
	char ffname[256];
	FILE *f;
	EVP_MD_CTX mdctx;
	unsigned char md_value[CW_MAX_BINARY_MD_SIZE];
	unsigned int md_len;
	struct cw_key *key;
	static int notice = 0;
	int found = 0;

	/* Make sure its name is a public or private key */

	if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
		ktype = CW_KEY_PUBLIC;
	} else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
		ktype = CW_KEY_PRIVATE;
	} else
		return NULL;

	/* Get actual filename */
	snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);

	cw_mutex_lock(&keylock);
	key = keys;
	while(key) {
		/* Look for an existing version already */
		if (!strcasecmp(key->fn, ffname)) 
			break;
		key = key->next;
	}
	cw_mutex_unlock(&keylock);

	/* Open file */
	f = fopen(ffname, "r");
	if (!f) {
		cw_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
		return NULL;
	}
	EVP_DigestInit(&mdctx, EVP_md5());
	while(!feof(f)) {
		/* Calculate a "whatever" quality md5sum of the key */
		char buf[256];
		memset(buf, 0, 256);
		fgets(buf, sizeof(buf), f);
		if (!feof(f)) {
			EVP_DigestUpdate(&mdctx, (unsigned char *) buf, strlen(buf));
		}
	}
	EVP_DigestFinal(&mdctx, md_value, &md_len);
	if (key) {
		/* If the MD5 sum is the same, and it isn't awaiting a passcode 
		   then this is far enough */
		if (!memcmp(md_value, key->md_value, md_len) &&
		    !(key->ktype & KEY_NEEDS_PASSCODE)) {
			fclose(f);
			key->delme = 0;
			return NULL;
		} else {
			/* Preserve keytype */
			ktype = key->ktype;
			/* Recycle the same structure */
			found++;
		}
	}

	/* Make fname just be the normal name now */
	*c = '\0';
	if (!key) {
		key = (struct cw_key *)malloc(sizeof(struct cw_key));
		if (!key) {
			cw_log(LOG_WARNING, "Out of memory\n");
			fclose(f);
			return NULL;
		}
		memset(key, 0, sizeof(struct cw_key));
	}
	/* At this point we have a key structure (old or new).  Time to
	   fill it with what we know */
	/* Gotta lock if this one already exists */
	if (found)
		cw_mutex_lock(&keylock);
	/* First the filename */
	cw_copy_string(key->fn, ffname, sizeof(key->fn));
	/* Then the name */
	cw_copy_string(key->name, fname, sizeof(key->name));
	key->ktype = ktype;
	/* Yes, assume we're going to be deleted */
	key->delme = 1;
	/* Keep the key type */
	memcpy(key->md_value, md_value, md_len);
	key->md_len = md_len;
	/* Can I/O takes the FD we're given */
	key->infd = ifd;
	key->outfd = ofd;
	/* Reset the file back to the beginning */
	rewind(f);
	/* Now load the key with the right method */
	if (ktype == CW_KEY_PUBLIC)
		key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
	else
		key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
	fclose(f);
	if (key->rsa) {
		if (RSA_size(key->rsa) == 128) {
			/* Key loaded okay */
			key->ktype &= ~KEY_NEEDS_PASSCODE;
			if (option_verbose > 2)
				cw_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
			if (option_debug)
				cw_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
			key->delme = 0;
		} else
			cw_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
	} else if (key->infd != -2) {
		cw_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
		if (ofd > -1) {
			ERR_print_errors_fp(stderr);
		} else
			ERR_print_errors_fp(stderr);
	} else {
		cw_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
		key->ktype |= KEY_NEEDS_PASSCODE;
		if (!notice) {
			if (!option_initcrypto) 
				cw_log(LOG_NOTICE, "Add the '-i' flag to the callweaver command line if you want to automatically initialize passcodes at launch.\n");
			notice++;
		}
		/* Keep it anyway */
		key->delme = 0;
		/* Print final notice about "init keys" when done */
		*not2 = 1;
	}
	if (found)
		cw_mutex_unlock(&keylock);
	if (!found) {
		cw_mutex_lock(&keylock);
		key->next = keys;
		keys = key;
		cw_mutex_unlock(&keylock);
	}
	return key;
}