0001
0002
0003
0004
0005
0006
0007 #include <linux/errno.h>
0008 #include <linux/types.h>
0009 #include <linux/socket.h>
0010 #include <linux/in.h>
0011 #include <linux/kernel.h>
0012 #include <linux/timer.h>
0013 #include <linux/string.h>
0014 #include <linux/sockios.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/net.h>
0017 #include <linux/gfp.h>
0018 #include <net/ax25.h>
0019 #include <linux/inet.h>
0020 #include <linux/netdevice.h>
0021 #include <linux/skbuff.h>
0022 #include <net/sock.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/fcntl.h>
0025 #include <linux/mm.h>
0026 #include <linux/interrupt.h>
0027
0028 void ax25_ds_nr_error_recovery(ax25_cb *ax25)
0029 {
0030 ax25_ds_establish_data_link(ax25);
0031 }
0032
0033
0034
0035
0036 void ax25_ds_enquiry_response(ax25_cb *ax25)
0037 {
0038 ax25_cb *ax25o;
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 ax25_std_enquiry_response(ax25);
0064
0065 if (!(ax25->condition & AX25_COND_PEER_RX_BUSY)) {
0066 ax25_requeue_frames(ax25);
0067 ax25_kick(ax25);
0068 }
0069
0070 if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 || skb_peek(&ax25->ack_queue) != NULL)
0071 ax25_ds_t1_timeout(ax25);
0072 else
0073 ax25->n2count = 0;
0074
0075 ax25_start_t3timer(ax25);
0076 ax25_ds_set_timer(ax25->ax25_dev);
0077
0078 spin_lock(&ax25_list_lock);
0079 ax25_for_each(ax25o, &ax25_list) {
0080 if (ax25o == ax25)
0081 continue;
0082
0083 if (ax25o->ax25_dev != ax25->ax25_dev)
0084 continue;
0085
0086 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
0087 ax25_ds_t1_timeout(ax25o);
0088 continue;
0089 }
0090
0091 if (!(ax25o->condition & AX25_COND_PEER_RX_BUSY) && ax25o->state == AX25_STATE_3) {
0092 ax25_requeue_frames(ax25o);
0093 ax25_kick(ax25o);
0094 }
0095
0096 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 || skb_peek(&ax25o->ack_queue) != NULL)
0097 ax25_ds_t1_timeout(ax25o);
0098
0099
0100
0101 if (ax25o->state != AX25_STATE_0)
0102 ax25_start_t3timer(ax25o);
0103 }
0104 spin_unlock(&ax25_list_lock);
0105 }
0106
0107 void ax25_ds_establish_data_link(ax25_cb *ax25)
0108 {
0109 ax25->condition &= AX25_COND_DAMA_MODE;
0110 ax25->n2count = 0;
0111 ax25_calculate_t1(ax25);
0112 ax25_start_t1timer(ax25);
0113 ax25_stop_t2timer(ax25);
0114 ax25_start_t3timer(ax25);
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124 static void ax25_kiss_cmd(ax25_dev *ax25_dev, unsigned char cmd, unsigned char param)
0125 {
0126 struct sk_buff *skb;
0127 unsigned char *p;
0128
0129 if (ax25_dev->dev == NULL)
0130 return;
0131
0132 if ((skb = alloc_skb(2, GFP_ATOMIC)) == NULL)
0133 return;
0134
0135 skb_reset_network_header(skb);
0136 p = skb_put(skb, 2);
0137
0138 *p++ = cmd;
0139 *p++ = param;
0140
0141 skb->protocol = ax25_type_trans(skb, ax25_dev->dev);
0142
0143 dev_queue_xmit(skb);
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 static int ax25_check_dama_slave(ax25_dev *ax25_dev)
0155 {
0156 ax25_cb *ax25;
0157 int res = 0;
0158
0159 spin_lock(&ax25_list_lock);
0160 ax25_for_each(ax25, &ax25_list)
0161 if (ax25->ax25_dev == ax25_dev && (ax25->condition & AX25_COND_DAMA_MODE) && ax25->state > AX25_STATE_1) {
0162 res = 1;
0163 break;
0164 }
0165 spin_unlock(&ax25_list_lock);
0166
0167 return res;
0168 }
0169
0170 static void ax25_dev_dama_on(ax25_dev *ax25_dev)
0171 {
0172 if (ax25_dev == NULL)
0173 return;
0174
0175 if (ax25_dev->dama.slave == 0)
0176 ax25_kiss_cmd(ax25_dev, 5, 1);
0177
0178 ax25_dev->dama.slave = 1;
0179 ax25_ds_set_timer(ax25_dev);
0180 }
0181
0182 void ax25_dev_dama_off(ax25_dev *ax25_dev)
0183 {
0184 if (ax25_dev == NULL)
0185 return;
0186
0187 if (ax25_dev->dama.slave && !ax25_check_dama_slave(ax25_dev)) {
0188 ax25_kiss_cmd(ax25_dev, 5, 0);
0189 ax25_dev->dama.slave = 0;
0190 ax25_ds_del_timer(ax25_dev);
0191 }
0192 }
0193
0194 void ax25_dama_on(ax25_cb *ax25)
0195 {
0196 ax25_dev_dama_on(ax25->ax25_dev);
0197 ax25->condition |= AX25_COND_DAMA_MODE;
0198 }
0199
0200 void ax25_dama_off(ax25_cb *ax25)
0201 {
0202 ax25->condition &= ~AX25_COND_DAMA_MODE;
0203 ax25_dev_dama_off(ax25->ax25_dev);
0204 }