Exemplo n.º 1
0
/*获得用户所在组xml文件
*/
char * CBaseModule::getMobUserGroupXMLFile(const char *groupname, const char *mobusername)
{
	if (NULL == groupname || NULL == mobusername || switch_strlen_zero(groupname) || switch_strlen_zero(mobusername)) {
		return NULL;
	}

	//conf\directory\groups\用户组名
	char *path = switch_mprintf("%s%s%s%s%s%s%s%s%s%s", 
		SWITCH_GLOBAL_dirs.conf_dir, 
		SWITCH_PATH_SEPARATOR, 
		USER_DIRECTORY, 
		SWITCH_PATH_SEPARATOR, 
		DIR_DEFINE_GROUPS,  	//组的根目录groups  		  
		SWITCH_PATH_SEPARATOR, 
		groupname, 
		SWITCH_PATH_SEPARATOR, 
		mobusername, 
		CARICCP_XML_FILE_TYPE);

	return path;
}
Exemplo n.º 2
0
/* This is where we actually charge the guy 
  This can be called anytime a call is in progress or at the end of a call before the session is destroyed */
static switch_status_t do_billing(switch_core_session_t *session)
{
	/* FS vars we will use */
	switch_channel_t *channel;
	switch_caller_profile_t *profile;

	/* Local vars */
	nibble_data_t *nibble_data;
	switch_time_t ts = switch_micro_time_now();
	double billamount;
	char date[80] = "";
	char *uuid;
	switch_size_t retsize;
	switch_time_exp_t tm;
	const char *billrate;
	const char *billincrement;
	const char *billaccount;
	double nobal_amt = globals.nobal_amt;
	double lowbal_amt = globals.lowbal_amt;
	double balance;

	if (!session) {
		/* Why are we here? */
		return SWITCH_STATUS_SUCCESS;
	}

	uuid = switch_core_session_get_uuid(session);

	/* Get channel var */
	if (!(channel = switch_core_session_get_channel(session))) {
		return SWITCH_STATUS_SUCCESS;
	}

	/* Variables kept in FS but relevant only to this module */
	billrate = switch_channel_get_variable(channel, "nibble_rate");
	billincrement = switch_channel_get_variable(channel, "nibble_increment");
	billaccount = switch_channel_get_variable(channel, "nibble_account");
	
	if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) {
		nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt"));
	}
	
	if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) {
		lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt"));
	}
	
	/* Return if there's no billing information on this session */
	if (!billrate || !billaccount) {
		return SWITCH_STATUS_SUCCESS;
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate,
					  billaccount);

	/* Get caller profile info from channel */
	profile = switch_channel_get_caller_profile(channel);

	if (!profile || !profile->times) {
		/* No caller profile (why would this happen?) */
		return SWITCH_STATUS_SUCCESS;
	}

	if (profile->times->answered < 1) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Not billing %s - call is not in answered state\n", billaccount);

		/* See if this person has enough money left to continue the call */
		balance = get_balance(billaccount, channel);
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, nobal_amt);
		if (balance <= nobal_amt) {
			/* Not enough money - reroute call to nobal location */
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
							  balance, nobal_amt, billaccount);

			transfer_call(session, globals.nobal_action);
		}

		return SWITCH_STATUS_SUCCESS;
	}

	/* Lock this session's data for this module while we tinker with it */
	if (globals.mutex) {
		switch_mutex_lock(globals.mutex);
	}

	/* Get our nibble data var. This will be NULL if it's our first call here for this session */
	nibble_data = (nibble_data_t *) switch_channel_get_private(channel, "_nibble_data_");

	/* Are we in paused mode? If so, we don't do anything here - go back! */
	if (nibble_data && (nibble_data->pausets > 0)) {
		if (globals.mutex) {
			switch_mutex_unlock(globals.mutex);
		}
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Received heartbeat, but we're paused - ignoring\n");
		return SWITCH_STATUS_SUCCESS;
	}

	/* Have we done any billing on this channel yet? If no, set up vars for doing so */
	if (!nibble_data) {
		nibble_data = switch_core_session_alloc(session, sizeof(*nibble_data));
		memset(nibble_data, 0, sizeof(*nibble_data));

		/* Setup new billing data (based on call answer time, in case this module started late with active calls) */
		nibble_data->lastts = profile->times->answered;	/* Set the initial answer time to match when the call was really answered */
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid);
	}

	switch_time_exp_lt(&tm, nibble_data->lastts);
	switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n",
					  (int) ((ts - nibble_data->lastts) / 1000000), date);

	if ((ts - nibble_data->lastts) >= 0) {
		/* If billincrement is set we bill by it and not by time elapsed */
		if (!(switch_strlen_zero(billincrement))) {
			switch_time_t chargedunits = (ts - nibble_data->lastts) / 1000000 <= atol(billincrement) ? atol(billincrement) * 1000000 : (switch_time_t)(ceil((ts - nibble_data->lastts) / (atol(billincrement) * 1000000.0))) * atol(billincrement) * 1000000;
			billamount = (atof(billrate) / 1000000 / 60) * chargedunits - nibble_data->bill_adjustments;
			/* Account for the prepaid amount */
			nibble_data->lastts += chargedunits;
		} else {		
			/* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */
			billamount = (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
			/* Update the last time we billed */
			nibble_data->lastts = ts;
		}

		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount,
						  uuid, nibble_data->total);

		/* DO ODBC BILLING HERE and reset counters if it's successful! */
		if (bill_event(billamount, billaccount, channel) == SWITCH_STATUS_SUCCESS) {
			/* Increment total cost */
			nibble_data->total += billamount;

			/* Reset manual billing adjustments from pausing */
			nibble_data->bill_adjustments = 0;

			/* Update channel variable with current billing */
			switch_channel_set_variable_printf(channel, "nibble_total_billed", "%f", nibble_data->total);
		} else {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to log to database!\n");
		}
	} else {
		if (switch_strlen_zero(billincrement))
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n", uuid);
	}

	/* Save this location */
	if (channel) {
		switch_channel_set_private(channel, "_nibble_data_", nibble_data);

		/* don't verify balance and transfer to nobal if we're done with call */
		if (switch_channel_get_state(channel) != CS_REPORTING && switch_channel_get_state(channel) != CS_HANGUP) {
			
			balance = get_balance(billaccount, channel);
			
			/* See if we've achieved low balance */
			if (!nibble_data->lowbal_action_executed && balance <= lowbal_amt) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below low balance amount of %f! (Account %s)\n",
								  balance, lowbal_amt, billaccount);

				if (exec_app(session, globals.lowbal_action) != SWITCH_STATUS_SUCCESS)
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Low balance action didn't execute\n");
				else
					nibble_data->lowbal_action_executed = 1;
			}

			/* See if this person has enough money left to continue the call */
			if (balance <= nobal_amt) {
				/* Not enough money - reroute call to nobal location */
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
								  balance, nobal_amt, billaccount);

				/* IMPORTANT: Billing must be paused before the transfer occurs! This prevents infinite loops, since the transfer will result */
				/* in nibblebill checking the call again in the routing process for an allowed balance! */
				/* If you intend to give the user the option to re-up their balance, you must clear & resume billing once the balance is updated! */
				nibblebill_pause(session);
				transfer_call(session, globals.nobal_action);
			}
		}
	}


	/* Done changing - release lock */
	if (globals.mutex) {
		switch_mutex_unlock(globals.mutex);
	}

	/* Go check if this call is allowed to continue */

	return SWITCH_STATUS_SUCCESS;
}
Exemplo n.º 3
0
/* the main application entry point */
int main(int argc, char *argv[])
{
	char pid_path[PATH_MAX] = "";	/* full path to the pid file */
	char pid_buffer[32] = "";	/* pid string */
	char old_pid_buffer[32] = "";	/* pid string */
	switch_size_t pid_len, old_pid_len;
	const char *err = NULL;		/* error value for return from freeswitch initialization */
#ifndef WIN32
	switch_bool_t nf = SWITCH_FALSE;				/* TRUE if we are running in nofork mode */
	switch_bool_t do_wait = SWITCH_FALSE;
	char *runas_user = NULL;
	char *runas_group = NULL;
	int fds[2] = { 0, 0 };
#else
	switch_bool_t win32_service = SWITCH_FALSE;
#endif
	switch_bool_t nc = SWITCH_FALSE;				/* TRUE if we are running in noconsole mode */
	pid_t pid = 0;
	int i, x;
	char *opts;
	char opts_str[1024] = "";
	char *local_argv[1024] = { 0 };
	int local_argc = argc;
	char *arg_argv[128] = { 0 };
	int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0;
	int priority = 0;
#ifdef __sun
	switch_core_flag_t flags = SCF_USE_SQL;
#else
	switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT;
#endif
	int ret = 0;
	switch_status_t destroy_status;
	switch_file_t *fd;
	switch_memory_pool_t *pool = NULL;
#ifdef HAVE_SETRLIMIT
#ifndef FS_64BIT
	switch_bool_t waste = SWITCH_FALSE;
#endif
#endif

	for (x = 0; x < argc; x++) {
		local_argv[x] = argv[x];
	}

	if ((opts = getenv("FREESWITCH_OPTS"))) {
		strncpy(opts_str, opts, sizeof(opts_str) - 1);
		i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0])));
		for (x = 0; x < i; x++) {
			local_argv[local_argc++] = arg_argv[x];
		}
	}

	if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) {
		nc = SWITCH_TRUE;
	}

	for (x = 1; x < local_argc; x++) {

		if (switch_strlen_zero(local_argv[x]))
			continue;

		if (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")) {
			printf("%s\n", usage);
			exit(EXIT_SUCCESS);
		}
#ifdef WIN32
		if (x == 1 && !strcmp(local_argv[x], "-service")) {
			/* New installs will always have the service name specified, but keep a default for compat */
			x++;
			if (!switch_strlen_zero(local_argv[x])) {
				switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
			} else {
				switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
			}

			win32_service = SWITCH_TRUE;
			continue;
		}

		else if (x == 1 && !strcmp(local_argv[x], "-install")) {
			char servicePath[PATH_MAX];
			char exePath[PATH_MAX];
			SC_HANDLE hService;
			SC_HANDLE hSCManager;
			SERVICE_DESCRIPTION desc;
			desc.lpDescription = "The FreeSWITCH service.";

			x++;
			if (!switch_strlen_zero(local_argv[x])) {
				switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
			} else {
				switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
			}

			GetModuleFileName(NULL, exePath, sizeof(exePath));
			snprintf(servicePath, sizeof(servicePath), "%s -service %s", exePath, service_name);

			/* Perform service installation */

			hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
			if (!hSCManager) {
				fprintf(stderr, "Could not open service manager (%u).\n", GetLastError());
				exit(EXIT_FAILURE);
			}

			hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
						 servicePath, NULL, NULL, NULL, NULL, /* Service start name */ NULL);
			if (!hService) {
				fprintf(stderr, "Error creating freeswitch service (%u).\n", GetLastError());
				CloseServiceHandle(hSCManager);
				exit(EXIT_FAILURE);
			}

			/* Set desc, and don't care if it succeeds */
			if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
				fprintf(stderr, "FreeSWITCH installed, but could not set the service description (%u).\n", GetLastError());
			}

			CloseServiceHandle(hService);
			CloseServiceHandle(hSCManager);
			exit(EXIT_SUCCESS);
		}

		else if (x == 1 && !strcmp(local_argv[x], "-uninstall")) {
			SC_HANDLE hService;
			SC_HANDLE hSCManager;
			BOOL deleted;

			x++;
			if (!switch_strlen_zero(local_argv[x])) {
				switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
			} else {
				switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
			}

			/* Do the uninstallation */
			hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
			if (!hSCManager) {
				fprintf(stderr, "Could not open service manager (%u).\n", GetLastError());
				exit(EXIT_FAILURE);
			}

			hService = OpenService(hSCManager, service_name, DELETE);
			if (!hService) {
				fprintf(stderr, "Error opening service (%u).\n", GetLastError());
				CloseServiceHandle(hSCManager);
				exit(EXIT_FAILURE);
			}

			/* remove the service! */
			deleted = DeleteService(hService);
			if (!deleted) {
				fprintf(stderr, "Error deleting service (%u).\n", GetLastError());
			}

			CloseServiceHandle(hService);
			CloseServiceHandle(hSCManager);
			exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE);
		}

		else if (!strcmp(local_argv[x], "-monotonic-clock")) {
			flags |= SCF_USE_WIN32_MONOTONIC;
		}
#else
		else if (!strcmp(local_argv[x], "-u")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
				exit(EXIT_FAILURE);
			}
			runas_user = local_argv[x];
		}

		else if (!strcmp(local_argv[x], "-g")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
				exit(EXIT_FAILURE);
			}
			runas_group = local_argv[x];
		}

		else if (!strcmp(local_argv[x], "-nf")) {
			nf = SWITCH_TRUE;
		}

		else if (!strcmp(local_argv[x], "-version")) {
			fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN);
			exit(EXIT_SUCCESS);
		}
#endif
#ifdef HAVE_SETRLIMIT
		else if (!strcmp(local_argv[x], "-core")) {
			struct rlimit rlp;
			memset(&rlp, 0, sizeof(rlp));
			rlp.rlim_cur = RLIM_INFINITY;
			rlp.rlim_max = RLIM_INFINITY;
			setrlimit(RLIMIT_CORE, &rlp);
		}

		else if (!strcmp(local_argv[x], "-waste")) {
#ifndef FS_64BIT
			fprintf(stderr, "WARNING: Wasting up to 8 megs of memory per thread.\n");
			sleep(2);
			waste = SWITCH_TRUE;
#endif
		}

		else if (!strcmp(local_argv[x], "-no-auto-stack")) {
#ifndef FS_64BIT
			waste = SWITCH_TRUE;
#endif
		}
