📄 q921.c
字号:
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 + -