Exemplo n.º 1
0
static struct ast_variable *realtime_pgsql(const char *database, const char *table, va_list ap)
{
	PGresult *result = NULL;
	int num_rows = 0, pgerror;
	char sql[256], escapebuf[513];
	char *stringp;
	char *chunk;
	char *op;
	const char *newparam, *newval;
	struct ast_variable *var = NULL, *prev = NULL;

	if (!table) {
		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
		return NULL;
	}

	/* Get the first parameter and first value in our list of passed paramater/value pairs */
	newparam = va_arg(ap, const char *);
	newval = va_arg(ap, const char *);
	if (!newparam || !newval) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
		if (pgsqlConn) {
			PQfinish(pgsqlConn);
			pgsqlConn = NULL;
		};
		return NULL;
	}

	/* Create the first part of the query using the first parameter/value pairs we just extracted
	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
	op = strchr(newparam, ' ') ? "" : " =";

	PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
	if (pgerror) {
		ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
		va_end(ap);
		return NULL;
	}

	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op,
			 escapebuf);
	while ((newparam = va_arg(ap, const char *))) {
		newval = va_arg(ap, const char *);
		if (!strchr(newparam, ' '))
			op = " =";
		else
			op = "";

		PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
		if (pgerror) {
			ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
			va_end(ap);
			return NULL;
		}

		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam,
				 op, escapebuf);
	}
	va_end(ap);

	/* We now have our complete statement; Lets connect to the server and execute it. */
	ast_mutex_lock(&pgsql_lock);
	if (!pgsql_reconnect(database)) {
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	}

	if (!(result = PQexec(pgsqlConn, sql))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
				PQerrorMessage(pgsqlConn));
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	} else {
		ExecStatusType result_status = PQresultStatus(result);
		if (result_status != PGRES_COMMAND_OK
			&& result_status != PGRES_TUPLES_OK
			&& result_status != PGRES_NONFATAL_ERROR) {
			ast_log(LOG_WARNING,
					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
					PQresultErrorMessage(result), PQresStatus(result_status));
			ast_mutex_unlock(&pgsql_lock);
			return NULL;
		}
	}

	ast_log(LOG_DEBUG, "1Postgresql RealTime: Result=%p Query: %s\n", result, sql);

	if ((num_rows = PQntuples(result)) > 0) {
		int i = 0;
		int rowIndex = 0;
		int numFields = PQnfields(result);
		char **fieldnames = NULL;

		ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows);

		if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
			ast_mutex_unlock(&pgsql_lock);
			PQclear(result);
			return NULL;
		}
		for (i = 0; i < numFields; i++)
			fieldnames[i] = PQfname(result, i);
		for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
			for (i = 0; i < numFields; i++) {
				stringp = PQgetvalue(result, rowIndex, i);
				while (stringp) {
					chunk = strsep(&stringp, ";");
					if (chunk && !ast_strlen_zero(ast_strip(chunk))) {
						if (prev) {
							prev->next = ast_variable_new(fieldnames[i], chunk);
							if (prev->next) {
								prev = prev->next;
							}
						} else {
							prev = var = ast_variable_new(fieldnames[i], chunk);
						}
					}
				}
			}
		}
		ast_free(fieldnames);
	} else {
		ast_log(LOG_DEBUG, "Postgresql RealTime: Could not find any rows in table %s.\n", table);
	}

	ast_mutex_unlock(&pgsql_lock);
	PQclear(result);

	return var;
}
Exemplo n.º 2
0
static int sqlite_log(struct ast_cdr *cdr)
{
	int res = 0;
	char *zErr = 0;
	char startstr[80], answerstr[80], endstr[80];
	int count;
#if LOG_HRTIME
	double hrbillsec = 0.0;
	double hrduration;
#endif

	ast_mutex_lock(&sqlite_lock);

	format_date(startstr, sizeof(startstr), &cdr->start);
	format_date(answerstr, sizeof(answerstr), &cdr->answer);
	format_date(endstr, sizeof(endstr), &cdr->end);

#if LOG_HRTIME
	if (!ast_tvzero(cdr->answer)) {
		hrbillsec = (double) ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0;
	}
	hrduration = (double) ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0;
#endif

	for(count=0; count<5; count++) {
		res = sqlite_exec_printf(db,
			"INSERT INTO cdr ("
				"clid,src,dst,dcontext,"
				"channel,dstchannel,lastapp,lastdata, "
				"start,answer,end,"
				"duration,billsec,disposition,amaflags, "
				"accountcode"
#				if LOG_UNIQUEID
				",uniqueid"
#				endif
#				if LOG_USERFIELD
				",userfield"
#				endif
			") VALUES ("
				"'%q', '%q', '%q', '%q', "
				"'%q', '%q', '%q', '%q', "
				"'%q', '%q', '%q', "
#if LOG_HRTIME
				"%f, %f, %d, %d, "
#else
				"%d, %d, %d, %d, "
#endif
				"'%q'"
#				if LOG_UNIQUEID
				",'%q'"
#				endif
#				if LOG_USERFIELD
				",'%q'"
#				endif
			")", NULL, NULL, &zErr,
				cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
				cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
				startstr, answerstr, endstr,
#if LOG_HRTIME
				hrduration, hrbillsec, cdr->disposition, cdr->amaflags,
#else
				cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
#endif
				cdr->accountcode
#				if LOG_UNIQUEID
				,cdr->uniqueid
#				endif
#				if LOG_USERFIELD
				,cdr->userfield
#				endif
			);
		if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
			break;
		usleep(200);
	}

	if (zErr) {
		ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
		ast_free(zErr);
	}

	ast_mutex_unlock(&sqlite_lock);
	return res;
}
Exemplo n.º 3
0
static int load_config(void)
{
	/* int res; */
	struct ast_config *cfg;
	struct ast_variable *var;
	const char *tmp;
	struct ast_flags config_flags = { 0 };

	cfg = ast_config_load(CBMYSQL_CONFIG, config_flags);
	if (!cfg) {
		ast_log(LOG_WARNING, "Unable to load config for CBMySQL: %s\n", CBMYSQL_CONFIG);
		return 0;
	}
	
	var = ast_variable_browse(cfg, "global");
	if (!var) {
		return 0;
	}

	tmp = ast_variable_retrieve(cfg,"global","hostname");
	if (tmp) {
		hostname = malloc(strlen(tmp) + 1);
		if (hostname != NULL) {
			hostname_alloc = 1;
			strcpy(hostname,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		hostname = malloc(strlen("localhost") + 1);
		if (hostname != NULL) {
			ast_log(LOG_WARNING,"MySQL server hostname not specified.  Assuming localhost\n");
			hostname_alloc = 1;
			strcpy(hostname,"localhost");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","dbname");
	if (tmp) {
		dbname = malloc(strlen(tmp) + 1);
		if (dbname != NULL) {
			dbname_alloc = 1;
			strcpy(dbname,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		dbname = malloc(strlen("meetme") + 1);
		if (dbname != NULL) {
			ast_log(LOG_WARNING,"MySQL database not specified.  Assuming meetme\n");
			dbname_alloc = 1;
			strcpy(dbname,"meetme");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}
	tmp = ast_variable_retrieve(cfg,"global","table");
	if (tmp) {
		table = malloc(strlen(tmp) + 1);
		if (table != NULL) {
			table_alloc = 1;
			strcpy(table,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		table = malloc(strlen("booking") + 1);
		if (table != NULL) {
			ast_log(LOG_WARNING,"MySQL table not specified.  Assuming booking\n");
			table_alloc = 1;
			strcpy(table,"booking");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}



	tmp = ast_variable_retrieve(cfg,"global","user");
	if (tmp) {
		dbuser = malloc(strlen(tmp) + 1);
		if (dbuser != NULL) {
			dbuser_alloc = 1;
			strcpy(dbuser,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		dbuser = malloc(strlen("root") + 1);
		if (dbuser != NULL) {
			ast_log(LOG_WARNING,"MySQL database user not specified.  Assuming root\n");
			strcpy(password,"root");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","sock");
	if (tmp) {
		dbsock = malloc(strlen(tmp) + 1);
		if (dbsock != NULL) {
			dbsock_alloc = 1;
			strcpy(dbsock,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		ast_log(LOG_WARNING,"MySQL database sock file not specified.  Using default\n");
		dbsock = NULL;
	}

	tmp = ast_variable_retrieve(cfg,"global","password");
	if (tmp) {
		password = malloc(strlen(tmp) + 1);
		if (password != NULL) {
			password_alloc = 1;
			strcpy(password,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
		password = malloc(strlen("") + 1);
		if (password != NULL) {
			ast_log(LOG_WARNING,"MySQL database password not specified.  Assuming blank\n");
			password_alloc = 1;
			strcpy(password,"");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","port");
	if (tmp) {
		if (sscanf(tmp,"%d",&dbport) < 1) {
			ast_log(LOG_WARNING,"Invalid MySQL port number.  Using default\n");
			dbport = 0;
		}
	}

        tmp = ast_variable_retrieve(cfg,"global","DBOpts");
        if (tmp) {
		DBOpts = ast_true(tmp);
	}

	if (!DBOpts){
	   tmp = ast_variable_retrieve(cfg,"global","OptsAdm");
	   if (tmp) {
		OptsAdm = malloc(strlen(tmp) + 1);
                if (OptsAdm != NULL) {
                        strcpy(OptsAdm,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	    } else {
		ast_log(LOG_WARNING,"Invalid Conference Admin options.  Using default\n");
	    }

      	   tmp = ast_variable_retrieve(cfg,"global","OptsUsr");
	   if (tmp) {
                   OptsUsr = malloc(strlen(tmp) + 1);
                   if (OptsUsr != NULL) {
                           strcpy(OptsUsr,tmp);
		   } else {
		      	   ast_log(LOG_ERROR,"Out of memory error.\n");
			   return -1;
		   }
	    } else {
		ast_log(LOG_WARNING,"Invalid Conference User options.  Using default\n");
	    }
}

	tmp = ast_variable_retrieve(cfg,"global","ConfApp");
	if (tmp) {
                ConfApp = malloc(strlen(tmp) + 1);
                if (ConfApp != NULL) {
                        strcpy(ConfApp,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
                ConfApp = malloc(strlen("MeetMe") + 1);
                if (ConfApp!= NULL) {
			ast_log(LOG_WARNING,"No Conference application.  Using MeetMe\n");
			strcpy(ConfApp, "MeetMe");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","ConfAppCount");
	if (tmp) {
                ConfAppCount = malloc(strlen(tmp) + 1);
                if (ConfAppCount!= NULL) {
                        strcpy(ConfAppCount,tmp);
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	} else {
                ConfAppCount = malloc(strlen("MeetMeCount") + 1);
                if (ConfAppCount!= NULL) {
			ast_log(LOG_WARNING,"No Conference count application.  Using MeetMe\n");
			strcpy(ConfAppCount, "MeetMeCount");
		} else {
			ast_log(LOG_ERROR,"Out of memory error.\n");
			return -1;
		}
	}

        tmp = ast_variable_retrieve(cfg,"global","earlyalert");
        if (tmp) {
                if (sscanf(tmp,"%d",&earlyalert) < 1) 
                        ast_log(LOG_WARNING,"Invalid Early Alert time.\n");
        }

        tmp = ast_variable_retrieve(cfg,"global","fuzzystart");
        if (tmp) {
                if (sscanf(tmp,"%d",&fuzzystart) < 1) 
                        ast_log(LOG_WARNING,"Invalid Fuzzy Start time.\n");
        }


	ast_config_destroy(cfg);

	if (option_debug > 3){
		ast_log(LOG_DEBUG,"CBMySQL: got hostname of %s\n",hostname);
		ast_log(LOG_DEBUG,"CBMySQL: got port of %d\n",dbport);
		if (dbsock)
			ast_log(LOG_DEBUG,"CBMySQL: got sock file of %s\n",dbsock);
		ast_log(LOG_DEBUG,"CBMySQL: got user of %s\n",dbuser);
		ast_log(LOG_DEBUG,"CBMySQL: got dbname of %s\n",dbname);
		ast_log(LOG_DEBUG,"CBMySQL: got password of %s\n",password);
		if (DBOpts) {
		     	ast_log(LOG_DEBUG,"CBMySQL: Using Database  for Admin & User Options\n ");
		} else {
	     		ast_log(LOG_DEBUG,"CBMySQL: got Admin Options of %s\n",OptsAdm);
	     		ast_log(LOG_DEBUG,"CBMySQL: got User Options of %s\n",OptsUsr);
		}
		ast_log(LOG_DEBUG,"CBMySQL: got Connference Application of %s\n",ConfApp);
		ast_log(LOG_DEBUG,"CBMySQL: got Conference Count Application of %s\n",ConfAppCount);
		if (earlyalert)
			ast_log(LOG_DEBUG, "CBMySQL: Early Alert set to %i seconds.\n", earlyalert);
		if (fuzzystart)
			ast_log(LOG_DEBUG, "CBMySQL: Fuzzy Start set to %i seconds.\n", fuzzystart);
	}

	ast_mutex_lock(&handle.lock);
	mysql_init(&handle.mysql);

	if (!mysql_real_connect(&handle.mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) {
		ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", dbname, hostname);
		connected = 0;
		records = 0;
	} else {
		ast_log(LOG_NOTICE,"Successfully connected to MySQL database.\n");
		connected = 1;
		records = 0;
		connect_time = time(NULL);
	}
	ast_mutex_unlock(&handle.lock);
	if (connected)
		return 1;
	else
		return 0;
}
Exemplo n.º 4
0
/* ENUM lookup */
int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char* suffix, char* options, unsigned int record, struct enum_context **argcontext)
{
	struct enum_context *context;
	char tmp[512];
	char domain[256];
	char left[128];
	char middle[128];
	char naptrinput[128];
	char apex[128] = "";
	int ret = -1;
	/* for ISN rewrite */
	char *p1 = NULL;
	char *p2 = NULL;
	char *p3 = NULL;
	int k = 0;
	int i = 0;
	int z = 0;
	int spaceleft = 0;
	struct timeval time_start, time_end;

	if (ast_strlen_zero(suffix)) {
		ast_log(LOG_WARNING, "ast_get_enum need a suffix parameter now.\n");
		return -1;
	}

	ast_debug(2, "num='%s', tech='%s', suffix='%s', options='%s', record=%u\n", number, tech, suffix, options, record);

/*
  We don't need that any more, that "n" preceding the number has been replaced by a flag
  in the options paramter.
	ast_copy_string(naptrinput, number, sizeof(naptrinput));
*/
/*
 * The "number" parameter includes a leading '+' if it's a full E.164 number (and not ISN)
 * We need to preserve that as the regex inside NAPTRs expect the +.
 *
 * But for the domain generation, the '+' is a nuissance, so we get rid of it.
*/
	ast_copy_string(naptrinput, number[0] == 'n' ? number + 1 : number, sizeof(naptrinput));
	if (number[0] == '+') {
		number++;
	}

	if (!(context = ast_calloc(1, sizeof(*context)))) {
		return -1;
	}

	if ((p3 = strchr(naptrinput, '*'))) {
		*p3='\0';
	}

	context->naptrinput = naptrinput;	/* The number */
	context->dst = dst;			/* Return string */
	context->dstlen = dstlen;
	context->tech = tech;
	context->techlen = techlen;
	context->options = 0;
	context->position = record > 0 ? record : 1;
	context->count = 0;
	context->naptr_rrs = NULL;
	context->naptr_rrs_count = 0;

	/*
	 * Process options:
	 *
	 *	c	Return count, not URI
	 *	i	Use infrastructure ENUM
	 *	s	Do ISN transformation
	 *	d	Direct DNS query: no reversing.
	 *
	 */
	if (options != NULL) {
		if (strchr(options,'s')) {
			context->options |= ENUMLOOKUP_OPTIONS_ISN;
		} else if (strchr(options,'i')) {
			context->options |= ENUMLOOKUP_OPTIONS_IENUM;
		} else if (strchr(options,'d')) {
			context->options |= ENUMLOOKUP_OPTIONS_DIRECT;
		}
		if (strchr(options,'c')) {
			context->options |= ENUMLOOKUP_OPTIONS_COUNT;
		}
		if (strchr(number,'*')) {
			context->options |= ENUMLOOKUP_OPTIONS_ISN;
		}
	}
	ast_debug(2, "ENUM options(%s): pos=%d, options='%d'\n", options, context->position, context->options);
	ast_debug(1, "n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
			number, tech, suffix, context->options, context->position);

	/*
	 * This code does more than simple RFC3261 ENUM. All these rewriting
	 * schemes have in common that they build the FQDN for the NAPTR lookup
	 * by concatenating
	 *    - a number which needs be flipped and "."-seperated 	(left)
	 *    - some fixed string					(middle)
	 *    - an Apex.						(apex)
	 *
	 * The RFC3261 ENUM is: left=full number, middle="", apex=from args.
	 * ISN:  number = "middle*left", apex=from args
	 * I-ENUM: EBL parameters build the split, can change apex
	 * Direct: left="", middle=argument, apex=from args
	 *
	 */

	/* default: the whole number will be flipped, no middle domain component */
	ast_copy_string(left, number, sizeof(left));
	middle[0] = '\0';
	/*
	 * I-ENUM can change the apex, thus we copy it
	 */
	ast_copy_string(apex, suffix, sizeof(apex));
	/* ISN rewrite */
	if ((context->options & ENUMLOOKUP_OPTIONS_ISN) && (p1 = strchr(number, '*'))) {
		*p1++ = '\0';
		ast_copy_string(left, number, sizeof(left));
		ast_copy_string(middle, p1, sizeof(middle) - 1);
		strcat(middle, ".");
		ast_debug(2, "ISN ENUM: left=%s, middle='%s'\n", left, middle);
	/* Direct DNS lookup rewrite */
	} else if (context->options & ENUMLOOKUP_OPTIONS_DIRECT) {
		left[0] = 0; /* nothing to flip around */
		ast_copy_string(middle, number, sizeof(middle) - 1);
		strcat(middle, ".");
		ast_debug(2, "DIRECT ENUM:  middle='%s'\n", middle);
	/* Infrastructure ENUM rewrite */
	} else if (context->options & ENUMLOOKUP_OPTIONS_IENUM) {
		int sdl = 0;
		char cc[8];
		char sep[256], n_apex[256];
		int cc_len = cclen(number);
		sdl = cc_len;
		ast_mutex_lock(&enumlock);
		ast_copy_string(sep, ienum_branchlabel, sizeof(sep)); /* default */
		ast_mutex_unlock(&enumlock);

		switch (ebl_alg) {
		case ENUMLOOKUP_BLR_EBL:
			ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
			sdl = blr_ebl(cc, suffix, sep, sizeof(sep) - 1, n_apex, sizeof(n_apex) - 1);

			if (sdl >= 0) {
				ast_copy_string(apex, n_apex, sizeof(apex));
				ast_debug(2, "EBL ENUM: sep=%s, apex='%s'\n", sep, n_apex);
			} else {
				sdl = cc_len;
			}
			break;
		case ENUMLOOKUP_BLR_TXT:
			ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
			sdl = blr_txt(cc, suffix);

			if (sdl < 0) {
				sdl = cc_len;
			}
			break;

		case ENUMLOOKUP_BLR_CC:	/* BLR is at the country-code level */
		default:
			sdl = cc_len;
			break;
		}

		if (sdl > strlen(number)) {	/* Number too short for this sdl? */
			ast_log(LOG_WARNING, "I-ENUM: subdomain location %d behind number %s\n", sdl, number);
			ast_free(context);
			return 0;
		}
		ast_copy_string(left, number + sdl, sizeof(left));

		ast_mutex_lock(&enumlock);
		ast_copy_string(middle, sep, sizeof(middle) - 1);
		strcat(middle, ".");
		ast_mutex_unlock(&enumlock);

		/* check the space we need for middle */
		if ((sdl * 2 + strlen(middle) + 2) > sizeof(middle)) {
			ast_log(LOG_WARNING, "ast_get_enum: not enough space for I-ENUM rewrite.\n");
			ast_free(context);
			return -1;
		}

		p1 = middle + strlen(middle);
		for (p2 = (char *) number + sdl - 1; p2 >= number; p2--) {
			if (isdigit(*p2)) {
				*p1++ = *p2;
				*p1++ = '.';
			}
		}
		*p1 = '\0';

		ast_debug(2, "I-ENUM: cclen=%d, left=%s, middle='%s', apex='%s'\n", cc_len, left, middle, apex);
	}

	if (strlen(left) * 2 + 2 > sizeof(domain)) {
		ast_log(LOG_WARNING, "string to long in ast_get_enum\n");
		ast_free(context);
		return -1;
	}

	/* flip left into domain */
	p1 = domain;
	for (p2 = left + strlen(left); p2 >= left; p2--) {
		if (isdigit(*p2)) {
			*p1++ = *p2;
			*p1++ = '.';
		}
	}
	*p1 = '\0';

	if (chan && ast_autoservice_start(chan) < 0) {
		ast_free(context);
		return -1;
	}

	spaceleft = sizeof(tmp) - 2;
	ast_copy_string(tmp, domain, spaceleft);
	spaceleft -= strlen(domain);

	if (*middle) {
		strncat(tmp, middle, spaceleft);
		spaceleft -= strlen(middle);
	}

	strncat(tmp,apex,spaceleft);
	time_start = ast_tvnow();
	ret = ast_search_dns(context, tmp, C_IN, T_NAPTR, enum_callback);
	time_end = ast_tvnow();

	ast_debug(2, "profiling: %s, %s, %" PRIi64 " ms\n",
			(ret == 0) ? "OK" : "FAIL", tmp, ast_tvdiff_ms(time_end, time_start));

	if (ret < 0) {
		ast_debug(1, "No such number found: %s (%s)\n", tmp, strerror(errno));
		context->naptr_rrs_count = -1;
		strcpy(dst, "0");
		ret = 0;
	}

	if (context->naptr_rrs_count >= context->position && ! (context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
		/* sort array by NAPTR order/preference */
		for (k = 0; k < context->naptr_rrs_count; k++) {
			for (i = 0; i < context->naptr_rrs_count; i++) {
				/* use order first and then preference to compare */
				if ((ntohs(context->naptr_rrs[k].naptr.order) < ntohs(context->naptr_rrs[i].naptr.order)
				     && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
				     || (ntohs(context->naptr_rrs[k].naptr.order) > ntohs(context->naptr_rrs[i].naptr.order)
				     && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
					z = context->naptr_rrs[k].sort_pos;
					context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
					context->naptr_rrs[i].sort_pos = z;
					continue;
				}
				if (ntohs(context->naptr_rrs[k].naptr.order) == ntohs(context->naptr_rrs[i].naptr.order)) {
					if ((ntohs(context->naptr_rrs[k].naptr.pref) < ntohs(context->naptr_rrs[i].naptr.pref)
					     && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
					     || (ntohs(context->naptr_rrs[k].naptr.pref) > ntohs(context->naptr_rrs[i].naptr.pref)
					     && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
						z = context->naptr_rrs[k].sort_pos;
						context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
						context->naptr_rrs[i].sort_pos = z;
					}
				}
			}
		}
		for (k = 0; k < context->naptr_rrs_count; k++) {
			if (context->naptr_rrs[k].sort_pos == context->position - 1) {
				ast_copy_string(context->dst, context->naptr_rrs[k].result, dstlen);
				ast_copy_string(context->tech, context->naptr_rrs[k].tech, techlen);
				break;
			}
		}
	} else if (!(context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
		context->dst[0] = 0;
	} else if ((context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
		snprintf(context->dst, context->dstlen, "%d", context->naptr_rrs_count + context->count);
	}

	if (chan) {
		ret |= ast_autoservice_stop(chan);
	}

	if (!argcontext) {
		for (k = 0; k < context->naptr_rrs_count; k++) {
			ast_free(context->naptr_rrs[k].result);
			ast_free(context->naptr_rrs[k].tech);
		}
		ast_free(context->naptr_rrs);
		ast_free(context);
	} else {
		*argcontext = context;
	}

	return ret;
}
Exemplo n.º 5
0
/* Needs to be called with d->lock */
sccp_channel_t *
sccp_dev_allocate_channel(sccp_device_t * d, sccp_line_t * l, int outgoing, char * dial)
{
  sccp_channel_t * c = NULL;
  struct ast_channel * tmp = NULL;
  pthread_t t;
  int callId;

  if (!d->session) {
    ast_log(LOG_ERROR, "Tried to open channel on device without a session\n");
    return NULL;
  }

  // If there is no current line, then we can't make a call in, or out.
  if (!d->currentLine) {
    ast_log(LOG_ERROR, "Tried to open channel on a device with no selected line\n");
    return NULL;
  }

  if (l == NULL)
    l = d->currentLine;

  ast_mutex_lock(&callCountLock);
  callId = callCount++;
  ast_mutex_unlock(&callCountLock);

  c = malloc(sizeof(sccp_channel_t));
  memset(c, 0, sizeof(sccp_channel_t));
  c->callid = callId;
  c->line = l;

  ast_mutex_lock(&l->lock);
  l->channelCount++;
  ast_mutex_unlock(&l->lock);

  ast_log(LOG_DEBUG, "After: #Channel ->lnext = %p, c = %p, channels = %p\n", c->lnext, c, chans);
  tmp = sccp_new_channel(c, AST_STATE_OFFHOOK);
  ast_log(LOG_DEBUG, "New channel name is: %s\n", tmp->name);
  ast_log(LOG_DEBUG, "After: #Channel ->lnext = %p, c = %p, channels = %p\n", c->lnext, c, chans);

  ast_mutex_lock(&chanlock);
    c->lnext = chans;
    chans = c;
  ast_mutex_unlock(&chanlock);

  c->owner = tmp;

  c->next = l->channels;
  l->channels = c;
  l->activeChannel = c;

  if (outgoing) {

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    c->isOutgoing = 1;
    d->active_channel = c;

    ast_log(LOG_DEBUG, "After: #Channel ->lnext = %p, c = %p, channels = %p\n", c->lnext, c, chans);

    sccp_dev_set_speaker(d, StationSpeakerOn);
    sccp_channel_set_callstate(c, TsOffHook);
    sccp_dev_statusprompt_set(d, c, NULL, 0);
    sccp_dev_set_keyset(d, c, KEYMODE_OFFHOOK);
    sccp_dev_set_sptone(d, "InsideDialTone");

    if (dial) {

      strncpy(tmp->exten, dial, AST_MAX_EXTENSION);
      if (ast_pbx_start(tmp)) {
        ast_log(LOG_WARNING, "PBX exited non-zero\n");
        sccp_dev_statusprompt_set(l->device, c, "PBX Error", 10);
        sccp_dev_set_sptone(l->device, "ReorderTone");
        ast_indicate(tmp, AST_CONTROL_CONGESTION);
      }

  ast_log(LOG_DEBUG, "After: #Channel ->lnext = %p, c = %p, channels = %p\n", c->lnext, c, chans);

    } else if (pthread_create(&t, &attr, sccp_start_channel, tmp)) {
      ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
      ast_hangup(tmp);
      free(c);
      return NULL;
    }

  } else {

    // It's an incoming call.

  }

  ast_log(LOG_DEBUG, "After: #Channel ->lnext = %p, c = %p, chans = %p\n", c->lnext, c, chans);

  return c;
}
Exemplo n.º 6
0
static void lock_it(ast_mutex_t *lock)
{
    indicator = 1;
    ast_mutex_lock(lock);
}
Exemplo n.º 7
0
/*
 * Helper thread to periodically poll the video sources and enqueue the
 * generated frames directed to the remote party to the channel's queue.
 * Using a separate thread also helps because the encoding can be
 * computationally expensive so we don't want to starve the main thread.
 */
static void *video_thread(void *arg)
{
	struct video_desc *env = arg;
	int count = 0;
	char save_display[128] = "";
	int i; /* integer variable used as iterator */

	/* if sdl_videodriver is set, override the environment. Also,
	 * if it contains 'console' override DISPLAY around the call to SDL_Init
	 * so we use the console as opposed to the x11 version of aalib
	 */
	if (!ast_strlen_zero(env->sdl_videodriver)) { /* override */
		const char *s = getenv("DISPLAY");
		setenv("SDL_VIDEODRIVER", env->sdl_videodriver, 1);
		if (s && !strcasecmp(env->sdl_videodriver, "aalib-console")) {
			ast_copy_string(save_display, s, sizeof(save_display));
			unsetenv("DISPLAY");
		}
	}
	sdl_setup(env);
	if (!ast_strlen_zero(save_display)) {
		setenv("DISPLAY", save_display, 1);
	}

	ast_mutex_init(&env->dec_lock);	/* used to sync decoder and renderer */

	if (grabber_open(&env->out)) {
		ast_log(LOG_WARNING, "cannot open local video source\n");
	}

	if (env->out.device_num) {
		env->out.devices[env->out.device_primary].status_index |= IS_PRIMARY | IS_SECONDARY;
	}

	/* even if no device is connected, we must call video_out_init,
	 * as some of the data structures it initializes are
	 * used in get_video_frames()
	 */
	video_out_init(env);

	/* Writes intial status of the sources. */
	if (env->gui) {
		for (i = 0; i < env->out.device_num; i++) {
			print_message(env->gui->thumb_bd_array[i].board,
				src_msgs[env->out.devices[i].status_index]);
		}
	}

	for (;;) {
		struct timespec t = { 0, 50000000 };	/* XXX 20 times/sec */
		struct ast_frame *p, *f;
		struct ast_channel *chan;
		int fd;
		char *caption = NULL, buf[160];

		/* determine if video format changed */
		if (count++ % 10 == 0) {
			if (env->out.sendvideo && env->out.devices) {
				snprintf(buf, sizeof(buf), "%s %s %dx%d @@ %dfps %dkbps",
				env->out.devices[env->out.device_primary].name, env->codec_name,
				env->enc_in.w, env->enc_in.h,
				env->out.fps, env->out.bitrate / 1000);
			} else {
				sprintf(buf, "hold");
			}
			caption = buf;
		}

		/* manage keypad events */
		/* XXX here we should always check for events,
		* otherwise the drag will not work */ 
		if (env->gui)
			eventhandler(env, caption);

		/* sleep for a while */
		nanosleep(&t, NULL);

	    if (env->in) {
			struct video_dec_desc *v = env->in;

			/*
			 * While there is something to display, call the decoder and free
			 * the buffer, possibly enabling the receiver to store new data.
			 */
			while (v->dec_in_dpy) {
				struct fbuf_t *tmp = v->dec_in_dpy;	/* store current pointer */

				/* decode the frame, but show it only if not frozen */
				if (v->d_callbacks->dec_run(v, tmp) && !env->frame_freeze)
					show_frame(env, WIN_REMOTE);
				tmp->used = 0;	/* mark buffer as free */
				tmp->ebit = 0;
				ast_mutex_lock(&env->dec_lock);
				if (++v->dec_in_dpy == &v->dec_in[N_DEC_IN])	/* advance to next, circular */
					v->dec_in_dpy = &v->dec_in[0];

				if (v->dec_in_cur == NULL)	/* receiver was idle, enable it... */
					v->dec_in_cur = tmp;	/* using the slot just freed */
				else if (v->dec_in_dpy == v->dec_in_cur) /* this was the last slot */
					v->dec_in_dpy = NULL;	/* nothing more to display */
				ast_mutex_unlock(&env->dec_lock);
			}
		}

		if (env->shutdown)
			break;
		f = get_video_frames(env, &p);	/* read and display */
		if (!f)
			continue;
		chan = env->owner;
		if (chan == NULL) {
			/* drop the chain of frames, nobody uses them */
			while (f) {
				struct ast_frame *g = AST_LIST_NEXT(f, frame_list);
				ast_frfree(f);
				f = g;
			}
			continue;
		}
		fd = chan->alertpipe[1];
		ast_channel_lock(chan);

		/* AST_LIST_INSERT_TAIL is only good for one frame, cannot use here */
		if (chan->readq.first == NULL) {
			chan->readq.first = f;
		} else {
			chan->readq.last->frame_list.next = f;
		}
		chan->readq.last = p;
		/*
		 * more or less same as ast_queue_frame, but extra
		 * write on the alertpipe to signal frames.
		 */
		if (fd > -1) {
			int blah = 1, l = sizeof(blah);
			for (p = f; p; p = AST_LIST_NEXT(p, frame_list)) {
				if (write(fd, &blah, l) != l)
					ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d: %s!\n",
						chan->name, f->frametype, f->subclass, strerror(errno));
			}
		}
		ast_channel_unlock(chan);
	}
	/* thread terminating, here could call the uninit */
	/* uninitialize the local and remote video environments */
	env->in = dec_uninit(env->in);
	video_out_uninit(env);

	if (env->gui)
		env->gui = cleanup_sdl(env->gui, env->out.device_num);
	ast_mutex_destroy(&env->dec_lock);
	env->shutdown = 0;
	return NULL;
}
Exemplo n.º 8
0
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
{
	char *argv[AST_MAX_ARGS];
	struct ast_cli_entry *e, *e1, *e2;
	int x;
	int matchnum=0;
	char *dup, *res;
	char fullcmd1[80] = "";
	char fullcmd2[80] = "";
	char matchstr[80];
	char *fullcmd = NULL;

	if ((dup = parse_args(text, &x, argv))) {
		join(matchstr, sizeof(matchstr), argv);
		if (lock)
			ast_mutex_lock(&clilock);
		e1 = builtins;
		e2 = helpers;
		while(e1->cmda[0] || e2) {
			if (e2)
				join(fullcmd2, sizeof(fullcmd2), e2->cmda);
			if (e1->cmda[0])
				join(fullcmd1, sizeof(fullcmd1), e1->cmda);
			if (!e1->cmda[0] || 
					(e2 && (strcmp(fullcmd2, fullcmd1) < 0))) {
				/* Use e2 */
				e = e2;
				fullcmd = fullcmd2;
				/* Increment by going to next */
				e2 = e2->next;
			} else {
				/* Use e1 */
				e = e1;
				fullcmd = fullcmd1;
				e1++;
			}
			if ((fullcmd[0] != '_') && !strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
				/* We contain the first part of one or more commands */
				matchnum++;
				if (matchnum > state) {
					/* Now, what we're supposed to return is the next word... */
					if (!ast_strlen_zero(word) && x>0) {
						res = e->cmda[x-1];
					} else {
						res = e->cmda[x];
					}
					if (res) {
						if (lock)
							ast_mutex_unlock(&clilock);
						free(dup);
						return res ? strdup(res) : NULL;
					}
				}
			}
			if (e->generator && !strncasecmp(matchstr, fullcmd, strlen(fullcmd))) {
				/* We have a command in its entirity within us -- theoretically only one
				   command can have this occur */
				fullcmd = e->generator(matchstr, word, (!ast_strlen_zero(word) ? (x - 1) : (x)), state);
				if (lock)
					ast_mutex_unlock(&clilock);
				free(dup);
				return fullcmd;
			}
			
		}
		if (lock)
			ast_mutex_unlock(&clilock);
		free(dup);
	}
	return NULL;
}
Exemplo n.º 9
0
static void *mixmonitor_thread(void *obj) 
{
	struct mixmonitor *mixmonitor = obj;
	struct ast_filestream **fs = NULL;
	unsigned int oflags;
	char *ext;
	int errflag = 0;

	ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);

	fs = &mixmonitor->mixmonitor_ds->fs;

	/* The audiohook must enter and exit the loop locked */
	ast_audiohook_lock(&mixmonitor->audiohook);
	while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
		struct ast_frame *fr = NULL;

		ast_audiohook_trigger_wait(&mixmonitor->audiohook);

		if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING)
			break;

		if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR)))
			continue;

		/* audiohook lock is not required for the next block.
		 * Unlock it, but remember to lock it before looping or exiting */
		ast_audiohook_unlock(&mixmonitor->audiohook);

		ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
		if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || (mixmonitor->mixmonitor_ds->chan && ast_bridged_channel(mixmonitor->mixmonitor_ds->chan))) {
			/* Initialize the file if not already done so */
			if (!*fs && !errflag && !mixmonitor->mixmonitor_ds->fs_quit) {
				oflags = O_CREAT | O_WRONLY;
				oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;

				if ((ext = strrchr(mixmonitor->filename, '.')))
					*(ext++) = '\0';
				else
					ext = "raw";

				if (!(*fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0666))) {
					ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
					errflag = 1;
				}
			}

			/* Write out the frame(s) */
			if (*fs) {
				struct ast_frame *cur;

				for (cur = fr; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
					ast_writestream(*fs, cur);
				}
			}
		}
		ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);

		/* All done! free it. */
		ast_frame_free(fr, 0);
		ast_audiohook_lock(&mixmonitor->audiohook);
	}

	ast_audiohook_unlock(&mixmonitor->audiohook);

	/* Datastore cleanup.  close the filestream and wait for ds destruction */
	ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
	mixmonitor_ds_close_fs(mixmonitor->mixmonitor_ds);
	if (!mixmonitor->mixmonitor_ds->destruction_ok) {
		ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
	}
	ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);

	/* kill the audiohook */
	destroy_monitor_audiohook(mixmonitor);

	if (mixmonitor->post_process) {
		ast_verb(2, "Executing [%s]\n", mixmonitor->post_process);
		ast_safe_system(mixmonitor->post_process);
	}

	ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
	mixmonitor_free(mixmonitor);
	return NULL;
}
/* Start monitoring a channel */
int ast_monitor_start(	struct ast_channel *chan, const char *format_spec,
		const char *fname_base, int need_lock)
{
	int res = 0;
	char tmp[256];

	if (need_lock) {
		if (ast_mutex_lock(&chan->lock)) {
			ast_log(LOG_WARNING, "Unable to lock channel\n");
			return -1;
		}
	}

	if (!(chan->monitor)) {
		struct ast_channel_monitor *monitor;
		char *channel_name, *p;

		/* Create monitoring directory if needed */
		if (mkdir(ast_config_AST_MONITOR_DIR, 0770) < 0) {
			if (errno != EEXIST) {
				ast_log(LOG_WARNING, "Unable to create audio monitor directory: %s\n",
					strerror(errno));
			}
		}

		monitor = malloc(sizeof(struct ast_channel_monitor));
		if (!monitor) {
			if (need_lock) 
				ast_mutex_unlock(&chan->lock);
			return -1;
		}
		memset(monitor, 0, sizeof(struct ast_channel_monitor));

		/* Determine file names */
		if (!ast_strlen_zero(fname_base)) {
			int directory = strchr(fname_base, '/') ? 1 : 0;
			/* try creating the directory just in case it doesn't exist */
			if (directory) {
				char *name = strdup(fname_base);
				snprintf(tmp, sizeof(tmp), "mkdir -p \"%s\"",dirname(name));
				free(name);
				ast_safe_system(tmp);
			}
			snprintf(monitor->read_filename, FILENAME_MAX, "%s/%s-in",
						directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
			snprintf(monitor->write_filename, FILENAME_MAX, "%s/%s-out",
						directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
			ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base));
		} else {
			ast_mutex_lock(&monitorlock);
			snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld",
						ast_config_AST_MONITOR_DIR, seq);
			snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld",
						ast_config_AST_MONITOR_DIR, seq);
			seq++;
			ast_mutex_unlock(&monitorlock);

			if((channel_name = ast_strdupa(chan->name))) {
				while((p = strchr(channel_name, '/'))) {
					*p = '-';
				}
				snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
						 ast_config_AST_MONITOR_DIR, (int)time(NULL),channel_name);
				monitor->filename_changed = 1;
			} else {
				ast_log(LOG_ERROR,"Failed to allocate Memory\n");
				return -1;
			}
		}

		monitor->stop = ast_monitor_stop;

		/* Determine file format */
		if (!ast_strlen_zero(format_spec)) {
			monitor->format = strdup(format_spec);
		} else {
			monitor->format = strdup("wav");
		}
		
		/* open files */
		if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) {
			ast_filedelete(monitor->read_filename, NULL);
		}
		if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
						monitor->format, NULL,
						O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
			ast_log(LOG_WARNING, "Could not create file %s\n",
						monitor->read_filename);
			free(monitor);
			ast_mutex_unlock(&chan->lock);
			return -1;
		}
		if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
			ast_filedelete(monitor->write_filename, NULL);
		}
		if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
						monitor->format, NULL,
						O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
			ast_log(LOG_WARNING, "Could not create file %s\n",
						monitor->write_filename);
			ast_closestream(monitor->read_stream);
			free(monitor);
			ast_mutex_unlock(&chan->lock);
			return -1;
		}
		chan->monitor = monitor;
		/* so we know this call has been monitored in case we need to bill for it or something */
		pbx_builtin_setvar_helper(chan, "__MONITORED","true");
	} else {
		ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n",
					chan->name);
		res = -1;
	}

	if (need_lock) {
		ast_mutex_unlock(&chan->lock);
	}
	return res;
}
Exemplo n.º 11
0
/*--- ast_get_enum: ENUM lookup */
int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char* suffix, char* options)
{
	struct enum_context context;
	char tmp[259 + 512];
	char naptrinput[512];
	int pos = strlen(number) - 1;
	int newpos = 0;
	int ret = -1;
	struct enum_search *s = NULL;
	int version = -1;
	/* for ISN rewrite */
	char *p1 = NULL;
	char *p2 = NULL;
	int k = 0;
	int i = 0;
	int z = 0;

	if (number[0] == 'n') {
		strncpy(naptrinput, number+1, sizeof(naptrinput));
	} else {
		strncpy(naptrinput, number, sizeof(naptrinput));
	}

	context.naptrinput = naptrinput;	/* The number */
	context.dst = dst;			/* Return string */
	context.dstlen = dstlen;
	context.tech = tech;
	context.techlen = techlen;
	context.options = 0;
	context.position = 1;
	context.naptr_rrs = NULL;
	context.naptr_rrs_count = 0;

	if (options != NULL){
		if (*options == 'c'){
			context.options = ENUMLOOKUP_OPTIONS_COUNT;
			context.position = 0;
		} else {
			context.position = atoi(options);
			if (context.position < 1)
				context.position = 1;
		}
	}

	if (pos > 128)
		pos = 128;

	/* ISN rewrite */
	p1 = strchr(number, '*');

	if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */
		p1 = NULL;
		k = 1; /* strip 'n' from number */
	}

	if (p1 != NULL) {
		p2 = p1+1;
		while (p1 > number){
			p1--;
			tmp[newpos++] = *p1;
			tmp[newpos++] = '.';
		}
		if (*p2) {
			while(*p2 && newpos < 128){
				tmp[newpos++] = *p2;
				p2++;
			}
			tmp[newpos++] = '.';
		}

	} else {
		while (pos >= k) {
			if (isdigit(number[pos])) {
				tmp[newpos++] = number[pos];
				tmp[newpos++] = '.';
			}
			pos--;
		}
	}

	if (chan && ast_autoservice_start(chan) < 0)
		return -1;

	for (;;) {
		ast_mutex_lock(&enumlock);
		if (version != enumver) {
			/* Ooh, a reload... */
			s = toplevs;
			version = enumver;
		} else {
			s = s->next;
		}
		if (suffix != NULL) {
			strncpy(tmp + newpos, suffix, sizeof(tmp) - newpos - 1);
		} else if (s) {
			strncpy(tmp + newpos, s->toplev, sizeof(tmp) - newpos - 1);
		}
		ast_mutex_unlock(&enumlock);
		if (!s)
			break;
		ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
		if (ret > 0)
			break;
		if (suffix != NULL)
                       break;
	}
	if (ret < 0) {
		ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
		ret = 0;
	}

	if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
		/* sort array by NAPTR order/preference/tech */
		for (k = 0; k < context.naptr_rrs_count; k++) {
			for (i = 0; i < context.naptr_rrs_count; i++) {
				/* Compare by order first. */
				if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
						&& context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
					|| (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
						&& context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
					z = context.naptr_rrs[k].sort_pos;
					context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
					context.naptr_rrs[i].sort_pos = z;
				} else if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
					/* Order is the same, so sort by preference next */
					if (ntohs(context.naptr_rrs[k].naptr.pref) == ntohs(context.naptr_rrs[i].naptr.pref)) {
						/* Preference is the same, so sort by tech */
						if ((strcmp(context.naptr_rrs[k].tech, context.naptr_rrs[i].tech) < 0
								&& context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
							|| (strcmp(context.naptr_rrs[k].tech, context.naptr_rrs[i].tech) > 0
								&& context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)) {
							z = context.naptr_rrs[k].sort_pos;
							context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
							context.naptr_rrs[i].sort_pos = z;
						}
					} else if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
							&& context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
						|| (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
							&& context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
						z = context.naptr_rrs[k].sort_pos;
						context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
						context.naptr_rrs[i].sort_pos = z;
					}
				}
			}
		}
		for (k = 0; k < context.naptr_rrs_count; k++) {
			if (context.naptr_rrs[k].sort_pos == context.position - 1) {
				ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
				ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
				break;
			}
		}
	} else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
		context.dst[0] = 0;
	}

	if (chan)
		ret |= ast_autoservice_stop(chan);

	for (k=0; k<context.naptr_rrs_count; k++) {
		free(context.naptr_rrs[k].result);
		free(context.naptr_rrs[k].tech);
	}

	free(context.naptr_rrs);

	return ret;
}
/* Stop monitoring a channel */
int ast_monitor_stop(struct ast_channel *chan, int need_lock)
{
	char *execute, *execute_args;
	int delfiles = 0;

	if (need_lock) {
		if (ast_mutex_lock(&chan->lock)) {
			ast_log(LOG_WARNING, "Unable to lock channel\n");
			return -1;
		}
	}

	if (chan->monitor) {
		char filename[ FILENAME_MAX ];

		if (chan->monitor->read_stream) {
			ast_closestream(chan->monitor->read_stream);
		}
		if (chan->monitor->write_stream) {
			ast_closestream(chan->monitor->write_stream);
		}

		if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) {
			if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
				snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
				if (ast_fileexists(filename, NULL, NULL) > 0) {
					ast_filedelete(filename, NULL);
				}
				ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
			} else {
				ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
			}

			if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
				snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
				if (ast_fileexists(filename, NULL, NULL) > 0) {
					ast_filedelete(filename, NULL);
				}
				ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
			} else {
				ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
			}
		}

		if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
			char tmp[1024];
			char tmp2[1024];
			char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
			char *name = chan->monitor->filename_base;
			int directory = strchr(name, '/') ? 1 : 0;
			char *dir = directory ? "" : ast_config_AST_MONITOR_DIR;

			/* Set the execute application */
			execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
			if (ast_strlen_zero(execute)) { 
				execute = "nice -n 19 soxmix";
				delfiles = 1;
			} 
			execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
			if (ast_strlen_zero(execute_args)) {
				execute_args = "";
			}
			
			snprintf(tmp, sizeof(tmp), "%s \"%s/%s-in.%s\" \"%s/%s-out.%s\" \"%s/%s.%s\" %s &", execute, dir, name, format, dir, name, format, dir, name, format,execute_args);
			if (delfiles) {
				snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s/%s-\"* ) &",tmp, dir ,name); /* remove legs when done mixing */
				ast_copy_string(tmp, tmp2, sizeof(tmp));
			}
			ast_log(LOG_DEBUG,"monitor executing %s\n",tmp);
			if (ast_safe_system(tmp) == -1)
				ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
		}
		
		free(chan->monitor->format);
		free(chan->monitor);
		chan->monitor = NULL;
	}

	if (need_lock)
		ast_mutex_unlock(&chan->lock);
	return 0;
}
Exemplo n.º 13
0
static int odbc_log(struct ast_cdr *cdr)
{
	int ODBC_res;
	char sqlcmd[2048] = "", timestr[128];
	int res = 0;
	struct tm tm;

	if (usegmtime) 
		gmtime_r(&cdr->start.tv_sec,&tm);
	else
		ast_localtime(&cdr->start.tv_sec, &tm, NULL);

	ast_mutex_lock(&odbc_lock);
	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
	memset(sqlcmd,0,2048);
	if (loguniqueid) {
		snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
		"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
		"lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) "
		"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
	} else {
		snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
		"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
		"duration,billsec,disposition,amaflags,accountcode) "
		"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
	}

	if (!connected) {
		res = odbc_init();
		if (res < 0) {
			odbc_disconnect();
			ast_mutex_unlock(&odbc_lock);
			return 0;
		}				
	}

	ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);

	if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
		if (option_verbose > 10)
			ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res);
		SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
		odbc_disconnect();
		ast_mutex_unlock(&odbc_lock);
		return 0;
	}

	/* We really should only have to do this once.  But for some
	   strange reason if I don't it blows holes in memory like
	   like a shotgun.  So we just do this so its safe. */

	ODBC_res = SQLPrepare(ODBC_stmt, (unsigned char *)sqlcmd, SQL_NTS);
	
	if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
		if (option_verbose > 10)
			ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in PREPARE %d\n", ODBC_res);
		SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
		odbc_disconnect();
		ast_mutex_unlock(&odbc_lock);
		return 0;
	}

	SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, &timestr, 0, NULL);
	SQLBindParameter(ODBC_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL);
	SQLBindParameter(ODBC_stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL);
	SQLBindParameter(ODBC_stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL);
	SQLBindParameter(ODBC_stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL);
	SQLBindParameter(ODBC_stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL);
	SQLBindParameter(ODBC_stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL);
	SQLBindParameter(ODBC_stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL);
	SQLBindParameter(ODBC_stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL);
	SQLBindParameter(ODBC_stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL);
	SQLBindParameter(ODBC_stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL);
	if (dispositionstring)
		SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL);
	else
		SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL);
	SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL);
	SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL);

	if (loguniqueid) {
		SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL);
		SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL);
	}

	if (connected) {
		res = odbc_do_query();
		if (res < 0) {
			if (option_verbose > 10)		
				ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
			if (option_verbose > 10)
				ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Reconnecting to dsn %s\n", dsn);
			SQLDisconnect(ODBC_con);
			res = odbc_init();
			if (res < 0) {
				if (option_verbose > 10)
					ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: %s has gone away!\n", dsn);
				odbc_disconnect();
			} else {
				if (option_verbose > 10)
					ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Trying Query again!\n");
				res = odbc_do_query();
				if (res < 0) {
					if (option_verbose > 10)
						ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
				}
			}
		}
	} else {
		if (option_verbose > 10)
			ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
	}
	SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
	ast_mutex_unlock(&odbc_lock);
	return 0;
}
Exemplo n.º 14
0
static int odbc_load_module(void)
{
	int res = 0;
	struct ast_config *cfg;
	struct ast_variable *var;
	const char *tmp;

	ast_mutex_lock(&odbc_lock);

	cfg = ast_config_load(config);
	if (!cfg) {
		ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
		res = AST_MODULE_LOAD_DECLINE;
		goto out;
	}
	
	var = ast_variable_browse(cfg, "global");
	if (!var) {
		/* nothing configured */
		goto out;
	}

	tmp = ast_variable_retrieve(cfg,"global","dsn");
	if (tmp == NULL) {
		ast_log(LOG_WARNING,"cdr_odbc: dsn not specified.  Assuming asteriskdb\n");
		tmp = "asteriskdb";
	}
	dsn = strdup(tmp);
	if (dsn == NULL) {
		ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
		res = -1;
		goto out;
	}

	tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
	if (tmp) {
		dispositionstring = ast_true(tmp);
	} else {
		dispositionstring = 0;
	}
		
	tmp = ast_variable_retrieve(cfg,"global","username");
	if (tmp) {
		username = strdup(tmp);
		if (username == NULL) {
			ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
			res = -1;
			goto out;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","password");
	if (tmp) {
		password = strdup(tmp);
		if (password == NULL) {
			ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
			res = -1;
			goto out;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
	if (tmp) {
		loguniqueid = ast_true(tmp);
		if (loguniqueid) {
			ast_log(LOG_DEBUG,"cdr_odbc: Logging uniqueid\n");
		} else {
			ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
		}
	} else {
		ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
		loguniqueid = 0;
	}

	tmp = ast_variable_retrieve(cfg,"global","usegmtime");
	if (tmp) {
		usegmtime = ast_true(tmp);
		if (usegmtime) {
			ast_log(LOG_DEBUG,"cdr_odbc: Logging in GMT\n");
		} else {
			ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
		}
	} else {
		ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
		usegmtime = 0;
	}

	tmp = ast_variable_retrieve(cfg,"global","table");
	if (tmp == NULL) {
		ast_log(LOG_WARNING,"cdr_odbc: table not specified.  Assuming cdr\n");
		tmp = "cdr";
	}
	table = strdup(tmp);
	if (table == NULL) {
		ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
		res = -1;
		goto out;
	}

	if (option_verbose > 2) {
		ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: dsn is %s\n",dsn);
		if (username)
		{
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: username is %s\n",username);
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: password is [secret]\n");
		}
		else
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: retreiving username and password from odbc config\n");
		ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: table is %s\n",table);
	}
	
	res = odbc_init();
	if (res < 0) {
		ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
		if (option_verbose > 2) {
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
		}
	}
	res = ast_cdr_register(name, ast_module_info->description, odbc_log);
	if (res) {
		ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
	}
out:
	if (cfg)
		ast_config_destroy(cfg);
	ast_mutex_unlock(&odbc_lock);
	return res;
}
Exemplo n.º 15
0
static char *handle_memory_show_summary(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
#define my_max(a, b) ((a) >= (b) ? (a) : (b))

	const char *fn = NULL;
	int idx;
	int cmp;
	struct ast_region *reg;
	unsigned int whales_len;
	unsigned int minnows_len;
	unsigned int total_len = 0;
	unsigned int selected_len = 0;
	unsigned int cache_len = 0;
	unsigned int count = 0;
	struct file_summary {
		struct file_summary *next;
		unsigned int len;
		unsigned int cache_len;
		unsigned int count;
		unsigned int lineno;
		char name[my_max(sizeof(reg->file), sizeof(reg->func))];
	} *list = NULL, *cur, **prev;

	switch (cmd) {
	case CLI_INIT:
		e->command = "memory show summary";
		e->usage =
			"Usage: memory show summary [<file>]\n"
			"       Summarizes heap memory allocations by file, or optionally\n"
			"       by line if a file is specified.\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if (a->argc == 4) {
		fn = a->argv[3];
	} else if (a->argc != 3) {
		return CLI_SHOWUSAGE;
	}

	ast_mutex_lock(&reglock);
	for (idx = 0; idx < ARRAY_LEN(regions); ++idx) {
		for (reg = regions[idx]; reg; reg = AST_LIST_NEXT(reg, node)) {
			total_len += reg->len;
			if (fn) {
				if (strcasecmp(fn, reg->file)) {
					continue;
				}

				/* Sort list by func/lineno.  Find existing or place to insert. */
				for (prev = &list; (cur = *prev); prev = &cur->next) {
					cmp = strcmp(cur->name, reg->func);
					if (cmp < 0) {
						continue;
					}
					if (cmp > 0) {
						/* Insert before current */
						cur = NULL;
						break;
					}
					cmp = cur->lineno - reg->lineno;
					if (cmp < 0) {
						continue;
					}
					if (cmp > 0) {
						/* Insert before current */
						cur = NULL;
					}
					break;
				}
			} else {
				/* Sort list by filename.  Find existing or place to insert. */
				for (prev = &list; (cur = *prev); prev = &cur->next) {
					cmp = strcmp(cur->name, reg->file);
					if (cmp < 0) {
						continue;
					}
					if (cmp > 0) {
						/* Insert before current */
						cur = NULL;
					}
					break;
				}
			}

			if (!cur) {
				cur = ast_alloca(sizeof(*cur));
				memset(cur, 0, sizeof(*cur));
				cur->lineno = reg->lineno;
				ast_copy_string(cur->name, fn ? reg->func : reg->file, sizeof(cur->name));

				cur->next = *prev;
				*prev = cur;
			}

			cur->len += reg->len;
			if (reg->cache) {
				cur->cache_len += reg->len;
			}
			++cur->count;
		}
	}

	whales_len = freed_regions_size(&whales);
	minnows_len = freed_regions_size(&minnows);
	ast_mutex_unlock(&reglock);

	/* Dump the whole list */
	for (cur = list; cur; cur = cur->next) {
		selected_len += cur->len;
		cache_len += cur->cache_len;
		count += cur->count;
		if (cur->cache_len) {
			if (fn) {
				ast_cli(a->fd, "%10u bytes (%10u cache) in %10u allocations by %20s() line %5u of %s\n",
					cur->len, cur->cache_len, cur->count, cur->name, cur->lineno, fn);
			} else {
				ast_cli(a->fd, "%10u bytes (%10u cache) in %10u allocations in file %s\n",
					cur->len, cur->cache_len, cur->count, cur->name);
			}
		} else {
			if (fn) {
				ast_cli(a->fd, "%10u bytes in %10u allocations by %20s() line %5u of %s\n",
					cur->len, cur->count, cur->name, cur->lineno, fn);
			} else {
				ast_cli(a->fd, "%10u bytes in %10u allocations in file %s\n",
					cur->len, cur->count, cur->name);
			}
		}
	}

	print_memory_show_common_stats(a->fd,
		whales_len, minnows_len, total_len,
		selected_len, cache_len, count);

	return CLI_SUCCESS;
}
Exemplo n.º 16
0
static void *mixmonitor_thread(void *obj) 
{
	struct mixmonitor *mixmonitor = obj;

	struct ast_filestream **fs = NULL;
	struct ast_filestream **fs_read = NULL;
	struct ast_filestream **fs_write = NULL;

	unsigned int oflags;
	int errflag = 0;
	struct ast_format format_slin;

	ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);

	fs = &mixmonitor->mixmonitor_ds->fs;
	fs_read = &mixmonitor->mixmonitor_ds->fs_read;
	fs_write = &mixmonitor->mixmonitor_ds->fs_write;

	ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
	mixmonitor_save_prep(mixmonitor, mixmonitor->filename, fs, &oflags, &errflag);
	mixmonitor_save_prep(mixmonitor, mixmonitor->filename_read, fs_read, &oflags, &errflag);
	mixmonitor_save_prep(mixmonitor, mixmonitor->filename_write, fs_write, &oflags, &errflag);

	ast_format_set(&format_slin, ast_format_slin_by_rate(mixmonitor->mixmonitor_ds->samp_rate), 0);

	ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);


	/* The audiohook must enter and exit the loop locked */
	ast_audiohook_lock(&mixmonitor->audiohook);
	while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
		struct ast_frame *fr = NULL;
		struct ast_frame *fr_read = NULL;
		struct ast_frame *fr_write = NULL;

		if (!(fr = ast_audiohook_read_frame_all(&mixmonitor->audiohook, SAMPLES_PER_FRAME, &format_slin,
						&fr_read, &fr_write))) {
			ast_audiohook_trigger_wait(&mixmonitor->audiohook);

			if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
				break;
			}
			continue;
		}

		/* audiohook lock is not required for the next block.
		 * Unlock it, but remember to lock it before looping or exiting */
		ast_audiohook_unlock(&mixmonitor->audiohook);

		if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || (mixmonitor->autochan->chan && ast_bridged_channel(mixmonitor->autochan->chan))) {
			ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);

			/* Write out the frame(s) */
			if ((*fs_read) && (fr_read)) {
				struct ast_frame *cur;

				for (cur = fr_read; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
					ast_writestream(*fs_read, cur);
				}
			}

			if ((*fs_write) && (fr_write)) {
				struct ast_frame *cur;

				for (cur = fr_write; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
					ast_writestream(*fs_write, cur);
				}
			}

			if ((*fs) && (fr)) {
				struct ast_frame *cur;

				for (cur = fr; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
					ast_writestream(*fs, cur);
				}
			}
			ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
		}
		/* All done! free it. */
		if (fr) {
			ast_frame_free(fr, 0);
		}
		if (fr_read) {
			ast_frame_free(fr_read, 0);
		}
		if (fr_write) {
			ast_frame_free(fr_write, 0);
		}

		fr = NULL;
		fr_write = NULL;
		fr_read = NULL;

		ast_audiohook_lock(&mixmonitor->audiohook);
	}
	ast_audiohook_unlock(&mixmonitor->audiohook);

	ast_autochan_destroy(mixmonitor->autochan);

	/* Datastore cleanup.  close the filestream and wait for ds destruction */
	ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
	mixmonitor_ds_close_fs(mixmonitor->mixmonitor_ds);
	if (!mixmonitor->mixmonitor_ds->destruction_ok) {
		ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
	}
	ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);

	/* kill the audiohook */
	destroy_monitor_audiohook(mixmonitor);

	if (mixmonitor->post_process) {
		ast_verb(2, "Executing [%s]\n", mixmonitor->post_process);
		ast_safe_system(mixmonitor->post_process);
	}

	ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
	mixmonitor_free(mixmonitor);
	return NULL;
}
Exemplo n.º 17
0
static int tds_log(struct ast_cdr *cdr)
{
	char sqlcmd[2048], start[80], answer[80], end[80];
	char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid;
	int res = 0;
	int retried = 0;
#ifdef FREETDS_PRE_0_62
	TDS_INT result_type;
#endif

	ast_mutex_lock(&tds_lock);

	memset(sqlcmd, 0, 2048);

	accountcode = anti_injection(cdr->accountcode, 20);
	src = anti_injection(cdr->src, 80);
	dst = anti_injection(cdr->dst, 80);
	dcontext = anti_injection(cdr->dcontext, 80);
	clid = anti_injection(cdr->clid, 80);
	channel = anti_injection(cdr->channel, 80);
	dstchannel = anti_injection(cdr->dstchannel, 80);
	lastapp = anti_injection(cdr->lastapp, 80);
	lastdata = anti_injection(cdr->lastdata, 80);
	uniqueid = anti_injection(cdr->uniqueid, 32);

	get_date(start, cdr->start);
	get_date(answer, cdr->answer);
	get_date(end, cdr->end);

	sprintf(
		sqlcmd,
		"INSERT INTO cdr "
		"("
			"accountcode, "
			"src, "
			"dst, "
			"dcontext, "
			"clid, "
			"channel, "
			"dstchannel, "
			"lastapp, "
			"lastdata, "
			"start, "
			"answer, "
			"[end], "
			"duration, "
			"billsec, "
			"disposition, "
			"amaflags, "
			"uniqueid"
		") "
		"VALUES "
		"("
			"'%s', "	/* accountcode */
			"'%s', "	/* src */
			"'%s', "	/* dst */
			"'%s', "	/* dcontext */
			"'%s', "	/* clid */
			"'%s', "	/* channel */
			"'%s', "	/* dstchannel */
			"'%s', "	/* lastapp */
			"'%s', "	/* lastdata */
			"%s, "		/* start */
			"%s, "		/* answer */
			"%s, "		/* end */
			"%ld, "		/* duration */
			"%ld, "		/* billsec */
			"'%s', "	/* disposition */
			"'%s', "	/* amaflags */
			"'%s'"		/* uniqueid */
		")",
		accountcode,
		src,
		dst,
		dcontext,
		clid,
		channel,
		dstchannel,
		lastapp,
		lastdata,
		start,
		answer,
		end,
		cdr->duration,
		cdr->billsec,
		ast_cdr_disp2str(cdr->disposition),
		ast_cdr_flags2str(cdr->amaflags),
		uniqueid
	);

	do {
		if (!connected) {
			if (mssql_connect())
				ast_log(LOG_ERROR, "Failed to reconnect to SQL database.\n");
			else
				ast_log(LOG_WARNING, "Reconnected to SQL database.\n");

			retried = 1;	/* note that we have now tried */
		}

#ifdef FREETDS_PRE_0_62
		if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
#else
		if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
#endif
		{
			ast_log(LOG_ERROR, "Failed to insert Call Data Record into SQL database.\n");

			mssql_disconnect();	/* this is ok even if we are already disconnected */
		}
	} while (!connected && !retried);

	free(accountcode);
	free(src);
	free(dst);
	free(dcontext);
	free(clid);
	free(channel);
	free(dstchannel);
	free(lastapp);
	free(lastdata);
	free(uniqueid);

	ast_mutex_unlock(&tds_lock);

	return res;
}
Exemplo n.º 18
0
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type,
		const char *userdefevname, const char *extra, struct ast_channel *peer2)
{
	struct timeval eventtime;
	struct ast_event *ev;
	const char *peername = "";
	struct ast_channel *peer;

	ast_channel_lock(chan);
	peer = ast_bridged_channel(chan);
	if (peer) {
		ast_channel_ref(peer);
	}
	ast_channel_unlock(chan);

	/* Make sure a reload is not occurring while we're checking to see if this
	 * is an event that we care about.  We could lose an important event in this
	 * process otherwise. */
	ast_mutex_lock(&reload_lock);

	if (!cel_enabled || !ast_cel_track_event(event_type)) {
		ast_mutex_unlock(&reload_lock);
		if (peer) {
			ast_channel_unref(peer);
		}
		return 0;
	}

	if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) {
		char *app;
		if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) {
			ast_mutex_unlock(&reload_lock);
			if (peer) {
				ast_channel_unref(peer);
			}
			return 0;
		}
		ao2_ref(app, -1);
	}

	ast_mutex_unlock(&reload_lock);

	if (peer) {
		ast_channel_lock(peer);
		peername = ast_strdupa(peer->name);
		ast_channel_unlock(peer);
	} else if (peer2) {
		ast_channel_lock(peer2);
		peername = ast_strdupa(peer2->name);
		ast_channel_unlock(peer2);
	}

	if (!userdefevname) {
		userdefevname = "";
	}

	if (!extra) {
		extra = "";
	}

	eventtime = ast_tvnow();

	ast_channel_lock(chan);

	ev = ast_event_new(AST_EVENT_CEL,
		AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
		AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
		AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
		AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
		AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR,
			S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
		AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR,
			S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
		AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR,
			S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""),
		AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR,
			S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""),
		AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR,
			S_OR(chan->dialed.number.str, ""),
		AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
		AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
		AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
		AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
		AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
		AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
		AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
		AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
		AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
		AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
		AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
		AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
		AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
		AST_EVENT_IE_END);

	ast_channel_unlock(chan);

	if (peer) {
		peer = ast_channel_unref(peer);
	}

	if (ev && ast_event_queue(ev)) {
		ast_event_destroy(ev);
		return -1;
	}

	return 0;
}
Exemplo n.º 19
0
int console_write_video(struct ast_channel *chan, struct ast_frame *f)
{
	struct video_desc *env = get_video_desc(chan);
	struct video_dec_desc *v = env->in;

	if (!env->gui)	/* no gui, no rendering */
		return 0;
	if (v == NULL)
		env->in = v = dec_init(f->subclass & ~1);
	if (v == NULL) {
		/* This is not fatal, but we won't have incoming video */
		ast_log(LOG_WARNING, "Cannot initialize input decoder\n");
		return 0;
	}

	if (v->dec_in_cur == NULL)	/* no buffer for incoming frames, drop */
		return 0;
#if defined(DROP_PACKETS) && DROP_PACKETS > 0
	/* Simulate lost packets */
	if ((random() % 10000) <= 100*DROP_PACKETS) {
		ast_log(LOG_NOTICE, "Packet lost [%d]\n", f->seqno);
		return 0;
	}
#endif
	if (v->discard) {
		/*
		 * In discard mode, drop packets until we find one with
		 * the RTP marker set (which is the end of frame).
		 * Note that the RTP marker flag is sent as the LSB of the
		 * subclass, which is a  bitmask of formats. The low bit is
		 * normally used for audio so there is no interference.
		 */
		if (f->subclass & 0x01) {
			v->dec_in_cur->used = 0;
			v->dec_in_cur->ebit = 0;
			v->next_seq = f->seqno + 1;	/* wrap at 16 bit */
			v->discard = 0;
			ast_log(LOG_WARNING, "out of discard mode, frame %d\n", f->seqno);
		}
		return 0;
	}

	/*
	 * Only in-order fragments will be accepted. Remember seqno
	 * has 16 bit so there is wraparound. Also, ideally we could
	 * accept a bit of reordering, but at the moment we don't.
	 */
	if (v->next_seq != f->seqno) {
		ast_log(LOG_WARNING, "discarding frame out of order, %d %d\n",
			v->next_seq, f->seqno);
		v->discard = 1;
		return 0;
	}
	v->next_seq++;

	if (f->data.ptr == NULL || f->datalen < 2) {
		ast_log(LOG_WARNING, "empty video frame, discard\n");
		return 0;
	}
	if (v->d_callbacks->dec_decap(v->dec_in_cur, f->data.ptr, f->datalen)) {
		ast_log(LOG_WARNING, "error in dec_decap, enter discard\n");
		v->discard = 1;
	}
	if (f->subclass & 0x01) {	// RTP Marker
		/* prepare to decode: advance the buffer so the video thread knows. */
		struct fbuf_t *tmp = v->dec_in_cur;	/* store current pointer */
		ast_mutex_lock(&env->dec_lock);
		if (++v->dec_in_cur == &v->dec_in[N_DEC_IN])	/* advance to next, circular */
			v->dec_in_cur = &v->dec_in[0];
		if (v->dec_in_dpy == NULL) {	/* were not displaying anything, so set it */
			v->dec_in_dpy = tmp;
		} else if (v->dec_in_dpy == v->dec_in_cur) { /* current slot is busy */
			v->dec_in_cur = NULL;
		}
		ast_mutex_unlock(&env->dec_lock);
	}
	return 0;
}
Exemplo n.º 20
0
struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
{
	char prefix[256];
	DBT key, data;
	char *keys, *values;
	int values_len;
	int res;
	int pass;
	struct ast_db_entry *last = NULL;
	struct ast_db_entry *cur, *ret=NULL;

	if (!ast_strlen_zero(family)) {
		if (!ast_strlen_zero(keytree)) {
			/* Family and key tree */
			snprintf(prefix, sizeof(prefix), "/%s/%s", family, prefix);
		} else {
			/* Family only */
			snprintf(prefix, sizeof(prefix), "/%s", family);
		}
	} else {
		prefix[0] = '\0';
	}
	ast_mutex_lock(&dblock);
	if (dbinit()) {
		ast_mutex_unlock(&dblock);
		ast_log(LOG_WARNING, "Database unavailable\n");
		return NULL;	
	}
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	pass = 0;
	while (!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
		if (key.size) {
			keys = key.data;
			keys[key.size - 1] = '\0';
		} else {
			keys = "<bad key>";
		}
		if (data.size) {
			values = data.data;
			values[data.size - 1] = '\0';
		} else {
			values = "<bad value>";
		}
		values_len = strlen(values) + 1;
		if (keymatch(keys, prefix) && (cur = ast_malloc(sizeof(*cur) + strlen(keys) + 1 + values_len))) {
			cur->next = NULL;
			cur->key = cur->data + values_len;
			strcpy(cur->data, values);
			strcpy(cur->key, keys);
			if (last) {
				last->next = cur;
			} else {
				ret = cur;
			}
			last = cur;
		}
	}
	ast_mutex_unlock(&dblock);
	return ret;	
}
Exemplo n.º 21
0
int ooh323c_start_call_thread(ooCallData *call) {
 char c = 'c';
 int res;
 struct callthread *cur = callThreads;

 ast_mutex_lock(&callThreadsLock);
 while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
	cur = cur->next;
 }
 ast_mutex_unlock(&callThreadsLock);

 if (cur != NULL && cur->inUse) {
	ast_mutex_unlock(&cur->lock);
	cur = NULL;
 }

