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

📄 iax.c

📁 IAX client库, 一个VOIP的库. 支持H.323和SIP, PBX就是采用的它
💻 C
📖 第 1 页 / 共 5 页
字号:
static int send_command(struct iax_session *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno){	return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0);}static int send_command_final(struct iax_session *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno){#if 0	/* It is assumed that the callno has already been locked */	iax_predestroy(i);#endif		int r;	r = __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1, 0);	if (r >= 0) destroy_session(i);	return r;}static int send_command_immediate(struct iax_session *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno){	return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, 0);}static int send_command_transfer(struct iax_session *i, char type, int command, unsigned int ts, char *data, int datalen){	return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0, 0);}static int send_command_samples(struct iax_session *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno, int samples){	return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, samples);}int iax_transfer(struct iax_session *session, char *number){		static int res;				//Return Code	struct iax_ie_data ied;			//IE Data Structure (Stuff To Send)	// Clear The Memory Used For IE Buffer	memset(&ied, 0, sizeof(ied));		// Copy The Transfer Destination Into The IE Structure	iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);		// Send The Transfer Command - Asterisk Will Handle The Rest!				res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);		// Return Success	return 0;	}static void stop_transfer(struct iax_session *session){	struct iax_sched *sch;	sch = schedq;	while(sch) {		if (sch->frame && (sch->frame->session == session))					sch->frame->retries = -1;		sch = sch->next;	}}	/* stop_transfer */static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq){	session->peercallno = peercallno;	/* Change from transfer to session now */	if (xfr2peer) {		memcpy(&session->peeraddr, &session->transfer, sizeof(session->peeraddr));		memset(&session->transfer, 0, sizeof(session->transfer));		session->transferring = TRANSFER_NONE;		session->transferpeer = 0;		session->transfer_moh = 0;		/* Force retransmission of a real voice packet, and reset all timing */		session->svoiceformat = -1;		session->voiceformat = 0;	}	memset(&session->rxcore, 0, sizeof(session->rxcore));	memset(&session->offset, 0, sizeof(session->offset));	memset(&session->history, 0, sizeof(session->history));#ifdef NEWJB	{ /* Reset jitterbuffer */	    jb_frame frame;	    while(jb_getall(session->jb,&frame) == JB_OK) 		iax_event_free(frame.data);		    jb_reset(session->jb);	}#endif	session->jitterbuffer = 0;	session->jitter = 0;	session->lag = 0;	if (! preserveSeq)	{		/* Reset sequence numbers */		session->aseqno = 0;		session->oseqno = 0;		session->iseqno = 0;	}	session->lastsent = 0;	session->last_ts = 0;	session->lastvoicets = 0;	session->pingtime = 30;	/* We have to dump anything we were going to (re)transmit now that we've been	   transferred since they're all invalid and for the old host. */	stop_transfer(session);}	/* complete_transfer */int iax_setup_transfer(struct iax_session *org_session, struct iax_session *new_session){	int res;	struct iax_ie_data ied0;	struct iax_ie_data ied1;	struct iax_session *s0 = org_session;	struct iax_session *s1 = new_session;	memset(&ied0, 0, sizeof(ied0));	memset(&ied1, 0, sizeof(ied1));	/* reversed setup */	iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &s1->peeraddr);	iax_ie_append_short(&ied0, IAX_IE_CALLNO, s1->peercallno);	iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transfer_id);	iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &s0->peeraddr);	iax_ie_append_short(&ied1, IAX_IE_CALLNO, s0->peercallno);	iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transfer_id);	s0->transfer = s1->peeraddr;	s1->transfer = s0->peeraddr;	s0->transferid = transfer_id;	s1->transferid = transfer_id;	s0->transfercallno = s0->peercallno;	s1->transfercallno = s1->peercallno;	s0->transferring = TRANSFER_BEGIN;	s1->transferring = TRANSFER_BEGIN;	s0->transferpeer = s1->callno;	s1->transferpeer = s0->callno;	transfer_id++;	if (transfer_id > 32767)		transfer_id = 1;	res = send_command(s0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);	if (res < 0) {		return -1;	}	res = send_command(s1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);	if (res < 0) {		return -1;	}	return 0;}static int iax_finish_transfer(struct iax_session *s, short new_peer){	int res;	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_short(&ied, IAX_IE_CALLNO, new_peer);	res = send_command(s, AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied.buf, ied.pos, -1);	complete_transfer(s, new_peer, 0, 1);	return res;}static struct iax_session *iax_find_session2(short callno){	struct iax_session *cur = sessions;	while(cur) {		if (callno == cur->callno && callno != 0)  {			return cur;		}		cur = cur->next;	}	return NULL;}static int iax_handle_txready(struct iax_session *s){	struct iax_session *s0, *s1;	short	s0_org_peer, s1_org_peer;	if (s->transfer_moh) {		s->transfer_moh = 0;		iax_unquelch(s);	}	complete_transfer(s, s->peercallno, 0, 1);	s->transferring = TRANSFER_REL;	s0 = s;	s1 = iax_find_session2(s0->transferpeer);	if (s1 != NULL &&	    s1->callno == s0->transferpeer &&		 s0->transferring == TRANSFER_REL &&		 s1->transferring == TRANSFER_REL) {		s0_org_peer = s0->peercallno;		s1_org_peer = s1->peercallno;		iax_finish_transfer(s0, s1_org_peer);		iax_finish_transfer(s1, s0_org_peer);		return 1;	}	return 0;}static void iax_handle_txreject(struct iax_session *s){	struct iax_session *s0, *s1;	s0 = s;	s1 = iax_find_session2(s0->transferpeer);	if (s1 != NULL &&		 s0->transferpeer == s1->callno &&		 s1->transferring) {		if (s1->transfer_moh) {			s1->transfer_moh = 0;			send_command_immediate(s1, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s1->iseqno);		}	}	if (s0->transfer_moh) {		s0->transfer_moh = 0;		send_command_immediate(s0, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s0->iseqno);	}	memset(&s->transfer, 0, sizeof(s->transfer));	s->transferring = TRANSFER_NONE;	s->transferpeer = 0;	s->transfer_moh = 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;#ifdef NEWJB			{			    jb_frame frame;			    while(jb_getall(session->jb,&frame) == JB_OK) 				iax_event_free(frame.data);		   				    jb_destroy(session->jb);			}#endif			free(session);			return;		}		prev = cur;		cur = cur->next;	}}static int iax_send_lagrp(struct iax_session *session, unsigned int ts);static int iax_send_pong(struct iax_session *session, unsigned int ts);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_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_send_lagrp(event->session, event->ts);				iax_event_free(event);				break;			case IAX_EVENT_PING:				event->etype = IAX_EVENT_PONG;				iax_send_pong(event->session, event->ts);				iax_event_free(event);				break;			default:				return event;			}		} else 			iax_event_free(event);	}	return NULL;}static int iax2_vnak(struct iax_session *session){	return send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, session->iseqno);}int iax_send_dtmf(struct iax_session *session, char digit){	return send_command(session, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);}int iax_send_voice(struct iax_session *session, int format, char *data, int datalen, int samples){	/* Send a (possibly compressed) voice frame */	if (!session->quelch)		return send_command_samples(session, AST_FRAME_VOICE, format, 0, data, datalen, -1, samples);	return 0;}int iax_send_cng(struct iax_session *session, int level, char *data, int datalen){    	session->notsilenttx = 0;	return send_command(session, AST_FRAME_CNG, level, 0, data, datalen, -1);}int iax_send_image(struct iax_session *session, int format, char *data, int datalen){	/* Send an image frame */	return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1);}int iax_register(struct iax_session *session, char *server, char *peer, char *secret, int refresh){	/* Send a registration request */	char tmp[256];	char *p;	int res;	int portno = IAX_DEFAULT_PORTNO;	struct iax_ie_data ied;	struct hostent *hp;		tmp[255] = '\0';	strncpy(tmp, server, sizeof(tmp) - 1);	p = strchr(tmp, ':');	if (p) {		*p = '\0';		portno = atoi(p+1);	}		memset(&ied, 0, sizeof(ied));	if (secret)		strncpy(session->secret, secret, sizeof(session->secret) - 1);	else		strcpy(session->secret, "");	/* Connect first */	hp = gethostbyname(tmp);	if (!hp) {		snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", tmp);		return -1;	}	memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));	session->peeraddr.sin_port = htons(portno);	session->peeraddr.sin_family = AF_INET;	strncpy(session->username, peer, sizeof(session->username) - 1);	session->refresh = refresh;	iax_ie_append_str(&ied, IAX_IE_USERNAME, peer);	iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);	res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);	return res;}int iax_reject(struct iax_session *session, char *reason){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_str(&ied, IAX_IE_CAUSE, reason ? reason : "Unspecified");	return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);}int iax_hangup(struct iax_session *session, char *byemsg){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_str(&ied, IAX_IE_CAUSE, byemsg ? byemsg : "Normal clearing");	return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);}int iax_sendurl(struct iax_session *session, char *url){	return send_command(session, AST_FRAME_HTML, AST_HTML_URL, 0, url, strlen(url), -1);}int iax_ring_announce(struct iax_session *session){	return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_RINGING, 0, NULL, 0, -1);}int iax_lag_request(struct iax_session *session){	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);}int iax_busy(struct iax_session *session){	return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_BUSY, 0, NULL, 0, -1);}int iax_accept(struct iax_session *session, int format){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_int(&ied, IAX_IE_FORMAT, format);	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied.buf, ied.pos, -1);}int iax_answer(struct iax_session *session){	return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);}int iax_load_complete(struct iax_session *session){	return send_command(session, AST_FRAME_HTML, AST_HTML_LDCOMPLETE, 0, NULL, 0, -1);}

⌨️ 快捷键说明

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