root/net/ax25/ax25_std_timer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ax25_std_heartbeat_expiry
  2. ax25_std_t2timer_expiry
  3. ax25_std_t3timer_expiry
  4. ax25_std_idletimer_expiry
  5. ax25_std_t1timer_expiry

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
   5  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   6  * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
   7  * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
   8  */
   9 #include <linux/errno.h>
  10 #include <linux/types.h>
  11 #include <linux/socket.h>
  12 #include <linux/in.h>
  13 #include <linux/kernel.h>
  14 #include <linux/timer.h>
  15 #include <linux/string.h>
  16 #include <linux/sockios.h>
  17 #include <linux/net.h>
  18 #include <net/ax25.h>
  19 #include <linux/inet.h>
  20 #include <linux/netdevice.h>
  21 #include <linux/skbuff.h>
  22 #include <net/sock.h>
  23 #include <net/tcp_states.h>
  24 #include <linux/uaccess.h>
  25 #include <linux/fcntl.h>
  26 #include <linux/mm.h>
  27 #include <linux/interrupt.h>
  28 
  29 void ax25_std_heartbeat_expiry(ax25_cb *ax25)
  30 {
  31         struct sock *sk = ax25->sk;
  32 
  33         if (sk)
  34                 bh_lock_sock(sk);
  35 
  36         switch (ax25->state) {
  37         case AX25_STATE_0:
  38         case AX25_STATE_2:
  39                 /* Magic here: If we listen() and a new link dies before it
  40                    is accepted() it isn't 'dead' so doesn't get removed. */
  41                 if (!sk || sock_flag(sk, SOCK_DESTROY) ||
  42                     (sk->sk_state == TCP_LISTEN &&
  43                      sock_flag(sk, SOCK_DEAD))) {
  44                         if (sk) {
  45                                 sock_hold(sk);
  46                                 ax25_destroy_socket(ax25);
  47                                 bh_unlock_sock(sk);
  48                                 /* Ungrab socket and destroy it */
  49                                 sock_put(sk);
  50                         } else
  51                                 ax25_destroy_socket(ax25);
  52                         return;
  53                 }
  54                 break;
  55 
  56         case AX25_STATE_3:
  57         case AX25_STATE_4:
  58                 /*
  59                  * Check the state of the receive buffer.
  60                  */
  61                 if (sk != NULL) {
  62                         if (atomic_read(&sk->sk_rmem_alloc) <
  63                             (sk->sk_rcvbuf >> 1) &&
  64                             (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
  65                                 ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
  66                                 ax25->condition &= ~AX25_COND_ACK_PENDING;
  67                                 ax25_send_control(ax25, AX25_RR, AX25_POLLOFF, AX25_RESPONSE);
  68                                 break;
  69                         }
  70                 }
  71         }
  72 
  73         if (sk)
  74                 bh_unlock_sock(sk);
  75 
  76         ax25_start_heartbeat(ax25);
  77 }
  78 
  79 void ax25_std_t2timer_expiry(ax25_cb *ax25)
  80 {
  81         if (ax25->condition & AX25_COND_ACK_PENDING) {
  82                 ax25->condition &= ~AX25_COND_ACK_PENDING;
  83                 ax25_std_timeout_response(ax25);
  84         }
  85 }
  86 
  87 void ax25_std_t3timer_expiry(ax25_cb *ax25)
  88 {
  89         ax25->n2count = 0;
  90         ax25_std_transmit_enquiry(ax25);
  91         ax25->state   = AX25_STATE_4;
  92 }
  93 
  94 void ax25_std_idletimer_expiry(ax25_cb *ax25)
  95 {
  96         ax25_clear_queues(ax25);
  97 
  98         ax25->n2count = 0;
  99         ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 100         ax25->state   = AX25_STATE_2;
 101 
 102         ax25_calculate_t1(ax25);
 103         ax25_start_t1timer(ax25);
 104         ax25_stop_t2timer(ax25);
 105         ax25_stop_t3timer(ax25);
 106 
 107         if (ax25->sk != NULL) {
 108                 bh_lock_sock(ax25->sk);
 109                 ax25->sk->sk_state     = TCP_CLOSE;
 110                 ax25->sk->sk_err       = 0;
 111                 ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
 112                 if (!sock_flag(ax25->sk, SOCK_DEAD)) {
 113                         ax25->sk->sk_state_change(ax25->sk);
 114                         sock_set_flag(ax25->sk, SOCK_DEAD);
 115                 }
 116                 bh_unlock_sock(ax25->sk);
 117         }
 118 }
 119 
 120 void ax25_std_t1timer_expiry(ax25_cb *ax25)
 121 {
 122         switch (ax25->state) {
 123         case AX25_STATE_1:
 124                 if (ax25->n2count == ax25->n2) {
 125                         if (ax25->modulus == AX25_MODULUS) {
 126                                 ax25_disconnect(ax25, ETIMEDOUT);
 127                                 return;
 128                         } else {
 129                                 ax25->modulus = AX25_MODULUS;
 130                                 ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
 131                                 ax25->n2count = 0;
 132                                 ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
 133                         }
 134                 } else {
 135                         ax25->n2count++;
 136                         if (ax25->modulus == AX25_MODULUS)
 137                                 ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
 138                         else
 139                                 ax25_send_control(ax25, AX25_SABME, AX25_POLLON, AX25_COMMAND);
 140                 }
 141                 break;
 142 
 143         case AX25_STATE_2:
 144                 if (ax25->n2count == ax25->n2) {
 145                         ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 146                         if (!sock_flag(ax25->sk, SOCK_DESTROY))
 147                                 ax25_disconnect(ax25, ETIMEDOUT);
 148                         return;
 149                 } else {
 150                         ax25->n2count++;
 151                         ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 152                 }
 153                 break;
 154 
 155         case AX25_STATE_3:
 156                 ax25->n2count = 1;
 157                 ax25_std_transmit_enquiry(ax25);
 158                 ax25->state   = AX25_STATE_4;
 159                 break;
 160 
 161         case AX25_STATE_4:
 162                 if (ax25->n2count == ax25->n2) {
 163                         ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
 164                         ax25_disconnect(ax25, ETIMEDOUT);
 165                         return;
 166                 } else {
 167                         ax25->n2count++;
 168                         ax25_std_transmit_enquiry(ax25);
 169                 }
 170                 break;
 171         }
 172 
 173         ax25_calculate_t1(ax25);
 174         ax25_start_t1timer(ax25);
 175 }

/* [<][>][^][v][top][bottom][index][help] */