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  */
  22 
  23 #include <linux/config.h>
  24 #ifdef CONFIG_AX25
  25 #include <linux/errno.h>
  26 #include <linux/types.h>
  27 #include <linux/socket.h>
  28 #include <linux/in.h>
  29 #include <linux/kernel.h>
  30 #include <linux/sched.h>
  31 #include <linux/timer.h>
  32 #include <linux/string.h>
  33 #include <linux/sockios.h>
  34 #include <linux/net.h>
  35 #include <net/ax25.h>
  36 #include <linux/inet.h>
  37 #include <linux/netdevice.h>
  38 #include <linux/skbuff.h>
  39 #include <net/sock.h>
  40 #include <asm/segment.h>
  41 #include <asm/system.h>
  42 #include <linux/fcntl.h>
  43 #include <linux/mm.h>
  44 #include <linux/interrupt.h>
  45 #ifdef CONFIG_NETROM
  46 #include <net/netrom.h>
  47 #endif
  48 
  49 static void ax25_timer(unsigned long);
  50 
  51 /*
  52  *      Linux set/reset timer routines
  53  */
  54 void ax25_set_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56         unsigned long flags;    
  57 
  58         save_flags(flags);
  59         cli();
  60         del_timer(&ax25->timer);
  61         restore_flags(flags);
  62 
  63         ax25->timer.next     = ax25->timer.prev = NULL; 
  64         ax25->timer.data     = (unsigned long)ax25;
  65         ax25->timer.function = &ax25_timer;
  66 
  67         ax25->timer.expires = jiffies + 10;
  68         add_timer(&ax25->timer);
  69 }
  70 
  71 static void ax25_reset_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73         unsigned long flags;
  74         
  75         save_flags(flags);
  76         cli();
  77         del_timer(&ax25->timer);
  78         restore_flags(flags);
  79 
  80         ax25->timer.data     = (unsigned long)ax25;
  81         ax25->timer.function = &ax25_timer;
  82         ax25->timer.expires  = jiffies + 10;
  83         add_timer(&ax25->timer);
  84 }
  85 
  86 /*
  87  *      AX.25 TIMER 
  88  *
  89  *      This routine is called every 500ms. Decrement timer by this
  90  *      amount - if expired then process the event.
  91  */
  92 static void ax25_timer(unsigned long param)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         ax25_cb *ax25 = (ax25_cb *)param;
  95 
  96         switch (ax25->state) {
  97                 case AX25_STATE_0:
  98                         /* Magic here: If we listen() and a new link dies before it
  99                            is accepted() it isnt 'dead' so doesnt get removed. */
 100                         if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
 101                                 del_timer(&ax25->timer);
 102                                 ax25_destroy_socket(ax25);
 103                                 return;
 104                         }
 105                         break;
 106 
 107                 case AX25_STATE_3:
 108                 case AX25_STATE_4:
 109                         /*
 110                          * Check the state of the receive buffer.
 111                          */
 112                         if (ax25->sk != NULL) {
 113                                 if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
 114                                         ax25->condition &= ~OWN_RX_BUSY_CONDITION;
 115                                         if (!ax25->dama_slave) /* dl1bke */
 116                                                 ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
 117                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 118                                         break;
 119                                 }
 120                         }
 121                         /*
 122                          * Check for frames to transmit.
 123                          */
 124                         if (!ax25->dama_slave)
 125                                 ax25_kick(ax25);        /* dl1bke 960114 */
 126                         break;
 127 
 128                 default:
 129                         break;
 130         }
 131 
 132         if (ax25->t2timer > 0 && --ax25->t2timer == 0) {
 133                 if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
 134                         if (ax25->condition & ACK_PENDING_CONDITION) {
 135                                 ax25->condition &= ~ACK_PENDING_CONDITION;
 136                                 if (!ax25->dama_slave)                  /* dl1bke 960114 */
 137                                         ax25_timeout_response(ax25);
 138                         }
 139                 }
 140         }
 141 
 142         if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
 143                 /* dl1bke 960114: T3 expires and we are in DAMA mode:  */
 144                 /*                send a DISC and abort the connection */
 145                 if (ax25->dama_slave) {
 146 #ifdef CONFIG_NETROM
 147                         nr_link_failed(&ax25->dest_addr, ax25->device);
 148 #endif
 149                         ax25_clear_queues(ax25);
 150                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 151                                 
 152                         ax25->state = AX25_STATE_0;
 153                         if (ax25->sk != NULL) {
 154                                 if (ax25->sk->debug)
 155                                         printk("T3 Timeout\n");
 156                                 ax25->sk->state = TCP_CLOSE;
 157                                 ax25->sk->err   = ETIMEDOUT;
 158                                 if (!ax25->sk->dead)
 159                                         ax25->sk->state_change(ax25->sk);
 160                                 ax25->sk->dead  = 1;
 161                         }
 162                         
 163                         return;
 164                 }
 165                 
 166                 if (ax25->state == AX25_STATE_3) {
 167                         ax25->n2count = 0;
 168                         ax25_transmit_enquiry(ax25);
 169                         ax25->state   = AX25_STATE_4;
 170                 }
 171                 ax25->t3timer = ax25->t3;
 172         }
 173 
 174         /* dl1bke 960114: DAMA T1 timeouts are handled in ax25_dama_slave_transmit */
 175         /*                nevertheless we have to re-enqueue the timer struct...   */
 176         
 177         if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
 178                 ax25_reset_timer(ax25);
 179                 return;
 180         }
 181 
 182         if (!ax25_dev_is_dama_slave(ax25->device)) {
 183                 if (ax25->dama_slave)
 184                         ax25->dama_slave = 0;
 185                 ax25_t1_timeout(ax25);
 186         }
 187 }
 188 
 189 
 190 /* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
 191  *                within the poll of any connected channel. Remember 
 192  *                that we are not allowed to send anything unless we
 193  *                get polled by the Master.
 194  *                
 195  *                Thus we'll have to do parts of our T1 handling in
 196  *                ax25_enquiry_response().
 197  */
 198 void ax25_t1_timeout(ax25_cb * ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {       
 200         switch (ax25->state) {
 201                 case AX25_STATE_1: 
 202                         if (ax25->n2count == ax25->n2) {
 203                                 if (ax25->modulus == MODULUS) {
 204 #ifdef CONFIG_NETROM
 205                                         nr_link_failed(&ax25->dest_addr, ax25->device);
 206 #endif
 207                                         ax25_clear_queues(ax25);
 208                                         ax25->state = AX25_STATE_0;
 209                                         if (ax25->sk != NULL) {
 210                                                 ax25->sk->state = TCP_CLOSE;
 211                                                 ax25->sk->err   = ETIMEDOUT;
 212                                                 if (!ax25->sk->dead)
 213                                                         ax25->sk->state_change(ax25->sk);
 214                                                 ax25->sk->dead  = 1;
 215                                         }
 216                                 } else {
 217                                         ax25->modulus = MODULUS;
 218                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 219                                         ax25->n2count = 0;
 220                                         ax25_send_control(ax25, SABM, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 221                                 }
 222                         } else {
 223                                 ax25->n2count++;
 224                                 if (ax25->modulus == MODULUS) {
 225                                         ax25_send_control(ax25, SABM, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 226                                 } else {
 227                                         ax25_send_control(ax25, SABME, ax25_dev_is_dama_slave(ax25->device)? POLLOFF : POLLON, C_COMMAND);
 228                                 }
 229                         }
 230                         break;
 231 
 232                 case AX25_STATE_2:
 233                         if (ax25->n2count == ax25->n2) {
 234 #ifdef CONFIG_NETROM
 235                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 236 #endif
 237                                 ax25_clear_queues(ax25);
 238                                 ax25->state = AX25_STATE_0;
 239                                 ax25_send_control(ax25, DISC, POLLON, C_COMMAND); /* dl1bke */
 240                                 
 241                                 if (ax25->sk != NULL) {
 242                                         ax25->sk->state = TCP_CLOSE;
 243                                         ax25->sk->err   = ETIMEDOUT;
 244                                         if (!ax25->sk->dead)
 245                                                 ax25->sk->state_change(ax25->sk);
 246                                         ax25->sk->dead  = 1;
 247                                 }
 248                         } else {
 249                                 ax25->n2count++;
 250                                 if (!ax25_dev_is_dama_slave(ax25->device))      /* dl1bke */
 251                                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 252                         }
 253                         break;
 254 
 255                 case AX25_STATE_3: 
 256                         ax25->n2count = 1;
 257                         if (!ax25->dama_slave)                  /* dl1bke 960114 */
 258                                 ax25_transmit_enquiry(ax25);
 259                         ax25->state   = AX25_STATE_4;
 260                         break;
 261 
 262                 case AX25_STATE_4:
 263                         if (ax25->n2count == ax25->n2) {
 264 #ifdef CONFIG_NETROM
 265                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 266 #endif
 267                                 ax25_clear_queues(ax25);
 268                                 ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 269                                 ax25->state = AX25_STATE_0;
 270                                 if (ax25->sk != NULL) {
 271                                         if (ax25->sk->debug)
 272                                                 printk("Link Failure\n");
 273                                         ax25->sk->state = TCP_CLOSE;
 274                                         ax25->sk->err   = ETIMEDOUT;
 275                                         if (!ax25->sk->dead)
 276                                                 ax25->sk->state_change(ax25->sk);
 277                                         ax25->sk->dead  = 1;
 278                                 }
 279                         } else {
 280                                 ax25->n2count++;
 281                                 if (!ax25->dama_slave)          /* dl1bke 960114 */
 282                                         ax25_transmit_enquiry(ax25);
 283                         }
 284                         break;
 285         }
 286 
 287         ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 288 
 289         ax25_set_timer(ax25);
 290 }
 291 
 292 #endif

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