📄 phone.c
字号:
/* This is the phone program, written by David Ashley * dash@xdr.com * http://www.xdr.com/dash * This program is released under the terms of the GPL *//* $Header: /cvs/phone/phone.c,v 1.13 2000/02/02 06:19:20 dash Exp $ */#include "phone.h"#define SERVER "matcher.xdr.com"#define MAXBLOCKS 14char exitflag=0;int talktries=0;long nextsendtalk;long lastdiff,latency;int block160size;int sndin,sndblocksize;unsigned char sndblock1[16384],sndblock2[16384];char username[MAXNAMESIZE];char calling[MAXNAMESIZE];int tryingtocall=0;unsigned char myhash[8];unsigned char mykey[8];int connected=0;int gottalk=0;long incount,outcount;#define WRITEFIFOMAX 64unsigned char *writeput,*writetake,*writelimit;int writein;unsigned char writefifo[1024*WRITEFIFOMAX];int loudcount;unsigned char myip[16];int myiplen;long dspopentime;long totalwritten;long totalread;#define PACKETSTOPACK 5unsigned char packed[32+PACKETSTOPACK*33];int packedin;int havedsp=0;opendsp(){int t;int res;int pid; if(havedsp) return 0; sndin=open("/dev/dsp",O_RDWR); if(sndin<0) return -1;/* t=8; res=ioctl(sndin,SNDCTL_DSP_SAMPLESIZE,&t); if(res) return -2;*/ t=8000; res=ioctl(sndin,SNDCTL_DSP_SPEED,&t); if(res) return -3; t=1; res=ioctl(sndin,SNDCTL_DSP_CHANNELS,&t); if(res) return -4; res=ioctl(sndin,SNDCTL_DSP_GETFMTS,&t); if(!(t&AFMT_S16_LE)) { printf("Digitizing in 8 bit mode\n"); block160size=160; t=AFMT_U8; res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); if(res) return -6; t=0x20008; res=ioctl(sndin,SNDCTL_DSP_SETFRAGMENT,&t); if(res) return -5; } else { printf("Digitizing in 16 bit mode\n"); block160size=160*2; t=AFMT_S16_LE; res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); if(res) return -6; t=0x20009; res=ioctl(sndin,SNDCTL_DSP_SETFRAGMENT,&t); if(res) return -5; }// t=0;res=ioctl(sndin,SNDCTL_DSP_SETFMT,&t); res=ioctl(sndin,SNDCTL_DSP_GETCAPS,&t); if(res) return -7; if(!(t&DSP_CAP_DUPLEX)) { printf("Your soundcard/driver combination isn't allowing full duplex.\n"); printf("That means you can't read from the microphone and write to\n"); printf("the speakers at the same time.\n"); printf("Unfortunately, this program depends on this capability.\n"); return -8; } res=ioctl(sndin,SNDCTL_DSP_GETBLKSIZE,&sndblocksize); if(res) return -9; havedsp=1; read(sndin,sndblock1,sndblocksize); writeput=writetake=writefifo; writelimit=writefifo+WRITEFIFOMAX*sndblocksize; writein=0; packedin=0; dspopentime=gtime2(); totalwritten=0; totalread=0; return 0;}tryopendsp(){int result; if(result=opendsp()) { printf("Failed to open dsp, result code %d\n",result); exit(1); } incount=-1; outcount=0;}closedsp(){ if(havedsp) { close(sndin); havedsp=0; }}int openserver(char *mname,int port){struct hostent *hostptr;int status; hostptr=gethostbyname(mname); if(!hostptr) { hostptr=gethostbyaddr(mname,strlen(mname),AF_INET); if(!hostptr) return 0; } memset(&servername,0,sizeof(servername)); servername.sin_family=AF_INET; servername.sin_port=htons(port); memcpy(&servername.sin_addr,hostptr->h_addr,hostptr->h_length); return 1;}void messagetoserver(unsigned char *m,int len){unsigned char temp[512],*p,*p2;int i; p=temp; *p++=CODE_CRYPT; memcpy(p,myhash,HASHSIZE);p+=HASHSIZE; p2=p; memcpy(p,specialkey,sizeof(specialkey));p+=sizeof(specialkey); memcpy(p,m,len);p+=len; len+=sizeof(specialkey); while(len&7) { *p++=0; ++len; } i=len; while(--i>0) { p2[1]^=*p2; ++p2; } encryptblock(temp+HASHSIZE+1,len,mykey);/*{int i;for(i=0;i<p-temp;++i) printf(" %02x",temp[i]);printf("\n");}*/ putmsg(&servername,temp,p-temp);}void registerme(void){int t; mesg[0]=CODE_IAM; memcpy(mesg+1,myip,4); t=ntohs(myname.sin_port); mesg[5]=t>>8; mesg[6]=t; messagetoserver(mesg,1+6);}void unregisterme(void){int t; mesg[0]=CODE_IAMNOT; memcpy(mesg+1,myip,4); t=ntohs(myname.sin_port); mesg[5]=t>>8; mesg[6]=t; messagetoserver(mesg,1+6);}void sendtalk(void){ if(talktries==MAXTALKTRIES) { printf("No response to TALK request after %d tries. Giving up.\n", talktries); talktries=0; return; } ++talktries; mesg[0]=CODE_TALK; memcpy(mesg+1,username,MAXNAMESIZE); mesg[1+MAXNAMESIZE]=0; putmsg(&buddy,mesg,1+MAXNAMESIZE); nextsendtalk=gtime()+TALKTRYDELAY;}unsigned char myvisibleaddr[IPADDRSIZE];unsigned char myvisibleport[IPPORTSIZE];#define FOUR 0int pack(unsigned char *out,unsigned char *in,int size){int i,j;#if FOUR for(j=i=0;i<size;i+=4) out[j++]=in[i]&0xf0 | ((in[i+2]&0xf0)>>4);#else for(j=i=0;i<size;i+=2) out[j++]=in[i];#endif return j;}int unpack(unsigned char *out,unsigned char *in,int size){int i,j,k;#if FOUR for(j=i=0;i<size;++i) { k=in[i]; out[j++]=k&0xf0; out[j++]=k&0xf0; out[j++]=(k&0x0f)<<4; out[j++]=(k&0x0f)<<4; }#else for(j=i=0;i<size;++i) { k=in[i]; out[j++]=k; out[j++]=k; }#endif return j;}void answer(void){ gottalk=0; talktries=0; tryopendsp(); connected=1;}void userprocessmsg(struct sockaddr_in *from,unsigned char *msg,int size){long int i,j,k;char name[MAXNAMESIZE+1];char txt[64];char txt2[64];unsigned char publicaddr[4];unsigned char publicport[4];unsigned char localaddr[4];unsigned char localport[2]; if(size<1) return; if(*msg==CODE_CRYPT) { ++msg; --size; if(size<sizeof(specialkey)) return; encryptblock(msg,size,mykey); i=size; while(--i>0) msg[i]^=msg[i-1]; if(memcmp(msg,specialkey,sizeof(specialkey))) return; msg+=sizeof(specialkey); size-=sizeof(specialkey); } if(size<1) return; --size; switch(*msg++) { case CODE_ENTRY: if(memcmp(&servername.sin_addr.s_addr,&from->sin_addr.s_addr,IPADDRSIZE)) break; if(memcmp(&servername.sin_port,&from->sin_port,IPPORTSIZE)) break; if(size<STATSIZE) break; memcpy(publicaddr,msg,IPADDRSIZE); memcpy(publicport,msg+IPADDRSIZE,IPPORTSIZE); memcpy(localaddr,msg+IPADDRSIZE+IPPORTSIZE,IPADDRSIZE); memcpy(localport,msg+IPADDRSIZE*2+IPPORTSIZE,IPPORTSIZE); memset(name,0,sizeof(name)); memcpy(name,msg+12,MAXNAMESIZE); if(!strcmp(name,username)) { memcpy(myvisibleaddr,publicaddr,IPADDRSIZE); memcpy(myvisibleport,publicport,IPPORTSIZE); } else { sprintf(txt,"%d.%d.%d.%d:%d",msg[0],msg[1],msg[2],msg[3], (msg[4]<<8)|msg[5]); sprintf(txt2,"%d.%d.%d.%d:%d",localaddr[0],localaddr[1], localaddr[2],localaddr[3],(localport[0]<<8)|localport[1]); printf("%-21s Local:%-21s: %s\n",txt,txt2,name); } if(!connected && tryingtocall && !strcmp(name,calling)) { if(!memcmp(publicaddr,myvisibleaddr,IPADDRSIZE)) { memcpy(&buddy.sin_addr.s_addr,localaddr,IPADDRSIZE); memcpy(&buddy.sin_port,localport,IPPORTSIZE); } else { memcpy(&buddy.sin_addr.s_addr,publicaddr,IPADDRSIZE); memcpy(&buddy.sin_port,publicport,IPPORTSIZE); } buddy.sin_family=AF_INET; talktries=0; sendtalk(); } break; case CODE_SOUND: if(!connected) { printf("got some sound...\n"); if(talktries && !memcmp(&from->sin_addr.s_addr,&buddy.sin_addr.s_addr,IPADDRSIZE) && !memcmp(&from->sin_port,&buddy.sin_port,IPPORTSIZE)) { memcpy(&buddy,from,sizeof(buddy)); answer(); } else { mesg[0]=CODE_BYE; putmsg(from,mesg,1); break; } } if(size>3) { j=(msg[0]<<16) | (msg[1]<<8) | msg[2]; msg+=3; k=(msg[0]<<24) | (msg[1]<<16) | (msg[2]<<8) | msg[3]; msg+=4; lastdiff=gtime2()-k; k=(msg[0]<<24) | (msg[1]<<16) | (msg[2]<<8) | msg[3]; msg+=4; latency=lastdiff+k; if(j>incount) { incount=j; for(i=0;i<PACKETSTOPACK;++i) { unpack33to160(sndblock2,msg+i*33); writein+=block160size; j=writelimit-writeput; if(j>block160size) j=block160size; memcpy(writeput,sndblock2,j); writeput+=j; if(writeput==writelimit) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -