Wed Jan 8 2020 09:49:50

Asterisk developer's documentation


res_timing_dahdi.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \author Russell Bryant <russell@digium.com>
22  *
23  * \brief DAHDI timing interface
24  */
25 
26 /*** MODULEINFO
27  <depend>dahdi</depend>
28  <support_level>core</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 413586 $");
34 
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <math.h>
39 
40 #include <dahdi/user.h>
41 
42 #include "asterisk/module.h"
43 #include "asterisk/timing.h"
44 #include "asterisk/utils.h"
45 
46 static void *timing_funcs_handle;
47 
48 static int dahdi_timer_open(void);
49 static void dahdi_timer_close(int handle);
50 static int dahdi_timer_set_rate(int handle, unsigned int rate);
51 static int dahdi_timer_ack(int handle, unsigned int quantity);
52 static int dahdi_timer_enable_continuous(int handle);
53 static int dahdi_timer_disable_continuous(int handle);
54 static enum ast_timer_event dahdi_timer_get_event(int handle);
55 static unsigned int dahdi_timer_get_max_rate(int handle);
56 
58  .name = "DAHDI",
59  .priority = 100,
60  .timer_open = dahdi_timer_open,
61  .timer_close = dahdi_timer_close,
62  .timer_set_rate = dahdi_timer_set_rate,
63  .timer_ack = dahdi_timer_ack,
64  .timer_enable_continuous = dahdi_timer_enable_continuous,
65  .timer_disable_continuous = dahdi_timer_disable_continuous,
66  .timer_get_event = dahdi_timer_get_event,
67  .timer_get_max_rate = dahdi_timer_get_max_rate,
68 };
69 
70 static int dahdi_timer_open(void)
71 {
72  return open("/dev/dahdi/timer", O_RDWR);
73 }
74 
75 static void dahdi_timer_close(int handle)
76 {
77  close(handle);
78 }
79 
80 static int dahdi_timer_set_rate(int handle, unsigned int rate)
81 {
82  /* DAHDI timers are configured using a number of samples,
83  * based on an 8 kHz sample rate. */
84  unsigned int samples = roundf((8000.0 / ((float) rate)));
85 
86  if (ioctl(handle, DAHDI_TIMERCONFIG, &samples)) {
87  ast_log(LOG_ERROR, "Failed to configure DAHDI timing fd for %u sample timer ticks\n",
88  samples);
89  return -1;
90  }
91 
92  return 0;
93 }
94 
95 static int dahdi_timer_ack(int handle, unsigned int quantity)
96 {
97  return ioctl(handle, DAHDI_TIMERACK, &quantity) ? -1 : 0;
98 }
99 
100 static int dahdi_timer_enable_continuous(int handle)
101 {
102  int flags = 1;
103 
104  return ioctl(handle, DAHDI_TIMERPING, &flags) ? -1 : 0;
105 }
106 
107 static int dahdi_timer_disable_continuous(int handle)
108 {
109  int flags = -1;
110 
111  return ioctl(handle, DAHDI_TIMERPONG, &flags) ? -1 : 0;
112 }
113 
114 static enum ast_timer_event dahdi_timer_get_event(int handle)
115 {
116  int res;
117  int event;
118 
119  res = ioctl(handle, DAHDI_GETEVENT, &event);
120 
121  if (res) {
122  event = DAHDI_EVENT_TIMER_EXPIRED;
123  }
124 
125  switch (event) {
126  case DAHDI_EVENT_TIMER_PING:
128  case DAHDI_EVENT_TIMER_EXPIRED:
129  default:
130  return AST_TIMING_EVENT_EXPIRED;
131  }
132 }
133 
134 static unsigned int dahdi_timer_get_max_rate(int handle)
135 {
136  return 1000;
137 }
138 
139 #define SEE_TIMING "For more information on Asterisk timing modules, including ways to potentially fix this problem, please see https://wiki.asterisk.org/wiki/display/AST/Timing+Interfaces\n"
140 
141 static int dahdi_test_timer(void)
142 {
143  int fd;
144  int x = 160;
145 
146  fd = open("/dev/dahdi/timer", O_RDWR);
147 
148  if (fd < 0) {
149  return -1;
150  }
151 
152  if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) {
153  ast_log(LOG_ERROR, "You have DAHDI built and drivers loaded, but the DAHDI timer test failed to set DAHDI_TIMERCONFIG to %d.\n" SEE_TIMING, x);
154  close(fd);
155  return -1;
156  }
157 
158  if ((x = ast_wait_for_input(fd, 300)) < 0) {
159  ast_log(LOG_ERROR, "You have DAHDI built and drivers loaded, but the DAHDI timer could not be polled during the DAHDI timer test.\n" SEE_TIMING);
160  close(fd);
161  return -1;
162  }
163 
164  if (!x) {
165  const char dahdi_timer_error[] = {
166  "Asterisk has detected a problem with your DAHDI configuration and will shutdown for your protection. You have options:"
167  "\n\t1. You only have to compile DAHDI support into Asterisk if you need it. One option is to recompile without DAHDI support."
168  "\n\t2. You only have to load DAHDI drivers if you want to take advantage of DAHDI services. One option is to unload DAHDI modules if you don't need them."
169  "\n\t3. If you need DAHDI services, you must correctly configure DAHDI."
170  };
171  ast_log(LOG_ERROR, "%s\n" SEE_TIMING, dahdi_timer_error);
172  usleep(100);
173  close(fd);
174  return -1;
175  }
176 
177  close(fd);
178 
179  return 0;
180 }
181 
182 static int load_module(void)
183 {
184  if (dahdi_test_timer()) {
186  }
187 
188  return (timing_funcs_handle = ast_register_timing_interface(&dahdi_timing)) ?
190 }
191 
192 static int unload_module(void)
193 {
194  if (timing_funcs_handle) {
196  }
197 
198  return 0;
199 }
200 
201 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "DAHDI Timing Interface",
202  .load = load_module,
203  .unload = unload_module,
204  .load_pri = AST_MODPRI_TIMING,
205  );
const char * name
Definition: timing.h:70
Timing module interface.
Definition: timing.h:69
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_timing_interface dahdi_timing
static int dahdi_timer_disable_continuous(int handle)
static enum ast_timer_event dahdi_timer_get_event(int handle)
int ast_unregister_timing_interface(void *handle)
Unregister a previously registered timing interface.
Definition: timing.c:105
ast_timer_event
Definition: timing.h:57
float roundf(float x)
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
static int dahdi_timer_enable_continuous(int handle)
Utility functions.
static void * timing_funcs_handle
#define SEE_TIMING
static void dahdi_timer_close(int handle)
static int dahdi_timer_open(void)
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int dahdi_test_timer(void)
static int dahdi_timer_set_rate(int handle, unsigned int rate)
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition: timing.h:94
static int dahdi_timer_ack(int handle, unsigned int quantity)
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1255
static int load_module(void)
static int unload_module(void)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
static unsigned int dahdi_timer_get_max_rate(int handle)
Timing source management.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180