0001
0002
0003
0004
0005
0006 #include <linux/errno.h>
0007 #include <linux/types.h>
0008 #include <linux/socket.h>
0009 #include <linux/in.h>
0010 #include <linux/kernel.h>
0011 #include <linux/timer.h>
0012 #include <linux/string.h>
0013 #include <linux/sockios.h>
0014 #include <linux/net.h>
0015 #include <linux/gfp.h>
0016 #include <net/ax25.h>
0017 #include <linux/inet.h>
0018 #include <linux/netdevice.h>
0019 #include <linux/skbuff.h>
0020 #include <net/sock.h>
0021 #include <linux/fcntl.h>
0022 #include <linux/mm.h>
0023 #include <linux/interrupt.h>
0024 #include <net/rose.h>
0025
0026
0027
0028
0029
0030 static void rose_send_iframe(struct sock *sk, struct sk_buff *skb)
0031 {
0032 struct rose_sock *rose = rose_sk(sk);
0033
0034 if (skb == NULL)
0035 return;
0036
0037 skb->data[2] |= (rose->vr << 5) & 0xE0;
0038 skb->data[2] |= (rose->vs << 1) & 0x0E;
0039
0040 rose_start_idletimer(sk);
0041
0042 rose_transmit_link(skb, rose->neighbour);
0043 }
0044
0045 void rose_kick(struct sock *sk)
0046 {
0047 struct rose_sock *rose = rose_sk(sk);
0048 struct sk_buff *skb, *skbn;
0049 unsigned short start, end;
0050
0051 if (rose->state != ROSE_STATE_3)
0052 return;
0053
0054 if (rose->condition & ROSE_COND_PEER_RX_BUSY)
0055 return;
0056
0057 if (!skb_peek(&sk->sk_write_queue))
0058 return;
0059
0060 start = (skb_peek(&rose->ack_queue) == NULL) ? rose->va : rose->vs;
0061 end = (rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
0062
0063 if (start == end)
0064 return;
0065
0066 rose->vs = start;
0067
0068
0069
0070
0071
0072
0073 skb = skb_dequeue(&sk->sk_write_queue);
0074
0075 do {
0076 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
0077 skb_queue_head(&sk->sk_write_queue, skb);
0078 break;
0079 }
0080
0081 skb_set_owner_w(skbn, sk);
0082
0083
0084
0085
0086 rose_send_iframe(sk, skbn);
0087
0088 rose->vs = (rose->vs + 1) % ROSE_MODULUS;
0089
0090
0091
0092
0093 skb_queue_tail(&rose->ack_queue, skb);
0094
0095 } while (rose->vs != end &&
0096 (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
0097
0098 rose->vl = rose->vr;
0099 rose->condition &= ~ROSE_COND_ACK_PENDING;
0100
0101 rose_stop_timer(sk);
0102 }
0103
0104
0105
0106
0107
0108
0109 void rose_enquiry_response(struct sock *sk)
0110 {
0111 struct rose_sock *rose = rose_sk(sk);
0112
0113 if (rose->condition & ROSE_COND_OWN_RX_BUSY)
0114 rose_write_internal(sk, ROSE_RNR);
0115 else
0116 rose_write_internal(sk, ROSE_RR);
0117
0118 rose->vl = rose->vr;
0119 rose->condition &= ~ROSE_COND_ACK_PENDING;
0120
0121 rose_stop_timer(sk);
0122 }