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

📄 chan_misdn.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	switch (bc->AOCDtype) {	case Fac_AOCDCurrency:		pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");		if (bc->AOCD.currency.chargeNotAvailable)			pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");		else {			pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");			if (bc->AOCD.currency.freeOfCharge)				pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");			else {				pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");				if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {					pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);					if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf))						pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);				}			}		}		break;	case Fac_AOCDChargingUnit:		pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");		if (bc->AOCD.chargingUnit.chargeNotAvailable)			pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");		else {			pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");			if (bc->AOCD.chargingUnit.freeOfCharge)				pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");			else {				pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");				if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {					pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);					if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf))						pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);				}			}		}		break;	default:		break;	}}/*************** Helpers END *************/static void sighandler(int sig){}static void* misdn_tasks_thread_func (void *data){	int wait;	struct sigaction sa;	sa.sa_handler = sighandler;	sa.sa_flags = SA_NODEFER;	sigemptyset(&sa.sa_mask);	sigaddset(&sa.sa_mask, SIGUSR1);	sigaction(SIGUSR1, &sa, NULL);		sem_post((sem_t *)data);	while (1) {		wait = ast_sched_wait(misdn_tasks);		if (wait < 0)			wait = 8000;		if (poll(NULL, 0, wait) < 0)			chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");		ast_sched_runq(misdn_tasks);	}	return NULL;}static void misdn_tasks_init (void){	sem_t blocker;	int i = 5;	if (sem_init(&blocker, 0, 0)) {		perror("chan_misdn: Failed to initialize semaphore!");		exit(1);	}	chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");		misdn_tasks = sched_context_create();	pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);	while (sem_wait(&blocker) && --i);	sem_destroy(&blocker);}static void misdn_tasks_destroy (void){	if (misdn_tasks) {		chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");		if ( pthread_cancel(misdn_tasks_thread) == 0 ) {			cb_log(4, 0, "Joining misdn_tasks thread\n");			pthread_join(misdn_tasks_thread, NULL);		}		sched_context_destroy(misdn_tasks);	}}static inline void misdn_tasks_wakeup (void){	pthread_kill(misdn_tasks_thread, SIGUSR1);}static inline int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable){	int task_id;	if (!misdn_tasks) {		misdn_tasks_init();	}	task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);	misdn_tasks_wakeup();	return task_id;}static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data){	return _misdn_tasks_add_variable(timeout, callback, data, 0);}static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data){	return _misdn_tasks_add_variable(timeout, callback, data, 1);}static void misdn_tasks_remove (int task_id){	AST_SCHED_DEL(misdn_tasks, task_id);}static int misdn_l1_task (const void *data){	misdn_lib_isdn_l1watcher(*(int *)data);	chan_misdn_log(5, *(int *)data, "L1watcher timeout\n");	return 1;}static int misdn_overlap_dial_task (const void *data){	struct timeval tv_end, tv_now;	int diff;	struct chan_list *ch = (struct chan_list *)data;	chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);	if (ch->state != MISDN_WAITING4DIGS) {		ch->overlap_dial_task = -1;		return 0;	}		ast_mutex_lock(&ch->overlap_tv_lock);	tv_end = ch->overlap_tv;	ast_mutex_unlock(&ch->overlap_tv_lock);		tv_end.tv_sec += ch->overlap_dial;	tv_now = ast_tvnow();	diff = ast_tvdiff_ms(tv_end, tv_now);	if (diff <= 100) {		char *dad=ch->bc->dad, sexten[]="s";		/* if we are 100ms near the timeout, we are satisfied.. */		stop_indicate(ch);				if (ast_strlen_zero(ch->bc->dad)) {			dad=sexten;			strcpy(ch->ast->exten, sexten);		}		if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {			ch->state=MISDN_DIALING;			if (pbx_start_chan(ch) < 0) {				chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");				goto misdn_overlap_dial_task_disconnect;			}		} else {misdn_overlap_dial_task_disconnect:			hanguptone_indicate(ch);			ch->bc->out_cause=1;			ch->state=MISDN_CLEANING;			misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);		}		ch->overlap_dial_task = -1;		return 0;	} else		return diff;}static void send_digit_to_chan(struct chan_list *cl, char digit ){	static const char* dtmf_tones[] = {		"!941+1336/100,!0/100",	/* 0 */		"!697+1209/100,!0/100",	/* 1 */		"!697+1336/100,!0/100",	/* 2 */		"!697+1477/100,!0/100",	/* 3 */		"!770+1209/100,!0/100",	/* 4 */		"!770+1336/100,!0/100",	/* 5 */		"!770+1477/100,!0/100",	/* 6 */		"!852+1209/100,!0/100",	/* 7 */		"!852+1336/100,!0/100",	/* 8 */		"!852+1477/100,!0/100",	/* 9 */		"!697+1633/100,!0/100",	/* A */		"!770+1633/100,!0/100",	/* B */		"!852+1633/100,!0/100",	/* C */		"!941+1633/100,!0/100",	/* D */		"!941+1209/100,!0/100",	/* * */		"!941+1477/100,!0/100" };	/* # */	struct ast_channel *chan=cl->ast;   	if (digit >= '0' && digit <='9')		ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);	else if (digit >= 'A' && digit <= 'D')		ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);	else if (digit == '*')		ast_playtones_start(chan,0,dtmf_tones[14], 0);	else if (digit == '#')		ast_playtones_start(chan,0,dtmf_tones[15], 0);	else {		/* not handled */		ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);        	}}/*** CLI HANDLING ***/static int misdn_set_debug(int fd, int argc, char *argv[]){	int level;	if (argc != 4 && argc != 5 && argc != 6 && argc != 7)		return RESULT_SHOWUSAGE; 	level = atoi(argv[3]);	switch (argc) {		case 4:			case 5: {					int i;					int only = 0;					if (argc == 5) {						if (strncasecmp(argv[4], "only", strlen(argv[4])))							return RESULT_SHOWUSAGE;						else							only = 1;					}					for (i=0; i<=max_ports; i++) {						misdn_debug[i] = level;						misdn_debug_only[i] = only;					}					ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");				}				break;		case 6: 		case 7: {					int port;					if (strncasecmp(argv[4], "port", strlen(argv[4])))						return RESULT_SHOWUSAGE;					port = atoi(argv[5]);					if (port <= 0 || port > max_ports) {						switch (max_ports) {							case 0:								ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");								break;							case 1:								ast_cli(fd, "port number not valid! only port 1 is available.\n");								break;							default:								ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);							}							return 0;					}					if (argc == 7) {						if (strncasecmp(argv[6], "only", strlen(argv[6])))							return RESULT_SHOWUSAGE;						else							misdn_debug_only[port] = 1;					} else						misdn_debug_only[port] = 0;					misdn_debug[port] = level;					ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);				}	}	return 0;}static int misdn_set_crypt_debug(int fd, int argc, char *argv[]){	if (argc != 5) return RESULT_SHOWUSAGE; 	return 0;}static int misdn_port_block(int fd, int argc, char *argv[]){	int port;	if (argc != 4)		return RESULT_SHOWUSAGE;  	port = atoi(argv[3]);	misdn_lib_port_block(port);	return 0;}static int misdn_port_unblock(int fd, int argc, char *argv[]){	int port;  	if (argc != 4)		return RESULT_SHOWUSAGE;  	port = atoi(argv[3]);	misdn_lib_port_unblock(port);	return 0;}static int misdn_restart_port (int fd, int argc, char *argv[]){	int port;  	if (argc != 4)		return RESULT_SHOWUSAGE;  	port = atoi(argv[3]);	misdn_lib_port_restart(port);	return 0;}static int misdn_restart_pid (int fd, int argc, char *argv[]){	int pid;  	if (argc != 4)		return RESULT_SHOWUSAGE;  	pid = atoi(argv[3]);	misdn_lib_pid_restart(pid);	return 0;}static int misdn_port_up (int fd, int argc, char *argv[]){	int port;		if (argc != 4)		return RESULT_SHOWUSAGE;		port = atoi(argv[3]);		misdn_lib_get_port_up(port);  	return 0;}static int misdn_port_down (int fd, int argc, char *argv[]){	int port;	if (argc != 4)		return RESULT_SHOWUSAGE;		port = atoi(argv[3]);		misdn_lib_get_port_down(port);  	return 0;}static inline void show_config_description (int fd, enum misdn_cfg_elements elem){	char section[BUFFERSIZE];	char name[BUFFERSIZE];	char desc[BUFFERSIZE];	char def[BUFFERSIZE];	char tmp[BUFFERSIZE];	misdn_cfg_get_name(elem, tmp, sizeof(tmp));	term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));	misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));	if (elem < MISDN_CFG_LAST)		term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));	else		term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));	if (*def)		ast_cli(fd, "[%s] %s   (Default: %s)\n\t%s\n", section, name, def, desc);	else		ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);}static int misdn_show_config (int fd, int argc, char *argv[]){	char buffer[BUFFERSIZE];	enum misdn_cfg_elements elem;	int linebreak;	int onlyport = -1;	int ok = 0;	if (argc >= 4) {		if (!strcmp(argv[3], "description")) {			if (argc == 5) {				enum misdn_cfg_elements elem = misdn_cfg_get_elem (argv[4]);				if (elem == MISDN_CFG_FIRST)					ast_cli(fd, "Unknown element: %s\n", argv[4]);				else					show_config_description(fd, elem);				return 0;			}			return RESULT_SHOWUSAGE;		}		if (!strcmp(argv[3], "descriptions")) {			if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) {				for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {					show_config_description(fd, elem);					ast_cli(fd, "\n");				}				ok = 1;			}			if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {				for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {					show_config_description(fd, elem);					ast_cli(fd, "\n");				}				ok = 1;			}			return ok ? 0 : RESULT_SHOWUSAGE;		}		if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {			ast_cli(fd, "Unknown option: %s\n", argv[3]);			return RESULT_SHOWUSAGE;		}	}		if (argc == 3 || onlyport == 0) {		ast_cli(fd,"Misdn General-Config: \n"); 		for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {			misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);			ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");		}		ast_cli(fd, "\n");	}	if (onlyport < 0) {		int port = misdn_cfg_get_next_port(0);		for (; port > 0; port = misdn_cfg_get_next_port(port)) {			ast_cli(fd, "\n[PORT %d]\n", port);			for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {				misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);				ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");			}				ast_cli(fd, "\n");		}	}		if (onlyport > 0) {		if (misdn_cfg_is_port_valid(onlyport)) {			ast_cli(fd, "[PORT %d]\n", onlyport);			for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {				misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE);				ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");			}				ast_cli(fd, "\n");		} else {			ast_cli(fd, "Port %d is not active!\n", onlyport);		}	}	return 0;}struct state_struct {	enum misdn_chan_state state;	char txt[255] ;} ;static struct state_struct state_array[] = {	{MISDN_NOTHING,"NOTHING"}, /* at beginning */	{MISDN_WAITING4DIGS,"WAITING4DIGS"}, /*  when waiting for infos */	{MISDN_EXTCANTMATCH,"EXTCANTMATCH"}, /*  when asterisk couldn't match our ext */	{MISDN_INCOMING_SETUP,"INCOMING SETUP"}, /*  when pbx_start */	{MISDN_DIALING,"DIALING"}, /*  when pbx_start */	{MISDN_PROGRESS,"PROGRESS"}, /*  when pbx_start */	{MISDN_PROCEEDING,"PROCEEDING"}, /*  when pbx_start */	{MISDN_CALLING,"CALLING"}, /*  when misdn_call is called */	{MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"}, /*  when misdn_call is called */	{MISDN_ALERTING,"ALERTING"}, /*  when Alerting */	{MISDN_BUSY,"BUSY"}, /*  when BUSY */	{MISDN_CONNECTED,"CONNECTED"}, /*  when connected */	{MISDN_PRECONNECTED,"PRECONNECTED"}, /*  when connected */	{MISDN_DISCONNECTED,"DISCONNECTED"}, /*  when connected */

⌨️ 快捷键说明

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