linux-old/net/netrom/nr_timer.c
<<
>>
Prefs
   1/*
   2 *      NET/ROM release 007
   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 *      NET/ROM 001     Jonathan(G4KLX) Cloned from ax25_timer.c
  14 *      NET/ROM 007     Jonathan(G4KLX) New timer architecture.
  15 *                                      Implemented idle timer.
  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#include <net/netrom.h>
  39
  40static void nr_heartbeat_expiry(unsigned long);
  41static void nr_t1timer_expiry(unsigned long);
  42static void nr_t2timer_expiry(unsigned long);
  43static void nr_t4timer_expiry(unsigned long);
  44static void nr_idletimer_expiry(unsigned long);
  45
  46void nr_start_t1timer(struct sock *sk)
  47{
  48        del_timer(&sk->protinfo.nr->t1timer);
  49
  50        sk->protinfo.nr->t1timer.data     = (unsigned long)sk;
  51        sk->protinfo.nr->t1timer.function = &nr_t1timer_expiry;
  52        sk->protinfo.nr->t1timer.expires  = jiffies + sk->protinfo.nr->t1;
  53
  54        add_timer(&sk->protinfo.nr->t1timer);
  55}
  56
  57void nr_start_t2timer(struct sock *sk)
  58{
  59        del_timer(&sk->protinfo.nr->t2timer);
  60
  61        sk->protinfo.nr->t2timer.data     = (unsigned long)sk;
  62        sk->protinfo.nr->t2timer.function = &nr_t2timer_expiry;
  63        sk->protinfo.nr->t2timer.expires  = jiffies + sk->protinfo.nr->t2;
  64
  65        add_timer(&sk->protinfo.nr->t2timer);
  66}
  67
  68void nr_start_t4timer(struct sock *sk)
  69{
  70        del_timer(&sk->protinfo.nr->t4timer);
  71
  72        sk->protinfo.nr->t4timer.data     = (unsigned long)sk;
  73        sk->protinfo.nr->t4timer.function = &nr_t4timer_expiry;
  74        sk->protinfo.nr->t4timer.expires  = jiffies + sk->protinfo.nr->t4;
  75
  76        add_timer(&sk->protinfo.nr->t4timer);
  77}
  78
  79void nr_start_idletimer(struct sock *sk)
  80{
  81        del_timer(&sk->protinfo.nr->idletimer);
  82
  83        if (sk->protinfo.nr->idle > 0) {
  84                sk->protinfo.nr->idletimer.data     = (unsigned long)sk;
  85                sk->protinfo.nr->idletimer.function = &nr_idletimer_expiry;
  86                sk->protinfo.nr->idletimer.expires  = jiffies + sk->protinfo.nr->idle;
  87
  88                add_timer(&sk->protinfo.nr->idletimer);
  89        }
  90}
  91
  92void nr_start_heartbeat(struct sock *sk)
  93{
  94        del_timer(&sk->timer);
  95
  96        sk->timer.data     = (unsigned long)sk;
  97        sk->timer.function = &nr_heartbeat_expiry;
  98        sk->timer.expires  = jiffies + 5 * HZ;
  99
 100        add_timer(&sk->timer);
 101}
 102
 103void nr_stop_t1timer(struct sock *sk)
 104{
 105        del_timer(&sk->protinfo.nr->t1timer);
 106}
 107
 108void nr_stop_t2timer(struct sock *sk)
 109{
 110        del_timer(&sk->protinfo.nr->t2timer);
 111}
 112
 113void nr_stop_t4timer(struct sock *sk)
 114{
 115        del_timer(&sk->protinfo.nr->t4timer);
 116}
 117
 118void nr_stop_idletimer(struct sock *sk)
 119{
 120        del_timer(&sk->protinfo.nr->idletimer);
 121}
 122
 123void nr_stop_heartbeat(struct sock *sk)
 124{
 125        del_timer(&sk->timer);
 126}
 127
 128int nr_t1timer_running(struct sock *sk)
 129{
 130        return timer_pending(&sk->protinfo.nr->t1timer);
 131}
 132
 133static void nr_heartbeat_expiry(unsigned long param)
 134{
 135        struct sock *sk = (struct sock *)param;
 136
 137        switch (sk->protinfo.nr->state) {
 138
 139                case NR_STATE_0:
 140                        /* Magic here: If we listen() and a new link dies before it
 141                           is accepted() it isn't 'dead' so doesn't get removed. */
 142                        if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
 143                                nr_destroy_socket(sk);
 144                                return;
 145                        }
 146                        break;
 147
 148                case NR_STATE_3:
 149                        /*
 150                         * Check for the state of the receive buffer.
 151                         */
 152                        if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
 153                            (sk->protinfo.nr->condition & NR_COND_OWN_RX_BUSY)) {
 154                                sk->protinfo.nr->condition &= ~NR_COND_OWN_RX_BUSY;
 155                                sk->protinfo.nr->condition &= ~NR_COND_ACK_PENDING;
 156                                sk->protinfo.nr->vl         = sk->protinfo.nr->vr;
 157                                nr_write_internal(sk, NR_INFOACK);
 158                                break;
 159                        }
 160                        break;
 161        }
 162
 163        nr_start_heartbeat(sk);
 164}
 165
 166static void nr_t2timer_expiry(unsigned long param)
 167{
 168        struct sock *sk = (struct sock *)param;
 169
 170        if (sk->protinfo.nr->condition & NR_COND_ACK_PENDING) {
 171                sk->protinfo.nr->condition &= ~NR_COND_ACK_PENDING;
 172                nr_enquiry_response(sk);
 173        }
 174}
 175
 176static void nr_t4timer_expiry(unsigned long param)
 177{
 178        struct sock *sk = (struct sock *)param;
 179
 180        sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
 181}
 182
 183static void nr_idletimer_expiry(unsigned long param)
 184{
 185        struct sock *sk = (struct sock *)param;
 186
 187        nr_clear_queues(sk);
 188
 189        sk->protinfo.nr->n2count = 0;
 190        nr_write_internal(sk, NR_DISCREQ);
 191        sk->protinfo.nr->state = NR_STATE_2;
 192
 193        nr_start_t1timer(sk);
 194        nr_stop_t2timer(sk);
 195        nr_stop_t4timer(sk);
 196
 197        sk->state     = TCP_CLOSE;
 198        sk->err       = 0;
 199        sk->shutdown |= SEND_SHUTDOWN;
 200
 201        if (!sk->dead)
 202                sk->state_change(sk);
 203
 204        sk->dead = 1;
 205}
 206
 207static void nr_t1timer_expiry(unsigned long param)
 208{
 209        struct sock *sk = (struct sock *)param;
 210
 211        switch (sk->protinfo.nr->state) {
 212
 213                case NR_STATE_1: 
 214                        if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
 215                                nr_disconnect(sk, ETIMEDOUT);
 216                                return;
 217                        } else {
 218                                sk->protinfo.nr->n2count++;
 219                                nr_write_internal(sk, NR_CONNREQ);
 220                        }
 221                        break;
 222
 223                case NR_STATE_2:
 224                        if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
 225                                nr_disconnect(sk, ETIMEDOUT);
 226                                return;
 227                        } else {
 228                                sk->protinfo.nr->n2count++;
 229                                nr_write_internal(sk, NR_DISCREQ);
 230                        }
 231                        break;
 232
 233                case NR_STATE_3:
 234                        if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
 235                                nr_disconnect(sk, ETIMEDOUT);
 236                                return;
 237                        } else {
 238                                sk->protinfo.nr->n2count++;
 239                                nr_requeue_frames(sk);
 240                        }
 241                        break;
 242        }
 243
 244        nr_start_t1timer(sk);
 245}
 246
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.