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

📄 eagi_proxy.c

📁 asterisk 是一个很有知名度开源软件
💻 C
字号:
/* * Asterisk EAGI -> TCP/IP proxy * 	by Danijel Korzinek (devil_slayer _at_ hotmail.com) * * This simple C application allows you to control asterisk thru one TCP/IP * socket and listen to the conversation thru another socket. * * Great for ASR or wizzard-of-oz telephony systems! * * HOWTO: * 	The program is compiled using the following command: * 		gcc eagi_proxy.c -o eagi_proxy -lpthread * * 	In the dialplan, you can add something like this to the main context: * 		exten => s,1,Answer * 		exten => s,n,EAGI(/path/to/eagi_proxy) * 		exten => s,n,Hangup * * 	To test the program you can use the netcat utility: * 		(http://netcat.sourceforge.net/) * * 		-in one console run: * 			nc -vv -l -p 8418 > /path/to/file.raw * 		-in another run: * 			nc -vv -l -p 8417 * 		-you can use any file for the signal or even /dev/null * 		-you can change the port numbers in the sourcecode below * * 	Once you make the call, both programs will accept the incoming * 	connection. The program on port 8417 will print out the enviornemnt * 	(unless the appropriate define below is commented) and you can write * 	any AGI command there (http://www.voip-info.org/wiki-Asterisk+AGI), * 	e.g.: * 		GET DATA /path/to/gsm/file 10000 4 * * 	Finally, you can open the RAW file in any sound editor. The format is: * 		RAW little-endian 8kHz 16bit */#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <string.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/time.h>#include <arpa/inet.h>#include <netdb.h>#include <fcntl.h>#include <errno.h>#include <ctype.h>#include <pthread.h>/* DEFINES */#define SIGNAL_PORT 8418#define COMMAND_PORT 8417#define SEND_ENVIORNMENT /*send the enviornment thru the socket*//************************/#define BUFSIZE 1024char buf[BUFSIZE];#define WINSIZE 400 /* 25 ms @ 8 kHz and 16bit */char window[WINSIZE];#define WINBUF_NUM 2400 /* number of WINSIZE windows = 1 minute */char* winbuf;char *end, *bs, *be;/* winbuf - start of buffer  * end - end of buffer   * bs - start of data * be - end of data  */int command_desc; /* command transfer descriptor */int speech_desc; /* speech signal descrriptor */char connected=1; /* connection state */int connect_to_host(char* host, int port); /* connect to a given host (name or IP) and given port number in nonblocking mode returning socket descriptor*/void read_full(int file, char* buffer, int num); /* read EXACTLY "num" ammount of bytes from "file" descriptor to "buffer"*/int read_some(int file, char* buffer, int size); /* read AT MOST "size" ammount of bytes */void write_buf(int file, char* buffer, int num); /* write "num" ammount of bytes to "file" descriptor and buffer the surplus if the write would block */int write_amap(int file, char* buffer, int num); /*write AT MOST "num" ammount of bytes and return ammount that was written*/void setnonblocking(int desc); /*sets the socket non-blocking; for polling */void finalize(); /* this function is run at exit */pthread_mutex_t command_mutex;/* command socket mutex */pthread_t stdin_thread,signal_thread;void* readStdin(void* ptr);void* readSignal(void* ptr);/* The program creates 3 threads: * 1) Main thread - reads commands from the socket and sends them to asterisk * 2) stdin_thread - reads asterisk output and sends it to the command socket * 3) signal_thread - reads the sound from asterisk and sends it to the signal socket */int main(){	int ret;		atexit(finalize);	setlinebuf(stdin);	setlinebuf(stdout);	winbuf=(char*)malloc(WINSIZE*WINBUF_NUM);	end=winbuf+WINSIZE*WINBUF_NUM;	bs=be=winbuf;	speech_desc=connect_to_host("localhost",SIGNAL_PORT);	if(speech_desc<0) 	{		perror("signal socket");		return -1;	}	command_desc=connect_to_host("localhost",COMMAND_PORT);	if(command_desc<0) 	{		perror("command socket");		return -1;	}	pthread_mutex_init(&command_mutex,NULL);	pthread_create(&stdin_thread,NULL,readStdin,NULL);	pthread_create(&signal_thread,NULL,readSignal,NULL);	while(connected)	{			pthread_mutex_lock(&command_mutex);		ret=read_some(command_desc,buf,BUFSIZE);		pthread_mutex_unlock(&command_mutex);		if(ret>0)		{			buf[ret]=0;			printf("%s",buf);					}	}	return 0;}void finalize(){	close(command_desc);	close(speech_desc);	free(winbuf);	}void* readStdin(void* ptr){	while(1)/*read enviornment*/	{		fgets(buf,BUFSIZE,stdin);		#ifdef SEND_ENVIORNMENT			pthread_mutex_lock(&command_mutex);			write_buf(command_desc,buf,strlen(buf));			pthread_mutex_unlock(&command_mutex);		#endif		if(feof(stdin) || buf[0]=='\n') 		{			break;		}	}	while(connected)	{		fgets(buf,BUFSIZE,stdin);		pthread_mutex_lock(&command_mutex);		write_buf(command_desc,buf,strlen(buf));		pthread_mutex_unlock(&command_mutex);	}	pthread_exit(NULL);}void* readSignal(void* ptr){	while(connected)	{		read_full(3,window,WINSIZE);		write_buf(speech_desc,window,WINSIZE);	}	pthread_exit(NULL);}void read_full(int file, char* buffer, int num){	int count,pos=0;	while(num)	{		count=read(file,buffer+pos,num);		if(count==0 || (count<0 && errno!=EAGAIN))		{			connected=0;			return;		}		num-=count;		pos+=count;	}}int connect_to_host(char* name, int port){	int address;	struct hostent* host_entity;	int res,desc;	int opts;	struct sockaddr_in host;		/* get adress */		if(!strcmp(name,"localhost"))		address=htonl(2130706433); /*127.0.0.1*/	else	{		address=inet_addr(name); /* check if it's an IP that's written in the string */		if(address==(in_addr_t)-1)		{			host_entity = gethostbyname(name); /* search for the host under this name */				if(!host_entity)			{				fprintf(stderr,"EAGI proxy: Wrong address!\n"); /* can't find anything*/				return -1;			}			address=*((int*)host_entity->h_addr);		}	}	desc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);	if(desc<0)	{		fprintf(stderr,"EAGI proxy: Cannot create socket!\n");		return -1;	}	memset((void*)&host,0,sizeof(struct sockaddr_in));		host.sin_family=AF_INET;	host.sin_port=htons(port);	host.sin_addr.s_addr=address;		res=connect(desc,(struct sockaddr*)&host,sizeof(host));	if(res<0)	{		fprintf(stderr,"EAGI proxy: Cannot connect!\n");		return -1;	}	/* set to non-blocking mode */	opts = fcntl(desc,F_GETFL);	if (opts < 0) {		perror("fcntl(F_GETFL)");		exit(EXIT_FAILURE);	}	opts = (opts | O_NONBLOCK);	if (fcntl(desc,F_SETFL,opts) < 0) {		perror("fcntl(F_SETFL)");		exit(EXIT_FAILURE);	}	return desc;}int read_some(int desc, char* buffer, int size){	unsigned char c;	int res,i=0;	for(;;)	{		res=read(desc,&c,1);		if(res<1)		{			if(errno!=EAGAIN)			{				perror("Error reading");				connected=0;			}				break;		}		if(res==0) 		{			connected=0;			break;		}				buffer[i]=c;		i++;	}	return i;}/* This is a tricky function! */void write_buf(int desc, char* buf, int size){	int ret;	/*NOTE: AMAP -> as much as possible */	if(be!=bs)/* if data left in buffer */	{		if(be>bs)/* if buffer not split */		{			ret=write_amap(desc,bs,be-bs);/* write AMAP */			bs+=ret;/* shift the start of the buffer */		}		else/* if buffer is split */		{			ret=write_amap(desc,bs,end-bs);/* write higher part first */			if(ret==end-bs)/* if wrote whole of the higher part */			{				ret=write_amap(desc,winbuf,be-winbuf);/* write lower part */				bs=winbuf+ret;/* shift start to new position */			}			else bs+=ret;/* if not wrote whole of higher part, only shift start */		}	}	if(be==bs)/* if buffer is empty now */	{		ret=write_amap(desc,buf,size);/* write AMAP of the new data */		buf+=ret;/* shift start of new data */		size-=ret;/* lower size of new data */	}	if(size)/* if new data still remains unsent */	{		if(be>=bs)/* if data not split */		{			if(size>end-be)/* if new data size doesn't fit higher end */			{				size-=end-be;/* reduce new data size by the higher end size */				memcpy(be,buf,end-be);/* copy to higher end */				be=winbuf;/* shift end to begining of buffer */				buf+=end-be;/* shift start of new data */			}			else/* if new data fits the higher end */			{				memcpy(be,buf,size);/* copy to higher end */				be+=size;/* shift end by size */				if(be>=end)/* if end goes beyond the buffer */					be=winbuf;/* restart */				size=0;/* everything copied */			}		}		if(size)/* if new data still remains */		{			if(size>=bs-be)/* if new data doesn't fit between end and start */			{				fprintf(stderr,"Buffer overflow!\n");				size=bs-be-1;/* reduce the size that we can copy */			}			if(size)/* if we can copy anything */			{				memcpy(be,buf,size);/* copy the new data between end and start */				be+=size;/* shift end by size */			}		}	}}int write_amap(int desc, char* buf, int size){	int ret;	ret=write(desc,buf,size);	if(ret<0)	{		if(errno!=EAGAIN) 		{			perror("Error writing");			connected=0;		}		return 0;	}	if(ret==0)		connected=0;	return ret;}void setnonblocking(int desc){	int opts;		opts = fcntl(desc,F_GETFL);	if(opts < 0)	{		perror("fcntl(F_GETFL)");		exit(-1);	}	opts = (opts | O_NONBLOCK );	if(fcntl(desc,F_SETFL,opts) < 0)	{		perror("fcntl(F_SETFL)");		exit(-1);	}}

⌨️ 快捷键说明

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