Wed Jan 27 20:02:15 2016

Asterisk developer's documentation


res_timing_dahdi.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2008, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! 
00020  * \file
00021  * \author Russell Bryant <russell@digium.com>
00022  *
00023  * \brief DAHDI timing interface 
00024  */
00025 
00026 /*** MODULEINFO
00027    <depend>dahdi</depend>
00028    <support_level>core</support_level>
00029  ***/
00030 
00031 #include "asterisk.h"
00032 
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 413586 $");
00034 
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <fcntl.h>
00038 #include <math.h>
00039 
00040 #include <dahdi/user.h>
00041 
00042 #include "asterisk/module.h"
00043 #include "asterisk/timing.h"
00044 #include "asterisk/utils.h"
00045 
00046 static void *timing_funcs_handle;
00047 
00048 static int dahdi_timer_open(void);
00049 static void dahdi_timer_close(int handle);
00050 static int dahdi_timer_set_rate(int handle, unsigned int rate);
00051 static int dahdi_timer_ack(int handle, unsigned int quantity);
00052 static int dahdi_timer_enable_continuous(int handle);
00053 static int dahdi_timer_disable_continuous(int handle);
00054 static enum ast_timer_event dahdi_timer_get_event(int handle);
00055 static unsigned int dahdi_timer_get_max_rate(int handle);
00056 
00057 static struct ast_timing_interface dahdi_timing = {
00058    .name = "DAHDI",
00059    .priority = 100,
00060    .timer_open = dahdi_timer_open,
00061    .timer_close = dahdi_timer_close,
00062    .timer_set_rate = dahdi_timer_set_rate,
00063    .timer_ack = dahdi_timer_ack,
00064    .timer_enable_continuous = dahdi_timer_enable_continuous,
00065    .timer_disable_continuous = dahdi_timer_disable_continuous,
00066    .timer_get_event = dahdi_timer_get_event,
00067    .timer_get_max_rate = dahdi_timer_get_max_rate,
00068 };
00069 
00070 static int dahdi_timer_open(void)
00071 {
00072    return open("/dev/dahdi/timer", O_RDWR);
00073 }
00074 
00075 static void dahdi_timer_close(int handle)
00076 {
00077    close(handle);
00078 }
00079 
00080 static int dahdi_timer_set_rate(int handle, unsigned int rate)
00081 {
00082    /* DAHDI timers are configured using a number of samples,
00083     * based on an 8 kHz sample rate. */
00084    unsigned int samples = roundf((8000.0 / ((float) rate)));
00085 
00086    if (ioctl(handle, DAHDI_TIMERCONFIG, &samples)) {
00087       ast_log(LOG_ERROR, "Failed to configure DAHDI timing fd for %u sample timer ticks\n",
00088          samples);
00089       return -1;
00090    }
00091 
00092    return 0;
00093 }
00094 
00095 static int dahdi_timer_ack(int handle, unsigned int quantity)
00096 {
00097    return ioctl(handle, DAHDI_TIMERACK, &quantity) ? -1 : 0;
00098 }
00099 
00100 static int dahdi_timer_enable_continuous(int handle)
00101 {
00102    int flags = 1;
00103 
00104    return ioctl(handle, DAHDI_TIMERPING, &flags) ? -1 : 0;
00105 }
00106 
00107 static int dahdi_timer_disable_continuous(int handle)
00108 {
00109    int flags = -1;
00110 
00111    return ioctl(handle, DAHDI_TIMERPONG, &flags) ? -1 : 0;
00112 }
00113 
00114 static enum ast_timer_event dahdi_timer_get_event(int handle)
00115 {
00116    int res;
00117    int event;
00118 
00119    res = ioctl(handle, DAHDI_GETEVENT, &event);
00120 
00121    if (res) {
00122       event = DAHDI_EVENT_TIMER_EXPIRED;
00123    }
00124 
00125    switch (event) {
00126    case DAHDI_EVENT_TIMER_PING:
00127       return AST_TIMING_EVENT_CONTINUOUS;
00128    case DAHDI_EVENT_TIMER_EXPIRED:
00129    default:
00130       return AST_TIMING_EVENT_EXPIRED; 
00131    }
00132 }
00133 
00134 static unsigned int dahdi_timer_get_max_rate(int handle)
00135 {
00136    return 1000;
00137 }
00138 
00139 #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"
00140 
00141 static int dahdi_test_timer(void)
00142 {
00143    int fd;
00144    int x = 160;
00145    
00146    fd = open("/dev/dahdi/timer", O_RDWR);
00147 
00148    if (fd < 0) {
00149       return -1;
00150    }
00151 
00152    if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) {
00153       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);
00154       close(fd);
00155       return -1;
00156    }
00157 
00158    if ((x = ast_wait_for_input(fd, 300)) < 0) {
00159       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);
00160       close(fd);
00161       return -1;
00162    }
00163 
00164    if (!x) {
00165       const char dahdi_timer_error[] = {
00166          "Asterisk has detected a problem with your DAHDI configuration and will shutdown for your protection.  You have options:"
00167          "\n\t1. You only have to compile DAHDI support into Asterisk if you need it.  One option is to recompile without DAHDI support."
00168          "\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."
00169          "\n\t3. If you need DAHDI services, you must correctly configure DAHDI."
00170       };
00171       ast_log(LOG_ERROR, "%s\n" SEE_TIMING, dahdi_timer_error);
00172       usleep(100);
00173       close(fd);
00174       return -1;
00175    }
00176 
00177    close(fd);
00178 
00179    return 0;
00180 }
00181 
00182 static int load_module(void)
00183 {
00184    if (dahdi_test_timer()) {
00185       return AST_MODULE_LOAD_DECLINE;
00186    }
00187 
00188    return (timing_funcs_handle = ast_register_timing_interface(&dahdi_timing)) ?
00189       AST_MODULE_LOAD_SUCCESS : AST_MODULE_LOAD_DECLINE;
00190 }
00191 
00192 static int unload_module(void)
00193 {
00194    if (timing_funcs_handle) {
00195       return ast_unregister_timing_interface(timing_funcs_handle);
00196    }
00197 
00198    return 0;
00199 }
00200 
00201 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "DAHDI Timing Interface",
00202       .load = load_module,
00203       .unload = unload_module,
00204       .load_pri = AST_MODPRI_TIMING,
00205       );

Generated on 27 Jan 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1