patch-2.1.44 linux/net/ax25/ax25_out.c
Next file: linux/net/ax25/ax25_route.c
Previous file: linux/net/ax25/ax25_ip.c
Back to the patch index
Back to the overall index
- Lines: 264
- Date:
Mon Jul 7 08:19:59 1997
- Orig file:
v2.1.43/linux/net/ax25/ax25_out.c
- Orig date:
Thu May 29 21:53:11 1997
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_out.c linux/net/ax25/ax25_out.c
@@ -1,5 +1,5 @@
/*
- * AX.25 release 036
+ * AX.25 release 037
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
@@ -26,6 +26,7 @@
* AX.25 I-Frames. Added PACLEN parameter.
* Joerg(DL1BKE) Fixed a problem with buffer allocation
* for fragments.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
*/
#include <linux/config.h>
@@ -52,7 +53,7 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
-int ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct device *dev)
+ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct device *dev)
{
ax25_dev *ax25_dev;
ax25_cb *ax25;
@@ -65,15 +66,14 @@
*/
if ((ax25 = ax25_find_cb(src, dest, digi, dev)) != NULL) {
ax25_output(ax25, paclen, skb);
- ax25->idletimer = ax25->idle;
- return 1; /* It already existed */
+ return ax25; /* It already existed */
}
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
- return 0;
+ return NULL;
if ((ax25 = ax25_create_cb()) == NULL)
- return 0;
+ return NULL;
ax25_fillin_cb(ax25, ax25_dev);
@@ -83,11 +83,9 @@
if (digi != NULL) {
if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
ax25_free_cb(ax25);
- return 0;
+ return NULL;
}
*ax25->digipeat = *digi;
- } else {
- ax25_rt_build_path(ax25, dest, dev);
}
switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
@@ -106,19 +104,15 @@
#endif
}
- /* idle timeouts only for mode vc connections */
-
- ax25->idletimer = ax25->idle;
-
ax25_insert_socket(ax25);
ax25->state = AX25_STATE_1;
- ax25_set_timer(ax25);
+ ax25_start_heartbeat(ax25);
ax25_output(ax25, paclen, skb);
- return 1; /* We had to create it */
+ return ax25; /* We had to create it */
}
/*
@@ -195,10 +189,8 @@
}
if (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_SIMPLEX ||
- ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_DUPLEX) {
- if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4)
- ax25_kick(ax25);
- }
+ ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_DUPLEX)
+ ax25_kick(ax25);
}
/*
@@ -228,6 +220,8 @@
frame[1] |= (ax25->vr << 1);
}
+ ax25_start_idletimer(ax25);
+
ax25_transmit_buffer(ax25, skb, AX25_COMMAND);
}
@@ -237,76 +231,80 @@
int last = 1;
unsigned short start, end, next;
- del_timer(&ax25->timer);
+ if (ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
+ return;
+
+ if (ax25->condition & AX25_COND_PEER_RX_BUSY)
+ return;
+
+ if (skb_peek(&ax25->write_queue) == NULL)
+ return;
start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
end = (ax25->va + ax25->window) % ax25->modulus;
- if (!(ax25->condition & AX25_COND_PEER_RX_BUSY) &&
- start != end &&
- skb_peek(&ax25->write_queue) != NULL) {
+ if (start == end)
+ return;
- ax25->vs = start;
+ ax25->vs = start;
- /*
- * Transmit data until either we're out of data to send or
- * the window is full. Send a poll on the final I frame if
- * the window is filled.
- */
+ /*
+ * Transmit data until either we're out of data to send or
+ * the window is full. Send a poll on the final I frame if
+ * the window is filled.
+ */
- /*
- * Dequeue the frame and copy it.
- */
- skb = skb_dequeue(&ax25->write_queue);
+ /*
+ * Dequeue the frame and copy it.
+ */
+ skb = skb_dequeue(&ax25->write_queue);
- do {
- if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
- skb_queue_head(&ax25->write_queue, skb);
- break;
- }
+ do {
+ if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+ skb_queue_head(&ax25->write_queue, skb);
+ break;
+ }
- if (skb->sk != NULL)
- skb_set_owner_w(skbn, skb->sk);
+ if (skb->sk != NULL)
+ skb_set_owner_w(skbn, skb->sk);
- next = (ax25->vs + 1) % ax25->modulus;
- last = (next == end);
+ next = (ax25->vs + 1) % ax25->modulus;
+ last = (next == end);
- /*
- * Transmit the frame copy.
- * bke 960114: do not set the Poll bit on the last frame
- * in DAMA mode.
- */
- switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
- case AX25_PROTO_STD_SIMPLEX:
- case AX25_PROTO_STD_DUPLEX:
- ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
- break;
+ /*
+ * Transmit the frame copy.
+ * bke 960114: do not set the Poll bit on the last frame
+ * in DAMA mode.
+ */
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
+ break;
#ifdef CONFIG_AX25_DAMA_SLAVE
- case AX25_PROTO_DAMA_SLAVE:
- ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
- break;
+ case AX25_PROTO_DAMA_SLAVE:
+ ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
+ break;
#endif
- }
+ }
- ax25->vs = next;
+ ax25->vs = next;
- /*
- * Requeue the original data frame.
- */
- skb_queue_tail(&ax25->ack_queue, skb);
+ /*
+ * Requeue the original data frame.
+ */
+ skb_queue_tail(&ax25->ack_queue, skb);
- } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
+ } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
- ax25->condition &= ~AX25_COND_ACK_PENDING;
+ ax25->condition &= ~AX25_COND_ACK_PENDING;
- if (ax25->t1timer == 0) {
- ax25->t3timer = 0;
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
- }
+ if (!ax25_t1timer_running(ax25)) {
+ ax25_stop_t3timer(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
}
-
- ax25_set_timer(ax25);
}
void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
@@ -316,14 +314,7 @@
int headroom;
if (ax25->ax25_dev == NULL) {
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ENETUNREACH;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ENETUNREACH);
return;
}
@@ -381,12 +372,13 @@
if (ax25->vs == nr) {
ax25_frames_acked(ax25, nr);
ax25_calculate_rtt(ax25);
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
+ ax25_stop_t1timer(ax25);
+ ax25_start_t3timer(ax25);
} else {
if (ax25->va != nr) {
ax25_frames_acked(ax25, nr);
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
}
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov