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

📄 q921.c

📁 Q.931/Q.921 source code compiles
💻 C
📖 第 1 页 / 共 3 页
字号:
					lastframe->h.p_f = 1;					/* Update nr */					lastframe->h.n_r = pri->v_r;					pri->v_na = pri->v_r;					q921_transmit(pri, (q921_h *)&lastframe->h, lastframe->len);				}			}			if (pri->debug & PRI_DEBUG_Q921_DUMP)			      pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);			pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);		} else {			if (pri->debug & PRI_DEBUG_Q921_STATE)			      pri_message(pri, "-- Timeout occured, restarting PRI\n");			if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)			     pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n",DBGINFO);			pri->q921_state = Q921_LINK_CONNECTION_RELEASED;			     pri->t200_timer = 0;			if (pri->bri && pri->master) {				q921_tei_release_and_reacquire(pri->master);				return;			} else {				q921_dchannel_down(pri);				q921_start(pri, 1);				pri->schedev = 1;			}		}	} else if (pri->solicitfbit) {		if (pri->debug & PRI_DEBUG_Q921_DUMP)			pri_message(pri, "-- Retrying poll with f-bit\n");		if (pri->retrans < pri->timers[PRI_TIMER_N200]) {			pri->retrans++;			pri->solicitfbit = 1;			q921_rr(pri, 1, 1);			pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);		} else {			if (pri->debug & PRI_DEBUG_Q921_STATE)				pri_message(pri, "-- Timeout occured, restarting PRI\n");			if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)				pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);			pri->q921_state = Q921_LINK_CONNECTION_RELEASED;			pri->t200_timer = 0;			if (pri->bri && pri->master) {				q921_tei_release_and_reacquire(pri->master);				return;			} else {				q921_dchannel_down(pri);				q921_start(pri, 1);				pri->schedev = 1;			}		}	} else {		pri_error(pri, "T200 counter expired, nothing to send...\n");	   	pri->t200_timer = 0;	}}int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr){	q921_frame *f, *prev=NULL;	for (f=pri->txqueue; f; f = f->next) prev = f;	f = calloc(1, sizeof(q921_frame) + len + 2);	if (f) {		Q921_INIT(pri, f->h);		switch(pri->localtype) {		case PRI_NETWORK:			if (cr)				f->h.h.c_r = 1;			else				f->h.h.c_r = 0;		break;		case PRI_CPE:			if (cr)				f->h.h.c_r = 0;			else				f->h.h.c_r = 1;		break;		}		f->next = NULL;		f->transmitted = 0;		f->len = len + 4;		memcpy(f->h.data, buf, len);		f->h.n_s = pri->v_s;		f->h.n_r = pri->v_r;		pri->v_s++;		pri->v_na = pri->v_r;		f->h.p_f = 0;		f->h.ft = 0;		if (prev)			prev->next = f;		else			pri->txqueue = f;		/* Immediately transmit unless we're in a recovery state, or the window		   size is too big */		if (!pri->retrans && !pri->busy) {			if (pri->windowlen < pri->window) {				pri->windowlen++;				q921_transmit(pri, (q921_h *)(&f->h), f->len);				f->transmitted++;			} else {				if (pri->debug & PRI_DEBUG_Q921_DUMP)					pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n", 						f->h.n_s, pri->windowlen, pri->window);			}		}		if (pri->t203_timer) {			if (pri->debug & PRI_DEBUG_Q921_DUMP)				pri_message(pri, "Stopping T_203 timer\n");			pri_schedule_del(pri, pri->t203_timer);			pri->t203_timer = 0;		}		if (pri->debug & PRI_DEBUG_Q921_DUMP)			pri_message(pri, "Starting T_200 timer\n");		reschedule_t200(pri);			} else {		pri_error(pri, "!! Out of memory for Q.921 transmit\n");		return -1;	}	return 0;}static void t203_expire(void *vpri){	struct pri *pri = vpri;	if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {		if (pri->debug & PRI_DEBUG_Q921_DUMP)			pri_message(pri, "T203 counter expired, sending RR and scheduling T203 again\n");		/* Solicit an F-bit in the other's RR */		pri->solicitfbit = 1;		pri->retrans = 0;		q921_rr(pri, 1, 1);		/* Start timer T200 to resend our RR if we don't get it */		pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);	} else {		if (pri->debug & PRI_DEBUG_Q921_DUMP)			pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);		pri->t203_timer = 0;	}}static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len){	int res;	pri_event *ev;	pri->solicitfbit = 0;	/* Make sure this is a valid packet */	if (i->n_s == pri->v_r) {		/* Increment next expected I-frame */		Q921_INC(pri->v_r);		/* Handle their ACK */		pri->sentrej = 0;		ev = q921_ack_rx(pri, i->n_r, 0);		if (ev)			return ev;		if (i->p_f) {			/* If the Poll/Final bit is set, immediate send the RR */			q921_rr(pri, 1, 0);		} else if (pri->busy || pri->retrans) {			q921_rr(pri, 0, 0); 		}		/* Receive Q.931 data */		res = q931_receive(pri, (q931_h *)i->data, len - 4);		/* Send an RR if one wasn't sent already */		if (pri->v_na != pri->v_r) 			q921_rr(pri, 0, 0);		if (res == -1) {			return NULL;		}		if (res & Q931_RES_HAVEEVENT)			return &pri->ev;	} else {		/* If we haven't already sent a reject, send it now, otherwise		   we are obliged to RR */		if (!pri->sentrej)			q921_reject(pri, i->p_f);		else if (i->p_f)			q921_rr(pri, 1, 0);	}	return NULL;}void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx){	int x;        char *type;	char direction_tag;		direction_tag = txrx ? '>' : '<';	if (showraw) {		char *buf = malloc(len * 3 + 1);		int buflen = 0;		if (buf) {			for (x=0;x<len;x++) 				buflen += sprintf(buf + buflen, "%02x ", h->raw[x]);			pri_message(pri, "\n%c [ %s]\n", direction_tag, buf);			free(buf);		}	}	switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {	case 0:	case 2:		pri_message(pri, "\n%c Informational frame:\n", direction_tag);		break;	case 1:		pri_message(pri, "\n%c Supervisory frame:\n", direction_tag);		break;	case 3:		pri_message(pri, "\n%c Unnumbered frame:\n", direction_tag);		break;	}		pri_message(pri, "%c SAPI: %02d  C/R: %d EA: %d\n""%c  TEI: %03d        EA: %d\n",     	direction_tag,	h->h.sapi, 	h->h.c_r,	h->h.ea1,    	direction_tag,	h->h.tei,	h->h.ea2);	switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {	case 0:	case 2:		/* Informational frame */		pri_message(pri, "%c N(S): %03d   0: %d\n""%c N(R): %03d   P: %d\n""%c %d bytes of data\n",    	direction_tag,	h->i.n_s,	h->i.ft,    	direction_tag,	h->i.n_r,	h->i.p_f,     	direction_tag,	len - 4);		break;	case 1:		/* Supervisory frame */		type = "???";		switch (h->s.ss) {		case 0:			type = "RR (receive ready)";			break;		case 1:			type = "RNR (receive not ready)";			break;		case 2:			type = "REJ (reject)";			break;		}		pri_message(pri, "%c Zero: %d     S: %d 01: %d  [ %s ]\n""%c N(R): %03d P/F: %d\n""%c %d bytes of data\n",    	direction_tag,	h->s.x0,	h->s.ss,	h->s.ft,	type,	direction_tag,	h->s.n_r,	h->s.p_f, 	direction_tag,	len - 4);		break;	case 3:				/* Unnumbered frame */		type = "???";		if (h->u.ft == 3) {			switch (h->u.m3) {			case 0:				if (h->u.m2 == 3)					type = "DM (disconnect mode)";				else if (h->u.m2 == 0)					type = "UI (unnumbered information)";				break;			case 2:				if (h->u.m2 == 0)					type = "DISC (disconnect)";				break;			case 3:			       	if (h->u.m2 == 3)					type = "SABME (set asynchronous balanced mode extended)";				else if (h->u.m2 == 0)					type = "UA (unnumbered acknowledgement)";				break;			case 4:				if (h->u.m2 == 1)					type = "FRMR (frame reject)";				break;			case 5:				if (h->u.m2 == 3)					type = "XID (exchange identification note)";				break;			}		}		pri_message(pri, "%c   M3: %d   P/F: %d M2: %d 11: %d  [ %s ]\n""%c %d bytes of data\n",	direction_tag,	h->u.m3,	h->u.p_f,	h->u.m2,	h->u.ft,	type,	direction_tag,	len - 3);		break;	};	if ((h->u.ft == 3) && (h->u.m3 == 0) && (h->u.m2 == 0) && (h->u.data[0] == 0x0f)) {		int ri;		int tei;		ri = (h->u.data[1] << 8) | h->u.data[2];		tei = (h->u.data[4] >> 1);		/* TEI assignment related */		switch (h->u.data[3]) {		case Q921_TEI_IDENTITY_REQUEST:			type = "TEI Identity Request";			break;		case Q921_TEI_IDENTITY_ASSIGNED:			type = "TEI Identity Assigned";			break;		case Q921_TEI_IDENTITY_CHECK_REQUEST:			type = "TEI Identity Check Request";			break;		case Q921_TEI_IDENTITY_REMOVE:			type = "TEI Identity Remove";			break;		case Q921_TEI_IDENTITY_DENIED:			type = "TEI Identity Denied";			break;		case Q921_TEI_IDENTITY_CHECK_RESPONSE:			type = "TEI Identity Check Response";			break;		case Q921_TEI_IDENTITY_VERIFY:			type = "TEI Identity Verify";			break;		default:			type = "Unknown";			break;		}		pri_message(pri, "%c MDL Message: %s (%d)\n", direction_tag, type, h->u.data[3]);		pri_message(pri, "%c RI: %d\n", direction_tag, ri);		pri_message(pri, "%c Ai: %d E:%d\n", direction_tag, (h->u.data[4] >> 1) & 0x7f, h->u.data[4] & 1);	}}static pri_event *q921_dchannel_up(struct pri *pri){	/* Reset counters, etc */	q921_reset(pri);		/* Stop any SABME retransmissions */	if (pri->sabme_timer) {		pri_schedule_del(pri, pri->sabme_timer);		pri->sabme_timer = 0;	}		/* Reset any rejects */	pri->sentrej = 0;		/* Go into connection established state */	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED)		pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_ESTABLISHED\n", DBGINFO);	pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;	/* Start the T203 timer */	pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);		/* Notify Layer 3 */	q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);	/* Report event that D-Channel is now up */	pri->ev.gen.e = PRI_EVENT_DCHAN_UP;	return &pri->ev;}static pri_event *q921_dchannel_down(struct pri *pri){	/* Reset counters, reset sabme timer etc */	q921_reset(pri);		/* Notify Layer 3 */	q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);	/* Report event that D-Channel is now up */	pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;	return &pri->ev;}void q921_reset(struct pri *pri){	/* Having gotten a SABME we MUST reset our entire state */	pri->v_s = 0;	pri->v_a = 0;	pri->v_r = 0;	pri->v_na = 0;	pri->window = pri->timers[PRI_TIMER_K];	pri->windowlen = 0;	if (pri->sabme_timer)		pri_schedule_del(pri, pri->sabme_timer);	if (pri->t203_timer)		pri_schedule_del(pri, pri->t203_timer);	if (pri->t200_timer)		pri_schedule_del(pri, pri->t200_timer);	pri->sabme_timer = 0;	pri->sabme_count = 0;	pri->t203_timer = 0;	pri->t200_timer = 0;	pri->busy = 0;	pri->solicitfbit = 0;	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)		pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);	pri->q921_state = Q921_LINK_CONNECTION_RELEASED;	pri->retrans = 0;	pri->sentrej = 0;	

⌨️ 快捷键说明

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