?? q921.c
字號:
/* 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(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; };}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 */ 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; 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; 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; /* 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(pri, "!! Got I-frame while link state %d\n", pri->q921_state); return NULL; } /* Informational frame */ if (len < 4) { pri_error(pri, "!! 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(pri, "!! Got S-frame while link down\n"); return NULL; } if (len < 4) { pri_error(pri, "!! 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_DUMP) pri_message(pri, "-- Got RR response to our frame\n"); } else { if (pri->debug & PRI_DEBUG_Q921_DUMP) pri_message(pri, "-- 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_DUMP) pri_message(pri, "-- 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_DUMP) pri_message(pri, "-- 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(pri, "!! 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(pri, "!! 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(pri, "!! 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, pri->timers[PRI_TIMER_T203], t203_expire, pri); } } break; default: pri_error(pri, "!! 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(pri, "!! 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_DEBUG_Q921_DUMP)) pri_message(pri, "-- 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_DUMP) pri_message(pri, "-- 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(pri, "XXX Unnumbered Information not implemented XXX\n"); } break; case 2: if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) pri_message(pri, "-- 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_DEBUG_Q921_DUMP)) { pri_message(pri, "-- 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_DEBUG_Q921_DUMP)) { pri_message(pri, "-- Got UA from %s peer Link up.\n", h->h.c_r ? "cpe" : "network"); } return q921_dchannel_up(pri); } else pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state); } else pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2); break; case 4: pri_error(pri, "!! Frame got rejected!\n"); break; case 5: pri_error(pri, "!! XID frames not supported\n"); break; default: pri_error(pri, "!! 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 | PRI_DEBUG_Q921_RAW)) q921_dump(pri, 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(pri, "!! 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 + -