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

📄 iax.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 5 页
字号:
	}
	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, 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)
{    
	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, unsigned char *data, int datalen)
{
	/* Send an image frame */
	return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1);
}

int tiax_send_pfc_poke(struct iax_session *session, char *server)
{
	
	return 0;
}

int tiax_send_iep(struct iax_session *session,char *server, char *inviter,char *invitee)
{
	/* 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));

	/* 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, (unsigned char *) peer);
//	iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);
	if(inviter)
		iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, (unsigned char *) inviter);
	if(invitee)
		iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, (unsigned char *) invitee);
	res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_IEP, 0, ied.buf, ied.pos, -1);
	return res;
}

int tiax_send_nattrv(struct iax_session *session, char *server, char *callerid, 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));

	/* 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, (unsigned char *) peer);
	iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);
	if(callerid)
		iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, (unsigned char *) callerid);
	res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_NATTRV, 0, ied.buf, ied.pos, -1);
	return res;
}

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);
		session->peeraddr.sin_addr.s_addr = inet_addr(tmp);
		//return -1;
	}
	else
		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, (unsigned char *) 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_register_release(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);
		session->peeraddr.sin_addr.s_addr = inet_addr(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, (unsigned char *) peer);
	iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);
	res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 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 ? (unsigned char *) reason : (unsigned char *) "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 ? (unsigned char *) byemsg : (unsigned char *) "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, 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);
}

int iax_send_url(struct iax_session *session, char *url, int link)
{
	return send_command(session, AST_FRAME_HTML, link ? AST_HTML_LINKURL : AST_HTML_URL, 0, (unsigned char *) url, strlen(url), -1);
}

int iax_send_text(struct iax_session *session, char *text)
{
	return send_command(session, AST_FRAME_TEXT, 0, 0, (unsigned char *) text, 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;

        memset(&ied, 0, sizeof(ied));
#ifdef NEWJB
	{
	    jb_info stats;
	    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, 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);
	}
#else
	    iax_ie_append_int(&ied,IAX_IE_RR_JITTER, session->jitter);
	    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
	    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_PKTS, stats.frames_in); */
	    /* don't know, don't send! iax_ie_append_short(&ied,IAX_IE_RR_DELAY, stats.current - stats.min); */
#endif

	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;

⌨️ 快捷键说明

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