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

📄 miniphone.c

📁 来自网络的iaxclient的协议栈源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Miniphone: A simple, command line telephone * * IAX Support for talking to Asterisk and other Gnophone clients * * Copyright (C) 1999, Linux Support Services, Inc. * * Mark Spencer <markster@linux-support.net> * * This program is free software, distributed under the terms of * the GNU General Public License */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <stdio.h>#include <errno.h>#include <sys/ioctl.h>#include <iax-client.h>#include <linux/soundcard.h>#include <errno.h>#include <sys/time.h>#include <sys/signal.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <gsm.h>#include <miniphone.h>#include <time.h>#include "busy.h"#include "dialtone.h"#include "answer.h"#include "ringtone.h"#include "ring10.h"#include "options.h"#define FRAME_SIZE 160static char callerid[80];struct peer {	int time;	gsm gsmin;	gsm gsmout;	struct iax_session *session;	struct peer *next;};static char *audiodev = "/dev/dsp";static int audiofd = -1;static struct peer *peers;static int answered_call = 0;static struct peer *find_peer(struct iax_session *);static int audio_setup(char *);static void sighandler(int);static void parse_args(FILE *, unsigned char *);void do_iax_event(FILE *);void call(FILE *, char *);void answer_call(void);void reject_call(void);static void handle_event(FILE *, struct iax_event *e, struct peer *p);void parse_cmd(FILE *, int, char **);void issue_prompt(FILE *);void dump_array(FILE *, char **);struct sound {	short *data;	int datalen;	int samplen;	int silencelen;	int repeat;};static int cursound = -1;static int sampsent = 0;static int offset = 0;static int silencelen = 0;static int nosound = 0;static int offhook = 0;static int ringing = 0;static int writeonly = 0;static struct iax_session *registry = NULL;static struct timeval regtime;#define TONE_NONE     -1#define TONE_RINGTONE 0#define TONE_BUSY     1#define TONE_CONGEST  2#define TONE_RINGER   3#define TONE_ANSWER   4#define TONE_DIALTONE  5#define OUTPUT_NONE    0#define OUTPUT_SPEAKER 1#define OUTPUT_HANDSET 2#define OUTPUT_BOTH    3static struct sound sounds[] = {	{ ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },	{ busy, sizeof(busy)/2, 4000, 4000, 1 },	{ busy, sizeof(busy)/2, 2000, 2000, 1 },	{ ring10, sizeof(ring10)/2, 16000, 32000, 1 },	{ answer, sizeof(answer)/2, 2200, 0, 0 },	{ dialtone, sizeof(dialtone)/2, 8000, 0, 1 },};static char *help[] = {"Welcome to the miniphone telephony client, the commands are as follows:\n","Help\t\t-\tDisplays this screen.","Help <Command>\t-\tInqueries specific information on a command.","Dial <Number>\t-\tDials the number supplied in the first arguement","Status\t\t-\tLists the current sessions and their current status.","Quit\t\t-\tShuts down the client.","",0};static short silence[FRAME_SIZE];static struct peer *most_recent_answer;static struct iax_session *newcall = 0;static struct peer *find_peer(struct iax_session *session){	struct peer *cur = peers;	while(cur) {		if (cur->session == session)			return cur;		cur = cur->next;	}	return NULL;}static int audio_setup(char *dev){	int fd;		int fmt = AFMT_S16_LE;	int channels = 1;	int speed = 8000;	int fragsize = (40 << 16) | 6;	if ( (fd = open(dev, O_RDWR | O_NONBLOCK)) < 0) {		fprintf(stderr, "Unable to open audio device %s: %s\n", dev, strerror(errno));		return -1;	}	if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) || (fmt != AFMT_S16_LE)) {		fprintf(stderr, "Unable to set in signed linear format.\n");		return -1;	}	if (ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0)) {		fprintf(stderr, "Unable to set full duplex operation.\n");		writeonly = 1;		/* return -1; */	}	if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) || (channels != 1)) {		fprintf(stderr, "Unable to set to mono\n");		return -1;	}	if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) || (speed != 8000)) {		fprintf(stderr, "Unable to set speed to 8000 hz\n");		return -1;	}	if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) {		fprintf(stderr, "Unable to set fragment size...\n");		return -1;	}	return fd;}static int send_sound(int soundfd){	/* Send FRAME_SIZE samples of whatever */	short myframe[FRAME_SIZE];	short *frame = NULL;	int total = FRAME_SIZE;	int amt=0;	int res;	int myoff;	audio_buf_info abi;	if (cursound > -1) {		res = ioctl(soundfd, SNDCTL_DSP_GETOSPACE ,&abi);		if (res) {			fprintf(stderr,"Unable to read output space\n");			return -1;		}		/* Calculate how many samples we can send, max */		if (total > (abi.fragments * abi.fragsize / 2)) 			total = abi.fragments * abi.fragsize / 2;		res = total;		if (sampsent < sounds[cursound].samplen) {			myoff=0;			while(total) {				amt = total;				if (amt > (sounds[cursound].datalen - offset)) 					amt = sounds[cursound].datalen - offset;				memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);				total -= amt;				offset += amt;				sampsent += amt;				myoff += amt;				if (offset >= sounds[cursound].datalen)					offset = 0;			}			/* Set it up for silence */			if (sampsent >= sounds[cursound].samplen) 				silencelen = sounds[cursound].silencelen;			frame = myframe;		} else {			if (silencelen > 0) {				frame = silence;				silencelen -= res;			} else {				if (sounds[cursound].repeat) {					/* Start over */					sampsent = 0;					offset = 0;				} else {					cursound = -1;					nosound = 0;				}			}		}#if 0		if (frame)			printf("res is %d, frame[0] is %d\n", res, frame[0]);#endif				res = write(soundfd, frame, res * 2);		if (res > 0)			return 0;		return res;	}	return 0;}static int iax_regtimeout(int timeout){	if (timeout) {		gettimeofday(&regtime, NULL);		regtime.tv_sec += timeout;	} else {		regtime.tv_usec = 0;		regtime.tv_sec = 0;	}	return 0;}static int check_iax_register(void){	int res;	if (strlen(regpeer) && strlen(server)) {		registry = iax_session_new();			res = iax_register(registry, server,regpeer,regsecret, refresh);			if (res) {			fprintf(stderr, "Failed registration: %s\n", iax_errstr);			return -1;		}		iax_regtimeout(5 * refresh / 6);	} else {		iax_regtimeout(0);		refresh = 60;	}	return 0;}static int check_iax_timeout(void){	struct timeval tv;	int ms;	if (!regtime.tv_usec || !regtime.tv_sec)		return -1;	gettimeofday(&tv, NULL);	if ((tv.tv_usec >= regtime.tv_usec) && (tv.tv_sec >= regtime.tv_sec)) {		check_iax_register();		/* Have it check again soon */		return 100;	}	ms = (regtime.tv_sec - tv.tv_sec) * 1000 + (regtime.tv_usec - tv.tv_usec) / 1000;	return ms;}static int gentone(int sound, int uninterruptible){	cursound = sound;	sampsent = 0;	offset = 0;	silencelen = 0;	nosound = uninterruptible;	printf("Sending tone %d\n", sound);	return 0;}voidsighandler(int sig){	if(sig == SIGHUP) {		puts("rehashing!");	} else if(sig == SIGINT) {		static int prev = 0;		int cur;				if ( (cur = time(0))-prev <= 5) {			printf("Terminating!\n");			exit(0);		} else {			prev = cur;			printf("Press interrupt key again in the next %d seconds to really terminate\n", 5-(cur-prev));		}	}}voidparse_args(FILE *f, unsigned char *cmd){	static char *argv[MAXARGS];	unsigned char *parse = cmd;	int argc = 0, t = 0;	// Don't mess with anything that doesn't exist...	if(!*parse)		return;	bzero(argv, sizeof(argv));	while(*parse) {		if(*parse < 33 || *parse > 128) {			*parse = 0, t++;			if(t > MAXARG) {				fprintf(f, "Warning: Argument exceeds maximum argument size, command ignored!\n");				return;			}		} else if(t || !argc) {			if(argc == MAXARGS) {				fprintf(f, "Warning: Command ignored, too many arguments\n");				return;			}			argv[argc++] = parse;			t = 0;		}		parse++;	}	if(argc)		parse_cmd(f, argc, argv);}intmain(int argc, char *argv[]){	int port;	int netfd; 	int c, h=0, m, regm;	FILE *f;	int fd = STDIN_FILENO;	char rcmd[RBUFSIZE];	fd_set readfd;	fd_set writefd;	struct timeval timer;	struct timeval *timerptr = NULL;	gsm_frame fo;	load_options();	if (!strlen(callerid))		gethostname(callerid, sizeof(callerid));	signal(SIGHUP, sighandler);	signal(SIGINT, sighandler);	if ( !(f = fdopen(fd, "w+"))) {		fprintf(stderr, "Unable to create file on fd %d\n", fd);		return -1;	}	if ( (audiofd = audio_setup(audiodev)) == -1) {		fprintf(stderr, "Fatal error: failed to open sound device");		return -1;

⌨️ 快捷键说明

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