root/net/ax25/ax25_timer.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ax25_set_timer
  2. ax25_reset_timer
  3. ax25_timer
  4. ax25_t1_timeout

   1 /*
   2  *      AX.25 release 031
   3  *
   4  *      This is ALPHA test software. This code may break your machine, randomly fail to work with new 
   5  *      releases, misbehave and/or generally screw up. It might even work. 
   6  *
   7  *      This code REQUIRES 1.2.1 or higher/ NET3.029
   8  *
   9  *      This module:
  10  *              This module is free software; you can redistribute it and/or
  11  *              modify it under the terms of the GNU General Public License
  12  *              as published by the Free Software Foundation; either version
  13  *              2 of the License, or (at your option) any later version.
  14  *
  15  *      History
  16  *      AX.25 028a      Jonathan(G4KLX) New state machine based on SDL diagrams.
  17  *      AX.25 028b      Jonathan(G4KLX) Extracted AX25 control block from the
  18  *                                      sock structure.
  19  *      AX.25 029       Alan(GW4PTS)    Switched to KA9Q constant names.
  20  *      AX.25 031       Joerg(DL1BKE)   Added DAMA support
  21  *      AX.25 032       Joerg(DL1BKE)   Fixed DAMA timeout bug
  22  */
  23 
  24 #include <linux/config.h>
  25 #ifdef CONFIG_AX25
  26 #include <linux/errno.h>
  27 #include <linux/types.h>
  28 #include <linux/socket.h>
  29 #include <linux/in.h>
  30 #include <linux/kernel.h>
  31 #include <linux/sched.h>
  32 #include <linux/timer.h>
  33 #include <linux/string.h>
  34 #include <linux/sockios.h>
  35 #include <linux/net.h>
  36 #include <net/ax25.h>
  37 #include <linux/inet.h>
  38 #include <linux/netdevice.h>
  39 #include <linux/skbuff.h>
  40 #include <net/sock.h>
  41 #include <asm/segment.h>
  42 #include <asm/system.h>
  43 #include <linux/fcntl.h>
  44 #include <linux/mm.h>
  45 #include <linux/interrupt.h>
  46 #ifdef CONFIG_NETROM
  47 #include <net/netrom.h>
  48 #endif
  49 
  50 static void ax25_timer(unsigned long);
  51 
  52 /*
  53  *      Linux set/reset timer routines
  54  */
  55 void ax25_set_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         unsigned long flags;    
  58 
  59         save_flags(flags);
  60         cli();
  61         del_timer(&ax25->timer);
  62         restore_flags(flags);
  63 
  64         ax25->timer.next     = ax25->timer.prev = NULL; 
  65         ax25->timer.data     = (unsigned long)ax25;
  66         ax25->timer.function = &ax25_timer;
  67 
  68         ax25->timer.expires = jiffies + 10;
  69         add_timer(&ax25->timer);
  70 }
  71 
  72 static void ax25_reset_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74         unsigned long flags;
  75         
  76         save_flags(flags);
  77         cli();
  78         del_timer(&ax25->timer);
  79         restore_flags(flags);
  80 
  81         ax25->timer.data     = (unsigned long)ax25;
  82         ax25->timer.function = &ax25_timer;
  83         ax25->timer.expires  = jiffies + 10;
  84         add_timer(&ax25->timer);
  85 }
  86 
  87 /*
  88  *      AX.25 TIMER 
  89  *
  90  *      This routine is called every 500ms. Decrement timer by this
  91  *      amount - if expired then process the event.
  92  */
  93 static void ax25_timer(unsigned long param)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95         ax25_cb *ax25 = (ax25_cb *)param;
  96 
  97         switch (ax25->state) {
  98                 case AX25_STATE_0:
  99                         /* Magic here: If we listen() and a new link dies before it
 100                            is accepted() it isn't 'dead' so doesn't get removed. */
 101                         if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
 102                                 del_timer(&ax25->timer);
 103                                 ax25_destroy_socket(ax25);
 104                                 return;
 105                         }
 106                         break;
 107 
 108                 case AX25_STATE_3:
 109                 case AX25_STATE_4:
 110                         /*
 111                          * Check the state of the receive buffer.
 112                          */
 113                         if (ax25->sk != NULL) {
 114                                 if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
 115                                         ax25->condition &= ~OWN_RX_BUSY_CONDITION;
 116                                         if (!ax25->dama_slave) /* dl1bke */
 117                                                 ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
 118                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 119                                         break;
 120                                 }
 121                         }
 122                         /*
 123                          * Check for frames to transmit.
 124                          */
 125                         if (!ax25->dama_slave)
 126                                 ax25_kick(ax25);        /* dl1bke 960114 */
 127                         break;
 128 
 129                 default:
 130                         break;
 131         }
 132 
 133         if (ax25->t2timer > 0 && --ax25->t2timer == 0) {
 134                 if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
 135                         if (ax25->condition & ACK_PENDING_CONDITION) {
 136                                 ax25->condition &= ~ACK_PENDING_CONDITION;
 137                                 if (!ax25->dama_slave)                  /* dl1bke 960114 */
 138                                         ax25_timeout_response(ax25);
 139                         }
 140                 }
 141         }
 142 
 143         if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
 144                 /* dl1bke 960114: T3 expires and we are in DAMA mode:  */
 145                 /*                send a DISC and abort the connection */
 146                 if (ax25->dama_slave) {
 147 #ifdef CONFIG_NETROM
 148                         nr_link_failed(&ax25->dest_addr, ax25->device);
 149 #endif
 150                         ax25_clear_queues(ax25);
 151                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 152                                 
 153                         ax25->state = AX25_STATE_0;
 154                         if (ax25->sk != NULL) {
 155                                 if (ax25->sk->debug)
 156                                         printk("T3 Timeout\n");
 157                                 ax25->sk->state = TCP_CLOSE;
 158                                 ax25->sk->err   = ETIMEDOUT;
 159                                 if (!ax25->sk->dead)
 160                                         ax25->sk->state_change(ax25->sk);
 161                                 ax25->sk->dead  = 1;
 162                         }
 163 
 164                         ax25_reset_timer(ax25);
 165                         return;
 166                 }
 167                 
 168                 if (ax25->state == AX25_STATE_3) {
 169                         ax25->n2count = 0;
 170                         ax25_transmit_enquiry(ax25);
 171                         ax25->state   = AX25_STATE_4;
 172                 }
 173                 ax25->t3timer = ax25->t3;
 174         }
 175         
 176         if (ax25->idletimer > 0 && --ax25->idletimer == 0) {
 177                 /* dl1bke 960228: close the connection when IDLE expires */
 178                 /*                similar to DAMA T3 timeout but with    */
 179                 /*                a "clean" disconnect of the connection */
 180 
 181                 ax25_clear_queues(ax25);
 182 
 183                 ax25->n2count = 0;
 184                 if (!ax25->dama_slave) {
 185                         ax25->t3timer = 0;
 186                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 187                 } else {
 188                         ax25->t3timer = ax25->t3;
 189                 }
 190                 
 191                 /* state 1 or 2 should not happen, but... */
 192                 
 193                 if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2)
 194                         ax25->state = AX25_STATE_0;
 195                 else
 196                         ax25->state = AX25_STATE_2;
 197 
 198                 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 199 
 200                 if (ax25->sk != NULL) {
 201                         ax25->sk->state = TCP_CLOSE;
 202                         ax25->sk->err = 0;
 203                         if (!ax25->sk->dead)
 204                                 ax25->sk->state_change(ax25->sk);
 205                         ax25->sk->dead = 1;
 206                         ax25->sk->destroy = 1;
 207                 }
 208         }
 209                                                                                                                                                                                                                                                                                                                                                         
 210         /* dl1bke 960114: DAMA T1 timeouts are handled in ax25_dama_slave_transmit */
 211         /*                nevertheless we have to re-enqueue the timer struct...   */
 212         
 213         if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
 214                 ax25_reset_timer(ax25);
 215                 return;
 216         }
 217 
 218         if (!ax25_dev_is_dama_slave(ax25->device)) {
 219                 if (ax25->dama_slave)
 220                         ax25->dama_slave = 0;
 221                 ax25_t1_timeout(ax25);
 222         }
 223 }
 224 
 225 
 226 /* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
 227  *                within the poll of any connected channel. Remember 
 228  *                that we are not allowed to send anything unless we
 229  *                get polled by the Master.
 230  *                
 231  *                Thus we'll have to do parts of our T1 handling in
 232  *                ax25_enquiry_response().
 233  */
 234 void ax25_t1_timeout(ax25_cb * ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {       
 236         switch (ax25->state) {
 237                 case AX25_STATE_1: 
 238                         if (ax25->n2count == ax25->n2) {
 239                                 if (ax25->modulus == MODULUS) {
 240 #ifdef CONFIG_NETROM
 241                                         nr_link_failed(&ax25->dest_addr, ax25->device);
 242 #endif
 243                                         ax25_clear_queues(ax25);
 244                                         ax25->state = AX25_STATE_0;
 245                                         if (ax25->sk != NULL) {
 246                                                 ax25->sk->state = TCP_CLOSE;
 247                                                 ax25->sk->err   = ETIMEDOUT;
 248                                                 if (!ax25->sk->dead)
 249                                                         ax25->sk->state_change(ax25->sk);
 250                                                 ax25->sk->dead  = 1;
 251                                         }
 252                                 } else {
 253                                         ax25->modulus = MODULUS;
 254                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 255                                         ax25->n2count = 0;
 256                                         ax25_send_control(ax25, SABM, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 257                                 }
 258                         } else {
 259                                 ax25->n2count++;
 260                                 if (ax25->modulus == MODULUS) {
 261                                         ax25_send_control(ax25, SABM, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 262                                 } else {
 263                                         ax25_send_control(ax25, SABME, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 264                                 }
 265                         }
 266                         break;
 267 
 268                 case AX25_STATE_2:
 269                         if (ax25->n2count == ax25->n2) {
 270 #ifdef CONFIG_NETROM
 271                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 272 #endif
 273                                 ax25_clear_queues(ax25);
 274                                 ax25->state = AX25_STATE_0;
 275                                 ax25_send_control(ax25, DISC, POLLON, C_COMMAND); /* dl1bke */
 276                                 
 277                                 if (ax25->sk != NULL) {
 278                                         ax25->sk->state = TCP_CLOSE;
 279                                         ax25->sk->err   = ETIMEDOUT;
 280                                         if (!ax25->sk->dead)
 281                                                 ax25->sk->state_change(ax25->sk);
 282                                         ax25->sk->dead  = 1;
 283                                 }
 284                         } else {
 285                                 ax25->n2count++;
 286                                 if (!ax25_dev_is_dama_slave(ax25->device))      /* dl1bke */
 287                                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 288                         }
 289                         break;
 290 
 291                 case AX25_STATE_3: 
 292                         ax25->n2count = 1;
 293                         if (!ax25->dama_slave)                  /* dl1bke 960114 */
 294                                 ax25_transmit_enquiry(ax25);
 295                         ax25->state   = AX25_STATE_4;
 296                         break;
 297 
 298                 case AX25_STATE_4:
 299                         if (ax25->n2count == ax25->n2) {
 300 #ifdef CONFIG_NETROM
 301                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 302 #endif
 303                                 ax25_clear_queues(ax25);
 304                                 ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 305                                 ax25->state = AX25_STATE_0;
 306                                 if (ax25->sk != NULL) {
 307                                         if (ax25->sk->debug)
 308                                                 printk("Link Failure\n");
 309                                         ax25->sk->state = TCP_CLOSE;
 310                                         ax25->sk->err   = ETIMEDOUT;
 311                                         if (!ax25->sk->dead)
 312                                                 ax25->sk->state_change(ax25->sk);
 313                                         ax25->sk->dead  = 1;
 314                                 }
 315                         } else {
 316                                 ax25->n2count++;
 317                                 if (!ax25->dama_slave)          /* dl1bke 960114 */
 318                                         ax25_transmit_enquiry(ax25);
 319                         }
 320                         break;
 321         }
 322 
 323         ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 324 
 325         ax25_set_timer(ax25);
 326 }
 327 
 328 #endif

/* [previous][next][first][last][top][bottom][index][help] */