Version 0.2.0 from FTP

git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@14 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Mark Spencer 2001-11-29 18:09:09 +00:00
parent 0aa2e6fe6c
commit ecca15537d

97
q921.c
View File

@ -32,6 +32,15 @@
#include "pri_q921.h"
#include "pri_q931.h"
/*
* Define RANDOM_DROPS To randomly drop packets in order to simulate loss for testing
* retransmission functionality
*/
/*
#define RANDOM_DROPS
*/
#define Q921_INIT(hf) do { \
(hf).h.sapi = 0; \
(hf).h.ea1 = 0; \
@ -54,6 +63,13 @@ static void q921_discard_retransmissions(struct pri *pri)
static int q921_transmit(struct pri *pri, q921_h *h, int len) {
int res;
#ifdef RANDOM_DROPS
if (!(random() % 3)) {
printf(" === Dropping Packet ===\n");
return 0;
}
#endif
/* Just send it raw */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
@ -159,9 +175,9 @@ static void q921_ack_rx(struct pri *pri, int ack)
/* Cancel each packet as necessary */
for (x=pri->v_a; x != ack; Q921_INC(x))
cnt += q921_ack_packet(pri, x);
if (cnt) {
if (!pri->txqueue) {
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Since there was something acked, stopping T200 counter\n");
printf("-- Since there wis nothing left, stopping T200 counter\n");
/* Something was ACK'd. Stop T200 counter */
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
@ -211,13 +227,15 @@ static void q921_rr(struct pri *pri, int pbit) {
q921_transmit(pri, &h, 4);
}
static pri_event *q921_dchannel_down(struct pri *pri);
static void t200_expire(void *vpri)
{
struct pri *pri = vpri;
if (pri->txqueue) {
/* Retransmit first packet in the queue, setting the poll bit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("T200 counter expired, resending last frame and scheduling t200 again (retrans so far = %d)\n", pri->retrans);
printf("-- T200 counter expired, What to do...\n");
/* Force Poll bit */
pri->txqueue->h.p_f = 1;
/* Update nr */
@ -225,11 +243,28 @@ static void t200_expire(void *vpri)
pri->v_na = pri->v_r;
pri->solicitfbit = 1;
pri->retrans++;
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
/* Up to three retransmissions */
if (pri->retrans < N_200) {
/* Reschedule t200_timer */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Retransmitting %d bytes\n", pri->txqueue->len);
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Rescheduling retransmission (%d)\n", pri->retrans);
pri->t200_timer = pri_schedule_event(pri, T_200, t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Timeout occured, restarting PRI\n");
pri->state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
q921_start(pri);
pri->schedev = 1;
}
} else {
fprintf(stderr, "T200 counter expired, nothing to send...\n");
pri->t200_timer = 0;
}
pri->t200_timer = 0;
}
int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
@ -474,6 +509,7 @@ void q921_reset(struct pri *pri)
pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
{
q921_frame *f;
/* Discard FCS */
len -= 2;
@ -534,8 +570,57 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
pri->solicitfbit = 0;
}
break;
#if 0
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Got receiver not ready\n");
pri->busy = 1;
break;
#endif
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- 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);
}
/* Resend the proper I-frame */
for(f=pri->txqueue;f;f=f->next) {
if (f->h.n_s == h->s.n_r) {
/* Matches the request */
break;
}
}
if (f) {
/* Retransmit the requested frame */
q921_transmit(pri, (q921_h *)(&f->h), f->len);
} else {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
fprintf(stderr, "!! 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->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:
fprintf(stderr, "!! XXX Unknown Supervisory frame XXX\n");
fprintf(stderr, "!! 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: