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

   1 /*
   2  *      AX.25 release 030
   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  */
  21 
  22 #include <linux/config.h>
  23 #ifdef CONFIG_AX25
  24 #include <linux/errno.h>
  25 #include <linux/types.h>
  26 #include <linux/socket.h>
  27 #include <linux/in.h>
  28 #include <linux/kernel.h>
  29 #include <linux/sched.h>
  30 #include <linux/timer.h>
  31 #include <linux/string.h>
  32 #include <linux/sockios.h>
  33 #include <linux/net.h>
  34 #include <net/ax25.h>
  35 #include <linux/inet.h>
  36 #include <linux/netdevice.h>
  37 #include <linux/skbuff.h>
  38 #include <net/sock.h>
  39 #include <asm/segment.h>
  40 #include <asm/system.h>
  41 #include <linux/fcntl.h>
  42 #include <linux/mm.h>
  43 #include <linux/interrupt.h>
  44 #ifdef CONFIG_NETROM
  45 #include <net/netrom.h>
  46 #endif
  47 
  48 static void ax25_timer(unsigned long);
  49 
  50 /*
  51  *      Linux set/reset timer routines
  52  */
  53 void ax25_set_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55         unsigned long flags;    
  56 
  57         save_flags(flags);
  58         cli();
  59         del_timer(&ax25->timer);
  60         restore_flags(flags);
  61 
  62         ax25->timer.next     = ax25->timer.prev = NULL; 
  63         ax25->timer.data     = (unsigned long)ax25;
  64         ax25->timer.function = &ax25_timer;
  65 
  66         ax25->timer.expires = jiffies + 10;
  67         add_timer(&ax25->timer);
  68 }
  69 
  70 static void ax25_reset_timer(ax25_cb *ax25)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         unsigned long flags;
  73         
  74         save_flags(flags);
  75         cli();
  76         del_timer(&ax25->timer);
  77         restore_flags(flags);
  78 
  79         ax25->timer.data     = (unsigned long)ax25;
  80         ax25->timer.function = &ax25_timer;
  81         ax25->timer.expires  = jiffies + 10;
  82         add_timer(&ax25->timer);
  83 }
  84 
  85 /*
  86  *      AX.25 TIMER 
  87  *
  88  *      This routine is called every 500ms. Decrement timer by this
  89  *      amount - if expired then process the event.
  90  */
  91 static void ax25_timer(unsigned long param)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         ax25_cb *ax25 = (ax25_cb *)param;
  94 
  95         switch (ax25->state) {
  96                 case AX25_STATE_0:
  97                         /* Magic here: If we listen() and a new link dies before it
  98                            is accepted() it isnt 'dead' so doesnt get removed. */
  99                         if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
 100                                 del_timer(&ax25->timer);
 101                                 ax25_destroy_socket(ax25);
 102                                 return;
 103                         }
 104                         break;
 105 
 106                 case AX25_STATE_3:
 107                 case AX25_STATE_4:
 108                         /*
 109                          * Check the state of the receive buffer.
 110                          */
 111                         if (ax25->sk != NULL) {
 112                                 if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
 113                                         ax25->condition &= ~OWN_RX_BUSY_CONDITION;
 114                                         ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
 115                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 116                                         break;
 117                                 }
 118                         }
 119                         /*
 120                          * Check for frames to transmit.
 121                          */
 122                         ax25_kick(ax25);
 123                         break;
 124 
 125                 default:
 126                         break;
 127         }
 128 
 129         if (ax25->t2timer > 0 && --ax25->t2timer == 0) {
 130                 if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
 131                         if (ax25->condition & ACK_PENDING_CONDITION) {
 132                                 ax25->condition &= ~ACK_PENDING_CONDITION;
 133                                 ax25_timeout_response(ax25);
 134                         }
 135                 }
 136         }
 137 
 138         if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
 139                 if (ax25->state == AX25_STATE_3) {
 140                         ax25->n2count = 0;
 141                         ax25_transmit_enquiry(ax25);
 142                         ax25->state   = AX25_STATE_4;
 143                 }
 144                 ax25->t3timer = ax25->t3;
 145         }
 146 
 147         if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
 148                 ax25_reset_timer(ax25);
 149                 return;
 150         }
 151 
 152         switch (ax25->state) {
 153                 case AX25_STATE_1: 
 154                         if (ax25->n2count == ax25->n2) {
 155                                 if (ax25->modulus == MODULUS) {
 156 #ifdef CONFIG_NETROM
 157                                         nr_link_failed(&ax25->dest_addr, ax25->device);
 158 #endif
 159                                         ax25_clear_queues(ax25);
 160                                         ax25->state = AX25_STATE_0;
 161                                         if (ax25->sk != NULL) {
 162                                                 ax25->sk->state = TCP_CLOSE;
 163                                                 ax25->sk->err   = ETIMEDOUT;
 164                                                 if (!ax25->sk->dead)
 165                                                         ax25->sk->state_change(ax25->sk);
 166                                                 ax25->sk->dead  = 1;
 167                                         }
 168                                 } else {
 169                                         ax25->modulus = MODULUS;
 170                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 171                                         ax25->n2count = 0;
 172                                         ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
 173                                 }
 174                         } else {
 175                                 ax25->n2count++;
 176                                 if (ax25->modulus == MODULUS) {
 177                                         ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
 178                                 } else {
 179                                         ax25_send_control(ax25, SABME, POLLON, C_COMMAND);
 180                                 }
 181                         }
 182                         break;
 183 
 184                 case AX25_STATE_2:
 185                         if (ax25->n2count == ax25->n2) {
 186 #ifdef CONFIG_NETROM
 187                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 188 #endif
 189                                 ax25_clear_queues(ax25);
 190                                 ax25->state = AX25_STATE_0;
 191                                 if (ax25->sk != NULL) {
 192                                         ax25->sk->state = TCP_CLOSE;
 193                                         ax25->sk->err   = ETIMEDOUT;
 194                                         if (!ax25->sk->dead)
 195                                                 ax25->sk->state_change(ax25->sk);
 196                                         ax25->sk->dead  = 1;
 197                                 }
 198                         } else {
 199                                 ax25->n2count++;
 200                                 ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 201                         }
 202                         break;
 203 
 204                 case AX25_STATE_3: 
 205                         ax25->n2count = 1;
 206                         ax25_transmit_enquiry(ax25);
 207                         ax25->state   = AX25_STATE_4;
 208                         break;
 209 
 210                 case AX25_STATE_4:
 211                         if (ax25->n2count == ax25->n2) {
 212 #ifdef CONFIG_NETROM
 213                                 nr_link_failed(&ax25->dest_addr, ax25->device);
 214 #endif
 215                                 ax25_clear_queues(ax25);
 216                                 ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 217                                 ax25->state = AX25_STATE_0;
 218                                 if (ax25->sk != NULL) {
 219                                         ax25->sk->state = TCP_CLOSE;
 220                                         ax25->sk->err   = ETIMEDOUT;
 221                                         if (!ax25->sk->dead)
 222                                                 ax25->sk->state_change(ax25->sk);
 223                                         ax25->sk->dead  = 1;
 224                                 }
 225                         } else {
 226                                 ax25->n2count++;
 227                                 ax25_transmit_enquiry(ax25);
 228                         }
 229                         break;
 230         }
 231 
 232         ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 233 
 234         ax25_set_timer(ax25);
 235 }
 236 
 237 #endif

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