/* make new thread */
 if (cur == NULL) {
	if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
		ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
							call->callToken);
		return -1;
	}

	ast_module_ref(myself);
	memset(cur, 0, sizeof(cur));
	if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
		ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
		free(cur);
		return -1;
	}
	cur->inUse = TRUE;
	cur->call = call;

	ast_mutex_init(&cur->lock);

	if (gH323Debug)
		ast_debug(1,"new call thread created for call %s\n", call->callToken);

	if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
 	{
  		ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
					call->callToken);
		ast_mutex_destroy(&cur->lock);
		close(cur->thePipe[0]);
		close(cur->thePipe[1]);
		free(cur);
  		return -1;
 	}

 } else {
	if (gH323Debug)
		ast_debug(1,"using existing call thread for call %s\n", call->callToken);
	cur->inUse = TRUE;
	cur->call = call;
	res = write(cur->thePipe[1], &c, 1);
	ast_mutex_unlock(&cur->lock);

 }
 return 0;
}
Exemplo n.º 22
0
int load_module()
{
	struct ast_config *cfg;
	struct ast_variable *v;
	struct phone_pvt *tmp;
	int mode = MODE_IMMEDIATE;
	int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
	cfg = ast_load(config);

	/* We *must* have a config file otherwise stop immediately */
	if (!cfg) {
		ast_log(LOG_ERROR, "Unable to load config %s\n", config);
		return -1;
	}
	if (ast_mutex_lock(&iflock)) {
		/* It's a little silly to lock it, but we mind as well just to be sure */
		ast_log(LOG_ERROR, "Unable to lock interface list???\n");
		return -1;
	}
	v = ast_variable_browse(cfg, "interfaces");
	while(v) {
		/* Create the interface list */
		if (!strcasecmp(v->name, "device")) {
				tmp = mkif(v->value, mode, txgain, rxgain);
				if (tmp) {
					tmp->next = iflist;
					iflist = tmp;
					
				} else {
					ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
					ast_destroy(cfg);
					ast_mutex_unlock(&iflock);
					__unload_module();
					return -1;
				}
		} else if (!strcasecmp(v->name, "silencesupression")) {
			silencesupression = ast_true(v->value);
		} else if (!strcasecmp(v->name, "language")) {
			strncpy(language, v->value, sizeof(language)-1);
		} else if (!strcasecmp(v->name, "callerid")) {
			strncpy(callerid, v->value, sizeof(callerid)-1);
		} else if (!strcasecmp(v->name, "mode")) {
			if (!strncasecmp(v->value, "di", 2)) 
				mode = MODE_DIALTONE;
			else if (!strncasecmp(v->value, "im", 2))
				mode = MODE_IMMEDIATE;
			else if (!strncasecmp(v->value, "fx", 2))
				mode = MODE_FXO;
			else
				ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
		} else if (!strcasecmp(v->name, "context")) {
			strncpy(context, v->value, sizeof(context)-1);
		} else if (!strcasecmp(v->name, "format")) {
			if (!strcasecmp(v->value, "g723.1")) {
				prefformat = AST_FORMAT_G723_1;
			} else if (!strcasecmp(v->value, "slinear")) {
				prefformat = AST_FORMAT_SLINEAR;
			} else if (!strcasecmp(v->value, "ulaw")) {
				prefformat = AST_FORMAT_ULAW;
			} else
				ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
		} else if (!strcasecmp(v->name, "echocancel")) {
			if (!strcasecmp(v->value, "off")) {
				echocancel = AEC_OFF;
			} else if (!strcasecmp(v->value, "low")) {
				echocancel = AEC_LOW;
			} else if (!strcasecmp(v->value, "medium")) {
				echocancel = AEC_MED;
			} else if (!strcasecmp(v->value, "high")) {
				echocancel = AEC_HIGH;
			} else 
				ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);
		} else if (!strcasecmp(v->name, "txgain")) {
			txgain = parse_gain_value(v->name, v->value);
		} else if (!strcasecmp(v->name, "rxgain")) {
			rxgain = parse_gain_value(v->name, v->value);
		}	
		v = v->next;
	}
	ast_mutex_unlock(&iflock);
	/* Make sure we can register our Adtranphone channel type */
	if (ast_channel_register(type, tdesc, 
			 AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
		ast_destroy(cfg);
		__unload_module();
		return -1;
	}
	ast_destroy(cfg);
	/* And start the monitor for the first time */
	restart_monitor();
	return 0;
}
Exemplo n.º 23
0
/*! \brief Start monitoring a channel
 * \param chan ast_channel struct to record
 * \param format_spec file format to use for recording
 * \param fname_base filename base to record to
 * \param need_lock whether to lock the channel mutex
 * \param stream_action whether to record the input and/or output streams.  X_REC_IN | X_REC_OUT is most often used
 * Creates the file to record, if no format is specified it assumes WAV
 * It also sets channel variable __MONITORED=yes
 * \retval 0 on success
 * \retval -1 on failure
 */
