Tue Aug 20 16:34:37 2013

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: 375893 $");
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    int samples;
00083 
00084    /* DAHDI timers are configured using a number of samples,
00085     * based on an 8 kHz sample rate. */
00086    samples = (unsigned int) roundf((8000.0 / ((float) rate)));
00087 
00088    if (ioctl(handle, DAHDI_TIMERCONFIG, &samples)) {
00089       ast_log(LOG_ERROR, "Failed to configure DAHDI timing fd for %u sample timer ticks\n",
00090          samples);
00091       return -1;
00092    }
00093 
00094    return 0;
00095 }
00096 
00097 static int dahdi_timer_ack(int handle, unsigned int quantity)
00098 {
00099    return ioctl(handle, DAHDI_TIMERACK, &quantity) ? -1 : 0;
00100 }
00101 
00102 static int dahdi_timer_enable_continuous(int handle)
00103 {
00104    int flags = 1;
00105 
00106    return ioctl(handle, DAHDI_TIMERPING, &flags) ? -1 : 0;
00107 }
00108 
00109 static int dahdi_timer_disable_continuous(int handle)
00110 {
00111    int flags = -1;
00112 
00113    return ioctl(handle, DAHDI_TIMERPONG, &flags) ? -1 : 0;
00114 }
00115 
00116 static enum ast_timer_event dahdi_timer_get_event(int handle)
00117 {
00118    int res;
00119    int event;
00120 
00121    res = ioctl(handle, DAHDI_GETEVENT, &event);
00122 
00123    if (res) {
00124       event = DAHDI_EVENT_TIMER_EXPIRED;
00125    }
00126 
00127    switch (event) {
00128    case DAHDI_EVENT_TIMER_PING:
00129       return AST_TIMING_EVENT_CONTINUOUS;
00130    case DAHDI_EVENT_TIMER_EXPIRED:
00131    default:
00132       return AST_TIMING_EVENT_EXPIRED; 
00133    }
00134 }
00135 
00136 static unsigned int dahdi_timer_get_max_rate(int handle)
00137 {
00138    return 1000;
00139 }
00140 
00141 #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"
00142 
00143 static int dahdi_test_timer(void)
00144 {
00145    int fd;
00146    int x = 160;
00147    
00148    fd = open("/dev/dahdi/timer", O_RDWR);
00149 
00150    if (fd < 0) {
00151       return -1;
00152    }
00153 
00154    if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) {
00155       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);
00156       close(fd);
00157       return -1;
00158    }
00159 
00160    if ((x = ast_wait_for_input(fd, 300)) < 0) {
00161       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);
00162       close(fd);
00163       return -1;
00164    }
00165 
00166    if (!x) {
00167       const char dahdi_timer_error[] = {
00168          "Asterisk has detected a problem with your DAHDI configuration and will shutdown for your protection.  You have options:"
00169          "\n\t1. You only have to compile DAHDI support into Asterisk if you need it.  One option is to recompile without DAHDI support."
00170          "\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."
00171          "\n\t3. If you need DAHDI services, you must correctly configure DAHDI."
00172       };
00173       ast_log(LOG_ERROR, "%s\n" SEE_TIMING, dahdi_timer_error);
00174       usleep(100);
00175       close(fd);
00176       return -1;
00177    }
00178 
00179    close(fd);
00180 
00181    return 0;
00182 }
00183 
00184 static int load_module(void)
00185 {
00186    if (dahdi_test_timer()) {
00187       return AST_MODULE_LOAD_DECLINE;
00188    }
00189 
00190    return (timing_funcs_handle = ast_register_timing_interface(&dahdi_timing)) ?
00191       AST_MODULE_LOAD_SUCCESS : AST_MODULE_LOAD_DECLINE;
00192 }
00193 
00194 static int unload_module(void)
00195 {
00196    if (timing_funcs_handle) {
00197       return ast_unregister_timing_interface(timing_funcs_handle);
00198    }
00199 
00200    return 0;
00201 }
00202 
00203 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "DAHDI Timing Interface",
00204       .load = load_module,
00205       .unload = unload_module,
00206       .load_pri = AST_MODPRI_TIMING,
00207       );

Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1