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

📄 iax.c

📁 来自网络的iaxclient的协议栈源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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) {			jb_frame frame;			if (prev)				prev->next = session->next;			else				sessions = session->next;			while(jb_getall(session->jb,&frame) == JB_OK)				iax_event_free((struct iax_event *)frame.data);			jb_destroy(session->jb);			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 ( event->etype == IAX_EVENT_NULL ) return 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)			{				/* the user on the outside may need to look at the session so we will not free				   it here anymore we will test for hangup event in iax_event_free and do it				   there.				 */			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;			case IAX_EVENT_POKE:				event->etype = IAX_EVENT_PONG;				iax_send_pong(event->session, event->ts);				destroy_session(event->session);				iax_event_free(event);				break;			default:				return event;			}		} else			iax_event_free(event);	}	return NULL;}static int iax2_vnak(struct iax_session *session){	/* send vnak just once for a given sequence number */	if ( (unsigned char)(session->lastvnak - session->iseqno) < 128 )	{		return 0;	}	session->lastvnak = session->iseqno;	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, unsigned 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, unsigned char *data,		int datalen){#ifdef USE_VOICE_TS_PREDICTION	session->notsilenttx = 0;#endif	return send_command(session, AST_FRAME_CNG, level, 0, data, datalen, -1);}int iax_send_image(struct iax_session *session, int format, unsigned char *data,		int datalen){	/* Send an image frame */	return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1);}int iax_send_video(struct iax_session *session, int format, unsigned char *data,		int datalen, int fullframe){	if (!session->quelch)	{		int res = send_command_video(session, AST_FRAME_VIDEO, format,				0, data, datalen, -1, fullframe);		return res;	}	return 0;}int iax_send_video_trunk(struct iax_session *session, int format,		char *data, int datalen, int fullframe, int ntrunk){	static int my_lastts = 0;	if ( ntrunk == 0 )		my_lastts = calc_timestamp(session, 0, NULL);	if ( !session->quelch )	{		return send_command_video(session, AST_FRAME_VIDEO, format,				my_lastts, (unsigned char *)data, datalen, -1,				fullframe);	}	return 0;}int iax_video_bypass_jitter(struct iax_session *s, int mode){	video_bypass_jitterbuffer = mode;	return 0;}int iax_register(struct iax_session *session, const char *server, const char *peer, const 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;	iax_sched_del(NULL, NULL, send_ping, (void *) session, 1);	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,			(unsigned char *)url, (int)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_congestion(struct iax_session *session){	return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_CONGESTION, 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);}int iax_send_url(struct iax_session *session, const char *url, int link){	return send_command(session, AST_FRAME_HTML,			link ? AST_HTML_LINKURL : AST_HTML_URL, 0,			(unsigned char *)url, (int)strlen(url), -1);}int iax_send_text(struct iax_session *session, const char *text){	return send_command(session, AST_FRAME_TEXT, 0, 0,			(unsigned char *)text, (int)strlen(text) + 1, -1);}int iax_send_unlink(struct iax_session *session){	return send_command(session, AST_FRAME_HTML, AST_HTML_UNLINK, 0, NULL, 0, -1);}int iax_send_link_reject(struct iax_session *session){	return send_command(session, AST_FRAME_HTML, AST_HTML_LINKREJECT, 0, NULL, 0, -1);}static int iax_send_pong(struct iax_session *session, unsigned int ts){        struct iax_ie_data ied;	jb_info stats;        memset(&ied, 0, sizeof(ied));	jb_getinfo(session->jb, &stats);	iax_ie_append_int(&ied,IAX_IE_RR_JITTER, stats.jitter);	/* XXX: should be short-term loss pct.. */	if(stats.frames_in == 0) stats.frames_in = 1;	iax_ie_append_int(&ied,IAX_IE_RR_LOSS,			((0xff & (stats.losspct/1000)) << 24 |			 (stats.frames_lost & 0x00ffffff)));	iax_ie_append_int(&ied,IAX_IE_RR_PKTS, stats.frames_in);	iax_ie_append_short(&ied,IAX_IE_RR_DELAY,			(unsigned short)(stats.current - stats.min));	iax_ie_append_int(&ied,IAX_IE_RR_DROPPED, stats.frames_dropped);	iax_ie_append_int(&ied,IAX_IE_RR_OOO, stats.frames_ooo);	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PONG, ts, ied.buf, ied.pos, -1);}/* external API; deprecated since we send pings ourselves now (finally) */int iax_send_ping(struct iax_session *session){	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);}/* scheduled ping sender; sends ping, then reschedules */static void send_ping(void *s){	struct iax_session *session = (struct iax_session *)s;	/* important, eh? */	if(!iax_session_valid(session)) return;	send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);	session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, ping_time * 1000);	return;}static int iax_send_lagrp(struct iax_session *session, unsigned int ts){	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRP, ts, NULL, 0, -1);}static int iax_send_txcnt(struct iax_session *session){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);	return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);}static int iax_send_txrej(struct iax_session *session){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);	return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, ied.buf, ied.pos);}static int iax_send_txaccept(struct iax_session *session){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);	return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, ied.buf, ied.pos);}static int iax_send_txready(struct iax_session *session){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	/* see asterisk chan_iax2.c */	iax_ie_append_short(&ied, IAX_IE_CALLNO, session->callno);	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied.buf, ied.pos, -1);}int iax_auth_reply(struct iax_session *session, char *password, char *challenge, int methods){	char reply[16];	struct MD5Context md5;	char realreply[256];	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	if ((methods & IAX_AUTH_MD5) && challenge) {		MD5Init(&md5);		MD5Update(&md5, (const unsigned char *) challenge,				(unsigned int)strlen(challenge));		MD5Update(&md5, (const unsigned char *) password,				(unsigned int)strlen(password));		MD5Final((unsigned char *) reply, &md5);		memset(realreply, 0, sizeof(realreply));		convert_reply(realreply, (unsigned char *) reply);		iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);	} else {		iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, password);	}	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);}static int iax_regauth_reply(struct iax_session *session, char *password, char *challenge, int methods){	char reply[16];	struct MD5Context md5;	char realreply[256];	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_str(&ied, IAX_IE_USERNAME, session->username);	iax_ie_append_short(&ied, IAX_IE_REFRESH, session->refresh);	if ((methods & IAX_AUTHMETHOD_MD5) && challenge) {		MD5Init(&md5);		MD5Update(&md5, (const unsigned char *) challenge,				(unsigned int)strlen(challenge));		MD5Update(&md5, (const unsigned char *) password,				(unsigned int)strlen(password));		MD5Final((unsigned char *) reply, &md5);		memset(realreply, 0, sizeof(realreply));		convert_reply(realreply, (unsigned char *) reply);		iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);	} else {		iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, password);	}	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);}int iax_dial(struct iax_session *session, char *number){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DIAL, 0, ied.buf, ied.pos, -1);}int iax_quelch(struct iax_session *session){	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, NULL, 0, -1);}int iax_unquelch(struct iax_session *session){	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, -1);}int iax_dialplan_request(struct iax_session *session, char *number){	struct iax_ie_data ied;	memset(&ied, 0, sizeof(ied));	iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);	return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);}static inline int which_bit(unsigned int i){	char x;	for(x = 0; x < 32; x++) {		if ((1U << x) == i) {			return x + 1;		}	}	return 0;}char iax_pref_codec_add(struct iax_session *session, unsigned int format){	int diff = (int) 'A';	session->codec_order[session->codec_order_len++] = (which_bit(format)) + diff;	session->codec_order[session->codec_order_len] = '\0';	return session->codec_order[session->codec_order_len-1];}void iax_pref_codec_del(struct iax_session *session, unsigned int format){	int diff = (int) 'A';	int x;	char old[32];	char remove = which_bit(format) + diff;	strncpy(old, session->codec_order, sizeof(old));	session->codec_order_len = 0;	for (x = 0;  x < (int) strlen(old);  x++) {		if (old[x] != remove) {			session->codec_order[session->codec_order_len++] = old[x];		}	}	session->codec_order[session->codec_order_len] = '\0';}int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len){	int diff = (int) 'A';	int x;	for (x = 0; x < session->codec_order_len && x < len; x++) {		array[x] = (1 << (session->codec_order[x] - diff - 1));	}

⌨️ 快捷键说明

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