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

📄 q921.c

📁 This a software PBX driver
💻 C
📖 第 1 页 / 共 2 页
字号:
		Q921_INC(pri->v_r);		/* Handle their ACK */		pri->sentrej = 0;		ev = q921_ack_rx(pri, i->n_r);		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) {			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(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("\n%c [ %s]\n", direction_tag, buf);			free(buf);		}	}	switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {	case 0:	case 2:		pri_message("\n%c Informational frame:\n", direction_tag);		break;	case 1:		pri_message("\n%c Supervisory frame:\n", direction_tag);		break;	case 3:		pri_message("\n%c Unnumbered frame:\n", direction_tag);		break;	}		pri_message("%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("%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("%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("%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;	};}static pri_event *q921_dchannel_up(struct pri *pri){	/* Reset counters, etc */	q921_reset(pri);		/* Stop any SABME retransmissions */	pri_schedule_del(pri, pri->sabme_timer);	pri->sabme_timer = 0;		/* Reset any rejects */	pri->sentrej = 0;		/* Go into connection established state */	pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;	/* Start the T203 timer */	pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);		/* 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);		/* 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 = 7;	pri->windowlen = 0;	pri_schedule_del(pri, pri->sabme_timer);	pri_schedule_del(pri, pri->t203_timer);	pri_schedule_del(pri, pri->t200_timer);	pri->sabme_timer = 0;	pri->t203_timer = 0;	pri->t200_timer = 0;	pri->busy = 0;	pri->solicitfbit = 0;	pri->q921_state = Q921_LINK_CONNECTION_RELEASED;	pri->retrans = 0;	pri->sentrej = 0;		/* Discard anything waiting to go out */	q921_discard_retransmissions(pri);}static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len){	q921_frame *f;	pri_event *ev;	int sendnow;	switch(h->h.data[0] & Q921_FRAMETYPE_MASK) {	case 0:	case 2:		if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {			pri_error("!! Got I-frame while link state %d\n", pri->q921_state);			return NULL;		}		/* Informational frame */		if (len < 4) {			pri_error("!! Received short I-frame (expected 4, got %d)\n", len);			break;		}		return q921_handle_iframe(pri, &h->i, len);			break;	case 1:		if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {			pri_error("!! Got S-frame while link down\n");			return NULL;		}		if (len < 4) {			pri_error("!! Received short S-frame (expected 4, got %d)\n", len);			break;		}		switch(h->s.ss) {		case 0:			/* Receiver Ready */			pri->busy = 0;			/* Acknowledge frames as necessary */			ev = q921_ack_rx(pri, h->s.n_r);			if (ev)				return ev;			if (h->s.p_f) {				/* If it's a p/f one then send back a RR in return with the p/f bit set */				if (pri->solicitfbit) {					if (pri->debug & PRI_DEBUG_Q921_STATE) 						pri_message("-- Got RR response to our frame\n");				} else {					if (pri->debug & PRI_DEBUG_Q921_STATE) 						pri_message("-- Unsolicited RR with P/F bit, responding\n");						q921_rr(pri, 1, 0);				}				pri->solicitfbit = 0;			}			break;      case 1:         /* Receiver not ready */         if (pri->debug & PRI_DEBUG_Q921_STATE)            pri_message("-- Got receiver not ready\n");	 if(h->s.p_f) {		/* Send RR if poll bit set */		q921_rr(pri, h->s.p_f, 0);	 }         pri->busy = 1;         break;         case 2:         /* Just retransmit */         if (pri->debug & PRI_DEBUG_Q921_STATE)            pri_message("-- Got reject requesting packet %d...  Retransmitting.\n", h->s.n_r);         if (h->s.p_f) {            /* If it has the poll bit set, send an appropriate supervisory response */            q921_rr(pri, 1, 0);         }		 sendnow = 0;         /* Resend the proper I-frame */         for(f=pri->txqueue;f;f=f->next) {               if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {                     /* Matches the request, or follows in our window, and has					    already been transmitted. */					 sendnow = 1;					 pri_error("!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);				     f->h.n_r = pri->v_r;                     q921_transmit(pri, (q921_h *)(&f->h), f->len);               }         }         if (!sendnow) {               if (pri->txqueue) {                     /* This should never happen */		     if (!h->s.p_f || h->s.n_r) {			pri_error("!! Got reject for frame %d, but we only have others!\n", h->s.n_r);		     }               } else {                     /* Hrm, we have nothing to send, but have been REJ'd.  Reset v_a, v_s, etc */				pri_error("!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);                     pri->v_a = h->s.n_r;                     pri->v_s = h->s.n_r;                     /* Reset t200 timer if it was somehow going */                     if (pri->t200_timer) {                           pri_schedule_del(pri, pri->t200_timer);                           pri->t200_timer = 0;                     }                     /* Reset and restart t203 timer */                     if (pri->t203_timer)                           pri_schedule_del(pri, pri->t203_timer);                     pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);               }         }         break;		default:			pri_error("!! XXX Unknown Supervisory frame ss=0x%02x,pf=%02xnr=%02x vs=%02x, va=%02x XXX\n", h->s.ss, h->s.p_f, h->s.n_r,					pri->v_s, pri->v_a);		}		break;	case 3:		if (len < 3) {			pri_error("!! Received short unnumbered frame\n");			break;		}		switch(h->u.m3) {		case 0:			if (h->u.m2 == 3) {				if (h->u.p_f) {					/* Section 5.7.1 says we should restart on receiving a DM response with the f-bit set to					   one, but we wait T200 first */					if (pri->debug & PRI_DEBUG_Q921_STATE)						pri_message("-- Got DM Mode from peer.\n");					/* Disconnected mode, try again after T200 */					ev = q921_dchannel_down(pri);					q921_start(pri, 0);					return ev;										} else {					if (pri->debug & PRI_DEBUG_Q921_STATE)						pri_message("-- Ignoring unsolicited DM with p/f set to 0\n");#if 0					/* Requesting that we start */					q921_start(pri, 0);#endif									}				break;			} else if (!h->u.m2) {				pri_message("XXX Unnumbered Information not implemented XXX\n");			}			break;		case 2:			if (pri->debug &  PRI_DEBUG_Q921_STATE)				pri_message("-- Got Disconnect from peer.\n");			/* Acknowledge */			q921_send_ua(pri, h->u.p_f);			ev = q921_dchannel_down(pri);			q921_start(pri, 0);			return ev;		case 3:			if (h->u.m2 == 3) {				/* SABME */				if (pri->debug & PRI_DEBUG_Q921_STATE) {					pri_message("-- Got SABME from %s peer.\n", h->h.c_r ? "network" : "cpe");				}				if (h->h.c_r) {					pri->remotetype = PRI_NETWORK;					if (pri->localtype == PRI_NETWORK) {						/* We can't both be networks */						return pri_mkerror(pri, "We think we're the network, but they think they're the network, too.");					}				} else {					pri->remotetype = PRI_CPE;					if (pri->localtype == PRI_CPE) {						/* We can't both be CPE */						return pri_mkerror(pri, "We think we're the CPE, but they think they're the CPE too.\n");					}				}				/* Send Unnumbered Acknowledgement */				q921_send_ua(pri, h->u.p_f);				return q921_dchannel_up(pri);			} else if (h->u.m2 == 0) {					/* It's a UA */				if (pri->q921_state == Q921_AWAITING_ESTABLISH) {					if (pri->debug & PRI_DEBUG_Q921_STATE) {						pri_message("-- Got UA from %s peer  Link up.\n", h->h.c_r ? "cpe" : "network");					}					return q921_dchannel_up(pri);				} else 					pri_error("!! Got a UA, but i'm in state %d\n", pri->q921_state);			} else 				pri_error("!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);			break;		case 4:			pri_error("!! Frame got rejected!\n");			break;		case 5:			pri_error("!! XID frames not supported\n");			break;		default:			pri_error("!! Don't know what to do with M3=%d u-frames\n", h->u.m3);		}		break;					}	return NULL;}static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len){	pri_event *ev;	/* Discard FCS */	len -= 2;		if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)		q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);	/* Check some reject conditions -- Start by rejecting improper ea's */	if (h->h.ea1 || !(h->h.ea2))		return NULL;	/* Check for broadcasts - not yet handled */	if (h->h.tei == Q921_TEI_GROUP)		return NULL;	/* Check for SAPIs we don't yet handle */	if ((h->h.sapi != pri->sapi) || (h->h.tei != pri->tei)) {#ifdef PROCESS_SUBCHANNELS		/* If it's not us, try any subchannels we have */		if (pri->subchannel)			return q921_receive(pri->subchannel, h, len + 2);		else #endif			return NULL;	}	ev = __q921_receive_qualified(pri, h, len);	reschedule_t203(pri);	return ev;}pri_event *q921_receive(struct pri *pri, q921_h *h, int len){	pri_event *e;	e = __q921_receive(pri, h, len);#ifdef LIBPRI_COUNTERS	pri->q921_rxcount++;#endif	return e;}void q921_start(struct pri *pri, int now){	if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {		pri_error("!! q921_start: Not in 'Link Connection Released' state\n");		return;	}	/* Reset our interface */	q921_reset(pri);	/* Do the SABME XXX Maybe we should implement T_WAIT? XXX */	q921_send_sabme(pri, now);}

⌨️ 快捷键说明

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