⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aststubs.c

📁 asterisk 中国七号驱动修改代码可以在ASTERISIK-1。4上编译pa
💻 C
字号:
/* aststubs.c - asterisk stubs * Copyright (C) 2007, Anders Baekgaard * * Author: Anders Baekgaard <ab@dicea.dk> * This work is included with chan_ss7, see copyright below. *//* * This file is part of chan_ss7. * * chan_ss7 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * chan_ss7 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with chan_ss7; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include <stdio.h>#include <stdarg.h>#include <malloc.h>#include <pthread.h>#define AST_API_MODULE#include <asterisk/linkedlists.h>#include <asterisk/time.h>#include <asterisk/options.h>#include <asterisk/utils.h>#include "asterisk/abstract_jb.h"#include "aststubs.h"int option_debug;struct ast_cli_entry;int option_verbose;int option_debug;struct ast_flags ast_options;char ast_config_AST_CONFIG_DIR[PATH_MAX];#undef pthread_mutex_init#undef pthread_mutex_lock#undef pthread_mutex_unlock#undef pthread_mutex_t#undef ast_calloc#define ast_mutex_init(m) pthread_mutex_init(m,0)#define ast_mutex_lock pthread_mutex_lock#define ast_mutex_unlock pthread_mutex_unlock#define ast_mutex_t pthread_mutex_t#define ast_calloc calloc//define DEBUG(x) {if (option_debug) x;}#define DEBUG(x)int ast_safe_system(const char *s);void ast_register_file_version(const char *file, const char *version);void ast_unregister_file_version(const char *file);void ast_cli_register_multiple(struct ast_cli_entry *e, int len);void ast_cli(int fd, char *fmt, ...);int ast_safe_system(const char *s){  return -1;}void ast_register_file_version(const char *file, const char *version){}void ast_unregister_file_version(const char *file){}void ast_cli_register_multiple(struct ast_cli_entry *e, int len){}void ast_cli(int fd, char *fmt, ...){}void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...){  va_list ap;  char *l;  char buff[1024];  if ((level == __LOG_DEBUG) && !option_debug)    return;  switch (level) {  case __LOG_DEBUG: l= "DEBUG"; break;  case __LOG_EVENT: l= "EVENT"; break;  case __LOG_NOTICE: l= "NOTICE"; break;  case __LOG_WARNING: l= "WARNING"; break;  case __LOG_ERROR: l= "ERROR"; break;  default: l = "unknown";  }  sprintf(buff, "[%s] %s:%d %s %s", l, file, line, function, fmt);  va_start(ap, fmt);  vprintf(buff, ap);  fflush(stdout);}void ast_verbose(const char *fmt, ...){  va_list ap;  va_start(ap, fmt);  vprintf(fmt, ap);  fflush(stdout);}#ifndef AST_LIST_INSERT_BEFORE_CURRENT/* Asterisk 1.2.x */#define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do {		\	if (__list_prev) {						\		(elm)->field.next = __list_prev->field.next;		\		__list_prev->field.next = elm;				\	} else {							\		(elm)->field.next = (head)->first;			\		(head)->first = (elm);					\	}								\	__new_prev = (elm);						\} while (0)#endifstruct sched {	AST_LIST_ENTRY(sched) list;	int id;                       /*!< ID number of event */	struct timeval when;          /*!< Absolute time event should take place */	int resched;                  /*!< When to reschedule */	int variable;                 /*!< Use return value from callback to reschedule */	void *data;                   /*!< Data */	ast_sched_cb callback;        /*!< Callback */};struct sched_context {	ast_mutex_t lock;	unsigned int eventcnt;                  /*!< Number of events processed */	unsigned int schedcnt;                  /*!< Number of outstanding schedule events */	AST_LIST_HEAD_NOLOCK(, sched) schedq;   /*!< Schedule entry and main queue */#ifdef SCHED_MAX_CACHE	AST_LIST_HEAD_NOLOCK(, sched) schedc;   /*!< Cache of unused schedule structures and how many */	unsigned int schedccnt;#endif};#define ONE_MILLION	1000000static struct timeval tvfix(struct timeval a){	if (a.tv_usec >= ONE_MILLION) {		ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",			a.tv_sec, (long int) a.tv_usec);		a.tv_sec += a.tv_usec / ONE_MILLION;		a.tv_usec %= ONE_MILLION;	} else if (a.tv_usec < 0) {		ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",			a.tv_sec, (long int) a.tv_usec);		a.tv_usec = 0;	}	return a;}struct timeval ast_tvadd(struct timeval a, struct timeval b){	/* consistency checks to guarantee usec in 0..999999 */	a = tvfix(a);	b = tvfix(b);	a.tv_sec += b.tv_sec;	a.tv_usec += b.tv_usec;	if (a.tv_usec >= ONE_MILLION) {		a.tv_sec++;		a.tv_usec -= ONE_MILLION;	}	return a;}struct sched_context *mtp_sched_context_create(void){	struct sched_context *tmp;	if (!(tmp = ast_calloc(1, sizeof(*tmp))))		return NULL;	ast_mutex_init(&tmp->lock);	tmp->eventcnt = 1;		return tmp;}void mtp_sched_context_destroy(struct sched_context *con){	struct sched *s;	ast_mutex_lock(&con->lock);#ifdef SCHED_MAX_CACHE	/* Eliminate the cache */	while ((s = AST_LIST_REMOVE_HEAD(&con->schedc, list)))		free(s);#endif	/* And the queue */	while ((s = AST_LIST_REMOVE_HEAD(&con->schedq, list)))		free(s);		/* And the context */	ast_mutex_unlock(&con->lock);	ast_mutex_destroy(&con->lock);	free(con);}static struct sched *sched_alloc(struct sched_context *con){	struct sched *tmp;	/*	 * We keep a small cache of schedule entries	 * to minimize the number of necessary malloc()'s	 */#ifdef SCHED_MAX_CACHE	if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list)))		con->schedccnt--;	else#endif		tmp = ast_calloc(1, sizeof(*tmp));	return tmp;}static void sched_release(struct sched_context *con, struct sched *tmp){	/*	 * Add to the cache, or just free() if we	 * already have too many cache entries	 */#ifdef SCHED_MAX_CACHE	 	if (con->schedccnt < SCHED_MAX_CACHE) {		AST_LIST_INSERT_HEAD(&con->schedc, tmp, list);		con->schedccnt++;	} else#endif		free(tmp);}int mtp_sched_wait(struct sched_context *con){	int ms;	DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));	ast_mutex_lock(&con->lock);	if (AST_LIST_EMPTY(&con->schedq)) {		ms = -1;	} else {		ms = ast_tvdiff_ms(AST_LIST_FIRST(&con->schedq)->when, ast_tvnow());		if (ms < 0)			ms = 0;	}	ast_mutex_unlock(&con->lock);	return ms;}static void schedule(struct sched_context *con, struct sched *s){	 	struct sched *cur = NULL;		AST_LIST_TRAVERSE_SAFE_BEGIN(&con->schedq, cur, list) {		if (ast_tvcmp(s->when, cur->when) == -1) {			AST_LIST_INSERT_BEFORE_CURRENT(&con->schedq, s, list);			break;		}	}	AST_LIST_TRAVERSE_SAFE_END	if (!cur)		AST_LIST_INSERT_TAIL(&con->schedq, s, list);		con->schedcnt++;}static int sched_settime(struct timeval *tv, int when){	struct timeval now = ast_tvnow();	/*ast_log(LOG_DEBUG, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/	if (ast_tvzero(*tv))	/* not supplied, default to now */		*tv = now;	*tv = ast_tvadd(*tv, ast_samp2tv(when, 1000));	if (ast_tvcmp(*tv, now) < 0) {		ast_log(LOG_DEBUG, "Request to schedule in the past?!?!\n");		*tv = now;	}	return 0;}static int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable){	struct sched *tmp;	int res = -1;	DEBUG(ast_log(LOG_DEBUG, "ast_sched_add()\n"));	if (!when) {		ast_log(LOG_NOTICE, "Scheduled event in 0 ms?\n");		return -1;	}	ast_mutex_lock(&con->lock);	if ((tmp = sched_alloc(con))) {		tmp->id = con->eventcnt++;		tmp->callback = callback;		tmp->data = data;		tmp->resched = when;		tmp->variable = variable;		tmp->when = ast_tv(0, 0);		if (sched_settime(&tmp->when, when)) {			sched_release(con, tmp);		} else {			schedule(con, tmp);			res = tmp->id;		}	}#ifdef DUMP_SCHEDULER	/* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */	if (option_debug)		ast_sched_dump(con);#endif	ast_mutex_unlock(&con->lock);	return res;}int mtp_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data){	return ast_sched_add_variable(con, when, callback, data, 0);}int mtp_sched_del(struct sched_context *con, int id){	struct sched *s;	DEBUG(ast_log(LOG_DEBUG, "ast_sched_del()\n"));		ast_mutex_lock(&con->lock);	AST_LIST_TRAVERSE_SAFE_BEGIN(&con->schedq, s, list) {		if (s->id == id) {			AST_LIST_REMOVE_CURRENT(&con->schedq, list);			con->schedcnt--;			sched_release(con, s);			break;		}	}	AST_LIST_TRAVERSE_SAFE_END#ifdef DUMP_SCHEDULER	/* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */	if (option_debug)		ast_sched_dump(con);#endif	ast_mutex_unlock(&con->lock);	if (!s) {		if (option_debug)			ast_log(LOG_DEBUG, "Attempted to delete nonexistent schedule entry %d!\n", id);#ifdef DO_CRASH		CRASH;#endif		return -1;	}		return 0;}int mtp_sched_runq(struct sched_context *con){	struct sched *current;	struct timeval tv;	int numevents;	int res;	DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n"));			ast_mutex_lock(&con->lock);	for (numevents = 0; !AST_LIST_EMPTY(&con->schedq); numevents++) {		/* schedule all events which are going to expire within 1ms.		 * We only care about millisecond accuracy anyway, so this will		 * help us get more than one event at one time if they are very		 * close together.		 */		tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));		if (ast_tvcmp(AST_LIST_FIRST(&con->schedq)->when, tv) != -1)			break;				current = AST_LIST_REMOVE_HEAD(&con->schedq, list);		con->schedcnt--;		/*		 * At this point, the schedule queue is still intact.  We		 * have removed the first event and the rest is still there,		 * so it's permissible for the callback to add new events, but		 * trying to delete itself won't work because it isn't in		 * the schedule queue.  If that's what it wants to do, it 		 * should return 0.		 */					ast_mutex_unlock(&con->lock);		res = current->callback(current->data);		ast_mutex_lock(&con->lock);					if (res) {		 	/*			 * If they return non-zero, we should schedule them to be			 * run again.			 */			if (sched_settime(&current->when, current->variable? res : current->resched)) {				sched_release(con, current);			} else				schedule(con, current);		} else {			/* No longer needed, so release it */		 	sched_release(con, current);		}	}	ast_mutex_unlock(&con->lock);		return numevents;}int ast_jb_read_conf(struct ast_jb_conf *conf, char *varname, char *value){  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -