forked from Distrotech/libss7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathss7_sched.c
120 lines (107 loc) · 3.1 KB
/
ss7_sched.c
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
111
112
113
114
115
116
117
118
119
120
/*
* libss7: An implementation of Signalling System 7
*
* Written by Matthew Fredrickson <[email protected]>
*
* scheduling routines taken from libpri by Mark Spencer <[email protected]>
*
* Copyright (C) 2006-2008, Digium, Inc
* All Rights Reserved.
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*
* In addition, when this program is distributed with Asterisk in
* any form that would qualify as a 'combined work' or as a
* 'derivative work' (but not mere aggregation), you can redistribute
* and/or modify the combination under the terms of the license
* provided with that copy of Asterisk, instead of the license
* terms granted here.
*/
#include "libss7.h"
#include "ss7_internal.h"
#include "mtp3.h"
#include <stdio.h>
/* Scheduler routines */
int ss7_schedule_event(struct ss7 *ss7, int ms, void (*function)(void *data), void *data)
{
int x;
struct timeval tv;
for (x=1;x<MAX_SCHED;x++)
if (!ss7->ss7_sched[x].callback)
break;
if (x == MAX_SCHED) {
ss7_error(ss7, "No more room in scheduler\n");
return -1;
}
gettimeofday(&tv, NULL);
tv.tv_sec += ms / 1000;
tv.tv_usec += (ms % 1000) * 1000;
if (tv.tv_usec > 1000000) {
tv.tv_usec -= 1000000;
tv.tv_sec += 1;
}
ss7->ss7_sched[x].when = tv;
ss7->ss7_sched[x].callback = function;
ss7->ss7_sched[x].data = data;
return x;
}
struct timeval *ss7_schedule_next(struct ss7 *ss7)
{
struct timeval *closest = NULL;
int x;
/* Check subchannels */
for (x=1;x<MAX_SCHED;x++) {
if (ss7->ss7_sched[x].callback &&
(!closest || (closest->tv_sec > ss7->ss7_sched[x].when.tv_sec) ||
((closest->tv_sec == ss7->ss7_sched[x].when.tv_sec) &&
(closest->tv_usec > ss7->ss7_sched[x].when.tv_usec))))
closest = &ss7->ss7_sched[x].when;
}
return closest;
}
static int __ss7_schedule_run(struct ss7 *ss7, struct timeval *tv)
{
int x;
void (*callback)(void *);
void *data;
for (x=1;x<MAX_SCHED;x++) {
if (ss7->ss7_sched[x].callback &&
((ss7->ss7_sched[x].when.tv_sec < tv->tv_sec) ||
((ss7->ss7_sched[x].when.tv_sec == tv->tv_sec) &&
(ss7->ss7_sched[x].when.tv_usec <= tv->tv_usec)))) {
callback = ss7->ss7_sched[x].callback;
data = ss7->ss7_sched[x].data;
ss7->ss7_sched[x].callback = NULL;
ss7->ss7_sched[x].data = NULL;
callback(data);
}
}
return 0;
}
int ss7_schedule_run(struct ss7 *ss7)
{
int res;
struct timeval tv;
gettimeofday(&tv, NULL);
res = __ss7_schedule_run(ss7, &tv);
return res;
}
void ss7_schedule_del(struct ss7 *ss7, int *id)
{
if ((*id >= MAX_SCHED))
ss7_error(ss7, "Asked to delete sched id %d???\n", *id);
if (*id < 0) /* Item already deleted */
return;
ss7->ss7_sched[*id].callback = NULL;
*id = -1; /* "Delete" the event */
}