hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/***
 *
 *  rtcfg/rtcfg_timer.c
 *
 *  Real-Time Configuration Distribution Protocol
 *
 *  Copyright (C) 2003-2005 Jan Kiszka <jan.kiszka@web.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
 
#include <linux/kernel.h>
#include <linux/list.h>
 
#include <rtdev.h>
#include <rtcfg/rtcfg.h>
#include <rtcfg/rtcfg_conn_event.h>
#include <rtcfg/rtcfg_event.h>
#include <rtcfg/rtcfg_frame.h>
#include <rtcfg/rtcfg_timer.h>
 
void rtcfg_timer(rtdm_timer_t *t)
{
   struct rtcfg_device *rtcfg_dev =
       container_of(t, struct rtcfg_device, timer);
 
   set_bit(FLAG_TIMER_PENDING, &rtcfg_dev->flags);
   rtcfg_thread_signal();
}
 
void rtcfg_timer_run_one(int ifindex)
{
   struct rtcfg_device *rtcfg_dev = &device[ifindex];
   struct list_head *entry;
   struct rtcfg_connection *conn;
   int last_stage_1 = -1;
   int burst_credit;
   int index;
   int ret, shutdown;
 
   shutdown = test_and_clear_bit(FLAG_TIMER_SHUTDOWN, &rtcfg_dev->flags);
 
   if (!test_and_clear_bit(FLAG_TIMER_PENDING, &rtcfg_dev->flags) ||
       shutdown)
       return;
 
   rtdm_mutex_lock(&rtcfg_dev->dev_mutex);
 
   if (rtcfg_dev->state == RTCFG_MAIN_SERVER_RUNNING) {
       index = 0;
       burst_credit = rtcfg_dev->burstrate;
 
       list_for_each (entry, &rtcfg_dev->spec.srv.conn_list) {
           conn = list_entry(entry, struct rtcfg_connection,
                     entry);
 
           if ((conn->state == RTCFG_CONN_SEARCHING) ||
               (conn->state == RTCFG_CONN_DEAD)) {
               if ((burst_credit > 0) &&
                   (index > last_stage_1)) {
                   if ((ret = rtcfg_send_stage_1(conn)) <
                       0) {
                       RTCFG_DEBUG(
                           2,
                           "RTcfg: error %d while sending "
                           "stage 1 frame\n",
                           ret);
                   }
                   burst_credit--;
                   last_stage_1 = index;
               }
           } else {
               /* skip connection in history */
               if (last_stage_1 == (index - 1))
                   last_stage_1 = index;
 
               rtcfg_do_conn_event(conn, RTCFG_TIMER, NULL);
           }
           index++;
       }
 
       /* handle pointer overrun of the last stage 1 transmission */
       if (last_stage_1 == (index - 1))
           last_stage_1 = -1;
   } else if (rtcfg_dev->state == RTCFG_MAIN_CLIENT_READY)
       rtcfg_send_heartbeat(ifindex);
 
   rtdm_mutex_unlock(&rtcfg_dev->dev_mutex);
}
 
void rtcfg_timer_run(void)
{
   int ifindex;
 
   for (ifindex = 0; ifindex < MAX_RT_DEVICES; ifindex++)
       rtcfg_timer_run_one(ifindex);
}