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

📄 iax.c

📁 iax协议Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
		fh->csub = AST_HTML_LDCOMPLETE;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_VOICE:		ts = ntohl(fh->ts);		if (event->event.voice.datalen > left) {			strcpy(iax_errstr, "Voice frame too large\n");		}		/* Don't do anything if we're quelching audio */		if (session->quelch)			break;		/* If the voice format is the same, and the top of our 		   timestamp is the same, then we stick with a mini-frame, otherwise		   we send a large frame */		if ((event->event.voice.format == session->svoiceformat) &&		    ((session->lastvoicets & 0xFFFF0000) == (ts & 0xFFFF0000))) {			/* We can send a mini-frame since we're using the same			   voice format and don't need a timestamp update.  */			f.datalen += event->event.voice.datalen;			f.datalen -= sizeof(struct iax_full_hdr) - sizeof(struct iax_mini_hdr);			memcpy(mh->data, event->event.voice.data, event->event.voice.datalen);			mh->ts = htons((short)(ts & 0x0000FFFF));			mh->callno = htons((short)session->callno);			session->lastvoicets = ts;			iax_xmit_frame(&f);		} else {			/* Send a full frame for our voice frame */			fh->type = AST_FRAME_VOICE;			fh->csub = compress_subclass(event->event.voice.format);			session->svoiceformat = event->event.voice.format;			fh->seqno = htons((short) session->oseqno++);			memcpy(fh->data, event->event.voice.data, event->event.voice.datalen);			f.datalen += event->event.voice.datalen;			session->lastvoicets = ts;			iax_reliable_xmit(&f);		}		break;	case IAX_EVENT_IMAGE:		fh->type = AST_FRAME_IMAGE;		fh->csub = compress_subclass(event->event.image.format);		fh->seqno = htons((short) session->oseqno++);		memcpy(fh->data, event->event.image.data, event->event.image.datalen);		f.datalen += event->event.image.datalen;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_DIAL:		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_DIAL;		MYSNPRINTF "%s", event->event.dial.number);		f.datalen += strlen(requeststr);		iax_reliable_xmit(&f);		break;	case IAX_EVENT_DPREQ:		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_DPREQ;		MYSNPRINTF "%s", event->event.dpreq.number);		f.datalen += strlen(requeststr);		iax_reliable_xmit(&f);		break;	case IAX_EVENT_TXREPLY:		/* Transmit an IAX Transmit request */		fh->type = AST_FRAME_IAX;		fh->seqno = htons(0);		fh->csub = IAX_COMMAND_TXCNT;		fh->dcallno = htons((short)session->transfercallno);		f.transferpacket = 1;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_TXREJECT:		/* Reject the IAX transfer -- the peer couldn't see us or we couldn't see them */		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_TXREJ;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_TXACCEPT:		/* Accept a connect request */		fh->type = AST_FRAME_IAX;		fh->seqno = htons(0);		fh->csub = IAX_COMMAND_TXACC;		fh->dcallno = htons((short)session->transfercallno);		f.transferpacket = 1;		f.retries = -1;		iax_xmit_frame(&f);		break;	case IAX_EVENT_TXREADY:		/* We've been accepted on the transfer.  Notify the gateway that we're ready */		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_TXREADY;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_QUELCH:		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_QUELCH;		iax_reliable_xmit(&f);		break;	case IAX_EVENT_UNQUELCH:		fh->type = AST_FRAME_IAX;		fh->seqno = htons(session->oseqno++);		fh->csub = IAX_COMMAND_UNQUELCH;		iax_reliable_xmit(&f);		break;	default:		DEBU(G "Don't know how to send a %d event\n", event->etype);		IAXERROR "Unknown event type.\n");	}	return 0;}static void destroy_session(struct iax_session *session){	struct iax_session *cur, *prev=NULL;	struct iax_sched *curs, *prevs=NULL, *nexts=NULL;	int    loop_cnt=0;	curs = schedq;	while(curs) {		nexts = curs->next;		if (curs->frame && curs->frame->session == session) {			/* Just mark these frames as if they've been sent */			curs->frame->retries = -1;		} else if (curs->event && curs->event->session == session) {			if (prevs)				prevs->next = nexts;			else				schedq = nexts;			if (curs->event)				iax_event_free(curs->event);			free(curs);		} else {			prevs = curs;		}		curs = nexts;		loop_cnt++;	}			cur = sessions;	while(cur) {		if (cur == session) {			if (prev)				prev->next = session->next;			else				sessions = session->next;			free(session);			return;		}		prev = cur;		cur = cur->next;	}}static struct iax_event *handle_event(struct iax_event *event){	/* We have a candidate event to be delievered.  Be sure	   the session still exists. */	if (event) {		if (iax_session_valid(event->session)) {			/* Lag requests are never actually sent to the client, but			   other than that are handled as normal packets */			switch(event->etype) {			case IAX_EVENT_REGREP:			case IAX_EVENT_REJECT:			case IAX_EVENT_HANGUP:				/* Destroy this session -- it's no longer valid */				destroy_session(event->session);				return event;			case IAX_EVENT_LAGRQ:				event->etype = IAX_EVENT_LAGRP;				iax_do_event(event->session, event);				iax_event_free(event);				break;			case IAX_EVENT_PING:				event->etype = IAX_EVENT_PONG;				iax_do_event(event->session, event);				iax_event_free(event);				break;			default:				return event;			}		}	}	return NULL;}int iax_send_dtmf(struct iax_session *session, char digit){	/* Send a DTMF digit */	struct iax_event e;	e.etype = IAX_EVENT_DTMF;	e.event.dtmf.digit = digit;	return iax_do_event(session, &e);}int iax_send_voice(struct iax_session *session, int format, char *data, int datalen){	/* Send a (possibly compressed) voice frame */	struct iax_event e;	e.etype = IAX_EVENT_VOICE;	e.event.voice.format = format;	e.event.voice.data = data;	e.event.voice.datalen = datalen;	return iax_do_event(session, &e);}int iax_send_image(struct iax_session *session, int format, char *data, int datalen){	/* Send an image frame */	struct iax_event e;	e.etype = IAX_EVENT_IMAGE;	e.event.image.format = format;	e.event.image.data = data;	e.event.image.datalen = datalen;	return iax_do_event(session, &e);}int iax_register(struct iax_session *session, char *server, char *peer, char *secret, int refresh){	/* Send a registration request */	struct iax_event e;	char *tmp = strdup(server);	int res;	if (!tmp)		return -1;	e.etype = IAX_EVENT_REGREQ;	e.event.regrequest.server = tmp;	if (strchr(e.event.regrequest.server, ':')) {		strtok(e.event.regrequest.server, ":");		e.event.regrequest.portno = atoi(strtok(NULL, ":"));	} else		e.event.regrequest.portno = IAX_DEFAULT_PORTNO;	e.event.regrequest.peer = peer;	e.event.regrequest.secret = secret;	e.event.regrequest.refresh = refresh;	res = iax_do_event(session, &e);	free(tmp);	return res;}int iax_reject(struct iax_session *session, char *reason){	struct iax_event e;	e.etype = IAX_EVENT_REJECT;	e.event.reject.reason = reason;	return iax_do_event(session, &e);}int iax_hangup(struct iax_session *session, char *byemsg){	struct iax_event e;	e.etype = IAX_EVENT_HANGUP;	e.event.hangup.byemsg = byemsg;	return iax_do_event(session, &e);}int iax_sendurl(struct iax_session *session, char *url){	struct iax_event e;	e.etype = IAX_EVENT_URL;	e.event.url.url = url;	return iax_do_event(session, &e);}int iax_ring_announce(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_RINGA;	return iax_do_event(session, &e);}int iax_lag_request(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_LAGRQ;	return iax_do_event(session, &e);}int iax_busy(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_BUSY;	return iax_do_event(session, &e);}int iax_accept(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_ACCEPT;	return iax_do_event(session, &e);}int iax_answer(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_ANSWER;	return iax_do_event(session, &e);}int iax_load_complete(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_LDCOMPLETE;	return iax_do_event(session, &e);}int iax_send_url(struct iax_session *session, char *url, int link){	struct iax_event e;	e.etype = IAX_EVENT_URL;	e.event.url.link = link;	e.event.url.url = url;	return iax_do_event(session, &e);}int iax_send_text(struct iax_session *session, char *text){	struct iax_event e;	e.etype = IAX_EVENT_TEXT;	snprintf(e.event.text.text, sizeof(e.event.text.text), "%s", text);	return iax_do_event(session, &e);}int iax_send_unlink(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_UNLINK;	return iax_do_event(session, &e);}int iax_send_link_reject(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_LINKREJECT;	return iax_do_event(session, &e);}int iax_auth_reply(struct iax_session *session, char *password, char *challenge, int methods){	struct iax_event e;	char reply[16];	struct MD5Context md5;	char realreply[256];	e.etype = IAX_EVENT_AUTHRP;	if ((methods & IAX_AUTHMETHOD_MD5) && challenge) {		e.event.authreply.authmethod = IAX_AUTHMETHOD_MD5;		MD5Init(&md5);		MD5Update(&md5, (const unsigned char *) challenge, strlen(challenge));		MD5Update(&md5, (const unsigned char *) password, strlen(password));		MD5Final((unsigned char *) reply, &md5);		bzero(realreply, sizeof(realreply));		convert_reply(realreply, (unsigned char *) reply);		e.event.authreply.reply = realreply;	} else {		e.event.authreply.authmethod = IAX_AUTHMETHOD_PLAINTEXT;		e.event.authreply.reply = password;	}	return iax_do_event(session, &e);}void iax_set_formats(int fmt){	sformats = fmt;}int iax_dial(struct iax_session *session, char *number){	struct iax_event e;	e.etype = IAX_EVENT_DIAL;	e.event.dial.number = number;	return iax_do_event(session, &e);}int iax_quelch(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_QUELCH;	return iax_do_event(session, &e);}int iax_unquelch(struct iax_session *session){	struct iax_event e;	e.etype = IAX_EVENT_UNQUELCH;	return iax_do_event(session, &e);}int iax_dialplan_request(struct iax_session *session, char *number){	struct iax_event e;	e.etype = IAX_EVENT_DPREQ;	e.event.dpreq.number = number;	return iax_do_event(session, &e);}int iax_call(struct iax_session *session, char *callerid, char *ich, char *lang, int wait){	struct iax_event e;	char *tmp = ich ? strdup(ich) : NULL;	char *part1, *part2;	int res;	/* We start by parsing up the temporary variable which is of the form of:	   [user@]peer[:portno][/exten[@context]] */	if (!tmp) {		IAXERROR "Invalid IAX Call Handle\n");		DEBU(G "Invalid IAX Call Handle\n");		return -1;	}		e.event.connect.callerid = callerid;	e.event.connect.formats = sformats;	e.event.connect.version = IAX_PROTO_VERSION;	e.event.connect.language = lang;		e.etype = IAX_EVENT_CONNECT;	/* Part 1 is [user[:password]@]peer[:port] */	part1 = strtok(tmp, "/");	/* Part 2 is exten[@context] if it is anything all */	part2 = strtok(NULL, "/");		if (strchr(part1, '@')) {		e.event.connect.username = strtok(part1, "@");		e.event.connect.hostname = strtok(NULL, "@");	} else {		e.event.connect.username = NULL;		e.event.connect.hostname = part1;	}		if (e.event.connect.username && strchr(e.event.connect.username, ':')) {		e.event.connect.username = strtok(e.event.connect.username, ":");		e.event.connect.secret = strtok(NULL, ":");	}		if (strchr(e.event.connect.hostname, ':')) {		strtok(e.event.connect.hostname, ":");		e.event.connect.portno = atoi(strtok(NULL, ":"));	} else {		e.event.connect.portno = IAX_DEFAULT_PORTNO;	}	if (part2) {		e.event.connect.exten = strtok(part2, "@");		e.event.connect.dnid = e.event.connect.exten;		e.event.connect.context = strtok(NULL, "@");	} else {		e.event.connect.exten = NULL;		e.event.connect.dnid = NULL;		e.event.connect.context = NULL;	}	res = iax_do_event(session, &e);	free(tmp);	if (res < 0)		return res;	if (wait) {		DEBU(G "Waiting not yet implemented\n");		return -1;	}	return res;}static int calc_rxstamp(struct iax_session *session){	struct timeval tv;	int ms;	if (!session->rxcore.tv_sec && !session->rxcore.tv_usec) {		gettimeofday(&session->rxcore, NULL);	}		gettimeofday(&tv, NULL);	ms = (tv.tv_sec - session->rxcore.tv_sec) * 1000 +		 (tv.tv_usec - session->rxcore.tv_usec) / 1000;		return ms;}static int match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur){	if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&

⌨️ 快捷键说明

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