int ast_monitor_start(	struct ast_channel *chan, const char *format_spec,
		const char *fname_base, int need_lock, int stream_action)
{
	int res = 0;

	LOCK_IF_NEEDED(chan, need_lock);

	if (!(chan->monitor)) {
		struct ast_channel_monitor *monitor;
		char *channel_name, *p;

		/* Create monitoring directory if needed */
		ast_mkdir(ast_config_AST_MONITOR_DIR, 0777);

		if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
			UNLOCK_IF_NEEDED(chan, need_lock);
			return -1;
		}

		/* Determine file names */
		if (!ast_strlen_zero(fname_base)) {
			int directory = strchr(fname_base, '/') ? 1 : 0;
			const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;

			snprintf(monitor->read_filename, FILENAME_MAX, "%s/%s-in",
						absolute, fname_base);
			snprintf(monitor->write_filename, FILENAME_MAX, "%s/%s-out",
						absolute, fname_base);
			snprintf(monitor->filename_base, FILENAME_MAX, "%s/%s",
					 	absolute, fname_base);

			/* try creating the directory just in case it doesn't exist */
			if (directory) {
				char *name = ast_strdupa(monitor->filename_base);
				ast_mkdir(dirname(name), 0777);
			}
		} else {
			ast_mutex_lock(&monitorlock);
			snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld",
						ast_config_AST_MONITOR_DIR, seq);
			snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld",
						ast_config_AST_MONITOR_DIR, seq);
			seq++;
			ast_mutex_unlock(&monitorlock);

			channel_name = ast_strdupa(chan->name);
			while ((p = strchr(channel_name, '/'))) {
				*p = '-';
			}
			snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
					 ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);
			monitor->filename_changed = 1;
		}

		monitor->stop = ast_monitor_stop;

		/* Determine file format */
		if (!ast_strlen_zero(format_spec)) {
			monitor->format = ast_strdup(format_spec);
		} else {
			monitor->format = ast_strdup("wav");
		}
		
		/* open files */
		if (stream_action & X_REC_IN) {
			if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0)
				ast_filedelete(monitor->read_filename, NULL);
			if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
							monitor->format, NULL,
							O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
				ast_log(LOG_WARNING, "Could not create file %s\n",
							monitor->read_filename);
				ast_free(monitor);
				UNLOCK_IF_NEEDED(chan, need_lock);
				return -1;
			}
		} else
			monitor->read_stream = NULL;

		if (stream_action & X_REC_OUT) {
			if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
				ast_filedelete(monitor->write_filename, NULL);
			}
			if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
							monitor->format, NULL,
							O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
				ast_log(LOG_WARNING, "Could not create file %s\n",
							monitor->write_filename);
				ast_closestream(monitor->read_stream);
				ast_free(monitor);
				UNLOCK_IF_NEEDED(chan, need_lock);
				return -1;
			}
		} else
			monitor->write_stream = NULL;

		chan->monitor = monitor;
		ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
		/* so we know this call has been monitored in case we need to bill for it or something */
		pbx_builtin_setvar_helper(chan, "__MONITORED","true");

		manager_event(EVENT_FLAG_CALL, "MonitorStart",
        	                "Channel: %s\r\n"
                	        "Uniqueid: %s\r\n",                        
	                        chan->name,
        	                chan->uniqueid                        
                	        );
	} else {
		ast_debug(1,"Cannot start monitoring %s, already monitored\n", chan->name);
		res = -1;
	}

	UNLOCK_IF_NEEDED(chan, need_lock);

	return res;
}
Exemplo n.º 24
0
static void phone_check_exception(struct phone_pvt *i)
{
	int offhook=0;
	char digit[2] = {0 , 0};
	union telephony_exception phonee;
	/* XXX Do something XXX */
#if 0
	ast_log(LOG_DEBUG, "Exception!\n");
#endif
	phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
	if (phonee.bits.dtmf_ready)  {
		digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);
		if (i->mode == MODE_DIALTONE) {
			ioctl(i->fd, PHONE_PLAY_STOP);
			ioctl(i->fd, PHONE_REC_STOP);
			ioctl(i->fd, PHONE_CPT_STOP);
			i->dialtone = 0;
			if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
				strncat(i->ext, digit, sizeof(i->ext) - strlen(i->ext) - 1);
			if (ast_exists_extension(NULL, i->context, i->ext, 1, i->callerid)) {
				/* It's a valid extension in its context, get moving! */
				phone_new(i, AST_STATE_RING, i->context);
				/* No need to restart monitor, we are the monitor */
				if (i->owner) {
					ast_mutex_lock(&usecnt_lock);
					usecnt--;
					ast_mutex_unlock(&usecnt_lock);
					ast_update_use_count();
				}
			} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->callerid)) {
				/* There is nothing in the specified extension that can match anymore.
				   Try the default */
				if (ast_exists_extension(NULL, "default", i->ext, 1, i->callerid)) {
					/* Check the default, too... */
					phone_new(i, AST_STATE_RING, "default");
					if (i->owner) {
						ast_mutex_lock(&usecnt_lock);
						usecnt--;
						ast_mutex_unlock(&usecnt_lock);
						ast_update_use_count();
					}
					/* XXX This should probably be justified better XXX */
				}  else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->callerid)) {
					/* It's not a valid extension, give a busy signal */
					if (option_debug)
						ast_log(LOG_DEBUG, "%s can't match anything in %s or default\n", i->ext, i->context);
					ioctl(i->fd, PHONE_BUSY);
					i->cpt = 1;
				}
			}
#if 0
			ast_verbose("Extension is %s\n", i->ext);
#endif
		}
	}
	if (phonee.bits.hookstate) {
		offhook = ioctl(i->fd, PHONE_HOOKSTATE);
		if (offhook) {
			if (i->mode == MODE_IMMEDIATE) {
				phone_new(i, AST_STATE_RING, i->context);
			} else if (i->mode == MODE_DIALTONE) {
				ast_mutex_lock(&usecnt_lock);
				usecnt++;
				ast_mutex_unlock(&usecnt_lock);
				ast_update_use_count();
				/* Reset the extension */
				i->ext[0] = '\0';
				/* Play the dialtone */
				i->dialtone++;
				ioctl(i->fd, PHONE_PLAY_STOP);
				ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
				ioctl(i->fd, PHONE_PLAY_START);
				i->lastformat = -1;
			}
		} else {
			if (i->dialtone) {
				ast_mutex_lock(&usecnt_lock);
				usecnt--;
				ast_mutex_unlock(&usecnt_lock);
				ast_update_use_count();
			}
			memset(i->ext, 0, sizeof(i->ext));
			if (i->cpt)
			{
				ioctl(i->fd, PHONE_CPT_STOP);
				i->cpt = 0;
			}
			ioctl(i->fd, PHONE_PLAY_STOP);
			ioctl(i->fd, PHONE_REC_STOP);
			i->dialtone = 0;
			i->lastformat = -1;
		}
	}
	if (phonee.bits.pstn_ring) {
		ast_verbose("Unit is ringing\n");
		phone_new(i, AST_STATE_RING, i->context);
	}
	if (phonee.bits.caller_id)
		ast_verbose("We have caller ID\n");
	
	
}
Exemplo n.º 25
0
static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	char prefix[MAX_DB_FIELD];
	int counter = 0;
	sqlite3_stmt *stmt = gettree_stmt;

	switch (cmd) {
	case CLI_INIT:
		e->command = "database show";
		e->usage =
			"Usage: database show [family [keytree]]\n"
			"   OR: database show [family[/keytree]]\n"
			"       Shows Asterisk database contents, optionally restricted\n"
			"       to a given family, or family and keytree. The two arguments\n"
			"       may be separated either by a space or by a slash.\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if (a->argc == 4) {
		/* Family and key tree */
		snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
	} else if (a->argc == 3) {
		/* Family only */
		snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
	} else if (a->argc == 2) {
		/* Neither */
		prefix[0] = '\0';
		stmt = gettree_all_stmt;

	} else {
		return CLI_SHOWUSAGE;
	}

	ast_mutex_lock(&dblock);
	if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
		ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
		sqlite3_reset(stmt);
		ast_mutex_unlock(&dblock);
		return NULL;
	}

	while (sqlite3_step(stmt) == SQLITE_ROW) {
		const char *key_s, *value_s;
		if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
			ast_log(LOG_WARNING, "Skipping invalid key!\n");
			continue;
		}
		if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
			ast_log(LOG_WARNING, "Skipping invalid value!\n");
			continue;
		}
		++counter;
		ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
	}

	sqlite3_reset(stmt);
	ast_mutex_unlock(&dblock);

	ast_cli(a->fd, "%d results found.\n", counter);
	return CLI_SUCCESS;
}
Exemplo n.º 26
0
static void *do_monitor(void *data)
{
	fd_set rfds, efds;
	int n, res;
	struct phone_pvt *i;
	int tonepos = 0;
	/* The tone we're playing this round */
	struct timeval tv = {0,0};
	int dotone;
	/* This thread monitors all the frame relay interfaces which are not yet in use
	   (and thus do not have a separate thread) indefinitely */
	/* From here on out, we die whenever asked */
	if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
		ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
		return NULL;
	}
	for(;;) {
		/* Don't let anybody kill us right away.  Nobody should lock the interface list
		   and wait for the monitor list, but the other way around is okay. */
		if (ast_mutex_lock(&monlock)) {
			ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
			return NULL;
		}
		/* Lock the interface list */
		if (ast_mutex_lock(&iflock)) {
			ast_log(LOG_ERROR, "Unable to grab interface lock\n");
			ast_mutex_unlock(&monlock);
			return NULL;
		}
		/* Build the stuff we're going to select on, that is the socket of every
		   phone_pvt that does not have an associated owner channel */
		n = -1;
		FD_ZERO(&rfds);
		FD_ZERO(&efds);
		i = iflist;
		dotone = 0;
		while(i) {
			if (FD_ISSET(i->fd, &rfds)) 
				ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
			if (!i->owner) {
				/* This needs to be watched, as it lacks an owner */
				FD_SET(i->fd, &rfds);
				FD_SET(i->fd, &efds);
				if (i->fd > n)
					n = i->fd;
				if (i->dialtone) {
					/* Remember we're going to have to come back and play
					   more dialtones */
					if (!tv.tv_usec && !tv.tv_sec) {
						/* If we're due for a dialtone, play one */
						if (write(i->fd, DialTone + tonepos, 240) != 240)
							ast_log(LOG_WARNING, "Dial tone write error\n");
					}
					dotone++;
				}
			}
			
			i = i->next;
		}
		/* Okay, now that we know what to do, release the interface lock */
		ast_mutex_unlock(&iflock);
		
		/* And from now on, we're okay to be killed, so release the monitor lock as well */
		ast_mutex_unlock(&monlock);
		/* Wait indefinitely for something to happen */
		if (dotone) {
			/* If we're ready to recycle the time, set it to 30 ms */
			tonepos += 240;
			if (tonepos >= sizeof(DialTone))
					tonepos = 0;
			if (!tv.tv_usec && !tv.tv_sec) {
				tv.tv_usec = 30000;
				tv.tv_sec = 0;
			}
			res = ast_select(n + 1, &rfds, NULL, &efds, &tv);
		} else {
			res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
			tv.tv_usec = 0;
			tv.tv_sec = 0;
			tonepos = 0;
		}
		/* Okay, select has finished.  Let's see what happened.  */
		if (res < 0) {
			ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
			continue;
		}
		/* If there are no fd's changed, just continue, it's probably time
		   to play some more dialtones */
		if (!res)
			continue;
		/* Alright, lock the interface list again, and let's look and see what has
		   happened */
		if (ast_mutex_lock(&iflock)) {
			ast_log(LOG_WARNING, "Unable to lock the interface list\n");
			continue;
		}
		i = iflist;
		while(i) {
			if (FD_ISSET(i->fd, &rfds)) {
				if (i->owner) {
					ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->fd, i->dev);
					continue;
				}
				phone_mini_packet(i);
			}
			if (FD_ISSET(i->fd, &efds)) {
				if (i->owner) {
					ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->fd, i->dev);
					continue;
				}
				phone_check_exception(i);
			}
			i=i->next;
		}
		ast_mutex_unlock(&iflock);
	}
	/* Never reached */
	return NULL;
	
}
Exemplo n.º 27
0
static int roomQuery(struct userkeyin dtmfinput, struct roomdetails *dtmfmatch)
{
	int rows = 0, res = 0, retries = 5;
	char sqlcmd[2048]="";
	char currenttime[128]="";
	char eatime[128]="";
	struct tm *l_time;
	time_t now;
	MYSQL_RES *result;
	MYSQL_ROW data;


	memset(sqlcmd,0,2048);

db_reconnect:
	if ((!connected) && (hostname || dbsock) && dbuser && password && dbname) {
		ast_mutex_lock(&handle.lock);		
		mysql_init(&handle.mysql);
		if (mysql_real_connect(&handle.mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) {
			connected = 1;
			connect_time = time(NULL);
			records = 0;
		} else {
			ast_log(LOG_ERROR, "CBMySQL: cannot connect to database server %s/%s/%s/%s\n", hostname, dbname, dbuser, password);
		}
		ast_mutex_unlock(&handle.lock);		
	} else {
		int error;
		if ((error = mysql_ping(&handle.mysql))) {
			connected = 0;
			records = 0;
			switch (error) {
				case CR_SERVER_GONE_ERROR:
					ast_log(LOG_ERROR, "CBMySQL: server got error\n");
					break;
				default:
					ast_log(LOG_ERROR, "CBMySQL: Unknown connection error\n");
			}
		}
	}

	retries--;
	if (retries && !connected){
		usleep(20000);
		goto db_reconnect;
	}

	if (!connected) {
		ast_log(LOG_ERROR, "CBMySQL:  Retried connecting to the database five times, giving up.\n");
		return 0;
		
	} else {
   		time(&now);
   		
		l_time = localtime(&now);	
   	    	strftime(currenttime, sizeof(currenttime), DATE_FORMAT, l_time);


		sprintf(sqlcmd,"SELECT b.roomNo,b.roomPass,b.maxUser,b.status,b.silPass,b.aFlags,b.uFlags,b.bookId,b.startTime FROM %s b WHERE b.roomNo = '%s' AND b.status = 'A' AND b.startTime <= '%s' AND (b.endTime >= '%s' OR b.endTime = '0000-00-00 00:00:00')", table, dtmfinput.inroom, currenttime, currenttime);
		ast_mutex_lock(&handle.lock);
		mysql_real_query(&handle.mysql,sqlcmd,strlen(sqlcmd));    
		result = mysql_store_result(&handle.mysql);
		ast_mutex_unlock(&handle.lock);
		if ( result != NULL ){
			data = mysql_fetch_row(result);
			rows = mysql_num_rows(result);
			if (rows == 1){
				strcpy(dtmfmatch->roomno, data[0]);
				strcpy(dtmfmatch->roompass, data[1]);
				strcpy(dtmfmatch->maxusers, data[2]);
				strcpy(dtmfmatch->status, data[3]);
				strcpy(dtmfmatch->silpass, data[4]);
				strcpy(dtmfmatch->aFlags, data[5]);
				strcpy(dtmfmatch->uFlags, data[6]);
				strcpy(dtmfmatch->bookid, data[7]);
				if ( strlen(dtmfmatch->roompass) ==0 && strlen(dtmfmatch->silpass) ==0){
					res = 2;
				}
				else 
				{
					res =  1;
				}

				mysql_free_result(result);
				return res;
			}
		}
		else 
		{
			ast_log(LOG_ERROR,"CBMySQL: MySQL Error response: %s\n", mysql_error(&handle.mysql));
			return  0;
		}
				
		if (fuzzystart){
			now += fuzzystart;
			l_time = localtime(&now);	
   	    		strftime(currenttime, sizeof(currenttime), DATE_FORMAT, l_time);
		}


		sprintf(sqlcmd,"SELECT b.roomNo,b.roomPass,b.maxUser,b.status,b.silPass,b.aFlags,b.uFlags,b.bookId,b.startTime FROM %s b WHERE b.roomNo = '%s' AND b.status = 'A' AND b.startTime <= '%s' AND (b.endTime >= '%s' OR b.endTime = '0000-00-00 00:00:00')", table, dtmfinput.inroom, currenttime, currenttime);
		ast_mutex_lock(&handle.lock);
 		mysql_real_query(&handle.mysql,sqlcmd,strlen(sqlcmd));    
  		result = mysql_store_result(&handle.mysql);
		ast_mutex_unlock(&handle.lock);
		if ( result != NULL ){
 			data = mysql_fetch_row(result);
			rows = mysql_num_rows(result);
			if (rows == 1){
				strcpy(dtmfmatch->roomno, data[0]);
				strcpy(dtmfmatch->roompass, data[1]);
				strcpy(dtmfmatch->maxusers, data[2]);
				strcpy(dtmfmatch->status, data[3]);
				strcpy(dtmfmatch->silpass, data[4]);
				strcpy(dtmfmatch->aFlags, data[5]);
				strcpy(dtmfmatch->uFlags, data[6]);
				strcpy(dtmfmatch->bookid, data[7]);
				if ( strlen(dtmfmatch->roompass) ==0 && strlen(dtmfmatch->silpass) ==0){
					res = 2;
				}
				else 
				{
					res =  1;
				}

				mysql_free_result(result);
				return res;
			}
		}
		else
		{
			ast_log(LOG_ERROR,"CBMySQL: MySQL Error response: %s\n", mysql_error(&handle.mysql));
			return 0;
		}

		if (earlyalert){
			now += earlyalert;
			l_time = localtime(&now);	
   	    		strftime(currenttime, sizeof(currenttime), DATE_FORMAT, l_time);
		}

		sprintf(sqlcmd,"SELECT b.roomNo,b.roomPass,b.maxUser,b.status,b.silPass,b.aFlags,b.uFlags,b.bookId,b.startTime FROM %s b WHERE b.roomNo = '%s' AND b.status = 'A' AND b.startTime <= '%s' AND (b.endTime >= '%s' OR b.endTime = '0000-00-00 00:00:00')", table, dtmfinput.inroom, currenttime, currenttime);
		ast_mutex_lock(&handle.lock);
 		mysql_real_query(&handle.mysql,sqlcmd,strlen(sqlcmd));    
  		result = mysql_store_result(&handle.mysql);
		ast_mutex_unlock(&handle.lock);
		if ( result != NULL ){
 			data = mysql_fetch_row(result);
			rows = mysql_num_rows(result);
			if (rows == 1){
				ast_log(LOG_NOTICE,"CBMySQL: Caller attempted to join a conference that has not started.\n");
				mysql_free_result(result);
				return -2;
			}
		}
		else
		{
			ast_log(LOG_ERROR,"CBMySQL: MySQL Error response: %s\n", mysql_error(&handle.mysql));
			return 0;
		}
	}
	return 0;
}	
Exemplo n.º 28
0
static char *handle_memory_show_allocations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	const char *fn = NULL;
	struct ast_region *reg;
	unsigned int idx;
	unsigned int whales_len;
	unsigned int minnows_len;
	unsigned int total_len = 0;
	unsigned int selected_len = 0;
	unsigned int cache_len = 0;
	unsigned int count = 0;

	switch (cmd) {
	case CLI_INIT:
		e->command = "memory show allocations";
		e->usage =
			"Usage: memory show allocations [<file>|anomalies]\n"
			"       Dumps a list of segments of allocated memory.\n"
			"       Defaults to listing all memory allocations.\n"
			"       <file> - Restricts output to memory allocated by the file.\n"
			"       anomalies - Only check for fence violations.\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if (a->argc == 4) {
		fn = a->argv[3];
	} else if (a->argc != 3) {
		return CLI_SHOWUSAGE;
	}

	/* Look for historical misspelled option as well. */
	if (fn && (!strcasecmp(fn, "anomalies") || !strcasecmp(fn, "anomolies"))) {
		regions_check_all_fences();
		ast_cli(a->fd, "Anomaly check complete.\n");
		return CLI_SUCCESS;
	}

	ast_mutex_lock(&reglock);
	for (idx = 0; idx < ARRAY_LEN(regions); ++idx) {
		for (reg = regions[idx]; reg; reg = AST_LIST_NEXT(reg, node)) {
			total_len += reg->len;
			if (fn && strcasecmp(fn, reg->file)) {
				continue;
			}

			region_check_fences(reg);

			ast_cli(a->fd, "%10u bytes allocated%s by %20s() line %5u of %s\n",
				(unsigned int) reg->len, reg->cache ? " (cache)" : "",
				reg->func, reg->lineno, reg->file);

			selected_len += reg->len;
			if (reg->cache) {
				cache_len += reg->len;
			}
			++count;
		}
	}

	whales_len = freed_regions_size(&whales);
	minnows_len = freed_regions_size(&minnows);
	ast_mutex_unlock(&reglock);

	print_memory_show_common_stats(a->fd,
		whales_len, minnows_len, total_len,
		selected_len, cache_len, count);

	return CLI_SUCCESS;
}
Exemplo n.º 29
0
/*! \brief SpeechBackground(Sound File|Timeout) Dialplan Application */
static int speech_background(struct ast_channel *chan, void *data)
{
        unsigned int timeout = 0;
        int res = 0, done = 0, argc = 0, started = 0, quieted = 0, max_dtmf_len = 0;
        struct ast_module_user *u = NULL;
        struct ast_speech *speech = find_speech(chan);
        struct ast_frame *f = NULL;
        int oldreadformat = AST_FORMAT_SLINEAR;
        char dtmf[AST_MAX_EXTENSION] = "";
        time_t start, current;
        struct ast_datastore *datastore = NULL;
        char *argv[2], *args = NULL, *filename_tmp = NULL, *filename = NULL, tmp[2] = "", dtmf_terminator = '#';
	const char *tmp2 = NULL;

        args = ast_strdupa(data);

        u = ast_module_user_add(chan);

        if (speech == NULL) {
                ast_module_user_remove(u);
                return -1;
        }

	/* If channel is not already answered, then answer it */
	if (chan->_state != AST_STATE_UP && ast_answer(chan)) {
		ast_module_user_remove(u);
		return -1;
	}

        /* Record old read format */
        oldreadformat = chan->readformat;

        /* Change read format to be signed linear */
        if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
                ast_module_user_remove(u);
                return -1;
        }

        /* Parse out options */
        argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
        if (argc > 0) {
                /* Yay sound file */
                filename_tmp = ast_strdupa(argv[0]);
		if (!ast_strlen_zero(argv[1])) {
			if ((timeout = atoi(argv[1])) == 0)
				timeout = -1;
		} else
			timeout = 0;
        }

	/* See if the maximum DTMF length variable is set... we use a variable in case they want to carry it through their entire dialplan */
	if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_MAXLEN")) && !ast_strlen_zero(tmp2))
		max_dtmf_len = atoi(tmp2);

	/* See if a terminator is specified */
	if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_TERMINATOR"))) {
		if (ast_strlen_zero(tmp2))
			dtmf_terminator = '\0';
		else
			dtmf_terminator = tmp2[0];
	}

        /* Before we go into waiting for stuff... make sure the structure is ready, if not - start it again */
        if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
		ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
                ast_speech_start(speech);
        }

	/* Ensure no streams are currently running */
	ast_stopstream(chan);

        /* Okay it's streaming so go into a loop grabbing frames! */
        while (done == 0) {
		/* If the filename is null and stream is not running, start up a new sound file */
		if (!quieted && (chan->streamid == -1 && chan->timingfunc == NULL) && (filename = strsep(&filename_tmp, "&"))) {
			/* Discard old stream information */
			ast_stopstream(chan);
			/* Start new stream */
			speech_streamfile(chan, filename, chan->language);
		}

                /* Run scheduled stuff */
                ast_sched_runq(chan->sched);

                /* Yay scheduling */
                res = ast_sched_wait(chan->sched);
                if (res < 0) {
                        res = 1000;
                }

                /* If there is a frame waiting, get it - if not - oh well */
                if (ast_waitfor(chan, res) > 0) {
                        f = ast_read(chan);
                        if (f == NULL) {
                                /* The channel has hung up most likely */
                                done = 3;
                                break;
                        }
                }

		/* Do timeout check (shared between audio/dtmf) */
		if ((!quieted || strlen(dtmf)) && started == 1) {
			time(&current);
			if ((current-start) >= timeout) {
				done = 1;
				if (f)
					ast_frfree(f);
				break;
			}
		}

                /* Do checks on speech structure to see if it's changed */
                ast_mutex_lock(&speech->lock);
                if (ast_test_flag(speech, AST_SPEECH_QUIET)) {
			if (chan->stream)
				ast_stopstream(chan);
			ast_clear_flag(speech, AST_SPEECH_QUIET);
			quieted = 1;
                }
                /* Check state so we can see what to do */
                switch (speech->state) {
                case AST_SPEECH_STATE_READY:
                        /* If audio playback has stopped do a check for timeout purposes */
                        if (chan->streamid == -1 && chan->timingfunc == NULL)
                                ast_stopstream(chan);
                        if (!quieted && chan->stream == NULL && timeout && started == 0 && !filename_tmp) {
				if (timeout == -1) {
					done = 1;
					if (f)
						ast_frfree(f);
					break;
				}
				time(&start);
				started = 1;
                        }
                        /* Write audio frame out to speech engine if no DTMF has been received */
                        if (!strlen(dtmf) && f != NULL && f->frametype == AST_FRAME_VOICE) {
                                ast_speech_write(speech, f->data, f->datalen);
                        }
                        break;
                case AST_SPEECH_STATE_WAIT:
                        /* Cue up waiting sound if not already playing */
			if (!strlen(dtmf)) {
				if (chan->stream == NULL) {
					if (speech->processing_sound != NULL) {
						if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
							speech_streamfile(chan, speech->processing_sound, chan->language);
						}
					}
				} else if (chan->streamid == -1 && chan->timingfunc == NULL) {
					ast_stopstream(chan);
					if (speech->processing_sound != NULL) {
						if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
							speech_streamfile(chan, speech->processing_sound, chan->language);
						}
					}
				}
			}
                        break;
                case AST_SPEECH_STATE_DONE:
			/* Now that we are done... let's switch back to not ready state */
			ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
			if (!strlen(dtmf)) {
				/* Copy to speech structure the results, if available */
				speech->results = ast_speech_results_get(speech);
				/* Break out of our background too */
				done = 1;
				/* Stop audio playback */
				if (chan->stream != NULL) {
					ast_stopstream(chan);
				}
			}
                        break;
                default:
                        break;
                }
                ast_mutex_unlock(&speech->lock);

                /* Deal with other frame types */
                if (f != NULL) {
                        /* Free the frame we received */
                        switch (f->frametype) {
                        case AST_FRAME_DTMF:
				if (dtmf_terminator != '\0' && f->subclass == dtmf_terminator) {
					done = 1;
				} else {
					if (chan->stream != NULL) {
						ast_stopstream(chan);
					}
					if (!started) {
						/* Change timeout to be 5 seconds for DTMF input */
						timeout = (chan->pbx && chan->pbx->dtimeout) ? chan->pbx->dtimeout : 5;
						started = 1;
					}
					time(&start);
					snprintf(tmp, sizeof(tmp), "%c", f->subclass);
					strncat(dtmf, tmp, sizeof(dtmf) - strlen(dtmf) - 1);
					/* If the maximum length of the DTMF has been reached, stop now */
					if (max_dtmf_len && strlen(dtmf) == max_dtmf_len)
						done = 1;
				}
                                break;
                        case AST_FRAME_CONTROL:
                                switch (f->subclass) {
                                case AST_CONTROL_HANGUP:
                                        /* Since they hung up we should destroy the speech structure */
                                        done = 3;
                                default:
                                        break;
                                }
                        default:
                                break;
                        }
                        ast_frfree(f);
                        f = NULL;
                }
        }

	if (strlen(dtmf)) {
		/* We sort of make a results entry */
		speech->results = ast_calloc(1, sizeof(*speech->results));
		if (speech->results != NULL) {
			ast_speech_dtmf(speech, dtmf);
			speech->results->score = 1000;
			speech->results->text = strdup(dtmf);
			speech->results->grammar = strdup("dtmf");
		}
		ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
	}

        /* See if it was because they hung up */
        if (done == 3) {
                /* Destroy speech structure */
                ast_speech_destroy(speech);
                datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
                if (datastore != NULL) {
                        ast_channel_datastore_remove(chan, datastore);
                }
        } else {
                /* Channel is okay so restore read format */
                ast_set_read_format(chan, oldreadformat);
        }

        ast_module_user_remove(u);

        return 0;
}
Exemplo n.º 30
0
static struct ast_config *config_pgsql(const char *database, const char *table,
					   const char *file, struct ast_config *cfg,
					   int withcomments)
{
	PGresult *result = NULL;
	long num_rows;
	struct ast_variable *new_v;
	struct ast_category *cur_cat = NULL;
	char sqlbuf[1024] = "";
	char *sql = sqlbuf;
	size_t sqlleft = sizeof(sqlbuf);
	char last[80] = "";
	int last_cat_metric = 0;

	last[0] = '\0';

	if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) {
		ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n");
		return NULL;
	}

	ast_build_string(&sql, &sqlleft, "SELECT category, var_name, var_val, cat_metric FROM %s ", table);
	ast_build_string(&sql, &sqlleft, "WHERE filename='%s' and commented=0", file);
	ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");

	ast_log(LOG_DEBUG, "Postgresql RealTime: Static SQL: %s\n", sqlbuf);

	/* We now have our complete statement; Lets connect to the server and execute it. */
	ast_mutex_lock(&pgsql_lock);
	if (!pgsql_reconnect(database)) {
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	}

	if (!(result = PQexec(pgsqlConn, sqlbuf))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
				PQerrorMessage(pgsqlConn));
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	} else {
		ExecStatusType result_status = PQresultStatus(result);
		if (result_status != PGRES_COMMAND_OK
			&& result_status != PGRES_TUPLES_OK
			&& result_status != PGRES_NONFATAL_ERROR) {
			ast_log(LOG_WARNING,
					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
					PQresultErrorMessage(result), PQresStatus(result_status));
			ast_mutex_unlock(&pgsql_lock);
			return NULL;
		}
	}

	if ((num_rows = PQntuples(result)) > 0) {
		int rowIndex = 0;

		ast_log(LOG_DEBUG, "Postgresql RealTime: Found %ld rows.\n", num_rows);

		for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
			char *field_category = PQgetvalue(result, rowIndex, 0);
			char *field_var_name = PQgetvalue(result, rowIndex, 1);
			char *field_var_val = PQgetvalue(result, rowIndex, 2);
			char *field_cat_metric = PQgetvalue(result, rowIndex, 3);
			if (!strcmp(field_var_name, "#include")) {
				if (!ast_config_internal_load(field_var_val, cfg, 0)) {
					PQclear(result);
					ast_mutex_unlock(&pgsql_lock);
					return NULL;
				}
				continue;
			}

			if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) {
				cur_cat = ast_category_new(field_category);
				if (!cur_cat)
					break;
				strcpy(last, field_category);
				last_cat_metric = atoi(field_cat_metric);
				ast_category_append(cfg, cur_cat);
			}
			new_v = ast_variable_new(field_var_name, field_var_val);
			ast_variable_append(cur_cat, new_v);
		}
	} else {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Could not find config '%s' in database.\n", file);
	}

	PQclear(result);
	ast_mutex_unlock(&pgsql_lock);

	return cfg;
}