#endif
		else if (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp")) {
			priority = 2;
		}

		else if (!strcmp(local_argv[x], "-lp")) {
			priority = -1;
		}

		else if (!strcmp(local_argv[x], "-np")) {
			priority = 1;
		}

		else if (!strcmp(local_argv[x], "-nosql")) {
			flags &= ~SCF_USE_SQL;
		}

		else if (!strcmp(local_argv[x], "-nonat")) {
			flags &= ~SCF_USE_AUTO_NAT;
		}

		else if (!strcmp(local_argv[x], "-nonatmap")) {
			flags &= ~SCF_USE_NAT_MAPPING;
		}

		else if (!strcmp(local_argv[x], "-heavy-timer")) {
			flags |= SCF_USE_HEAVY_TIMING;
		}

		else if (!strcmp(local_argv[x], "-nort")) {
			flags &= ~SCF_USE_CLOCK_RT;
		}

		else if (!strcmp(local_argv[x], "-nocal")) {
			flags &= ~SCF_CALIBRATE_CLOCK;
		}

		else if (!strcmp(local_argv[x], "-vg")) {
			flags |= SCF_VG;
		}

		else if (!strcmp(local_argv[x], "-stop")) {
			do_kill = SWITCH_TRUE;
		}

		else if (!strcmp(local_argv[x], "-nc")) {
			nc = SWITCH_TRUE;
		}
