1/* 2 * AX.25 release 037 3 * 4 * This code REQUIRES 2.1.15 or higher/ NET3.038 5 * 6 * This module: 7 * This module is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 * 12 * History 13 * AX.25 036 Jonathan(G4KLX) Cloned from ax25_timer.c. 14 * Joerg(DL1BKE) Added DAMA Slave Timeout timer 15 * AX.25 037 Jonathan(G4KLX) New timer architecture. 16 */ 17 18#include <linux/errno.h> 19#include <linux/types.h> 20#include <linux/socket.h> 21#include <linux/in.h> 22#include <linux/kernel.h> 23#include <linux/sched.h> 24#include <linux/timer.h> 25#include <linux/string.h> 26#include <linux/sockios.h> 27#include <linux/net.h> 28#include <net/ax25.h> 29#include <linux/inet.h> 30#include <linux/netdevice.h> 31#include <linux/skbuff.h> 32#include <net/sock.h> 33#include <asm/uaccess.h> 34#include <asm/system.h> 35#include <linux/fcntl.h> 36#include <linux/mm.h> 37#include <linux/interrupt.h> 38 39static void ax25_ds_timeout(unsigned long); 40 41/* 42 * Add DAMA slave timeout timer to timer list. 43 * Unlike the connection based timers the timeout function gets 44 * triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT 45 * (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in 46 * 1/10th of a second. 47 */ 48 49static void ax25_ds_add_timer(ax25_dev *ax25_dev) 50{ 51 struct timer_list *t = &ax25_dev->dama.slave_timer; 52 t->data = (unsigned long) ax25_dev; 53 t->function = &ax25_ds_timeout; 54 t->expires = jiffies + HZ; 55 add_timer(t); 56} 57 58void ax25_ds_del_timer(ax25_dev *ax25_dev) 59{ 60 if (ax25_dev) del_timer(&ax25_dev->dama.slave_timer); 61} 62 63void ax25_ds_set_timer(ax25_dev *ax25_dev) 64{ 65 if (ax25_dev == NULL) /* paranoia */ 66 return; 67 68 del_timer(&ax25_dev->dama.slave_timer); 69 ax25_dev->dama.slave_timeout = ax25_dev->values[AX25_VALUES_DS_TIMEOUT] / 10; 70 ax25_ds_add_timer(ax25_dev); 71} 72 73/* 74 * DAMA Slave Timeout 75 * Silently discard all (slave) connections in case our master forgot us... 76 */ 77 78static void ax25_ds_timeout(unsigned long arg) 79{ 80 ax25_dev *ax25_dev = (struct ax25_dev *) arg; 81 ax25_cb *ax25; 82 83 if (ax25_dev == NULL || !ax25_dev->dama.slave) 84 return; /* Yikes! */ 85 86 if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) { 87 ax25_ds_set_timer(ax25_dev); 88 return; 89 } 90 91 for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) { 92 if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE)) 93 continue; 94 95 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 96 ax25_disconnect(ax25, ETIMEDOUT); 97 } 98 99 ax25_dev_dama_off(ax25_dev); 100} 101 102void ax25_ds_heartbeat_expiry(ax25_cb *ax25) 103{ 104 switch (ax25->state) { 105 106 case AX25_STATE_0: 107 /* Magic here: If we listen() and a new link dies before it 108 is accepted() it isn't 'dead' so doesn't get removed. */ 109 if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) { 110 ax25_destroy_socket(ax25); 111 return; 112 } 113 break; 114 115 case AX25_STATE_3: 116 /* 117 * Check the state of the receive buffer. 118 */ 119 if (ax25->sk != NULL) { 120 if (atomic_read(&ax25->sk->rmem_alloc) < (ax25->sk->rcvbuf / 2) && 121 (ax25->condition & AX25_COND_OWN_RX_BUSY)) { 122 ax25->condition &= ~AX25_COND_OWN_RX_BUSY; 123 ax25->condition &= ~AX25_COND_ACK_PENDING; 124 break; 125 } 126 } 127 break; 128 } 129 130 ax25_start_heartbeat(ax25); 131} 132 133/* dl1bke 960114: T3 works much like the IDLE timeout, but 134 * gets reloaded with every frame for this 135 * connection. 136 */ 137void ax25_ds_t3timer_expiry(ax25_cb *ax25) 138{ 139 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 140 ax25_dama_off(ax25); 141 ax25_disconnect(ax25, ETIMEDOUT); 142} 143 144/* dl1bke 960228: close the connection when IDLE expires. 145 * unlike T3 this timer gets reloaded only on 146 * I frames. 147 */ 148void ax25_ds_idletimer_expiry(ax25_cb *ax25) 149{ 150 ax25_clear_queues(ax25); 151 152 ax25->n2count = 0; 153 ax25->state = AX25_STATE_2; 154 155 ax25_calculate_t1(ax25); 156 ax25_start_t1timer(ax25); 157 ax25_stop_t3timer(ax25); 158 159 if (ax25->sk != NULL) { 160 ax25->sk->state = TCP_CLOSE; 161 ax25->sk->err = 0; 162 ax25->sk->shutdown |= SEND_SHUTDOWN; 163 if (!ax25->sk->dead) 164 ax25->sk->state_change(ax25->sk); 165 ax25->sk->dead = 1; 166 } 167} 168 169/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC 170 * within the poll of any connected channel. Remember 171 * that we are not allowed to send anything unless we 172 * get polled by the Master. 173 * 174 * Thus we'll have to do parts of our T1 handling in 175 * ax25_enquiry_response(). 176 */ 177void ax25_ds_t1_timeout(ax25_cb *ax25) 178{ 179 switch (ax25->state) { 180 181 case AX25_STATE_1: 182 if (ax25->n2count == ax25->n2) { 183 if (ax25->modulus == AX25_MODULUS) { 184 ax25_disconnect(ax25, ETIMEDOUT); 185 return; 186 } else { 187 ax25->modulus = AX25_MODULUS; 188 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; 189 ax25->n2count = 0; 190 ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND); 191 } 192 } else { 193 ax25->n2count++; 194 if (ax25->modulus == AX25_MODULUS) 195 ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND); 196 else 197 ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND); 198 } 199 break; 200 201 case AX25_STATE_2: 202 if (ax25->n2count == ax25->n2) { 203 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 204 ax25_disconnect(ax25, ETIMEDOUT); 205 return; 206 } else { 207 ax25->n2count++; 208 } 209 break; 210 211 case AX25_STATE_3: 212 if (ax25->n2count == ax25->n2) { 213 ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE); 214 ax25_disconnect(ax25, ETIMEDOUT); 215 return; 216 } else { 217 ax25->n2count++; 218 } 219 break; 220 } 221 222 ax25_calculate_t1(ax25); 223 ax25_start_t1timer(ax25); 224} 225