#ifndef WIN32
		else if (!strcmp(local_argv[x], "-ncwait")) {
			nc = SWITCH_TRUE;
			do_wait = SWITCH_TRUE;
		}
#endif
		else if (!strcmp(local_argv[x], "-c")) {
			nc = SWITCH_FALSE;
		}

		else if (!strcmp(local_argv[x], "-conf")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -conf you must specify a config directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.conf_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]);
			alt_dirs++;
		}

		else if (!strcmp(local_argv[x], "-mod")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -mod you must specify a module directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.mod_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.mod_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-log")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -log you must specify a log directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.log_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]);
			alt_dirs++;
			log_set = SWITCH_TRUE;
		}

		else if (!strcmp(local_argv[x], "-run")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -run you must specify a pid directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.run_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.run_dir, local_argv[x]);
			run_set = SWITCH_TRUE;
		}

		else if (!strcmp(local_argv[x], "-db")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -db you must specify a db directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.db_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]);
			alt_dirs++;
		}

		else if (!strcmp(local_argv[x], "-scripts")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -scripts you must specify a scripts directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.script_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.script_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-htdocs")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.htdocs_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.htdocs_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-base")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -base you must specify a base directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.base_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.base_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-temp")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -temp you must specify a temp directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.temp_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.temp_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-storage")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -storage you must specify a storage directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.storage_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.storage_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-recordings")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -recordings you must specify a recording directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.recordings_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.recordings_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-grammar")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -grammar you must specify a grammar directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.grammar_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.grammar_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-sounds")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -sounds you must specify a sounds directory\n");
				return 255;
			}

			SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_dirs.sounds_dir) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_dirs.sounds_dir, local_argv[x]);
		}

		else if (!strcmp(local_argv[x], "-cfgname")) {
			x++;
			if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
				fprintf(stderr, "When using -cfgname you must specify a filename\n");
				return 255;
			}

			SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(strlen(local_argv[x]) + 1);
			if (!SWITCH_GLOBAL_filenames.conf_name) {
				fprintf(stderr, "Allocation error\n");
				return 255;
			}
			strcpy(SWITCH_GLOBAL_filenames.conf_name, local_argv[x]);
		}

		/* Unknown option (always last!) */
		else {
			fprintf(stderr, "Unknown option '%s', see '%s -help' for a list of valid options\n",
				local_argv[x], local_argv[0]);
			exit(EXIT_FAILURE);
		}
	}

	if (log_set && !run_set) {
		SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(SWITCH_GLOBAL_dirs.log_dir) + 1);
		if (!SWITCH_GLOBAL_dirs.run_dir) {
			fprintf(stderr, "Allocation error\n");
			return 255;
		}
		strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir);
	}

	if (do_kill) {
		return freeswitch_kill_background();
	}

	if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "FATAL ERROR! Could not initialize APR\n");
		return 255;
	}

	if (alt_dirs && alt_dirs != 3) {
		fprintf(stderr, "You must specify all or none of -conf, -log, and -db\n");
		return 255;
	}

#ifndef FS_64BIT
#if defined(HAVE_SETRLIMIT) && !defined(__sun)
	if (!waste && !(flags & SCF_VG)) {
		struct rlimit rlp;

		memset(&rlp, 0, sizeof(rlp));
		getrlimit(RLIMIT_STACK, &rlp);

		if (rlp.rlim_cur != SWITCH_THREAD_STACKSIZE) {
			char buf[1024] = "";
			int i = 0;

			memset(&rlp, 0, sizeof(rlp));
			rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
			rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
			setrlimit(RLIMIT_STACK, &rlp);

			apr_terminate();
			ret = (int) execv(argv[0], argv);

			for (i = 0; i < argc; i++) {
				switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]);
			}

			return system(buf);
		}
	}
#endif
#endif
	signal(SIGILL, handle_SIGILL);
	signal(SIGTERM, handle_SIGILL);
#ifndef WIN32
	if (do_wait) {
		if (pipe(fds)) {
			fprintf(stderr, "System Error!\n");
			exit(-1);
		}

		signal(SIGCHLD, handle_SIGCHLD);
	}
#endif

	if (nc) {
#ifdef WIN32
		FreeConsole();
#else
		if (!nf) {
			daemonize(do_wait ? fds : NULL);
		}
#endif
	}

	switch (priority) {
	case 2:
		set_realtime_priority();
		break;
	case 1:
		set_normal_priority();
		break;
	case -1:
		set_low_priority();
		break;
	default:
		set_auto_priority();
		break;
	}
	
	switch_core_setrlimits();


#ifndef WIN32
	if (runas_user || runas_group) {
		if (change_user_group(runas_user, runas_group) < 0) {
			fprintf(stderr, "Failed to switch user [%s] / group [%s]\n",
				switch_strlen_zero(runas_user)  ? "-" : runas_user,
				switch_strlen_zero(runas_group) ? "-" : runas_group);
			return 255;
		}
	}
#else
	if (win32_service) {
		/* Attempt to start service */
		SERVICE_TABLE_ENTRY dispatchTable[] = {
			{service_name, &service_main}
			,
			{NULL, NULL}
		};
		service_flags = flags; /* copy parsed flags for service startup */

		if (StartServiceCtrlDispatcher(dispatchTable) == 0) {
			/* Not loaded as a service */
			fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
			fprintf(stderr, "To install the service load freeswitch with -install\n");
		}
		exit(EXIT_SUCCESS);
	}
#endif

	switch_core_set_globals();

	pid = getpid();

	memset(pid_buffer, 0, sizeof(pid_buffer));
	switch_snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile);
	switch_snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid);
	pid_len = strlen(pid_buffer);

	apr_pool_create(&pool, NULL);

	switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, pool);

	if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) == SWITCH_STATUS_SUCCESS) {

		old_pid_len = sizeof(old_pid_buffer);
		switch_file_read(fd, old_pid_buffer, &old_pid_len);
		switch_file_close(fd);
	}

	if (switch_file_open(&fd,
						 pid_path,
						 SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE,
						 SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot open pid file %s.\n", pid_path);
		return 255;
	}

	if (switch_file_lock(fd, SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot lock pid file %s.\n", pid_path);
		old_pid_len = strlen(old_pid_buffer);
		if (strlen(old_pid_buffer)) {
			switch_file_write(fd, old_pid_buffer, &old_pid_len);
		}
		return 255;
	}

	switch_file_write(fd, pid_buffer, &pid_len);

	if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot Initialize [%s]\n", err);
		return 255;
	}

#ifndef WIN32
	if (do_wait) {
		if (fds[1] > -1) {
			int i, v = 1;

			if ((i = write(fds[1], &v, sizeof(v))) < 0) {
				fprintf(stderr, "System Error [%s]\n", strerror(errno));
			} else {
				i = read(fds[1], &v, sizeof(v));
			}
		
			shutdown(fds[1], 2);
			close(fds[1]);
			fds[1] = -1;
		}
	}
#endif

	switch_core_runtime_loop(nc);

	destroy_status = switch_core_destroy();

	switch_file_close(fd);
	apr_pool_destroy(pool);

	if (unlink(pid_path) != 0) {
		fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path);
	}

	if (destroy_status == SWITCH_STATUS_RESTART) {
		char buf[1024] = "";
		int j = 0;

		switch_sleep(1000000);
		ret = (int) execv(argv[0], argv);
		fprintf(stderr, "Restart Failed [%s] resorting to plan b\n", strerror(errno));

		for (j = 0; j < argc; j++) {
			switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[j]);
		}

		ret = system(buf);
	}

	return ret;
}
Exemplo n.º 4
0
cc_status_t cc_agent_update(const char *key, const char *value, const char *agent)
{
	cc_status_t result = CC_STATUS_SUCCESS;
	char *sql;
	char res[256];
	switch_event_t *event;

	/* Check to see if agent already exist */
	sql = switch_mprintf("SELECT count(*) FROM agents WHERE name = '%q'", agent);
	cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
	switch_safe_free(sql);

	if (atoi(res) == 0) {
		result = CC_STATUS_AGENT_NOT_FOUND;
		goto done;
	}

	if (!strcasecmp(key, "status")) {
		if (cc_agent_str2status(value) != CC_AGENT_STATUS_UNKNOWN) {
			/* Reset values on available only */
			if (cc_agent_str2status(value) == CC_AGENT_STATUS_AVAILABLE) {
				sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" SWITCH_TIME_T_FMT "', talk_time = 0, calls_answered = 0, no_answer_count = 0"
						" WHERE name = '%q' AND NOT status = '%q'",
						value, local_epoch_time_now(NULL),
						agent, value);
			} else {
				sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" SWITCH_TIME_T_FMT "' WHERE name = '%q'",
						value, local_epoch_time_now(NULL), agent);
			}
			cc_execute_sql(NULL, sql, NULL);
			switch_safe_free(sql);


			/* Used to stop any active callback */
			if (cc_agent_str2status(value) != CC_AGENT_STATUS_AVAILABLE) {
				sql = switch_mprintf("SELECT uuid FROM members WHERE serving_agent = '%q' AND serving_system = 'single_box' AND NOT state = 'Answered'", agent);
				cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
				switch_safe_free(sql);
				if (!switch_strlen_zero(res)) {
				//	switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL);

					/*hmeng*/
					switch_core_session_hupall_matching_var_ans("cc_member_pre_answer_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL, (switch_hup_type_t) (SHT_UNANSWERED | SHT_ANSWERED));
				}
			}

            // get operator
            sql = switch_mprintf("SELECT name FROM operators WHERE agent = '%q'", agent);
            cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
            switch_safe_free(sql);
            
			result = CC_STATUS_SUCCESS;

			if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Operator", res);     // res --> operator.name
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent);
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-status-change");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Status", value);
				switch_event_fire(&event);
			}

		} else {
			result = CC_STATUS_AGENT_INVALID_STATUS;
			goto done;
		}
	} else if (!strcasecmp(key, "state")) {
		if (cc_agent_str2state(value) != CC_AGENT_STATE_UNKNOWN) {
			if (cc_agent_str2state(value) != CC_AGENT_STATE_RECEIVING) {
				sql = switch_mprintf("UPDATE agents SET state = '%q' WHERE name = '%q'", value, agent);
			} else {
				sql = switch_mprintf("UPDATE agents SET state = '%q', last_offered_call = '%" SWITCH_TIME_T_FMT "' WHERE name = '%q'",
						value, local_epoch_time_now(NULL), agent);
			}
			cc_execute_sql(NULL, sql, NULL);
			switch_safe_free(sql);

			result = CC_STATUS_SUCCESS;

			if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent);
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-state-change");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-State", value);
				switch_event_fire(&event);
			}

		} else {
			result = CC_STATUS_AGENT_INVALID_STATE;
			goto done;
		}
	} else if (!strcasecmp(key, "uuid")) {
		sql = switch_mprintf("UPDATE agents SET uuid = '%q', system = 'single_box' WHERE name = '%q'", value, agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "contact")) {
		sql = switch_mprintf("UPDATE agents SET contact = '%q', system = 'single_box' WHERE name = '%q'", value, agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "ready_time")) {
		sql = switch_mprintf("UPDATE agents SET ready_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "busy_delay_time")) {
		sql = switch_mprintf("UPDATE agents SET busy_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "reject_delay_time")) {
		sql = switch_mprintf("UPDATE agents SET reject_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "no_answer_delay_time")) {
		sql = switch_mprintf("UPDATE agents SET no_answer_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;
	} else if (!strcasecmp(key, "type")) {
		if (strcasecmp(value, CC_AGENT_TYPE_CALLBACK) && strcasecmp(value, CC_AGENT_TYPE_UUID_STANDBY)) {
			result = CC_STATUS_AGENT_INVALID_TYPE;
			goto done;
		}

		sql = switch_mprintf("UPDATE agents SET type = '%q' WHERE name = '%q'", value, agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;

	} else if (!strcasecmp(key, "max_no_answer")) {
		sql = switch_mprintf("UPDATE agents SET max_no_answer = '%d', system = 'single_box' WHERE name = '%q'", atoi(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;

	} else if (!strcasecmp(key, "wrap_up_time")) {
		sql = switch_mprintf("UPDATE agents SET wrap_up_time = '%d', system = 'single_box' WHERE name = '%q'", atoi(value), agent);
		cc_execute_sql(NULL, sql, NULL);
		switch_safe_free(sql);

		result = CC_STATUS_SUCCESS;

	} else {
		result = CC_STATUS_INVALID_KEY;
		goto done;

	}

done:
	if (result == CC_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Updated Agent %s set %s = %s\n", agent, key, value);
	}

	return result;
}
Exemplo n.º 5
0
static switch_status_t fire_cdr_event(switch_channel_t *channel){
	
	switch_status_t status = SWITCH_STATUS_FALSE;
	switch_event_t *event = NULL;

	const char *desc = NULL;
	const char *caller_id_name = NULL;
	const char *caller_id_number = NULL;

	const char *destination_number = NULL;
	const char *dialed_extension = NULL;

	const char *context = NULL;
	const char *context_extension = NULL;

	const char *start_epoch = NULL;
	const char *answer_epoch = NULL;
	const char *end_epoch = NULL;

	const char *start_stamp = NULL;
	const char *answer_stamp = NULL;
	const char *end_stamp = NULL;
	const char *duration = NULL;
	const char *billsec = NULL;
	
	const char *originate_disposition = NULL;
	const char *hangup_cause = NULL;
	const char *uuid = NULL;
	const char *bleg_uuid = NULL;

	const char *read_codec = NULL;
	const char *write_codec = NULL;

	if(!channel){
		return status;
	}
	get_var(desc);
	get_var(caller_id_name);
	get_var(caller_id_number);
	//caller_id_name = switch_channel_get_variable(channel,"caller_id_name");
	//caller_id_number = switch_channel_get_variable(channel,"caller_id_number");
	get_var(destination_number);
	get_var(dialed_extension);
	get_var(context);
	get_var(context_extension);
	get_var(start_epoch);
	get_var(answer_epoch);
	get_var(end_epoch);
	get_var(start_stamp);
	get_var(answer_stamp);
	get_var(end_stamp);
	get_var(duration);
	get_var(billsec);
	get_var(hangup_cause);
	get_var(originate_disposition);
	get_var(uuid);
	get_var(bleg_uuid);
	get_var(read_codec);
	get_var(write_codec);

	
    if(!caller_id_number || !destination_number ||
	   !start_epoch  || !start_stamp || !uuid){
		return status;
	}

	if(switch_event_create_subclass(&event,SWITCH_EVENT_CUSTOM,CDR_EVENT) == SWITCH_STATUS_SUCCESS){
		event_add_header(caller_id_number);
		if(desc){
			caller_id_name = desc;
		}
		//if(!caller_id_name){
		//caller_id_name = caller_id_number;
		//}
		if(caller_id_name){
			event_add_header(caller_id_name);
		}

		event_add_header(destination_number);
		if(dialed_extension && strstr(dialed_extension,"$1") == NULL){
			event_add_header(dialed_extension);//dialed_extension = destination_number;
		}
		
		if(context){
			event_add_header(context);
		}
		if(context_extension){
			event_add_header(context_extension);
		}
		event_add_header(start_epoch);
		if(switch_strlen_zero(end_epoch)){
			end_epoch = start_epoch;
		}
		event_add_header(end_epoch);

		if(switch_strlen_zero(answer_epoch)){
			answer_epoch = end_epoch;
		}
		event_add_header(answer_epoch);

		
		event_add_header(start_stamp);

		if(switch_strlen_zero(end_stamp)){
			end_stamp = start_stamp;
		}
		event_add_header(end_stamp);

		if(switch_strlen_zero(answer_stamp)){
			answer_stamp = end_stamp;
		}
		event_add_header(answer_stamp);
		
		if(switch_strlen_zero(duration)){
			duration = "0";
		}
		event_add_header(duration);
		if(switch_strlen_zero(billsec)){
			billsec = "0";
		}
		event_add_header(billsec);
		//if(originate_disposition){
		//event_add_header(originate_disposition);
		//}

		if(originate_disposition){

			if(hangup_cause){
				switch_call_cause_t originate = switch_channel_str2cause(originate_disposition);
				switch_call_cause_t hangup = switch_channel_str2cause(hangup_cause);
				if((hangup == SWITCH_CAUSE_NORMAL_CLEARING || hangup == SWITCH_CAUSE_NONE)
				   && (originate != SWITCH_CAUSE_NORMAL_CLEARING)
				   && (originate != SWITCH_CAUSE_NONE)){
					hangup_cause = originate_disposition;
				}
			}
			else{
				hangup_cause = originate_disposition;
			}
		}
		if(!hangup_cause){
			hangup_cause = "NONE";
		}

		if(hangup_cause){
			event_add_header(hangup_cause);
		}

		event_add_header(uuid);
		if(bleg_uuid){
			event_add_header(bleg_uuid);
		}
		if(read_codec){
			event_add_header(read_codec);
		}
		if(write_codec){
			event_add_header(write_codec);
		}
    
		status = switch_event_fire(&event);
		//switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_DEBUG,"fire cdr event for %s\n",caller_id_number); 
	}

	return status;
}